Deleted Added
full compact
i386.md (90286) i386.md (96294)
1;; GCC machine description for IA-32 and x86-64.
2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3;; Free Software Foundation, Inc.
4;; Mostly by William Schelter.
5;; x86_64 support added by Jan Hubicka
6;;
7;; This file is part of GNU CC.
8;;
9;; GNU CC is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; GNU CC is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GNU CC; see the file COPYING. If not, write to
21;; the Free Software Foundation, 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA. */
23;;
24;; The original PO technology requires these to be ordered by speed,
25;; so that assigner will pick the fastest.
26;;
27;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28;;
29;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
30;; updates for most instructions.
31;;
32;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
33;; constraint letters.
34;;
35;; The special asm out single letter directives following a '%' are:
36;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
37;; operands[1].
38;; 'L' Print the opcode suffix for a 32-bit integer opcode.
39;; 'W' Print the opcode suffix for a 16-bit integer opcode.
40;; 'B' Print the opcode suffix for an 8-bit integer opcode.
41;; 'Q' Print the opcode suffix for a 64-bit float opcode.
42;; 'S' Print the opcode suffix for a 32-bit float opcode.
43;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
44;; 'J' Print the appropriate jump operand.
45;;
46;; 'b' Print the QImode name of the register for the indicated operand.
47;; %b0 would print %al if operands[0] is reg 0.
48;; 'w' Likewise, print the HImode name of the register.
49;; 'k' Likewise, print the SImode name of the register.
50;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
51;; 'y' Print "st(0)" instead of "st" as a register.
52;;
53;; UNSPEC usage:
54;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
55;; operand 0 is the memory address to scan.
56;; operand 1 is a register containing the value to scan for. The mode
57;; of the scas opcode will be the same as the mode of this operand.
58;; operand 2 is the known alignment of operand 0.
59;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
60;; operand 0 is the argument for `sin'.
61;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
62;; operand 0 is the argument for `cos'.
63;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
64;; always SImode. operand 0 is the size of the stack allocation.
65;; 4 This is the source of a fake SET of the frame pointer which is used to
66;; prevent insns referencing it being scheduled across the initial
67;; decrement of the stack pointer.
68;; 5 This is a `bsf' operation.
69;; 6 This is the @GOT offset of a PIC address.
70;; 7 This is the @GOTOFF offset of a PIC address.
71;; 8 This is a reference to a symbol's @PLT address.
72;; 9 This is an `fnstsw' operation.
73;; 10 This is a `sahf' operation.
74;; 11 This is a `fstcw' operation
75;; 12 This is behaviour of add when setting carry flag.
76;; 13 This is a `eh_return' placeholder.
77
78;; For SSE/MMX support:
79;; 30 This is `fix', guaranteed to be truncating.
80;; 31 This is a `emms' operation.
81;; 32 This is a `maskmov' operation.
82;; 33 This is a `movmsk' operation.
83;; 34 This is a `non-temporal' move.
84;; 36 This is used to distinguish COMISS from UCOMISS.
85;; 37 This is a `ldmxcsr' operation.
86;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
87;; 39 This is a forced `movups' instruction (rather than whatever movti does)
88;; 40 This is a `stmxcsr' operation.
89;; 41 This is a `shuffle' operation.
90;; 42 This is a `rcp' operation.
91;; 43 This is a `rsqsrt' operation.
92;; 44 This is a `sfence' operation.
93;; 45 This is a noop to prevent excessive combiner cleverness.
94;; 46 This is a `femms' operation.
95;; 49 This is a 'pavgusb' operation.
96;; 50 This is a `pfrcp' operation.
97;; 51 This is a `pfrcpit1' operation.
98;; 52 This is a `pfrcpit2' operation.
99;; 53 This is a `pfrsqrt' operation.
100;; 54 This is a `pfrsqrit1' operation.
101
102;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
103;; from i386.c.
104
105;; In C guard expressions, put expressions which may be compile-time
106;; constants first. This allows for better optimization. For
107;; example, write "TARGET_64BIT && reload_completed", not
108;; "reload_completed && TARGET_64BIT".
109
110
111;; Processor type. This attribute must exactly match the processor_type
112;; enumeration in i386.h.
113(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
114 (const (symbol_ref "ix86_cpu")))
115
1;; GCC machine description for IA-32 and x86-64.
2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3;; Free Software Foundation, Inc.
4;; Mostly by William Schelter.
5;; x86_64 support added by Jan Hubicka
6;;
7;; This file is part of GNU CC.
8;;
9;; GNU CC is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; GNU CC is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GNU CC; see the file COPYING. If not, write to
21;; the Free Software Foundation, 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA. */
23;;
24;; The original PO technology requires these to be ordered by speed,
25;; so that assigner will pick the fastest.
26;;
27;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28;;
29;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
30;; updates for most instructions.
31;;
32;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
33;; constraint letters.
34;;
35;; The special asm out single letter directives following a '%' are:
36;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
37;; operands[1].
38;; 'L' Print the opcode suffix for a 32-bit integer opcode.
39;; 'W' Print the opcode suffix for a 16-bit integer opcode.
40;; 'B' Print the opcode suffix for an 8-bit integer opcode.
41;; 'Q' Print the opcode suffix for a 64-bit float opcode.
42;; 'S' Print the opcode suffix for a 32-bit float opcode.
43;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
44;; 'J' Print the appropriate jump operand.
45;;
46;; 'b' Print the QImode name of the register for the indicated operand.
47;; %b0 would print %al if operands[0] is reg 0.
48;; 'w' Likewise, print the HImode name of the register.
49;; 'k' Likewise, print the SImode name of the register.
50;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
51;; 'y' Print "st(0)" instead of "st" as a register.
52;;
53;; UNSPEC usage:
54;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
55;; operand 0 is the memory address to scan.
56;; operand 1 is a register containing the value to scan for. The mode
57;; of the scas opcode will be the same as the mode of this operand.
58;; operand 2 is the known alignment of operand 0.
59;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
60;; operand 0 is the argument for `sin'.
61;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
62;; operand 0 is the argument for `cos'.
63;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
64;; always SImode. operand 0 is the size of the stack allocation.
65;; 4 This is the source of a fake SET of the frame pointer which is used to
66;; prevent insns referencing it being scheduled across the initial
67;; decrement of the stack pointer.
68;; 5 This is a `bsf' operation.
69;; 6 This is the @GOT offset of a PIC address.
70;; 7 This is the @GOTOFF offset of a PIC address.
71;; 8 This is a reference to a symbol's @PLT address.
72;; 9 This is an `fnstsw' operation.
73;; 10 This is a `sahf' operation.
74;; 11 This is a `fstcw' operation
75;; 12 This is behaviour of add when setting carry flag.
76;; 13 This is a `eh_return' placeholder.
77
78;; For SSE/MMX support:
79;; 30 This is `fix', guaranteed to be truncating.
80;; 31 This is a `emms' operation.
81;; 32 This is a `maskmov' operation.
82;; 33 This is a `movmsk' operation.
83;; 34 This is a `non-temporal' move.
84;; 36 This is used to distinguish COMISS from UCOMISS.
85;; 37 This is a `ldmxcsr' operation.
86;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
87;; 39 This is a forced `movups' instruction (rather than whatever movti does)
88;; 40 This is a `stmxcsr' operation.
89;; 41 This is a `shuffle' operation.
90;; 42 This is a `rcp' operation.
91;; 43 This is a `rsqsrt' operation.
92;; 44 This is a `sfence' operation.
93;; 45 This is a noop to prevent excessive combiner cleverness.
94;; 46 This is a `femms' operation.
95;; 49 This is a 'pavgusb' operation.
96;; 50 This is a `pfrcp' operation.
97;; 51 This is a `pfrcpit1' operation.
98;; 52 This is a `pfrcpit2' operation.
99;; 53 This is a `pfrsqrt' operation.
100;; 54 This is a `pfrsqrit1' operation.
101
102;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
103;; from i386.c.
104
105;; In C guard expressions, put expressions which may be compile-time
106;; constants first. This allows for better optimization. For
107;; example, write "TARGET_64BIT && reload_completed", not
108;; "reload_completed && TARGET_64BIT".
109
110
111;; Processor type. This attribute must exactly match the processor_type
112;; enumeration in i386.h.
113(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
114 (const (symbol_ref "ix86_cpu")))
115
116;; $FreeBSD: head/contrib/gcc/config/i386/i386.md 90286 2002-02-06 05:02:18Z obrien $
116;; $FreeBSD: head/contrib/gcc/config/i386/i386.md 96294 2002-05-09 22:44:32Z obrien $
117
118;; A basic instruction type. Refinements due to arguments to be
119;; provided in other attributes.
120(define_attr "type"
121 "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
122 (const_string "other"))
123
124;; Main data type used by the insn
125(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
126 (const_string "unknown"))
127
128;; Set for i387 operations.
129(define_attr "i387" ""
130 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
131 (const_int 1)
132 (const_int 0)))
133
134;; The (bounding maximum) length of an instruction immediate.
135(define_attr "length_immediate" ""
136 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
137 (const_int 0)
138 (eq_attr "i387" "1")
139 (const_int 0)
140 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
141 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
142 (eq_attr "type" "imov,test")
143 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
144 (eq_attr "type" "call")
145 (if_then_else (match_operand 0 "constant_call_address_operand" "")
146 (const_int 4)
147 (const_int 0))
148 (eq_attr "type" "callv")
149 (if_then_else (match_operand 1 "constant_call_address_operand" "")
150 (const_int 4)
151 (const_int 0))
152 (eq_attr "type" "ibr")
153 (if_then_else (and (ge (minus (match_dup 0) (pc))
154 (const_int -128))
155 (lt (minus (match_dup 0) (pc))
156 (const_int 124)))
157 (const_int 1)
158 (const_int 4))
159 ]
160 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
161
162;; The (bounding maximum) length of an instruction address.
163(define_attr "length_address" ""
164 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
165 (const_int 0)
166 (and (eq_attr "type" "call")
167 (match_operand 1 "constant_call_address_operand" ""))
168 (const_int 0)
169 (and (eq_attr "type" "callv")
170 (match_operand 1 "constant_call_address_operand" ""))
171 (const_int 0)
172 ]
173 (symbol_ref "ix86_attr_length_address_default (insn)")))
174
175;; Set when length prefix is used.
176(define_attr "prefix_data16" ""
177 (if_then_else (eq_attr "mode" "HI")
178 (const_int 1)
179 (const_int 0)))
180
181;; Set when string REP prefix is used.
182(define_attr "prefix_rep" "" (const_int 0))
183
184;; Set when 0f opcode prefix is used.
185(define_attr "prefix_0f" ""
186 (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
187 (const_int 1)
188 (const_int 0)))
189
190;; Set when modrm byte is used.
191(define_attr "modrm" ""
192 (cond [(eq_attr "type" "str,cld")
193 (const_int 0)
194 (eq_attr "i387" "1")
195 (const_int 0)
196 (and (eq_attr "type" "incdec")
197 (ior (match_operand:SI 1 "register_operand" "")
198 (match_operand:HI 1 "register_operand" "")))
199 (const_int 0)
200 (and (eq_attr "type" "push")
201 (not (match_operand 1 "memory_operand" "")))
202 (const_int 0)
203 (and (eq_attr "type" "pop")
204 (not (match_operand 0 "memory_operand" "")))
205 (const_int 0)
206 (and (eq_attr "type" "imov")
207 (and (match_operand 0 "register_operand" "")
208 (match_operand 1 "immediate_operand" "")))
209 (const_int 0)
210 ]
211 (const_int 1)))
212
213;; The (bounding maximum) length of an instruction in bytes.
214;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
215;; to split it and compute proper length as for other insns.
216(define_attr "length" ""
217 (cond [(eq_attr "type" "other,multi,fistp")
218 (const_int 16)
219 ]
220 (plus (plus (attr "modrm")
221 (plus (attr "prefix_0f")
222 (plus (attr "i387")
223 (const_int 1))))
224 (plus (attr "prefix_rep")
225 (plus (attr "prefix_data16")
226 (plus (attr "length_immediate")
227 (attr "length_address")))))))
228
229;; The `memory' attribute is `none' if no memory is referenced, `load' or
230;; `store' if there is a simple memory reference therein, or `unknown'
231;; if the instruction is complex.
232
233(define_attr "memory" "none,load,store,both,unknown"
234 (cond [(eq_attr "type" "other,multi,str")
235 (const_string "unknown")
236 (eq_attr "type" "lea,fcmov,fpspc,cld")
237 (const_string "none")
238 (eq_attr "type" "fistp")
239 (const_string "both")
240 (eq_attr "type" "push")
241 (if_then_else (match_operand 1 "memory_operand" "")
242 (const_string "both")
243 (const_string "store"))
244 (eq_attr "type" "pop,setcc")
245 (if_then_else (match_operand 0 "memory_operand" "")
246 (const_string "both")
247 (const_string "load"))
248 (eq_attr "type" "icmp,test")
249 (if_then_else (ior (match_operand 0 "memory_operand" "")
250 (match_operand 1 "memory_operand" ""))
251 (const_string "load")
252 (const_string "none"))
253 (eq_attr "type" "ibr")
254 (if_then_else (match_operand 0 "memory_operand" "")
255 (const_string "load")
256 (const_string "none"))
257 (eq_attr "type" "call")
258 (if_then_else (match_operand 0 "constant_call_address_operand" "")
259 (const_string "none")
260 (const_string "load"))
261 (eq_attr "type" "callv")
262 (if_then_else (match_operand 1 "constant_call_address_operand" "")
263 (const_string "none")
264 (const_string "load"))
265 (and (eq_attr "type" "alu1,negnot")
266 (match_operand 1 "memory_operand" ""))
267 (const_string "both")
268 (and (match_operand 0 "memory_operand" "")
269 (match_operand 1 "memory_operand" ""))
270 (const_string "both")
271 (match_operand 0 "memory_operand" "")
272 (const_string "store")
273 (match_operand 1 "memory_operand" "")
274 (const_string "load")
275 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
276 (match_operand 2 "memory_operand" ""))
277 (const_string "load")
278 (and (eq_attr "type" "icmov")
279 (match_operand 3 "memory_operand" ""))
280 (const_string "load")
281 ]
282 (const_string "none")))
283
284;; Indicates if an instruction has both an immediate and a displacement.
285
286(define_attr "imm_disp" "false,true,unknown"
287 (cond [(eq_attr "type" "other,multi")
288 (const_string "unknown")
289 (and (eq_attr "type" "icmp,test,imov")
290 (and (match_operand 0 "memory_displacement_operand" "")
291 (match_operand 1 "immediate_operand" "")))
292 (const_string "true")
293 (and (eq_attr "type" "alu,ishift,imul,idiv")
294 (and (match_operand 0 "memory_displacement_operand" "")
295 (match_operand 2 "immediate_operand" "")))
296 (const_string "true")
297 ]
298 (const_string "false")))
299
300;; Indicates if an FP operation has an integer source.
301
302(define_attr "fp_int_src" "false,true"
303 (const_string "false"))
304
305;; Describe a user's asm statement.
306(define_asm_attributes
307 [(set_attr "length" "128")
308 (set_attr "type" "multi")])
309
310;; Pentium Scheduling
311;;
312;; The Pentium is an in-order core with two integer pipelines.
313
314;; True for insns that behave like prefixed insns on the Pentium.
315(define_attr "pent_prefix" "false,true"
316 (if_then_else (ior (eq_attr "prefix_0f" "1")
317 (ior (eq_attr "prefix_data16" "1")
318 (eq_attr "prefix_rep" "1")))
319 (const_string "true")
320 (const_string "false")))
321
322;; Categorize how an instruction slots.
323
324;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
325;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
326;; rules, because it results in noticeably better code on non-MMX Pentium
327;; and doesn't hurt much on MMX. (Prefixed instructions are not very
328;; common, so the scheduler usualy has a non-prefixed insn to pair).
329
330(define_attr "pent_pair" "uv,pu,pv,np"
331 (cond [(eq_attr "imm_disp" "true")
332 (const_string "np")
333 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
334 (and (eq_attr "type" "pop,push")
335 (eq_attr "memory" "!both")))
336 (if_then_else (eq_attr "pent_prefix" "true")
337 (const_string "pu")
338 (const_string "uv"))
339 (eq_attr "type" "ibr")
340 (const_string "pv")
341 (and (eq_attr "type" "ishift")
342 (match_operand 2 "const_int_operand" ""))
343 (const_string "pu")
344 (and (eq_attr "type" "call")
345 (match_operand 0 "constant_call_address_operand" ""))
346 (const_string "pv")
347 (and (eq_attr "type" "callv")
348 (match_operand 1 "constant_call_address_operand" ""))
349 (const_string "pv")
350 ]
351 (const_string "np")))
352
353;; Rough readiness numbers. Fine tuning happens in i386.c.
354;;
355;; u describes pipe U
356;; v describes pipe V
357;; uv describes either pipe U or V for those that can issue to either
358;; np describes not paring
359;; fpu describes fpu
360;; fpm describes fp insns of different types are not pipelined.
361;;
362;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
363
364(define_function_unit "pent_np" 1 0
365 (and (eq_attr "cpu" "pentium")
366 (eq_attr "type" "imul"))
367 11 11)
368
369(define_function_unit "pent_mul" 1 1
370 (and (eq_attr "cpu" "pentium")
371 (eq_attr "type" "imul"))
372 11 11)
373
374;; Rep movs takes minimally 12 cycles.
375(define_function_unit "pent_np" 1 0
376 (and (eq_attr "cpu" "pentium")
377 (eq_attr "type" "str"))
378 12 12)
379
380; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
381(define_function_unit "pent_np" 1 0
382 (and (eq_attr "cpu" "pentium")
383 (eq_attr "type" "idiv"))
384 46 46)
385
386; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
387; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
388; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
389; The integer <-> fp conversion is not modeled correctly. Fild behaves
390; like normal fp operation and fist takes 6 cycles.
391
392(define_function_unit "fpu" 1 0
393 (and (eq_attr "cpu" "pentium")
394 (and (eq_attr "type" "fmov")
395 (and (eq_attr "memory" "load,store")
396 (eq_attr "mode" "XF"))))
397 3 3)
398
399(define_function_unit "pent_np" 1 0
400 (and (eq_attr "cpu" "pentium")
401 (and (eq_attr "type" "fmov")
402 (and (eq_attr "memory" "load,store")
403 (eq_attr "mode" "XF"))))
404 3 3)
405
406(define_function_unit "fpu" 1 0
407 (and (eq_attr "cpu" "pentium")
408 (and (eq_attr "type" "fmov")
409 (ior (match_operand 1 "immediate_operand" "")
410 (eq_attr "memory" "store"))))
411 2 2)
412
413(define_function_unit "pent_np" 1 0
414 (and (eq_attr "cpu" "pentium")
415 (and (eq_attr "type" "fmov")
416 (ior (match_operand 1 "immediate_operand" "")
417 (eq_attr "memory" "store"))))
418 2 2)
419
420(define_function_unit "pent_np" 1 0
421 (and (eq_attr "cpu" "pentium")
422 (eq_attr "type" "cld"))
423 2 2)
424
425(define_function_unit "fpu" 1 0
426 (and (eq_attr "cpu" "pentium")
427 (and (eq_attr "type" "fmov")
428 (eq_attr "memory" "none,load")))
429 1 1)
430
431; Read/Modify/Write instructions usually take 3 cycles.
432(define_function_unit "pent_u" 1 0
433 (and (eq_attr "cpu" "pentium")
434 (and (eq_attr "type" "alu,alu1,ishift")
435 (and (eq_attr "pent_pair" "pu")
436 (eq_attr "memory" "both"))))
437 3 3)
438
439(define_function_unit "pent_uv" 2 0
440 (and (eq_attr "cpu" "pentium")
441 (and (eq_attr "type" "alu,alu1,ishift")
442 (and (eq_attr "pent_pair" "!np")
443 (eq_attr "memory" "both"))))
444 3 3)
445
446(define_function_unit "pent_np" 1 0
447 (and (eq_attr "cpu" "pentium")
448 (and (eq_attr "type" "alu,alu1,negnot,ishift")
449 (and (eq_attr "pent_pair" "np")
450 (eq_attr "memory" "both"))))
451 3 3)
452
453; Read/Modify or Modify/Write instructions usually take 2 cycles.
454(define_function_unit "pent_u" 1 0
455 (and (eq_attr "cpu" "pentium")
456 (and (eq_attr "type" "alu,ishift")
457 (and (eq_attr "pent_pair" "pu")
458 (eq_attr "memory" "load,store"))))
459 2 2)
460
461(define_function_unit "pent_uv" 2 0
462 (and (eq_attr "cpu" "pentium")
463 (and (eq_attr "type" "alu,ishift")
464 (and (eq_attr "pent_pair" "!np")
465 (eq_attr "memory" "load,store"))))
466 2 2)
467
468(define_function_unit "pent_np" 1 0
469 (and (eq_attr "cpu" "pentium")
470 (and (eq_attr "type" "alu,ishift")
471 (and (eq_attr "pent_pair" "np")
472 (eq_attr "memory" "load,store"))))
473 2 2)
474
475; Insns w/o memory operands and move instructions usually take one cycle.
476(define_function_unit "pent_u" 1 0
477 (and (eq_attr "cpu" "pentium")
478 (eq_attr "pent_pair" "pu"))
479 1 1)
480
481(define_function_unit "pent_v" 1 0
482 (and (eq_attr "cpu" "pentium")
483 (eq_attr "pent_pair" "pv"))
484 1 1)
485
486(define_function_unit "pent_uv" 2 0
487 (and (eq_attr "cpu" "pentium")
488 (eq_attr "pent_pair" "!np"))
489 1 1)
490
491(define_function_unit "pent_np" 1 0
492 (and (eq_attr "cpu" "pentium")
493 (eq_attr "pent_pair" "np"))
494 1 1)
495
496; Pairable insns only conflict with other non-pairable insns.
497(define_function_unit "pent_np" 1 0
498 (and (eq_attr "cpu" "pentium")
499 (and (eq_attr "type" "alu,alu1,ishift")
500 (and (eq_attr "pent_pair" "!np")
501 (eq_attr "memory" "both"))))
502 3 3
503 [(eq_attr "pent_pair" "np")])
504
505(define_function_unit "pent_np" 1 0
506 (and (eq_attr "cpu" "pentium")
507 (and (eq_attr "type" "alu,alu1,ishift")
508 (and (eq_attr "pent_pair" "!np")
509 (eq_attr "memory" "load,store"))))
510 2 2
511 [(eq_attr "pent_pair" "np")])
512
513(define_function_unit "pent_np" 1 0
514 (and (eq_attr "cpu" "pentium")
515 (eq_attr "pent_pair" "!np"))
516 1 1
517 [(eq_attr "pent_pair" "np")])
518
519; Floating point instructions usually blocks cycle longer when combined with
520; integer instructions, because of the inpaired fxch instruction.
521(define_function_unit "pent_np" 1 0
522 (and (eq_attr "cpu" "pentium")
523 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
524 2 2
525 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
526
527(define_function_unit "fpu" 1 0
528 (and (eq_attr "cpu" "pentium")
529 (eq_attr "type" "fcmp,fxch,fsgn"))
530 1 1)
531
532; Addition takes 3 cycles; assume other random cruft does as well.
533; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
534(define_function_unit "fpu" 1 0
535 (and (eq_attr "cpu" "pentium")
536 (eq_attr "type" "fop,fop1,fistp"))
537 3 1)
538
539; Multiplication takes 3 cycles and is only half pipelined.
540(define_function_unit "fpu" 1 0
541 (and (eq_attr "cpu" "pentium")
542 (eq_attr "type" "fmul"))
543 3 1)
544
545(define_function_unit "pent_mul" 1 1
546 (and (eq_attr "cpu" "pentium")
547 (eq_attr "type" "fmul"))
548 2 2)
549
550; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
551; They can overlap with integer insns. Only the last two cycles can overlap
552; with other fp insns. Only fsin/fcos can overlap with multiplies.
553; Only last two cycles of fsin/fcos can overlap with other instructions.
554(define_function_unit "fpu" 1 0
555 (and (eq_attr "cpu" "pentium")
556 (eq_attr "type" "fdiv"))
557 39 37)
558
559(define_function_unit "pent_mul" 1 1
560 (and (eq_attr "cpu" "pentium")
561 (eq_attr "type" "fdiv"))
562 39 39)
563
564(define_function_unit "fpu" 1 0
565 (and (eq_attr "cpu" "pentium")
566 (eq_attr "type" "fpspc"))
567 70 68)
568
569(define_function_unit "pent_mul" 1 1
570 (and (eq_attr "cpu" "pentium")
571 (eq_attr "type" "fpspc"))
572 70 70)
573
574;; Pentium Pro/PII Scheduling
575;;
576;; The PPro has an out-of-order core, but the instruction decoders are
577;; naturally in-order and asymmetric. We get best performance by scheduling
578;; for the decoders, for in doing so we give the oo execution unit the
579;; most choices.
580
581;; Categorize how many uops an ia32 instruction evaluates to:
582;; one -- an instruction with 1 uop can be decoded by any of the
583;; three decoders.
584;; few -- an instruction with 1 to 4 uops can be decoded only by
585;; decoder 0.
586;; many -- a complex instruction may take an unspecified number of
587;; cycles to decode in decoder 0.
588
589(define_attr "ppro_uops" "one,few,many"
590 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
591 (const_string "many")
592 (eq_attr "type" "icmov,fcmov,str,cld")
593 (const_string "few")
594 (eq_attr "type" "imov")
595 (if_then_else (eq_attr "memory" "store,both")
596 (const_string "few")
597 (const_string "one"))
598 (eq_attr "memory" "!none")
599 (const_string "few")
600 ]
601 (const_string "one")))
602
603;; Rough readiness numbers. Fine tuning happens in i386.c.
604;;
605;; p0 describes port 0.
606;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
607;; p2 describes port 2 for loads.
608;; p34 describes ports 3 and 4 for stores.
609;; fpu describes the fpu accessed via port 0.
610;; ??? It is less than clear if there are separate fadd and fmul units
611;; that could operate in parallel.
612;;
613;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
614
615(define_function_unit "ppro_p0" 1 0
616 (and (eq_attr "cpu" "pentiumpro")
617 (eq_attr "type" "ishift,lea,ibr,cld"))
618 1 1)
619
620(define_function_unit "ppro_p0" 1 0
621 (and (eq_attr "cpu" "pentiumpro")
622 (eq_attr "type" "imul"))
623 4 1)
624
625;; ??? Does the divider lock out the pipe while it works,
626;; or is there a disconnected unit?
627(define_function_unit "ppro_p0" 1 0
628 (and (eq_attr "cpu" "pentiumpro")
629 (eq_attr "type" "idiv"))
630 17 17)
631
632(define_function_unit "ppro_p0" 1 0
633 (and (eq_attr "cpu" "pentiumpro")
634 (eq_attr "type" "fop,fop1,fsgn,fistp"))
635 3 1)
636
637(define_function_unit "ppro_p0" 1 0
638 (and (eq_attr "cpu" "pentiumpro")
639 (eq_attr "type" "fcmov"))
640 2 1)
641
642(define_function_unit "ppro_p0" 1 0
643 (and (eq_attr "cpu" "pentiumpro")
644 (eq_attr "type" "fcmp"))
645 1 1)
646
647(define_function_unit "ppro_p0" 1 0
648 (and (eq_attr "cpu" "pentiumpro")
649 (eq_attr "type" "fmov"))
650 1 1)
651
652(define_function_unit "ppro_p0" 1 0
653 (and (eq_attr "cpu" "pentiumpro")
654 (eq_attr "type" "fmul"))
655 5 1)
656
657(define_function_unit "ppro_p0" 1 0
658 (and (eq_attr "cpu" "pentiumpro")
659 (eq_attr "type" "fdiv,fpspc"))
660 56 1)
661
662(define_function_unit "ppro_p01" 2 0
663 (and (eq_attr "cpu" "pentiumpro")
664 (eq_attr "type" "!imov,fmov"))
665 1 1)
666
667(define_function_unit "ppro_p01" 2 0
668 (and (and (eq_attr "cpu" "pentiumpro")
669 (eq_attr "type" "imov,fmov"))
670 (eq_attr "memory" "none"))
671 1 1)
672
673(define_function_unit "ppro_p2" 1 0
674 (and (eq_attr "cpu" "pentiumpro")
675 (ior (eq_attr "type" "pop")
676 (eq_attr "memory" "load,both")))
677 3 1)
678
679(define_function_unit "ppro_p34" 1 0
680 (and (eq_attr "cpu" "pentiumpro")
681 (ior (eq_attr "type" "push")
682 (eq_attr "memory" "store,both")))
683 1 1)
684
685(define_function_unit "fpu" 1 0
686 (and (eq_attr "cpu" "pentiumpro")
687 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
688 1 1)
689
690(define_function_unit "fpu" 1 0
691 (and (eq_attr "cpu" "pentiumpro")
692 (eq_attr "type" "fmul"))
693 5 2)
694
695(define_function_unit "fpu" 1 0
696 (and (eq_attr "cpu" "pentiumpro")
697 (eq_attr "type" "fdiv,fpspc"))
698 56 56)
699
700;; imul uses the fpu. ??? does it have the same throughput as fmul?
701(define_function_unit "fpu" 1 0
702 (and (eq_attr "cpu" "pentiumpro")
703 (eq_attr "type" "imul"))
704 4 1)
705
706;; AMD K6/K6-2 Scheduling
707;;
708;; The K6 has similar architecture to PPro. Important difference is, that
709;; there are only two decoders and they seems to be much slower than execution
710;; units. So we have to pay much more attention to proper decoding for
711;; schedulers. We share most of scheduler code for PPro in i386.c
712;;
713;; The fp unit is not pipelined and do one operation per two cycles including
714;; the FXCH.
715;;
716;; alu describes both ALU units (ALU-X and ALU-Y).
717;; alux describes X alu unit
718;; fpu describes FPU unit
719;; load describes load unit.
720;; branch describes branch unit.
721;; store decsribes store unit. This unit is not modelled completely and only
722;; used to model lea operation. Otherwise it lie outside of the critical
723;; path.
724;;
725;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
726
727;; The decoder specification is in the PPro section above!
728
729;; Shift instructions and certain arithmetic are issued only to X pipe.
730(define_function_unit "k6_alux" 1 0
731 (and (eq_attr "cpu" "k6")
732 (eq_attr "type" "ishift,alu1,negnot,cld"))
733 1 1)
734
735;; The QI mode arithmetic is issued to X pipe only.
736(define_function_unit "k6_alux" 1 0
737 (and (eq_attr "cpu" "k6")
738 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
739 (match_operand:QI 0 "general_operand" "")))
740 1 1)
741
742(define_function_unit "k6_alu" 2 0
743 (and (eq_attr "cpu" "k6")
744 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
745 1 1)
746
747(define_function_unit "k6_alu" 2 0
748 (and (eq_attr "cpu" "k6")
749 (and (eq_attr "type" "imov")
750 (eq_attr "memory" "none")))
751 1 1)
752
753(define_function_unit "k6_branch" 1 0
754 (and (eq_attr "cpu" "k6")
755 (eq_attr "type" "call,callv,ibr"))
756 1 1)
757
758;; Load unit have two cycle latency, but we take care for it in adjust_cost
759(define_function_unit "k6_load" 1 0
760 (and (eq_attr "cpu" "k6")
761 (ior (eq_attr "type" "pop")
762 (eq_attr "memory" "load,both")))
763 1 1)
764
765(define_function_unit "k6_load" 1 0
766 (and (eq_attr "cpu" "k6")
767 (and (eq_attr "type" "str")
768 (eq_attr "memory" "load,both")))
769 10 10)
770
771;; Lea have two instructions, so latency is probably 2
772(define_function_unit "k6_store" 1 0
773 (and (eq_attr "cpu" "k6")
774 (eq_attr "type" "lea"))
775 2 1)
776
777(define_function_unit "k6_store" 1 0
778 (and (eq_attr "cpu" "k6")
779 (eq_attr "type" "str"))
780 10 10)
781
782(define_function_unit "k6_store" 1 0
783 (and (eq_attr "cpu" "k6")
784 (ior (eq_attr "type" "push")
785 (eq_attr "memory" "store,both")))
786 1 1)
787
788(define_function_unit "k6_fpu" 1 1
789 (and (eq_attr "cpu" "k6")
790 (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
791 2 2)
792
793(define_function_unit "k6_fpu" 1 1
794 (and (eq_attr "cpu" "k6")
795 (eq_attr "type" "fmul"))
796 2 2)
797
798;; ??? Guess
799(define_function_unit "k6_fpu" 1 1
800 (and (eq_attr "cpu" "k6")
801 (eq_attr "type" "fdiv,fpspc"))
802 56 56)
803
804(define_function_unit "k6_alu" 2 0
805 (and (eq_attr "cpu" "k6")
806 (eq_attr "type" "imul"))
807 2 2)
808
809(define_function_unit "k6_alux" 1 0
810 (and (eq_attr "cpu" "k6")
811 (eq_attr "type" "imul"))
812 2 2)
813
814;; ??? Guess
815(define_function_unit "k6_alu" 2 0
816 (and (eq_attr "cpu" "k6")
817 (eq_attr "type" "idiv"))
818 17 17)
819
820(define_function_unit "k6_alux" 1 0
821 (and (eq_attr "cpu" "k6")
822 (eq_attr "type" "idiv"))
823 17 17)
824
825;; AMD Athlon Scheduling
826;;
827;; The Athlon does contain three pipelined FP units, three integer units and
828;; three address generation units.
829;;
830;; The predecode logic is determining boundaries of instructions in the 64
831;; byte cache line. So the cache line straddling problem of K6 might be issue
832;; here as well, but it is not noted in the documentation.
833;;
834;; Three DirectPath instructions decoders and only one VectorPath decoder
835;; is available. They can decode three DirectPath instructions or one VectorPath
836;; instruction per cycle.
837;; Decoded macro instructions are then passed to 72 entry instruction control
838;; unit, that passes
839;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
840;;
841;; The load/store queue unit is not attached to the schedulers but
842;; communicates with all the execution units separately instead.
843
844(define_attr "athlon_decode" "direct,vector"
845 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
846 (const_string "vector")
847 (and (eq_attr "type" "push")
848 (match_operand 1 "memory_operand" ""))
849 (const_string "vector")
850 (and (eq_attr "type" "fmov")
851 (and (eq_attr "memory" "load,store")
852 (eq_attr "mode" "XF")))
853 (const_string "vector")]
854 (const_string "direct")))
855
856(define_function_unit "athlon_vectordec" 1 0
857 (and (eq_attr "cpu" "athlon")
858 (eq_attr "athlon_decode" "vector"))
859 1 1)
860
861(define_function_unit "athlon_directdec" 3 0
862 (and (eq_attr "cpu" "athlon")
863 (eq_attr "athlon_decode" "direct"))
864 1 1)
865
866(define_function_unit "athlon_vectordec" 1 0
867 (and (eq_attr "cpu" "athlon")
868 (eq_attr "athlon_decode" "direct"))
869 1 1 [(eq_attr "athlon_decode" "vector")])
870
871(define_function_unit "athlon_ieu" 3 0
872 (and (eq_attr "cpu" "athlon")
873 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
874 1 1)
875
876(define_function_unit "athlon_ieu" 3 0
877 (and (eq_attr "cpu" "athlon")
878 (eq_attr "type" "str"))
879 15 15)
880
881(define_function_unit "athlon_ieu" 3 0
882 (and (eq_attr "cpu" "athlon")
883 (eq_attr "type" "imul"))
884 5 0)
885
886(define_function_unit "athlon_ieu" 3 0
887 (and (eq_attr "cpu" "athlon")
888 (eq_attr "type" "idiv"))
889 42 0)
890
891(define_function_unit "athlon_muldiv" 1 0
892 (and (eq_attr "cpu" "athlon")
893 (eq_attr "type" "imul"))
894 5 0)
895
896(define_function_unit "athlon_muldiv" 1 0
897 (and (eq_attr "cpu" "athlon")
898 (eq_attr "type" "idiv"))
899 42 42)
900
901(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
902 (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
903 (const_string "add")
904 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
905 (const_string "mul")
906 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
907 (const_string "store")
908 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
909 (const_string "any")
910 (and (eq_attr "type" "fmov")
911 (ior (match_operand:SI 1 "register_operand" "")
912 (match_operand 1 "immediate_operand" "")))
913 (const_string "store")
914 (eq_attr "type" "fmov")
915 (const_string "muladd")]
916 (const_string "none")))
917
918;; We use latencies 1 for definitions. This is OK to model colisions
919;; in execution units. The real latencies are modeled in the "fp" pipeline.
920
921;; fsin, fcos: 96-192
922;; fsincos: 107-211
923;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
924(define_function_unit "athlon_fp" 3 0
925 (and (eq_attr "cpu" "athlon")
926 (eq_attr "type" "fpspc"))
927 100 1)
928
929;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
930(define_function_unit "athlon_fp" 3 0
931 (and (eq_attr "cpu" "athlon")
932 (eq_attr "type" "fdiv"))
933 24 1)
934
935(define_function_unit "athlon_fp" 3 0
936 (and (eq_attr "cpu" "athlon")
937 (eq_attr "type" "fop,fop1,fmul,fistp"))
938 4 1)
939
940;; XFmode loads are slow.
941;; XFmode store is slow too (8 cycles), but we don't need to model it, because
942;; there are no dependent instructions.
943
944(define_function_unit "athlon_fp" 3 0
945 (and (eq_attr "cpu" "athlon")
946 (and (eq_attr "type" "fmov")
947 (and (eq_attr "memory" "load")
948 (eq_attr "mode" "XF"))))
949 10 1)
950
951(define_function_unit "athlon_fp" 3 0
952 (and (eq_attr "cpu" "athlon")
953 (eq_attr "type" "fmov,fsgn"))
954 2 1)
955
956;; fcmp and ftst instructions
957(define_function_unit "athlon_fp" 3 0
958 (and (eq_attr "cpu" "athlon")
959 (and (eq_attr "type" "fcmp")
960 (eq_attr "athlon_decode" "direct")))
961 3 1)
962
963;; fcmpi instructions.
964(define_function_unit "athlon_fp" 3 0
965 (and (eq_attr "cpu" "athlon")
966 (and (eq_attr "type" "fcmp")
967 (eq_attr "athlon_decode" "vector")))
968 3 1)
969
970(define_function_unit "athlon_fp" 3 0
971 (and (eq_attr "cpu" "athlon")
972 (eq_attr "type" "fcmov"))
973 7 1)
974
975(define_function_unit "athlon_fp_mul" 1 0
976 (and (eq_attr "cpu" "athlon")
977 (eq_attr "athlon_fpunits" "mul"))
978 1 1)
979
980(define_function_unit "athlon_fp_add" 1 0
981 (and (eq_attr "cpu" "athlon")
982 (eq_attr "athlon_fpunits" "add"))
983 1 1)
984
985(define_function_unit "athlon_fp_muladd" 2 0
986 (and (eq_attr "cpu" "athlon")
987 (eq_attr "athlon_fpunits" "muladd,mul,add"))
988 1 1)
989
990(define_function_unit "athlon_fp_store" 1 0
991 (and (eq_attr "cpu" "athlon")
992 (eq_attr "athlon_fpunits" "store"))
993 1 1)
994
995;; We don't need to model the Address Generation Unit, since we don't model
996;; the re-order buffer yet and thus we never schedule more than three operations
997;; at time. Later we may want to experiment with MD_SCHED macros modeling the
998;; decoders independently on the functional units.
999
1000;(define_function_unit "athlon_agu" 3 0
1001; (and (eq_attr "cpu" "athlon")
1002; (and (eq_attr "memory" "!none")
1003; (eq_attr "athlon_fpunits" "none")))
1004; 1 1)
1005
1006;; Model load unit to avoid too long sequences of loads. We don't need to
1007;; model store queue, since it is hardly going to be bottleneck.
1008
1009(define_function_unit "athlon_load" 2 0
1010 (and (eq_attr "cpu" "athlon")
1011 (eq_attr "memory" "load,both"))
1012 1 1)
1013
1014
1015;; Compare instructions.
1016
1017;; All compare insns have expanders that save the operands away without
1018;; actually generating RTL. The bCOND or sCOND (emitted immediately
1019;; after the cmp) will actually emit the cmpM.
1020
1021(define_expand "cmpdi"
1022 [(set (reg:CC 17)
1023 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1024 (match_operand:DI 1 "x86_64_general_operand" "")))]
1025 ""
1026{
1027 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1028 operands[0] = force_reg (DImode, operands[0]);
1029 ix86_compare_op0 = operands[0];
1030 ix86_compare_op1 = operands[1];
1031 DONE;
1032})
1033
1034(define_expand "cmpsi"
1035 [(set (reg:CC 17)
1036 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1037 (match_operand:SI 1 "general_operand" "")))]
1038 ""
1039{
1040 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1041 operands[0] = force_reg (SImode, operands[0]);
1042 ix86_compare_op0 = operands[0];
1043 ix86_compare_op1 = operands[1];
1044 DONE;
1045})
1046
1047(define_expand "cmphi"
1048 [(set (reg:CC 17)
1049 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
1050 (match_operand:HI 1 "general_operand" "")))]
1051 ""
1052{
1053 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1054 operands[0] = force_reg (HImode, operands[0]);
1055 ix86_compare_op0 = operands[0];
1056 ix86_compare_op1 = operands[1];
1057 DONE;
1058})
1059
1060(define_expand "cmpqi"
1061 [(set (reg:CC 17)
1062 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
1063 (match_operand:QI 1 "general_operand" "")))]
1064 "TARGET_QIMODE_MATH"
1065{
1066 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1067 operands[0] = force_reg (QImode, operands[0]);
1068 ix86_compare_op0 = operands[0];
1069 ix86_compare_op1 = operands[1];
1070 DONE;
1071})
1072
1073(define_insn "cmpdi_ccno_1_rex64"
1074 [(set (reg 17)
1075 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
1076 (match_operand:DI 1 "const0_operand" "n,n")))]
1077 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1078 "@
1079 test{q}\t{%0, %0|%0, %0}
1080 cmp{q}\t{%1, %0|%0, %1}"
1081 [(set_attr "type" "test,icmp")
1082 (set_attr "length_immediate" "0,1")
1083 (set_attr "mode" "DI")])
1084
1085(define_insn "*cmpdi_minus_1_rex64"
1086 [(set (reg 17)
1087 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1088 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1089 (const_int 0)))]
1090 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
1091 "cmp{q}\t{%1, %0|%0, %1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "mode" "DI")])
1094
1095(define_expand "cmpdi_1_rex64"
1096 [(set (reg:CC 17)
1097 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1098 (match_operand:DI 1 "general_operand" "")))]
1099 "TARGET_64BIT"
1100 "")
1101
1102(define_insn "cmpdi_1_insn_rex64"
1103 [(set (reg 17)
1104 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1105 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1106 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1107 "cmp{q}\t{%1, %0|%0, %1}"
1108 [(set_attr "type" "icmp")
1109 (set_attr "mode" "DI")])
1110
1111
1112(define_insn "*cmpsi_ccno_1"
1113 [(set (reg 17)
1114 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1115 (match_operand:SI 1 "const0_operand" "n,n")))]
1116 "ix86_match_ccmode (insn, CCNOmode)"
1117 "@
1118 test{l}\t{%0, %0|%0, %0}
1119 cmp{l}\t{%1, %0|%0, %1}"
1120 [(set_attr "type" "test,icmp")
1121 (set_attr "length_immediate" "0,1")
1122 (set_attr "mode" "SI")])
1123
1124(define_insn "*cmpsi_minus_1"
1125 [(set (reg 17)
1126 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1127 (match_operand:SI 1 "general_operand" "ri,mr"))
1128 (const_int 0)))]
1129 "ix86_match_ccmode (insn, CCGOCmode)"
1130 "cmp{l}\t{%1, %0|%0, %1}"
1131 [(set_attr "type" "icmp")
1132 (set_attr "mode" "SI")])
1133
1134(define_expand "cmpsi_1"
1135 [(set (reg:CC 17)
1136 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1137 (match_operand:SI 1 "general_operand" "ri,mr")))]
1138 ""
1139 "")
1140
1141(define_insn "*cmpsi_1_insn"
1142 [(set (reg 17)
1143 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1144 (match_operand:SI 1 "general_operand" "ri,mr")))]
1145 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1146 && ix86_match_ccmode (insn, CCmode)"
1147 "cmp{l}\t{%1, %0|%0, %1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "SI")])
1150
1151(define_insn "*cmphi_ccno_1"
1152 [(set (reg 17)
1153 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1154 (match_operand:HI 1 "const0_operand" "n,n")))]
1155 "ix86_match_ccmode (insn, CCNOmode)"
1156 "@
1157 test{w}\t{%0, %0|%0, %0}
1158 cmp{w}\t{%1, %0|%0, %1}"
1159 [(set_attr "type" "test,icmp")
1160 (set_attr "length_immediate" "0,1")
1161 (set_attr "mode" "HI")])
1162
1163(define_insn "*cmphi_minus_1"
1164 [(set (reg 17)
1165 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1166 (match_operand:HI 1 "general_operand" "ri,mr"))
1167 (const_int 0)))]
1168 "ix86_match_ccmode (insn, CCGOCmode)"
1169 "cmp{w}\t{%1, %0|%0, %1}"
1170 [(set_attr "type" "icmp")
1171 (set_attr "mode" "HI")])
1172
1173(define_insn "*cmphi_1"
1174 [(set (reg 17)
1175 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1176 (match_operand:HI 1 "general_operand" "ri,mr")))]
1177 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1178 && ix86_match_ccmode (insn, CCmode)"
1179 "cmp{w}\t{%1, %0|%0, %1}"
1180 [(set_attr "type" "icmp")
1181 (set_attr "mode" "HI")])
1182
1183(define_insn "*cmpqi_ccno_1"
1184 [(set (reg 17)
1185 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1186 (match_operand:QI 1 "const0_operand" "n,n")))]
1187 "ix86_match_ccmode (insn, CCNOmode)"
1188 "@
1189 test{b}\t{%0, %0|%0, %0}
1190 cmp{b}\t{$0, %0|%0, 0}"
1191 [(set_attr "type" "test,icmp")
1192 (set_attr "length_immediate" "0,1")
1193 (set_attr "mode" "QI")])
1194
1195(define_insn "*cmpqi_1"
1196 [(set (reg 17)
1197 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1198 (match_operand:QI 1 "general_operand" "qi,mq")))]
1199 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1200 && ix86_match_ccmode (insn, CCmode)"
1201 "cmp{b}\t{%1, %0|%0, %1}"
1202 [(set_attr "type" "icmp")
1203 (set_attr "mode" "QI")])
1204
1205(define_insn "*cmpqi_minus_1"
1206 [(set (reg 17)
1207 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1208 (match_operand:QI 1 "general_operand" "qi,mq"))
1209 (const_int 0)))]
1210 "ix86_match_ccmode (insn, CCGOCmode)"
1211 "cmp{b}\t{%1, %0|%0, %1}"
1212 [(set_attr "type" "icmp")
1213 (set_attr "mode" "QI")])
1214
1215(define_insn "*cmpqi_ext_1"
1216 [(set (reg 17)
1217 (compare
1218 (match_operand:QI 0 "general_operand" "Qm")
1219 (subreg:QI
1220 (zero_extract:SI
1221 (match_operand 1 "ext_register_operand" "Q")
1222 (const_int 8)
1223 (const_int 8)) 0)))]
1224 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1225 "cmp{b}\t{%h1, %0|%0, %h1}"
1226 [(set_attr "type" "icmp")
1227 (set_attr "mode" "QI")])
1228
1229(define_insn "*cmpqi_ext_1_rex64"
1230 [(set (reg 17)
1231 (compare
1232 (match_operand:QI 0 "register_operand" "Q")
1233 (subreg:QI
1234 (zero_extract:SI
1235 (match_operand 1 "ext_register_operand" "Q")
1236 (const_int 8)
1237 (const_int 8)) 0)))]
1238 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1239 "cmp{b}\t{%h1, %0|%0, %h1}"
1240 [(set_attr "type" "icmp")
1241 (set_attr "mode" "QI")])
1242
1243(define_insn "*cmpqi_ext_2"
1244 [(set (reg 17)
1245 (compare
1246 (subreg:QI
1247 (zero_extract:SI
1248 (match_operand 0 "ext_register_operand" "Q")
1249 (const_int 8)
1250 (const_int 8)) 0)
1251 (match_operand:QI 1 "const0_operand" "n")))]
1252 "ix86_match_ccmode (insn, CCNOmode)"
1253 "test{b}\t%h0, %h0"
1254 [(set_attr "type" "test")
1255 (set_attr "length_immediate" "0")
1256 (set_attr "mode" "QI")])
1257
1258(define_expand "cmpqi_ext_3"
1259 [(set (reg:CC 17)
1260 (compare:CC
1261 (subreg:QI
1262 (zero_extract:SI
1263 (match_operand 0 "ext_register_operand" "")
1264 (const_int 8)
1265 (const_int 8)) 0)
1266 (match_operand:QI 1 "general_operand" "")))]
1267 ""
1268 "")
1269
1270(define_insn "cmpqi_ext_3_insn"
1271 [(set (reg 17)
1272 (compare
1273 (subreg:QI
1274 (zero_extract:SI
1275 (match_operand 0 "ext_register_operand" "Q")
1276 (const_int 8)
1277 (const_int 8)) 0)
1278 (match_operand:QI 1 "general_operand" "Qmn")))]
1279 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1280 "cmp{b}\t{%1, %h0|%h0, %1}"
1281 [(set_attr "type" "icmp")
1282 (set_attr "mode" "QI")])
1283
1284(define_insn "cmpqi_ext_3_insn_rex64"
1285 [(set (reg 17)
1286 (compare
1287 (subreg:QI
1288 (zero_extract:SI
1289 (match_operand 0 "ext_register_operand" "Q")
1290 (const_int 8)
1291 (const_int 8)) 0)
1292 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1293 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1294 "cmp{b}\t{%1, %h0|%h0, %1}"
1295 [(set_attr "type" "icmp")
1296 (set_attr "mode" "QI")])
1297
1298(define_insn "*cmpqi_ext_4"
1299 [(set (reg 17)
1300 (compare
1301 (subreg:QI
1302 (zero_extract:SI
1303 (match_operand 0 "ext_register_operand" "Q")
1304 (const_int 8)
1305 (const_int 8)) 0)
1306 (subreg:QI
1307 (zero_extract:SI
1308 (match_operand 1 "ext_register_operand" "Q")
1309 (const_int 8)
1310 (const_int 8)) 0)))]
1311 "ix86_match_ccmode (insn, CCmode)"
1312 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1313 [(set_attr "type" "icmp")
1314 (set_attr "mode" "QI")])
1315
1316;; These implement float point compares.
1317;; %%% See if we can get away with VOIDmode operands on the actual insns,
1318;; which would allow mix and match FP modes on the compares. Which is what
1319;; the old patterns did, but with many more of them.
1320
1321(define_expand "cmpxf"
1322 [(set (reg:CC 17)
1323 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1324 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1325 "!TARGET_64BIT && TARGET_80387"
1326{
1327 ix86_compare_op0 = operands[0];
1328 ix86_compare_op1 = operands[1];
1329 DONE;
1330})
1331
1332(define_expand "cmptf"
1333 [(set (reg:CC 17)
1334 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1335 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1336 "TARGET_80387"
1337{
1338 ix86_compare_op0 = operands[0];
1339 ix86_compare_op1 = operands[1];
1340 DONE;
1341})
1342
1343(define_expand "cmpdf"
1344 [(set (reg:CC 17)
1345 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1346 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1347 "TARGET_80387 || TARGET_SSE2"
1348{
1349 ix86_compare_op0 = operands[0];
1350 ix86_compare_op1 = operands[1];
1351 DONE;
1352})
1353
1354(define_expand "cmpsf"
1355 [(set (reg:CC 17)
1356 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1357 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1358 "TARGET_80387 || TARGET_SSE"
1359{
1360 ix86_compare_op0 = operands[0];
1361 ix86_compare_op1 = operands[1];
1362 DONE;
1363})
1364
1365;; FP compares, step 1:
1366;; Set the FP condition codes.
1367;;
1368;; CCFPmode compare with exceptions
1369;; CCFPUmode compare with no exceptions
1370
1371;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1372;; and that fp moves clobber the condition codes, and that there is
1373;; currently no way to describe this fact to reg-stack. So there are
1374;; no splitters yet for this.
1375
1376;; %%% YIKES! This scheme does not retain a strong connection between
1377;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1378;; work! Only allow tos/mem with tos in op 0.
1379;;
1380;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1381;; things aren't as bad as they sound...
1382
1383(define_insn "*cmpfp_0"
1384 [(set (match_operand:HI 0 "register_operand" "=a")
1385 (unspec:HI
1386 [(compare:CCFP (match_operand 1 "register_operand" "f")
1387 (match_operand 2 "const0_operand" "X"))] 9))]
1388 "TARGET_80387
1389 && FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1391{
1392 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1393 return "ftst\;fnstsw\t%0\;fstp\t%y0";
1394 else
1395 return "ftst\;fnstsw\t%0";
1396}
1397 [(set_attr "type" "multi")
1398 (set_attr "mode" "unknownfp")])
1399
1400;; We may not use "#" to split and emit these, since the REG_DEAD notes
1401;; used to manage the reg stack popping would not be preserved.
1402
1403(define_insn "*cmpfp_2_sf"
1404 [(set (reg:CCFP 18)
1405 (compare:CCFP
1406 (match_operand:SF 0 "register_operand" "f")
1407 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1408 "TARGET_80387"
1409 "* return output_fp_compare (insn, operands, 0, 0);"
1410 [(set_attr "type" "fcmp")
1411 (set_attr "mode" "SF")])
1412
1413(define_insn "*cmpfp_2_sf_1"
1414 [(set (match_operand:HI 0 "register_operand" "=a")
1415 (unspec:HI
1416 [(compare:CCFP
1417 (match_operand:SF 1 "register_operand" "f")
1418 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1419 "TARGET_80387"
1420 "* return output_fp_compare (insn, operands, 2, 0);"
1421 [(set_attr "type" "fcmp")
1422 (set_attr "mode" "SF")])
1423
1424(define_insn "*cmpfp_2_df"
1425 [(set (reg:CCFP 18)
1426 (compare:CCFP
1427 (match_operand:DF 0 "register_operand" "f")
1428 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1429 "TARGET_80387"
1430 "* return output_fp_compare (insn, operands, 0, 0);"
1431 [(set_attr "type" "fcmp")
1432 (set_attr "mode" "DF")])
1433
1434(define_insn "*cmpfp_2_df_1"
1435 [(set (match_operand:HI 0 "register_operand" "=a")
1436 (unspec:HI
1437 [(compare:CCFP
1438 (match_operand:DF 1 "register_operand" "f")
1439 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1440 "TARGET_80387"
1441 "* return output_fp_compare (insn, operands, 2, 0);"
1442 [(set_attr "type" "multi")
1443 (set_attr "mode" "DF")])
1444
1445(define_insn "*cmpfp_2_xf"
1446 [(set (reg:CCFP 18)
1447 (compare:CCFP
1448 (match_operand:XF 0 "register_operand" "f")
1449 (match_operand:XF 1 "register_operand" "f")))]
1450 "!TARGET_64BIT && TARGET_80387"
1451 "* return output_fp_compare (insn, operands, 0, 0);"
1452 [(set_attr "type" "fcmp")
1453 (set_attr "mode" "XF")])
1454
1455(define_insn "*cmpfp_2_tf"
1456 [(set (reg:CCFP 18)
1457 (compare:CCFP
1458 (match_operand:TF 0 "register_operand" "f")
1459 (match_operand:TF 1 "register_operand" "f")))]
1460 "TARGET_80387"
1461 "* return output_fp_compare (insn, operands, 0, 0);"
1462 [(set_attr "type" "fcmp")
1463 (set_attr "mode" "XF")])
1464
1465(define_insn "*cmpfp_2_xf_1"
1466 [(set (match_operand:HI 0 "register_operand" "=a")
1467 (unspec:HI
1468 [(compare:CCFP
1469 (match_operand:XF 1 "register_operand" "f")
1470 (match_operand:XF 2 "register_operand" "f"))] 9))]
1471 "!TARGET_64BIT && TARGET_80387"
1472 "* return output_fp_compare (insn, operands, 2, 0);"
1473 [(set_attr "type" "multi")
1474 (set_attr "mode" "XF")])
1475
1476(define_insn "*cmpfp_2_tf_1"
1477 [(set (match_operand:HI 0 "register_operand" "=a")
1478 (unspec:HI
1479 [(compare:CCFP
1480 (match_operand:TF 1 "register_operand" "f")
1481 (match_operand:TF 2 "register_operand" "f"))] 9))]
1482 "TARGET_80387"
1483 "* return output_fp_compare (insn, operands, 2, 0);"
1484 [(set_attr "type" "multi")
1485 (set_attr "mode" "XF")])
1486
1487(define_insn "*cmpfp_2u"
1488 [(set (reg:CCFPU 18)
1489 (compare:CCFPU
1490 (match_operand 0 "register_operand" "f")
1491 (match_operand 1 "register_operand" "f")))]
1492 "TARGET_80387
1493 && FLOAT_MODE_P (GET_MODE (operands[0]))
1494 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495 "* return output_fp_compare (insn, operands, 0, 1);"
1496 [(set_attr "type" "fcmp")
1497 (set_attr "mode" "unknownfp")])
1498
1499(define_insn "*cmpfp_2u_1"
1500 [(set (match_operand:HI 0 "register_operand" "=a")
1501 (unspec:HI
1502 [(compare:CCFPU
1503 (match_operand 1 "register_operand" "f")
1504 (match_operand 2 "register_operand" "f"))] 9))]
1505 "TARGET_80387
1506 && FLOAT_MODE_P (GET_MODE (operands[1]))
1507 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1508 "* return output_fp_compare (insn, operands, 2, 1);"
1509 [(set_attr "type" "multi")
1510 (set_attr "mode" "unknownfp")])
1511
1512;; Patterns to match the SImode-in-memory ficom instructions.
1513;;
1514;; %%% Play games with accepting gp registers, as otherwise we have to
1515;; force them to memory during rtl generation, which is no good. We
1516;; can get rid of this once we teach reload to do memory input reloads
1517;; via pushes.
1518
1519(define_insn "*ficom_1"
1520 [(set (reg:CCFP 18)
1521 (compare:CCFP
1522 (match_operand 0 "register_operand" "f,f")
1523 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1524 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1525 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1526 "#")
1527
1528;; Split the not-really-implemented gp register case into a
1529;; push-op-pop sequence.
1530;;
1531;; %%% This is most efficient, but am I gonna get in trouble
1532;; for separating cc0_setter and cc0_user?
1533
1534(define_split
1535 [(set (reg:CCFP 18)
1536 (compare:CCFP
1537 (match_operand:SF 0 "register_operand" "")
1538 (float (match_operand:SI 1 "register_operand" ""))))]
1539 "0 && TARGET_80387 && reload_completed"
1540 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1541 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1542 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1543 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1544 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1545 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1546
1547;; FP compares, step 2
1548;; Move the fpsw to ax.
1549
1550(define_insn "x86_fnstsw_1"
1551 [(set (match_operand:HI 0 "register_operand" "=a")
1552 (unspec:HI [(reg 18)] 9))]
1553 "TARGET_80387"
1554 "fnstsw\t%0"
1555 [(set_attr "length" "2")
1556 (set_attr "mode" "SI")
1557 (set_attr "i387" "1")
1558 (set_attr "ppro_uops" "few")])
1559
1560;; FP compares, step 3
1561;; Get ax into flags, general case.
1562
1563(define_insn "x86_sahf_1"
1564 [(set (reg:CC 17)
1565 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1566 "!TARGET_64BIT"
1567 "sahf"
1568 [(set_attr "length" "1")
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "mode" "SI")
1571 (set_attr "ppro_uops" "one")])
1572
1573;; Pentium Pro can do steps 1 through 3 in one go.
1574
1575(define_insn "*cmpfp_i"
1576 [(set (reg:CCFP 17)
1577 (compare:CCFP (match_operand 0 "register_operand" "f")
1578 (match_operand 1 "register_operand" "f")))]
1579 "TARGET_80387 && TARGET_CMOVE
1580 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && FLOAT_MODE_P (GET_MODE (operands[0]))
1582 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1583 "* return output_fp_compare (insn, operands, 1, 0);"
1584 [(set_attr "type" "fcmp")
1585 (set_attr "mode" "unknownfp")
1586 (set_attr "athlon_decode" "vector")])
1587
1588(define_insn "*cmpfp_i_sse"
1589 [(set (reg:CCFP 17)
1590 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1591 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1592 "TARGET_80387
1593 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1594 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1595 "* return output_fp_compare (insn, operands, 1, 0);"
1596 [(set_attr "type" "fcmp,sse")
1597 (set_attr "mode" "unknownfp")
1598 (set_attr "athlon_decode" "vector")])
1599
1600(define_insn "*cmpfp_i_sse_only"
1601 [(set (reg:CCFP 17)
1602 (compare:CCFP (match_operand 0 "register_operand" "x")
1603 (match_operand 1 "nonimmediate_operand" "xm")))]
1604 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1605 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1606 "* return output_fp_compare (insn, operands, 1, 0);"
1607 [(set_attr "type" "sse")
1608 (set_attr "mode" "unknownfp")
1609 (set_attr "athlon_decode" "vector")])
1610
1611(define_insn "*cmpfp_iu"
1612 [(set (reg:CCFPU 17)
1613 (compare:CCFPU (match_operand 0 "register_operand" "f")
1614 (match_operand 1 "register_operand" "f")))]
1615 "TARGET_80387 && TARGET_CMOVE
1616 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1617 && FLOAT_MODE_P (GET_MODE (operands[0]))
1618 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1619 "* return output_fp_compare (insn, operands, 1, 1);"
1620 [(set_attr "type" "fcmp")
1621 (set_attr "mode" "unknownfp")
1622 (set_attr "athlon_decode" "vector")])
1623
1624(define_insn "*cmpfp_iu_sse"
1625 [(set (reg:CCFPU 17)
1626 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1627 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1628 "TARGET_80387
1629 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1630 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1631 "* return output_fp_compare (insn, operands, 1, 1);"
1632 [(set_attr "type" "fcmp,sse")
1633 (set_attr "mode" "unknownfp")
1634 (set_attr "athlon_decode" "vector")])
1635
1636(define_insn "*cmpfp_iu_sse_only"
1637 [(set (reg:CCFPU 17)
1638 (compare:CCFPU (match_operand 0 "register_operand" "x")
1639 (match_operand 1 "nonimmediate_operand" "xm")))]
1640 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1641 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1642 "* return output_fp_compare (insn, operands, 1, 1);"
1643 [(set_attr "type" "sse")
1644 (set_attr "mode" "unknownfp")
1645 (set_attr "athlon_decode" "vector")])
1646
1647;; Move instructions.
1648
1649;; General case of fullword move.
1650
1651(define_expand "movsi"
1652 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1653 (match_operand:SI 1 "general_operand" ""))]
1654 ""
1655 "ix86_expand_move (SImode, operands); DONE;")
1656
1657;; Push/pop instructions. They are separate since autoinc/dec is not a
1658;; general_operand.
1659;;
1660;; %%% We don't use a post-inc memory reference because x86 is not a
1661;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1662;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1663;; targets without our curiosities, and it is just as easy to represent
1664;; this differently.
1665
1666(define_insn "*pushsi2"
1667 [(set (match_operand:SI 0 "push_operand" "=<")
1668 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1669 "!TARGET_64BIT"
1670 "push{l}\t%1"
1671 [(set_attr "type" "push")
1672 (set_attr "mode" "SI")])
1673
1674;; For 64BIT abi we always round up to 8 bytes.
1675(define_insn "*pushsi2_rex64"
1676 [(set (match_operand:SI 0 "push_operand" "=X")
1677 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1678 "TARGET_64BIT"
1679 "push{q}\t%q1"
1680 [(set_attr "type" "push")
1681 (set_attr "mode" "SI")])
1682
1683(define_insn "*pushsi2_prologue"
1684 [(set (match_operand:SI 0 "push_operand" "=<")
1685 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1686 (clobber (mem:BLK (scratch)))]
1687 "!TARGET_64BIT"
1688 "push{l}\t%1"
1689 [(set_attr "type" "push")
1690 (set_attr "mode" "SI")])
1691
1692(define_insn "*popsi1_epilogue"
1693 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1694 (mem:SI (reg:SI 7)))
1695 (set (reg:SI 7)
1696 (plus:SI (reg:SI 7) (const_int 4)))
1697 (clobber (mem:BLK (scratch)))]
1698 "!TARGET_64BIT"
1699 "pop{l}\t%0"
1700 [(set_attr "type" "pop")
1701 (set_attr "mode" "SI")])
1702
1703(define_insn "popsi1"
1704 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1705 (mem:SI (reg:SI 7)))
1706 (set (reg:SI 7)
1707 (plus:SI (reg:SI 7) (const_int 4)))]
1708 "!TARGET_64BIT"
1709 "pop{l}\t%0"
1710 [(set_attr "type" "pop")
1711 (set_attr "mode" "SI")])
1712
1713(define_insn "*movsi_xor"
1714 [(set (match_operand:SI 0 "register_operand" "=r")
1715 (match_operand:SI 1 "const0_operand" "i"))
1716 (clobber (reg:CC 17))]
1717 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1718 "xor{l}\t{%0, %0|%0, %0}"
1719 [(set_attr "type" "alu1")
1720 (set_attr "mode" "SI")
1721 (set_attr "length_immediate" "0")])
1722
1723(define_insn "*movsi_or"
1724 [(set (match_operand:SI 0 "register_operand" "=r")
1725 (match_operand:SI 1 "immediate_operand" "i"))
1726 (clobber (reg:CC 17))]
1727 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1728 && INTVAL (operands[1]) == -1
1729 && (TARGET_PENTIUM || optimize_size)"
1730{
1731 operands[1] = constm1_rtx;
1732 return "or{l}\t{%1, %0|%0, %1}";
1733}
1734 [(set_attr "type" "alu1")
1735 (set_attr "mode" "SI")
1736 (set_attr "length_immediate" "1")])
1737
117
118;; A basic instruction type. Refinements due to arguments to be
119;; provided in other attributes.
120(define_attr "type"
121 "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
122 (const_string "other"))
123
124;; Main data type used by the insn
125(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
126 (const_string "unknown"))
127
128;; Set for i387 operations.
129(define_attr "i387" ""
130 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
131 (const_int 1)
132 (const_int 0)))
133
134;; The (bounding maximum) length of an instruction immediate.
135(define_attr "length_immediate" ""
136 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
137 (const_int 0)
138 (eq_attr "i387" "1")
139 (const_int 0)
140 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
141 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
142 (eq_attr "type" "imov,test")
143 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
144 (eq_attr "type" "call")
145 (if_then_else (match_operand 0 "constant_call_address_operand" "")
146 (const_int 4)
147 (const_int 0))
148 (eq_attr "type" "callv")
149 (if_then_else (match_operand 1 "constant_call_address_operand" "")
150 (const_int 4)
151 (const_int 0))
152 (eq_attr "type" "ibr")
153 (if_then_else (and (ge (minus (match_dup 0) (pc))
154 (const_int -128))
155 (lt (minus (match_dup 0) (pc))
156 (const_int 124)))
157 (const_int 1)
158 (const_int 4))
159 ]
160 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
161
162;; The (bounding maximum) length of an instruction address.
163(define_attr "length_address" ""
164 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
165 (const_int 0)
166 (and (eq_attr "type" "call")
167 (match_operand 1 "constant_call_address_operand" ""))
168 (const_int 0)
169 (and (eq_attr "type" "callv")
170 (match_operand 1 "constant_call_address_operand" ""))
171 (const_int 0)
172 ]
173 (symbol_ref "ix86_attr_length_address_default (insn)")))
174
175;; Set when length prefix is used.
176(define_attr "prefix_data16" ""
177 (if_then_else (eq_attr "mode" "HI")
178 (const_int 1)
179 (const_int 0)))
180
181;; Set when string REP prefix is used.
182(define_attr "prefix_rep" "" (const_int 0))
183
184;; Set when 0f opcode prefix is used.
185(define_attr "prefix_0f" ""
186 (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
187 (const_int 1)
188 (const_int 0)))
189
190;; Set when modrm byte is used.
191(define_attr "modrm" ""
192 (cond [(eq_attr "type" "str,cld")
193 (const_int 0)
194 (eq_attr "i387" "1")
195 (const_int 0)
196 (and (eq_attr "type" "incdec")
197 (ior (match_operand:SI 1 "register_operand" "")
198 (match_operand:HI 1 "register_operand" "")))
199 (const_int 0)
200 (and (eq_attr "type" "push")
201 (not (match_operand 1 "memory_operand" "")))
202 (const_int 0)
203 (and (eq_attr "type" "pop")
204 (not (match_operand 0 "memory_operand" "")))
205 (const_int 0)
206 (and (eq_attr "type" "imov")
207 (and (match_operand 0 "register_operand" "")
208 (match_operand 1 "immediate_operand" "")))
209 (const_int 0)
210 ]
211 (const_int 1)))
212
213;; The (bounding maximum) length of an instruction in bytes.
214;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
215;; to split it and compute proper length as for other insns.
216(define_attr "length" ""
217 (cond [(eq_attr "type" "other,multi,fistp")
218 (const_int 16)
219 ]
220 (plus (plus (attr "modrm")
221 (plus (attr "prefix_0f")
222 (plus (attr "i387")
223 (const_int 1))))
224 (plus (attr "prefix_rep")
225 (plus (attr "prefix_data16")
226 (plus (attr "length_immediate")
227 (attr "length_address")))))))
228
229;; The `memory' attribute is `none' if no memory is referenced, `load' or
230;; `store' if there is a simple memory reference therein, or `unknown'
231;; if the instruction is complex.
232
233(define_attr "memory" "none,load,store,both,unknown"
234 (cond [(eq_attr "type" "other,multi,str")
235 (const_string "unknown")
236 (eq_attr "type" "lea,fcmov,fpspc,cld")
237 (const_string "none")
238 (eq_attr "type" "fistp")
239 (const_string "both")
240 (eq_attr "type" "push")
241 (if_then_else (match_operand 1 "memory_operand" "")
242 (const_string "both")
243 (const_string "store"))
244 (eq_attr "type" "pop,setcc")
245 (if_then_else (match_operand 0 "memory_operand" "")
246 (const_string "both")
247 (const_string "load"))
248 (eq_attr "type" "icmp,test")
249 (if_then_else (ior (match_operand 0 "memory_operand" "")
250 (match_operand 1 "memory_operand" ""))
251 (const_string "load")
252 (const_string "none"))
253 (eq_attr "type" "ibr")
254 (if_then_else (match_operand 0 "memory_operand" "")
255 (const_string "load")
256 (const_string "none"))
257 (eq_attr "type" "call")
258 (if_then_else (match_operand 0 "constant_call_address_operand" "")
259 (const_string "none")
260 (const_string "load"))
261 (eq_attr "type" "callv")
262 (if_then_else (match_operand 1 "constant_call_address_operand" "")
263 (const_string "none")
264 (const_string "load"))
265 (and (eq_attr "type" "alu1,negnot")
266 (match_operand 1 "memory_operand" ""))
267 (const_string "both")
268 (and (match_operand 0 "memory_operand" "")
269 (match_operand 1 "memory_operand" ""))
270 (const_string "both")
271 (match_operand 0 "memory_operand" "")
272 (const_string "store")
273 (match_operand 1 "memory_operand" "")
274 (const_string "load")
275 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
276 (match_operand 2 "memory_operand" ""))
277 (const_string "load")
278 (and (eq_attr "type" "icmov")
279 (match_operand 3 "memory_operand" ""))
280 (const_string "load")
281 ]
282 (const_string "none")))
283
284;; Indicates if an instruction has both an immediate and a displacement.
285
286(define_attr "imm_disp" "false,true,unknown"
287 (cond [(eq_attr "type" "other,multi")
288 (const_string "unknown")
289 (and (eq_attr "type" "icmp,test,imov")
290 (and (match_operand 0 "memory_displacement_operand" "")
291 (match_operand 1 "immediate_operand" "")))
292 (const_string "true")
293 (and (eq_attr "type" "alu,ishift,imul,idiv")
294 (and (match_operand 0 "memory_displacement_operand" "")
295 (match_operand 2 "immediate_operand" "")))
296 (const_string "true")
297 ]
298 (const_string "false")))
299
300;; Indicates if an FP operation has an integer source.
301
302(define_attr "fp_int_src" "false,true"
303 (const_string "false"))
304
305;; Describe a user's asm statement.
306(define_asm_attributes
307 [(set_attr "length" "128")
308 (set_attr "type" "multi")])
309
310;; Pentium Scheduling
311;;
312;; The Pentium is an in-order core with two integer pipelines.
313
314;; True for insns that behave like prefixed insns on the Pentium.
315(define_attr "pent_prefix" "false,true"
316 (if_then_else (ior (eq_attr "prefix_0f" "1")
317 (ior (eq_attr "prefix_data16" "1")
318 (eq_attr "prefix_rep" "1")))
319 (const_string "true")
320 (const_string "false")))
321
322;; Categorize how an instruction slots.
323
324;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
325;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
326;; rules, because it results in noticeably better code on non-MMX Pentium
327;; and doesn't hurt much on MMX. (Prefixed instructions are not very
328;; common, so the scheduler usualy has a non-prefixed insn to pair).
329
330(define_attr "pent_pair" "uv,pu,pv,np"
331 (cond [(eq_attr "imm_disp" "true")
332 (const_string "np")
333 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
334 (and (eq_attr "type" "pop,push")
335 (eq_attr "memory" "!both")))
336 (if_then_else (eq_attr "pent_prefix" "true")
337 (const_string "pu")
338 (const_string "uv"))
339 (eq_attr "type" "ibr")
340 (const_string "pv")
341 (and (eq_attr "type" "ishift")
342 (match_operand 2 "const_int_operand" ""))
343 (const_string "pu")
344 (and (eq_attr "type" "call")
345 (match_operand 0 "constant_call_address_operand" ""))
346 (const_string "pv")
347 (and (eq_attr "type" "callv")
348 (match_operand 1 "constant_call_address_operand" ""))
349 (const_string "pv")
350 ]
351 (const_string "np")))
352
353;; Rough readiness numbers. Fine tuning happens in i386.c.
354;;
355;; u describes pipe U
356;; v describes pipe V
357;; uv describes either pipe U or V for those that can issue to either
358;; np describes not paring
359;; fpu describes fpu
360;; fpm describes fp insns of different types are not pipelined.
361;;
362;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
363
364(define_function_unit "pent_np" 1 0
365 (and (eq_attr "cpu" "pentium")
366 (eq_attr "type" "imul"))
367 11 11)
368
369(define_function_unit "pent_mul" 1 1
370 (and (eq_attr "cpu" "pentium")
371 (eq_attr "type" "imul"))
372 11 11)
373
374;; Rep movs takes minimally 12 cycles.
375(define_function_unit "pent_np" 1 0
376 (and (eq_attr "cpu" "pentium")
377 (eq_attr "type" "str"))
378 12 12)
379
380; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
381(define_function_unit "pent_np" 1 0
382 (and (eq_attr "cpu" "pentium")
383 (eq_attr "type" "idiv"))
384 46 46)
385
386; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
387; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
388; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
389; The integer <-> fp conversion is not modeled correctly. Fild behaves
390; like normal fp operation and fist takes 6 cycles.
391
392(define_function_unit "fpu" 1 0
393 (and (eq_attr "cpu" "pentium")
394 (and (eq_attr "type" "fmov")
395 (and (eq_attr "memory" "load,store")
396 (eq_attr "mode" "XF"))))
397 3 3)
398
399(define_function_unit "pent_np" 1 0
400 (and (eq_attr "cpu" "pentium")
401 (and (eq_attr "type" "fmov")
402 (and (eq_attr "memory" "load,store")
403 (eq_attr "mode" "XF"))))
404 3 3)
405
406(define_function_unit "fpu" 1 0
407 (and (eq_attr "cpu" "pentium")
408 (and (eq_attr "type" "fmov")
409 (ior (match_operand 1 "immediate_operand" "")
410 (eq_attr "memory" "store"))))
411 2 2)
412
413(define_function_unit "pent_np" 1 0
414 (and (eq_attr "cpu" "pentium")
415 (and (eq_attr "type" "fmov")
416 (ior (match_operand 1 "immediate_operand" "")
417 (eq_attr "memory" "store"))))
418 2 2)
419
420(define_function_unit "pent_np" 1 0
421 (and (eq_attr "cpu" "pentium")
422 (eq_attr "type" "cld"))
423 2 2)
424
425(define_function_unit "fpu" 1 0
426 (and (eq_attr "cpu" "pentium")
427 (and (eq_attr "type" "fmov")
428 (eq_attr "memory" "none,load")))
429 1 1)
430
431; Read/Modify/Write instructions usually take 3 cycles.
432(define_function_unit "pent_u" 1 0
433 (and (eq_attr "cpu" "pentium")
434 (and (eq_attr "type" "alu,alu1,ishift")
435 (and (eq_attr "pent_pair" "pu")
436 (eq_attr "memory" "both"))))
437 3 3)
438
439(define_function_unit "pent_uv" 2 0
440 (and (eq_attr "cpu" "pentium")
441 (and (eq_attr "type" "alu,alu1,ishift")
442 (and (eq_attr "pent_pair" "!np")
443 (eq_attr "memory" "both"))))
444 3 3)
445
446(define_function_unit "pent_np" 1 0
447 (and (eq_attr "cpu" "pentium")
448 (and (eq_attr "type" "alu,alu1,negnot,ishift")
449 (and (eq_attr "pent_pair" "np")
450 (eq_attr "memory" "both"))))
451 3 3)
452
453; Read/Modify or Modify/Write instructions usually take 2 cycles.
454(define_function_unit "pent_u" 1 0
455 (and (eq_attr "cpu" "pentium")
456 (and (eq_attr "type" "alu,ishift")
457 (and (eq_attr "pent_pair" "pu")
458 (eq_attr "memory" "load,store"))))
459 2 2)
460
461(define_function_unit "pent_uv" 2 0
462 (and (eq_attr "cpu" "pentium")
463 (and (eq_attr "type" "alu,ishift")
464 (and (eq_attr "pent_pair" "!np")
465 (eq_attr "memory" "load,store"))))
466 2 2)
467
468(define_function_unit "pent_np" 1 0
469 (and (eq_attr "cpu" "pentium")
470 (and (eq_attr "type" "alu,ishift")
471 (and (eq_attr "pent_pair" "np")
472 (eq_attr "memory" "load,store"))))
473 2 2)
474
475; Insns w/o memory operands and move instructions usually take one cycle.
476(define_function_unit "pent_u" 1 0
477 (and (eq_attr "cpu" "pentium")
478 (eq_attr "pent_pair" "pu"))
479 1 1)
480
481(define_function_unit "pent_v" 1 0
482 (and (eq_attr "cpu" "pentium")
483 (eq_attr "pent_pair" "pv"))
484 1 1)
485
486(define_function_unit "pent_uv" 2 0
487 (and (eq_attr "cpu" "pentium")
488 (eq_attr "pent_pair" "!np"))
489 1 1)
490
491(define_function_unit "pent_np" 1 0
492 (and (eq_attr "cpu" "pentium")
493 (eq_attr "pent_pair" "np"))
494 1 1)
495
496; Pairable insns only conflict with other non-pairable insns.
497(define_function_unit "pent_np" 1 0
498 (and (eq_attr "cpu" "pentium")
499 (and (eq_attr "type" "alu,alu1,ishift")
500 (and (eq_attr "pent_pair" "!np")
501 (eq_attr "memory" "both"))))
502 3 3
503 [(eq_attr "pent_pair" "np")])
504
505(define_function_unit "pent_np" 1 0
506 (and (eq_attr "cpu" "pentium")
507 (and (eq_attr "type" "alu,alu1,ishift")
508 (and (eq_attr "pent_pair" "!np")
509 (eq_attr "memory" "load,store"))))
510 2 2
511 [(eq_attr "pent_pair" "np")])
512
513(define_function_unit "pent_np" 1 0
514 (and (eq_attr "cpu" "pentium")
515 (eq_attr "pent_pair" "!np"))
516 1 1
517 [(eq_attr "pent_pair" "np")])
518
519; Floating point instructions usually blocks cycle longer when combined with
520; integer instructions, because of the inpaired fxch instruction.
521(define_function_unit "pent_np" 1 0
522 (and (eq_attr "cpu" "pentium")
523 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
524 2 2
525 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
526
527(define_function_unit "fpu" 1 0
528 (and (eq_attr "cpu" "pentium")
529 (eq_attr "type" "fcmp,fxch,fsgn"))
530 1 1)
531
532; Addition takes 3 cycles; assume other random cruft does as well.
533; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
534(define_function_unit "fpu" 1 0
535 (and (eq_attr "cpu" "pentium")
536 (eq_attr "type" "fop,fop1,fistp"))
537 3 1)
538
539; Multiplication takes 3 cycles and is only half pipelined.
540(define_function_unit "fpu" 1 0
541 (and (eq_attr "cpu" "pentium")
542 (eq_attr "type" "fmul"))
543 3 1)
544
545(define_function_unit "pent_mul" 1 1
546 (and (eq_attr "cpu" "pentium")
547 (eq_attr "type" "fmul"))
548 2 2)
549
550; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
551; They can overlap with integer insns. Only the last two cycles can overlap
552; with other fp insns. Only fsin/fcos can overlap with multiplies.
553; Only last two cycles of fsin/fcos can overlap with other instructions.
554(define_function_unit "fpu" 1 0
555 (and (eq_attr "cpu" "pentium")
556 (eq_attr "type" "fdiv"))
557 39 37)
558
559(define_function_unit "pent_mul" 1 1
560 (and (eq_attr "cpu" "pentium")
561 (eq_attr "type" "fdiv"))
562 39 39)
563
564(define_function_unit "fpu" 1 0
565 (and (eq_attr "cpu" "pentium")
566 (eq_attr "type" "fpspc"))
567 70 68)
568
569(define_function_unit "pent_mul" 1 1
570 (and (eq_attr "cpu" "pentium")
571 (eq_attr "type" "fpspc"))
572 70 70)
573
574;; Pentium Pro/PII Scheduling
575;;
576;; The PPro has an out-of-order core, but the instruction decoders are
577;; naturally in-order and asymmetric. We get best performance by scheduling
578;; for the decoders, for in doing so we give the oo execution unit the
579;; most choices.
580
581;; Categorize how many uops an ia32 instruction evaluates to:
582;; one -- an instruction with 1 uop can be decoded by any of the
583;; three decoders.
584;; few -- an instruction with 1 to 4 uops can be decoded only by
585;; decoder 0.
586;; many -- a complex instruction may take an unspecified number of
587;; cycles to decode in decoder 0.
588
589(define_attr "ppro_uops" "one,few,many"
590 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
591 (const_string "many")
592 (eq_attr "type" "icmov,fcmov,str,cld")
593 (const_string "few")
594 (eq_attr "type" "imov")
595 (if_then_else (eq_attr "memory" "store,both")
596 (const_string "few")
597 (const_string "one"))
598 (eq_attr "memory" "!none")
599 (const_string "few")
600 ]
601 (const_string "one")))
602
603;; Rough readiness numbers. Fine tuning happens in i386.c.
604;;
605;; p0 describes port 0.
606;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
607;; p2 describes port 2 for loads.
608;; p34 describes ports 3 and 4 for stores.
609;; fpu describes the fpu accessed via port 0.
610;; ??? It is less than clear if there are separate fadd and fmul units
611;; that could operate in parallel.
612;;
613;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
614
615(define_function_unit "ppro_p0" 1 0
616 (and (eq_attr "cpu" "pentiumpro")
617 (eq_attr "type" "ishift,lea,ibr,cld"))
618 1 1)
619
620(define_function_unit "ppro_p0" 1 0
621 (and (eq_attr "cpu" "pentiumpro")
622 (eq_attr "type" "imul"))
623 4 1)
624
625;; ??? Does the divider lock out the pipe while it works,
626;; or is there a disconnected unit?
627(define_function_unit "ppro_p0" 1 0
628 (and (eq_attr "cpu" "pentiumpro")
629 (eq_attr "type" "idiv"))
630 17 17)
631
632(define_function_unit "ppro_p0" 1 0
633 (and (eq_attr "cpu" "pentiumpro")
634 (eq_attr "type" "fop,fop1,fsgn,fistp"))
635 3 1)
636
637(define_function_unit "ppro_p0" 1 0
638 (and (eq_attr "cpu" "pentiumpro")
639 (eq_attr "type" "fcmov"))
640 2 1)
641
642(define_function_unit "ppro_p0" 1 0
643 (and (eq_attr "cpu" "pentiumpro")
644 (eq_attr "type" "fcmp"))
645 1 1)
646
647(define_function_unit "ppro_p0" 1 0
648 (and (eq_attr "cpu" "pentiumpro")
649 (eq_attr "type" "fmov"))
650 1 1)
651
652(define_function_unit "ppro_p0" 1 0
653 (and (eq_attr "cpu" "pentiumpro")
654 (eq_attr "type" "fmul"))
655 5 1)
656
657(define_function_unit "ppro_p0" 1 0
658 (and (eq_attr "cpu" "pentiumpro")
659 (eq_attr "type" "fdiv,fpspc"))
660 56 1)
661
662(define_function_unit "ppro_p01" 2 0
663 (and (eq_attr "cpu" "pentiumpro")
664 (eq_attr "type" "!imov,fmov"))
665 1 1)
666
667(define_function_unit "ppro_p01" 2 0
668 (and (and (eq_attr "cpu" "pentiumpro")
669 (eq_attr "type" "imov,fmov"))
670 (eq_attr "memory" "none"))
671 1 1)
672
673(define_function_unit "ppro_p2" 1 0
674 (and (eq_attr "cpu" "pentiumpro")
675 (ior (eq_attr "type" "pop")
676 (eq_attr "memory" "load,both")))
677 3 1)
678
679(define_function_unit "ppro_p34" 1 0
680 (and (eq_attr "cpu" "pentiumpro")
681 (ior (eq_attr "type" "push")
682 (eq_attr "memory" "store,both")))
683 1 1)
684
685(define_function_unit "fpu" 1 0
686 (and (eq_attr "cpu" "pentiumpro")
687 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
688 1 1)
689
690(define_function_unit "fpu" 1 0
691 (and (eq_attr "cpu" "pentiumpro")
692 (eq_attr "type" "fmul"))
693 5 2)
694
695(define_function_unit "fpu" 1 0
696 (and (eq_attr "cpu" "pentiumpro")
697 (eq_attr "type" "fdiv,fpspc"))
698 56 56)
699
700;; imul uses the fpu. ??? does it have the same throughput as fmul?
701(define_function_unit "fpu" 1 0
702 (and (eq_attr "cpu" "pentiumpro")
703 (eq_attr "type" "imul"))
704 4 1)
705
706;; AMD K6/K6-2 Scheduling
707;;
708;; The K6 has similar architecture to PPro. Important difference is, that
709;; there are only two decoders and they seems to be much slower than execution
710;; units. So we have to pay much more attention to proper decoding for
711;; schedulers. We share most of scheduler code for PPro in i386.c
712;;
713;; The fp unit is not pipelined and do one operation per two cycles including
714;; the FXCH.
715;;
716;; alu describes both ALU units (ALU-X and ALU-Y).
717;; alux describes X alu unit
718;; fpu describes FPU unit
719;; load describes load unit.
720;; branch describes branch unit.
721;; store decsribes store unit. This unit is not modelled completely and only
722;; used to model lea operation. Otherwise it lie outside of the critical
723;; path.
724;;
725;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
726
727;; The decoder specification is in the PPro section above!
728
729;; Shift instructions and certain arithmetic are issued only to X pipe.
730(define_function_unit "k6_alux" 1 0
731 (and (eq_attr "cpu" "k6")
732 (eq_attr "type" "ishift,alu1,negnot,cld"))
733 1 1)
734
735;; The QI mode arithmetic is issued to X pipe only.
736(define_function_unit "k6_alux" 1 0
737 (and (eq_attr "cpu" "k6")
738 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
739 (match_operand:QI 0 "general_operand" "")))
740 1 1)
741
742(define_function_unit "k6_alu" 2 0
743 (and (eq_attr "cpu" "k6")
744 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
745 1 1)
746
747(define_function_unit "k6_alu" 2 0
748 (and (eq_attr "cpu" "k6")
749 (and (eq_attr "type" "imov")
750 (eq_attr "memory" "none")))
751 1 1)
752
753(define_function_unit "k6_branch" 1 0
754 (and (eq_attr "cpu" "k6")
755 (eq_attr "type" "call,callv,ibr"))
756 1 1)
757
758;; Load unit have two cycle latency, but we take care for it in adjust_cost
759(define_function_unit "k6_load" 1 0
760 (and (eq_attr "cpu" "k6")
761 (ior (eq_attr "type" "pop")
762 (eq_attr "memory" "load,both")))
763 1 1)
764
765(define_function_unit "k6_load" 1 0
766 (and (eq_attr "cpu" "k6")
767 (and (eq_attr "type" "str")
768 (eq_attr "memory" "load,both")))
769 10 10)
770
771;; Lea have two instructions, so latency is probably 2
772(define_function_unit "k6_store" 1 0
773 (and (eq_attr "cpu" "k6")
774 (eq_attr "type" "lea"))
775 2 1)
776
777(define_function_unit "k6_store" 1 0
778 (and (eq_attr "cpu" "k6")
779 (eq_attr "type" "str"))
780 10 10)
781
782(define_function_unit "k6_store" 1 0
783 (and (eq_attr "cpu" "k6")
784 (ior (eq_attr "type" "push")
785 (eq_attr "memory" "store,both")))
786 1 1)
787
788(define_function_unit "k6_fpu" 1 1
789 (and (eq_attr "cpu" "k6")
790 (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
791 2 2)
792
793(define_function_unit "k6_fpu" 1 1
794 (and (eq_attr "cpu" "k6")
795 (eq_attr "type" "fmul"))
796 2 2)
797
798;; ??? Guess
799(define_function_unit "k6_fpu" 1 1
800 (and (eq_attr "cpu" "k6")
801 (eq_attr "type" "fdiv,fpspc"))
802 56 56)
803
804(define_function_unit "k6_alu" 2 0
805 (and (eq_attr "cpu" "k6")
806 (eq_attr "type" "imul"))
807 2 2)
808
809(define_function_unit "k6_alux" 1 0
810 (and (eq_attr "cpu" "k6")
811 (eq_attr "type" "imul"))
812 2 2)
813
814;; ??? Guess
815(define_function_unit "k6_alu" 2 0
816 (and (eq_attr "cpu" "k6")
817 (eq_attr "type" "idiv"))
818 17 17)
819
820(define_function_unit "k6_alux" 1 0
821 (and (eq_attr "cpu" "k6")
822 (eq_attr "type" "idiv"))
823 17 17)
824
825;; AMD Athlon Scheduling
826;;
827;; The Athlon does contain three pipelined FP units, three integer units and
828;; three address generation units.
829;;
830;; The predecode logic is determining boundaries of instructions in the 64
831;; byte cache line. So the cache line straddling problem of K6 might be issue
832;; here as well, but it is not noted in the documentation.
833;;
834;; Three DirectPath instructions decoders and only one VectorPath decoder
835;; is available. They can decode three DirectPath instructions or one VectorPath
836;; instruction per cycle.
837;; Decoded macro instructions are then passed to 72 entry instruction control
838;; unit, that passes
839;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
840;;
841;; The load/store queue unit is not attached to the schedulers but
842;; communicates with all the execution units separately instead.
843
844(define_attr "athlon_decode" "direct,vector"
845 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
846 (const_string "vector")
847 (and (eq_attr "type" "push")
848 (match_operand 1 "memory_operand" ""))
849 (const_string "vector")
850 (and (eq_attr "type" "fmov")
851 (and (eq_attr "memory" "load,store")
852 (eq_attr "mode" "XF")))
853 (const_string "vector")]
854 (const_string "direct")))
855
856(define_function_unit "athlon_vectordec" 1 0
857 (and (eq_attr "cpu" "athlon")
858 (eq_attr "athlon_decode" "vector"))
859 1 1)
860
861(define_function_unit "athlon_directdec" 3 0
862 (and (eq_attr "cpu" "athlon")
863 (eq_attr "athlon_decode" "direct"))
864 1 1)
865
866(define_function_unit "athlon_vectordec" 1 0
867 (and (eq_attr "cpu" "athlon")
868 (eq_attr "athlon_decode" "direct"))
869 1 1 [(eq_attr "athlon_decode" "vector")])
870
871(define_function_unit "athlon_ieu" 3 0
872 (and (eq_attr "cpu" "athlon")
873 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
874 1 1)
875
876(define_function_unit "athlon_ieu" 3 0
877 (and (eq_attr "cpu" "athlon")
878 (eq_attr "type" "str"))
879 15 15)
880
881(define_function_unit "athlon_ieu" 3 0
882 (and (eq_attr "cpu" "athlon")
883 (eq_attr "type" "imul"))
884 5 0)
885
886(define_function_unit "athlon_ieu" 3 0
887 (and (eq_attr "cpu" "athlon")
888 (eq_attr "type" "idiv"))
889 42 0)
890
891(define_function_unit "athlon_muldiv" 1 0
892 (and (eq_attr "cpu" "athlon")
893 (eq_attr "type" "imul"))
894 5 0)
895
896(define_function_unit "athlon_muldiv" 1 0
897 (and (eq_attr "cpu" "athlon")
898 (eq_attr "type" "idiv"))
899 42 42)
900
901(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
902 (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
903 (const_string "add")
904 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
905 (const_string "mul")
906 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
907 (const_string "store")
908 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
909 (const_string "any")
910 (and (eq_attr "type" "fmov")
911 (ior (match_operand:SI 1 "register_operand" "")
912 (match_operand 1 "immediate_operand" "")))
913 (const_string "store")
914 (eq_attr "type" "fmov")
915 (const_string "muladd")]
916 (const_string "none")))
917
918;; We use latencies 1 for definitions. This is OK to model colisions
919;; in execution units. The real latencies are modeled in the "fp" pipeline.
920
921;; fsin, fcos: 96-192
922;; fsincos: 107-211
923;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
924(define_function_unit "athlon_fp" 3 0
925 (and (eq_attr "cpu" "athlon")
926 (eq_attr "type" "fpspc"))
927 100 1)
928
929;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
930(define_function_unit "athlon_fp" 3 0
931 (and (eq_attr "cpu" "athlon")
932 (eq_attr "type" "fdiv"))
933 24 1)
934
935(define_function_unit "athlon_fp" 3 0
936 (and (eq_attr "cpu" "athlon")
937 (eq_attr "type" "fop,fop1,fmul,fistp"))
938 4 1)
939
940;; XFmode loads are slow.
941;; XFmode store is slow too (8 cycles), but we don't need to model it, because
942;; there are no dependent instructions.
943
944(define_function_unit "athlon_fp" 3 0
945 (and (eq_attr "cpu" "athlon")
946 (and (eq_attr "type" "fmov")
947 (and (eq_attr "memory" "load")
948 (eq_attr "mode" "XF"))))
949 10 1)
950
951(define_function_unit "athlon_fp" 3 0
952 (and (eq_attr "cpu" "athlon")
953 (eq_attr "type" "fmov,fsgn"))
954 2 1)
955
956;; fcmp and ftst instructions
957(define_function_unit "athlon_fp" 3 0
958 (and (eq_attr "cpu" "athlon")
959 (and (eq_attr "type" "fcmp")
960 (eq_attr "athlon_decode" "direct")))
961 3 1)
962
963;; fcmpi instructions.
964(define_function_unit "athlon_fp" 3 0
965 (and (eq_attr "cpu" "athlon")
966 (and (eq_attr "type" "fcmp")
967 (eq_attr "athlon_decode" "vector")))
968 3 1)
969
970(define_function_unit "athlon_fp" 3 0
971 (and (eq_attr "cpu" "athlon")
972 (eq_attr "type" "fcmov"))
973 7 1)
974
975(define_function_unit "athlon_fp_mul" 1 0
976 (and (eq_attr "cpu" "athlon")
977 (eq_attr "athlon_fpunits" "mul"))
978 1 1)
979
980(define_function_unit "athlon_fp_add" 1 0
981 (and (eq_attr "cpu" "athlon")
982 (eq_attr "athlon_fpunits" "add"))
983 1 1)
984
985(define_function_unit "athlon_fp_muladd" 2 0
986 (and (eq_attr "cpu" "athlon")
987 (eq_attr "athlon_fpunits" "muladd,mul,add"))
988 1 1)
989
990(define_function_unit "athlon_fp_store" 1 0
991 (and (eq_attr "cpu" "athlon")
992 (eq_attr "athlon_fpunits" "store"))
993 1 1)
994
995;; We don't need to model the Address Generation Unit, since we don't model
996;; the re-order buffer yet and thus we never schedule more than three operations
997;; at time. Later we may want to experiment with MD_SCHED macros modeling the
998;; decoders independently on the functional units.
999
1000;(define_function_unit "athlon_agu" 3 0
1001; (and (eq_attr "cpu" "athlon")
1002; (and (eq_attr "memory" "!none")
1003; (eq_attr "athlon_fpunits" "none")))
1004; 1 1)
1005
1006;; Model load unit to avoid too long sequences of loads. We don't need to
1007;; model store queue, since it is hardly going to be bottleneck.
1008
1009(define_function_unit "athlon_load" 2 0
1010 (and (eq_attr "cpu" "athlon")
1011 (eq_attr "memory" "load,both"))
1012 1 1)
1013
1014
1015;; Compare instructions.
1016
1017;; All compare insns have expanders that save the operands away without
1018;; actually generating RTL. The bCOND or sCOND (emitted immediately
1019;; after the cmp) will actually emit the cmpM.
1020
1021(define_expand "cmpdi"
1022 [(set (reg:CC 17)
1023 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1024 (match_operand:DI 1 "x86_64_general_operand" "")))]
1025 ""
1026{
1027 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1028 operands[0] = force_reg (DImode, operands[0]);
1029 ix86_compare_op0 = operands[0];
1030 ix86_compare_op1 = operands[1];
1031 DONE;
1032})
1033
1034(define_expand "cmpsi"
1035 [(set (reg:CC 17)
1036 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1037 (match_operand:SI 1 "general_operand" "")))]
1038 ""
1039{
1040 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1041 operands[0] = force_reg (SImode, operands[0]);
1042 ix86_compare_op0 = operands[0];
1043 ix86_compare_op1 = operands[1];
1044 DONE;
1045})
1046
1047(define_expand "cmphi"
1048 [(set (reg:CC 17)
1049 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
1050 (match_operand:HI 1 "general_operand" "")))]
1051 ""
1052{
1053 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1054 operands[0] = force_reg (HImode, operands[0]);
1055 ix86_compare_op0 = operands[0];
1056 ix86_compare_op1 = operands[1];
1057 DONE;
1058})
1059
1060(define_expand "cmpqi"
1061 [(set (reg:CC 17)
1062 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
1063 (match_operand:QI 1 "general_operand" "")))]
1064 "TARGET_QIMODE_MATH"
1065{
1066 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1067 operands[0] = force_reg (QImode, operands[0]);
1068 ix86_compare_op0 = operands[0];
1069 ix86_compare_op1 = operands[1];
1070 DONE;
1071})
1072
1073(define_insn "cmpdi_ccno_1_rex64"
1074 [(set (reg 17)
1075 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
1076 (match_operand:DI 1 "const0_operand" "n,n")))]
1077 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1078 "@
1079 test{q}\t{%0, %0|%0, %0}
1080 cmp{q}\t{%1, %0|%0, %1}"
1081 [(set_attr "type" "test,icmp")
1082 (set_attr "length_immediate" "0,1")
1083 (set_attr "mode" "DI")])
1084
1085(define_insn "*cmpdi_minus_1_rex64"
1086 [(set (reg 17)
1087 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1088 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1089 (const_int 0)))]
1090 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
1091 "cmp{q}\t{%1, %0|%0, %1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "mode" "DI")])
1094
1095(define_expand "cmpdi_1_rex64"
1096 [(set (reg:CC 17)
1097 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1098 (match_operand:DI 1 "general_operand" "")))]
1099 "TARGET_64BIT"
1100 "")
1101
1102(define_insn "cmpdi_1_insn_rex64"
1103 [(set (reg 17)
1104 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1105 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1106 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1107 "cmp{q}\t{%1, %0|%0, %1}"
1108 [(set_attr "type" "icmp")
1109 (set_attr "mode" "DI")])
1110
1111
1112(define_insn "*cmpsi_ccno_1"
1113 [(set (reg 17)
1114 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1115 (match_operand:SI 1 "const0_operand" "n,n")))]
1116 "ix86_match_ccmode (insn, CCNOmode)"
1117 "@
1118 test{l}\t{%0, %0|%0, %0}
1119 cmp{l}\t{%1, %0|%0, %1}"
1120 [(set_attr "type" "test,icmp")
1121 (set_attr "length_immediate" "0,1")
1122 (set_attr "mode" "SI")])
1123
1124(define_insn "*cmpsi_minus_1"
1125 [(set (reg 17)
1126 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1127 (match_operand:SI 1 "general_operand" "ri,mr"))
1128 (const_int 0)))]
1129 "ix86_match_ccmode (insn, CCGOCmode)"
1130 "cmp{l}\t{%1, %0|%0, %1}"
1131 [(set_attr "type" "icmp")
1132 (set_attr "mode" "SI")])
1133
1134(define_expand "cmpsi_1"
1135 [(set (reg:CC 17)
1136 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1137 (match_operand:SI 1 "general_operand" "ri,mr")))]
1138 ""
1139 "")
1140
1141(define_insn "*cmpsi_1_insn"
1142 [(set (reg 17)
1143 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1144 (match_operand:SI 1 "general_operand" "ri,mr")))]
1145 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1146 && ix86_match_ccmode (insn, CCmode)"
1147 "cmp{l}\t{%1, %0|%0, %1}"
1148 [(set_attr "type" "icmp")
1149 (set_attr "mode" "SI")])
1150
1151(define_insn "*cmphi_ccno_1"
1152 [(set (reg 17)
1153 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1154 (match_operand:HI 1 "const0_operand" "n,n")))]
1155 "ix86_match_ccmode (insn, CCNOmode)"
1156 "@
1157 test{w}\t{%0, %0|%0, %0}
1158 cmp{w}\t{%1, %0|%0, %1}"
1159 [(set_attr "type" "test,icmp")
1160 (set_attr "length_immediate" "0,1")
1161 (set_attr "mode" "HI")])
1162
1163(define_insn "*cmphi_minus_1"
1164 [(set (reg 17)
1165 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1166 (match_operand:HI 1 "general_operand" "ri,mr"))
1167 (const_int 0)))]
1168 "ix86_match_ccmode (insn, CCGOCmode)"
1169 "cmp{w}\t{%1, %0|%0, %1}"
1170 [(set_attr "type" "icmp")
1171 (set_attr "mode" "HI")])
1172
1173(define_insn "*cmphi_1"
1174 [(set (reg 17)
1175 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1176 (match_operand:HI 1 "general_operand" "ri,mr")))]
1177 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1178 && ix86_match_ccmode (insn, CCmode)"
1179 "cmp{w}\t{%1, %0|%0, %1}"
1180 [(set_attr "type" "icmp")
1181 (set_attr "mode" "HI")])
1182
1183(define_insn "*cmpqi_ccno_1"
1184 [(set (reg 17)
1185 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1186 (match_operand:QI 1 "const0_operand" "n,n")))]
1187 "ix86_match_ccmode (insn, CCNOmode)"
1188 "@
1189 test{b}\t{%0, %0|%0, %0}
1190 cmp{b}\t{$0, %0|%0, 0}"
1191 [(set_attr "type" "test,icmp")
1192 (set_attr "length_immediate" "0,1")
1193 (set_attr "mode" "QI")])
1194
1195(define_insn "*cmpqi_1"
1196 [(set (reg 17)
1197 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1198 (match_operand:QI 1 "general_operand" "qi,mq")))]
1199 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1200 && ix86_match_ccmode (insn, CCmode)"
1201 "cmp{b}\t{%1, %0|%0, %1}"
1202 [(set_attr "type" "icmp")
1203 (set_attr "mode" "QI")])
1204
1205(define_insn "*cmpqi_minus_1"
1206 [(set (reg 17)
1207 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1208 (match_operand:QI 1 "general_operand" "qi,mq"))
1209 (const_int 0)))]
1210 "ix86_match_ccmode (insn, CCGOCmode)"
1211 "cmp{b}\t{%1, %0|%0, %1}"
1212 [(set_attr "type" "icmp")
1213 (set_attr "mode" "QI")])
1214
1215(define_insn "*cmpqi_ext_1"
1216 [(set (reg 17)
1217 (compare
1218 (match_operand:QI 0 "general_operand" "Qm")
1219 (subreg:QI
1220 (zero_extract:SI
1221 (match_operand 1 "ext_register_operand" "Q")
1222 (const_int 8)
1223 (const_int 8)) 0)))]
1224 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1225 "cmp{b}\t{%h1, %0|%0, %h1}"
1226 [(set_attr "type" "icmp")
1227 (set_attr "mode" "QI")])
1228
1229(define_insn "*cmpqi_ext_1_rex64"
1230 [(set (reg 17)
1231 (compare
1232 (match_operand:QI 0 "register_operand" "Q")
1233 (subreg:QI
1234 (zero_extract:SI
1235 (match_operand 1 "ext_register_operand" "Q")
1236 (const_int 8)
1237 (const_int 8)) 0)))]
1238 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1239 "cmp{b}\t{%h1, %0|%0, %h1}"
1240 [(set_attr "type" "icmp")
1241 (set_attr "mode" "QI")])
1242
1243(define_insn "*cmpqi_ext_2"
1244 [(set (reg 17)
1245 (compare
1246 (subreg:QI
1247 (zero_extract:SI
1248 (match_operand 0 "ext_register_operand" "Q")
1249 (const_int 8)
1250 (const_int 8)) 0)
1251 (match_operand:QI 1 "const0_operand" "n")))]
1252 "ix86_match_ccmode (insn, CCNOmode)"
1253 "test{b}\t%h0, %h0"
1254 [(set_attr "type" "test")
1255 (set_attr "length_immediate" "0")
1256 (set_attr "mode" "QI")])
1257
1258(define_expand "cmpqi_ext_3"
1259 [(set (reg:CC 17)
1260 (compare:CC
1261 (subreg:QI
1262 (zero_extract:SI
1263 (match_operand 0 "ext_register_operand" "")
1264 (const_int 8)
1265 (const_int 8)) 0)
1266 (match_operand:QI 1 "general_operand" "")))]
1267 ""
1268 "")
1269
1270(define_insn "cmpqi_ext_3_insn"
1271 [(set (reg 17)
1272 (compare
1273 (subreg:QI
1274 (zero_extract:SI
1275 (match_operand 0 "ext_register_operand" "Q")
1276 (const_int 8)
1277 (const_int 8)) 0)
1278 (match_operand:QI 1 "general_operand" "Qmn")))]
1279 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1280 "cmp{b}\t{%1, %h0|%h0, %1}"
1281 [(set_attr "type" "icmp")
1282 (set_attr "mode" "QI")])
1283
1284(define_insn "cmpqi_ext_3_insn_rex64"
1285 [(set (reg 17)
1286 (compare
1287 (subreg:QI
1288 (zero_extract:SI
1289 (match_operand 0 "ext_register_operand" "Q")
1290 (const_int 8)
1291 (const_int 8)) 0)
1292 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1293 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1294 "cmp{b}\t{%1, %h0|%h0, %1}"
1295 [(set_attr "type" "icmp")
1296 (set_attr "mode" "QI")])
1297
1298(define_insn "*cmpqi_ext_4"
1299 [(set (reg 17)
1300 (compare
1301 (subreg:QI
1302 (zero_extract:SI
1303 (match_operand 0 "ext_register_operand" "Q")
1304 (const_int 8)
1305 (const_int 8)) 0)
1306 (subreg:QI
1307 (zero_extract:SI
1308 (match_operand 1 "ext_register_operand" "Q")
1309 (const_int 8)
1310 (const_int 8)) 0)))]
1311 "ix86_match_ccmode (insn, CCmode)"
1312 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1313 [(set_attr "type" "icmp")
1314 (set_attr "mode" "QI")])
1315
1316;; These implement float point compares.
1317;; %%% See if we can get away with VOIDmode operands on the actual insns,
1318;; which would allow mix and match FP modes on the compares. Which is what
1319;; the old patterns did, but with many more of them.
1320
1321(define_expand "cmpxf"
1322 [(set (reg:CC 17)
1323 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1324 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1325 "!TARGET_64BIT && TARGET_80387"
1326{
1327 ix86_compare_op0 = operands[0];
1328 ix86_compare_op1 = operands[1];
1329 DONE;
1330})
1331
1332(define_expand "cmptf"
1333 [(set (reg:CC 17)
1334 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1335 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1336 "TARGET_80387"
1337{
1338 ix86_compare_op0 = operands[0];
1339 ix86_compare_op1 = operands[1];
1340 DONE;
1341})
1342
1343(define_expand "cmpdf"
1344 [(set (reg:CC 17)
1345 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1346 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1347 "TARGET_80387 || TARGET_SSE2"
1348{
1349 ix86_compare_op0 = operands[0];
1350 ix86_compare_op1 = operands[1];
1351 DONE;
1352})
1353
1354(define_expand "cmpsf"
1355 [(set (reg:CC 17)
1356 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1357 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1358 "TARGET_80387 || TARGET_SSE"
1359{
1360 ix86_compare_op0 = operands[0];
1361 ix86_compare_op1 = operands[1];
1362 DONE;
1363})
1364
1365;; FP compares, step 1:
1366;; Set the FP condition codes.
1367;;
1368;; CCFPmode compare with exceptions
1369;; CCFPUmode compare with no exceptions
1370
1371;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1372;; and that fp moves clobber the condition codes, and that there is
1373;; currently no way to describe this fact to reg-stack. So there are
1374;; no splitters yet for this.
1375
1376;; %%% YIKES! This scheme does not retain a strong connection between
1377;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1378;; work! Only allow tos/mem with tos in op 0.
1379;;
1380;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1381;; things aren't as bad as they sound...
1382
1383(define_insn "*cmpfp_0"
1384 [(set (match_operand:HI 0 "register_operand" "=a")
1385 (unspec:HI
1386 [(compare:CCFP (match_operand 1 "register_operand" "f")
1387 (match_operand 2 "const0_operand" "X"))] 9))]
1388 "TARGET_80387
1389 && FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1391{
1392 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1393 return "ftst\;fnstsw\t%0\;fstp\t%y0";
1394 else
1395 return "ftst\;fnstsw\t%0";
1396}
1397 [(set_attr "type" "multi")
1398 (set_attr "mode" "unknownfp")])
1399
1400;; We may not use "#" to split and emit these, since the REG_DEAD notes
1401;; used to manage the reg stack popping would not be preserved.
1402
1403(define_insn "*cmpfp_2_sf"
1404 [(set (reg:CCFP 18)
1405 (compare:CCFP
1406 (match_operand:SF 0 "register_operand" "f")
1407 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1408 "TARGET_80387"
1409 "* return output_fp_compare (insn, operands, 0, 0);"
1410 [(set_attr "type" "fcmp")
1411 (set_attr "mode" "SF")])
1412
1413(define_insn "*cmpfp_2_sf_1"
1414 [(set (match_operand:HI 0 "register_operand" "=a")
1415 (unspec:HI
1416 [(compare:CCFP
1417 (match_operand:SF 1 "register_operand" "f")
1418 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1419 "TARGET_80387"
1420 "* return output_fp_compare (insn, operands, 2, 0);"
1421 [(set_attr "type" "fcmp")
1422 (set_attr "mode" "SF")])
1423
1424(define_insn "*cmpfp_2_df"
1425 [(set (reg:CCFP 18)
1426 (compare:CCFP
1427 (match_operand:DF 0 "register_operand" "f")
1428 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1429 "TARGET_80387"
1430 "* return output_fp_compare (insn, operands, 0, 0);"
1431 [(set_attr "type" "fcmp")
1432 (set_attr "mode" "DF")])
1433
1434(define_insn "*cmpfp_2_df_1"
1435 [(set (match_operand:HI 0 "register_operand" "=a")
1436 (unspec:HI
1437 [(compare:CCFP
1438 (match_operand:DF 1 "register_operand" "f")
1439 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1440 "TARGET_80387"
1441 "* return output_fp_compare (insn, operands, 2, 0);"
1442 [(set_attr "type" "multi")
1443 (set_attr "mode" "DF")])
1444
1445(define_insn "*cmpfp_2_xf"
1446 [(set (reg:CCFP 18)
1447 (compare:CCFP
1448 (match_operand:XF 0 "register_operand" "f")
1449 (match_operand:XF 1 "register_operand" "f")))]
1450 "!TARGET_64BIT && TARGET_80387"
1451 "* return output_fp_compare (insn, operands, 0, 0);"
1452 [(set_attr "type" "fcmp")
1453 (set_attr "mode" "XF")])
1454
1455(define_insn "*cmpfp_2_tf"
1456 [(set (reg:CCFP 18)
1457 (compare:CCFP
1458 (match_operand:TF 0 "register_operand" "f")
1459 (match_operand:TF 1 "register_operand" "f")))]
1460 "TARGET_80387"
1461 "* return output_fp_compare (insn, operands, 0, 0);"
1462 [(set_attr "type" "fcmp")
1463 (set_attr "mode" "XF")])
1464
1465(define_insn "*cmpfp_2_xf_1"
1466 [(set (match_operand:HI 0 "register_operand" "=a")
1467 (unspec:HI
1468 [(compare:CCFP
1469 (match_operand:XF 1 "register_operand" "f")
1470 (match_operand:XF 2 "register_operand" "f"))] 9))]
1471 "!TARGET_64BIT && TARGET_80387"
1472 "* return output_fp_compare (insn, operands, 2, 0);"
1473 [(set_attr "type" "multi")
1474 (set_attr "mode" "XF")])
1475
1476(define_insn "*cmpfp_2_tf_1"
1477 [(set (match_operand:HI 0 "register_operand" "=a")
1478 (unspec:HI
1479 [(compare:CCFP
1480 (match_operand:TF 1 "register_operand" "f")
1481 (match_operand:TF 2 "register_operand" "f"))] 9))]
1482 "TARGET_80387"
1483 "* return output_fp_compare (insn, operands, 2, 0);"
1484 [(set_attr "type" "multi")
1485 (set_attr "mode" "XF")])
1486
1487(define_insn "*cmpfp_2u"
1488 [(set (reg:CCFPU 18)
1489 (compare:CCFPU
1490 (match_operand 0 "register_operand" "f")
1491 (match_operand 1 "register_operand" "f")))]
1492 "TARGET_80387
1493 && FLOAT_MODE_P (GET_MODE (operands[0]))
1494 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495 "* return output_fp_compare (insn, operands, 0, 1);"
1496 [(set_attr "type" "fcmp")
1497 (set_attr "mode" "unknownfp")])
1498
1499(define_insn "*cmpfp_2u_1"
1500 [(set (match_operand:HI 0 "register_operand" "=a")
1501 (unspec:HI
1502 [(compare:CCFPU
1503 (match_operand 1 "register_operand" "f")
1504 (match_operand 2 "register_operand" "f"))] 9))]
1505 "TARGET_80387
1506 && FLOAT_MODE_P (GET_MODE (operands[1]))
1507 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1508 "* return output_fp_compare (insn, operands, 2, 1);"
1509 [(set_attr "type" "multi")
1510 (set_attr "mode" "unknownfp")])
1511
1512;; Patterns to match the SImode-in-memory ficom instructions.
1513;;
1514;; %%% Play games with accepting gp registers, as otherwise we have to
1515;; force them to memory during rtl generation, which is no good. We
1516;; can get rid of this once we teach reload to do memory input reloads
1517;; via pushes.
1518
1519(define_insn "*ficom_1"
1520 [(set (reg:CCFP 18)
1521 (compare:CCFP
1522 (match_operand 0 "register_operand" "f,f")
1523 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1524 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1525 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1526 "#")
1527
1528;; Split the not-really-implemented gp register case into a
1529;; push-op-pop sequence.
1530;;
1531;; %%% This is most efficient, but am I gonna get in trouble
1532;; for separating cc0_setter and cc0_user?
1533
1534(define_split
1535 [(set (reg:CCFP 18)
1536 (compare:CCFP
1537 (match_operand:SF 0 "register_operand" "")
1538 (float (match_operand:SI 1 "register_operand" ""))))]
1539 "0 && TARGET_80387 && reload_completed"
1540 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1541 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1542 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1543 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1544 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1545 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1546
1547;; FP compares, step 2
1548;; Move the fpsw to ax.
1549
1550(define_insn "x86_fnstsw_1"
1551 [(set (match_operand:HI 0 "register_operand" "=a")
1552 (unspec:HI [(reg 18)] 9))]
1553 "TARGET_80387"
1554 "fnstsw\t%0"
1555 [(set_attr "length" "2")
1556 (set_attr "mode" "SI")
1557 (set_attr "i387" "1")
1558 (set_attr "ppro_uops" "few")])
1559
1560;; FP compares, step 3
1561;; Get ax into flags, general case.
1562
1563(define_insn "x86_sahf_1"
1564 [(set (reg:CC 17)
1565 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1566 "!TARGET_64BIT"
1567 "sahf"
1568 [(set_attr "length" "1")
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "mode" "SI")
1571 (set_attr "ppro_uops" "one")])
1572
1573;; Pentium Pro can do steps 1 through 3 in one go.
1574
1575(define_insn "*cmpfp_i"
1576 [(set (reg:CCFP 17)
1577 (compare:CCFP (match_operand 0 "register_operand" "f")
1578 (match_operand 1 "register_operand" "f")))]
1579 "TARGET_80387 && TARGET_CMOVE
1580 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && FLOAT_MODE_P (GET_MODE (operands[0]))
1582 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1583 "* return output_fp_compare (insn, operands, 1, 0);"
1584 [(set_attr "type" "fcmp")
1585 (set_attr "mode" "unknownfp")
1586 (set_attr "athlon_decode" "vector")])
1587
1588(define_insn "*cmpfp_i_sse"
1589 [(set (reg:CCFP 17)
1590 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1591 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1592 "TARGET_80387
1593 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1594 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1595 "* return output_fp_compare (insn, operands, 1, 0);"
1596 [(set_attr "type" "fcmp,sse")
1597 (set_attr "mode" "unknownfp")
1598 (set_attr "athlon_decode" "vector")])
1599
1600(define_insn "*cmpfp_i_sse_only"
1601 [(set (reg:CCFP 17)
1602 (compare:CCFP (match_operand 0 "register_operand" "x")
1603 (match_operand 1 "nonimmediate_operand" "xm")))]
1604 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1605 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1606 "* return output_fp_compare (insn, operands, 1, 0);"
1607 [(set_attr "type" "sse")
1608 (set_attr "mode" "unknownfp")
1609 (set_attr "athlon_decode" "vector")])
1610
1611(define_insn "*cmpfp_iu"
1612 [(set (reg:CCFPU 17)
1613 (compare:CCFPU (match_operand 0 "register_operand" "f")
1614 (match_operand 1 "register_operand" "f")))]
1615 "TARGET_80387 && TARGET_CMOVE
1616 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1617 && FLOAT_MODE_P (GET_MODE (operands[0]))
1618 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1619 "* return output_fp_compare (insn, operands, 1, 1);"
1620 [(set_attr "type" "fcmp")
1621 (set_attr "mode" "unknownfp")
1622 (set_attr "athlon_decode" "vector")])
1623
1624(define_insn "*cmpfp_iu_sse"
1625 [(set (reg:CCFPU 17)
1626 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1627 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1628 "TARGET_80387
1629 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1630 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1631 "* return output_fp_compare (insn, operands, 1, 1);"
1632 [(set_attr "type" "fcmp,sse")
1633 (set_attr "mode" "unknownfp")
1634 (set_attr "athlon_decode" "vector")])
1635
1636(define_insn "*cmpfp_iu_sse_only"
1637 [(set (reg:CCFPU 17)
1638 (compare:CCFPU (match_operand 0 "register_operand" "x")
1639 (match_operand 1 "nonimmediate_operand" "xm")))]
1640 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1641 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1642 "* return output_fp_compare (insn, operands, 1, 1);"
1643 [(set_attr "type" "sse")
1644 (set_attr "mode" "unknownfp")
1645 (set_attr "athlon_decode" "vector")])
1646
1647;; Move instructions.
1648
1649;; General case of fullword move.
1650
1651(define_expand "movsi"
1652 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1653 (match_operand:SI 1 "general_operand" ""))]
1654 ""
1655 "ix86_expand_move (SImode, operands); DONE;")
1656
1657;; Push/pop instructions. They are separate since autoinc/dec is not a
1658;; general_operand.
1659;;
1660;; %%% We don't use a post-inc memory reference because x86 is not a
1661;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1662;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1663;; targets without our curiosities, and it is just as easy to represent
1664;; this differently.
1665
1666(define_insn "*pushsi2"
1667 [(set (match_operand:SI 0 "push_operand" "=<")
1668 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1669 "!TARGET_64BIT"
1670 "push{l}\t%1"
1671 [(set_attr "type" "push")
1672 (set_attr "mode" "SI")])
1673
1674;; For 64BIT abi we always round up to 8 bytes.
1675(define_insn "*pushsi2_rex64"
1676 [(set (match_operand:SI 0 "push_operand" "=X")
1677 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1678 "TARGET_64BIT"
1679 "push{q}\t%q1"
1680 [(set_attr "type" "push")
1681 (set_attr "mode" "SI")])
1682
1683(define_insn "*pushsi2_prologue"
1684 [(set (match_operand:SI 0 "push_operand" "=<")
1685 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1686 (clobber (mem:BLK (scratch)))]
1687 "!TARGET_64BIT"
1688 "push{l}\t%1"
1689 [(set_attr "type" "push")
1690 (set_attr "mode" "SI")])
1691
1692(define_insn "*popsi1_epilogue"
1693 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1694 (mem:SI (reg:SI 7)))
1695 (set (reg:SI 7)
1696 (plus:SI (reg:SI 7) (const_int 4)))
1697 (clobber (mem:BLK (scratch)))]
1698 "!TARGET_64BIT"
1699 "pop{l}\t%0"
1700 [(set_attr "type" "pop")
1701 (set_attr "mode" "SI")])
1702
1703(define_insn "popsi1"
1704 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1705 (mem:SI (reg:SI 7)))
1706 (set (reg:SI 7)
1707 (plus:SI (reg:SI 7) (const_int 4)))]
1708 "!TARGET_64BIT"
1709 "pop{l}\t%0"
1710 [(set_attr "type" "pop")
1711 (set_attr "mode" "SI")])
1712
1713(define_insn "*movsi_xor"
1714 [(set (match_operand:SI 0 "register_operand" "=r")
1715 (match_operand:SI 1 "const0_operand" "i"))
1716 (clobber (reg:CC 17))]
1717 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1718 "xor{l}\t{%0, %0|%0, %0}"
1719 [(set_attr "type" "alu1")
1720 (set_attr "mode" "SI")
1721 (set_attr "length_immediate" "0")])
1722
1723(define_insn "*movsi_or"
1724 [(set (match_operand:SI 0 "register_operand" "=r")
1725 (match_operand:SI 1 "immediate_operand" "i"))
1726 (clobber (reg:CC 17))]
1727 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1728 && INTVAL (operands[1]) == -1
1729 && (TARGET_PENTIUM || optimize_size)"
1730{
1731 operands[1] = constm1_rtx;
1732 return "or{l}\t{%1, %0|%0, %1}";
1733}
1734 [(set_attr "type" "alu1")
1735 (set_attr "mode" "SI")
1736 (set_attr "length_immediate" "1")])
1737
1738; The first alternative is used only to compute proper length of instruction.
1739; Reload's algorithm does not take into account the cost of spill instructions
1740; needed to free register in given class, so avoid it from choosing the first
1741; alternative when eax is not available.
1742
1738(define_insn "*movsi_1"
1743(define_insn "*movsi_1"
1739 [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
1740 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
1744 [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1745 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
1741 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1742{
1743 switch (get_attr_type (insn))
1744 {
1745 case TYPE_SSE:
1746 if (get_attr_mode (insn) == TImode)
1747 return "movdqa\t{%1, %0|%0, %1}";
1748 return "movd\t{%1, %0|%0, %1}";
1749
1750 case TYPE_MMX:
1746 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1747{
1748 switch (get_attr_type (insn))
1749 {
1750 case TYPE_SSE:
1751 if (get_attr_mode (insn) == TImode)
1752 return "movdqa\t{%1, %0|%0, %1}";
1753 return "movd\t{%1, %0|%0, %1}";
1754
1755 case TYPE_MMX:
1756 if (get_attr_mode (insn) == DImode)
1757 return "movq\t{%1, %0|%0, %1}";
1751 return "movd\t{%1, %0|%0, %1}";
1752
1753 case TYPE_LEA:
1754 return "lea{l}\t{%1, %0|%0, %1}";
1755
1756 default:
1757 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1758 abort();
1759 return "mov{l}\t{%1, %0|%0, %1}";
1760 }
1761}
1762 [(set (attr "type")
1758 return "movd\t{%1, %0|%0, %1}";
1759
1760 case TYPE_LEA:
1761 return "lea{l}\t{%1, %0|%0, %1}";
1762
1763 default:
1764 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1765 abort();
1766 return "mov{l}\t{%1, %0|%0, %1}";
1767 }
1768}
1769 [(set (attr "type")
1763 (cond [(eq_attr "alternative" "4,5")
1770 (cond [(eq_attr "alternative" "4,5,6")
1764 (const_string "mmx")
1771 (const_string "mmx")
1765 (eq_attr "alternative" "6,7,8")
1772 (eq_attr "alternative" "7,8,9")
1766 (const_string "sse")
1767 (and (ne (symbol_ref "flag_pic") (const_int 0))
1768 (match_operand:SI 1 "symbolic_operand" ""))
1769 (const_string "lea")
1770 ]
1771 (const_string "imov")))
1773 (const_string "sse")
1774 (and (ne (symbol_ref "flag_pic") (const_int 0))
1775 (match_operand:SI 1 "symbolic_operand" ""))
1776 (const_string "lea")
1777 ]
1778 (const_string "imov")))
1772 (set_attr "modrm" "0,*,0,*,*,*,*,*,*")
1773 (set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
1779 (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
1780 (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
1774
1775;; Stores and loads of ax to arbitary constant address.
1776;; We fake an second form of instruction to force reload to load address
1777;; into register when rax is not available
1778(define_insn "*movabssi_1_rex64"
1779 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1780 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1781 "TARGET_64BIT"
1782 "@
1783 movabs{l}\t{%1, %P0|%P0, %1}
1784 mov{l}\t{%1, %a0|%a0, %1}
1785 movabs{l}\t{%1, %a0|%a0, %1}"
1786 [(set_attr "type" "imov")
1787 (set_attr "modrm" "0,*,*")
1788 (set_attr "length_address" "8,0,0")
1789 (set_attr "length_immediate" "0,*,*")
1790 (set_attr "memory" "store")
1791 (set_attr "mode" "SI")])
1792
1793(define_insn "*movabssi_2_rex64"
1794 [(set (match_operand:SI 0 "register_operand" "=a,r")
1795 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1796 "TARGET_64BIT"
1797 "@
1798 movabs{l}\t{%P1, %0|%0, %P1}
1799 mov{l}\t{%a1, %0|%0, %a1}"
1800 [(set_attr "type" "imov")
1801 (set_attr "modrm" "0,*")
1802 (set_attr "length_address" "8,0")
1803 (set_attr "length_immediate" "0")
1804 (set_attr "memory" "load")
1805 (set_attr "mode" "SI")])
1806
1807(define_insn "*swapsi"
1808 [(set (match_operand:SI 0 "register_operand" "+r")
1809 (match_operand:SI 1 "register_operand" "+r"))
1810 (set (match_dup 1)
1811 (match_dup 0))]
1812 ""
1813 "xchg{l}\t%1, %0"
1814 [(set_attr "type" "imov")
1815 (set_attr "pent_pair" "np")
1816 (set_attr "athlon_decode" "vector")
1817 (set_attr "mode" "SI")
1818 (set_attr "modrm" "0")
1819 (set_attr "ppro_uops" "few")])
1820
1821(define_expand "movhi"
1822 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1823 (match_operand:HI 1 "general_operand" ""))]
1824 ""
1825 "ix86_expand_move (HImode, operands); DONE;")
1826
1827(define_insn "*pushhi2"
1828 [(set (match_operand:HI 0 "push_operand" "=<,<")
1829 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1830 "!TARGET_64BIT"
1831 "@
1832 push{w}\t{|WORD PTR }%1
1833 push{w}\t%1"
1834 [(set_attr "type" "push")
1835 (set_attr "mode" "HI")])
1836
1837;; For 64BIT abi we always round up to 8 bytes.
1838(define_insn "*pushhi2_rex64"
1839 [(set (match_operand:HI 0 "push_operand" "=X")
1840 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1841 "TARGET_64BIT"
1842 "push{q}\t%q1"
1843 [(set_attr "type" "push")
1844 (set_attr "mode" "QI")])
1845
1781
1782;; Stores and loads of ax to arbitary constant address.
1783;; We fake an second form of instruction to force reload to load address
1784;; into register when rax is not available
1785(define_insn "*movabssi_1_rex64"
1786 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1787 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1788 "TARGET_64BIT"
1789 "@
1790 movabs{l}\t{%1, %P0|%P0, %1}
1791 mov{l}\t{%1, %a0|%a0, %1}
1792 movabs{l}\t{%1, %a0|%a0, %1}"
1793 [(set_attr "type" "imov")
1794 (set_attr "modrm" "0,*,*")
1795 (set_attr "length_address" "8,0,0")
1796 (set_attr "length_immediate" "0,*,*")
1797 (set_attr "memory" "store")
1798 (set_attr "mode" "SI")])
1799
1800(define_insn "*movabssi_2_rex64"
1801 [(set (match_operand:SI 0 "register_operand" "=a,r")
1802 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1803 "TARGET_64BIT"
1804 "@
1805 movabs{l}\t{%P1, %0|%0, %P1}
1806 mov{l}\t{%a1, %0|%0, %a1}"
1807 [(set_attr "type" "imov")
1808 (set_attr "modrm" "0,*")
1809 (set_attr "length_address" "8,0")
1810 (set_attr "length_immediate" "0")
1811 (set_attr "memory" "load")
1812 (set_attr "mode" "SI")])
1813
1814(define_insn "*swapsi"
1815 [(set (match_operand:SI 0 "register_operand" "+r")
1816 (match_operand:SI 1 "register_operand" "+r"))
1817 (set (match_dup 1)
1818 (match_dup 0))]
1819 ""
1820 "xchg{l}\t%1, %0"
1821 [(set_attr "type" "imov")
1822 (set_attr "pent_pair" "np")
1823 (set_attr "athlon_decode" "vector")
1824 (set_attr "mode" "SI")
1825 (set_attr "modrm" "0")
1826 (set_attr "ppro_uops" "few")])
1827
1828(define_expand "movhi"
1829 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1830 (match_operand:HI 1 "general_operand" ""))]
1831 ""
1832 "ix86_expand_move (HImode, operands); DONE;")
1833
1834(define_insn "*pushhi2"
1835 [(set (match_operand:HI 0 "push_operand" "=<,<")
1836 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1837 "!TARGET_64BIT"
1838 "@
1839 push{w}\t{|WORD PTR }%1
1840 push{w}\t%1"
1841 [(set_attr "type" "push")
1842 (set_attr "mode" "HI")])
1843
1844;; For 64BIT abi we always round up to 8 bytes.
1845(define_insn "*pushhi2_rex64"
1846 [(set (match_operand:HI 0 "push_operand" "=X")
1847 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1848 "TARGET_64BIT"
1849 "push{q}\t%q1"
1850 [(set_attr "type" "push")
1851 (set_attr "mode" "QI")])
1852
1853; The first alternative is used only to compute proper length of instruction.
1854; Reload's algorithm does not take into account the cost of spill instructions
1855; needed to free register in given class, so avoid it from choosing the first
1856; alternative when eax is not available.
1857
1846(define_insn "*movhi_1"
1858(define_insn "*movhi_1"
1847 [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1859 [(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
1848 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1849 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1850{
1851 switch (get_attr_type (insn))
1852 {
1853 case TYPE_IMOVX:
1854 /* movzwl is faster than movw on p2 due to partial word stalls,
1855 though not as fast as an aligned movl. */
1856 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1857 default:
1858 if (get_attr_mode (insn) == MODE_SI)
1859 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1860 else
1861 return "mov{w}\t{%1, %0|%0, %1}";
1862 }
1863}
1864 [(set (attr "type")
1865 (cond [(and (eq_attr "alternative" "0,1")
1866 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1867 (const_int 0))
1868 (eq (symbol_ref "TARGET_HIMODE_MATH")
1869 (const_int 0))))
1870 (const_string "imov")
1871 (and (eq_attr "alternative" "2,3,4")
1872 (match_operand:HI 1 "aligned_operand" ""))
1873 (const_string "imov")
1874 (and (ne (symbol_ref "TARGET_MOVX")
1875 (const_int 0))
1876 (eq_attr "alternative" "0,1,3,4"))
1877 (const_string "imovx")
1878 ]
1879 (const_string "imov")))
1880 (set (attr "mode")
1881 (cond [(eq_attr "type" "imovx")
1882 (const_string "SI")
1883 (and (eq_attr "alternative" "2,3,4")
1884 (match_operand:HI 1 "aligned_operand" ""))
1885 (const_string "SI")
1886 (and (eq_attr "alternative" "0,1")
1887 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1888 (const_int 0))
1889 (eq (symbol_ref "TARGET_HIMODE_MATH")
1890 (const_int 0))))
1891 (const_string "SI")
1892 ]
1893 (const_string "HI")))
1894 (set_attr "modrm" "0,*,*,0,*,*")])
1895
1896;; Stores and loads of ax to arbitary constant address.
1897;; We fake an second form of instruction to force reload to load address
1898;; into register when rax is not available
1899(define_insn "*movabshi_1_rex64"
1900 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1901 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1902 "TARGET_64BIT"
1903 "@
1904 movabs{w}\t{%1, %P0|%P0, %1}
1905 mov{w}\t{%1, %a0|%a0, %1}
1906 movabs{w}\t{%1, %a0|%a0, %1}"
1907 [(set_attr "type" "imov")
1908 (set_attr "modrm" "0,*,*")
1909 (set_attr "length_address" "8,0,0")
1910 (set_attr "length_immediate" "0,*,*")
1911 (set_attr "memory" "store")
1912 (set_attr "mode" "HI")])
1913
1914(define_insn "*movabshi_2_rex64"
1915 [(set (match_operand:HI 0 "register_operand" "=a,r")
1916 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1917 "TARGET_64BIT"
1918 "@
1919 movabs{w}\t{%P1, %0|%0, %P1}
1920 mov{w}\t{%a1, %0|%0, %a1}"
1921 [(set_attr "type" "imov")
1922 (set_attr "modrm" "0,*")
1923 (set_attr "length_address" "8,0")
1924 (set_attr "length_immediate" "0")
1925 (set_attr "memory" "load")
1926 (set_attr "mode" "HI")])
1927
1928(define_insn "*swaphi_1"
1929 [(set (match_operand:HI 0 "register_operand" "+r")
1930 (match_operand:HI 1 "register_operand" "+r"))
1931 (set (match_dup 1)
1932 (match_dup 0))]
1933 "TARGET_PARTIAL_REG_STALL"
1934 "xchg{w}\t%1, %0"
1935 [(set_attr "type" "imov")
1936 (set_attr "pent_pair" "np")
1937 (set_attr "mode" "HI")
1938 (set_attr "modrm" "0")
1939 (set_attr "ppro_uops" "few")])
1940
1941(define_insn "*swaphi_2"
1942 [(set (match_operand:HI 0 "register_operand" "+r")
1943 (match_operand:HI 1 "register_operand" "+r"))
1944 (set (match_dup 1)
1945 (match_dup 0))]
1946 "! TARGET_PARTIAL_REG_STALL"
1947 "xchg{l}\t%k1, %k0"
1948 [(set_attr "type" "imov")
1949 (set_attr "pent_pair" "np")
1950 (set_attr "mode" "SI")
1951 (set_attr "modrm" "0")
1952 (set_attr "ppro_uops" "few")])
1953
1954(define_expand "movstricthi"
1955 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1956 (match_operand:HI 1 "general_operand" ""))]
1957 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1958{
1959 /* Don't generate memory->memory moves, go through a register */
1960 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1961 operands[1] = force_reg (HImode, operands[1]);
1962})
1963
1964(define_insn "*movstricthi_1"
1965 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1966 (match_operand:HI 1 "general_operand" "rn,m"))]
1967 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1968 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1969 "mov{w}\t{%1, %0|%0, %1}"
1970 [(set_attr "type" "imov")
1971 (set_attr "mode" "HI")])
1972
1973(define_insn "*movstricthi_xor"
1974 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1975 (match_operand:HI 1 "const0_operand" "i"))
1976 (clobber (reg:CC 17))]
1977 "reload_completed
1978 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1979 "xor{w}\t{%0, %0|%0, %0}"
1980 [(set_attr "type" "alu1")
1981 (set_attr "mode" "HI")
1982 (set_attr "length_immediate" "0")])
1983
1984(define_expand "movqi"
1985 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1986 (match_operand:QI 1 "general_operand" ""))]
1987 ""
1988 "ix86_expand_move (QImode, operands); DONE;")
1989
1990;; emit_push_insn when it calls move_by_pieces requires an insn to
1991;; "push a byte". But actually we use pushw, which has the effect
1992;; of rounding the amount pushed up to a halfword.
1993
1994(define_insn "*pushqi2"
1995 [(set (match_operand:QI 0 "push_operand" "=X,X")
1996 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1997 "!TARGET_64BIT"
1998 "@
1999 push{w}\t{|word ptr }%1
2000 push{w}\t%w1"
2001 [(set_attr "type" "push")
2002 (set_attr "mode" "HI")])
2003
2004;; For 64BIT abi we always round up to 8 bytes.
2005(define_insn "*pushqi2_rex64"
2006 [(set (match_operand:QI 0 "push_operand" "=X")
2007 (match_operand:QI 1 "nonmemory_no_elim_operand" "ri"))]
2008 "TARGET_64BIT"
2009 "push{q}\t%q1"
2010 [(set_attr "type" "push")
2011 (set_attr "mode" "QI")])
2012
2013;; Situation is quite tricky about when to choose full sized (SImode) move
2014;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2015;; partial register dependency machines (such as AMD Athlon), where QImode
2016;; moves issue extra dependency and for partial register stalls machines
2017;; that don't use QImode patterns (and QImode move cause stall on the next
2018;; instruction).
2019;;
2020;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2021;; register stall machines with, where we use QImode instructions, since
2022;; partial register stall can be caused there. Then we use movzx.
2023(define_insn "*movqi_1"
2024 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2025 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2026 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
2027{
2028 switch (get_attr_type (insn))
2029 {
2030 case TYPE_IMOVX:
2031 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
2032 abort ();
2033 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2034 default:
2035 if (get_attr_mode (insn) == MODE_SI)
2036 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2037 else
2038 return "mov{b}\t{%1, %0|%0, %1}";
2039 }
2040}
2041 [(set (attr "type")
2042 (cond [(and (eq_attr "alternative" "3")
2043 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2044 (const_int 0))
2045 (eq (symbol_ref "TARGET_QIMODE_MATH")
2046 (const_int 0))))
2047 (const_string "imov")
2048 (eq_attr "alternative" "3,5")
2049 (const_string "imovx")
2050 (and (ne (symbol_ref "TARGET_MOVX")
2051 (const_int 0))
2052 (eq_attr "alternative" "2"))
2053 (const_string "imovx")
2054 ]
2055 (const_string "imov")))
2056 (set (attr "mode")
2057 (cond [(eq_attr "alternative" "3,4,5")
2058 (const_string "SI")
2059 (eq_attr "alternative" "6")
2060 (const_string "QI")
2061 (eq_attr "type" "imovx")
2062 (const_string "SI")
2063 (and (eq_attr "type" "imov")
2064 (and (eq_attr "alternative" "0,1,2")
2065 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2066 (const_int 0))))
2067 (const_string "SI")
2068 ;; Avoid partial register stalls when not using QImode arithmetic
2069 (and (eq_attr "type" "imov")
2070 (and (eq_attr "alternative" "0,1,2")
2071 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2072 (const_int 0))
2073 (eq (symbol_ref "TARGET_QIMODE_MATH")
2074 (const_int 0)))))
2075 (const_string "SI")
2076 ]
2077 (const_string "QI")))])
2078
2079(define_expand "reload_outqi"
2080 [(parallel [(match_operand:QI 0 "" "=m")
2081 (match_operand:QI 1 "register_operand" "r")
2082 (match_operand:QI 2 "register_operand" "=&q")])]
2083 ""
2084{
2085 rtx op0, op1, op2;
2086 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
2087
2088 if (reg_overlap_mentioned_p (op2, op0))
2089 abort ();
2090 if (! q_regs_operand (op1, QImode))
2091 {
2092 emit_insn (gen_movqi (op2, op1));
2093 op1 = op2;
2094 }
2095 emit_insn (gen_movqi (op0, op1));
2096 DONE;
2097})
2098
2099(define_insn "*swapqi"
2100 [(set (match_operand:QI 0 "register_operand" "+r")
2101 (match_operand:QI 1 "register_operand" "+r"))
2102 (set (match_dup 1)
2103 (match_dup 0))]
2104 ""
2105 "xchg{b}\t%1, %0"
2106 [(set_attr "type" "imov")
2107 (set_attr "pent_pair" "np")
2108 (set_attr "mode" "QI")
2109 (set_attr "modrm" "0")
2110 (set_attr "ppro_uops" "few")])
2111
2112(define_expand "movstrictqi"
2113 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2114 (match_operand:QI 1 "general_operand" ""))]
2115 "! TARGET_PARTIAL_REG_STALL"
2116{
2117 /* Don't generate memory->memory moves, go through a register. */
2118 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2119 operands[1] = force_reg (QImode, operands[1]);
2120})
2121
2122(define_insn "*movstrictqi_1"
2123 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2124 (match_operand:QI 1 "general_operand" "*qn,m"))]
2125 "! TARGET_PARTIAL_REG_STALL
2126 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2127 "mov{b}\t{%1, %0|%0, %1}"
2128 [(set_attr "type" "imov")
2129 (set_attr "mode" "QI")])
2130
2131(define_insn "*movstrictqi_xor"
2132 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2133 (match_operand:QI 1 "const0_operand" "i"))
2134 (clobber (reg:CC 17))]
2135 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
2136 "xor{b}\t{%0, %0|%0, %0}"
2137 [(set_attr "type" "alu1")
2138 (set_attr "mode" "QI")
2139 (set_attr "length_immediate" "0")])
2140
2141(define_insn "*movsi_extv_1"
2142 [(set (match_operand:SI 0 "register_operand" "=R")
2143 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2144 (const_int 8)
2145 (const_int 8)))]
2146 ""
2147 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2148 [(set_attr "type" "imovx")
2149 (set_attr "mode" "SI")])
2150
2151(define_insn "*movhi_extv_1"
2152 [(set (match_operand:HI 0 "register_operand" "=R")
2153 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2154 (const_int 8)
2155 (const_int 8)))]
2156 ""
2157 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2158 [(set_attr "type" "imovx")
2159 (set_attr "mode" "SI")])
2160
2161(define_insn "*movqi_extv_1"
2162 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2163 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2164 (const_int 8)
2165 (const_int 8)))]
2166 "!TARGET_64BIT"
2167{
2168 switch (get_attr_type (insn))
2169 {
2170 case TYPE_IMOVX:
2171 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2172 default:
2173 return "mov{b}\t{%h1, %0|%0, %h1}";
2174 }
2175}
2176 [(set (attr "type")
2177 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2178 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2179 (ne (symbol_ref "TARGET_MOVX")
2180 (const_int 0))))
2181 (const_string "imovx")
2182 (const_string "imov")))
2183 (set (attr "mode")
2184 (if_then_else (eq_attr "type" "imovx")
2185 (const_string "SI")
2186 (const_string "QI")))])
2187
2188(define_insn "*movqi_extv_1_rex64"
2189 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2190 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2191 (const_int 8)
2192 (const_int 8)))]
2193 "TARGET_64BIT"
2194{
2195 switch (get_attr_type (insn))
2196 {
2197 case TYPE_IMOVX:
2198 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2199 default:
2200 return "mov{b}\t{%h1, %0|%0, %h1}";
2201 }
2202}
2203 [(set (attr "type")
2204 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2205 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2206 (ne (symbol_ref "TARGET_MOVX")
2207 (const_int 0))))
2208 (const_string "imovx")
2209 (const_string "imov")))
2210 (set (attr "mode")
2211 (if_then_else (eq_attr "type" "imovx")
2212 (const_string "SI")
2213 (const_string "QI")))])
2214
2215;; Stores and loads of ax to arbitary constant address.
2216;; We fake an second form of instruction to force reload to load address
2217;; into register when rax is not available
2218(define_insn "*movabsqi_1_rex64"
2219 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2220 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
2221 "TARGET_64BIT"
2222 "@
2223 movabs{b}\t{%1, %P0|%P0, %1}
2224 mov{b}\t{%1, %a0|%a0, %1}
2225 movabs{b}\t{%1, %a0|%a0, %1}"
2226 [(set_attr "type" "imov")
2227 (set_attr "modrm" "0,*,*")
2228 (set_attr "length_address" "8,0,0")
2229 (set_attr "length_immediate" "0,*,*")
2230 (set_attr "memory" "store")
2231 (set_attr "mode" "QI")])
2232
2233(define_insn "*movabsqi_2_rex64"
2234 [(set (match_operand:QI 0 "register_operand" "=a,r")
2235 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2236 "TARGET_64BIT"
2237 "@
2238 movabs{b}\t{%P1, %0|%0, %P1}
2239 mov{b}\t{%a1, %0|%0, %a1}"
2240 [(set_attr "type" "imov")
2241 (set_attr "modrm" "0,*")
2242 (set_attr "length_address" "8,0")
2243 (set_attr "length_immediate" "0")
2244 (set_attr "memory" "load")
2245 (set_attr "mode" "QI")])
2246
2247(define_insn "*movsi_extzv_1"
2248 [(set (match_operand:SI 0 "register_operand" "=R")
2249 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2250 (const_int 8)
2251 (const_int 8)))]
2252 ""
2253 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2254 [(set_attr "type" "imovx")
2255 (set_attr "mode" "SI")])
2256
2257(define_insn "*movqi_extzv_2"
2258 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2259 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2260 (const_int 8)
2261 (const_int 8)) 0))]
2262 "!TARGET_64BIT"
2263{
2264 switch (get_attr_type (insn))
2265 {
2266 case TYPE_IMOVX:
2267 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2268 default:
2269 return "mov{b}\t{%h1, %0|%0, %h1}";
2270 }
2271}
2272 [(set (attr "type")
2273 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2274 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2275 (ne (symbol_ref "TARGET_MOVX")
2276 (const_int 0))))
2277 (const_string "imovx")
2278 (const_string "imov")))
2279 (set (attr "mode")
2280 (if_then_else (eq_attr "type" "imovx")
2281 (const_string "SI")
2282 (const_string "QI")))])
2283
2284(define_insn "*movqi_extzv_2_rex64"
2285 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2286 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2287 (const_int 8)
2288 (const_int 8)) 0))]
2289 "TARGET_64BIT"
2290{
2291 switch (get_attr_type (insn))
2292 {
2293 case TYPE_IMOVX:
2294 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2295 default:
2296 return "mov{b}\t{%h1, %0|%0, %h1}";
2297 }
2298}
2299 [(set (attr "type")
2300 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2301 (ne (symbol_ref "TARGET_MOVX")
2302 (const_int 0)))
2303 (const_string "imovx")
2304 (const_string "imov")))
2305 (set (attr "mode")
2306 (if_then_else (eq_attr "type" "imovx")
2307 (const_string "SI")
2308 (const_string "QI")))])
2309
2310(define_insn "movsi_insv_1"
2311 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2312 (const_int 8)
2313 (const_int 8))
2314 (match_operand:SI 1 "general_operand" "Qmn"))]
2315 "!TARGET_64BIT"
2316 "mov{b}\t{%b1, %h0|%h0, %b1}"
2317 [(set_attr "type" "imov")
2318 (set_attr "mode" "QI")])
2319
2320(define_insn "*movsi_insv_1_rex64"
2321 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2322 (const_int 8)
2323 (const_int 8))
2324 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2325 "TARGET_64BIT"
2326 "mov{b}\t{%b1, %h0|%h0, %b1}"
2327 [(set_attr "type" "imov")
2328 (set_attr "mode" "QI")])
2329
2330(define_insn "*movqi_insv_2"
2331 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2332 (const_int 8)
2333 (const_int 8))
2334 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2335 (const_int 8))
2336 (const_int 255)))]
2337 ""
2338 "mov{b}\t{%h1, %h0|%h0, %h1}"
2339 [(set_attr "type" "imov")
2340 (set_attr "mode" "QI")])
2341
2342(define_expand "movdi"
2343 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2344 (match_operand:DI 1 "general_operand" ""))]
2345 ""
2346 "ix86_expand_move (DImode, operands); DONE;")
2347
2348(define_insn "*pushdi"
2349 [(set (match_operand:DI 0 "push_operand" "=<")
2350 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2351 "!TARGET_64BIT"
2352 "#")
2353
2354(define_insn "pushdi2_rex64"
2355 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2356 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2357 "TARGET_64BIT"
2358 "@
2359 push{q}\t%1
2360 #"
2361 [(set_attr "type" "push,multi")
2362 (set_attr "mode" "DI")])
2363
2364;; Convert impossible pushes of immediate to existing instructions.
2365;; First try to get scratch register and go through it. In case this
2366;; fails, push sign extended lower part first and then overwrite
2367;; upper part by 32bit move.
2368(define_peephole2
2369 [(match_scratch:DI 2 "r")
2370 (set (match_operand:DI 0 "push_operand" "")
2371 (match_operand:DI 1 "immediate_operand" ""))]
2372 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2373 && !x86_64_immediate_operand (operands[1], DImode)"
2374 [(set (match_dup 2) (match_dup 1))
2375 (set (match_dup 0) (match_dup 2))]
2376 "")
2377
2378;; We need to define this as both peepholer and splitter for case
2379;; peephole2 pass is not run.
2380(define_peephole2
2381 [(set (match_operand:DI 0 "push_operand" "")
2382 (match_operand:DI 1 "immediate_operand" ""))]
2383 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2384 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2385 [(set (match_dup 0) (match_dup 1))
2386 (set (match_dup 2) (match_dup 3))]
2387 "split_di (operands + 1, 1, operands + 2, operands + 3);
2388 operands[1] = gen_lowpart (DImode, operands[2]);
2389 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2390 GEN_INT (4)));
2391 ")
2392
2393(define_split
2394 [(set (match_operand:DI 0 "push_operand" "")
2395 (match_operand:DI 1 "immediate_operand" ""))]
2396 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2397 && !symbolic_operand (operands[1], DImode)
2398 && !x86_64_immediate_operand (operands[1], DImode)"
2399 [(set (match_dup 0) (match_dup 1))
2400 (set (match_dup 2) (match_dup 3))]
2401 "split_di (operands + 1, 1, operands + 2, operands + 3);
2402 operands[1] = gen_lowpart (DImode, operands[2]);
2403 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2404 GEN_INT (4)));
2405 ")
2406
2407(define_insn "*pushdi2_prologue_rex64"
2408 [(set (match_operand:DI 0 "push_operand" "=<")
2409 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2410 (clobber (mem:BLK (scratch)))]
2411 "TARGET_64BIT"
2412 "push{q}\t%1"
2413 [(set_attr "type" "push")
2414 (set_attr "mode" "DI")])
2415
2416(define_insn "*popdi1_epilogue_rex64"
2417 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2418 (mem:DI (reg:DI 7)))
2419 (set (reg:DI 7)
2420 (plus:DI (reg:DI 7) (const_int 8)))
2421 (clobber (mem:BLK (scratch)))]
2422 "TARGET_64BIT"
2423 "pop{q}\t%0"
2424 [(set_attr "type" "pop")
2425 (set_attr "mode" "DI")])
2426
2427(define_insn "popdi1"
2428 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2429 (mem:DI (reg:DI 7)))
2430 (set (reg:DI 7)
2431 (plus:DI (reg:DI 7) (const_int 8)))]
2432 "TARGET_64BIT"
2433 "pop{q}\t%0"
2434 [(set_attr "type" "pop")
2435 (set_attr "mode" "DI")])
2436
2437(define_insn "*movdi_xor_rex64"
2438 [(set (match_operand:DI 0 "register_operand" "=r")
2439 (match_operand:DI 1 "const0_operand" "i"))
2440 (clobber (reg:CC 17))]
2441 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2442 && reload_completed"
2443 "xor{l}\t{%k0, %k0|%k0, %k0}"
2444 [(set_attr "type" "alu1")
2445 (set_attr "mode" "SI")
2446 (set_attr "length_immediate" "0")])
2447
2448(define_insn "*movdi_or_rex64"
2449 [(set (match_operand:DI 0 "register_operand" "=r")
2450 (match_operand:DI 1 "const_int_operand" "i"))
2451 (clobber (reg:CC 17))]
2452 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
2453 && reload_completed
2454 && GET_CODE (operands[1]) == CONST_INT
2455 && INTVAL (operands[1]) == -1"
2456{
2457 operands[1] = constm1_rtx;
2458 return "or{q}\t{%1, %0|%0, %1}";
2459}
2460 [(set_attr "type" "alu1")
2461 (set_attr "mode" "DI")
2462 (set_attr "length_immediate" "1")])
2463
2464(define_insn "*movdi_2"
1860 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1861 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1862{
1863 switch (get_attr_type (insn))
1864 {
1865 case TYPE_IMOVX:
1866 /* movzwl is faster than movw on p2 due to partial word stalls,
1867 though not as fast as an aligned movl. */
1868 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1869 default:
1870 if (get_attr_mode (insn) == MODE_SI)
1871 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1872 else
1873 return "mov{w}\t{%1, %0|%0, %1}";
1874 }
1875}
1876 [(set (attr "type")
1877 (cond [(and (eq_attr "alternative" "0,1")
1878 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1879 (const_int 0))
1880 (eq (symbol_ref "TARGET_HIMODE_MATH")
1881 (const_int 0))))
1882 (const_string "imov")
1883 (and (eq_attr "alternative" "2,3,4")
1884 (match_operand:HI 1 "aligned_operand" ""))
1885 (const_string "imov")
1886 (and (ne (symbol_ref "TARGET_MOVX")
1887 (const_int 0))
1888 (eq_attr "alternative" "0,1,3,4"))
1889 (const_string "imovx")
1890 ]
1891 (const_string "imov")))
1892 (set (attr "mode")
1893 (cond [(eq_attr "type" "imovx")
1894 (const_string "SI")
1895 (and (eq_attr "alternative" "2,3,4")
1896 (match_operand:HI 1 "aligned_operand" ""))
1897 (const_string "SI")
1898 (and (eq_attr "alternative" "0,1")
1899 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1900 (const_int 0))
1901 (eq (symbol_ref "TARGET_HIMODE_MATH")
1902 (const_int 0))))
1903 (const_string "SI")
1904 ]
1905 (const_string "HI")))
1906 (set_attr "modrm" "0,*,*,0,*,*")])
1907
1908;; Stores and loads of ax to arbitary constant address.
1909;; We fake an second form of instruction to force reload to load address
1910;; into register when rax is not available
1911(define_insn "*movabshi_1_rex64"
1912 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1913 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1914 "TARGET_64BIT"
1915 "@
1916 movabs{w}\t{%1, %P0|%P0, %1}
1917 mov{w}\t{%1, %a0|%a0, %1}
1918 movabs{w}\t{%1, %a0|%a0, %1}"
1919 [(set_attr "type" "imov")
1920 (set_attr "modrm" "0,*,*")
1921 (set_attr "length_address" "8,0,0")
1922 (set_attr "length_immediate" "0,*,*")
1923 (set_attr "memory" "store")
1924 (set_attr "mode" "HI")])
1925
1926(define_insn "*movabshi_2_rex64"
1927 [(set (match_operand:HI 0 "register_operand" "=a,r")
1928 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1929 "TARGET_64BIT"
1930 "@
1931 movabs{w}\t{%P1, %0|%0, %P1}
1932 mov{w}\t{%a1, %0|%0, %a1}"
1933 [(set_attr "type" "imov")
1934 (set_attr "modrm" "0,*")
1935 (set_attr "length_address" "8,0")
1936 (set_attr "length_immediate" "0")
1937 (set_attr "memory" "load")
1938 (set_attr "mode" "HI")])
1939
1940(define_insn "*swaphi_1"
1941 [(set (match_operand:HI 0 "register_operand" "+r")
1942 (match_operand:HI 1 "register_operand" "+r"))
1943 (set (match_dup 1)
1944 (match_dup 0))]
1945 "TARGET_PARTIAL_REG_STALL"
1946 "xchg{w}\t%1, %0"
1947 [(set_attr "type" "imov")
1948 (set_attr "pent_pair" "np")
1949 (set_attr "mode" "HI")
1950 (set_attr "modrm" "0")
1951 (set_attr "ppro_uops" "few")])
1952
1953(define_insn "*swaphi_2"
1954 [(set (match_operand:HI 0 "register_operand" "+r")
1955 (match_operand:HI 1 "register_operand" "+r"))
1956 (set (match_dup 1)
1957 (match_dup 0))]
1958 "! TARGET_PARTIAL_REG_STALL"
1959 "xchg{l}\t%k1, %k0"
1960 [(set_attr "type" "imov")
1961 (set_attr "pent_pair" "np")
1962 (set_attr "mode" "SI")
1963 (set_attr "modrm" "0")
1964 (set_attr "ppro_uops" "few")])
1965
1966(define_expand "movstricthi"
1967 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1968 (match_operand:HI 1 "general_operand" ""))]
1969 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1970{
1971 /* Don't generate memory->memory moves, go through a register */
1972 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1973 operands[1] = force_reg (HImode, operands[1]);
1974})
1975
1976(define_insn "*movstricthi_1"
1977 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1978 (match_operand:HI 1 "general_operand" "rn,m"))]
1979 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1980 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1981 "mov{w}\t{%1, %0|%0, %1}"
1982 [(set_attr "type" "imov")
1983 (set_attr "mode" "HI")])
1984
1985(define_insn "*movstricthi_xor"
1986 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1987 (match_operand:HI 1 "const0_operand" "i"))
1988 (clobber (reg:CC 17))]
1989 "reload_completed
1990 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1991 "xor{w}\t{%0, %0|%0, %0}"
1992 [(set_attr "type" "alu1")
1993 (set_attr "mode" "HI")
1994 (set_attr "length_immediate" "0")])
1995
1996(define_expand "movqi"
1997 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1998 (match_operand:QI 1 "general_operand" ""))]
1999 ""
2000 "ix86_expand_move (QImode, operands); DONE;")
2001
2002;; emit_push_insn when it calls move_by_pieces requires an insn to
2003;; "push a byte". But actually we use pushw, which has the effect
2004;; of rounding the amount pushed up to a halfword.
2005
2006(define_insn "*pushqi2"
2007 [(set (match_operand:QI 0 "push_operand" "=X,X")
2008 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
2009 "!TARGET_64BIT"
2010 "@
2011 push{w}\t{|word ptr }%1
2012 push{w}\t%w1"
2013 [(set_attr "type" "push")
2014 (set_attr "mode" "HI")])
2015
2016;; For 64BIT abi we always round up to 8 bytes.
2017(define_insn "*pushqi2_rex64"
2018 [(set (match_operand:QI 0 "push_operand" "=X")
2019 (match_operand:QI 1 "nonmemory_no_elim_operand" "ri"))]
2020 "TARGET_64BIT"
2021 "push{q}\t%q1"
2022 [(set_attr "type" "push")
2023 (set_attr "mode" "QI")])
2024
2025;; Situation is quite tricky about when to choose full sized (SImode) move
2026;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2027;; partial register dependency machines (such as AMD Athlon), where QImode
2028;; moves issue extra dependency and for partial register stalls machines
2029;; that don't use QImode patterns (and QImode move cause stall on the next
2030;; instruction).
2031;;
2032;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2033;; register stall machines with, where we use QImode instructions, since
2034;; partial register stall can be caused there. Then we use movzx.
2035(define_insn "*movqi_1"
2036 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2037 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2038 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
2039{
2040 switch (get_attr_type (insn))
2041 {
2042 case TYPE_IMOVX:
2043 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
2044 abort ();
2045 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2046 default:
2047 if (get_attr_mode (insn) == MODE_SI)
2048 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2049 else
2050 return "mov{b}\t{%1, %0|%0, %1}";
2051 }
2052}
2053 [(set (attr "type")
2054 (cond [(and (eq_attr "alternative" "3")
2055 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2056 (const_int 0))
2057 (eq (symbol_ref "TARGET_QIMODE_MATH")
2058 (const_int 0))))
2059 (const_string "imov")
2060 (eq_attr "alternative" "3,5")
2061 (const_string "imovx")
2062 (and (ne (symbol_ref "TARGET_MOVX")
2063 (const_int 0))
2064 (eq_attr "alternative" "2"))
2065 (const_string "imovx")
2066 ]
2067 (const_string "imov")))
2068 (set (attr "mode")
2069 (cond [(eq_attr "alternative" "3,4,5")
2070 (const_string "SI")
2071 (eq_attr "alternative" "6")
2072 (const_string "QI")
2073 (eq_attr "type" "imovx")
2074 (const_string "SI")
2075 (and (eq_attr "type" "imov")
2076 (and (eq_attr "alternative" "0,1,2")
2077 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2078 (const_int 0))))
2079 (const_string "SI")
2080 ;; Avoid partial register stalls when not using QImode arithmetic
2081 (and (eq_attr "type" "imov")
2082 (and (eq_attr "alternative" "0,1,2")
2083 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2084 (const_int 0))
2085 (eq (symbol_ref "TARGET_QIMODE_MATH")
2086 (const_int 0)))))
2087 (const_string "SI")
2088 ]
2089 (const_string "QI")))])
2090
2091(define_expand "reload_outqi"
2092 [(parallel [(match_operand:QI 0 "" "=m")
2093 (match_operand:QI 1 "register_operand" "r")
2094 (match_operand:QI 2 "register_operand" "=&q")])]
2095 ""
2096{
2097 rtx op0, op1, op2;
2098 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
2099
2100 if (reg_overlap_mentioned_p (op2, op0))
2101 abort ();
2102 if (! q_regs_operand (op1, QImode))
2103 {
2104 emit_insn (gen_movqi (op2, op1));
2105 op1 = op2;
2106 }
2107 emit_insn (gen_movqi (op0, op1));
2108 DONE;
2109})
2110
2111(define_insn "*swapqi"
2112 [(set (match_operand:QI 0 "register_operand" "+r")
2113 (match_operand:QI 1 "register_operand" "+r"))
2114 (set (match_dup 1)
2115 (match_dup 0))]
2116 ""
2117 "xchg{b}\t%1, %0"
2118 [(set_attr "type" "imov")
2119 (set_attr "pent_pair" "np")
2120 (set_attr "mode" "QI")
2121 (set_attr "modrm" "0")
2122 (set_attr "ppro_uops" "few")])
2123
2124(define_expand "movstrictqi"
2125 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2126 (match_operand:QI 1 "general_operand" ""))]
2127 "! TARGET_PARTIAL_REG_STALL"
2128{
2129 /* Don't generate memory->memory moves, go through a register. */
2130 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2131 operands[1] = force_reg (QImode, operands[1]);
2132})
2133
2134(define_insn "*movstrictqi_1"
2135 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2136 (match_operand:QI 1 "general_operand" "*qn,m"))]
2137 "! TARGET_PARTIAL_REG_STALL
2138 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2139 "mov{b}\t{%1, %0|%0, %1}"
2140 [(set_attr "type" "imov")
2141 (set_attr "mode" "QI")])
2142
2143(define_insn "*movstrictqi_xor"
2144 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2145 (match_operand:QI 1 "const0_operand" "i"))
2146 (clobber (reg:CC 17))]
2147 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
2148 "xor{b}\t{%0, %0|%0, %0}"
2149 [(set_attr "type" "alu1")
2150 (set_attr "mode" "QI")
2151 (set_attr "length_immediate" "0")])
2152
2153(define_insn "*movsi_extv_1"
2154 [(set (match_operand:SI 0 "register_operand" "=R")
2155 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2156 (const_int 8)
2157 (const_int 8)))]
2158 ""
2159 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2160 [(set_attr "type" "imovx")
2161 (set_attr "mode" "SI")])
2162
2163(define_insn "*movhi_extv_1"
2164 [(set (match_operand:HI 0 "register_operand" "=R")
2165 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2166 (const_int 8)
2167 (const_int 8)))]
2168 ""
2169 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2170 [(set_attr "type" "imovx")
2171 (set_attr "mode" "SI")])
2172
2173(define_insn "*movqi_extv_1"
2174 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2175 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2176 (const_int 8)
2177 (const_int 8)))]
2178 "!TARGET_64BIT"
2179{
2180 switch (get_attr_type (insn))
2181 {
2182 case TYPE_IMOVX:
2183 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2184 default:
2185 return "mov{b}\t{%h1, %0|%0, %h1}";
2186 }
2187}
2188 [(set (attr "type")
2189 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2190 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2191 (ne (symbol_ref "TARGET_MOVX")
2192 (const_int 0))))
2193 (const_string "imovx")
2194 (const_string "imov")))
2195 (set (attr "mode")
2196 (if_then_else (eq_attr "type" "imovx")
2197 (const_string "SI")
2198 (const_string "QI")))])
2199
2200(define_insn "*movqi_extv_1_rex64"
2201 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2202 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2203 (const_int 8)
2204 (const_int 8)))]
2205 "TARGET_64BIT"
2206{
2207 switch (get_attr_type (insn))
2208 {
2209 case TYPE_IMOVX:
2210 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2211 default:
2212 return "mov{b}\t{%h1, %0|%0, %h1}";
2213 }
2214}
2215 [(set (attr "type")
2216 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2217 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2218 (ne (symbol_ref "TARGET_MOVX")
2219 (const_int 0))))
2220 (const_string "imovx")
2221 (const_string "imov")))
2222 (set (attr "mode")
2223 (if_then_else (eq_attr "type" "imovx")
2224 (const_string "SI")
2225 (const_string "QI")))])
2226
2227;; Stores and loads of ax to arbitary constant address.
2228;; We fake an second form of instruction to force reload to load address
2229;; into register when rax is not available
2230(define_insn "*movabsqi_1_rex64"
2231 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2232 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
2233 "TARGET_64BIT"
2234 "@
2235 movabs{b}\t{%1, %P0|%P0, %1}
2236 mov{b}\t{%1, %a0|%a0, %1}
2237 movabs{b}\t{%1, %a0|%a0, %1}"
2238 [(set_attr "type" "imov")
2239 (set_attr "modrm" "0,*,*")
2240 (set_attr "length_address" "8,0,0")
2241 (set_attr "length_immediate" "0,*,*")
2242 (set_attr "memory" "store")
2243 (set_attr "mode" "QI")])
2244
2245(define_insn "*movabsqi_2_rex64"
2246 [(set (match_operand:QI 0 "register_operand" "=a,r")
2247 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2248 "TARGET_64BIT"
2249 "@
2250 movabs{b}\t{%P1, %0|%0, %P1}
2251 mov{b}\t{%a1, %0|%0, %a1}"
2252 [(set_attr "type" "imov")
2253 (set_attr "modrm" "0,*")
2254 (set_attr "length_address" "8,0")
2255 (set_attr "length_immediate" "0")
2256 (set_attr "memory" "load")
2257 (set_attr "mode" "QI")])
2258
2259(define_insn "*movsi_extzv_1"
2260 [(set (match_operand:SI 0 "register_operand" "=R")
2261 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2262 (const_int 8)
2263 (const_int 8)))]
2264 ""
2265 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2266 [(set_attr "type" "imovx")
2267 (set_attr "mode" "SI")])
2268
2269(define_insn "*movqi_extzv_2"
2270 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2271 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2272 (const_int 8)
2273 (const_int 8)) 0))]
2274 "!TARGET_64BIT"
2275{
2276 switch (get_attr_type (insn))
2277 {
2278 case TYPE_IMOVX:
2279 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2280 default:
2281 return "mov{b}\t{%h1, %0|%0, %h1}";
2282 }
2283}
2284 [(set (attr "type")
2285 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2286 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2287 (ne (symbol_ref "TARGET_MOVX")
2288 (const_int 0))))
2289 (const_string "imovx")
2290 (const_string "imov")))
2291 (set (attr "mode")
2292 (if_then_else (eq_attr "type" "imovx")
2293 (const_string "SI")
2294 (const_string "QI")))])
2295
2296(define_insn "*movqi_extzv_2_rex64"
2297 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2298 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2299 (const_int 8)
2300 (const_int 8)) 0))]
2301 "TARGET_64BIT"
2302{
2303 switch (get_attr_type (insn))
2304 {
2305 case TYPE_IMOVX:
2306 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2307 default:
2308 return "mov{b}\t{%h1, %0|%0, %h1}";
2309 }
2310}
2311 [(set (attr "type")
2312 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2313 (ne (symbol_ref "TARGET_MOVX")
2314 (const_int 0)))
2315 (const_string "imovx")
2316 (const_string "imov")))
2317 (set (attr "mode")
2318 (if_then_else (eq_attr "type" "imovx")
2319 (const_string "SI")
2320 (const_string "QI")))])
2321
2322(define_insn "movsi_insv_1"
2323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2324 (const_int 8)
2325 (const_int 8))
2326 (match_operand:SI 1 "general_operand" "Qmn"))]
2327 "!TARGET_64BIT"
2328 "mov{b}\t{%b1, %h0|%h0, %b1}"
2329 [(set_attr "type" "imov")
2330 (set_attr "mode" "QI")])
2331
2332(define_insn "*movsi_insv_1_rex64"
2333 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2334 (const_int 8)
2335 (const_int 8))
2336 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2337 "TARGET_64BIT"
2338 "mov{b}\t{%b1, %h0|%h0, %b1}"
2339 [(set_attr "type" "imov")
2340 (set_attr "mode" "QI")])
2341
2342(define_insn "*movqi_insv_2"
2343 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2344 (const_int 8)
2345 (const_int 8))
2346 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2347 (const_int 8))
2348 (const_int 255)))]
2349 ""
2350 "mov{b}\t{%h1, %h0|%h0, %h1}"
2351 [(set_attr "type" "imov")
2352 (set_attr "mode" "QI")])
2353
2354(define_expand "movdi"
2355 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2356 (match_operand:DI 1 "general_operand" ""))]
2357 ""
2358 "ix86_expand_move (DImode, operands); DONE;")
2359
2360(define_insn "*pushdi"
2361 [(set (match_operand:DI 0 "push_operand" "=<")
2362 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2363 "!TARGET_64BIT"
2364 "#")
2365
2366(define_insn "pushdi2_rex64"
2367 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2368 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2369 "TARGET_64BIT"
2370 "@
2371 push{q}\t%1
2372 #"
2373 [(set_attr "type" "push,multi")
2374 (set_attr "mode" "DI")])
2375
2376;; Convert impossible pushes of immediate to existing instructions.
2377;; First try to get scratch register and go through it. In case this
2378;; fails, push sign extended lower part first and then overwrite
2379;; upper part by 32bit move.
2380(define_peephole2
2381 [(match_scratch:DI 2 "r")
2382 (set (match_operand:DI 0 "push_operand" "")
2383 (match_operand:DI 1 "immediate_operand" ""))]
2384 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2385 && !x86_64_immediate_operand (operands[1], DImode)"
2386 [(set (match_dup 2) (match_dup 1))
2387 (set (match_dup 0) (match_dup 2))]
2388 "")
2389
2390;; We need to define this as both peepholer and splitter for case
2391;; peephole2 pass is not run.
2392(define_peephole2
2393 [(set (match_operand:DI 0 "push_operand" "")
2394 (match_operand:DI 1 "immediate_operand" ""))]
2395 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2396 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2397 [(set (match_dup 0) (match_dup 1))
2398 (set (match_dup 2) (match_dup 3))]
2399 "split_di (operands + 1, 1, operands + 2, operands + 3);
2400 operands[1] = gen_lowpart (DImode, operands[2]);
2401 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2402 GEN_INT (4)));
2403 ")
2404
2405(define_split
2406 [(set (match_operand:DI 0 "push_operand" "")
2407 (match_operand:DI 1 "immediate_operand" ""))]
2408 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2409 && !symbolic_operand (operands[1], DImode)
2410 && !x86_64_immediate_operand (operands[1], DImode)"
2411 [(set (match_dup 0) (match_dup 1))
2412 (set (match_dup 2) (match_dup 3))]
2413 "split_di (operands + 1, 1, operands + 2, operands + 3);
2414 operands[1] = gen_lowpart (DImode, operands[2]);
2415 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2416 GEN_INT (4)));
2417 ")
2418
2419(define_insn "*pushdi2_prologue_rex64"
2420 [(set (match_operand:DI 0 "push_operand" "=<")
2421 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2422 (clobber (mem:BLK (scratch)))]
2423 "TARGET_64BIT"
2424 "push{q}\t%1"
2425 [(set_attr "type" "push")
2426 (set_attr "mode" "DI")])
2427
2428(define_insn "*popdi1_epilogue_rex64"
2429 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2430 (mem:DI (reg:DI 7)))
2431 (set (reg:DI 7)
2432 (plus:DI (reg:DI 7) (const_int 8)))
2433 (clobber (mem:BLK (scratch)))]
2434 "TARGET_64BIT"
2435 "pop{q}\t%0"
2436 [(set_attr "type" "pop")
2437 (set_attr "mode" "DI")])
2438
2439(define_insn "popdi1"
2440 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2441 (mem:DI (reg:DI 7)))
2442 (set (reg:DI 7)
2443 (plus:DI (reg:DI 7) (const_int 8)))]
2444 "TARGET_64BIT"
2445 "pop{q}\t%0"
2446 [(set_attr "type" "pop")
2447 (set_attr "mode" "DI")])
2448
2449(define_insn "*movdi_xor_rex64"
2450 [(set (match_operand:DI 0 "register_operand" "=r")
2451 (match_operand:DI 1 "const0_operand" "i"))
2452 (clobber (reg:CC 17))]
2453 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2454 && reload_completed"
2455 "xor{l}\t{%k0, %k0|%k0, %k0}"
2456 [(set_attr "type" "alu1")
2457 (set_attr "mode" "SI")
2458 (set_attr "length_immediate" "0")])
2459
2460(define_insn "*movdi_or_rex64"
2461 [(set (match_operand:DI 0 "register_operand" "=r")
2462 (match_operand:DI 1 "const_int_operand" "i"))
2463 (clobber (reg:CC 17))]
2464 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
2465 && reload_completed
2466 && GET_CODE (operands[1]) == CONST_INT
2467 && INTVAL (operands[1]) == -1"
2468{
2469 operands[1] = constm1_rtx;
2470 return "or{q}\t{%1, %0|%0, %1}";
2471}
2472 [(set_attr "type" "alu1")
2473 (set_attr "mode" "DI")
2474 (set_attr "length_immediate" "1")])
2475
2476(define_insn "*movdi_2"
2465 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,*Y,!*Y")
2477 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
2466 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
2467 "!TARGET_64BIT
2468 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2469 "@
2470 #
2471 #
2472 movq\t{%1, %0|%0, %1}
2473 movq\t{%1, %0|%0, %1}
2474 movq\t{%1, %0|%0, %1}
2475 movdqa\t{%1, %0|%0, %1}
2476 movq\t{%1, %0|%0, %1}"
2477 [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
2478 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
2479
2480(define_split
2481 [(set (match_operand:DI 0 "push_operand" "")
2482 (match_operand:DI 1 "general_operand" ""))]
2483 "!TARGET_64BIT && reload_completed
2484 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2485 [(const_int 0)]
2486 "ix86_split_long_move (operands); DONE;")
2487
2488;; %%% This multiword shite has got to go.
2489(define_split
2490 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2491 (match_operand:DI 1 "general_operand" ""))]
2492 "!TARGET_64BIT && reload_completed
2493 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2494 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2495 [(const_int 0)]
2496 "ix86_split_long_move (operands); DONE;")
2497
2498(define_insn "*movdi_1_rex64"
2499 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
2500 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
2501 "TARGET_64BIT
2502 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2503{
2504 switch (get_attr_type (insn))
2505 {
2506 case TYPE_SSE:
2507 if (register_operand (operands[0], DImode)
2508 && register_operand (operands[1], DImode))
2509 return "movdqa\t{%1, %0|%0, %1}";
2510 /* FALLTHRU */
2511 case TYPE_MMX:
2512 return "movq\t{%1, %0|%0, %1}";
2513 case TYPE_MULTI:
2514 return "#";
2515 case TYPE_LEA:
2516 return "lea{q}\t{%a1, %0|%0, %a1}";
2517 default:
2518 if (flag_pic && SYMBOLIC_CONST (operands[1]))
2519 abort ();
2520 if (get_attr_mode (insn) == MODE_SI)
2521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2522 else if (which_alternative == 2)
2523 return "movabs{q}\t{%1, %0|%0, %1}";
2524 else
2525 return "mov{q}\t{%1, %0|%0, %1}";
2526 }
2527}
2528 [(set (attr "type")
2529 (cond [(eq_attr "alternative" "5,6")
2530 (const_string "mmx")
2531 (eq_attr "alternative" "7,8")
2532 (const_string "sse")
2533 (eq_attr "alternative" "4")
2534 (const_string "multi")
2535 (and (ne (symbol_ref "flag_pic") (const_int 0))
2536 (match_operand:DI 1 "symbolic_operand" ""))
2537 (const_string "lea")
2538 ]
2539 (const_string "imov")))
2540 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
2541 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
2542 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
2543
2544;; Stores and loads of ax to arbitary constant address.
2545;; We fake an second form of instruction to force reload to load address
2546;; into register when rax is not available
2547(define_insn "*movabsdi_1_rex64"
2548 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2549 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2550 "TARGET_64BIT"
2551 "@
2552 movabs{q}\t{%1, %P0|%P0, %1}
2553 mov{q}\t{%1, %a0|%a0, %1}
2554 movabs{q}\t{%1, %a0|%a0, %1}"
2555 [(set_attr "type" "imov")
2556 (set_attr "modrm" "0,*,*")
2557 (set_attr "length_address" "8,0,0")
2558 (set_attr "length_immediate" "0,*,*")
2559 (set_attr "memory" "store")
2560 (set_attr "mode" "DI")])
2561
2562(define_insn "*movabsdi_2_rex64"
2563 [(set (match_operand:DI 0 "register_operand" "=a,r")
2564 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2565 "TARGET_64BIT"
2566 "@
2567 movabs{q}\t{%P1, %0|%0, %P1}
2568 mov{q}\t{%a1, %0|%0, %a1}"
2569 [(set_attr "type" "imov")
2570 (set_attr "modrm" "0,*")
2571 (set_attr "length_address" "8,0")
2572 (set_attr "length_immediate" "0")
2573 (set_attr "memory" "load")
2574 (set_attr "mode" "DI")])
2575
2576;; Convert impossible stores of immediate to existing instructions.
2577;; First try to get scratch register and go through it. In case this
2578;; fails, move by 32bit parts.
2579(define_peephole2
2580 [(match_scratch:DI 2 "r")
2581 (set (match_operand:DI 0 "memory_operand" "")
2582 (match_operand:DI 1 "immediate_operand" ""))]
2583 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2584 && !x86_64_immediate_operand (operands[1], DImode)"
2585 [(set (match_dup 2) (match_dup 1))
2586 (set (match_dup 0) (match_dup 2))]
2587 "")
2588
2589;; We need to define this as both peepholer and splitter for case
2590;; peephole2 pass is not run.
2591(define_peephole2
2592 [(set (match_operand:DI 0 "memory_operand" "")
2593 (match_operand:DI 1 "immediate_operand" ""))]
2594 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2595 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2596 [(set (match_dup 2) (match_dup 3))
2597 (set (match_dup 4) (match_dup 5))]
2598 "split_di (operands, 2, operands + 2, operands + 4);")
2599
2600(define_split
2601 [(set (match_operand:DI 0 "memory_operand" "")
2602 (match_operand:DI 1 "immediate_operand" ""))]
2603 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2604 && !symbolic_operand (operands[1], DImode)
2605 && !x86_64_immediate_operand (operands[1], DImode)"
2606 [(set (match_dup 2) (match_dup 3))
2607 (set (match_dup 4) (match_dup 5))]
2608 "split_di (operands, 2, operands + 2, operands + 4);")
2609
2610(define_insn "*swapdi_rex64"
2611 [(set (match_operand:DI 0 "register_operand" "+r")
2612 (match_operand:DI 1 "register_operand" "+r"))
2613 (set (match_dup 1)
2614 (match_dup 0))]
2615 "TARGET_64BIT"
2616 "xchg{q}\t%1, %0"
2617 [(set_attr "type" "imov")
2618 (set_attr "pent_pair" "np")
2619 (set_attr "athlon_decode" "vector")
2620 (set_attr "mode" "DI")
2621 (set_attr "modrm" "0")
2622 (set_attr "ppro_uops" "few")])
2623
2624
2625(define_expand "movsf"
2626 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2627 (match_operand:SF 1 "general_operand" ""))]
2628 ""
2629 "ix86_expand_move (SFmode, operands); DONE;")
2630
2631(define_insn "*pushsf"
2632 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2633 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2634 "!TARGET_64BIT"
2635{
2636 switch (which_alternative)
2637 {
2638 case 0:
2639 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2640 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2641 operands[2] = stack_pointer_rtx;
2642 operands[3] = GEN_INT (4);
2643 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2644 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2645 else
2646 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2647
2648 case 1:
2649 return "push{l}\t%1";
2650 case 2:
2651 return "#";
2652
2653 default:
2654 abort ();
2655 }
2656}
2657 [(set_attr "type" "multi,push,multi")
2658 (set_attr "mode" "SF,SI,SF")])
2659
2660(define_insn "*pushsf_rex64"
2661 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2662 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2663 "TARGET_64BIT"
2664{
2665 switch (which_alternative)
2666 {
2667 case 0:
2668 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2669 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2670 operands[2] = stack_pointer_rtx;
2671 operands[3] = GEN_INT (8);
2672 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2673 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2674 else
2675 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2676
2677 case 1:
2678 return "push{q}\t%q1";
2679
2680 case 2:
2681 return "#";
2682
2683 default:
2684 abort ();
2685 }
2686}
2687 [(set_attr "type" "multi,push,multi")
2688 (set_attr "mode" "SF,DI,SF")])
2689
2690(define_split
2691 [(set (match_operand:SF 0 "push_operand" "")
2692 (match_operand:SF 1 "memory_operand" ""))]
2693 "reload_completed
2694 && GET_CODE (operands[1]) == MEM
2695 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2696 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2697 [(set (match_dup 0)
2698 (match_dup 1))]
2699 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2700
2701
2702;; %%% Kill this when call knows how to work this out.
2703(define_split
2704 [(set (match_operand:SF 0 "push_operand" "")
2705 (match_operand:SF 1 "register_operand" ""))]
2706 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2707 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2708 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2709
2710(define_split
2711 [(set (match_operand:SF 0 "push_operand" "")
2712 (match_operand:SF 1 "register_operand" ""))]
2713 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2714 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2715 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2716
2717(define_insn "*movsf_1"
2478 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
2479 "!TARGET_64BIT
2480 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2481 "@
2482 #
2483 #
2484 movq\t{%1, %0|%0, %1}
2485 movq\t{%1, %0|%0, %1}
2486 movq\t{%1, %0|%0, %1}
2487 movdqa\t{%1, %0|%0, %1}
2488 movq\t{%1, %0|%0, %1}"
2489 [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
2490 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
2491
2492(define_split
2493 [(set (match_operand:DI 0 "push_operand" "")
2494 (match_operand:DI 1 "general_operand" ""))]
2495 "!TARGET_64BIT && reload_completed
2496 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2497 [(const_int 0)]
2498 "ix86_split_long_move (operands); DONE;")
2499
2500;; %%% This multiword shite has got to go.
2501(define_split
2502 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2503 (match_operand:DI 1 "general_operand" ""))]
2504 "!TARGET_64BIT && reload_completed
2505 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2506 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2507 [(const_int 0)]
2508 "ix86_split_long_move (operands); DONE;")
2509
2510(define_insn "*movdi_1_rex64"
2511 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
2512 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
2513 "TARGET_64BIT
2514 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2515{
2516 switch (get_attr_type (insn))
2517 {
2518 case TYPE_SSE:
2519 if (register_operand (operands[0], DImode)
2520 && register_operand (operands[1], DImode))
2521 return "movdqa\t{%1, %0|%0, %1}";
2522 /* FALLTHRU */
2523 case TYPE_MMX:
2524 return "movq\t{%1, %0|%0, %1}";
2525 case TYPE_MULTI:
2526 return "#";
2527 case TYPE_LEA:
2528 return "lea{q}\t{%a1, %0|%0, %a1}";
2529 default:
2530 if (flag_pic && SYMBOLIC_CONST (operands[1]))
2531 abort ();
2532 if (get_attr_mode (insn) == MODE_SI)
2533 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2534 else if (which_alternative == 2)
2535 return "movabs{q}\t{%1, %0|%0, %1}";
2536 else
2537 return "mov{q}\t{%1, %0|%0, %1}";
2538 }
2539}
2540 [(set (attr "type")
2541 (cond [(eq_attr "alternative" "5,6")
2542 (const_string "mmx")
2543 (eq_attr "alternative" "7,8")
2544 (const_string "sse")
2545 (eq_attr "alternative" "4")
2546 (const_string "multi")
2547 (and (ne (symbol_ref "flag_pic") (const_int 0))
2548 (match_operand:DI 1 "symbolic_operand" ""))
2549 (const_string "lea")
2550 ]
2551 (const_string "imov")))
2552 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
2553 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
2554 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
2555
2556;; Stores and loads of ax to arbitary constant address.
2557;; We fake an second form of instruction to force reload to load address
2558;; into register when rax is not available
2559(define_insn "*movabsdi_1_rex64"
2560 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2561 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2562 "TARGET_64BIT"
2563 "@
2564 movabs{q}\t{%1, %P0|%P0, %1}
2565 mov{q}\t{%1, %a0|%a0, %1}
2566 movabs{q}\t{%1, %a0|%a0, %1}"
2567 [(set_attr "type" "imov")
2568 (set_attr "modrm" "0,*,*")
2569 (set_attr "length_address" "8,0,0")
2570 (set_attr "length_immediate" "0,*,*")
2571 (set_attr "memory" "store")
2572 (set_attr "mode" "DI")])
2573
2574(define_insn "*movabsdi_2_rex64"
2575 [(set (match_operand:DI 0 "register_operand" "=a,r")
2576 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2577 "TARGET_64BIT"
2578 "@
2579 movabs{q}\t{%P1, %0|%0, %P1}
2580 mov{q}\t{%a1, %0|%0, %a1}"
2581 [(set_attr "type" "imov")
2582 (set_attr "modrm" "0,*")
2583 (set_attr "length_address" "8,0")
2584 (set_attr "length_immediate" "0")
2585 (set_attr "memory" "load")
2586 (set_attr "mode" "DI")])
2587
2588;; Convert impossible stores of immediate to existing instructions.
2589;; First try to get scratch register and go through it. In case this
2590;; fails, move by 32bit parts.
2591(define_peephole2
2592 [(match_scratch:DI 2 "r")
2593 (set (match_operand:DI 0 "memory_operand" "")
2594 (match_operand:DI 1 "immediate_operand" ""))]
2595 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2596 && !x86_64_immediate_operand (operands[1], DImode)"
2597 [(set (match_dup 2) (match_dup 1))
2598 (set (match_dup 0) (match_dup 2))]
2599 "")
2600
2601;; We need to define this as both peepholer and splitter for case
2602;; peephole2 pass is not run.
2603(define_peephole2
2604 [(set (match_operand:DI 0 "memory_operand" "")
2605 (match_operand:DI 1 "immediate_operand" ""))]
2606 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2607 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2608 [(set (match_dup 2) (match_dup 3))
2609 (set (match_dup 4) (match_dup 5))]
2610 "split_di (operands, 2, operands + 2, operands + 4);")
2611
2612(define_split
2613 [(set (match_operand:DI 0 "memory_operand" "")
2614 (match_operand:DI 1 "immediate_operand" ""))]
2615 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2616 && !symbolic_operand (operands[1], DImode)
2617 && !x86_64_immediate_operand (operands[1], DImode)"
2618 [(set (match_dup 2) (match_dup 3))
2619 (set (match_dup 4) (match_dup 5))]
2620 "split_di (operands, 2, operands + 2, operands + 4);")
2621
2622(define_insn "*swapdi_rex64"
2623 [(set (match_operand:DI 0 "register_operand" "+r")
2624 (match_operand:DI 1 "register_operand" "+r"))
2625 (set (match_dup 1)
2626 (match_dup 0))]
2627 "TARGET_64BIT"
2628 "xchg{q}\t%1, %0"
2629 [(set_attr "type" "imov")
2630 (set_attr "pent_pair" "np")
2631 (set_attr "athlon_decode" "vector")
2632 (set_attr "mode" "DI")
2633 (set_attr "modrm" "0")
2634 (set_attr "ppro_uops" "few")])
2635
2636
2637(define_expand "movsf"
2638 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2639 (match_operand:SF 1 "general_operand" ""))]
2640 ""
2641 "ix86_expand_move (SFmode, operands); DONE;")
2642
2643(define_insn "*pushsf"
2644 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2645 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2646 "!TARGET_64BIT"
2647{
2648 switch (which_alternative)
2649 {
2650 case 0:
2651 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2652 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2653 operands[2] = stack_pointer_rtx;
2654 operands[3] = GEN_INT (4);
2655 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2656 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2657 else
2658 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2659
2660 case 1:
2661 return "push{l}\t%1";
2662 case 2:
2663 return "#";
2664
2665 default:
2666 abort ();
2667 }
2668}
2669 [(set_attr "type" "multi,push,multi")
2670 (set_attr "mode" "SF,SI,SF")])
2671
2672(define_insn "*pushsf_rex64"
2673 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2674 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2675 "TARGET_64BIT"
2676{
2677 switch (which_alternative)
2678 {
2679 case 0:
2680 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2681 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2682 operands[2] = stack_pointer_rtx;
2683 operands[3] = GEN_INT (8);
2684 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2685 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2686 else
2687 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2688
2689 case 1:
2690 return "push{q}\t%q1";
2691
2692 case 2:
2693 return "#";
2694
2695 default:
2696 abort ();
2697 }
2698}
2699 [(set_attr "type" "multi,push,multi")
2700 (set_attr "mode" "SF,DI,SF")])
2701
2702(define_split
2703 [(set (match_operand:SF 0 "push_operand" "")
2704 (match_operand:SF 1 "memory_operand" ""))]
2705 "reload_completed
2706 && GET_CODE (operands[1]) == MEM
2707 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2708 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2709 [(set (match_dup 0)
2710 (match_dup 1))]
2711 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2712
2713
2714;; %%% Kill this when call knows how to work this out.
2715(define_split
2716 [(set (match_operand:SF 0 "push_operand" "")
2717 (match_operand:SF 1 "register_operand" ""))]
2718 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2719 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2720 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2721
2722(define_split
2723 [(set (match_operand:SF 0 "push_operand" "")
2724 (match_operand:SF 1 "register_operand" ""))]
2725 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2726 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2727 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2728
2729(define_insn "*movsf_1"
2718 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m")
2719 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
2730 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2731 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
2720 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2721 && (reload_in_progress || reload_completed
2722 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2723 || GET_CODE (operands[1]) != CONST_DOUBLE
2724 || memory_operand (operands[0], SFmode))"
2725{
2726 switch (which_alternative)
2727 {
2728 case 0:
2729 if (REG_P (operands[1])
2730 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2731 return "fstp\t%y0";
2732 else if (STACK_TOP_P (operands[0]))
2733 return "fld%z1\t%y1";
2734 else
2735 return "fst\t%y0";
2736
2737 case 1:
2738 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2739 return "fstp%z0\t%y0";
2740 else
2741 return "fst%z0\t%y0";
2742
2743 case 2:
2744 switch (standard_80387_constant_p (operands[1]))
2745 {
2746 case 1:
2747 return "fldz";
2748 case 2:
2749 return "fld1";
2750 }
2751 abort();
2752
2753 case 3:
2754 case 4:
2755 return "mov{l}\t{%1, %0|%0, %1}";
2756 case 5:
2732 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2733 && (reload_in_progress || reload_completed
2734 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2735 || GET_CODE (operands[1]) != CONST_DOUBLE
2736 || memory_operand (operands[0], SFmode))"
2737{
2738 switch (which_alternative)
2739 {
2740 case 0:
2741 if (REG_P (operands[1])
2742 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2743 return "fstp\t%y0";
2744 else if (STACK_TOP_P (operands[0]))
2745 return "fld%z1\t%y1";
2746 else
2747 return "fst\t%y0";
2748
2749 case 1:
2750 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2751 return "fstp%z0\t%y0";
2752 else
2753 return "fst%z0\t%y0";
2754
2755 case 2:
2756 switch (standard_80387_constant_p (operands[1]))
2757 {
2758 case 1:
2759 return "fldz";
2760 case 2:
2761 return "fld1";
2762 }
2763 abort();
2764
2765 case 3:
2766 case 4:
2767 return "mov{l}\t{%1, %0|%0, %1}";
2768 case 5:
2757 return "pxor\t%0, %0";
2769 if (TARGET_SSE2)
2770 return "pxor\t%0, %0";
2771 else
2772 return "xorps\t%0, %0";
2758 case 6:
2759 if (TARGET_PARTIAL_REG_DEPENDENCY)
2760 return "movaps\t{%1, %0|%0, %1}";
2761 else
2762 return "movss\t{%1, %0|%0, %1}";
2763 case 7:
2764 case 8:
2765 return "movss\t{%1, %0|%0, %1}";
2766
2773 case 6:
2774 if (TARGET_PARTIAL_REG_DEPENDENCY)
2775 return "movaps\t{%1, %0|%0, %1}";
2776 else
2777 return "movss\t{%1, %0|%0, %1}";
2778 case 7:
2779 case 8:
2780 return "movss\t{%1, %0|%0, %1}";
2781
2782 case 9:
2783 case 10:
2784 return "movd\t{%1, %0|%0, %1}";
2785
2786 case 11:
2787 return "movq\t{%1, %0|%0, %1}";
2788
2767 default:
2768 abort();
2769 }
2770}
2789 default:
2790 abort();
2791 }
2792}
2771 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
2772 (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
2793 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx,mmx")
2794 (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
2773
2774(define_insn "*swapsf"
2775 [(set (match_operand:SF 0 "register_operand" "+f")
2776 (match_operand:SF 1 "register_operand" "+f"))
2777 (set (match_dup 1)
2778 (match_dup 0))]
2779 "reload_completed || !TARGET_SSE"
2780{
2781 if (STACK_TOP_P (operands[0]))
2782 return "fxch\t%1";
2783 else
2784 return "fxch\t%0";
2785}
2786 [(set_attr "type" "fxch")
2787 (set_attr "mode" "SF")])
2788
2789(define_expand "movdf"
2790 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2791 (match_operand:DF 1 "general_operand" ""))]
2792 ""
2793 "ix86_expand_move (DFmode, operands); DONE;")
2794
2795;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2796;; Size of pushdf using integer insturctions is 2+2*memory operand size
2797;; On the average, pushdf using integers can be still shorter. Allow this
2798;; pattern for optimize_size too.
2799
2800(define_insn "*pushdf_nointeger"
2801 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2802 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2803 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2804{
2805 switch (which_alternative)
2806 {
2807 case 0:
2808 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2809 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2810 operands[2] = stack_pointer_rtx;
2811 operands[3] = GEN_INT (8);
2812 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2813 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2814 else
2815 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2816
2817 case 1:
2818 case 2:
2819 case 3:
2820 return "#";
2821
2822 default:
2823 abort ();
2824 }
2825}
2826 [(set_attr "type" "multi")
2827 (set_attr "mode" "DF,SI,SI,DF")])
2828
2829(define_insn "*pushdf_integer"
2830 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2831 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2832 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2833{
2834 switch (which_alternative)
2835 {
2836 case 0:
2837 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2838 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2839 operands[2] = stack_pointer_rtx;
2840 operands[3] = GEN_INT (8);
2841 if (TARGET_64BIT)
2842 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2843 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2844 else
2845 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2846 else
2847 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2848 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2849 else
2850 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2851
2852
2853 case 1:
2854 case 2:
2855 return "#";
2856
2857 default:
2858 abort ();
2859 }
2860}
2861 [(set_attr "type" "multi")
2862 (set_attr "mode" "DF,SI,DF")])
2863
2864;; %%% Kill this when call knows how to work this out.
2865(define_split
2866 [(set (match_operand:DF 0 "push_operand" "")
2867 (match_operand:DF 1 "register_operand" ""))]
2868 "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2869 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2870 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2871 "")
2872
2873(define_split
2874 [(set (match_operand:DF 0 "push_operand" "")
2875 (match_operand:DF 1 "register_operand" ""))]
2876 "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2877 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2878 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2879 "")
2880
2881(define_split
2882 [(set (match_operand:DF 0 "push_operand" "")
2883 (match_operand:DF 1 "general_operand" ""))]
2884 "reload_completed"
2885 [(const_int 0)]
2886 "ix86_split_long_move (operands); DONE;")
2887
2888;; Moving is usually shorter when only FP registers are used. This separate
2889;; movdf pattern avoids the use of integer registers for FP operations
2890;; when optimizing for size.
2891
2892(define_insn "*movdf_nointeger"
2893 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2894 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
2895 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2896 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2897 && (reload_in_progress || reload_completed
2898 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2899 || GET_CODE (operands[1]) != CONST_DOUBLE
2900 || memory_operand (operands[0], DFmode))"
2901{
2902 switch (which_alternative)
2903 {
2904 case 0:
2905 if (REG_P (operands[1])
2906 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2907 return "fstp\t%y0";
2908 else if (STACK_TOP_P (operands[0]))
2909 return "fld%z1\t%y1";
2910 else
2911 return "fst\t%y0";
2912
2913 case 1:
2914 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2915 return "fstp%z0\t%y0";
2916 else
2917 return "fst%z0\t%y0";
2918
2919 case 2:
2920 switch (standard_80387_constant_p (operands[1]))
2921 {
2922 case 1:
2923 return "fldz";
2924 case 2:
2925 return "fld1";
2926 }
2927 abort();
2928
2929 case 3:
2930 case 4:
2931 return "#";
2932 case 5:
2933 return "pxor\t%0, %0";
2934 case 6:
2935 if (TARGET_PARTIAL_REG_DEPENDENCY)
2936 return "movapd\t{%1, %0|%0, %1}";
2937 else
2938 return "movsd\t{%1, %0|%0, %1}";
2939 case 7:
2940 case 8:
2941 return "movsd\t{%1, %0|%0, %1}";
2942
2943 default:
2944 abort();
2945 }
2946}
2947 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2948 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2949
2950(define_insn "*movdf_integer"
2951 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2952 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
2953 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2954 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2955 && (reload_in_progress || reload_completed
2956 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2957 || GET_CODE (operands[1]) != CONST_DOUBLE
2958 || memory_operand (operands[0], DFmode))"
2959{
2960 switch (which_alternative)
2961 {
2962 case 0:
2963 if (REG_P (operands[1])
2964 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2965 return "fstp\t%y0";
2966 else if (STACK_TOP_P (operands[0]))
2967 return "fld%z1\t%y1";
2968 else
2969 return "fst\t%y0";
2970
2971 case 1:
2972 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2973 return "fstp%z0\t%y0";
2974 else
2975 return "fst%z0\t%y0";
2976
2977 case 2:
2978 switch (standard_80387_constant_p (operands[1]))
2979 {
2980 case 1:
2981 return "fldz";
2982 case 2:
2983 return "fld1";
2984 }
2985 abort();
2986
2987 case 3:
2988 case 4:
2989 return "#";
2990
2991 case 5:
2992 return "pxor\t%0, %0";
2993 case 6:
2994 if (TARGET_PARTIAL_REG_DEPENDENCY)
2995 return "movapd\t{%1, %0|%0, %1}";
2996 else
2997 return "movsd\t{%1, %0|%0, %1}";
2998 case 7:
2999 case 8:
3000 return "movsd\t{%1, %0|%0, %1}";
3001
3002 default:
3003 abort();
3004 }
3005}
3006 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
3007 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
3008
3009(define_split
3010 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3011 (match_operand:DF 1 "general_operand" ""))]
3012 "reload_completed
3013 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3014 && ! (ANY_FP_REG_P (operands[0]) ||
3015 (GET_CODE (operands[0]) == SUBREG
3016 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3017 && ! (ANY_FP_REG_P (operands[1]) ||
3018 (GET_CODE (operands[1]) == SUBREG
3019 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3020 [(const_int 0)]
3021 "ix86_split_long_move (operands); DONE;")
3022
3023(define_insn "*swapdf"
3024 [(set (match_operand:DF 0 "register_operand" "+f")
3025 (match_operand:DF 1 "register_operand" "+f"))
3026 (set (match_dup 1)
3027 (match_dup 0))]
3028 "reload_completed || !TARGET_SSE2"
3029{
3030 if (STACK_TOP_P (operands[0]))
3031 return "fxch\t%1";
3032 else
3033 return "fxch\t%0";
3034}
3035 [(set_attr "type" "fxch")
3036 (set_attr "mode" "DF")])
3037
3038(define_expand "movxf"
3039 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3040 (match_operand:XF 1 "general_operand" ""))]
3041 "!TARGET_64BIT"
3042 "ix86_expand_move (XFmode, operands); DONE;")
3043
3044(define_expand "movtf"
3045 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3046 (match_operand:TF 1 "general_operand" ""))]
3047 ""
3048 "ix86_expand_move (TFmode, operands); DONE;")
3049
3050;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3051;; Size of pushdf using integer insturctions is 3+3*memory operand size
3052;; Pushing using integer instructions is longer except for constants
3053;; and direct memory references.
3054;; (assuming that any given constant is pushed only once, but this ought to be
3055;; handled elsewhere).
3056
3057(define_insn "*pushxf_nointeger"
3058 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3059 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3060 "!TARGET_64BIT && optimize_size"
3061{
3062 switch (which_alternative)
3063 {
3064 case 0:
3065 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3066 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3067 operands[2] = stack_pointer_rtx;
3068 operands[3] = GEN_INT (12);
3069 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3070 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3071 else
3072 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3073
3074 case 1:
3075 case 2:
3076 return "#";
3077
3078 default:
3079 abort ();
3080 }
3081}
3082 [(set_attr "type" "multi")
3083 (set_attr "mode" "XF,SI,SI")])
3084
3085(define_insn "*pushtf_nointeger"
3086 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3087 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
3088 "optimize_size"
3089{
3090 switch (which_alternative)
3091 {
3092 case 0:
3093 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3094 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3095 operands[2] = stack_pointer_rtx;
3096 operands[3] = GEN_INT (16);
3097 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3098 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3099 else
3100 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3101
3102 case 1:
3103 case 2:
3104 return "#";
3105
3106 default:
3107 abort ();
3108 }
3109}
3110 [(set_attr "type" "multi")
3111 (set_attr "mode" "XF,SI,SI")])
3112
3113(define_insn "*pushxf_integer"
3114 [(set (match_operand:XF 0 "push_operand" "=<,<")
3115 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
3116 "!TARGET_64BIT && !optimize_size"
3117{
3118 switch (which_alternative)
3119 {
3120 case 0:
3121 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3122 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3123 operands[2] = stack_pointer_rtx;
3124 operands[3] = GEN_INT (12);
3125 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3126 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3127 else
3128 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3129
3130 case 1:
3131 return "#";
3132
3133 default:
3134 abort ();
3135 }
3136}
3137 [(set_attr "type" "multi")
3138 (set_attr "mode" "XF,SI")])
3139
3140(define_insn "*pushtf_integer"
3141 [(set (match_operand:TF 0 "push_operand" "=<,<")
3142 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
3143 "!optimize_size"
3144{
3145 switch (which_alternative)
3146 {
3147 case 0:
3148 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3149 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3150 operands[2] = stack_pointer_rtx;
3151 operands[3] = GEN_INT (16);
3152 if (TARGET_64BIT)
3153 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3154 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3155 else
3156 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3157 else
3158 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3159 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3160 else
3161 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3162
3163 case 1:
3164 return "#";
3165
3166 default:
3167 abort ();
3168 }
3169}
3170 [(set_attr "type" "multi")
3171 (set_attr "mode" "XF,SI")])
3172
3173(define_split
3174 [(set (match_operand 0 "push_operand" "")
3175 (match_operand 1 "general_operand" ""))]
3176 "reload_completed
3177 && (GET_MODE (operands[0]) == XFmode
3178 || GET_MODE (operands[0]) == TFmode
3179 || GET_MODE (operands[0]) == DFmode)
3180 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
3181 [(const_int 0)]
3182 "ix86_split_long_move (operands); DONE;")
3183
3184(define_split
3185 [(set (match_operand:XF 0 "push_operand" "")
3186 (match_operand:XF 1 "register_operand" ""))]
3187 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3188 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3189 (set (mem:XF (reg:SI 7)) (match_dup 1))])
3190
3191(define_split
3192 [(set (match_operand:TF 0 "push_operand" "")
3193 (match_operand:TF 1 "register_operand" ""))]
3194 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3195 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3196 (set (mem:TF (reg:SI 7)) (match_dup 1))])
3197
3198(define_split
3199 [(set (match_operand:TF 0 "push_operand" "")
3200 (match_operand:TF 1 "register_operand" ""))]
3201 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3202 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3203 (set (mem:TF (reg:DI 7)) (match_dup 1))])
3204
3205;; Do not use integer registers when optimizing for size
3206(define_insn "*movxf_nointeger"
3207 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3208 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3209 "!TARGET_64BIT
3210 && optimize_size
3211 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3212 && (reload_in_progress || reload_completed
3213 || GET_CODE (operands[1]) != CONST_DOUBLE
3214 || memory_operand (operands[0], XFmode))"
3215{
3216 switch (which_alternative)
3217 {
3218 case 0:
3219 if (REG_P (operands[1])
3220 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3221 return "fstp\t%y0";
3222 else if (STACK_TOP_P (operands[0]))
3223 return "fld%z1\t%y1";
3224 else
3225 return "fst\t%y0";
3226
3227 case 1:
3228 /* There is no non-popping store to memory for XFmode. So if
3229 we need one, follow the store with a load. */
3230 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3231 return "fstp%z0\t%y0\;fld%z0\t%y0";
3232 else
3233 return "fstp%z0\t%y0";
3234
3235 case 2:
3236 switch (standard_80387_constant_p (operands[1]))
3237 {
3238 case 1:
3239 return "fldz";
3240 case 2:
3241 return "fld1";
3242 }
3243 break;
3244
3245 case 3: case 4:
3246 return "#";
3247 }
3248 abort();
3249}
3250 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3251 (set_attr "mode" "XF,XF,XF,SI,SI")])
3252
3253(define_insn "*movtf_nointeger"
3254 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3255 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3256 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3257 && optimize_size
3258 && (reload_in_progress || reload_completed
3259 || GET_CODE (operands[1]) != CONST_DOUBLE
3260 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3261 || memory_operand (operands[0], TFmode))"
3262{
3263 switch (which_alternative)
3264 {
3265 case 0:
3266 if (REG_P (operands[1])
3267 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3268 return "fstp\t%y0";
3269 else if (STACK_TOP_P (operands[0]))
3270 return "fld%z1\t%y1";
3271 else
3272 return "fst\t%y0";
3273
3274 case 1:
3275 /* There is no non-popping store to memory for XFmode. So if
3276 we need one, follow the store with a load. */
3277 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3278 return "fstp%z0\t%y0\;fld%z0\t%y0";
3279 else
3280 return "fstp%z0\t%y0";
3281
3282 case 2:
3283 switch (standard_80387_constant_p (operands[1]))
3284 {
3285 case 1:
3286 return "fldz";
3287 case 2:
3288 return "fld1";
3289 }
3290 break;
3291
3292 case 3: case 4:
3293 return "#";
3294 }
3295 abort();
3296}
3297 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3298 (set_attr "mode" "XF,XF,XF,SI,SI")])
3299
3300(define_insn "*movxf_integer"
3301 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3302 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3303 "!TARGET_64BIT
3304 && !optimize_size
3305 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3306 && (reload_in_progress || reload_completed
3307 || GET_CODE (operands[1]) != CONST_DOUBLE
3308 || memory_operand (operands[0], XFmode))"
3309{
3310 switch (which_alternative)
3311 {
3312 case 0:
3313 if (REG_P (operands[1])
3314 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3315 return "fstp\t%y0";
3316 else if (STACK_TOP_P (operands[0]))
3317 return "fld%z1\t%y1";
3318 else
3319 return "fst\t%y0";
3320
3321 case 1:
3322 /* There is no non-popping store to memory for XFmode. So if
3323 we need one, follow the store with a load. */
3324 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3325 return "fstp%z0\t%y0\;fld%z0\t%y0";
3326 else
3327 return "fstp%z0\t%y0";
3328
3329 case 2:
3330 switch (standard_80387_constant_p (operands[1]))
3331 {
3332 case 1:
3333 return "fldz";
3334 case 2:
3335 return "fld1";
3336 }
3337 break;
3338
3339 case 3: case 4:
3340 return "#";
3341 }
3342 abort();
3343}
3344 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3345 (set_attr "mode" "XF,XF,XF,SI,SI")])
3346
3347(define_insn "*movtf_integer"
3348 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3349 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3350 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3351 && !optimize_size
3352 && (reload_in_progress || reload_completed
3353 || GET_CODE (operands[1]) != CONST_DOUBLE
3354 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3355 || memory_operand (operands[0], TFmode))"
3356{
3357 switch (which_alternative)
3358 {
3359 case 0:
3360 if (REG_P (operands[1])
3361 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3362 return "fstp\t%y0";
3363 else if (STACK_TOP_P (operands[0]))
3364 return "fld%z1\t%y1";
3365 else
3366 return "fst\t%y0";
3367
3368 case 1:
3369 /* There is no non-popping store to memory for XFmode. So if
3370 we need one, follow the store with a load. */
3371 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3372 return "fstp%z0\t%y0\;fld%z0\t%y0";
3373 else
3374 return "fstp%z0\t%y0";
3375
3376 case 2:
3377 switch (standard_80387_constant_p (operands[1]))
3378 {
3379 case 1:
3380 return "fldz";
3381 case 2:
3382 return "fld1";
3383 }
3384 break;
3385
3386 case 3: case 4:
3387 return "#";
3388 }
3389 abort();
3390}
3391 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3392 (set_attr "mode" "XF,XF,XF,SI,SI")])
3393
3394(define_split
3395 [(set (match_operand 0 "nonimmediate_operand" "")
3396 (match_operand 1 "general_operand" ""))]
3397 "reload_completed
3398 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3399 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3400 && ! (ANY_FP_REG_P (operands[0]) ||
3401 (GET_CODE (operands[0]) == SUBREG
3402 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3403 && ! (ANY_FP_REG_P (operands[1]) ||
3404 (GET_CODE (operands[1]) == SUBREG
3405 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3406 [(const_int 0)]
3407 "ix86_split_long_move (operands); DONE;")
3408
3409(define_split
3410 [(set (match_operand 0 "register_operand" "")
3411 (match_operand 1 "memory_operand" ""))]
3412 "reload_completed
3413 && GET_CODE (operands[1]) == MEM
3414 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3415 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3416 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3417 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3418 && (!(SSE_REG_P (operands[0]) ||
3419 (GET_CODE (operands[0]) == SUBREG
3420 && SSE_REG_P (SUBREG_REG (operands[0]))))
3421 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3422 && (!(FP_REG_P (operands[0]) ||
3423 (GET_CODE (operands[0]) == SUBREG
3424 && FP_REG_P (SUBREG_REG (operands[0]))))
3425 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3426 [(set (match_dup 0)
3427 (match_dup 1))]
3428 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3429
3430(define_insn "swapxf"
3431 [(set (match_operand:XF 0 "register_operand" "+f")
3432 (match_operand:XF 1 "register_operand" "+f"))
3433 (set (match_dup 1)
3434 (match_dup 0))]
3435 ""
3436{
3437 if (STACK_TOP_P (operands[0]))
3438 return "fxch\t%1";
3439 else
3440 return "fxch\t%0";
3441}
3442 [(set_attr "type" "fxch")
3443 (set_attr "mode" "XF")])
3444
3445(define_insn "swaptf"
3446 [(set (match_operand:TF 0 "register_operand" "+f")
3447 (match_operand:TF 1 "register_operand" "+f"))
3448 (set (match_dup 1)
3449 (match_dup 0))]
3450 ""
3451{
3452 if (STACK_TOP_P (operands[0]))
3453 return "fxch\t%1";
3454 else
3455 return "fxch\t%0";
3456}
3457 [(set_attr "type" "fxch")
3458 (set_attr "mode" "XF")])
3459
3460;; Zero extension instructions
3461
3462(define_expand "zero_extendhisi2"
3463 [(set (match_operand:SI 0 "register_operand" "")
3464 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3465 ""
3466{
3467 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3468 {
3469 operands[1] = force_reg (HImode, operands[1]);
3470 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3471 DONE;
3472 }
3473})
3474
3475(define_insn "zero_extendhisi2_and"
3476 [(set (match_operand:SI 0 "register_operand" "=r")
3477 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3478 (clobber (reg:CC 17))]
3479 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3480 "#"
3481 [(set_attr "type" "alu1")
3482 (set_attr "mode" "SI")])
3483
3484(define_split
3485 [(set (match_operand:SI 0 "register_operand" "")
3486 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3487 (clobber (reg:CC 17))]
3488 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3489 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3490 (clobber (reg:CC 17))])]
3491 "")
3492
3493(define_insn "*zero_extendhisi2_movzwl"
3494 [(set (match_operand:SI 0 "register_operand" "=r")
3495 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3496 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3497 "movz{wl|x}\t{%1, %0|%0, %1}"
3498 [(set_attr "type" "imovx")
3499 (set_attr "mode" "SI")])
3500
3501(define_expand "zero_extendqihi2"
3502 [(parallel
3503 [(set (match_operand:HI 0 "register_operand" "")
3504 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3505 (clobber (reg:CC 17))])]
3506 ""
3507 "")
3508
3509(define_insn "*zero_extendqihi2_and"
3510 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3511 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3512 (clobber (reg:CC 17))]
3513 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3514 "#"
3515 [(set_attr "type" "alu1")
3516 (set_attr "mode" "HI")])
3517
3518(define_insn "*zero_extendqihi2_movzbw_and"
3519 [(set (match_operand:HI 0 "register_operand" "=r,r")
3520 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3521 (clobber (reg:CC 17))]
3522 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3523 "#"
3524 [(set_attr "type" "imovx,alu1")
3525 (set_attr "mode" "HI")])
3526
3527(define_insn "*zero_extendqihi2_movzbw"
3528 [(set (match_operand:HI 0 "register_operand" "=r")
3529 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3530 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3531 "movz{bw|x}\t{%1, %0|%0, %1}"
3532 [(set_attr "type" "imovx")
3533 (set_attr "mode" "HI")])
3534
3535;; For the movzbw case strip only the clobber
3536(define_split
3537 [(set (match_operand:HI 0 "register_operand" "")
3538 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3539 (clobber (reg:CC 17))]
3540 "reload_completed
3541 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3542 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3543 [(set (match_operand:HI 0 "register_operand" "")
3544 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3545
3546;; When source and destination does not overlap, clear destination
3547;; first and then do the movb
3548(define_split
3549 [(set (match_operand:HI 0 "register_operand" "")
3550 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3551 (clobber (reg:CC 17))]
3552 "reload_completed
3553 && ANY_QI_REG_P (operands[0])
3554 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3555 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3556 [(set (match_dup 0) (const_int 0))
3557 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3558 "operands[2] = gen_lowpart (QImode, operands[0]);")
3559
3560;; Rest is handled by single and.
3561(define_split
3562 [(set (match_operand:HI 0 "register_operand" "")
3563 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3564 (clobber (reg:CC 17))]
3565 "reload_completed
3566 && true_regnum (operands[0]) == true_regnum (operands[1])"
3567 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3568 (clobber (reg:CC 17))])]
3569 "")
3570
3571(define_expand "zero_extendqisi2"
3572 [(parallel
3573 [(set (match_operand:SI 0 "register_operand" "")
3574 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3575 (clobber (reg:CC 17))])]
3576 ""
3577 "")
3578
3579(define_insn "*zero_extendqisi2_and"
3580 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3581 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3582 (clobber (reg:CC 17))]
3583 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3584 "#"
3585 [(set_attr "type" "alu1")
3586 (set_attr "mode" "SI")])
3587
3588(define_insn "*zero_extendqisi2_movzbw_and"
3589 [(set (match_operand:SI 0 "register_operand" "=r,r")
3590 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3591 (clobber (reg:CC 17))]
3592 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3593 "#"
3594 [(set_attr "type" "imovx,alu1")
3595 (set_attr "mode" "SI")])
3596
3597(define_insn "*zero_extendqisi2_movzbw"
3598 [(set (match_operand:SI 0 "register_operand" "=r")
3599 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3600 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3601 "movz{bl|x}\t{%1, %0|%0, %1}"
3602 [(set_attr "type" "imovx")
3603 (set_attr "mode" "SI")])
3604
3605;; For the movzbl case strip only the clobber
3606(define_split
3607 [(set (match_operand:SI 0 "register_operand" "")
3608 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3609 (clobber (reg:CC 17))]
3610 "reload_completed
3611 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3612 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3613 [(set (match_dup 0)
3614 (zero_extend:SI (match_dup 1)))])
3615
3616;; When source and destination does not overlap, clear destination
3617;; first and then do the movb
3618(define_split
3619 [(set (match_operand:SI 0 "register_operand" "")
3620 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3621 (clobber (reg:CC 17))]
3622 "reload_completed
3623 && ANY_QI_REG_P (operands[0])
3624 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3625 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3626 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3627 [(set (match_dup 0) (const_int 0))
3628 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3629 "operands[2] = gen_lowpart (QImode, operands[0]);")
3630
3631;; Rest is handled by single and.
3632(define_split
3633 [(set (match_operand:SI 0 "register_operand" "")
3634 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3635 (clobber (reg:CC 17))]
3636 "reload_completed
3637 && true_regnum (operands[0]) == true_regnum (operands[1])"
3638 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3639 (clobber (reg:CC 17))])]
3640 "")
3641
3642;; %%% Kill me once multi-word ops are sane.
3643(define_expand "zero_extendsidi2"
3644 [(set (match_operand:DI 0 "register_operand" "=r")
3645 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3646 ""
3647 "if (!TARGET_64BIT)
3648 {
3649 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3650 DONE;
3651 }
3652 ")
3653
3654(define_insn "zero_extendsidi2_32"
3655 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3656 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3657 (clobber (reg:CC 17))]
3658 "!TARGET_64BIT"
3659 "#"
3660 [(set_attr "mode" "SI")])
3661
3662(define_insn "zero_extendsidi2_rex64"
3663 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3664 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3665 "TARGET_64BIT"
3666 "@
3667 mov\t{%k1, %k0|%k0, %k1}
3668 #"
3669 [(set_attr "type" "imovx,imov")
3670 (set_attr "mode" "SI,DI")])
3671
3672(define_split
3673 [(set (match_operand:DI 0 "memory_operand" "")
3674 (zero_extend:DI (match_dup 0)))]
3675 "TARGET_64BIT"
3676 [(set (match_dup 4) (const_int 0))]
3677 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3678
3679(define_split
3680 [(set (match_operand:DI 0 "register_operand" "")
3681 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3682 (clobber (reg:CC 17))]
3683 "!TARGET_64BIT && reload_completed
3684 && true_regnum (operands[0]) == true_regnum (operands[1])"
3685 [(set (match_dup 4) (const_int 0))]
3686 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3687
3688(define_split
3689 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3690 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3691 (clobber (reg:CC 17))]
3692 "!TARGET_64BIT && reload_completed"
3693 [(set (match_dup 3) (match_dup 1))
3694 (set (match_dup 4) (const_int 0))]
3695 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3696
3697(define_insn "zero_extendhidi2"
3698 [(set (match_operand:DI 0 "register_operand" "=r,r")
3699 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3700 "TARGET_64BIT"
3701 "@
3702 movz{wl|x}\t{%1, %k0|%k0, %1}
3703 movz{wq|x}\t{%1, %0|%0, %1}"
3704 [(set_attr "type" "imovx")
3705 (set_attr "mode" "SI,DI")])
3706
3707(define_insn "zero_extendqidi2"
3708 [(set (match_operand:DI 0 "register_operand" "=r,r")
3709 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3710 "TARGET_64BIT"
3711 "@
3712 movz{bl|x}\t{%1, %k0|%k0, %1}
3713 movz{bq|x}\t{%1, %0|%0, %1}"
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "SI,DI")])
3716
3717;; Sign extension instructions
3718
3719(define_expand "extendsidi2"
3720 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3721 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3722 (clobber (reg:CC 17))
3723 (clobber (match_scratch:SI 2 ""))])]
3724 ""
3725{
3726 if (TARGET_64BIT)
3727 {
3728 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3729 DONE;
3730 }
3731})
3732
3733(define_insn "*extendsidi2_1"
3734 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3735 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3736 (clobber (reg:CC 17))
3737 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3738 "!TARGET_64BIT"
3739 "#")
3740
3741(define_insn "extendsidi2_rex64"
3742 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3743 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3744 "TARGET_64BIT"
3745 "@
3746 {cltq|cdqe}
3747 movs{lq|x}\t{%1,%0|%0, %1}"
3748 [(set_attr "type" "imovx")
3749 (set_attr "mode" "DI")
3750 (set_attr "prefix_0f" "0")
3751 (set_attr "modrm" "0,1")])
3752
3753(define_insn "extendhidi2"
3754 [(set (match_operand:DI 0 "register_operand" "=r")
3755 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3756 "TARGET_64BIT"
3757 "movs{wq|x}\t{%1,%0|%0, %1}"
3758 [(set_attr "type" "imovx")
3759 (set_attr "mode" "DI")])
3760
3761(define_insn "extendqidi2"
3762 [(set (match_operand:DI 0 "register_operand" "=r")
3763 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3764 "TARGET_64BIT"
3765 "movs{bq|x}\t{%1,%0|%0, %1}"
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "DI")])
3768
3769;; Extend to memory case when source register does die.
3770(define_split
3771 [(set (match_operand:DI 0 "memory_operand" "")
3772 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3773 (clobber (reg:CC 17))
3774 (clobber (match_operand:SI 2 "register_operand" ""))]
3775 "(reload_completed
3776 && dead_or_set_p (insn, operands[1])
3777 && !reg_mentioned_p (operands[1], operands[0]))"
3778 [(set (match_dup 3) (match_dup 1))
3779 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3780 (clobber (reg:CC 17))])
3781 (set (match_dup 4) (match_dup 1))]
3782 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3783
3784;; Extend to memory case when source register does not die.
3785(define_split
3786 [(set (match_operand:DI 0 "memory_operand" "")
3787 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3788 (clobber (reg:CC 17))
3789 (clobber (match_operand:SI 2 "register_operand" ""))]
3790 "reload_completed"
3791 [(const_int 0)]
3792{
3793 split_di (&operands[0], 1, &operands[3], &operands[4]);
3794
3795 emit_move_insn (operands[3], operands[1]);
3796
3797 /* Generate a cltd if possible and doing so it profitable. */
3798 if (true_regnum (operands[1]) == 0
3799 && true_regnum (operands[2]) == 1
3800 && (optimize_size || TARGET_USE_CLTD))
3801 {
3802 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3803 }
3804 else
3805 {
3806 emit_move_insn (operands[2], operands[1]);
3807 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3808 }
3809 emit_move_insn (operands[4], operands[2]);
3810 DONE;
3811})
3812
3813;; Extend to register case. Optimize case where source and destination
3814;; registers match and cases where we can use cltd.
3815(define_split
3816 [(set (match_operand:DI 0 "register_operand" "")
3817 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3818 (clobber (reg:CC 17))
3819 (clobber (match_scratch:SI 2 ""))]
3820 "reload_completed"
3821 [(const_int 0)]
3822{
3823 split_di (&operands[0], 1, &operands[3], &operands[4]);
3824
3825 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3826 emit_move_insn (operands[3], operands[1]);
3827
3828 /* Generate a cltd if possible and doing so it profitable. */
3829 if (true_regnum (operands[3]) == 0
3830 && (optimize_size || TARGET_USE_CLTD))
3831 {
3832 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3833 DONE;
3834 }
3835
3836 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3837 emit_move_insn (operands[4], operands[1]);
3838
3839 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3840 DONE;
3841})
3842
3843(define_insn "extendhisi2"
3844 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3845 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3846 ""
3847{
3848 switch (get_attr_prefix_0f (insn))
3849 {
3850 case 0:
3851 return "{cwtl|cwde}";
3852 default:
3853 return "movs{wl|x}\t{%1,%0|%0, %1}";
3854 }
3855}
3856 [(set_attr "type" "imovx")
3857 (set_attr "mode" "SI")
3858 (set (attr "prefix_0f")
3859 ;; movsx is short decodable while cwtl is vector decoded.
3860 (if_then_else (and (eq_attr "cpu" "!k6")
3861 (eq_attr "alternative" "0"))
3862 (const_string "0")
3863 (const_string "1")))
3864 (set (attr "modrm")
3865 (if_then_else (eq_attr "prefix_0f" "0")
3866 (const_string "0")
3867 (const_string "1")))])
3868
3869(define_insn "*extendhisi2_zext"
3870 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3871 (zero_extend:DI
3872 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3873 "TARGET_64BIT"
3874{
3875 switch (get_attr_prefix_0f (insn))
3876 {
3877 case 0:
3878 return "{cwtl|cwde}";
3879 default:
3880 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3881 }
3882}
3883 [(set_attr "type" "imovx")
3884 (set_attr "mode" "SI")
3885 (set (attr "prefix_0f")
3886 ;; movsx is short decodable while cwtl is vector decoded.
3887 (if_then_else (and (eq_attr "cpu" "!k6")
3888 (eq_attr "alternative" "0"))
3889 (const_string "0")
3890 (const_string "1")))
3891 (set (attr "modrm")
3892 (if_then_else (eq_attr "prefix_0f" "0")
3893 (const_string "0")
3894 (const_string "1")))])
3895
3896(define_insn "extendqihi2"
3897 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3898 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3899 ""
3900{
3901 switch (get_attr_prefix_0f (insn))
3902 {
3903 case 0:
3904 return "{cbtw|cbw}";
3905 default:
3906 return "movs{bw|x}\t{%1,%0|%0, %1}";
3907 }
3908}
3909 [(set_attr "type" "imovx")
3910 (set_attr "mode" "HI")
3911 (set (attr "prefix_0f")
3912 ;; movsx is short decodable while cwtl is vector decoded.
3913 (if_then_else (and (eq_attr "cpu" "!k6")
3914 (eq_attr "alternative" "0"))
3915 (const_string "0")
3916 (const_string "1")))
3917 (set (attr "modrm")
3918 (if_then_else (eq_attr "prefix_0f" "0")
3919 (const_string "0")
3920 (const_string "1")))])
3921
3922(define_insn "extendqisi2"
3923 [(set (match_operand:SI 0 "register_operand" "=r")
3924 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3925 ""
3926 "movs{bl|x}\t{%1,%0|%0, %1}"
3927 [(set_attr "type" "imovx")
3928 (set_attr "mode" "SI")])
3929
3930(define_insn "*extendqisi2_zext"
3931 [(set (match_operand:DI 0 "register_operand" "=r")
3932 (zero_extend:DI
3933 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3934 "TARGET_64BIT"
3935 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3936 [(set_attr "type" "imovx")
3937 (set_attr "mode" "SI")])
3938
3939;; Conversions between float and double.
3940
3941;; These are all no-ops in the model used for the 80387. So just
3942;; emit moves.
3943
3944;; %%% Kill these when call knows how to work out a DFmode push earlier.
3945(define_insn "*dummy_extendsfdf2"
3946 [(set (match_operand:DF 0 "push_operand" "=<")
3947 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3948 "0"
3949 "#")
3950
3951(define_split
3952 [(set (match_operand:DF 0 "push_operand" "")
3953 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3954 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3955 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3956 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3957
3958(define_split
3959 [(set (match_operand:DF 0 "push_operand" "")
3960 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3961 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3962 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3963 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3964
3965(define_insn "*dummy_extendsfxf2"
3966 [(set (match_operand:XF 0 "push_operand" "=<")
3967 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3968 "0"
3969 "#")
3970
3971(define_split
3972 [(set (match_operand:XF 0 "push_operand" "")
3973 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3974 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3975 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3976 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3977
3978(define_insn "*dummy_extendsftf2"
3979 [(set (match_operand:TF 0 "push_operand" "=<")
3980 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3981 "0"
3982 "#")
3983
3984(define_split
3985 [(set (match_operand:TF 0 "push_operand" "")
3986 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3987 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3988 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3989 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3990
3991(define_split
3992 [(set (match_operand:TF 0 "push_operand" "")
3993 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3994 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3995 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3996 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3997
3998(define_insn "*dummy_extenddfxf2"
3999 [(set (match_operand:XF 0 "push_operand" "=<")
4000 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4001 "0"
4002 "#")
4003
4004(define_split
4005 [(set (match_operand:XF 0 "push_operand" "")
4006 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
4007 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4008 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
4009 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4010
4011(define_insn "*dummy_extenddftf2"
4012 [(set (match_operand:TF 0 "push_operand" "=<")
4013 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4014 "0"
4015 "#")
4016
4017(define_split
4018 [(set (match_operand:TF 0 "push_operand" "")
4019 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4020 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4021 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4022 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4023
4024(define_split
4025 [(set (match_operand:TF 0 "push_operand" "")
4026 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4027 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4028 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
4029 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
4030
4031(define_expand "extendsfdf2"
4032 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4033 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
4034 "TARGET_80387 || TARGET_SSE2"
4035{
4036 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4037 operands[1] = force_reg (SFmode, operands[1]);
4038})
4039
4040(define_insn "*extendsfdf2_1"
4041 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
4042 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
4043 "(TARGET_80387 || TARGET_SSE2)
4044 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4045{
4046 switch (which_alternative)
4047 {
4048 case 0:
4049 if (REG_P (operands[1])
4050 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4051 return "fstp\t%y0";
4052 else if (STACK_TOP_P (operands[0]))
4053 return "fld%z1\t%y1";
4054 else
4055 return "fst\t%y0";
4056
4057 case 1:
4058 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4059 return "fstp%z0\t%y0";
4060
4061 else
4062 return "fst%z0\t%y0";
4063 case 2:
4064 return "cvtss2sd\t{%1, %0|%0, %1}";
4065
4066 default:
4067 abort ();
4068 }
4069}
4070 [(set_attr "type" "fmov,fmov,sse")
4071 (set_attr "mode" "SF,XF,DF")])
4072
4073(define_insn "*extendsfdf2_1_sse_only"
4074 [(set (match_operand:DF 0 "register_operand" "=Y")
4075 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
4076 "!TARGET_80387 && TARGET_SSE2
4077 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4078 "cvtss2sd\t{%1, %0|%0, %1}"
4079 [(set_attr "type" "sse")
4080 (set_attr "mode" "DF")])
4081
4082(define_expand "extendsfxf2"
4083 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4084 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
4085 "!TARGET_64BIT && TARGET_80387"
4086{
4087 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4088 operands[1] = force_reg (SFmode, operands[1]);
4089})
4090
4091(define_insn "*extendsfxf2_1"
4092 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4093 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4094 "!TARGET_64BIT && TARGET_80387
4095 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4096{
4097 switch (which_alternative)
4098 {
4099 case 0:
4100 if (REG_P (operands[1])
4101 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4102 return "fstp\t%y0";
4103 else if (STACK_TOP_P (operands[0]))
4104 return "fld%z1\t%y1";
4105 else
4106 return "fst\t%y0";
4107
4108 case 1:
4109 /* There is no non-popping store to memory for XFmode. So if
4110 we need one, follow the store with a load. */
4111 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4112 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4113 else
4114 return "fstp%z0\t%y0";
4115
4116 default:
4117 abort ();
4118 }
4119}
4120 [(set_attr "type" "fmov")
4121 (set_attr "mode" "SF,XF")])
4122
4123(define_expand "extendsftf2"
4124 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4125 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
4126 "TARGET_80387"
4127{
4128 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4129 operands[1] = force_reg (SFmode, operands[1]);
4130})
4131
4132(define_insn "*extendsftf2_1"
4133 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4134 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4135 "TARGET_80387
4136 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4137{
4138 switch (which_alternative)
4139 {
4140 case 0:
4141 if (REG_P (operands[1])
4142 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4143 return "fstp\t%y0";
4144 else if (STACK_TOP_P (operands[0]))
4145 return "fld%z1\t%y1";
4146 else
4147 return "fst\t%y0";
4148
4149 case 1:
4150 /* There is no non-popping store to memory for XFmode. So if
4151 we need one, follow the store with a load. */
4152 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4153 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4154 else
4155 return "fstp%z0\t%y0";
4156
4157 default:
4158 abort ();
4159 }
4160}
4161 [(set_attr "type" "fmov")
4162 (set_attr "mode" "SF,XF")])
4163
4164(define_expand "extenddfxf2"
4165 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4166 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
4167 "!TARGET_64BIT && TARGET_80387"
4168{
4169 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4170 operands[1] = force_reg (DFmode, operands[1]);
4171})
4172
4173(define_insn "*extenddfxf2_1"
4174 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4175 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4176 "!TARGET_64BIT && TARGET_80387
4177 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4178{
4179 switch (which_alternative)
4180 {
4181 case 0:
4182 if (REG_P (operands[1])
4183 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4184 return "fstp\t%y0";
4185 else if (STACK_TOP_P (operands[0]))
4186 return "fld%z1\t%y1";
4187 else
4188 return "fst\t%y0";
4189
4190 case 1:
4191 /* There is no non-popping store to memory for XFmode. So if
4192 we need one, follow the store with a load. */
4193 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4194 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4195 else
4196 return "fstp%z0\t%y0";
4197
4198 default:
4199 abort ();
4200 }
4201}
4202 [(set_attr "type" "fmov")
4203 (set_attr "mode" "DF,XF")])
4204
4205(define_expand "extenddftf2"
4206 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4207 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
4208 "TARGET_80387"
4209{
4210 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4211 operands[1] = force_reg (DFmode, operands[1]);
4212})
4213
4214(define_insn "*extenddftf2_1"
4215 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4216 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4217 "TARGET_80387
4218 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4219{
4220 switch (which_alternative)
4221 {
4222 case 0:
4223 if (REG_P (operands[1])
4224 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4225 return "fstp\t%y0";
4226 else if (STACK_TOP_P (operands[0]))
4227 return "fld%z1\t%y1";
4228 else
4229 return "fst\t%y0";
4230
4231 case 1:
4232 /* There is no non-popping store to memory for XFmode. So if
4233 we need one, follow the store with a load. */
4234 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4235 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4236 else
4237 return "fstp%z0\t%y0";
4238
4239 default:
4240 abort ();
4241 }
4242}
4243 [(set_attr "type" "fmov")
4244 (set_attr "mode" "DF,XF")])
4245
4246;; %%% This seems bad bad news.
4247;; This cannot output into an f-reg because there is no way to be sure
4248;; of truncating in that case. Otherwise this is just like a simple move
4249;; insn. So we pretend we can output to a reg in order to get better
4250;; register preferencing, but we really use a stack slot.
4251
4252(define_expand "truncdfsf2"
4253 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4254 (float_truncate:SF
4255 (match_operand:DF 1 "register_operand" "")))
4256 (clobber (match_dup 2))])]
4257 "TARGET_80387 || TARGET_SSE2"
4258 "
4259 if (TARGET_80387)
4260 operands[2] = assign_386_stack_local (SFmode, 0);
4261 else
4262 {
4263 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4264 DONE;
4265 }
4266")
4267
4268(define_insn "*truncdfsf2_1"
4269 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4270 (float_truncate:SF
4271 (match_operand:DF 1 "register_operand" "f,f,f,f")))
4272 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4273 "TARGET_80387 && !TARGET_SSE2"
4274{
4275 switch (which_alternative)
4276 {
4277 case 0:
4278 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4279 return "fstp%z0\t%y0";
4280 else
4281 return "fst%z0\t%y0";
4282 default:
4283 abort ();
4284 }
4285}
4286 [(set_attr "type" "fmov,multi,multi,multi")
4287 (set_attr "mode" "SF,SF,SF,SF")])
4288
4289(define_insn "*truncdfsf2_1_sse"
4290 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
4291 (float_truncate:SF
4292 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
4293 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
4294 "TARGET_80387 && TARGET_SSE2"
4295{
4296 switch (which_alternative)
4297 {
4298 case 0:
4299 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4300 return "fstp%z0\t%y0";
4301 else
4302 return "fst%z0\t%y0";
4303 case 4:
4304 return "cvtsd2ss\t{%1, %0|%0, %1}";
4305 default:
4306 abort ();
4307 }
4308}
4309 [(set_attr "type" "fmov,multi,multi,multi,sse")
4310 (set_attr "mode" "SF,SF,SF,SF,DF")])
4311
4312(define_insn "*truncdfsf2_2"
4313 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
4314 (float_truncate:SF
4315 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4316 "TARGET_80387 && TARGET_SSE2
4317 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4318{
4319 switch (which_alternative)
4320 {
4321 case 0:
4322 return "cvtsd2ss\t{%1, %0|%0, %1}";
4323 case 1:
4324 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4325 return "fstp%z0\t%y0";
4326 else
4327 return "fst%z0\t%y0";
4328 default:
4329 abort ();
4330 }
4331}
4332 [(set_attr "type" "sse,fmov")
4333 (set_attr "mode" "DF,SF")])
4334
4335(define_insn "truncdfsf2_3"
4336 [(set (match_operand:SF 0 "memory_operand" "=m")
4337 (float_truncate:SF
4338 (match_operand:DF 1 "register_operand" "f")))]
4339 "TARGET_80387"
4340{
4341 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4342 return "fstp%z0\t%y0";
4343 else
4344 return "fst%z0\t%y0";
4345}
4346 [(set_attr "type" "fmov")
4347 (set_attr "mode" "SF")])
4348
4349(define_insn "truncdfsf2_sse_only"
4350 [(set (match_operand:SF 0 "register_operand" "=Y")
4351 (float_truncate:SF
4352 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4353 "!TARGET_80387 && TARGET_SSE2"
4354 "cvtsd2ss\t{%1, %0|%0, %1}"
4355 [(set_attr "type" "sse")
4356 (set_attr "mode" "DF")])
4357
4358(define_split
4359 [(set (match_operand:SF 0 "memory_operand" "")
4360 (float_truncate:SF
4361 (match_operand:DF 1 "register_operand" "")))
4362 (clobber (match_operand:SF 2 "memory_operand" ""))]
4363 "TARGET_80387"
4364 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4365 "")
4366
4367(define_split
4368 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4369 (float_truncate:SF
4370 (match_operand:DF 1 "nonimmediate_operand" "")))
4371 (clobber (match_operand 2 "" ""))]
4372 "TARGET_80387 && reload_completed
4373 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
4374 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4375 "")
4376
4377(define_split
4378 [(set (match_operand:SF 0 "register_operand" "")
4379 (float_truncate:SF
4380 (match_operand:DF 1 "register_operand" "")))
4381 (clobber (match_operand:SF 2 "memory_operand" ""))]
4382 "TARGET_80387 && reload_completed
4383 && FP_REG_P (operands[1])"
4384 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4385 (set (match_dup 0) (match_dup 2))]
4386 "")
4387
4388(define_expand "truncxfsf2"
4389 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4390 (float_truncate:SF
4391 (match_operand:XF 1 "register_operand" "")))
4392 (clobber (match_dup 2))])]
4393 "!TARGET_64BIT && TARGET_80387"
4394 "operands[2] = assign_386_stack_local (SFmode, 0);")
4395
4396(define_insn "*truncxfsf2_1"
4397 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4398 (float_truncate:SF
4399 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4400 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4401 "!TARGET_64BIT && TARGET_80387"
4402{
4403 switch (which_alternative)
4404 {
4405 case 0:
4406 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4407 return "fstp%z0\t%y0";
4408 else
4409 return "fst%z0\t%y0";
4410 default:
4411 abort();
4412 }
4413}
4414 [(set_attr "type" "fmov,multi,multi,multi")
4415 (set_attr "mode" "SF")])
4416
4417(define_insn "*truncxfsf2_2"
4418 [(set (match_operand:SF 0 "memory_operand" "=m")
4419 (float_truncate:SF
4420 (match_operand:XF 1 "register_operand" "f")))]
4421 "!TARGET_64BIT && TARGET_80387"
4422{
4423 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4424 return "fstp%z0\t%y0";
4425 else
4426 return "fst%z0\t%y0";
4427}
4428 [(set_attr "type" "fmov")
4429 (set_attr "mode" "SF")])
4430
4431(define_split
4432 [(set (match_operand:SF 0 "memory_operand" "")
4433 (float_truncate:SF
4434 (match_operand:XF 1 "register_operand" "")))
4435 (clobber (match_operand:SF 2 "memory_operand" ""))]
4436 "TARGET_80387"
4437 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4438 "")
4439
4440(define_split
4441 [(set (match_operand:SF 0 "register_operand" "")
4442 (float_truncate:SF
4443 (match_operand:XF 1 "register_operand" "")))
4444 (clobber (match_operand:SF 2 "memory_operand" ""))]
4445 "TARGET_80387 && reload_completed"
4446 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4447 (set (match_dup 0) (match_dup 2))]
4448 "")
4449
4450(define_expand "trunctfsf2"
4451 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4452 (float_truncate:SF
4453 (match_operand:TF 1 "register_operand" "")))
4454 (clobber (match_dup 2))])]
4455 "TARGET_80387"
4456 "operands[2] = assign_386_stack_local (SFmode, 0);")
4457
4458(define_insn "*trunctfsf2_1"
4459 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4460 (float_truncate:SF
4461 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4462 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4463 "TARGET_80387"
4464{
4465 switch (which_alternative)
4466 {
4467 case 0:
4468 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4469 return "fstp%z0\t%y0";
4470 else
4471 return "fst%z0\t%y0";
4472 default:
4473 abort();
4474 }
4475}
4476 [(set_attr "type" "fmov,multi,multi,multi")
4477 (set_attr "mode" "SF")])
4478
4479(define_insn "*trunctfsf2_2"
4480 [(set (match_operand:SF 0 "memory_operand" "=m")
4481 (float_truncate:SF
4482 (match_operand:TF 1 "register_operand" "f")))]
4483 "TARGET_80387"
4484{
4485 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4486 return "fstp%z0\t%y0";
4487 else
4488 return "fst%z0\t%y0";
4489}
4490 [(set_attr "type" "fmov")
4491 (set_attr "mode" "SF")])
4492
4493(define_split
4494 [(set (match_operand:SF 0 "memory_operand" "")
4495 (float_truncate:SF
4496 (match_operand:TF 1 "register_operand" "")))
4497 (clobber (match_operand:SF 2 "memory_operand" ""))]
4498 "TARGET_80387"
4499 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4500 "")
4501
4502(define_split
4503 [(set (match_operand:SF 0 "register_operand" "")
4504 (float_truncate:SF
4505 (match_operand:TF 1 "register_operand" "")))
4506 (clobber (match_operand:SF 2 "memory_operand" ""))]
4507 "TARGET_80387 && reload_completed"
4508 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4509 (set (match_dup 0) (match_dup 2))]
4510 "")
4511
4512
4513(define_expand "truncxfdf2"
4514 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4515 (float_truncate:DF
4516 (match_operand:XF 1 "register_operand" "")))
4517 (clobber (match_dup 2))])]
4518 "!TARGET_64BIT && TARGET_80387"
4519 "operands[2] = assign_386_stack_local (DFmode, 0);")
4520
4521(define_insn "*truncxfdf2_1"
4522 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4523 (float_truncate:DF
4524 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4525 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4526 "!TARGET_64BIT && TARGET_80387"
4527{
4528 switch (which_alternative)
4529 {
4530 case 0:
4531 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4532 return "fstp%z0\t%y0";
4533 else
4534 return "fst%z0\t%y0";
4535 default:
4536 abort();
4537 }
4538 abort ();
4539}
4540 [(set_attr "type" "fmov,multi,multi,multi")
4541 (set_attr "mode" "DF")])
4542
4543(define_insn "*truncxfdf2_2"
4544 [(set (match_operand:DF 0 "memory_operand" "=m")
4545 (float_truncate:DF
4546 (match_operand:XF 1 "register_operand" "f")))]
4547 "!TARGET_64BIT && TARGET_80387"
4548{
4549 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4550 return "fstp%z0\t%y0";
4551 else
4552 return "fst%z0\t%y0";
4553}
4554 [(set_attr "type" "fmov")
4555 (set_attr "mode" "DF")])
4556
4557(define_split
4558 [(set (match_operand:DF 0 "memory_operand" "")
4559 (float_truncate:DF
4560 (match_operand:XF 1 "register_operand" "")))
4561 (clobber (match_operand:DF 2 "memory_operand" ""))]
4562 "TARGET_80387"
4563 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4564 "")
4565
4566(define_split
4567 [(set (match_operand:DF 0 "register_operand" "")
4568 (float_truncate:DF
4569 (match_operand:XF 1 "register_operand" "")))
4570 (clobber (match_operand:DF 2 "memory_operand" ""))]
4571 "TARGET_80387 && reload_completed"
4572 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4573 (set (match_dup 0) (match_dup 2))]
4574 "")
4575
4576(define_expand "trunctfdf2"
4577 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4578 (float_truncate:DF
4579 (match_operand:TF 1 "register_operand" "")))
4580 (clobber (match_dup 2))])]
4581 "TARGET_80387"
4582 "operands[2] = assign_386_stack_local (DFmode, 0);")
4583
4584(define_insn "*trunctfdf2_1"
4585 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4586 (float_truncate:DF
4587 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4588 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4589 "TARGET_80387"
4590{
4591 switch (which_alternative)
4592 {
4593 case 0:
4594 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4595 return "fstp%z0\t%y0";
4596 else
4597 return "fst%z0\t%y0";
4598 default:
4599 abort();
4600 }
4601 abort ();
4602}
4603 [(set_attr "type" "fmov,multi,multi,multi")
4604 (set_attr "mode" "DF")])
4605
4606 (define_insn "*trunctfdf2_2"
4607 [(set (match_operand:DF 0 "memory_operand" "=m")
4608 (float_truncate:DF
4609 (match_operand:TF 1 "register_operand" "f")))]
4610 "TARGET_80387"
4611{
4612 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4613 return "fstp%z0\t%y0";
4614 else
4615 return "fst%z0\t%y0";
4616}
4617 [(set_attr "type" "fmov")
4618 (set_attr "mode" "DF")])
4619
4620(define_split
4621 [(set (match_operand:DF 0 "memory_operand" "")
4622 (float_truncate:DF
4623 (match_operand:TF 1 "register_operand" "")))
4624 (clobber (match_operand:DF 2 "memory_operand" ""))]
4625 "TARGET_80387"
4626 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4627 "")
4628
4629(define_split
4630 [(set (match_operand:DF 0 "register_operand" "")
4631 (float_truncate:DF
4632 (match_operand:TF 1 "register_operand" "")))
4633 (clobber (match_operand:DF 2 "memory_operand" ""))]
4634 "TARGET_80387 && reload_completed"
4635 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4636 (set (match_dup 0) (match_dup 2))]
4637 "")
4638
4639
4640;; %%% Break up all these bad boys.
4641
4642;; Signed conversion to DImode.
4643
4644(define_expand "fix_truncxfdi2"
4645 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4646 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4647 "!TARGET_64BIT && TARGET_80387"
4648 "")
4649
4650(define_expand "fix_trunctfdi2"
4651 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4652 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4653 "TARGET_80387"
4654 "")
4655
4656(define_expand "fix_truncdfdi2"
4657 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4658 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4659 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4660{
4661 if (TARGET_64BIT && TARGET_SSE2)
4662 {
4663 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4664 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4665 if (out != operands[0])
4666 emit_move_insn (operands[0], out);
4667 DONE;
4668 }
4669})
4670
4671(define_expand "fix_truncsfdi2"
4672 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4673 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4674 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4675{
4676 if (TARGET_SSE && TARGET_64BIT)
4677 {
4678 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4679 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4680 if (out != operands[0])
4681 emit_move_insn (operands[0], out);
4682 DONE;
4683 }
4684})
4685
4686;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4687;; of the machinery.
4688(define_insn_and_split "*fix_truncdi_1"
4689 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4690 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4691 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4692 && !reload_completed && !reload_in_progress
4693 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4694 "#"
4695 "&& 1"
4696 [(const_int 0)]
4697{
4698 operands[2] = assign_386_stack_local (HImode, 1);
4699 operands[3] = assign_386_stack_local (HImode, 2);
4700 if (memory_operand (operands[0], VOIDmode))
4701 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4702 operands[2], operands[3]));
4703 else
4704 {
4705 operands[4] = assign_386_stack_local (DImode, 0);
4706 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4707 operands[2], operands[3],
4708 operands[4]));
4709 }
4710 DONE;
4711}
4712 [(set_attr "type" "fistp")])
4713
4714(define_insn "fix_truncdi_nomemory"
4715 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4716 (fix:DI (match_operand 1 "register_operand" "f,f")))
4717 (use (match_operand:HI 2 "memory_operand" "m,m"))
4718 (use (match_operand:HI 3 "memory_operand" "m,m"))
4719 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4720 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4721 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4722 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4723 "#"
4724 [(set_attr "type" "fistp")])
4725
4726(define_insn "fix_truncdi_memory"
4727 [(set (match_operand:DI 0 "memory_operand" "=m")
4728 (fix:DI (match_operand 1 "register_operand" "f")))
4729 (use (match_operand:HI 2 "memory_operand" "m"))
4730 (use (match_operand:HI 3 "memory_operand" "m"))
4731 (clobber (match_scratch:DF 4 "=&1f"))]
4732 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4733 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4734 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4735 [(set_attr "type" "fistp")])
4736
4737(define_split
4738 [(set (match_operand:DI 0 "register_operand" "")
4739 (fix:DI (match_operand 1 "register_operand" "")))
4740 (use (match_operand:HI 2 "memory_operand" ""))
4741 (use (match_operand:HI 3 "memory_operand" ""))
4742 (clobber (match_operand:DI 4 "memory_operand" ""))
4743 (clobber (match_scratch 5 ""))]
4744 "reload_completed"
4745 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4746 (use (match_dup 2))
4747 (use (match_dup 3))
4748 (clobber (match_dup 5))])
4749 (set (match_dup 0) (match_dup 4))]
4750 "")
4751
4752(define_split
4753 [(set (match_operand:DI 0 "memory_operand" "")
4754 (fix:DI (match_operand 1 "register_operand" "")))
4755 (use (match_operand:HI 2 "memory_operand" ""))
4756 (use (match_operand:HI 3 "memory_operand" ""))
4757 (clobber (match_operand:DI 4 "memory_operand" ""))
4758 (clobber (match_scratch 5 ""))]
4759 "reload_completed"
4760 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4761 (use (match_dup 2))
4762 (use (match_dup 3))
4763 (clobber (match_dup 5))])]
4764 "")
4765
4766;; When SSE available, it is always faster to use it!
4767(define_insn "fix_truncsfdi_sse"
4768 [(set (match_operand:DI 0 "register_operand" "=r")
4769 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4770 "TARGET_64BIT && TARGET_SSE"
4771 "cvttss2si{q}\t{%1, %0|%0, %1}"
4772 [(set_attr "type" "sse")])
4773
4774(define_insn "fix_truncdfdi_sse"
4775 [(set (match_operand:DI 0 "register_operand" "=r")
4776 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4777 "TARGET_64BIT && TARGET_SSE2"
4778 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4779 [(set_attr "type" "sse")])
4780
4781;; Signed conversion to SImode.
4782
4783(define_expand "fix_truncxfsi2"
4784 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4785 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4786 "!TARGET_64BIT && TARGET_80387"
4787 "")
4788
4789(define_expand "fix_trunctfsi2"
4790 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4791 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4792 "TARGET_80387"
4793 "")
4794
4795(define_expand "fix_truncdfsi2"
4796 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4797 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4798 "TARGET_80387 || TARGET_SSE2"
4799{
4800 if (TARGET_SSE2)
4801 {
4802 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4803 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4804 if (out != operands[0])
4805 emit_move_insn (operands[0], out);
4806 DONE;
4807 }
4808})
4809
4810(define_expand "fix_truncsfsi2"
4811 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4812 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4813 "TARGET_80387 || TARGET_SSE"
4814{
4815 if (TARGET_SSE)
4816 {
4817 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4818 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4819 if (out != operands[0])
4820 emit_move_insn (operands[0], out);
4821 DONE;
4822 }
4823})
4824
4825;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4826;; of the machinery.
4827(define_insn_and_split "*fix_truncsi_1"
4828 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4829 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4830 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4831 && !reload_completed && !reload_in_progress
4832 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4833 "#"
4834 "&& 1"
4835 [(const_int 0)]
4836{
4837 operands[2] = assign_386_stack_local (HImode, 1);
4838 operands[3] = assign_386_stack_local (HImode, 2);
4839 if (memory_operand (operands[0], VOIDmode))
4840 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4841 operands[2], operands[3]));
4842 else
4843 {
4844 operands[4] = assign_386_stack_local (SImode, 0);
4845 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4846 operands[2], operands[3],
4847 operands[4]));
4848 }
4849 DONE;
4850}
4851 [(set_attr "type" "fistp")])
4852
4853(define_insn "fix_truncsi_nomemory"
4854 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4855 (fix:SI (match_operand 1 "register_operand" "f,f")))
4856 (use (match_operand:HI 2 "memory_operand" "m,m"))
4857 (use (match_operand:HI 3 "memory_operand" "m,m"))
4858 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4859 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4860 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4861 "#"
4862 [(set_attr "type" "fistp")])
4863
4864(define_insn "fix_truncsi_memory"
4865 [(set (match_operand:SI 0 "memory_operand" "=m")
4866 (fix:SI (match_operand 1 "register_operand" "f")))
4867 (use (match_operand:HI 2 "memory_operand" "m"))
4868 (use (match_operand:HI 3 "memory_operand" "m"))]
4869 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4870 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4871 "* return output_fix_trunc (insn, operands);"
4872 [(set_attr "type" "fistp")])
4873
4874;; When SSE available, it is always faster to use it!
4875(define_insn "fix_truncsfsi_sse"
4876 [(set (match_operand:SI 0 "register_operand" "=r")
4877 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4878 "TARGET_SSE"
4879 "cvttss2si\t{%1, %0|%0, %1}"
4880 [(set_attr "type" "sse")])
4881
4882(define_insn "fix_truncdfsi_sse"
4883 [(set (match_operand:SI 0 "register_operand" "=r")
4884 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4885 "TARGET_SSE2"
4886 "cvttsd2si\t{%1, %0|%0, %1}"
4887 [(set_attr "type" "sse")])
4888
4889(define_split
4890 [(set (match_operand:SI 0 "register_operand" "")
4891 (fix:SI (match_operand 1 "register_operand" "")))
4892 (use (match_operand:HI 2 "memory_operand" ""))
4893 (use (match_operand:HI 3 "memory_operand" ""))
4894 (clobber (match_operand:SI 4 "memory_operand" ""))]
4895 "reload_completed"
4896 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4897 (use (match_dup 2))
4898 (use (match_dup 3))])
4899 (set (match_dup 0) (match_dup 4))]
4900 "")
4901
4902(define_split
4903 [(set (match_operand:SI 0 "memory_operand" "")
4904 (fix:SI (match_operand 1 "register_operand" "")))
4905 (use (match_operand:HI 2 "memory_operand" ""))
4906 (use (match_operand:HI 3 "memory_operand" ""))
4907 (clobber (match_operand:SI 4 "memory_operand" ""))]
4908 "reload_completed"
4909 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4910 (use (match_dup 2))
4911 (use (match_dup 3))])]
4912 "")
4913
4914;; Signed conversion to HImode.
4915
4916(define_expand "fix_truncxfhi2"
4917 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4918 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4919 "!TARGET_64BIT && TARGET_80387"
4920 "")
4921
4922(define_expand "fix_trunctfhi2"
4923 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4924 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4925 "TARGET_80387"
4926 "")
4927
4928(define_expand "fix_truncdfhi2"
4929 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4930 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4931 "TARGET_80387 && !TARGET_SSE2"
4932 "")
4933
4934(define_expand "fix_truncsfhi2"
4935 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4936 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4937 "TARGET_80387 && !TARGET_SSE"
4938 "")
4939
4940;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4941;; of the machinery.
4942(define_insn_and_split "*fix_trunchi_1"
4943 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4944 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4945 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4946 && !reload_completed && !reload_in_progress
4947 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4948 "#"
4949 ""
4950 [(const_int 0)]
4951{
4952 operands[2] = assign_386_stack_local (HImode, 1);
4953 operands[3] = assign_386_stack_local (HImode, 2);
4954 if (memory_operand (operands[0], VOIDmode))
4955 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4956 operands[2], operands[3]));
4957 else
4958 {
4959 operands[4] = assign_386_stack_local (HImode, 0);
4960 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4961 operands[2], operands[3],
4962 operands[4]));
4963 }
4964 DONE;
4965}
4966 [(set_attr "type" "fistp")])
4967
4968(define_insn "fix_trunchi_nomemory"
4969 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4970 (fix:HI (match_operand 1 "register_operand" "f,f")))
4971 (use (match_operand:HI 2 "memory_operand" "m,m"))
4972 (use (match_operand:HI 3 "memory_operand" "m,m"))
4973 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4974 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4975 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4976 "#"
4977 [(set_attr "type" "fistp")])
4978
4979(define_insn "fix_trunchi_memory"
4980 [(set (match_operand:HI 0 "memory_operand" "=m")
4981 (fix:HI (match_operand 1 "register_operand" "f")))
4982 (use (match_operand:HI 2 "memory_operand" "m"))
4983 (use (match_operand:HI 3 "memory_operand" "m"))]
4984 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4985 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4986 "* return output_fix_trunc (insn, operands);"
4987 [(set_attr "type" "fistp")])
4988
4989(define_split
4990 [(set (match_operand:HI 0 "memory_operand" "")
4991 (fix:HI (match_operand 1 "register_operand" "")))
4992 (use (match_operand:HI 2 "memory_operand" ""))
4993 (use (match_operand:HI 3 "memory_operand" ""))
4994 (clobber (match_operand:HI 4 "memory_operand" ""))]
4995 "reload_completed"
4996 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4997 (use (match_dup 2))
4998 (use (match_dup 3))])]
4999 "")
5000
5001(define_split
5002 [(set (match_operand:HI 0 "register_operand" "")
5003 (fix:HI (match_operand 1 "register_operand" "")))
5004 (use (match_operand:HI 2 "memory_operand" ""))
5005 (use (match_operand:HI 3 "memory_operand" ""))
5006 (clobber (match_operand:HI 4 "memory_operand" ""))]
5007 "reload_completed"
5008 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
5009 (use (match_dup 2))
5010 (use (match_dup 3))
5011 (clobber (match_dup 4))])
5012 (set (match_dup 0) (match_dup 4))]
5013 "")
5014
5015;; %% Not used yet.
5016(define_insn "x86_fnstcw_1"
5017 [(set (match_operand:HI 0 "memory_operand" "=m")
5018 (unspec:HI [(reg:HI 18)] 11))]
5019 "TARGET_80387"
5020 "fnstcw\t%0"
5021 [(set_attr "length" "2")
5022 (set_attr "mode" "HI")
5023 (set_attr "i387" "1")
5024 (set_attr "ppro_uops" "few")])
5025
5026(define_insn "x86_fldcw_1"
5027 [(set (reg:HI 18)
5028 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
5029 "TARGET_80387"
5030 "fldcw\t%0"
5031 [(set_attr "length" "2")
5032 (set_attr "mode" "HI")
5033 (set_attr "i387" "1")
5034 (set_attr "athlon_decode" "vector")
5035 (set_attr "ppro_uops" "few")])
5036
5037;; Conversion between fixed point and floating point.
5038
5039;; Even though we only accept memory inputs, the backend _really_
5040;; wants to be able to do this between registers.
5041
5042(define_insn "floathisf2"
5043 [(set (match_operand:SF 0 "register_operand" "=f,f")
5044 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5045 "TARGET_80387 && !TARGET_SSE"
5046 "@
5047 fild%z1\t%1
5048 #"
5049 [(set_attr "type" "fmov,multi")
5050 (set_attr "mode" "SF")
5051 (set_attr "fp_int_src" "true")])
5052
5053(define_expand "floatsisf2"
5054 [(set (match_operand:SF 0 "register_operand" "")
5055 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5056 "TARGET_SSE || TARGET_80387"
5057 "")
5058
5059(define_insn "*floatsisf2_i387"
5060 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5061 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5062 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5063 "@
5064 fild%z1\t%1
5065 #
5066 cvtsi2ss\t{%1, %0|%0, %1}"
5067 [(set_attr "type" "fmov,multi,sse")
5068 (set_attr "mode" "SF")
5069 (set_attr "fp_int_src" "true")])
5070
5071(define_insn "*floatsisf2_sse"
5072 [(set (match_operand:SF 0 "register_operand" "=x")
5073 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5074 "TARGET_SSE"
5075 "cvtsi2ss\t{%1, %0|%0, %1}"
5076 [(set_attr "type" "sse")
5077 (set_attr "mode" "SF")
5078 (set_attr "fp_int_src" "true")])
5079
5080(define_expand "floatdisf2"
5081 [(set (match_operand:SF 0 "register_operand" "")
5082 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5083 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
5084 "")
5085
5086(define_insn "*floatdisf2_i387_only"
5087 [(set (match_operand:SF 0 "register_operand" "=f,?f")
5088 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5089 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
5090 "@
5091 fild%z1\t%1
5092 #"
5093 [(set_attr "type" "fmov,multi")
5094 (set_attr "mode" "SF")
5095 (set_attr "fp_int_src" "true")])
5096
5097(define_insn "*floatdisf2_i387"
5098 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5099 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5100 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5101 "@
5102 fild%z1\t%1
5103 #
5104 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5105 [(set_attr "type" "fmov,multi,sse")
5106 (set_attr "mode" "SF")
5107 (set_attr "fp_int_src" "true")])
5108
5109(define_insn "*floatdisf2_sse"
5110 [(set (match_operand:SF 0 "register_operand" "=x")
5111 (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5112 "TARGET_64BIT && TARGET_SSE"
5113 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5114 [(set_attr "type" "sse")
5115 (set_attr "mode" "SF")
5116 (set_attr "fp_int_src" "true")])
5117
5118(define_insn "floathidf2"
5119 [(set (match_operand:DF 0 "register_operand" "=f,f")
5120 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5121 "TARGET_80387 && !TARGET_SSE2"
5122 "@
5123 fild%z1\t%1
5124 #"
5125 [(set_attr "type" "fmov,multi")
5126 (set_attr "mode" "DF")
5127 (set_attr "fp_int_src" "true")])
5128
5129(define_expand "floatsidf2"
5130 [(set (match_operand:DF 0 "register_operand" "")
5131 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
2795
2796(define_insn "*swapsf"
2797 [(set (match_operand:SF 0 "register_operand" "+f")
2798 (match_operand:SF 1 "register_operand" "+f"))
2799 (set (match_dup 1)
2800 (match_dup 0))]
2801 "reload_completed || !TARGET_SSE"
2802{
2803 if (STACK_TOP_P (operands[0]))
2804 return "fxch\t%1";
2805 else
2806 return "fxch\t%0";
2807}
2808 [(set_attr "type" "fxch")
2809 (set_attr "mode" "SF")])
2810
2811(define_expand "movdf"
2812 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2813 (match_operand:DF 1 "general_operand" ""))]
2814 ""
2815 "ix86_expand_move (DFmode, operands); DONE;")
2816
2817;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2818;; Size of pushdf using integer insturctions is 2+2*memory operand size
2819;; On the average, pushdf using integers can be still shorter. Allow this
2820;; pattern for optimize_size too.
2821
2822(define_insn "*pushdf_nointeger"
2823 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2824 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2825 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2826{
2827 switch (which_alternative)
2828 {
2829 case 0:
2830 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2831 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2832 operands[2] = stack_pointer_rtx;
2833 operands[3] = GEN_INT (8);
2834 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2835 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2836 else
2837 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2838
2839 case 1:
2840 case 2:
2841 case 3:
2842 return "#";
2843
2844 default:
2845 abort ();
2846 }
2847}
2848 [(set_attr "type" "multi")
2849 (set_attr "mode" "DF,SI,SI,DF")])
2850
2851(define_insn "*pushdf_integer"
2852 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2853 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2854 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2855{
2856 switch (which_alternative)
2857 {
2858 case 0:
2859 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2860 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2861 operands[2] = stack_pointer_rtx;
2862 operands[3] = GEN_INT (8);
2863 if (TARGET_64BIT)
2864 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2865 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2866 else
2867 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2868 else
2869 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2870 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2871 else
2872 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2873
2874
2875 case 1:
2876 case 2:
2877 return "#";
2878
2879 default:
2880 abort ();
2881 }
2882}
2883 [(set_attr "type" "multi")
2884 (set_attr "mode" "DF,SI,DF")])
2885
2886;; %%% Kill this when call knows how to work this out.
2887(define_split
2888 [(set (match_operand:DF 0 "push_operand" "")
2889 (match_operand:DF 1 "register_operand" ""))]
2890 "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2891 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2892 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2893 "")
2894
2895(define_split
2896 [(set (match_operand:DF 0 "push_operand" "")
2897 (match_operand:DF 1 "register_operand" ""))]
2898 "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2899 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2900 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2901 "")
2902
2903(define_split
2904 [(set (match_operand:DF 0 "push_operand" "")
2905 (match_operand:DF 1 "general_operand" ""))]
2906 "reload_completed"
2907 [(const_int 0)]
2908 "ix86_split_long_move (operands); DONE;")
2909
2910;; Moving is usually shorter when only FP registers are used. This separate
2911;; movdf pattern avoids the use of integer registers for FP operations
2912;; when optimizing for size.
2913
2914(define_insn "*movdf_nointeger"
2915 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2916 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
2917 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2918 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2919 && (reload_in_progress || reload_completed
2920 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2921 || GET_CODE (operands[1]) != CONST_DOUBLE
2922 || memory_operand (operands[0], DFmode))"
2923{
2924 switch (which_alternative)
2925 {
2926 case 0:
2927 if (REG_P (operands[1])
2928 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2929 return "fstp\t%y0";
2930 else if (STACK_TOP_P (operands[0]))
2931 return "fld%z1\t%y1";
2932 else
2933 return "fst\t%y0";
2934
2935 case 1:
2936 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2937 return "fstp%z0\t%y0";
2938 else
2939 return "fst%z0\t%y0";
2940
2941 case 2:
2942 switch (standard_80387_constant_p (operands[1]))
2943 {
2944 case 1:
2945 return "fldz";
2946 case 2:
2947 return "fld1";
2948 }
2949 abort();
2950
2951 case 3:
2952 case 4:
2953 return "#";
2954 case 5:
2955 return "pxor\t%0, %0";
2956 case 6:
2957 if (TARGET_PARTIAL_REG_DEPENDENCY)
2958 return "movapd\t{%1, %0|%0, %1}";
2959 else
2960 return "movsd\t{%1, %0|%0, %1}";
2961 case 7:
2962 case 8:
2963 return "movsd\t{%1, %0|%0, %1}";
2964
2965 default:
2966 abort();
2967 }
2968}
2969 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2970 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2971
2972(define_insn "*movdf_integer"
2973 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2974 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
2975 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2976 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2977 && (reload_in_progress || reload_completed
2978 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2979 || GET_CODE (operands[1]) != CONST_DOUBLE
2980 || memory_operand (operands[0], DFmode))"
2981{
2982 switch (which_alternative)
2983 {
2984 case 0:
2985 if (REG_P (operands[1])
2986 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2987 return "fstp\t%y0";
2988 else if (STACK_TOP_P (operands[0]))
2989 return "fld%z1\t%y1";
2990 else
2991 return "fst\t%y0";
2992
2993 case 1:
2994 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2995 return "fstp%z0\t%y0";
2996 else
2997 return "fst%z0\t%y0";
2998
2999 case 2:
3000 switch (standard_80387_constant_p (operands[1]))
3001 {
3002 case 1:
3003 return "fldz";
3004 case 2:
3005 return "fld1";
3006 }
3007 abort();
3008
3009 case 3:
3010 case 4:
3011 return "#";
3012
3013 case 5:
3014 return "pxor\t%0, %0";
3015 case 6:
3016 if (TARGET_PARTIAL_REG_DEPENDENCY)
3017 return "movapd\t{%1, %0|%0, %1}";
3018 else
3019 return "movsd\t{%1, %0|%0, %1}";
3020 case 7:
3021 case 8:
3022 return "movsd\t{%1, %0|%0, %1}";
3023
3024 default:
3025 abort();
3026 }
3027}
3028 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
3029 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
3030
3031(define_split
3032 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3033 (match_operand:DF 1 "general_operand" ""))]
3034 "reload_completed
3035 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3036 && ! (ANY_FP_REG_P (operands[0]) ||
3037 (GET_CODE (operands[0]) == SUBREG
3038 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039 && ! (ANY_FP_REG_P (operands[1]) ||
3040 (GET_CODE (operands[1]) == SUBREG
3041 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3042 [(const_int 0)]
3043 "ix86_split_long_move (operands); DONE;")
3044
3045(define_insn "*swapdf"
3046 [(set (match_operand:DF 0 "register_operand" "+f")
3047 (match_operand:DF 1 "register_operand" "+f"))
3048 (set (match_dup 1)
3049 (match_dup 0))]
3050 "reload_completed || !TARGET_SSE2"
3051{
3052 if (STACK_TOP_P (operands[0]))
3053 return "fxch\t%1";
3054 else
3055 return "fxch\t%0";
3056}
3057 [(set_attr "type" "fxch")
3058 (set_attr "mode" "DF")])
3059
3060(define_expand "movxf"
3061 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3062 (match_operand:XF 1 "general_operand" ""))]
3063 "!TARGET_64BIT"
3064 "ix86_expand_move (XFmode, operands); DONE;")
3065
3066(define_expand "movtf"
3067 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3068 (match_operand:TF 1 "general_operand" ""))]
3069 ""
3070 "ix86_expand_move (TFmode, operands); DONE;")
3071
3072;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3073;; Size of pushdf using integer insturctions is 3+3*memory operand size
3074;; Pushing using integer instructions is longer except for constants
3075;; and direct memory references.
3076;; (assuming that any given constant is pushed only once, but this ought to be
3077;; handled elsewhere).
3078
3079(define_insn "*pushxf_nointeger"
3080 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3081 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3082 "!TARGET_64BIT && optimize_size"
3083{
3084 switch (which_alternative)
3085 {
3086 case 0:
3087 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3088 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3089 operands[2] = stack_pointer_rtx;
3090 operands[3] = GEN_INT (12);
3091 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3092 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3093 else
3094 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3095
3096 case 1:
3097 case 2:
3098 return "#";
3099
3100 default:
3101 abort ();
3102 }
3103}
3104 [(set_attr "type" "multi")
3105 (set_attr "mode" "XF,SI,SI")])
3106
3107(define_insn "*pushtf_nointeger"
3108 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3109 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
3110 "optimize_size"
3111{
3112 switch (which_alternative)
3113 {
3114 case 0:
3115 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3116 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3117 operands[2] = stack_pointer_rtx;
3118 operands[3] = GEN_INT (16);
3119 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3120 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3121 else
3122 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3123
3124 case 1:
3125 case 2:
3126 return "#";
3127
3128 default:
3129 abort ();
3130 }
3131}
3132 [(set_attr "type" "multi")
3133 (set_attr "mode" "XF,SI,SI")])
3134
3135(define_insn "*pushxf_integer"
3136 [(set (match_operand:XF 0 "push_operand" "=<,<")
3137 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
3138 "!TARGET_64BIT && !optimize_size"
3139{
3140 switch (which_alternative)
3141 {
3142 case 0:
3143 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3144 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3145 operands[2] = stack_pointer_rtx;
3146 operands[3] = GEN_INT (12);
3147 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3148 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3149 else
3150 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3151
3152 case 1:
3153 return "#";
3154
3155 default:
3156 abort ();
3157 }
3158}
3159 [(set_attr "type" "multi")
3160 (set_attr "mode" "XF,SI")])
3161
3162(define_insn "*pushtf_integer"
3163 [(set (match_operand:TF 0 "push_operand" "=<,<")
3164 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
3165 "!optimize_size"
3166{
3167 switch (which_alternative)
3168 {
3169 case 0:
3170 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3171 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3172 operands[2] = stack_pointer_rtx;
3173 operands[3] = GEN_INT (16);
3174 if (TARGET_64BIT)
3175 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3176 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3177 else
3178 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3179 else
3180 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3181 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3182 else
3183 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3184
3185 case 1:
3186 return "#";
3187
3188 default:
3189 abort ();
3190 }
3191}
3192 [(set_attr "type" "multi")
3193 (set_attr "mode" "XF,SI")])
3194
3195(define_split
3196 [(set (match_operand 0 "push_operand" "")
3197 (match_operand 1 "general_operand" ""))]
3198 "reload_completed
3199 && (GET_MODE (operands[0]) == XFmode
3200 || GET_MODE (operands[0]) == TFmode
3201 || GET_MODE (operands[0]) == DFmode)
3202 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
3203 [(const_int 0)]
3204 "ix86_split_long_move (operands); DONE;")
3205
3206(define_split
3207 [(set (match_operand:XF 0 "push_operand" "")
3208 (match_operand:XF 1 "register_operand" ""))]
3209 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3210 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3211 (set (mem:XF (reg:SI 7)) (match_dup 1))])
3212
3213(define_split
3214 [(set (match_operand:TF 0 "push_operand" "")
3215 (match_operand:TF 1 "register_operand" ""))]
3216 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3217 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3218 (set (mem:TF (reg:SI 7)) (match_dup 1))])
3219
3220(define_split
3221 [(set (match_operand:TF 0 "push_operand" "")
3222 (match_operand:TF 1 "register_operand" ""))]
3223 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3224 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3225 (set (mem:TF (reg:DI 7)) (match_dup 1))])
3226
3227;; Do not use integer registers when optimizing for size
3228(define_insn "*movxf_nointeger"
3229 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3230 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3231 "!TARGET_64BIT
3232 && optimize_size
3233 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3234 && (reload_in_progress || reload_completed
3235 || GET_CODE (operands[1]) != CONST_DOUBLE
3236 || memory_operand (operands[0], XFmode))"
3237{
3238 switch (which_alternative)
3239 {
3240 case 0:
3241 if (REG_P (operands[1])
3242 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3243 return "fstp\t%y0";
3244 else if (STACK_TOP_P (operands[0]))
3245 return "fld%z1\t%y1";
3246 else
3247 return "fst\t%y0";
3248
3249 case 1:
3250 /* There is no non-popping store to memory for XFmode. So if
3251 we need one, follow the store with a load. */
3252 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3253 return "fstp%z0\t%y0\;fld%z0\t%y0";
3254 else
3255 return "fstp%z0\t%y0";
3256
3257 case 2:
3258 switch (standard_80387_constant_p (operands[1]))
3259 {
3260 case 1:
3261 return "fldz";
3262 case 2:
3263 return "fld1";
3264 }
3265 break;
3266
3267 case 3: case 4:
3268 return "#";
3269 }
3270 abort();
3271}
3272 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3273 (set_attr "mode" "XF,XF,XF,SI,SI")])
3274
3275(define_insn "*movtf_nointeger"
3276 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3277 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3278 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3279 && optimize_size
3280 && (reload_in_progress || reload_completed
3281 || GET_CODE (operands[1]) != CONST_DOUBLE
3282 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3283 || memory_operand (operands[0], TFmode))"
3284{
3285 switch (which_alternative)
3286 {
3287 case 0:
3288 if (REG_P (operands[1])
3289 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3290 return "fstp\t%y0";
3291 else if (STACK_TOP_P (operands[0]))
3292 return "fld%z1\t%y1";
3293 else
3294 return "fst\t%y0";
3295
3296 case 1:
3297 /* There is no non-popping store to memory for XFmode. So if
3298 we need one, follow the store with a load. */
3299 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3300 return "fstp%z0\t%y0\;fld%z0\t%y0";
3301 else
3302 return "fstp%z0\t%y0";
3303
3304 case 2:
3305 switch (standard_80387_constant_p (operands[1]))
3306 {
3307 case 1:
3308 return "fldz";
3309 case 2:
3310 return "fld1";
3311 }
3312 break;
3313
3314 case 3: case 4:
3315 return "#";
3316 }
3317 abort();
3318}
3319 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3320 (set_attr "mode" "XF,XF,XF,SI,SI")])
3321
3322(define_insn "*movxf_integer"
3323 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3324 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3325 "!TARGET_64BIT
3326 && !optimize_size
3327 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3328 && (reload_in_progress || reload_completed
3329 || GET_CODE (operands[1]) != CONST_DOUBLE
3330 || memory_operand (operands[0], XFmode))"
3331{
3332 switch (which_alternative)
3333 {
3334 case 0:
3335 if (REG_P (operands[1])
3336 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3337 return "fstp\t%y0";
3338 else if (STACK_TOP_P (operands[0]))
3339 return "fld%z1\t%y1";
3340 else
3341 return "fst\t%y0";
3342
3343 case 1:
3344 /* There is no non-popping store to memory for XFmode. So if
3345 we need one, follow the store with a load. */
3346 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3347 return "fstp%z0\t%y0\;fld%z0\t%y0";
3348 else
3349 return "fstp%z0\t%y0";
3350
3351 case 2:
3352 switch (standard_80387_constant_p (operands[1]))
3353 {
3354 case 1:
3355 return "fldz";
3356 case 2:
3357 return "fld1";
3358 }
3359 break;
3360
3361 case 3: case 4:
3362 return "#";
3363 }
3364 abort();
3365}
3366 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3367 (set_attr "mode" "XF,XF,XF,SI,SI")])
3368
3369(define_insn "*movtf_integer"
3370 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3371 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3372 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3373 && !optimize_size
3374 && (reload_in_progress || reload_completed
3375 || GET_CODE (operands[1]) != CONST_DOUBLE
3376 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3377 || memory_operand (operands[0], TFmode))"
3378{
3379 switch (which_alternative)
3380 {
3381 case 0:
3382 if (REG_P (operands[1])
3383 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3384 return "fstp\t%y0";
3385 else if (STACK_TOP_P (operands[0]))
3386 return "fld%z1\t%y1";
3387 else
3388 return "fst\t%y0";
3389
3390 case 1:
3391 /* There is no non-popping store to memory for XFmode. So if
3392 we need one, follow the store with a load. */
3393 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3394 return "fstp%z0\t%y0\;fld%z0\t%y0";
3395 else
3396 return "fstp%z0\t%y0";
3397
3398 case 2:
3399 switch (standard_80387_constant_p (operands[1]))
3400 {
3401 case 1:
3402 return "fldz";
3403 case 2:
3404 return "fld1";
3405 }
3406 break;
3407
3408 case 3: case 4:
3409 return "#";
3410 }
3411 abort();
3412}
3413 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3414 (set_attr "mode" "XF,XF,XF,SI,SI")])
3415
3416(define_split
3417 [(set (match_operand 0 "nonimmediate_operand" "")
3418 (match_operand 1 "general_operand" ""))]
3419 "reload_completed
3420 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3421 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3422 && ! (ANY_FP_REG_P (operands[0]) ||
3423 (GET_CODE (operands[0]) == SUBREG
3424 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3425 && ! (ANY_FP_REG_P (operands[1]) ||
3426 (GET_CODE (operands[1]) == SUBREG
3427 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3428 [(const_int 0)]
3429 "ix86_split_long_move (operands); DONE;")
3430
3431(define_split
3432 [(set (match_operand 0 "register_operand" "")
3433 (match_operand 1 "memory_operand" ""))]
3434 "reload_completed
3435 && GET_CODE (operands[1]) == MEM
3436 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3437 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3438 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3439 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3440 && (!(SSE_REG_P (operands[0]) ||
3441 (GET_CODE (operands[0]) == SUBREG
3442 && SSE_REG_P (SUBREG_REG (operands[0]))))
3443 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3444 && (!(FP_REG_P (operands[0]) ||
3445 (GET_CODE (operands[0]) == SUBREG
3446 && FP_REG_P (SUBREG_REG (operands[0]))))
3447 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3448 [(set (match_dup 0)
3449 (match_dup 1))]
3450 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3451
3452(define_insn "swapxf"
3453 [(set (match_operand:XF 0 "register_operand" "+f")
3454 (match_operand:XF 1 "register_operand" "+f"))
3455 (set (match_dup 1)
3456 (match_dup 0))]
3457 ""
3458{
3459 if (STACK_TOP_P (operands[0]))
3460 return "fxch\t%1";
3461 else
3462 return "fxch\t%0";
3463}
3464 [(set_attr "type" "fxch")
3465 (set_attr "mode" "XF")])
3466
3467(define_insn "swaptf"
3468 [(set (match_operand:TF 0 "register_operand" "+f")
3469 (match_operand:TF 1 "register_operand" "+f"))
3470 (set (match_dup 1)
3471 (match_dup 0))]
3472 ""
3473{
3474 if (STACK_TOP_P (operands[0]))
3475 return "fxch\t%1";
3476 else
3477 return "fxch\t%0";
3478}
3479 [(set_attr "type" "fxch")
3480 (set_attr "mode" "XF")])
3481
3482;; Zero extension instructions
3483
3484(define_expand "zero_extendhisi2"
3485 [(set (match_operand:SI 0 "register_operand" "")
3486 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3487 ""
3488{
3489 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3490 {
3491 operands[1] = force_reg (HImode, operands[1]);
3492 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3493 DONE;
3494 }
3495})
3496
3497(define_insn "zero_extendhisi2_and"
3498 [(set (match_operand:SI 0 "register_operand" "=r")
3499 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3500 (clobber (reg:CC 17))]
3501 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3502 "#"
3503 [(set_attr "type" "alu1")
3504 (set_attr "mode" "SI")])
3505
3506(define_split
3507 [(set (match_operand:SI 0 "register_operand" "")
3508 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3509 (clobber (reg:CC 17))]
3510 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3511 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3512 (clobber (reg:CC 17))])]
3513 "")
3514
3515(define_insn "*zero_extendhisi2_movzwl"
3516 [(set (match_operand:SI 0 "register_operand" "=r")
3517 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3518 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3519 "movz{wl|x}\t{%1, %0|%0, %1}"
3520 [(set_attr "type" "imovx")
3521 (set_attr "mode" "SI")])
3522
3523(define_expand "zero_extendqihi2"
3524 [(parallel
3525 [(set (match_operand:HI 0 "register_operand" "")
3526 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3527 (clobber (reg:CC 17))])]
3528 ""
3529 "")
3530
3531(define_insn "*zero_extendqihi2_and"
3532 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3533 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3534 (clobber (reg:CC 17))]
3535 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3536 "#"
3537 [(set_attr "type" "alu1")
3538 (set_attr "mode" "HI")])
3539
3540(define_insn "*zero_extendqihi2_movzbw_and"
3541 [(set (match_operand:HI 0 "register_operand" "=r,r")
3542 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3543 (clobber (reg:CC 17))]
3544 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3545 "#"
3546 [(set_attr "type" "imovx,alu1")
3547 (set_attr "mode" "HI")])
3548
3549(define_insn "*zero_extendqihi2_movzbw"
3550 [(set (match_operand:HI 0 "register_operand" "=r")
3551 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3552 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3553 "movz{bw|x}\t{%1, %0|%0, %1}"
3554 [(set_attr "type" "imovx")
3555 (set_attr "mode" "HI")])
3556
3557;; For the movzbw case strip only the clobber
3558(define_split
3559 [(set (match_operand:HI 0 "register_operand" "")
3560 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3561 (clobber (reg:CC 17))]
3562 "reload_completed
3563 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3564 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3565 [(set (match_operand:HI 0 "register_operand" "")
3566 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3567
3568;; When source and destination does not overlap, clear destination
3569;; first and then do the movb
3570(define_split
3571 [(set (match_operand:HI 0 "register_operand" "")
3572 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3573 (clobber (reg:CC 17))]
3574 "reload_completed
3575 && ANY_QI_REG_P (operands[0])
3576 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3577 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3578 [(set (match_dup 0) (const_int 0))
3579 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3580 "operands[2] = gen_lowpart (QImode, operands[0]);")
3581
3582;; Rest is handled by single and.
3583(define_split
3584 [(set (match_operand:HI 0 "register_operand" "")
3585 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3586 (clobber (reg:CC 17))]
3587 "reload_completed
3588 && true_regnum (operands[0]) == true_regnum (operands[1])"
3589 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3590 (clobber (reg:CC 17))])]
3591 "")
3592
3593(define_expand "zero_extendqisi2"
3594 [(parallel
3595 [(set (match_operand:SI 0 "register_operand" "")
3596 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3597 (clobber (reg:CC 17))])]
3598 ""
3599 "")
3600
3601(define_insn "*zero_extendqisi2_and"
3602 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3603 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3604 (clobber (reg:CC 17))]
3605 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3606 "#"
3607 [(set_attr "type" "alu1")
3608 (set_attr "mode" "SI")])
3609
3610(define_insn "*zero_extendqisi2_movzbw_and"
3611 [(set (match_operand:SI 0 "register_operand" "=r,r")
3612 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3613 (clobber (reg:CC 17))]
3614 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3615 "#"
3616 [(set_attr "type" "imovx,alu1")
3617 (set_attr "mode" "SI")])
3618
3619(define_insn "*zero_extendqisi2_movzbw"
3620 [(set (match_operand:SI 0 "register_operand" "=r")
3621 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3622 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3623 "movz{bl|x}\t{%1, %0|%0, %1}"
3624 [(set_attr "type" "imovx")
3625 (set_attr "mode" "SI")])
3626
3627;; For the movzbl case strip only the clobber
3628(define_split
3629 [(set (match_operand:SI 0 "register_operand" "")
3630 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3631 (clobber (reg:CC 17))]
3632 "reload_completed
3633 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3634 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3635 [(set (match_dup 0)
3636 (zero_extend:SI (match_dup 1)))])
3637
3638;; When source and destination does not overlap, clear destination
3639;; first and then do the movb
3640(define_split
3641 [(set (match_operand:SI 0 "register_operand" "")
3642 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3643 (clobber (reg:CC 17))]
3644 "reload_completed
3645 && ANY_QI_REG_P (operands[0])
3646 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3647 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3648 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3649 [(set (match_dup 0) (const_int 0))
3650 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3651 "operands[2] = gen_lowpart (QImode, operands[0]);")
3652
3653;; Rest is handled by single and.
3654(define_split
3655 [(set (match_operand:SI 0 "register_operand" "")
3656 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3657 (clobber (reg:CC 17))]
3658 "reload_completed
3659 && true_regnum (operands[0]) == true_regnum (operands[1])"
3660 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3661 (clobber (reg:CC 17))])]
3662 "")
3663
3664;; %%% Kill me once multi-word ops are sane.
3665(define_expand "zero_extendsidi2"
3666 [(set (match_operand:DI 0 "register_operand" "=r")
3667 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3668 ""
3669 "if (!TARGET_64BIT)
3670 {
3671 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3672 DONE;
3673 }
3674 ")
3675
3676(define_insn "zero_extendsidi2_32"
3677 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3678 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3679 (clobber (reg:CC 17))]
3680 "!TARGET_64BIT"
3681 "#"
3682 [(set_attr "mode" "SI")])
3683
3684(define_insn "zero_extendsidi2_rex64"
3685 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3686 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3687 "TARGET_64BIT"
3688 "@
3689 mov\t{%k1, %k0|%k0, %k1}
3690 #"
3691 [(set_attr "type" "imovx,imov")
3692 (set_attr "mode" "SI,DI")])
3693
3694(define_split
3695 [(set (match_operand:DI 0 "memory_operand" "")
3696 (zero_extend:DI (match_dup 0)))]
3697 "TARGET_64BIT"
3698 [(set (match_dup 4) (const_int 0))]
3699 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3700
3701(define_split
3702 [(set (match_operand:DI 0 "register_operand" "")
3703 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3704 (clobber (reg:CC 17))]
3705 "!TARGET_64BIT && reload_completed
3706 && true_regnum (operands[0]) == true_regnum (operands[1])"
3707 [(set (match_dup 4) (const_int 0))]
3708 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3709
3710(define_split
3711 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3712 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3713 (clobber (reg:CC 17))]
3714 "!TARGET_64BIT && reload_completed"
3715 [(set (match_dup 3) (match_dup 1))
3716 (set (match_dup 4) (const_int 0))]
3717 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3718
3719(define_insn "zero_extendhidi2"
3720 [(set (match_operand:DI 0 "register_operand" "=r,r")
3721 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3722 "TARGET_64BIT"
3723 "@
3724 movz{wl|x}\t{%1, %k0|%k0, %1}
3725 movz{wq|x}\t{%1, %0|%0, %1}"
3726 [(set_attr "type" "imovx")
3727 (set_attr "mode" "SI,DI")])
3728
3729(define_insn "zero_extendqidi2"
3730 [(set (match_operand:DI 0 "register_operand" "=r,r")
3731 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3732 "TARGET_64BIT"
3733 "@
3734 movz{bl|x}\t{%1, %k0|%k0, %1}
3735 movz{bq|x}\t{%1, %0|%0, %1}"
3736 [(set_attr "type" "imovx")
3737 (set_attr "mode" "SI,DI")])
3738
3739;; Sign extension instructions
3740
3741(define_expand "extendsidi2"
3742 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3743 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3744 (clobber (reg:CC 17))
3745 (clobber (match_scratch:SI 2 ""))])]
3746 ""
3747{
3748 if (TARGET_64BIT)
3749 {
3750 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3751 DONE;
3752 }
3753})
3754
3755(define_insn "*extendsidi2_1"
3756 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3757 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3758 (clobber (reg:CC 17))
3759 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3760 "!TARGET_64BIT"
3761 "#")
3762
3763(define_insn "extendsidi2_rex64"
3764 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3765 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3766 "TARGET_64BIT"
3767 "@
3768 {cltq|cdqe}
3769 movs{lq|x}\t{%1,%0|%0, %1}"
3770 [(set_attr "type" "imovx")
3771 (set_attr "mode" "DI")
3772 (set_attr "prefix_0f" "0")
3773 (set_attr "modrm" "0,1")])
3774
3775(define_insn "extendhidi2"
3776 [(set (match_operand:DI 0 "register_operand" "=r")
3777 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3778 "TARGET_64BIT"
3779 "movs{wq|x}\t{%1,%0|%0, %1}"
3780 [(set_attr "type" "imovx")
3781 (set_attr "mode" "DI")])
3782
3783(define_insn "extendqidi2"
3784 [(set (match_operand:DI 0 "register_operand" "=r")
3785 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3786 "TARGET_64BIT"
3787 "movs{bq|x}\t{%1,%0|%0, %1}"
3788 [(set_attr "type" "imovx")
3789 (set_attr "mode" "DI")])
3790
3791;; Extend to memory case when source register does die.
3792(define_split
3793 [(set (match_operand:DI 0 "memory_operand" "")
3794 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3795 (clobber (reg:CC 17))
3796 (clobber (match_operand:SI 2 "register_operand" ""))]
3797 "(reload_completed
3798 && dead_or_set_p (insn, operands[1])
3799 && !reg_mentioned_p (operands[1], operands[0]))"
3800 [(set (match_dup 3) (match_dup 1))
3801 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3802 (clobber (reg:CC 17))])
3803 (set (match_dup 4) (match_dup 1))]
3804 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3805
3806;; Extend to memory case when source register does not die.
3807(define_split
3808 [(set (match_operand:DI 0 "memory_operand" "")
3809 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3810 (clobber (reg:CC 17))
3811 (clobber (match_operand:SI 2 "register_operand" ""))]
3812 "reload_completed"
3813 [(const_int 0)]
3814{
3815 split_di (&operands[0], 1, &operands[3], &operands[4]);
3816
3817 emit_move_insn (operands[3], operands[1]);
3818
3819 /* Generate a cltd if possible and doing so it profitable. */
3820 if (true_regnum (operands[1]) == 0
3821 && true_regnum (operands[2]) == 1
3822 && (optimize_size || TARGET_USE_CLTD))
3823 {
3824 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3825 }
3826 else
3827 {
3828 emit_move_insn (operands[2], operands[1]);
3829 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3830 }
3831 emit_move_insn (operands[4], operands[2]);
3832 DONE;
3833})
3834
3835;; Extend to register case. Optimize case where source and destination
3836;; registers match and cases where we can use cltd.
3837(define_split
3838 [(set (match_operand:DI 0 "register_operand" "")
3839 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3840 (clobber (reg:CC 17))
3841 (clobber (match_scratch:SI 2 ""))]
3842 "reload_completed"
3843 [(const_int 0)]
3844{
3845 split_di (&operands[0], 1, &operands[3], &operands[4]);
3846
3847 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3848 emit_move_insn (operands[3], operands[1]);
3849
3850 /* Generate a cltd if possible and doing so it profitable. */
3851 if (true_regnum (operands[3]) == 0
3852 && (optimize_size || TARGET_USE_CLTD))
3853 {
3854 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3855 DONE;
3856 }
3857
3858 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3859 emit_move_insn (operands[4], operands[1]);
3860
3861 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3862 DONE;
3863})
3864
3865(define_insn "extendhisi2"
3866 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3867 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3868 ""
3869{
3870 switch (get_attr_prefix_0f (insn))
3871 {
3872 case 0:
3873 return "{cwtl|cwde}";
3874 default:
3875 return "movs{wl|x}\t{%1,%0|%0, %1}";
3876 }
3877}
3878 [(set_attr "type" "imovx")
3879 (set_attr "mode" "SI")
3880 (set (attr "prefix_0f")
3881 ;; movsx is short decodable while cwtl is vector decoded.
3882 (if_then_else (and (eq_attr "cpu" "!k6")
3883 (eq_attr "alternative" "0"))
3884 (const_string "0")
3885 (const_string "1")))
3886 (set (attr "modrm")
3887 (if_then_else (eq_attr "prefix_0f" "0")
3888 (const_string "0")
3889 (const_string "1")))])
3890
3891(define_insn "*extendhisi2_zext"
3892 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3893 (zero_extend:DI
3894 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3895 "TARGET_64BIT"
3896{
3897 switch (get_attr_prefix_0f (insn))
3898 {
3899 case 0:
3900 return "{cwtl|cwde}";
3901 default:
3902 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3903 }
3904}
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "SI")
3907 (set (attr "prefix_0f")
3908 ;; movsx is short decodable while cwtl is vector decoded.
3909 (if_then_else (and (eq_attr "cpu" "!k6")
3910 (eq_attr "alternative" "0"))
3911 (const_string "0")
3912 (const_string "1")))
3913 (set (attr "modrm")
3914 (if_then_else (eq_attr "prefix_0f" "0")
3915 (const_string "0")
3916 (const_string "1")))])
3917
3918(define_insn "extendqihi2"
3919 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3920 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3921 ""
3922{
3923 switch (get_attr_prefix_0f (insn))
3924 {
3925 case 0:
3926 return "{cbtw|cbw}";
3927 default:
3928 return "movs{bw|x}\t{%1,%0|%0, %1}";
3929 }
3930}
3931 [(set_attr "type" "imovx")
3932 (set_attr "mode" "HI")
3933 (set (attr "prefix_0f")
3934 ;; movsx is short decodable while cwtl is vector decoded.
3935 (if_then_else (and (eq_attr "cpu" "!k6")
3936 (eq_attr "alternative" "0"))
3937 (const_string "0")
3938 (const_string "1")))
3939 (set (attr "modrm")
3940 (if_then_else (eq_attr "prefix_0f" "0")
3941 (const_string "0")
3942 (const_string "1")))])
3943
3944(define_insn "extendqisi2"
3945 [(set (match_operand:SI 0 "register_operand" "=r")
3946 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3947 ""
3948 "movs{bl|x}\t{%1,%0|%0, %1}"
3949 [(set_attr "type" "imovx")
3950 (set_attr "mode" "SI")])
3951
3952(define_insn "*extendqisi2_zext"
3953 [(set (match_operand:DI 0 "register_operand" "=r")
3954 (zero_extend:DI
3955 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3956 "TARGET_64BIT"
3957 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3958 [(set_attr "type" "imovx")
3959 (set_attr "mode" "SI")])
3960
3961;; Conversions between float and double.
3962
3963;; These are all no-ops in the model used for the 80387. So just
3964;; emit moves.
3965
3966;; %%% Kill these when call knows how to work out a DFmode push earlier.
3967(define_insn "*dummy_extendsfdf2"
3968 [(set (match_operand:DF 0 "push_operand" "=<")
3969 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3970 "0"
3971 "#")
3972
3973(define_split
3974 [(set (match_operand:DF 0 "push_operand" "")
3975 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3976 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3977 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3978 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3979
3980(define_split
3981 [(set (match_operand:DF 0 "push_operand" "")
3982 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3983 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3984 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3985 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3986
3987(define_insn "*dummy_extendsfxf2"
3988 [(set (match_operand:XF 0 "push_operand" "=<")
3989 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3990 "0"
3991 "#")
3992
3993(define_split
3994 [(set (match_operand:XF 0 "push_operand" "")
3995 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3996 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3997 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3998 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3999
4000(define_insn "*dummy_extendsftf2"
4001 [(set (match_operand:TF 0 "push_operand" "=<")
4002 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4003 "0"
4004 "#")
4005
4006(define_split
4007 [(set (match_operand:TF 0 "push_operand" "")
4008 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
4009 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4010 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4011 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
4012
4013(define_split
4014 [(set (match_operand:TF 0 "push_operand" "")
4015 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
4016 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4017 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
4018 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
4019
4020(define_insn "*dummy_extenddfxf2"
4021 [(set (match_operand:XF 0 "push_operand" "=<")
4022 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4023 "0"
4024 "#")
4025
4026(define_split
4027 [(set (match_operand:XF 0 "push_operand" "")
4028 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
4029 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4030 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
4031 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4032
4033(define_insn "*dummy_extenddftf2"
4034 [(set (match_operand:TF 0 "push_operand" "=<")
4035 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4036 "0"
4037 "#")
4038
4039(define_split
4040 [(set (match_operand:TF 0 "push_operand" "")
4041 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4042 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4043 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4044 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4045
4046(define_split
4047 [(set (match_operand:TF 0 "push_operand" "")
4048 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4049 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4050 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
4051 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
4052
4053(define_expand "extendsfdf2"
4054 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4055 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
4056 "TARGET_80387 || TARGET_SSE2"
4057{
4058 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4059 operands[1] = force_reg (SFmode, operands[1]);
4060})
4061
4062(define_insn "*extendsfdf2_1"
4063 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
4064 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
4065 "(TARGET_80387 || TARGET_SSE2)
4066 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4067{
4068 switch (which_alternative)
4069 {
4070 case 0:
4071 if (REG_P (operands[1])
4072 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4073 return "fstp\t%y0";
4074 else if (STACK_TOP_P (operands[0]))
4075 return "fld%z1\t%y1";
4076 else
4077 return "fst\t%y0";
4078
4079 case 1:
4080 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4081 return "fstp%z0\t%y0";
4082
4083 else
4084 return "fst%z0\t%y0";
4085 case 2:
4086 return "cvtss2sd\t{%1, %0|%0, %1}";
4087
4088 default:
4089 abort ();
4090 }
4091}
4092 [(set_attr "type" "fmov,fmov,sse")
4093 (set_attr "mode" "SF,XF,DF")])
4094
4095(define_insn "*extendsfdf2_1_sse_only"
4096 [(set (match_operand:DF 0 "register_operand" "=Y")
4097 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
4098 "!TARGET_80387 && TARGET_SSE2
4099 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4100 "cvtss2sd\t{%1, %0|%0, %1}"
4101 [(set_attr "type" "sse")
4102 (set_attr "mode" "DF")])
4103
4104(define_expand "extendsfxf2"
4105 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4106 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
4107 "!TARGET_64BIT && TARGET_80387"
4108{
4109 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4110 operands[1] = force_reg (SFmode, operands[1]);
4111})
4112
4113(define_insn "*extendsfxf2_1"
4114 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4115 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4116 "!TARGET_64BIT && TARGET_80387
4117 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4118{
4119 switch (which_alternative)
4120 {
4121 case 0:
4122 if (REG_P (operands[1])
4123 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4124 return "fstp\t%y0";
4125 else if (STACK_TOP_P (operands[0]))
4126 return "fld%z1\t%y1";
4127 else
4128 return "fst\t%y0";
4129
4130 case 1:
4131 /* There is no non-popping store to memory for XFmode. So if
4132 we need one, follow the store with a load. */
4133 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4134 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4135 else
4136 return "fstp%z0\t%y0";
4137
4138 default:
4139 abort ();
4140 }
4141}
4142 [(set_attr "type" "fmov")
4143 (set_attr "mode" "SF,XF")])
4144
4145(define_expand "extendsftf2"
4146 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4147 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
4148 "TARGET_80387"
4149{
4150 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4151 operands[1] = force_reg (SFmode, operands[1]);
4152})
4153
4154(define_insn "*extendsftf2_1"
4155 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4156 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4157 "TARGET_80387
4158 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4159{
4160 switch (which_alternative)
4161 {
4162 case 0:
4163 if (REG_P (operands[1])
4164 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4165 return "fstp\t%y0";
4166 else if (STACK_TOP_P (operands[0]))
4167 return "fld%z1\t%y1";
4168 else
4169 return "fst\t%y0";
4170
4171 case 1:
4172 /* There is no non-popping store to memory for XFmode. So if
4173 we need one, follow the store with a load. */
4174 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4175 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4176 else
4177 return "fstp%z0\t%y0";
4178
4179 default:
4180 abort ();
4181 }
4182}
4183 [(set_attr "type" "fmov")
4184 (set_attr "mode" "SF,XF")])
4185
4186(define_expand "extenddfxf2"
4187 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4188 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
4189 "!TARGET_64BIT && TARGET_80387"
4190{
4191 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4192 operands[1] = force_reg (DFmode, operands[1]);
4193})
4194
4195(define_insn "*extenddfxf2_1"
4196 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4197 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4198 "!TARGET_64BIT && TARGET_80387
4199 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4200{
4201 switch (which_alternative)
4202 {
4203 case 0:
4204 if (REG_P (operands[1])
4205 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4206 return "fstp\t%y0";
4207 else if (STACK_TOP_P (operands[0]))
4208 return "fld%z1\t%y1";
4209 else
4210 return "fst\t%y0";
4211
4212 case 1:
4213 /* There is no non-popping store to memory for XFmode. So if
4214 we need one, follow the store with a load. */
4215 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4216 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4217 else
4218 return "fstp%z0\t%y0";
4219
4220 default:
4221 abort ();
4222 }
4223}
4224 [(set_attr "type" "fmov")
4225 (set_attr "mode" "DF,XF")])
4226
4227(define_expand "extenddftf2"
4228 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4229 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
4230 "TARGET_80387"
4231{
4232 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4233 operands[1] = force_reg (DFmode, operands[1]);
4234})
4235
4236(define_insn "*extenddftf2_1"
4237 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4238 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4239 "TARGET_80387
4240 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4241{
4242 switch (which_alternative)
4243 {
4244 case 0:
4245 if (REG_P (operands[1])
4246 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4247 return "fstp\t%y0";
4248 else if (STACK_TOP_P (operands[0]))
4249 return "fld%z1\t%y1";
4250 else
4251 return "fst\t%y0";
4252
4253 case 1:
4254 /* There is no non-popping store to memory for XFmode. So if
4255 we need one, follow the store with a load. */
4256 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4257 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4258 else
4259 return "fstp%z0\t%y0";
4260
4261 default:
4262 abort ();
4263 }
4264}
4265 [(set_attr "type" "fmov")
4266 (set_attr "mode" "DF,XF")])
4267
4268;; %%% This seems bad bad news.
4269;; This cannot output into an f-reg because there is no way to be sure
4270;; of truncating in that case. Otherwise this is just like a simple move
4271;; insn. So we pretend we can output to a reg in order to get better
4272;; register preferencing, but we really use a stack slot.
4273
4274(define_expand "truncdfsf2"
4275 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4276 (float_truncate:SF
4277 (match_operand:DF 1 "register_operand" "")))
4278 (clobber (match_dup 2))])]
4279 "TARGET_80387 || TARGET_SSE2"
4280 "
4281 if (TARGET_80387)
4282 operands[2] = assign_386_stack_local (SFmode, 0);
4283 else
4284 {
4285 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4286 DONE;
4287 }
4288")
4289
4290(define_insn "*truncdfsf2_1"
4291 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4292 (float_truncate:SF
4293 (match_operand:DF 1 "register_operand" "f,f,f,f")))
4294 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4295 "TARGET_80387 && !TARGET_SSE2"
4296{
4297 switch (which_alternative)
4298 {
4299 case 0:
4300 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4301 return "fstp%z0\t%y0";
4302 else
4303 return "fst%z0\t%y0";
4304 default:
4305 abort ();
4306 }
4307}
4308 [(set_attr "type" "fmov,multi,multi,multi")
4309 (set_attr "mode" "SF,SF,SF,SF")])
4310
4311(define_insn "*truncdfsf2_1_sse"
4312 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
4313 (float_truncate:SF
4314 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
4315 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
4316 "TARGET_80387 && TARGET_SSE2"
4317{
4318 switch (which_alternative)
4319 {
4320 case 0:
4321 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4322 return "fstp%z0\t%y0";
4323 else
4324 return "fst%z0\t%y0";
4325 case 4:
4326 return "cvtsd2ss\t{%1, %0|%0, %1}";
4327 default:
4328 abort ();
4329 }
4330}
4331 [(set_attr "type" "fmov,multi,multi,multi,sse")
4332 (set_attr "mode" "SF,SF,SF,SF,DF")])
4333
4334(define_insn "*truncdfsf2_2"
4335 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
4336 (float_truncate:SF
4337 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4338 "TARGET_80387 && TARGET_SSE2
4339 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4340{
4341 switch (which_alternative)
4342 {
4343 case 0:
4344 return "cvtsd2ss\t{%1, %0|%0, %1}";
4345 case 1:
4346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4347 return "fstp%z0\t%y0";
4348 else
4349 return "fst%z0\t%y0";
4350 default:
4351 abort ();
4352 }
4353}
4354 [(set_attr "type" "sse,fmov")
4355 (set_attr "mode" "DF,SF")])
4356
4357(define_insn "truncdfsf2_3"
4358 [(set (match_operand:SF 0 "memory_operand" "=m")
4359 (float_truncate:SF
4360 (match_operand:DF 1 "register_operand" "f")))]
4361 "TARGET_80387"
4362{
4363 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4364 return "fstp%z0\t%y0";
4365 else
4366 return "fst%z0\t%y0";
4367}
4368 [(set_attr "type" "fmov")
4369 (set_attr "mode" "SF")])
4370
4371(define_insn "truncdfsf2_sse_only"
4372 [(set (match_operand:SF 0 "register_operand" "=Y")
4373 (float_truncate:SF
4374 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4375 "!TARGET_80387 && TARGET_SSE2"
4376 "cvtsd2ss\t{%1, %0|%0, %1}"
4377 [(set_attr "type" "sse")
4378 (set_attr "mode" "DF")])
4379
4380(define_split
4381 [(set (match_operand:SF 0 "memory_operand" "")
4382 (float_truncate:SF
4383 (match_operand:DF 1 "register_operand" "")))
4384 (clobber (match_operand:SF 2 "memory_operand" ""))]
4385 "TARGET_80387"
4386 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4387 "")
4388
4389(define_split
4390 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4391 (float_truncate:SF
4392 (match_operand:DF 1 "nonimmediate_operand" "")))
4393 (clobber (match_operand 2 "" ""))]
4394 "TARGET_80387 && reload_completed
4395 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
4396 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4397 "")
4398
4399(define_split
4400 [(set (match_operand:SF 0 "register_operand" "")
4401 (float_truncate:SF
4402 (match_operand:DF 1 "register_operand" "")))
4403 (clobber (match_operand:SF 2 "memory_operand" ""))]
4404 "TARGET_80387 && reload_completed
4405 && FP_REG_P (operands[1])"
4406 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4407 (set (match_dup 0) (match_dup 2))]
4408 "")
4409
4410(define_expand "truncxfsf2"
4411 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4412 (float_truncate:SF
4413 (match_operand:XF 1 "register_operand" "")))
4414 (clobber (match_dup 2))])]
4415 "!TARGET_64BIT && TARGET_80387"
4416 "operands[2] = assign_386_stack_local (SFmode, 0);")
4417
4418(define_insn "*truncxfsf2_1"
4419 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4420 (float_truncate:SF
4421 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4422 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4423 "!TARGET_64BIT && TARGET_80387"
4424{
4425 switch (which_alternative)
4426 {
4427 case 0:
4428 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4429 return "fstp%z0\t%y0";
4430 else
4431 return "fst%z0\t%y0";
4432 default:
4433 abort();
4434 }
4435}
4436 [(set_attr "type" "fmov,multi,multi,multi")
4437 (set_attr "mode" "SF")])
4438
4439(define_insn "*truncxfsf2_2"
4440 [(set (match_operand:SF 0 "memory_operand" "=m")
4441 (float_truncate:SF
4442 (match_operand:XF 1 "register_operand" "f")))]
4443 "!TARGET_64BIT && TARGET_80387"
4444{
4445 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4446 return "fstp%z0\t%y0";
4447 else
4448 return "fst%z0\t%y0";
4449}
4450 [(set_attr "type" "fmov")
4451 (set_attr "mode" "SF")])
4452
4453(define_split
4454 [(set (match_operand:SF 0 "memory_operand" "")
4455 (float_truncate:SF
4456 (match_operand:XF 1 "register_operand" "")))
4457 (clobber (match_operand:SF 2 "memory_operand" ""))]
4458 "TARGET_80387"
4459 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4460 "")
4461
4462(define_split
4463 [(set (match_operand:SF 0 "register_operand" "")
4464 (float_truncate:SF
4465 (match_operand:XF 1 "register_operand" "")))
4466 (clobber (match_operand:SF 2 "memory_operand" ""))]
4467 "TARGET_80387 && reload_completed"
4468 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4469 (set (match_dup 0) (match_dup 2))]
4470 "")
4471
4472(define_expand "trunctfsf2"
4473 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4474 (float_truncate:SF
4475 (match_operand:TF 1 "register_operand" "")))
4476 (clobber (match_dup 2))])]
4477 "TARGET_80387"
4478 "operands[2] = assign_386_stack_local (SFmode, 0);")
4479
4480(define_insn "*trunctfsf2_1"
4481 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4482 (float_truncate:SF
4483 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4484 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4485 "TARGET_80387"
4486{
4487 switch (which_alternative)
4488 {
4489 case 0:
4490 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4491 return "fstp%z0\t%y0";
4492 else
4493 return "fst%z0\t%y0";
4494 default:
4495 abort();
4496 }
4497}
4498 [(set_attr "type" "fmov,multi,multi,multi")
4499 (set_attr "mode" "SF")])
4500
4501(define_insn "*trunctfsf2_2"
4502 [(set (match_operand:SF 0 "memory_operand" "=m")
4503 (float_truncate:SF
4504 (match_operand:TF 1 "register_operand" "f")))]
4505 "TARGET_80387"
4506{
4507 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4508 return "fstp%z0\t%y0";
4509 else
4510 return "fst%z0\t%y0";
4511}
4512 [(set_attr "type" "fmov")
4513 (set_attr "mode" "SF")])
4514
4515(define_split
4516 [(set (match_operand:SF 0 "memory_operand" "")
4517 (float_truncate:SF
4518 (match_operand:TF 1 "register_operand" "")))
4519 (clobber (match_operand:SF 2 "memory_operand" ""))]
4520 "TARGET_80387"
4521 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4522 "")
4523
4524(define_split
4525 [(set (match_operand:SF 0 "register_operand" "")
4526 (float_truncate:SF
4527 (match_operand:TF 1 "register_operand" "")))
4528 (clobber (match_operand:SF 2 "memory_operand" ""))]
4529 "TARGET_80387 && reload_completed"
4530 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4531 (set (match_dup 0) (match_dup 2))]
4532 "")
4533
4534
4535(define_expand "truncxfdf2"
4536 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4537 (float_truncate:DF
4538 (match_operand:XF 1 "register_operand" "")))
4539 (clobber (match_dup 2))])]
4540 "!TARGET_64BIT && TARGET_80387"
4541 "operands[2] = assign_386_stack_local (DFmode, 0);")
4542
4543(define_insn "*truncxfdf2_1"
4544 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4545 (float_truncate:DF
4546 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4547 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4548 "!TARGET_64BIT && TARGET_80387"
4549{
4550 switch (which_alternative)
4551 {
4552 case 0:
4553 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4554 return "fstp%z0\t%y0";
4555 else
4556 return "fst%z0\t%y0";
4557 default:
4558 abort();
4559 }
4560 abort ();
4561}
4562 [(set_attr "type" "fmov,multi,multi,multi")
4563 (set_attr "mode" "DF")])
4564
4565(define_insn "*truncxfdf2_2"
4566 [(set (match_operand:DF 0 "memory_operand" "=m")
4567 (float_truncate:DF
4568 (match_operand:XF 1 "register_operand" "f")))]
4569 "!TARGET_64BIT && TARGET_80387"
4570{
4571 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4572 return "fstp%z0\t%y0";
4573 else
4574 return "fst%z0\t%y0";
4575}
4576 [(set_attr "type" "fmov")
4577 (set_attr "mode" "DF")])
4578
4579(define_split
4580 [(set (match_operand:DF 0 "memory_operand" "")
4581 (float_truncate:DF
4582 (match_operand:XF 1 "register_operand" "")))
4583 (clobber (match_operand:DF 2 "memory_operand" ""))]
4584 "TARGET_80387"
4585 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4586 "")
4587
4588(define_split
4589 [(set (match_operand:DF 0 "register_operand" "")
4590 (float_truncate:DF
4591 (match_operand:XF 1 "register_operand" "")))
4592 (clobber (match_operand:DF 2 "memory_operand" ""))]
4593 "TARGET_80387 && reload_completed"
4594 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4595 (set (match_dup 0) (match_dup 2))]
4596 "")
4597
4598(define_expand "trunctfdf2"
4599 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4600 (float_truncate:DF
4601 (match_operand:TF 1 "register_operand" "")))
4602 (clobber (match_dup 2))])]
4603 "TARGET_80387"
4604 "operands[2] = assign_386_stack_local (DFmode, 0);")
4605
4606(define_insn "*trunctfdf2_1"
4607 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4608 (float_truncate:DF
4609 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4610 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4611 "TARGET_80387"
4612{
4613 switch (which_alternative)
4614 {
4615 case 0:
4616 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4617 return "fstp%z0\t%y0";
4618 else
4619 return "fst%z0\t%y0";
4620 default:
4621 abort();
4622 }
4623 abort ();
4624}
4625 [(set_attr "type" "fmov,multi,multi,multi")
4626 (set_attr "mode" "DF")])
4627
4628 (define_insn "*trunctfdf2_2"
4629 [(set (match_operand:DF 0 "memory_operand" "=m")
4630 (float_truncate:DF
4631 (match_operand:TF 1 "register_operand" "f")))]
4632 "TARGET_80387"
4633{
4634 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4635 return "fstp%z0\t%y0";
4636 else
4637 return "fst%z0\t%y0";
4638}
4639 [(set_attr "type" "fmov")
4640 (set_attr "mode" "DF")])
4641
4642(define_split
4643 [(set (match_operand:DF 0 "memory_operand" "")
4644 (float_truncate:DF
4645 (match_operand:TF 1 "register_operand" "")))
4646 (clobber (match_operand:DF 2 "memory_operand" ""))]
4647 "TARGET_80387"
4648 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4649 "")
4650
4651(define_split
4652 [(set (match_operand:DF 0 "register_operand" "")
4653 (float_truncate:DF
4654 (match_operand:TF 1 "register_operand" "")))
4655 (clobber (match_operand:DF 2 "memory_operand" ""))]
4656 "TARGET_80387 && reload_completed"
4657 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4658 (set (match_dup 0) (match_dup 2))]
4659 "")
4660
4661
4662;; %%% Break up all these bad boys.
4663
4664;; Signed conversion to DImode.
4665
4666(define_expand "fix_truncxfdi2"
4667 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4668 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4669 "!TARGET_64BIT && TARGET_80387"
4670 "")
4671
4672(define_expand "fix_trunctfdi2"
4673 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4674 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4675 "TARGET_80387"
4676 "")
4677
4678(define_expand "fix_truncdfdi2"
4679 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4680 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4681 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4682{
4683 if (TARGET_64BIT && TARGET_SSE2)
4684 {
4685 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4686 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4687 if (out != operands[0])
4688 emit_move_insn (operands[0], out);
4689 DONE;
4690 }
4691})
4692
4693(define_expand "fix_truncsfdi2"
4694 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4695 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4696 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4697{
4698 if (TARGET_SSE && TARGET_64BIT)
4699 {
4700 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4701 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4702 if (out != operands[0])
4703 emit_move_insn (operands[0], out);
4704 DONE;
4705 }
4706})
4707
4708;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4709;; of the machinery.
4710(define_insn_and_split "*fix_truncdi_1"
4711 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4712 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4713 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4714 && !reload_completed && !reload_in_progress
4715 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4716 "#"
4717 "&& 1"
4718 [(const_int 0)]
4719{
4720 operands[2] = assign_386_stack_local (HImode, 1);
4721 operands[3] = assign_386_stack_local (HImode, 2);
4722 if (memory_operand (operands[0], VOIDmode))
4723 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4724 operands[2], operands[3]));
4725 else
4726 {
4727 operands[4] = assign_386_stack_local (DImode, 0);
4728 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4729 operands[2], operands[3],
4730 operands[4]));
4731 }
4732 DONE;
4733}
4734 [(set_attr "type" "fistp")])
4735
4736(define_insn "fix_truncdi_nomemory"
4737 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4738 (fix:DI (match_operand 1 "register_operand" "f,f")))
4739 (use (match_operand:HI 2 "memory_operand" "m,m"))
4740 (use (match_operand:HI 3 "memory_operand" "m,m"))
4741 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4742 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4743 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4744 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4745 "#"
4746 [(set_attr "type" "fistp")])
4747
4748(define_insn "fix_truncdi_memory"
4749 [(set (match_operand:DI 0 "memory_operand" "=m")
4750 (fix:DI (match_operand 1 "register_operand" "f")))
4751 (use (match_operand:HI 2 "memory_operand" "m"))
4752 (use (match_operand:HI 3 "memory_operand" "m"))
4753 (clobber (match_scratch:DF 4 "=&1f"))]
4754 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4755 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4756 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4757 [(set_attr "type" "fistp")])
4758
4759(define_split
4760 [(set (match_operand:DI 0 "register_operand" "")
4761 (fix:DI (match_operand 1 "register_operand" "")))
4762 (use (match_operand:HI 2 "memory_operand" ""))
4763 (use (match_operand:HI 3 "memory_operand" ""))
4764 (clobber (match_operand:DI 4 "memory_operand" ""))
4765 (clobber (match_scratch 5 ""))]
4766 "reload_completed"
4767 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4768 (use (match_dup 2))
4769 (use (match_dup 3))
4770 (clobber (match_dup 5))])
4771 (set (match_dup 0) (match_dup 4))]
4772 "")
4773
4774(define_split
4775 [(set (match_operand:DI 0 "memory_operand" "")
4776 (fix:DI (match_operand 1 "register_operand" "")))
4777 (use (match_operand:HI 2 "memory_operand" ""))
4778 (use (match_operand:HI 3 "memory_operand" ""))
4779 (clobber (match_operand:DI 4 "memory_operand" ""))
4780 (clobber (match_scratch 5 ""))]
4781 "reload_completed"
4782 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4783 (use (match_dup 2))
4784 (use (match_dup 3))
4785 (clobber (match_dup 5))])]
4786 "")
4787
4788;; When SSE available, it is always faster to use it!
4789(define_insn "fix_truncsfdi_sse"
4790 [(set (match_operand:DI 0 "register_operand" "=r")
4791 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4792 "TARGET_64BIT && TARGET_SSE"
4793 "cvttss2si{q}\t{%1, %0|%0, %1}"
4794 [(set_attr "type" "sse")])
4795
4796(define_insn "fix_truncdfdi_sse"
4797 [(set (match_operand:DI 0 "register_operand" "=r")
4798 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4799 "TARGET_64BIT && TARGET_SSE2"
4800 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4801 [(set_attr "type" "sse")])
4802
4803;; Signed conversion to SImode.
4804
4805(define_expand "fix_truncxfsi2"
4806 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4807 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4808 "!TARGET_64BIT && TARGET_80387"
4809 "")
4810
4811(define_expand "fix_trunctfsi2"
4812 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4813 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4814 "TARGET_80387"
4815 "")
4816
4817(define_expand "fix_truncdfsi2"
4818 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4819 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4820 "TARGET_80387 || TARGET_SSE2"
4821{
4822 if (TARGET_SSE2)
4823 {
4824 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4825 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4826 if (out != operands[0])
4827 emit_move_insn (operands[0], out);
4828 DONE;
4829 }
4830})
4831
4832(define_expand "fix_truncsfsi2"
4833 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4834 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4835 "TARGET_80387 || TARGET_SSE"
4836{
4837 if (TARGET_SSE)
4838 {
4839 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4840 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4841 if (out != operands[0])
4842 emit_move_insn (operands[0], out);
4843 DONE;
4844 }
4845})
4846
4847;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4848;; of the machinery.
4849(define_insn_and_split "*fix_truncsi_1"
4850 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4851 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4852 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4853 && !reload_completed && !reload_in_progress
4854 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4855 "#"
4856 "&& 1"
4857 [(const_int 0)]
4858{
4859 operands[2] = assign_386_stack_local (HImode, 1);
4860 operands[3] = assign_386_stack_local (HImode, 2);
4861 if (memory_operand (operands[0], VOIDmode))
4862 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4863 operands[2], operands[3]));
4864 else
4865 {
4866 operands[4] = assign_386_stack_local (SImode, 0);
4867 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4868 operands[2], operands[3],
4869 operands[4]));
4870 }
4871 DONE;
4872}
4873 [(set_attr "type" "fistp")])
4874
4875(define_insn "fix_truncsi_nomemory"
4876 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4877 (fix:SI (match_operand 1 "register_operand" "f,f")))
4878 (use (match_operand:HI 2 "memory_operand" "m,m"))
4879 (use (match_operand:HI 3 "memory_operand" "m,m"))
4880 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4881 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4882 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4883 "#"
4884 [(set_attr "type" "fistp")])
4885
4886(define_insn "fix_truncsi_memory"
4887 [(set (match_operand:SI 0 "memory_operand" "=m")
4888 (fix:SI (match_operand 1 "register_operand" "f")))
4889 (use (match_operand:HI 2 "memory_operand" "m"))
4890 (use (match_operand:HI 3 "memory_operand" "m"))]
4891 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4892 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4893 "* return output_fix_trunc (insn, operands);"
4894 [(set_attr "type" "fistp")])
4895
4896;; When SSE available, it is always faster to use it!
4897(define_insn "fix_truncsfsi_sse"
4898 [(set (match_operand:SI 0 "register_operand" "=r")
4899 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4900 "TARGET_SSE"
4901 "cvttss2si\t{%1, %0|%0, %1}"
4902 [(set_attr "type" "sse")])
4903
4904(define_insn "fix_truncdfsi_sse"
4905 [(set (match_operand:SI 0 "register_operand" "=r")
4906 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4907 "TARGET_SSE2"
4908 "cvttsd2si\t{%1, %0|%0, %1}"
4909 [(set_attr "type" "sse")])
4910
4911(define_split
4912 [(set (match_operand:SI 0 "register_operand" "")
4913 (fix:SI (match_operand 1 "register_operand" "")))
4914 (use (match_operand:HI 2 "memory_operand" ""))
4915 (use (match_operand:HI 3 "memory_operand" ""))
4916 (clobber (match_operand:SI 4 "memory_operand" ""))]
4917 "reload_completed"
4918 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4919 (use (match_dup 2))
4920 (use (match_dup 3))])
4921 (set (match_dup 0) (match_dup 4))]
4922 "")
4923
4924(define_split
4925 [(set (match_operand:SI 0 "memory_operand" "")
4926 (fix:SI (match_operand 1 "register_operand" "")))
4927 (use (match_operand:HI 2 "memory_operand" ""))
4928 (use (match_operand:HI 3 "memory_operand" ""))
4929 (clobber (match_operand:SI 4 "memory_operand" ""))]
4930 "reload_completed"
4931 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4932 (use (match_dup 2))
4933 (use (match_dup 3))])]
4934 "")
4935
4936;; Signed conversion to HImode.
4937
4938(define_expand "fix_truncxfhi2"
4939 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4940 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4941 "!TARGET_64BIT && TARGET_80387"
4942 "")
4943
4944(define_expand "fix_trunctfhi2"
4945 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4946 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4947 "TARGET_80387"
4948 "")
4949
4950(define_expand "fix_truncdfhi2"
4951 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4952 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4953 "TARGET_80387 && !TARGET_SSE2"
4954 "")
4955
4956(define_expand "fix_truncsfhi2"
4957 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4958 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4959 "TARGET_80387 && !TARGET_SSE"
4960 "")
4961
4962;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4963;; of the machinery.
4964(define_insn_and_split "*fix_trunchi_1"
4965 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4966 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4967 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4968 && !reload_completed && !reload_in_progress
4969 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4970 "#"
4971 ""
4972 [(const_int 0)]
4973{
4974 operands[2] = assign_386_stack_local (HImode, 1);
4975 operands[3] = assign_386_stack_local (HImode, 2);
4976 if (memory_operand (operands[0], VOIDmode))
4977 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4978 operands[2], operands[3]));
4979 else
4980 {
4981 operands[4] = assign_386_stack_local (HImode, 0);
4982 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4983 operands[2], operands[3],
4984 operands[4]));
4985 }
4986 DONE;
4987}
4988 [(set_attr "type" "fistp")])
4989
4990(define_insn "fix_trunchi_nomemory"
4991 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4992 (fix:HI (match_operand 1 "register_operand" "f,f")))
4993 (use (match_operand:HI 2 "memory_operand" "m,m"))
4994 (use (match_operand:HI 3 "memory_operand" "m,m"))
4995 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4996 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4997 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4998 "#"
4999 [(set_attr "type" "fistp")])
5000
5001(define_insn "fix_trunchi_memory"
5002 [(set (match_operand:HI 0 "memory_operand" "=m")
5003 (fix:HI (match_operand 1 "register_operand" "f")))
5004 (use (match_operand:HI 2 "memory_operand" "m"))
5005 (use (match_operand:HI 3 "memory_operand" "m"))]
5006 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
5007 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5008 "* return output_fix_trunc (insn, operands);"
5009 [(set_attr "type" "fistp")])
5010
5011(define_split
5012 [(set (match_operand:HI 0 "memory_operand" "")
5013 (fix:HI (match_operand 1 "register_operand" "")))
5014 (use (match_operand:HI 2 "memory_operand" ""))
5015 (use (match_operand:HI 3 "memory_operand" ""))
5016 (clobber (match_operand:HI 4 "memory_operand" ""))]
5017 "reload_completed"
5018 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
5019 (use (match_dup 2))
5020 (use (match_dup 3))])]
5021 "")
5022
5023(define_split
5024 [(set (match_operand:HI 0 "register_operand" "")
5025 (fix:HI (match_operand 1 "register_operand" "")))
5026 (use (match_operand:HI 2 "memory_operand" ""))
5027 (use (match_operand:HI 3 "memory_operand" ""))
5028 (clobber (match_operand:HI 4 "memory_operand" ""))]
5029 "reload_completed"
5030 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
5031 (use (match_dup 2))
5032 (use (match_dup 3))
5033 (clobber (match_dup 4))])
5034 (set (match_dup 0) (match_dup 4))]
5035 "")
5036
5037;; %% Not used yet.
5038(define_insn "x86_fnstcw_1"
5039 [(set (match_operand:HI 0 "memory_operand" "=m")
5040 (unspec:HI [(reg:HI 18)] 11))]
5041 "TARGET_80387"
5042 "fnstcw\t%0"
5043 [(set_attr "length" "2")
5044 (set_attr "mode" "HI")
5045 (set_attr "i387" "1")
5046 (set_attr "ppro_uops" "few")])
5047
5048(define_insn "x86_fldcw_1"
5049 [(set (reg:HI 18)
5050 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
5051 "TARGET_80387"
5052 "fldcw\t%0"
5053 [(set_attr "length" "2")
5054 (set_attr "mode" "HI")
5055 (set_attr "i387" "1")
5056 (set_attr "athlon_decode" "vector")
5057 (set_attr "ppro_uops" "few")])
5058
5059;; Conversion between fixed point and floating point.
5060
5061;; Even though we only accept memory inputs, the backend _really_
5062;; wants to be able to do this between registers.
5063
5064(define_insn "floathisf2"
5065 [(set (match_operand:SF 0 "register_operand" "=f,f")
5066 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5067 "TARGET_80387 && !TARGET_SSE"
5068 "@
5069 fild%z1\t%1
5070 #"
5071 [(set_attr "type" "fmov,multi")
5072 (set_attr "mode" "SF")
5073 (set_attr "fp_int_src" "true")])
5074
5075(define_expand "floatsisf2"
5076 [(set (match_operand:SF 0 "register_operand" "")
5077 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5078 "TARGET_SSE || TARGET_80387"
5079 "")
5080
5081(define_insn "*floatsisf2_i387"
5082 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5083 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5084 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5085 "@
5086 fild%z1\t%1
5087 #
5088 cvtsi2ss\t{%1, %0|%0, %1}"
5089 [(set_attr "type" "fmov,multi,sse")
5090 (set_attr "mode" "SF")
5091 (set_attr "fp_int_src" "true")])
5092
5093(define_insn "*floatsisf2_sse"
5094 [(set (match_operand:SF 0 "register_operand" "=x")
5095 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5096 "TARGET_SSE"
5097 "cvtsi2ss\t{%1, %0|%0, %1}"
5098 [(set_attr "type" "sse")
5099 (set_attr "mode" "SF")
5100 (set_attr "fp_int_src" "true")])
5101
5102(define_expand "floatdisf2"
5103 [(set (match_operand:SF 0 "register_operand" "")
5104 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5105 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
5106 "")
5107
5108(define_insn "*floatdisf2_i387_only"
5109 [(set (match_operand:SF 0 "register_operand" "=f,?f")
5110 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5111 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
5112 "@
5113 fild%z1\t%1
5114 #"
5115 [(set_attr "type" "fmov,multi")
5116 (set_attr "mode" "SF")
5117 (set_attr "fp_int_src" "true")])
5118
5119(define_insn "*floatdisf2_i387"
5120 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5121 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5122 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5123 "@
5124 fild%z1\t%1
5125 #
5126 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5127 [(set_attr "type" "fmov,multi,sse")
5128 (set_attr "mode" "SF")
5129 (set_attr "fp_int_src" "true")])
5130
5131(define_insn "*floatdisf2_sse"
5132 [(set (match_operand:SF 0 "register_operand" "=x")
5133 (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5134 "TARGET_64BIT && TARGET_SSE"
5135 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5136 [(set_attr "type" "sse")
5137 (set_attr "mode" "SF")
5138 (set_attr "fp_int_src" "true")])
5139
5140(define_insn "floathidf2"
5141 [(set (match_operand:DF 0 "register_operand" "=f,f")
5142 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5143 "TARGET_80387 && !TARGET_SSE2"
5144 "@
5145 fild%z1\t%1
5146 #"
5147 [(set_attr "type" "fmov,multi")
5148 (set_attr "mode" "DF")
5149 (set_attr "fp_int_src" "true")])
5150
5151(define_expand "floatsidf2"
5152 [(set (match_operand:DF 0 "register_operand" "")
5153 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5132 ""
5154 "TARGET_80387 || TARGET_SSE2"
5133 "")
5134
5135(define_insn "*floatsidf2_i387"
5136 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5137 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5138 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5139 "@
5140 fild%z1\t%1
5141 #
5142 cvtsi2sd\t{%1, %0|%0, %1}"
5143 [(set_attr "type" "fmov,multi,sse")
5144 (set_attr "mode" "DF")
5145 (set_attr "fp_int_src" "true")])
5146
5147(define_insn "*floatsidf2_sse"
5148 [(set (match_operand:DF 0 "register_operand" "=Y")
5149 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5150 "TARGET_SSE2"
5151 "cvtsi2sd\t{%1, %0|%0, %1}"
5152 [(set_attr "type" "sse")
5153 (set_attr "mode" "DF")
5154 (set_attr "fp_int_src" "true")])
5155
5156(define_expand "floatdidf2"
5157 [(set (match_operand:DF 0 "register_operand" "")
5158 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5159 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5160 "")
5161
5162(define_insn "*floatdidf2_i387_only"
5163 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5164 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5165 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5166 "@
5167 fild%z1\t%1
5168 #"
5169 [(set_attr "type" "fmov,multi")
5170 (set_attr "mode" "DF")
5171 (set_attr "fp_int_src" "true")])
5172
5173(define_insn "*floatdidf2_i387"
5174 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5175 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5176 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5177 "@
5178 fild%z1\t%1
5179 #
5180 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5181 [(set_attr "type" "fmov,multi,sse")
5182 (set_attr "mode" "DF")
5183 (set_attr "fp_int_src" "true")])
5184
5185(define_insn "*floatdidf2_sse"
5186 [(set (match_operand:DF 0 "register_operand" "=Y")
5187 (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5188 "TARGET_SSE2"
5189 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5190 [(set_attr "type" "sse")
5191 (set_attr "mode" "DF")
5192 (set_attr "fp_int_src" "true")])
5193
5194(define_insn "floathixf2"
5195 [(set (match_operand:XF 0 "register_operand" "=f,f")
5196 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5197 "!TARGET_64BIT && TARGET_80387"
5198 "@
5199 fild%z1\t%1
5200 #"
5201 [(set_attr "type" "fmov,multi")
5202 (set_attr "mode" "XF")
5203 (set_attr "fp_int_src" "true")])
5204
5205(define_insn "floathitf2"
5206 [(set (match_operand:TF 0 "register_operand" "=f,f")
5207 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5208 "TARGET_80387"
5209 "@
5210 fild%z1\t%1
5211 #"
5212 [(set_attr "type" "fmov,multi")
5213 (set_attr "mode" "XF")
5214 (set_attr "fp_int_src" "true")])
5215
5216(define_insn "floatsixf2"
5217 [(set (match_operand:XF 0 "register_operand" "=f,f")
5218 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5219 "!TARGET_64BIT && TARGET_80387"
5220 "@
5221 fild%z1\t%1
5222 #"
5223 [(set_attr "type" "fmov,multi")
5224 (set_attr "mode" "XF")
5225 (set_attr "fp_int_src" "true")])
5226
5227(define_insn "floatsitf2"
5228 [(set (match_operand:TF 0 "register_operand" "=f,f")
5229 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5230 "TARGET_80387"
5231 "@
5232 fild%z1\t%1
5233 #"
5234 [(set_attr "type" "fmov,multi")
5235 (set_attr "mode" "XF")
5236 (set_attr "fp_int_src" "true")])
5237
5238(define_insn "floatdixf2"
5239 [(set (match_operand:XF 0 "register_operand" "=f,f")
5240 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5241 "!TARGET_64BIT && TARGET_80387"
5242 "@
5243 fild%z1\t%1
5244 #"
5245 [(set_attr "type" "fmov,multi")
5246 (set_attr "mode" "XF")
5247 (set_attr "fp_int_src" "true")])
5248
5249(define_insn "floatditf2"
5250 [(set (match_operand:TF 0 "register_operand" "=f,f")
5251 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5252 "TARGET_80387"
5253 "@
5254 fild%z1\t%1
5255 #"
5256 [(set_attr "type" "fmov,multi")
5257 (set_attr "mode" "XF")
5258 (set_attr "fp_int_src" "true")])
5259
5260;; %%% Kill these when reload knows how to do it.
5261(define_split
5262 [(set (match_operand 0 "register_operand" "")
5263 (float (match_operand 1 "register_operand" "")))]
5264 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
5265 && FP_REG_P (operands[0])"
5266 [(const_int 0)]
5267{
5268 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5269 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5270 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5271 ix86_free_from_memory (GET_MODE (operands[1]));
5272 DONE;
5273})
5274
5275;; Add instructions
5276
5277;; %%% splits for addsidi3
5278; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5279; (plus:DI (match_operand:DI 1 "general_operand" "")
5280; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5281
5282(define_expand "adddi3"
5283 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5284 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5285 (match_operand:DI 2 "x86_64_general_operand" "")))
5286 (clobber (reg:CC 17))]
5287 ""
5288 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5289
5290(define_insn "*adddi3_1"
5291 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5292 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5293 (match_operand:DI 2 "general_operand" "roiF,riF")))
5294 (clobber (reg:CC 17))]
5295 "!TARGET_64BIT"
5296 "#")
5297
5298(define_split
5299 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5300 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5301 (match_operand:DI 2 "general_operand" "")))
5302 (clobber (reg:CC 17))]
5303 "!TARGET_64BIT && reload_completed"
5304 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
5305 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5306 (parallel [(set (match_dup 3)
5307 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5308 (match_dup 4))
5309 (match_dup 5)))
5310 (clobber (reg:CC 17))])]
5311 "split_di (operands+0, 1, operands+0, operands+3);
5312 split_di (operands+1, 1, operands+1, operands+4);
5313 split_di (operands+2, 1, operands+2, operands+5);")
5314
5315(define_insn "*adddi3_carry_rex64"
5316 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5317 (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
5318 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5319 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5320 (clobber (reg:CC 17))]
5321 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5322 "adc{q}\t{%2, %0|%0, %2}"
5323 [(set_attr "type" "alu")
5324 (set_attr "pent_pair" "pu")
5325 (set_attr "mode" "DI")
5326 (set_attr "ppro_uops" "few")])
5327
5328(define_insn "*adddi3_cc_rex64"
5329 [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5330 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
5331 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5332 (plus:DI (match_dup 1) (match_dup 2)))]
5333 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5334 "add{q}\t{%2, %0|%0, %2}"
5335 [(set_attr "type" "alu")
5336 (set_attr "mode" "DI")])
5337
5338(define_insn "*addsi3_carry"
5339 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5340 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5341 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5342 (match_operand:SI 2 "general_operand" "ri,rm")))
5343 (clobber (reg:CC 17))]
5344 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5345 "adc{l}\t{%2, %0|%0, %2}"
5346 [(set_attr "type" "alu")
5347 (set_attr "pent_pair" "pu")
5348 (set_attr "mode" "SI")
5349 (set_attr "ppro_uops" "few")])
5350
5351(define_insn "*addsi3_carry_zext"
5352 [(set (match_operand:DI 0 "register_operand" "=r")
5353 (zero_extend:DI
5354 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5355 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5356 (match_operand:SI 2 "general_operand" "rim"))))
5357 (clobber (reg:CC 17))]
5358 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5359 "adc{l}\t{%2, %k0|%k0, %2}"
5360 [(set_attr "type" "alu")
5361 (set_attr "pent_pair" "pu")
5362 (set_attr "mode" "SI")
5363 (set_attr "ppro_uops" "few")])
5364
5365(define_insn "*addsi3_cc"
5366 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5367 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
5368 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5369 (plus:SI (match_dup 1) (match_dup 2)))]
5370 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5371 "add{l}\t{%2, %0|%0, %2}"
5372 [(set_attr "type" "alu")
5373 (set_attr "mode" "SI")])
5374
5375(define_insn "addqi3_cc"
5376 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5377 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
5378 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5379 (plus:QI (match_dup 1) (match_dup 2)))]
5380 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5381 "add{b}\t{%2, %0|%0, %2}"
5382 [(set_attr "type" "alu")
5383 (set_attr "mode" "QI")])
5384
5385(define_expand "addsi3"
5386 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5387 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5388 (match_operand:SI 2 "general_operand" "")))
5389 (clobber (reg:CC 17))])]
5390 ""
5391 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5392
5393(define_insn "*lea_1"
5394 [(set (match_operand:SI 0 "register_operand" "=r")
5395 (match_operand:SI 1 "address_operand" "p"))]
5396 "!TARGET_64BIT"
5397 "lea{l}\t{%a1, %0|%0, %a1}"
5398 [(set_attr "type" "lea")
5399 (set_attr "mode" "SI")])
5400
5401(define_insn "*lea_1_rex64"
5402 [(set (match_operand:SI 0 "register_operand" "=r")
5403 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5404 "TARGET_64BIT"
5405 "lea{l}\t{%a1, %0|%0, %a1}"
5406 [(set_attr "type" "lea")
5407 (set_attr "mode" "SI")])
5408
5409(define_insn "*lea_1_zext"
5410 [(set (match_operand:DI 0 "register_operand" "=r")
5411 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5412 "TARGET_64BIT"
5413 "lea{l}\t{%a1, %k0|%k0, %a1}"
5414 [(set_attr "type" "lea")
5415 (set_attr "mode" "SI")])
5416
5417(define_insn "*lea_2_rex64"
5418 [(set (match_operand:DI 0 "register_operand" "=r")
5419 (match_operand:DI 1 "address_operand" "p"))]
5420 "TARGET_64BIT"
5421 "lea{q}\t{%a1, %0|%0, %a1}"
5422 [(set_attr "type" "lea")
5423 (set_attr "mode" "DI")])
5424
5425;; The lea patterns for non-Pmodes needs to be matched by several
5426;; insns converted to real lea by splitters.
5427
5428(define_insn_and_split "*lea_general_1"
5429 [(set (match_operand 0 "register_operand" "=r")
5430 (plus (plus (match_operand 1 "register_operand" "r")
5431 (match_operand 2 "register_operand" "r"))
5432 (match_operand 3 "immediate_operand" "i")))]
5433 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5434 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5435 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5436 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5437 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5438 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5439 || GET_MODE (operands[3]) == VOIDmode)"
5440 "#"
5441 "&& reload_completed"
5442 [(const_int 0)]
5443{
5444 rtx pat;
5445 operands[0] = gen_lowpart (SImode, operands[0]);
5446 operands[1] = gen_lowpart (Pmode, operands[1]);
5447 operands[2] = gen_lowpart (Pmode, operands[2]);
5448 operands[3] = gen_lowpart (Pmode, operands[3]);
5449 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5450 operands[3]);
5451 if (Pmode != SImode)
5452 pat = gen_rtx_SUBREG (SImode, pat, 0);
5453 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5454 DONE;
5455}
5456 [(set_attr "type" "lea")
5457 (set_attr "mode" "SI")])
5458
5459(define_insn_and_split "*lea_general_1_zext"
5460 [(set (match_operand:DI 0 "register_operand" "=r")
5461 (zero_extend:DI
5462 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5463 (match_operand:SI 2 "register_operand" "r"))
5464 (match_operand:SI 3 "immediate_operand" "i"))))]
5465 "TARGET_64BIT"
5466 "#"
5467 "&& reload_completed"
5468 [(set (match_dup 0)
5469 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5470 (match_dup 2))
5471 (match_dup 3)) 0)))]
5472{
5473 operands[1] = gen_lowpart (Pmode, operands[1]);
5474 operands[2] = gen_lowpart (Pmode, operands[2]);
5475 operands[3] = gen_lowpart (Pmode, operands[3]);
5476}
5477 [(set_attr "type" "lea")
5478 (set_attr "mode" "SI")])
5479
5480(define_insn_and_split "*lea_general_2"
5481 [(set (match_operand 0 "register_operand" "=r")
5482 (plus (mult (match_operand 1 "register_operand" "r")
5483 (match_operand 2 "const248_operand" "i"))
5484 (match_operand 3 "nonmemory_operand" "ri")))]
5485 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5486 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5487 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5488 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5489 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5490 || GET_MODE (operands[3]) == VOIDmode)"
5491 "#"
5492 "&& reload_completed"
5493 [(const_int 0)]
5494{
5495 rtx pat;
5496 operands[0] = gen_lowpart (SImode, operands[0]);
5497 operands[1] = gen_lowpart (Pmode, operands[1]);
5498 operands[3] = gen_lowpart (Pmode, operands[3]);
5499 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5500 operands[3]);
5501 if (Pmode != SImode)
5502 pat = gen_rtx_SUBREG (SImode, pat, 0);
5503 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5504 DONE;
5505}
5506 [(set_attr "type" "lea")
5507 (set_attr "mode" "SI")])
5508
5509(define_insn_and_split "*lea_general_2_zext"
5510 [(set (match_operand:DI 0 "register_operand" "=r")
5511 (zero_extend:DI
5512 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5513 (match_operand:SI 2 "const248_operand" "n"))
5514 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5515 "TARGET_64BIT"
5516 "#"
5517 "&& reload_completed"
5518 [(set (match_dup 0)
5519 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5520 (match_dup 2))
5521 (match_dup 3)) 0)))]
5522{
5523 operands[1] = gen_lowpart (Pmode, operands[1]);
5524 operands[3] = gen_lowpart (Pmode, operands[3]);
5525}
5526 [(set_attr "type" "lea")
5527 (set_attr "mode" "SI")])
5528
5529(define_insn_and_split "*lea_general_3"
5530 [(set (match_operand 0 "register_operand" "=r")
5531 (plus (plus (mult (match_operand 1 "register_operand" "r")
5532 (match_operand 2 "const248_operand" "i"))
5533 (match_operand 3 "register_operand" "r"))
5534 (match_operand 4 "immediate_operand" "i")))]
5535 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5536 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5537 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5538 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5539 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5540 "#"
5541 "&& reload_completed"
5542 [(const_int 0)]
5543{
5544 rtx pat;
5545 operands[0] = gen_lowpart (SImode, operands[0]);
5546 operands[1] = gen_lowpart (Pmode, operands[1]);
5547 operands[3] = gen_lowpart (Pmode, operands[3]);
5548 operands[4] = gen_lowpart (Pmode, operands[4]);
5549 pat = gen_rtx_PLUS (Pmode,
5550 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5551 operands[2]),
5552 operands[3]),
5553 operands[4]);
5554 if (Pmode != SImode)
5555 pat = gen_rtx_SUBREG (SImode, pat, 0);
5556 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5557 DONE;
5558}
5559 [(set_attr "type" "lea")
5560 (set_attr "mode" "SI")])
5561
5562(define_insn_and_split "*lea_general_3_zext"
5563 [(set (match_operand:DI 0 "register_operand" "=r")
5564 (zero_extend:DI
5565 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5566 (match_operand:SI 2 "const248_operand" "n"))
5567 (match_operand:SI 3 "register_operand" "r"))
5568 (match_operand:SI 4 "immediate_operand" "i"))))]
5569 "TARGET_64BIT"
5570 "#"
5571 "&& reload_completed"
5572 [(set (match_dup 0)
5573 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5574 (match_dup 2))
5575 (match_dup 3))
5576 (match_dup 4)) 0)))]
5577{
5578 operands[1] = gen_lowpart (Pmode, operands[1]);
5579 operands[3] = gen_lowpart (Pmode, operands[3]);
5580 operands[4] = gen_lowpart (Pmode, operands[4]);
5581}
5582 [(set_attr "type" "lea")
5583 (set_attr "mode" "SI")])
5584
5585(define_insn "*adddi_1_rex64"
5586 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5587 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5588 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5589 (clobber (reg:CC 17))]
5590 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5591{
5592 switch (get_attr_type (insn))
5593 {
5594 case TYPE_LEA:
5595 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5596 return "lea{q}\t{%a2, %0|%0, %a2}";
5597
5598 case TYPE_INCDEC:
5599 if (! rtx_equal_p (operands[0], operands[1]))
5600 abort ();
5601 if (operands[2] == const1_rtx)
5602 return "inc{q}\t%0";
5603 else if (operands[2] == constm1_rtx)
5604 return "dec{q}\t%0";
5605 else
5606 abort ();
5607
5608 default:
5609 if (! rtx_equal_p (operands[0], operands[1]))
5610 abort ();
5611
5612 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5613 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5614 if (GET_CODE (operands[2]) == CONST_INT
5615 /* Avoid overflows. */
5616 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5617 && (INTVAL (operands[2]) == 128
5618 || (INTVAL (operands[2]) < 0
5619 && INTVAL (operands[2]) != -128)))
5620 {
5621 operands[2] = GEN_INT (-INTVAL (operands[2]));
5622 return "sub{q}\t{%2, %0|%0, %2}";
5623 }
5624 return "add{q}\t{%2, %0|%0, %2}";
5625 }
5626}
5627 [(set (attr "type")
5628 (cond [(eq_attr "alternative" "2")
5629 (const_string "lea")
5630 ; Current assemblers are broken and do not allow @GOTOFF in
5631 ; ought but a memory context.
5632 (match_operand:DI 2 "pic_symbolic_operand" "")
5633 (const_string "lea")
5634 (match_operand:DI 2 "incdec_operand" "")
5635 (const_string "incdec")
5636 ]
5637 (const_string "alu")))
5638 (set_attr "mode" "DI")])
5639
5640;; Convert lea to the lea pattern to avoid flags dependency.
5641(define_split
5642 [(set (match_operand:DI 0 "register_operand" "")
5643 (plus:DI (match_operand:DI 1 "register_operand" "")
5644 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5645 (clobber (reg:CC 17))]
5646 "TARGET_64BIT && reload_completed
5647 && true_regnum (operands[0]) != true_regnum (operands[1])"
5648 [(set (match_dup 0)
5649 (plus:DI (match_dup 1)
5650 (match_dup 2)))]
5651 "")
5652
5653(define_insn "*adddi_2_rex64"
5654 [(set (reg 17)
5655 (compare
5656 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5657 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5658 (const_int 0)))
5659 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5660 (plus:DI (match_dup 1) (match_dup 2)))]
5661 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5662 && ix86_binary_operator_ok (PLUS, DImode, operands)
5663 /* Current assemblers are broken and do not allow @GOTOFF in
5664 ought but a memory context. */
5665 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5666{
5667 switch (get_attr_type (insn))
5668 {
5669 case TYPE_INCDEC:
5670 if (! rtx_equal_p (operands[0], operands[1]))
5671 abort ();
5672 if (operands[2] == const1_rtx)
5673 return "inc{q}\t%0";
5674 else if (operands[2] == constm1_rtx)
5675 return "dec{q}\t%0";
5676 else
5677 abort ();
5678
5679 default:
5680 if (! rtx_equal_p (operands[0], operands[1]))
5681 abort ();
5682 /* ???? We ought to handle there the 32bit case too
5683 - do we need new constrant? */
5684 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5685 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5686 if (GET_CODE (operands[2]) == CONST_INT
5687 /* Avoid overflows. */
5688 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5689 && (INTVAL (operands[2]) == 128
5690 || (INTVAL (operands[2]) < 0
5691 && INTVAL (operands[2]) != -128)))
5692 {
5693 operands[2] = GEN_INT (-INTVAL (operands[2]));
5694 return "sub{q}\t{%2, %0|%0, %2}";
5695 }
5696 return "add{q}\t{%2, %0|%0, %2}";
5697 }
5698}
5699 [(set (attr "type")
5700 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5701 (const_string "incdec")
5702 (const_string "alu")))
5703 (set_attr "mode" "DI")])
5704
5705(define_insn "*adddi_3_rex64"
5706 [(set (reg 17)
5707 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5708 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5709 (clobber (match_scratch:DI 0 "=r"))]
5710 "TARGET_64BIT
5711 && ix86_match_ccmode (insn, CCZmode)
5712 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5713 /* Current assemblers are broken and do not allow @GOTOFF in
5714 ought but a memory context. */
5715 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5716{
5717 switch (get_attr_type (insn))
5718 {
5719 case TYPE_INCDEC:
5720 if (! rtx_equal_p (operands[0], operands[1]))
5721 abort ();
5722 if (operands[2] == const1_rtx)
5723 return "inc{q}\t%0";
5724 else if (operands[2] == constm1_rtx)
5725 return "dec{q}\t%0";
5726 else
5727 abort ();
5728
5729 default:
5730 if (! rtx_equal_p (operands[0], operands[1]))
5731 abort ();
5732 /* ???? We ought to handle there the 32bit case too
5733 - do we need new constrant? */
5734 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5735 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5736 if (GET_CODE (operands[2]) == CONST_INT
5737 /* Avoid overflows. */
5738 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5739 && (INTVAL (operands[2]) == 128
5740 || (INTVAL (operands[2]) < 0
5741 && INTVAL (operands[2]) != -128)))
5742 {
5743 operands[2] = GEN_INT (-INTVAL (operands[2]));
5744 return "sub{q}\t{%2, %0|%0, %2}";
5745 }
5746 return "add{q}\t{%2, %0|%0, %2}";
5747 }
5748}
5749 [(set (attr "type")
5750 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5751 (const_string "incdec")
5752 (const_string "alu")))
5753 (set_attr "mode" "DI")])
5754
5755; For comparisons against 1, -1 and 128, we may generate better code
5756; by converting cmp to add, inc or dec as done by peephole2. This pattern
5757; is matched then. We can't accept general immediate, because for
5758; case of overflows, the result is messed up.
5759; This pattern also don't hold of 0x8000000000000000, since the value overflows
5760; when negated.
5761; Also carry flag is reversed compared to cmp, so this conversion is valid
5762; only for comparisons not depending on it.
5763(define_insn "*adddi_4_rex64"
5764 [(set (reg 17)
5765 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5766 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5767 (clobber (match_scratch:DI 0 "=rm"))]
5768 "TARGET_64BIT
5769 && ix86_match_ccmode (insn, CCGCmode)"
5770{
5771 switch (get_attr_type (insn))
5772 {
5773 case TYPE_INCDEC:
5774 if (operands[2] == constm1_rtx)
5775 return "inc{q}\t%0";
5776 else if (operands[2] == const1_rtx)
5777 return "dec{q}\t%0";
5778 else
5779 abort();
5780
5781 default:
5782 if (! rtx_equal_p (operands[0], operands[1]))
5783 abort ();
5784 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5785 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5786 if ((INTVAL (operands[2]) == -128
5787 || (INTVAL (operands[2]) > 0
5788 && INTVAL (operands[2]) != 128))
5789 /* Avoid overflows. */
5790 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5791 return "sub{q}\t{%2, %0|%0, %2}";
5792 operands[2] = GEN_INT (-INTVAL (operands[2]));
5793 return "add{q}\t{%2, %0|%0, %2}";
5794 }
5795}
5796 [(set (attr "type")
5797 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5798 (const_string "incdec")
5799 (const_string "alu")))
5800 (set_attr "mode" "DI")])
5801
5802(define_insn "*adddi_5_rex64"
5803 [(set (reg 17)
5804 (compare
5805 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5806 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5807 (const_int 0)))
5808 (clobber (match_scratch:DI 0 "=r"))]
5809 "TARGET_64BIT
5810 && ix86_match_ccmode (insn, CCGOCmode)
5811 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5812 /* Current assemblers are broken and do not allow @GOTOFF in
5813 ought but a memory context. */
5814 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5815{
5816 switch (get_attr_type (insn))
5817 {
5818 case TYPE_INCDEC:
5819 if (! rtx_equal_p (operands[0], operands[1]))
5820 abort ();
5821 if (operands[2] == const1_rtx)
5822 return "inc{q}\t%0";
5823 else if (operands[2] == constm1_rtx)
5824 return "dec{q}\t%0";
5825 else
5826 abort();
5827
5828 default:
5829 if (! rtx_equal_p (operands[0], operands[1]))
5830 abort ();
5831 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5832 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5833 if (GET_CODE (operands[2]) == CONST_INT
5834 /* Avoid overflows. */
5835 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5836 && (INTVAL (operands[2]) == 128
5837 || (INTVAL (operands[2]) < 0
5838 && INTVAL (operands[2]) != -128)))
5839 {
5840 operands[2] = GEN_INT (-INTVAL (operands[2]));
5841 return "sub{q}\t{%2, %0|%0, %2}";
5842 }
5843 return "add{q}\t{%2, %0|%0, %2}";
5844 }
5845}
5846 [(set (attr "type")
5847 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5848 (const_string "incdec")
5849 (const_string "alu")))
5850 (set_attr "mode" "DI")])
5851
5852
5853(define_insn "*addsi_1"
5854 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5855 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5856 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5857 (clobber (reg:CC 17))]
5858 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5859{
5860 switch (get_attr_type (insn))
5861 {
5862 case TYPE_LEA:
5863 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5864 return "lea{l}\t{%a2, %0|%0, %a2}";
5865
5866 case TYPE_INCDEC:
5867 if (! rtx_equal_p (operands[0], operands[1]))
5868 abort ();
5869 if (operands[2] == const1_rtx)
5870 return "inc{l}\t%0";
5871 else if (operands[2] == constm1_rtx)
5872 return "dec{l}\t%0";
5873 else
5874 abort();
5875
5876 default:
5877 if (! rtx_equal_p (operands[0], operands[1]))
5878 abort ();
5879
5880 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5881 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5882 if (GET_CODE (operands[2]) == CONST_INT
5883 && (INTVAL (operands[2]) == 128
5884 || (INTVAL (operands[2]) < 0
5885 && INTVAL (operands[2]) != -128)))
5886 {
5887 operands[2] = GEN_INT (-INTVAL (operands[2]));
5888 return "sub{l}\t{%2, %0|%0, %2}";
5889 }
5890 return "add{l}\t{%2, %0|%0, %2}";
5891 }
5892}
5893 [(set (attr "type")
5894 (cond [(eq_attr "alternative" "2")
5895 (const_string "lea")
5896 ; Current assemblers are broken and do not allow @GOTOFF in
5897 ; ought but a memory context.
5898 (match_operand:SI 2 "pic_symbolic_operand" "")
5899 (const_string "lea")
5900 (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 ]
5903 (const_string "alu")))
5904 (set_attr "mode" "SI")])
5905
5906;; Convert lea to the lea pattern to avoid flags dependency.
5907(define_split
5908 [(set (match_operand 0 "register_operand" "")
5909 (plus (match_operand 1 "register_operand" "")
5910 (match_operand 2 "nonmemory_operand" "")))
5911 (clobber (reg:CC 17))]
5912 "reload_completed
5913 && true_regnum (operands[0]) != true_regnum (operands[1])"
5914 [(const_int 0)]
5915{
5916 rtx pat;
5917 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5918 may confuse gen_lowpart. */
5919 if (GET_MODE (operands[0]) != Pmode)
5920 {
5921 operands[1] = gen_lowpart (Pmode, operands[1]);
5922 operands[2] = gen_lowpart (Pmode, operands[2]);
5923 }
5924 operands[0] = gen_lowpart (SImode, operands[0]);
5925 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5926 if (Pmode != SImode)
5927 pat = gen_rtx_SUBREG (SImode, pat, 0);
5928 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5929 DONE;
5930})
5931
5932;; It may seem that nonimmediate operand is proper one for operand 1.
5933;; The addsi_1 pattern allows nonimmediate operand at that place and
5934;; we take care in ix86_binary_operator_ok to not allow two memory
5935;; operands so proper swapping will be done in reload. This allow
5936;; patterns constructed from addsi_1 to match.
5937(define_insn "addsi_1_zext"
5938 [(set (match_operand:DI 0 "register_operand" "=r,r")
5939 (zero_extend:DI
5940 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5941 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5942 (clobber (reg:CC 17))]
5943 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5944{
5945 switch (get_attr_type (insn))
5946 {
5947 case TYPE_LEA:
5948 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5949 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5950
5951 case TYPE_INCDEC:
5952 if (operands[2] == const1_rtx)
5953 return "inc{l}\t%k0";
5954 else if (operands[2] == constm1_rtx)
5955 return "dec{l}\t%k0";
5956 else
5957 abort();
5958
5959 default:
5960 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5962 if (GET_CODE (operands[2]) == CONST_INT
5963 && (INTVAL (operands[2]) == 128
5964 || (INTVAL (operands[2]) < 0
5965 && INTVAL (operands[2]) != -128)))
5966 {
5967 operands[2] = GEN_INT (-INTVAL (operands[2]));
5968 return "sub{l}\t{%2, %k0|%k0, %2}";
5969 }
5970 return "add{l}\t{%2, %k0|%k0, %2}";
5971 }
5972}
5973 [(set (attr "type")
5974 (cond [(eq_attr "alternative" "1")
5975 (const_string "lea")
5976 ; Current assemblers are broken and do not allow @GOTOFF in
5977 ; ought but a memory context.
5978 (match_operand:SI 2 "pic_symbolic_operand" "")
5979 (const_string "lea")
5980 (match_operand:SI 2 "incdec_operand" "")
5981 (const_string "incdec")
5982 ]
5983 (const_string "alu")))
5984 (set_attr "mode" "SI")])
5985
5986;; Convert lea to the lea pattern to avoid flags dependency.
5987(define_split
5988 [(set (match_operand:DI 0 "register_operand" "")
5989 (zero_extend:DI
5990 (plus:SI (match_operand:SI 1 "register_operand" "")
5991 (match_operand:SI 2 "nonmemory_operand" ""))))
5992 (clobber (reg:CC 17))]
5993 "reload_completed
5994 && true_regnum (operands[0]) != true_regnum (operands[1])"
5995 [(set (match_dup 0)
5996 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5997{
5998 operands[1] = gen_lowpart (Pmode, operands[1]);
5999 operands[2] = gen_lowpart (Pmode, operands[2]);
6000})
6001
6002(define_insn "*addsi_2"
6003 [(set (reg 17)
6004 (compare
6005 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6006 (match_operand:SI 2 "general_operand" "rmni,rni"))
6007 (const_int 0)))
6008 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6009 (plus:SI (match_dup 1) (match_dup 2)))]
6010 "ix86_match_ccmode (insn, CCGOCmode)
6011 && ix86_binary_operator_ok (PLUS, SImode, operands)
6012 /* Current assemblers are broken and do not allow @GOTOFF in
6013 ought but a memory context. */
6014 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6015{
6016 switch (get_attr_type (insn))
6017 {
6018 case TYPE_INCDEC:
6019 if (! rtx_equal_p (operands[0], operands[1]))
6020 abort ();
6021 if (operands[2] == const1_rtx)
6022 return "inc{l}\t%0";
6023 else if (operands[2] == constm1_rtx)
6024 return "dec{l}\t%0";
6025 else
6026 abort();
6027
6028 default:
6029 if (! rtx_equal_p (operands[0], operands[1]))
6030 abort ();
6031 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6032 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6033 if (GET_CODE (operands[2]) == CONST_INT
6034 && (INTVAL (operands[2]) == 128
6035 || (INTVAL (operands[2]) < 0
6036 && INTVAL (operands[2]) != -128)))
6037 {
6038 operands[2] = GEN_INT (-INTVAL (operands[2]));
6039 return "sub{l}\t{%2, %0|%0, %2}";
6040 }
6041 return "add{l}\t{%2, %0|%0, %2}";
6042 }
6043}
6044 [(set (attr "type")
6045 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6046 (const_string "incdec")
6047 (const_string "alu")))
6048 (set_attr "mode" "SI")])
6049
6050;; See comment for addsi_1_zext why we do use nonimmediate_operand
6051(define_insn "*addsi_2_zext"
6052 [(set (reg 17)
6053 (compare
6054 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6055 (match_operand:SI 2 "general_operand" "rmni"))
6056 (const_int 0)))
6057 (set (match_operand:DI 0 "register_operand" "=r")
6058 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6059 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6060 && ix86_binary_operator_ok (PLUS, SImode, operands)
6061 /* Current assemblers are broken and do not allow @GOTOFF in
6062 ought but a memory context. */
6063 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6064{
6065 switch (get_attr_type (insn))
6066 {
6067 case TYPE_INCDEC:
6068 if (operands[2] == const1_rtx)
6069 return "inc{l}\t%k0";
6070 else if (operands[2] == constm1_rtx)
6071 return "dec{l}\t%k0";
6072 else
6073 abort();
6074
6075 default:
6076 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6077 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6078 if (GET_CODE (operands[2]) == CONST_INT
6079 && (INTVAL (operands[2]) == 128
6080 || (INTVAL (operands[2]) < 0
6081 && INTVAL (operands[2]) != -128)))
6082 {
6083 operands[2] = GEN_INT (-INTVAL (operands[2]));
6084 return "sub{l}\t{%2, %k0|%k0, %2}";
6085 }
6086 return "add{l}\t{%2, %k0|%k0, %2}";
6087 }
6088}
6089 [(set (attr "type")
6090 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6091 (const_string "incdec")
6092 (const_string "alu")))
6093 (set_attr "mode" "SI")])
6094
6095(define_insn "*addsi_3"
6096 [(set (reg 17)
6097 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6098 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6099 (clobber (match_scratch:SI 0 "=r"))]
6100 "ix86_match_ccmode (insn, CCZmode)
6101 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6102 /* Current assemblers are broken and do not allow @GOTOFF in
6103 ought but a memory context. */
6104 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6105{
6106 switch (get_attr_type (insn))
6107 {
6108 case TYPE_INCDEC:
6109 if (! rtx_equal_p (operands[0], operands[1]))
6110 abort ();
6111 if (operands[2] == const1_rtx)
6112 return "inc{l}\t%0";
6113 else if (operands[2] == constm1_rtx)
6114 return "dec{l}\t%0";
6115 else
6116 abort();
6117
6118 default:
6119 if (! rtx_equal_p (operands[0], operands[1]))
6120 abort ();
6121 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6122 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6123 if (GET_CODE (operands[2]) == CONST_INT
6124 && (INTVAL (operands[2]) == 128
6125 || (INTVAL (operands[2]) < 0
6126 && INTVAL (operands[2]) != -128)))
6127 {
6128 operands[2] = GEN_INT (-INTVAL (operands[2]));
6129 return "sub{l}\t{%2, %0|%0, %2}";
6130 }
6131 return "add{l}\t{%2, %0|%0, %2}";
6132 }
6133}
6134 [(set (attr "type")
6135 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6136 (const_string "incdec")
6137 (const_string "alu")))
6138 (set_attr "mode" "SI")])
6139
6140;; See comment for addsi_1_zext why we do use nonimmediate_operand
6141(define_insn "*addsi_3_zext"
6142 [(set (reg 17)
6143 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6144 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6145 (set (match_operand:DI 0 "register_operand" "=r")
6146 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6147 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6148 && ix86_binary_operator_ok (PLUS, SImode, operands)
6149 /* Current assemblers are broken and do not allow @GOTOFF in
6150 ought but a memory context. */
6151 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6152{
6153 switch (get_attr_type (insn))
6154 {
6155 case TYPE_INCDEC:
6156 if (operands[2] == const1_rtx)
6157 return "inc{l}\t%k0";
6158 else if (operands[2] == constm1_rtx)
6159 return "dec{l}\t%k0";
6160 else
6161 abort();
6162
6163 default:
6164 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6165 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6166 if (GET_CODE (operands[2]) == CONST_INT
6167 && (INTVAL (operands[2]) == 128
6168 || (INTVAL (operands[2]) < 0
6169 && INTVAL (operands[2]) != -128)))
6170 {
6171 operands[2] = GEN_INT (-INTVAL (operands[2]));
6172 return "sub{l}\t{%2, %k0|%k0, %2}";
6173 }
6174 return "add{l}\t{%2, %k0|%k0, %2}";
6175 }
6176}
6177 [(set (attr "type")
6178 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6179 (const_string "incdec")
6180 (const_string "alu")))
6181 (set_attr "mode" "SI")])
6182
6183; For comparisons agains 1, -1 and 128, we may generate better code
6184; by converting cmp to add, inc or dec as done by peephole2. This pattern
6185; is matched then. We can't accept general immediate, because for
6186; case of overflows, the result is messed up.
6187; This pattern also don't hold of 0x80000000, since the value overflows
6188; when negated.
6189; Also carry flag is reversed compared to cmp, so this conversion is valid
6190; only for comparisons not depending on it.
6191(define_insn "*addsi_4"
6192 [(set (reg 17)
6193 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6194 (match_operand:SI 2 "const_int_operand" "n")))
6195 (clobber (match_scratch:SI 0 "=rm"))]
6196 "ix86_match_ccmode (insn, CCGCmode)
6197 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6198{
6199 switch (get_attr_type (insn))
6200 {
6201 case TYPE_INCDEC:
6202 if (operands[2] == constm1_rtx)
6203 return "inc{l}\t%0";
6204 else if (operands[2] == const1_rtx)
6205 return "dec{l}\t%0";
6206 else
6207 abort();
6208
6209 default:
6210 if (! rtx_equal_p (operands[0], operands[1]))
6211 abort ();
6212 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6213 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6214 if ((INTVAL (operands[2]) == -128
6215 || (INTVAL (operands[2]) > 0
6216 && INTVAL (operands[2]) != 128)))
6217 return "sub{l}\t{%2, %0|%0, %2}";
6218 operands[2] = GEN_INT (-INTVAL (operands[2]));
6219 return "add{l}\t{%2, %0|%0, %2}";
6220 }
6221}
6222 [(set (attr "type")
6223 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6224 (const_string "incdec")
6225 (const_string "alu")))
6226 (set_attr "mode" "SI")])
6227
6228(define_insn "*addsi_5"
6229 [(set (reg 17)
6230 (compare
6231 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6232 (match_operand:SI 2 "general_operand" "rmni"))
6233 (const_int 0)))
6234 (clobber (match_scratch:SI 0 "=r"))]
6235 "ix86_match_ccmode (insn, CCGOCmode)
6236 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6237 /* Current assemblers are broken and do not allow @GOTOFF in
6238 ought but a memory context. */
6239 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6240{
6241 switch (get_attr_type (insn))
6242 {
6243 case TYPE_INCDEC:
6244 if (! rtx_equal_p (operands[0], operands[1]))
6245 abort ();
6246 if (operands[2] == const1_rtx)
6247 return "inc{l}\t%0";
6248 else if (operands[2] == constm1_rtx)
6249 return "dec{l}\t%0";
6250 else
6251 abort();
6252
6253 default:
6254 if (! rtx_equal_p (operands[0], operands[1]))
6255 abort ();
6256 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6257 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6258 if (GET_CODE (operands[2]) == CONST_INT
6259 && (INTVAL (operands[2]) == 128
6260 || (INTVAL (operands[2]) < 0
6261 && INTVAL (operands[2]) != -128)))
6262 {
6263 operands[2] = GEN_INT (-INTVAL (operands[2]));
6264 return "sub{l}\t{%2, %0|%0, %2}";
6265 }
6266 return "add{l}\t{%2, %0|%0, %2}";
6267 }
6268}
6269 [(set (attr "type")
6270 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set_attr "mode" "SI")])
6274
6275(define_expand "addhi3"
6276 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6277 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6278 (match_operand:HI 2 "general_operand" "")))
6279 (clobber (reg:CC 17))])]
6280 "TARGET_HIMODE_MATH"
6281 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6282
6283;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6284;; type optimizations enabled by define-splits. This is not important
6285;; for PII, and in fact harmful because of partial register stalls.
6286
6287(define_insn "*addhi_1_lea"
6288 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6289 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6290 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6291 (clobber (reg:CC 17))]
6292 "!TARGET_PARTIAL_REG_STALL
6293 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6294{
6295 switch (get_attr_type (insn))
6296 {
6297 case TYPE_LEA:
6298 return "#";
6299 case TYPE_INCDEC:
6300 if (operands[2] == const1_rtx)
6301 return "inc{w}\t%0";
6302 else if (operands[2] == constm1_rtx
6303 || (GET_CODE (operands[2]) == CONST_INT
6304 && INTVAL (operands[2]) == 65535))
6305 return "dec{w}\t%0";
6306 abort();
6307
6308 default:
6309 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6310 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6311 if (GET_CODE (operands[2]) == CONST_INT
6312 && (INTVAL (operands[2]) == 128
6313 || (INTVAL (operands[2]) < 0
6314 && INTVAL (operands[2]) != -128)))
6315 {
6316 operands[2] = GEN_INT (-INTVAL (operands[2]));
6317 return "sub{w}\t{%2, %0|%0, %2}";
6318 }
6319 return "add{w}\t{%2, %0|%0, %2}";
6320 }
6321}
6322 [(set (attr "type")
6323 (if_then_else (eq_attr "alternative" "2")
6324 (const_string "lea")
6325 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6326 (const_string "incdec")
6327 (const_string "alu"))))
6328 (set_attr "mode" "HI,HI,SI")])
6329
6330(define_insn "*addhi_1"
6331 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6332 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6333 (match_operand:HI 2 "general_operand" "ri,rm")))
6334 (clobber (reg:CC 17))]
6335 "TARGET_PARTIAL_REG_STALL
6336 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6337{
6338 switch (get_attr_type (insn))
6339 {
6340 case TYPE_INCDEC:
6341 if (operands[2] == const1_rtx)
6342 return "inc{w}\t%0";
6343 else if (operands[2] == constm1_rtx
6344 || (GET_CODE (operands[2]) == CONST_INT
6345 && INTVAL (operands[2]) == 65535))
6346 return "dec{w}\t%0";
6347 abort();
6348
6349 default:
6350 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6351 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6352 if (GET_CODE (operands[2]) == CONST_INT
6353 && (INTVAL (operands[2]) == 128
6354 || (INTVAL (operands[2]) < 0
6355 && INTVAL (operands[2]) != -128)))
6356 {
6357 operands[2] = GEN_INT (-INTVAL (operands[2]));
6358 return "sub{w}\t{%2, %0|%0, %2}";
6359 }
6360 return "add{w}\t{%2, %0|%0, %2}";
6361 }
6362}
6363 [(set (attr "type")
6364 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6365 (const_string "incdec")
6366 (const_string "alu")))
6367 (set_attr "mode" "HI")])
6368
6369(define_insn "*addhi_2"
6370 [(set (reg 17)
6371 (compare
6372 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6373 (match_operand:HI 2 "general_operand" "rmni,rni"))
6374 (const_int 0)))
6375 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6376 (plus:HI (match_dup 1) (match_dup 2)))]
6377 "ix86_match_ccmode (insn, CCGOCmode)
6378 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6379{
6380 switch (get_attr_type (insn))
6381 {
6382 case TYPE_INCDEC:
6383 if (operands[2] == const1_rtx)
6384 return "inc{w}\t%0";
6385 else if (operands[2] == constm1_rtx
6386 || (GET_CODE (operands[2]) == CONST_INT
6387 && INTVAL (operands[2]) == 65535))
6388 return "dec{w}\t%0";
6389 abort();
6390
6391 default:
6392 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6393 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6394 if (GET_CODE (operands[2]) == CONST_INT
6395 && (INTVAL (operands[2]) == 128
6396 || (INTVAL (operands[2]) < 0
6397 && INTVAL (operands[2]) != -128)))
6398 {
6399 operands[2] = GEN_INT (-INTVAL (operands[2]));
6400 return "sub{w}\t{%2, %0|%0, %2}";
6401 }
6402 return "add{w}\t{%2, %0|%0, %2}";
6403 }
6404}
6405 [(set (attr "type")
6406 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6407 (const_string "incdec")
6408 (const_string "alu")))
6409 (set_attr "mode" "HI")])
6410
6411(define_insn "*addhi_3"
6412 [(set (reg 17)
6413 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6414 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6415 (clobber (match_scratch:HI 0 "=r"))]
6416 "ix86_match_ccmode (insn, CCZmode)
6417 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6418{
6419 switch (get_attr_type (insn))
6420 {
6421 case TYPE_INCDEC:
6422 if (operands[2] == const1_rtx)
6423 return "inc{w}\t%0";
6424 else if (operands[2] == constm1_rtx
6425 || (GET_CODE (operands[2]) == CONST_INT
6426 && INTVAL (operands[2]) == 65535))
6427 return "dec{w}\t%0";
6428 abort();
6429
6430 default:
6431 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6432 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6433 if (GET_CODE (operands[2]) == CONST_INT
6434 && (INTVAL (operands[2]) == 128
6435 || (INTVAL (operands[2]) < 0
6436 && INTVAL (operands[2]) != -128)))
6437 {
6438 operands[2] = GEN_INT (-INTVAL (operands[2]));
6439 return "sub{w}\t{%2, %0|%0, %2}";
6440 }
6441 return "add{w}\t{%2, %0|%0, %2}";
6442 }
6443}
6444 [(set (attr "type")
6445 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6446 (const_string "incdec")
6447 (const_string "alu")))
6448 (set_attr "mode" "HI")])
6449
6450; See comments above addsi_3_imm for details.
6451(define_insn "*addhi_4"
6452 [(set (reg 17)
6453 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6454 (match_operand:HI 2 "const_int_operand" "n")))
6455 (clobber (match_scratch:HI 0 "=rm"))]
6456 "ix86_match_ccmode (insn, CCGCmode)
6457 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6458{
6459 switch (get_attr_type (insn))
6460 {
6461 case TYPE_INCDEC:
6462 if (operands[2] == constm1_rtx
6463 || (GET_CODE (operands[2]) == CONST_INT
6464 && INTVAL (operands[2]) == 65535))
6465 return "inc{w}\t%0";
6466 else if (operands[2] == const1_rtx)
6467 return "dec{w}\t%0";
6468 else
6469 abort();
6470
6471 default:
6472 if (! rtx_equal_p (operands[0], operands[1]))
6473 abort ();
6474 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6475 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6476 if ((INTVAL (operands[2]) == -128
6477 || (INTVAL (operands[2]) > 0
6478 && INTVAL (operands[2]) != 128)))
6479 return "sub{w}\t{%2, %0|%0, %2}";
6480 operands[2] = GEN_INT (-INTVAL (operands[2]));
6481 return "add{w}\t{%2, %0|%0, %2}";
6482 }
6483}
6484 [(set (attr "type")
6485 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6486 (const_string "incdec")
6487 (const_string "alu")))
6488 (set_attr "mode" "SI")])
6489
6490
6491(define_insn "*addhi_5"
6492 [(set (reg 17)
6493 (compare
6494 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6495 (match_operand:HI 2 "general_operand" "rmni"))
6496 (const_int 0)))
6497 (clobber (match_scratch:HI 0 "=r"))]
6498 "ix86_match_ccmode (insn, CCGOCmode)
6499 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6500{
6501 switch (get_attr_type (insn))
6502 {
6503 case TYPE_INCDEC:
6504 if (operands[2] == const1_rtx)
6505 return "inc{w}\t%0";
6506 else if (operands[2] == constm1_rtx
6507 || (GET_CODE (operands[2]) == CONST_INT
6508 && INTVAL (operands[2]) == 65535))
6509 return "dec{w}\t%0";
6510 abort();
6511
6512 default:
6513 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6514 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6515 if (GET_CODE (operands[2]) == CONST_INT
6516 && (INTVAL (operands[2]) == 128
6517 || (INTVAL (operands[2]) < 0
6518 && INTVAL (operands[2]) != -128)))
6519 {
6520 operands[2] = GEN_INT (-INTVAL (operands[2]));
6521 return "sub{w}\t{%2, %0|%0, %2}";
6522 }
6523 return "add{w}\t{%2, %0|%0, %2}";
6524 }
6525}
6526 [(set (attr "type")
6527 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6528 (const_string "incdec")
6529 (const_string "alu")))
6530 (set_attr "mode" "HI")])
6531
6532(define_expand "addqi3"
6533 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6534 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6535 (match_operand:QI 2 "general_operand" "")))
6536 (clobber (reg:CC 17))])]
6537 "TARGET_QIMODE_MATH"
6538 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6539
6540;; %%% Potential partial reg stall on alternative 2. What to do?
6541(define_insn "*addqi_1_lea"
6542 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6543 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6544 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6545 (clobber (reg:CC 17))]
6546 "!TARGET_PARTIAL_REG_STALL
6547 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6548{
6549 int widen = (which_alternative == 2);
6550 switch (get_attr_type (insn))
6551 {
6552 case TYPE_LEA:
6553 return "#";
6554 case TYPE_INCDEC:
6555 if (operands[2] == const1_rtx)
6556 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6557 else if (operands[2] == constm1_rtx
6558 || (GET_CODE (operands[2]) == CONST_INT
6559 && INTVAL (operands[2]) == 255))
6560 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6561 abort();
6562
6563 default:
6564 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6565 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6566 if (GET_CODE (operands[2]) == CONST_INT
6567 && (INTVAL (operands[2]) == 128
6568 || (INTVAL (operands[2]) < 0
6569 && INTVAL (operands[2]) != -128)))
6570 {
6571 operands[2] = GEN_INT (-INTVAL (operands[2]));
6572 if (widen)
6573 return "sub{l}\t{%2, %k0|%k0, %2}";
6574 else
6575 return "sub{b}\t{%2, %0|%0, %2}";
6576 }
6577 if (widen)
6578 return "add{l}\t{%k2, %k0|%k0, %k2}";
6579 else
6580 return "add{b}\t{%2, %0|%0, %2}";
6581 }
6582}
6583 [(set (attr "type")
6584 (if_then_else (eq_attr "alternative" "3")
6585 (const_string "lea")
6586 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6587 (const_string "incdec")
6588 (const_string "alu"))))
6589 (set_attr "mode" "QI,QI,SI,SI")])
6590
6591(define_insn "*addqi_1"
6592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6593 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6594 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6595 (clobber (reg:CC 17))]
6596 "TARGET_PARTIAL_REG_STALL
6597 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6598{
6599 int widen = (which_alternative == 2);
6600 switch (get_attr_type (insn))
6601 {
6602 case TYPE_INCDEC:
6603 if (operands[2] == const1_rtx)
6604 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6605 else if (operands[2] == constm1_rtx
6606 || (GET_CODE (operands[2]) == CONST_INT
6607 && INTVAL (operands[2]) == 255))
6608 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6609 abort();
6610
6611 default:
6612 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6613 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6614 if (GET_CODE (operands[2]) == CONST_INT
6615 && (INTVAL (operands[2]) == 128
6616 || (INTVAL (operands[2]) < 0
6617 && INTVAL (operands[2]) != -128)))
6618 {
6619 operands[2] = GEN_INT (-INTVAL (operands[2]));
6620 if (widen)
6621 return "sub{l}\t{%2, %k0|%k0, %2}";
6622 else
6623 return "sub{b}\t{%2, %0|%0, %2}";
6624 }
6625 if (widen)
6626 return "add{l}\t{%k2, %k0|%k0, %k2}";
6627 else
6628 return "add{b}\t{%2, %0|%0, %2}";
6629 }
6630}
6631 [(set (attr "type")
6632 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6633 (const_string "incdec")
6634 (const_string "alu")))
6635 (set_attr "mode" "QI,QI,SI")])
6636
6637(define_insn "*addqi_2"
6638 [(set (reg 17)
6639 (compare
6640 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6641 (match_operand:QI 2 "general_operand" "qmni,qni"))
6642 (const_int 0)))
6643 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6644 (plus:QI (match_dup 1) (match_dup 2)))]
6645 "ix86_match_ccmode (insn, CCGOCmode)
6646 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6647{
6648 switch (get_attr_type (insn))
6649 {
6650 case TYPE_INCDEC:
6651 if (operands[2] == const1_rtx)
6652 return "inc{b}\t%0";
6653 else if (operands[2] == constm1_rtx
6654 || (GET_CODE (operands[2]) == CONST_INT
6655 && INTVAL (operands[2]) == 255))
6656 return "dec{b}\t%0";
6657 abort();
6658
6659 default:
6660 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6661 if (GET_CODE (operands[2]) == CONST_INT
6662 && INTVAL (operands[2]) < 0)
6663 {
6664 operands[2] = GEN_INT (-INTVAL (operands[2]));
6665 return "sub{b}\t{%2, %0|%0, %2}";
6666 }
6667 return "add{b}\t{%2, %0|%0, %2}";
6668 }
6669}
6670 [(set (attr "type")
6671 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6672 (const_string "incdec")
6673 (const_string "alu")))
6674 (set_attr "mode" "QI")])
6675
6676(define_insn "*addqi_3"
6677 [(set (reg 17)
6678 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6679 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6680 (clobber (match_scratch:QI 0 "=q"))]
6681 "ix86_match_ccmode (insn, CCZmode)
6682 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6683{
6684 switch (get_attr_type (insn))
6685 {
6686 case TYPE_INCDEC:
6687 if (operands[2] == const1_rtx)
6688 return "inc{b}\t%0";
6689 else if (operands[2] == constm1_rtx
6690 || (GET_CODE (operands[2]) == CONST_INT
6691 && INTVAL (operands[2]) == 255))
6692 return "dec{b}\t%0";
6693 abort();
6694
6695 default:
6696 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6697 if (GET_CODE (operands[2]) == CONST_INT
6698 && INTVAL (operands[2]) < 0)
6699 {
6700 operands[2] = GEN_INT (-INTVAL (operands[2]));
6701 return "sub{b}\t{%2, %0|%0, %2}";
6702 }
6703 return "add{b}\t{%2, %0|%0, %2}";
6704 }
6705}
6706 [(set (attr "type")
6707 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6708 (const_string "incdec")
6709 (const_string "alu")))
6710 (set_attr "mode" "QI")])
6711
6712; See comments above addsi_3_imm for details.
6713(define_insn "*addqi_4"
6714 [(set (reg 17)
6715 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6716 (match_operand:QI 2 "const_int_operand" "n")))
6717 (clobber (match_scratch:QI 0 "=qm"))]
6718 "ix86_match_ccmode (insn, CCGCmode)
6719 && (INTVAL (operands[2]) & 0xff) != 0x80"
6720{
6721 switch (get_attr_type (insn))
6722 {
6723 case TYPE_INCDEC:
6724 if (operands[2] == constm1_rtx
6725 || (GET_CODE (operands[2]) == CONST_INT
6726 && INTVAL (operands[2]) == 255))
6727 return "inc{b}\t%0";
6728 else if (operands[2] == const1_rtx)
6729 return "dec{b}\t%0";
6730 else
6731 abort();
6732
6733 default:
6734 if (! rtx_equal_p (operands[0], operands[1]))
6735 abort ();
6736 if (INTVAL (operands[2]) < 0)
6737 {
6738 operands[2] = GEN_INT (-INTVAL (operands[2]));
6739 return "add{b}\t{%2, %0|%0, %2}";
6740 }
6741 return "sub{b}\t{%2, %0|%0, %2}";
6742 }
6743}
6744 [(set (attr "type")
6745 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6746 (const_string "incdec")
6747 (const_string "alu")))
6748 (set_attr "mode" "QI")])
6749
6750
6751(define_insn "*addqi_5"
6752 [(set (reg 17)
6753 (compare
6754 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6755 (match_operand:QI 2 "general_operand" "qmni"))
6756 (const_int 0)))
6757 (clobber (match_scratch:QI 0 "=q"))]
6758 "ix86_match_ccmode (insn, CCGOCmode)
6759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6760{
6761 switch (get_attr_type (insn))
6762 {
6763 case TYPE_INCDEC:
6764 if (operands[2] == const1_rtx)
6765 return "inc{b}\t%0";
6766 else if (operands[2] == constm1_rtx
6767 || (GET_CODE (operands[2]) == CONST_INT
6768 && INTVAL (operands[2]) == 255))
6769 return "dec{b}\t%0";
6770 abort();
6771
6772 default:
6773 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6774 if (GET_CODE (operands[2]) == CONST_INT
6775 && INTVAL (operands[2]) < 0)
6776 {
6777 operands[2] = GEN_INT (-INTVAL (operands[2]));
6778 return "sub{b}\t{%2, %0|%0, %2}";
6779 }
6780 return "add{b}\t{%2, %0|%0, %2}";
6781 }
6782}
6783 [(set (attr "type")
6784 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6785 (const_string "incdec")
6786 (const_string "alu")))
6787 (set_attr "mode" "QI")])
6788
6789
6790(define_insn "addqi_ext_1"
6791 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6792 (const_int 8)
6793 (const_int 8))
6794 (plus:SI
6795 (zero_extract:SI
6796 (match_operand 1 "ext_register_operand" "0")
6797 (const_int 8)
6798 (const_int 8))
6799 (match_operand:QI 2 "general_operand" "Qmn")))
6800 (clobber (reg:CC 17))]
6801 "!TARGET_64BIT"
6802{
6803 switch (get_attr_type (insn))
6804 {
6805 case TYPE_INCDEC:
6806 if (operands[2] == const1_rtx)
6807 return "inc{b}\t%h0";
6808 else if (operands[2] == constm1_rtx
6809 || (GET_CODE (operands[2]) == CONST_INT
6810 && INTVAL (operands[2]) == 255))
6811 return "dec{b}\t%h0";
6812 abort();
6813
6814 default:
6815 return "add{b}\t{%2, %h0|%h0, %2}";
6816 }
6817}
6818 [(set (attr "type")
6819 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6820 (const_string "incdec")
6821 (const_string "alu")))
6822 (set_attr "mode" "QI")])
6823
6824(define_insn "*addqi_ext_1_rex64"
6825 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6826 (const_int 8)
6827 (const_int 8))
6828 (plus:SI
6829 (zero_extract:SI
6830 (match_operand 1 "ext_register_operand" "0")
6831 (const_int 8)
6832 (const_int 8))
6833 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6834 (clobber (reg:CC 17))]
6835 "TARGET_64BIT"
6836{
6837 switch (get_attr_type (insn))
6838 {
6839 case TYPE_INCDEC:
6840 if (operands[2] == const1_rtx)
6841 return "inc{b}\t%h0";
6842 else if (operands[2] == constm1_rtx
6843 || (GET_CODE (operands[2]) == CONST_INT
6844 && INTVAL (operands[2]) == 255))
6845 return "dec{b}\t%h0";
6846 abort();
6847
6848 default:
6849 return "add{b}\t{%2, %h0|%h0, %2}";
6850 }
6851}
6852 [(set (attr "type")
6853 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6854 (const_string "incdec")
6855 (const_string "alu")))
6856 (set_attr "mode" "QI")])
6857
6858(define_insn "*addqi_ext_2"
6859 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6860 (const_int 8)
6861 (const_int 8))
6862 (plus:SI
6863 (zero_extract:SI
6864 (match_operand 1 "ext_register_operand" "%0")
6865 (const_int 8)
6866 (const_int 8))
6867 (zero_extract:SI
6868 (match_operand 2 "ext_register_operand" "Q")
6869 (const_int 8)
6870 (const_int 8))))
6871 (clobber (reg:CC 17))]
6872 ""
6873 "add{b}\t{%h2, %h0|%h0, %h2}"
6874 [(set_attr "type" "alu")
6875 (set_attr "mode" "QI")])
6876
6877;; The patterns that match these are at the end of this file.
6878
6879(define_expand "addxf3"
6880 [(set (match_operand:XF 0 "register_operand" "")
6881 (plus:XF (match_operand:XF 1 "register_operand" "")
6882 (match_operand:XF 2 "register_operand" "")))]
6883 "!TARGET_64BIT && TARGET_80387"
6884 "")
6885
6886(define_expand "addtf3"
6887 [(set (match_operand:TF 0 "register_operand" "")
6888 (plus:TF (match_operand:TF 1 "register_operand" "")
6889 (match_operand:TF 2 "register_operand" "")))]
6890 "TARGET_80387"
6891 "")
6892
6893(define_expand "adddf3"
6894 [(set (match_operand:DF 0 "register_operand" "")
6895 (plus:DF (match_operand:DF 1 "register_operand" "")
6896 (match_operand:DF 2 "nonimmediate_operand" "")))]
6897 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6898 "")
6899
6900(define_expand "addsf3"
6901 [(set (match_operand:SF 0 "register_operand" "")
6902 (plus:SF (match_operand:SF 1 "register_operand" "")
6903 (match_operand:SF 2 "nonimmediate_operand" "")))]
6904 "TARGET_80387 || TARGET_SSE_MATH"
6905 "")
6906
6907;; Subtract instructions
6908
6909;; %%% splits for subsidi3
6910
6911(define_expand "subdi3"
6912 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6913 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6914 (match_operand:DI 2 "x86_64_general_operand" "")))
6915 (clobber (reg:CC 17))])]
6916 ""
6917 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6918
6919(define_insn "*subdi3_1"
6920 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6921 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6922 (match_operand:DI 2 "general_operand" "roiF,riF")))
6923 (clobber (reg:CC 17))]
6924 "!TARGET_64BIT"
6925 "#")
6926
6927(define_split
6928 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6929 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6930 (match_operand:DI 2 "general_operand" "")))
6931 (clobber (reg:CC 17))]
6932 "!TARGET_64BIT && reload_completed"
6933 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6934 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6935 (parallel [(set (match_dup 3)
6936 (minus:SI (match_dup 4)
6937 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6938 (match_dup 5))))
6939 (clobber (reg:CC 17))])]
6940 "split_di (operands+0, 1, operands+0, operands+3);
6941 split_di (operands+1, 1, operands+1, operands+4);
6942 split_di (operands+2, 1, operands+2, operands+5);")
6943
6944(define_insn "subdi3_carry_rex64"
6945 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6946 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6947 (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6948 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6949 (clobber (reg:CC 17))]
6950 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6951 "sbb{q}\t{%2, %0|%0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "pent_pair" "pu")
6954 (set_attr "ppro_uops" "few")
6955 (set_attr "mode" "DI")])
6956
6957(define_insn "*subdi_1_rex64"
6958 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6959 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6960 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6961 (clobber (reg:CC 17))]
6962 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6963 "sub{q}\t{%2, %0|%0, %2}"
6964 [(set_attr "type" "alu")
6965 (set_attr "mode" "DI")])
6966
6967(define_insn "*subdi_2_rex64"
6968 [(set (reg 17)
6969 (compare
6970 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6971 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6972 (const_int 0)))
6973 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6974 (minus:DI (match_dup 1) (match_dup 2)))]
6975 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6976 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6977 "sub{q}\t{%2, %0|%0, %2}"
6978 [(set_attr "type" "alu")
6979 (set_attr "mode" "DI")])
6980
6981(define_insn "*subdi_3_rex63"
6982 [(set (reg 17)
6983 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6984 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6985 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6986 (minus:DI (match_dup 1) (match_dup 2)))]
6987 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6988 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6989 "sub{q}\t{%2, %0|%0, %2}"
6990 [(set_attr "type" "alu")
6991 (set_attr "mode" "DI")])
6992
6993
6994(define_insn "subsi3_carry"
6995 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6996 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6997 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6998 (match_operand:SI 2 "general_operand" "ri,rm"))))
6999 (clobber (reg:CC 17))]
7000 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7001 "sbb{l}\t{%2, %0|%0, %2}"
7002 [(set_attr "type" "alu")
7003 (set_attr "pent_pair" "pu")
7004 (set_attr "ppro_uops" "few")
7005 (set_attr "mode" "SI")])
7006
7007(define_insn "subsi3_carry_zext"
7008 [(set (match_operand:DI 0 "register_operand" "=rm,r")
7009 (zero_extend:DI
7010 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
7011 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7012 (match_operand:SI 2 "general_operand" "ri,rm")))))
7013 (clobber (reg:CC 17))]
7014 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7015 "sbb{l}\t{%2, %k0|%k0, %2}"
7016 [(set_attr "type" "alu")
7017 (set_attr "pent_pair" "pu")
7018 (set_attr "ppro_uops" "few")
7019 (set_attr "mode" "SI")])
7020
7021(define_expand "subsi3"
7022 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7023 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7024 (match_operand:SI 2 "general_operand" "")))
7025 (clobber (reg:CC 17))])]
7026 ""
7027 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7028
7029(define_insn "*subsi_1"
7030 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7031 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7032 (match_operand:SI 2 "general_operand" "ri,rm")))
7033 (clobber (reg:CC 17))]
7034 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7035 "sub{l}\t{%2, %0|%0, %2}"
7036 [(set_attr "type" "alu")
7037 (set_attr "mode" "SI")])
7038
7039(define_insn "*subsi_1_zext"
7040 [(set (match_operand:DI 0 "register_operand" "=r")
7041 (zero_extend:DI
7042 (minus:SI (match_operand:SI 1 "register_operand" "0")
7043 (match_operand:SI 2 "general_operand" "rim"))))
7044 (clobber (reg:CC 17))]
7045 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7046 "sub{l}\t{%2, %k0|%k0, %2}"
7047 [(set_attr "type" "alu")
7048 (set_attr "mode" "SI")])
7049
7050(define_insn "*subsi_2"
7051 [(set (reg 17)
7052 (compare
7053 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7054 (match_operand:SI 2 "general_operand" "ri,rm"))
7055 (const_int 0)))
7056 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7057 (minus:SI (match_dup 1) (match_dup 2)))]
7058 "ix86_match_ccmode (insn, CCGOCmode)
7059 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7060 "sub{l}\t{%2, %0|%0, %2}"
7061 [(set_attr "type" "alu")
7062 (set_attr "mode" "SI")])
7063
7064(define_insn "*subsi_2_zext"
7065 [(set (reg 17)
7066 (compare
7067 (minus:SI (match_operand:SI 1 "register_operand" "0")
7068 (match_operand:SI 2 "general_operand" "rim"))
7069 (const_int 0)))
7070 (set (match_operand:DI 0 "register_operand" "=r")
7071 (zero_extend:DI
7072 (minus:SI (match_dup 1)
7073 (match_dup 2))))]
7074 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7075 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7076 "sub{l}\t{%2, %k0|%k0, %2}"
7077 [(set_attr "type" "alu")
7078 (set_attr "mode" "SI")])
7079
7080(define_insn "*subsi_3"
7081 [(set (reg 17)
7082 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7083 (match_operand:SI 2 "general_operand" "ri,rm")))
7084 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7085 (minus:SI (match_dup 1) (match_dup 2)))]
7086 "ix86_match_ccmode (insn, CCmode)
7087 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7088 "sub{l}\t{%2, %0|%0, %2}"
7089 [(set_attr "type" "alu")
7090 (set_attr "mode" "SI")])
7091
7092(define_insn "*subsi_3_zext"
7093 [(set (reg 17)
7094 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7095 (match_operand:SI 2 "general_operand" "rim")))
7096 (set (match_operand:DI 0 "register_operand" "=r")
7097 (zero_extend:DI
7098 (minus:SI (match_dup 1)
7099 (match_dup 2))))]
7100 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7101 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7102 "sub{q}\t{%2, %0|%0, %2}"
7103 [(set_attr "type" "alu")
7104 (set_attr "mode" "DI")])
7105
7106(define_expand "subhi3"
7107 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7108 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7109 (match_operand:HI 2 "general_operand" "")))
7110 (clobber (reg:CC 17))])]
7111 "TARGET_HIMODE_MATH"
7112 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7113
7114(define_insn "*subhi_1"
7115 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7116 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7117 (match_operand:HI 2 "general_operand" "ri,rm")))
7118 (clobber (reg:CC 17))]
7119 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7120 "sub{w}\t{%2, %0|%0, %2}"
7121 [(set_attr "type" "alu")
7122 (set_attr "mode" "HI")])
7123
7124(define_insn "*subhi_2"
7125 [(set (reg 17)
7126 (compare
7127 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7128 (match_operand:HI 2 "general_operand" "ri,rm"))
7129 (const_int 0)))
7130 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7131 (minus:HI (match_dup 1) (match_dup 2)))]
7132 "ix86_match_ccmode (insn, CCGOCmode)
7133 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7134 "sub{w}\t{%2, %0|%0, %2}"
7135 [(set_attr "type" "alu")
7136 (set_attr "mode" "HI")])
7137
7138(define_insn "*subhi_3"
7139 [(set (reg 17)
7140 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7141 (match_operand:HI 2 "general_operand" "ri,rm")))
7142 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7143 (minus:HI (match_dup 1) (match_dup 2)))]
7144 "ix86_match_ccmode (insn, CCmode)
7145 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7146 "sub{w}\t{%2, %0|%0, %2}"
7147 [(set_attr "type" "alu")
7148 (set_attr "mode" "HI")])
7149
7150(define_expand "subqi3"
7151 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7152 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7153 (match_operand:QI 2 "general_operand" "")))
7154 (clobber (reg:CC 17))])]
7155 "TARGET_QIMODE_MATH"
7156 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7157
7158(define_insn "*subqi_1"
7159 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7160 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7161 (match_operand:QI 2 "general_operand" "qn,qmn")))
7162 (clobber (reg:CC 17))]
7163 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7164 "sub{b}\t{%2, %0|%0, %2}"
7165 [(set_attr "type" "alu")
7166 (set_attr "mode" "QI")])
7167
7168(define_insn "*subqi_2"
7169 [(set (reg 17)
7170 (compare
7171 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7172 (match_operand:QI 2 "general_operand" "qi,qm"))
7173 (const_int 0)))
7174 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7175 (minus:HI (match_dup 1) (match_dup 2)))]
7176 "ix86_match_ccmode (insn, CCGOCmode)
7177 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7178 "sub{b}\t{%2, %0|%0, %2}"
7179 [(set_attr "type" "alu")
7180 (set_attr "mode" "QI")])
7181
7182(define_insn "*subqi_3"
7183 [(set (reg 17)
7184 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7185 (match_operand:QI 2 "general_operand" "qi,qm")))
7186 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7187 (minus:HI (match_dup 1) (match_dup 2)))]
7188 "ix86_match_ccmode (insn, CCmode)
7189 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7190 "sub{b}\t{%2, %0|%0, %2}"
7191 [(set_attr "type" "alu")
7192 (set_attr "mode" "QI")])
7193
7194;; The patterns that match these are at the end of this file.
7195
7196(define_expand "subxf3"
7197 [(set (match_operand:XF 0 "register_operand" "")
7198 (minus:XF (match_operand:XF 1 "register_operand" "")
7199 (match_operand:XF 2 "register_operand" "")))]
7200 "!TARGET_64BIT && TARGET_80387"
7201 "")
7202
7203(define_expand "subtf3"
7204 [(set (match_operand:TF 0 "register_operand" "")
7205 (minus:TF (match_operand:TF 1 "register_operand" "")
7206 (match_operand:TF 2 "register_operand" "")))]
7207 "TARGET_80387"
7208 "")
7209
7210(define_expand "subdf3"
7211 [(set (match_operand:DF 0 "register_operand" "")
7212 (minus:DF (match_operand:DF 1 "register_operand" "")
7213 (match_operand:DF 2 "nonimmediate_operand" "")))]
7214 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7215 "")
7216
7217(define_expand "subsf3"
7218 [(set (match_operand:SF 0 "register_operand" "")
7219 (minus:SF (match_operand:SF 1 "register_operand" "")
7220 (match_operand:SF 2 "nonimmediate_operand" "")))]
7221 "TARGET_80387 || TARGET_SSE_MATH"
7222 "")
7223
7224;; Multiply instructions
7225
7226(define_expand "muldi3"
7227 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7228 (mult:DI (match_operand:DI 1 "register_operand" "")
7229 (match_operand:DI 2 "x86_64_general_operand" "")))
7230 (clobber (reg:CC 17))])]
7231 "TARGET_64BIT"
7232 "")
7233
7234(define_insn "*muldi3_1_rex64"
7235 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7236 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
7237 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7238 (clobber (reg:CC 17))]
7239 "TARGET_64BIT
7240 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7241 "@
7242 imul{q}\t{%2, %1, %0|%0, %1, %2}
7243 imul{q}\t{%2, %1, %0|%0, %1, %2}
7244 imul{q}\t{%2, %0|%0, %2}"
7245 [(set_attr "type" "imul")
7246 (set_attr "prefix_0f" "0,0,1")
7247 (set_attr "mode" "DI")])
7248
7249(define_expand "mulsi3"
7250 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7251 (mult:SI (match_operand:SI 1 "register_operand" "")
7252 (match_operand:SI 2 "general_operand" "")))
7253 (clobber (reg:CC 17))])]
7254 ""
7255 "")
7256
7257(define_insn "*mulsi3_1"
7258 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7259 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7260 (match_operand:SI 2 "general_operand" "K,i,mr")))
7261 (clobber (reg:CC 17))]
7262 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7263 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7264 ; there are two ways of writing the exact same machine instruction
7265 ; in assembly language. One, for example, is:
7266 ;
7267 ; imul $12, %eax
7268 ;
7269 ; while the other is:
7270 ;
7271 ; imul $12, %eax, %eax
7272 ;
7273 ; The first is simply short-hand for the latter. But, some assemblers,
7274 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7275 "@
7276 imul{l}\t{%2, %1, %0|%0, %1, %2}
7277 imul{l}\t{%2, %1, %0|%0, %1, %2}
7278 imul{l}\t{%2, %0|%0, %2}"
7279 [(set_attr "type" "imul")
7280 (set_attr "prefix_0f" "0,0,1")
7281 (set_attr "mode" "SI")])
7282
7283(define_insn "*mulsi3_1_zext"
7284 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7285 (zero_extend:DI
7286 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7287 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7288 (clobber (reg:CC 17))]
7289 "TARGET_64BIT
7290 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7291 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7292 ; there are two ways of writing the exact same machine instruction
7293 ; in assembly language. One, for example, is:
7294 ;
7295 ; imul $12, %eax
7296 ;
7297 ; while the other is:
7298 ;
7299 ; imul $12, %eax, %eax
7300 ;
7301 ; The first is simply short-hand for the latter. But, some assemblers,
7302 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7303 "@
7304 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7305 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7306 imul{l}\t{%2, %k0|%k0, %2}"
7307 [(set_attr "type" "imul")
7308 (set_attr "prefix_0f" "0,0,1")
7309 (set_attr "mode" "SI")])
7310
7311(define_expand "mulhi3"
7312 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7313 (mult:HI (match_operand:HI 1 "register_operand" "")
7314 (match_operand:HI 2 "general_operand" "")))
7315 (clobber (reg:CC 17))])]
7316 "TARGET_HIMODE_MATH"
7317 "")
7318
7319(define_insn "*mulhi3_1"
7320 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7321 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
7322 (match_operand:HI 2 "general_operand" "K,i,mr")))
7323 (clobber (reg:CC 17))]
7324 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7325 ; %%% There was a note about "Assembler has weird restrictions",
7326 ; concerning alternative 1 when op1 == op0. True?
7327 "@
7328 imul{w}\t{%2, %1, %0|%0, %1, %2}
7329 imul{w}\t{%2, %1, %0|%0, %1, %2}
7330 imul{w}\t{%2, %0|%0, %2}"
7331 [(set_attr "type" "imul")
7332 (set_attr "prefix_0f" "0,0,1")
7333 (set_attr "mode" "HI")])
7334
5155 "")
5156
5157(define_insn "*floatsidf2_i387"
5158 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5159 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5160 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5161 "@
5162 fild%z1\t%1
5163 #
5164 cvtsi2sd\t{%1, %0|%0, %1}"
5165 [(set_attr "type" "fmov,multi,sse")
5166 (set_attr "mode" "DF")
5167 (set_attr "fp_int_src" "true")])
5168
5169(define_insn "*floatsidf2_sse"
5170 [(set (match_operand:DF 0 "register_operand" "=Y")
5171 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5172 "TARGET_SSE2"
5173 "cvtsi2sd\t{%1, %0|%0, %1}"
5174 [(set_attr "type" "sse")
5175 (set_attr "mode" "DF")
5176 (set_attr "fp_int_src" "true")])
5177
5178(define_expand "floatdidf2"
5179 [(set (match_operand:DF 0 "register_operand" "")
5180 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5181 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5182 "")
5183
5184(define_insn "*floatdidf2_i387_only"
5185 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5186 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5187 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5188 "@
5189 fild%z1\t%1
5190 #"
5191 [(set_attr "type" "fmov,multi")
5192 (set_attr "mode" "DF")
5193 (set_attr "fp_int_src" "true")])
5194
5195(define_insn "*floatdidf2_i387"
5196 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5197 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5198 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5199 "@
5200 fild%z1\t%1
5201 #
5202 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5203 [(set_attr "type" "fmov,multi,sse")
5204 (set_attr "mode" "DF")
5205 (set_attr "fp_int_src" "true")])
5206
5207(define_insn "*floatdidf2_sse"
5208 [(set (match_operand:DF 0 "register_operand" "=Y")
5209 (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5210 "TARGET_SSE2"
5211 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5212 [(set_attr "type" "sse")
5213 (set_attr "mode" "DF")
5214 (set_attr "fp_int_src" "true")])
5215
5216(define_insn "floathixf2"
5217 [(set (match_operand:XF 0 "register_operand" "=f,f")
5218 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5219 "!TARGET_64BIT && TARGET_80387"
5220 "@
5221 fild%z1\t%1
5222 #"
5223 [(set_attr "type" "fmov,multi")
5224 (set_attr "mode" "XF")
5225 (set_attr "fp_int_src" "true")])
5226
5227(define_insn "floathitf2"
5228 [(set (match_operand:TF 0 "register_operand" "=f,f")
5229 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5230 "TARGET_80387"
5231 "@
5232 fild%z1\t%1
5233 #"
5234 [(set_attr "type" "fmov,multi")
5235 (set_attr "mode" "XF")
5236 (set_attr "fp_int_src" "true")])
5237
5238(define_insn "floatsixf2"
5239 [(set (match_operand:XF 0 "register_operand" "=f,f")
5240 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5241 "!TARGET_64BIT && TARGET_80387"
5242 "@
5243 fild%z1\t%1
5244 #"
5245 [(set_attr "type" "fmov,multi")
5246 (set_attr "mode" "XF")
5247 (set_attr "fp_int_src" "true")])
5248
5249(define_insn "floatsitf2"
5250 [(set (match_operand:TF 0 "register_operand" "=f,f")
5251 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5252 "TARGET_80387"
5253 "@
5254 fild%z1\t%1
5255 #"
5256 [(set_attr "type" "fmov,multi")
5257 (set_attr "mode" "XF")
5258 (set_attr "fp_int_src" "true")])
5259
5260(define_insn "floatdixf2"
5261 [(set (match_operand:XF 0 "register_operand" "=f,f")
5262 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5263 "!TARGET_64BIT && TARGET_80387"
5264 "@
5265 fild%z1\t%1
5266 #"
5267 [(set_attr "type" "fmov,multi")
5268 (set_attr "mode" "XF")
5269 (set_attr "fp_int_src" "true")])
5270
5271(define_insn "floatditf2"
5272 [(set (match_operand:TF 0 "register_operand" "=f,f")
5273 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5274 "TARGET_80387"
5275 "@
5276 fild%z1\t%1
5277 #"
5278 [(set_attr "type" "fmov,multi")
5279 (set_attr "mode" "XF")
5280 (set_attr "fp_int_src" "true")])
5281
5282;; %%% Kill these when reload knows how to do it.
5283(define_split
5284 [(set (match_operand 0 "register_operand" "")
5285 (float (match_operand 1 "register_operand" "")))]
5286 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
5287 && FP_REG_P (operands[0])"
5288 [(const_int 0)]
5289{
5290 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5291 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5292 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5293 ix86_free_from_memory (GET_MODE (operands[1]));
5294 DONE;
5295})
5296
5297;; Add instructions
5298
5299;; %%% splits for addsidi3
5300; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5301; (plus:DI (match_operand:DI 1 "general_operand" "")
5302; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5303
5304(define_expand "adddi3"
5305 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5306 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5307 (match_operand:DI 2 "x86_64_general_operand" "")))
5308 (clobber (reg:CC 17))]
5309 ""
5310 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5311
5312(define_insn "*adddi3_1"
5313 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5314 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5315 (match_operand:DI 2 "general_operand" "roiF,riF")))
5316 (clobber (reg:CC 17))]
5317 "!TARGET_64BIT"
5318 "#")
5319
5320(define_split
5321 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5322 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5323 (match_operand:DI 2 "general_operand" "")))
5324 (clobber (reg:CC 17))]
5325 "!TARGET_64BIT && reload_completed"
5326 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
5327 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5328 (parallel [(set (match_dup 3)
5329 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5330 (match_dup 4))
5331 (match_dup 5)))
5332 (clobber (reg:CC 17))])]
5333 "split_di (operands+0, 1, operands+0, operands+3);
5334 split_di (operands+1, 1, operands+1, operands+4);
5335 split_di (operands+2, 1, operands+2, operands+5);")
5336
5337(define_insn "*adddi3_carry_rex64"
5338 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5339 (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
5340 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5341 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5342 (clobber (reg:CC 17))]
5343 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5344 "adc{q}\t{%2, %0|%0, %2}"
5345 [(set_attr "type" "alu")
5346 (set_attr "pent_pair" "pu")
5347 (set_attr "mode" "DI")
5348 (set_attr "ppro_uops" "few")])
5349
5350(define_insn "*adddi3_cc_rex64"
5351 [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5352 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
5353 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5354 (plus:DI (match_dup 1) (match_dup 2)))]
5355 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5356 "add{q}\t{%2, %0|%0, %2}"
5357 [(set_attr "type" "alu")
5358 (set_attr "mode" "DI")])
5359
5360(define_insn "*addsi3_carry"
5361 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5362 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5363 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5364 (match_operand:SI 2 "general_operand" "ri,rm")))
5365 (clobber (reg:CC 17))]
5366 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5367 "adc{l}\t{%2, %0|%0, %2}"
5368 [(set_attr "type" "alu")
5369 (set_attr "pent_pair" "pu")
5370 (set_attr "mode" "SI")
5371 (set_attr "ppro_uops" "few")])
5372
5373(define_insn "*addsi3_carry_zext"
5374 [(set (match_operand:DI 0 "register_operand" "=r")
5375 (zero_extend:DI
5376 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5377 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5378 (match_operand:SI 2 "general_operand" "rim"))))
5379 (clobber (reg:CC 17))]
5380 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5381 "adc{l}\t{%2, %k0|%k0, %2}"
5382 [(set_attr "type" "alu")
5383 (set_attr "pent_pair" "pu")
5384 (set_attr "mode" "SI")
5385 (set_attr "ppro_uops" "few")])
5386
5387(define_insn "*addsi3_cc"
5388 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5389 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
5390 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5391 (plus:SI (match_dup 1) (match_dup 2)))]
5392 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5393 "add{l}\t{%2, %0|%0, %2}"
5394 [(set_attr "type" "alu")
5395 (set_attr "mode" "SI")])
5396
5397(define_insn "addqi3_cc"
5398 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5399 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
5400 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5401 (plus:QI (match_dup 1) (match_dup 2)))]
5402 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5403 "add{b}\t{%2, %0|%0, %2}"
5404 [(set_attr "type" "alu")
5405 (set_attr "mode" "QI")])
5406
5407(define_expand "addsi3"
5408 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5409 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5410 (match_operand:SI 2 "general_operand" "")))
5411 (clobber (reg:CC 17))])]
5412 ""
5413 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5414
5415(define_insn "*lea_1"
5416 [(set (match_operand:SI 0 "register_operand" "=r")
5417 (match_operand:SI 1 "address_operand" "p"))]
5418 "!TARGET_64BIT"
5419 "lea{l}\t{%a1, %0|%0, %a1}"
5420 [(set_attr "type" "lea")
5421 (set_attr "mode" "SI")])
5422
5423(define_insn "*lea_1_rex64"
5424 [(set (match_operand:SI 0 "register_operand" "=r")
5425 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5426 "TARGET_64BIT"
5427 "lea{l}\t{%a1, %0|%0, %a1}"
5428 [(set_attr "type" "lea")
5429 (set_attr "mode" "SI")])
5430
5431(define_insn "*lea_1_zext"
5432 [(set (match_operand:DI 0 "register_operand" "=r")
5433 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5434 "TARGET_64BIT"
5435 "lea{l}\t{%a1, %k0|%k0, %a1}"
5436 [(set_attr "type" "lea")
5437 (set_attr "mode" "SI")])
5438
5439(define_insn "*lea_2_rex64"
5440 [(set (match_operand:DI 0 "register_operand" "=r")
5441 (match_operand:DI 1 "address_operand" "p"))]
5442 "TARGET_64BIT"
5443 "lea{q}\t{%a1, %0|%0, %a1}"
5444 [(set_attr "type" "lea")
5445 (set_attr "mode" "DI")])
5446
5447;; The lea patterns for non-Pmodes needs to be matched by several
5448;; insns converted to real lea by splitters.
5449
5450(define_insn_and_split "*lea_general_1"
5451 [(set (match_operand 0 "register_operand" "=r")
5452 (plus (plus (match_operand 1 "register_operand" "r")
5453 (match_operand 2 "register_operand" "r"))
5454 (match_operand 3 "immediate_operand" "i")))]
5455 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5456 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5457 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5458 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5459 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5460 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5461 || GET_MODE (operands[3]) == VOIDmode)"
5462 "#"
5463 "&& reload_completed"
5464 [(const_int 0)]
5465{
5466 rtx pat;
5467 operands[0] = gen_lowpart (SImode, operands[0]);
5468 operands[1] = gen_lowpart (Pmode, operands[1]);
5469 operands[2] = gen_lowpart (Pmode, operands[2]);
5470 operands[3] = gen_lowpart (Pmode, operands[3]);
5471 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5472 operands[3]);
5473 if (Pmode != SImode)
5474 pat = gen_rtx_SUBREG (SImode, pat, 0);
5475 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5476 DONE;
5477}
5478 [(set_attr "type" "lea")
5479 (set_attr "mode" "SI")])
5480
5481(define_insn_and_split "*lea_general_1_zext"
5482 [(set (match_operand:DI 0 "register_operand" "=r")
5483 (zero_extend:DI
5484 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5485 (match_operand:SI 2 "register_operand" "r"))
5486 (match_operand:SI 3 "immediate_operand" "i"))))]
5487 "TARGET_64BIT"
5488 "#"
5489 "&& reload_completed"
5490 [(set (match_dup 0)
5491 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5492 (match_dup 2))
5493 (match_dup 3)) 0)))]
5494{
5495 operands[1] = gen_lowpart (Pmode, operands[1]);
5496 operands[2] = gen_lowpart (Pmode, operands[2]);
5497 operands[3] = gen_lowpart (Pmode, operands[3]);
5498}
5499 [(set_attr "type" "lea")
5500 (set_attr "mode" "SI")])
5501
5502(define_insn_and_split "*lea_general_2"
5503 [(set (match_operand 0 "register_operand" "=r")
5504 (plus (mult (match_operand 1 "register_operand" "r")
5505 (match_operand 2 "const248_operand" "i"))
5506 (match_operand 3 "nonmemory_operand" "ri")))]
5507 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5508 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5509 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5510 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5511 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5512 || GET_MODE (operands[3]) == VOIDmode)"
5513 "#"
5514 "&& reload_completed"
5515 [(const_int 0)]
5516{
5517 rtx pat;
5518 operands[0] = gen_lowpart (SImode, operands[0]);
5519 operands[1] = gen_lowpart (Pmode, operands[1]);
5520 operands[3] = gen_lowpart (Pmode, operands[3]);
5521 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5522 operands[3]);
5523 if (Pmode != SImode)
5524 pat = gen_rtx_SUBREG (SImode, pat, 0);
5525 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5526 DONE;
5527}
5528 [(set_attr "type" "lea")
5529 (set_attr "mode" "SI")])
5530
5531(define_insn_and_split "*lea_general_2_zext"
5532 [(set (match_operand:DI 0 "register_operand" "=r")
5533 (zero_extend:DI
5534 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5535 (match_operand:SI 2 "const248_operand" "n"))
5536 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5537 "TARGET_64BIT"
5538 "#"
5539 "&& reload_completed"
5540 [(set (match_dup 0)
5541 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5542 (match_dup 2))
5543 (match_dup 3)) 0)))]
5544{
5545 operands[1] = gen_lowpart (Pmode, operands[1]);
5546 operands[3] = gen_lowpart (Pmode, operands[3]);
5547}
5548 [(set_attr "type" "lea")
5549 (set_attr "mode" "SI")])
5550
5551(define_insn_and_split "*lea_general_3"
5552 [(set (match_operand 0 "register_operand" "=r")
5553 (plus (plus (mult (match_operand 1 "register_operand" "r")
5554 (match_operand 2 "const248_operand" "i"))
5555 (match_operand 3 "register_operand" "r"))
5556 (match_operand 4 "immediate_operand" "i")))]
5557 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5558 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5559 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5560 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5561 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5562 "#"
5563 "&& reload_completed"
5564 [(const_int 0)]
5565{
5566 rtx pat;
5567 operands[0] = gen_lowpart (SImode, operands[0]);
5568 operands[1] = gen_lowpart (Pmode, operands[1]);
5569 operands[3] = gen_lowpart (Pmode, operands[3]);
5570 operands[4] = gen_lowpart (Pmode, operands[4]);
5571 pat = gen_rtx_PLUS (Pmode,
5572 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5573 operands[2]),
5574 operands[3]),
5575 operands[4]);
5576 if (Pmode != SImode)
5577 pat = gen_rtx_SUBREG (SImode, pat, 0);
5578 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5579 DONE;
5580}
5581 [(set_attr "type" "lea")
5582 (set_attr "mode" "SI")])
5583
5584(define_insn_and_split "*lea_general_3_zext"
5585 [(set (match_operand:DI 0 "register_operand" "=r")
5586 (zero_extend:DI
5587 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5588 (match_operand:SI 2 "const248_operand" "n"))
5589 (match_operand:SI 3 "register_operand" "r"))
5590 (match_operand:SI 4 "immediate_operand" "i"))))]
5591 "TARGET_64BIT"
5592 "#"
5593 "&& reload_completed"
5594 [(set (match_dup 0)
5595 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5596 (match_dup 2))
5597 (match_dup 3))
5598 (match_dup 4)) 0)))]
5599{
5600 operands[1] = gen_lowpart (Pmode, operands[1]);
5601 operands[3] = gen_lowpart (Pmode, operands[3]);
5602 operands[4] = gen_lowpart (Pmode, operands[4]);
5603}
5604 [(set_attr "type" "lea")
5605 (set_attr "mode" "SI")])
5606
5607(define_insn "*adddi_1_rex64"
5608 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5609 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5610 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5611 (clobber (reg:CC 17))]
5612 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5613{
5614 switch (get_attr_type (insn))
5615 {
5616 case TYPE_LEA:
5617 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5618 return "lea{q}\t{%a2, %0|%0, %a2}";
5619
5620 case TYPE_INCDEC:
5621 if (! rtx_equal_p (operands[0], operands[1]))
5622 abort ();
5623 if (operands[2] == const1_rtx)
5624 return "inc{q}\t%0";
5625 else if (operands[2] == constm1_rtx)
5626 return "dec{q}\t%0";
5627 else
5628 abort ();
5629
5630 default:
5631 if (! rtx_equal_p (operands[0], operands[1]))
5632 abort ();
5633
5634 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5635 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5636 if (GET_CODE (operands[2]) == CONST_INT
5637 /* Avoid overflows. */
5638 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5639 && (INTVAL (operands[2]) == 128
5640 || (INTVAL (operands[2]) < 0
5641 && INTVAL (operands[2]) != -128)))
5642 {
5643 operands[2] = GEN_INT (-INTVAL (operands[2]));
5644 return "sub{q}\t{%2, %0|%0, %2}";
5645 }
5646 return "add{q}\t{%2, %0|%0, %2}";
5647 }
5648}
5649 [(set (attr "type")
5650 (cond [(eq_attr "alternative" "2")
5651 (const_string "lea")
5652 ; Current assemblers are broken and do not allow @GOTOFF in
5653 ; ought but a memory context.
5654 (match_operand:DI 2 "pic_symbolic_operand" "")
5655 (const_string "lea")
5656 (match_operand:DI 2 "incdec_operand" "")
5657 (const_string "incdec")
5658 ]
5659 (const_string "alu")))
5660 (set_attr "mode" "DI")])
5661
5662;; Convert lea to the lea pattern to avoid flags dependency.
5663(define_split
5664 [(set (match_operand:DI 0 "register_operand" "")
5665 (plus:DI (match_operand:DI 1 "register_operand" "")
5666 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5667 (clobber (reg:CC 17))]
5668 "TARGET_64BIT && reload_completed
5669 && true_regnum (operands[0]) != true_regnum (operands[1])"
5670 [(set (match_dup 0)
5671 (plus:DI (match_dup 1)
5672 (match_dup 2)))]
5673 "")
5674
5675(define_insn "*adddi_2_rex64"
5676 [(set (reg 17)
5677 (compare
5678 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5679 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5680 (const_int 0)))
5681 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5682 (plus:DI (match_dup 1) (match_dup 2)))]
5683 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5684 && ix86_binary_operator_ok (PLUS, DImode, operands)
5685 /* Current assemblers are broken and do not allow @GOTOFF in
5686 ought but a memory context. */
5687 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5688{
5689 switch (get_attr_type (insn))
5690 {
5691 case TYPE_INCDEC:
5692 if (! rtx_equal_p (operands[0], operands[1]))
5693 abort ();
5694 if (operands[2] == const1_rtx)
5695 return "inc{q}\t%0";
5696 else if (operands[2] == constm1_rtx)
5697 return "dec{q}\t%0";
5698 else
5699 abort ();
5700
5701 default:
5702 if (! rtx_equal_p (operands[0], operands[1]))
5703 abort ();
5704 /* ???? We ought to handle there the 32bit case too
5705 - do we need new constrant? */
5706 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5707 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5708 if (GET_CODE (operands[2]) == CONST_INT
5709 /* Avoid overflows. */
5710 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5711 && (INTVAL (operands[2]) == 128
5712 || (INTVAL (operands[2]) < 0
5713 && INTVAL (operands[2]) != -128)))
5714 {
5715 operands[2] = GEN_INT (-INTVAL (operands[2]));
5716 return "sub{q}\t{%2, %0|%0, %2}";
5717 }
5718 return "add{q}\t{%2, %0|%0, %2}";
5719 }
5720}
5721 [(set (attr "type")
5722 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5723 (const_string "incdec")
5724 (const_string "alu")))
5725 (set_attr "mode" "DI")])
5726
5727(define_insn "*adddi_3_rex64"
5728 [(set (reg 17)
5729 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5730 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5731 (clobber (match_scratch:DI 0 "=r"))]
5732 "TARGET_64BIT
5733 && ix86_match_ccmode (insn, CCZmode)
5734 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5735 /* Current assemblers are broken and do not allow @GOTOFF in
5736 ought but a memory context. */
5737 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5738{
5739 switch (get_attr_type (insn))
5740 {
5741 case TYPE_INCDEC:
5742 if (! rtx_equal_p (operands[0], operands[1]))
5743 abort ();
5744 if (operands[2] == const1_rtx)
5745 return "inc{q}\t%0";
5746 else if (operands[2] == constm1_rtx)
5747 return "dec{q}\t%0";
5748 else
5749 abort ();
5750
5751 default:
5752 if (! rtx_equal_p (operands[0], operands[1]))
5753 abort ();
5754 /* ???? We ought to handle there the 32bit case too
5755 - do we need new constrant? */
5756 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5757 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5758 if (GET_CODE (operands[2]) == CONST_INT
5759 /* Avoid overflows. */
5760 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5761 && (INTVAL (operands[2]) == 128
5762 || (INTVAL (operands[2]) < 0
5763 && INTVAL (operands[2]) != -128)))
5764 {
5765 operands[2] = GEN_INT (-INTVAL (operands[2]));
5766 return "sub{q}\t{%2, %0|%0, %2}";
5767 }
5768 return "add{q}\t{%2, %0|%0, %2}";
5769 }
5770}
5771 [(set (attr "type")
5772 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5773 (const_string "incdec")
5774 (const_string "alu")))
5775 (set_attr "mode" "DI")])
5776
5777; For comparisons against 1, -1 and 128, we may generate better code
5778; by converting cmp to add, inc or dec as done by peephole2. This pattern
5779; is matched then. We can't accept general immediate, because for
5780; case of overflows, the result is messed up.
5781; This pattern also don't hold of 0x8000000000000000, since the value overflows
5782; when negated.
5783; Also carry flag is reversed compared to cmp, so this conversion is valid
5784; only for comparisons not depending on it.
5785(define_insn "*adddi_4_rex64"
5786 [(set (reg 17)
5787 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5788 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5789 (clobber (match_scratch:DI 0 "=rm"))]
5790 "TARGET_64BIT
5791 && ix86_match_ccmode (insn, CCGCmode)"
5792{
5793 switch (get_attr_type (insn))
5794 {
5795 case TYPE_INCDEC:
5796 if (operands[2] == constm1_rtx)
5797 return "inc{q}\t%0";
5798 else if (operands[2] == const1_rtx)
5799 return "dec{q}\t%0";
5800 else
5801 abort();
5802
5803 default:
5804 if (! rtx_equal_p (operands[0], operands[1]))
5805 abort ();
5806 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5807 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5808 if ((INTVAL (operands[2]) == -128
5809 || (INTVAL (operands[2]) > 0
5810 && INTVAL (operands[2]) != 128))
5811 /* Avoid overflows. */
5812 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5813 return "sub{q}\t{%2, %0|%0, %2}";
5814 operands[2] = GEN_INT (-INTVAL (operands[2]));
5815 return "add{q}\t{%2, %0|%0, %2}";
5816 }
5817}
5818 [(set (attr "type")
5819 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5820 (const_string "incdec")
5821 (const_string "alu")))
5822 (set_attr "mode" "DI")])
5823
5824(define_insn "*adddi_5_rex64"
5825 [(set (reg 17)
5826 (compare
5827 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5828 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5829 (const_int 0)))
5830 (clobber (match_scratch:DI 0 "=r"))]
5831 "TARGET_64BIT
5832 && ix86_match_ccmode (insn, CCGOCmode)
5833 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5834 /* Current assemblers are broken and do not allow @GOTOFF in
5835 ought but a memory context. */
5836 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5837{
5838 switch (get_attr_type (insn))
5839 {
5840 case TYPE_INCDEC:
5841 if (! rtx_equal_p (operands[0], operands[1]))
5842 abort ();
5843 if (operands[2] == const1_rtx)
5844 return "inc{q}\t%0";
5845 else if (operands[2] == constm1_rtx)
5846 return "dec{q}\t%0";
5847 else
5848 abort();
5849
5850 default:
5851 if (! rtx_equal_p (operands[0], operands[1]))
5852 abort ();
5853 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5854 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5855 if (GET_CODE (operands[2]) == CONST_INT
5856 /* Avoid overflows. */
5857 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5858 && (INTVAL (operands[2]) == 128
5859 || (INTVAL (operands[2]) < 0
5860 && INTVAL (operands[2]) != -128)))
5861 {
5862 operands[2] = GEN_INT (-INTVAL (operands[2]));
5863 return "sub{q}\t{%2, %0|%0, %2}";
5864 }
5865 return "add{q}\t{%2, %0|%0, %2}";
5866 }
5867}
5868 [(set (attr "type")
5869 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5870 (const_string "incdec")
5871 (const_string "alu")))
5872 (set_attr "mode" "DI")])
5873
5874
5875(define_insn "*addsi_1"
5876 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5877 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5878 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5879 (clobber (reg:CC 17))]
5880 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5881{
5882 switch (get_attr_type (insn))
5883 {
5884 case TYPE_LEA:
5885 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5886 return "lea{l}\t{%a2, %0|%0, %a2}";
5887
5888 case TYPE_INCDEC:
5889 if (! rtx_equal_p (operands[0], operands[1]))
5890 abort ();
5891 if (operands[2] == const1_rtx)
5892 return "inc{l}\t%0";
5893 else if (operands[2] == constm1_rtx)
5894 return "dec{l}\t%0";
5895 else
5896 abort();
5897
5898 default:
5899 if (! rtx_equal_p (operands[0], operands[1]))
5900 abort ();
5901
5902 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5903 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5904 if (GET_CODE (operands[2]) == CONST_INT
5905 && (INTVAL (operands[2]) == 128
5906 || (INTVAL (operands[2]) < 0
5907 && INTVAL (operands[2]) != -128)))
5908 {
5909 operands[2] = GEN_INT (-INTVAL (operands[2]));
5910 return "sub{l}\t{%2, %0|%0, %2}";
5911 }
5912 return "add{l}\t{%2, %0|%0, %2}";
5913 }
5914}
5915 [(set (attr "type")
5916 (cond [(eq_attr "alternative" "2")
5917 (const_string "lea")
5918 ; Current assemblers are broken and do not allow @GOTOFF in
5919 ; ought but a memory context.
5920 (match_operand:SI 2 "pic_symbolic_operand" "")
5921 (const_string "lea")
5922 (match_operand:SI 2 "incdec_operand" "")
5923 (const_string "incdec")
5924 ]
5925 (const_string "alu")))
5926 (set_attr "mode" "SI")])
5927
5928;; Convert lea to the lea pattern to avoid flags dependency.
5929(define_split
5930 [(set (match_operand 0 "register_operand" "")
5931 (plus (match_operand 1 "register_operand" "")
5932 (match_operand 2 "nonmemory_operand" "")))
5933 (clobber (reg:CC 17))]
5934 "reload_completed
5935 && true_regnum (operands[0]) != true_regnum (operands[1])"
5936 [(const_int 0)]
5937{
5938 rtx pat;
5939 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5940 may confuse gen_lowpart. */
5941 if (GET_MODE (operands[0]) != Pmode)
5942 {
5943 operands[1] = gen_lowpart (Pmode, operands[1]);
5944 operands[2] = gen_lowpart (Pmode, operands[2]);
5945 }
5946 operands[0] = gen_lowpart (SImode, operands[0]);
5947 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5948 if (Pmode != SImode)
5949 pat = gen_rtx_SUBREG (SImode, pat, 0);
5950 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5951 DONE;
5952})
5953
5954;; It may seem that nonimmediate operand is proper one for operand 1.
5955;; The addsi_1 pattern allows nonimmediate operand at that place and
5956;; we take care in ix86_binary_operator_ok to not allow two memory
5957;; operands so proper swapping will be done in reload. This allow
5958;; patterns constructed from addsi_1 to match.
5959(define_insn "addsi_1_zext"
5960 [(set (match_operand:DI 0 "register_operand" "=r,r")
5961 (zero_extend:DI
5962 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5963 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5964 (clobber (reg:CC 17))]
5965 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5966{
5967 switch (get_attr_type (insn))
5968 {
5969 case TYPE_LEA:
5970 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5971 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5972
5973 case TYPE_INCDEC:
5974 if (operands[2] == const1_rtx)
5975 return "inc{l}\t%k0";
5976 else if (operands[2] == constm1_rtx)
5977 return "dec{l}\t%k0";
5978 else
5979 abort();
5980
5981 default:
5982 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5983 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5984 if (GET_CODE (operands[2]) == CONST_INT
5985 && (INTVAL (operands[2]) == 128
5986 || (INTVAL (operands[2]) < 0
5987 && INTVAL (operands[2]) != -128)))
5988 {
5989 operands[2] = GEN_INT (-INTVAL (operands[2]));
5990 return "sub{l}\t{%2, %k0|%k0, %2}";
5991 }
5992 return "add{l}\t{%2, %k0|%k0, %2}";
5993 }
5994}
5995 [(set (attr "type")
5996 (cond [(eq_attr "alternative" "1")
5997 (const_string "lea")
5998 ; Current assemblers are broken and do not allow @GOTOFF in
5999 ; ought but a memory context.
6000 (match_operand:SI 2 "pic_symbolic_operand" "")
6001 (const_string "lea")
6002 (match_operand:SI 2 "incdec_operand" "")
6003 (const_string "incdec")
6004 ]
6005 (const_string "alu")))
6006 (set_attr "mode" "SI")])
6007
6008;; Convert lea to the lea pattern to avoid flags dependency.
6009(define_split
6010 [(set (match_operand:DI 0 "register_operand" "")
6011 (zero_extend:DI
6012 (plus:SI (match_operand:SI 1 "register_operand" "")
6013 (match_operand:SI 2 "nonmemory_operand" ""))))
6014 (clobber (reg:CC 17))]
6015 "reload_completed
6016 && true_regnum (operands[0]) != true_regnum (operands[1])"
6017 [(set (match_dup 0)
6018 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6019{
6020 operands[1] = gen_lowpart (Pmode, operands[1]);
6021 operands[2] = gen_lowpart (Pmode, operands[2]);
6022})
6023
6024(define_insn "*addsi_2"
6025 [(set (reg 17)
6026 (compare
6027 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6028 (match_operand:SI 2 "general_operand" "rmni,rni"))
6029 (const_int 0)))
6030 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6031 (plus:SI (match_dup 1) (match_dup 2)))]
6032 "ix86_match_ccmode (insn, CCGOCmode)
6033 && ix86_binary_operator_ok (PLUS, SImode, operands)
6034 /* Current assemblers are broken and do not allow @GOTOFF in
6035 ought but a memory context. */
6036 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6037{
6038 switch (get_attr_type (insn))
6039 {
6040 case TYPE_INCDEC:
6041 if (! rtx_equal_p (operands[0], operands[1]))
6042 abort ();
6043 if (operands[2] == const1_rtx)
6044 return "inc{l}\t%0";
6045 else if (operands[2] == constm1_rtx)
6046 return "dec{l}\t%0";
6047 else
6048 abort();
6049
6050 default:
6051 if (! rtx_equal_p (operands[0], operands[1]))
6052 abort ();
6053 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6055 if (GET_CODE (operands[2]) == CONST_INT
6056 && (INTVAL (operands[2]) == 128
6057 || (INTVAL (operands[2]) < 0
6058 && INTVAL (operands[2]) != -128)))
6059 {
6060 operands[2] = GEN_INT (-INTVAL (operands[2]));
6061 return "sub{l}\t{%2, %0|%0, %2}";
6062 }
6063 return "add{l}\t{%2, %0|%0, %2}";
6064 }
6065}
6066 [(set (attr "type")
6067 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6068 (const_string "incdec")
6069 (const_string "alu")))
6070 (set_attr "mode" "SI")])
6071
6072;; See comment for addsi_1_zext why we do use nonimmediate_operand
6073(define_insn "*addsi_2_zext"
6074 [(set (reg 17)
6075 (compare
6076 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6077 (match_operand:SI 2 "general_operand" "rmni"))
6078 (const_int 0)))
6079 (set (match_operand:DI 0 "register_operand" "=r")
6080 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6081 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6082 && ix86_binary_operator_ok (PLUS, SImode, operands)
6083 /* Current assemblers are broken and do not allow @GOTOFF in
6084 ought but a memory context. */
6085 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6086{
6087 switch (get_attr_type (insn))
6088 {
6089 case TYPE_INCDEC:
6090 if (operands[2] == const1_rtx)
6091 return "inc{l}\t%k0";
6092 else if (operands[2] == constm1_rtx)
6093 return "dec{l}\t%k0";
6094 else
6095 abort();
6096
6097 default:
6098 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6099 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6100 if (GET_CODE (operands[2]) == CONST_INT
6101 && (INTVAL (operands[2]) == 128
6102 || (INTVAL (operands[2]) < 0
6103 && INTVAL (operands[2]) != -128)))
6104 {
6105 operands[2] = GEN_INT (-INTVAL (operands[2]));
6106 return "sub{l}\t{%2, %k0|%k0, %2}";
6107 }
6108 return "add{l}\t{%2, %k0|%k0, %2}";
6109 }
6110}
6111 [(set (attr "type")
6112 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6113 (const_string "incdec")
6114 (const_string "alu")))
6115 (set_attr "mode" "SI")])
6116
6117(define_insn "*addsi_3"
6118 [(set (reg 17)
6119 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6120 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6121 (clobber (match_scratch:SI 0 "=r"))]
6122 "ix86_match_ccmode (insn, CCZmode)
6123 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6124 /* Current assemblers are broken and do not allow @GOTOFF in
6125 ought but a memory context. */
6126 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6127{
6128 switch (get_attr_type (insn))
6129 {
6130 case TYPE_INCDEC:
6131 if (! rtx_equal_p (operands[0], operands[1]))
6132 abort ();
6133 if (operands[2] == const1_rtx)
6134 return "inc{l}\t%0";
6135 else if (operands[2] == constm1_rtx)
6136 return "dec{l}\t%0";
6137 else
6138 abort();
6139
6140 default:
6141 if (! rtx_equal_p (operands[0], operands[1]))
6142 abort ();
6143 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6144 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6145 if (GET_CODE (operands[2]) == CONST_INT
6146 && (INTVAL (operands[2]) == 128
6147 || (INTVAL (operands[2]) < 0
6148 && INTVAL (operands[2]) != -128)))
6149 {
6150 operands[2] = GEN_INT (-INTVAL (operands[2]));
6151 return "sub{l}\t{%2, %0|%0, %2}";
6152 }
6153 return "add{l}\t{%2, %0|%0, %2}";
6154 }
6155}
6156 [(set (attr "type")
6157 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6158 (const_string "incdec")
6159 (const_string "alu")))
6160 (set_attr "mode" "SI")])
6161
6162;; See comment for addsi_1_zext why we do use nonimmediate_operand
6163(define_insn "*addsi_3_zext"
6164 [(set (reg 17)
6165 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6166 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6167 (set (match_operand:DI 0 "register_operand" "=r")
6168 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6169 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6170 && ix86_binary_operator_ok (PLUS, SImode, operands)
6171 /* Current assemblers are broken and do not allow @GOTOFF in
6172 ought but a memory context. */
6173 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6174{
6175 switch (get_attr_type (insn))
6176 {
6177 case TYPE_INCDEC:
6178 if (operands[2] == const1_rtx)
6179 return "inc{l}\t%k0";
6180 else if (operands[2] == constm1_rtx)
6181 return "dec{l}\t%k0";
6182 else
6183 abort();
6184
6185 default:
6186 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6187 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6188 if (GET_CODE (operands[2]) == CONST_INT
6189 && (INTVAL (operands[2]) == 128
6190 || (INTVAL (operands[2]) < 0
6191 && INTVAL (operands[2]) != -128)))
6192 {
6193 operands[2] = GEN_INT (-INTVAL (operands[2]));
6194 return "sub{l}\t{%2, %k0|%k0, %2}";
6195 }
6196 return "add{l}\t{%2, %k0|%k0, %2}";
6197 }
6198}
6199 [(set (attr "type")
6200 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6201 (const_string "incdec")
6202 (const_string "alu")))
6203 (set_attr "mode" "SI")])
6204
6205; For comparisons agains 1, -1 and 128, we may generate better code
6206; by converting cmp to add, inc or dec as done by peephole2. This pattern
6207; is matched then. We can't accept general immediate, because for
6208; case of overflows, the result is messed up.
6209; This pattern also don't hold of 0x80000000, since the value overflows
6210; when negated.
6211; Also carry flag is reversed compared to cmp, so this conversion is valid
6212; only for comparisons not depending on it.
6213(define_insn "*addsi_4"
6214 [(set (reg 17)
6215 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6216 (match_operand:SI 2 "const_int_operand" "n")))
6217 (clobber (match_scratch:SI 0 "=rm"))]
6218 "ix86_match_ccmode (insn, CCGCmode)
6219 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6220{
6221 switch (get_attr_type (insn))
6222 {
6223 case TYPE_INCDEC:
6224 if (operands[2] == constm1_rtx)
6225 return "inc{l}\t%0";
6226 else if (operands[2] == const1_rtx)
6227 return "dec{l}\t%0";
6228 else
6229 abort();
6230
6231 default:
6232 if (! rtx_equal_p (operands[0], operands[1]))
6233 abort ();
6234 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6235 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6236 if ((INTVAL (operands[2]) == -128
6237 || (INTVAL (operands[2]) > 0
6238 && INTVAL (operands[2]) != 128)))
6239 return "sub{l}\t{%2, %0|%0, %2}";
6240 operands[2] = GEN_INT (-INTVAL (operands[2]));
6241 return "add{l}\t{%2, %0|%0, %2}";
6242 }
6243}
6244 [(set (attr "type")
6245 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6246 (const_string "incdec")
6247 (const_string "alu")))
6248 (set_attr "mode" "SI")])
6249
6250(define_insn "*addsi_5"
6251 [(set (reg 17)
6252 (compare
6253 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6254 (match_operand:SI 2 "general_operand" "rmni"))
6255 (const_int 0)))
6256 (clobber (match_scratch:SI 0 "=r"))]
6257 "ix86_match_ccmode (insn, CCGOCmode)
6258 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6259 /* Current assemblers are broken and do not allow @GOTOFF in
6260 ought but a memory context. */
6261 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6262{
6263 switch (get_attr_type (insn))
6264 {
6265 case TYPE_INCDEC:
6266 if (! rtx_equal_p (operands[0], operands[1]))
6267 abort ();
6268 if (operands[2] == const1_rtx)
6269 return "inc{l}\t%0";
6270 else if (operands[2] == constm1_rtx)
6271 return "dec{l}\t%0";
6272 else
6273 abort();
6274
6275 default:
6276 if (! rtx_equal_p (operands[0], operands[1]))
6277 abort ();
6278 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6279 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6280 if (GET_CODE (operands[2]) == CONST_INT
6281 && (INTVAL (operands[2]) == 128
6282 || (INTVAL (operands[2]) < 0
6283 && INTVAL (operands[2]) != -128)))
6284 {
6285 operands[2] = GEN_INT (-INTVAL (operands[2]));
6286 return "sub{l}\t{%2, %0|%0, %2}";
6287 }
6288 return "add{l}\t{%2, %0|%0, %2}";
6289 }
6290}
6291 [(set (attr "type")
6292 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6293 (const_string "incdec")
6294 (const_string "alu")))
6295 (set_attr "mode" "SI")])
6296
6297(define_expand "addhi3"
6298 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6299 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6300 (match_operand:HI 2 "general_operand" "")))
6301 (clobber (reg:CC 17))])]
6302 "TARGET_HIMODE_MATH"
6303 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6304
6305;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6306;; type optimizations enabled by define-splits. This is not important
6307;; for PII, and in fact harmful because of partial register stalls.
6308
6309(define_insn "*addhi_1_lea"
6310 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6311 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6312 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6313 (clobber (reg:CC 17))]
6314 "!TARGET_PARTIAL_REG_STALL
6315 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6316{
6317 switch (get_attr_type (insn))
6318 {
6319 case TYPE_LEA:
6320 return "#";
6321 case TYPE_INCDEC:
6322 if (operands[2] == const1_rtx)
6323 return "inc{w}\t%0";
6324 else if (operands[2] == constm1_rtx
6325 || (GET_CODE (operands[2]) == CONST_INT
6326 && INTVAL (operands[2]) == 65535))
6327 return "dec{w}\t%0";
6328 abort();
6329
6330 default:
6331 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6332 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6333 if (GET_CODE (operands[2]) == CONST_INT
6334 && (INTVAL (operands[2]) == 128
6335 || (INTVAL (operands[2]) < 0
6336 && INTVAL (operands[2]) != -128)))
6337 {
6338 operands[2] = GEN_INT (-INTVAL (operands[2]));
6339 return "sub{w}\t{%2, %0|%0, %2}";
6340 }
6341 return "add{w}\t{%2, %0|%0, %2}";
6342 }
6343}
6344 [(set (attr "type")
6345 (if_then_else (eq_attr "alternative" "2")
6346 (const_string "lea")
6347 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6348 (const_string "incdec")
6349 (const_string "alu"))))
6350 (set_attr "mode" "HI,HI,SI")])
6351
6352(define_insn "*addhi_1"
6353 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6354 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6355 (match_operand:HI 2 "general_operand" "ri,rm")))
6356 (clobber (reg:CC 17))]
6357 "TARGET_PARTIAL_REG_STALL
6358 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6359{
6360 switch (get_attr_type (insn))
6361 {
6362 case TYPE_INCDEC:
6363 if (operands[2] == const1_rtx)
6364 return "inc{w}\t%0";
6365 else if (operands[2] == constm1_rtx
6366 || (GET_CODE (operands[2]) == CONST_INT
6367 && INTVAL (operands[2]) == 65535))
6368 return "dec{w}\t%0";
6369 abort();
6370
6371 default:
6372 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6373 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6374 if (GET_CODE (operands[2]) == CONST_INT
6375 && (INTVAL (operands[2]) == 128
6376 || (INTVAL (operands[2]) < 0
6377 && INTVAL (operands[2]) != -128)))
6378 {
6379 operands[2] = GEN_INT (-INTVAL (operands[2]));
6380 return "sub{w}\t{%2, %0|%0, %2}";
6381 }
6382 return "add{w}\t{%2, %0|%0, %2}";
6383 }
6384}
6385 [(set (attr "type")
6386 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6387 (const_string "incdec")
6388 (const_string "alu")))
6389 (set_attr "mode" "HI")])
6390
6391(define_insn "*addhi_2"
6392 [(set (reg 17)
6393 (compare
6394 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6395 (match_operand:HI 2 "general_operand" "rmni,rni"))
6396 (const_int 0)))
6397 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6398 (plus:HI (match_dup 1) (match_dup 2)))]
6399 "ix86_match_ccmode (insn, CCGOCmode)
6400 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6401{
6402 switch (get_attr_type (insn))
6403 {
6404 case TYPE_INCDEC:
6405 if (operands[2] == const1_rtx)
6406 return "inc{w}\t%0";
6407 else if (operands[2] == constm1_rtx
6408 || (GET_CODE (operands[2]) == CONST_INT
6409 && INTVAL (operands[2]) == 65535))
6410 return "dec{w}\t%0";
6411 abort();
6412
6413 default:
6414 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6415 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6416 if (GET_CODE (operands[2]) == CONST_INT
6417 && (INTVAL (operands[2]) == 128
6418 || (INTVAL (operands[2]) < 0
6419 && INTVAL (operands[2]) != -128)))
6420 {
6421 operands[2] = GEN_INT (-INTVAL (operands[2]));
6422 return "sub{w}\t{%2, %0|%0, %2}";
6423 }
6424 return "add{w}\t{%2, %0|%0, %2}";
6425 }
6426}
6427 [(set (attr "type")
6428 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "HI")])
6432
6433(define_insn "*addhi_3"
6434 [(set (reg 17)
6435 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6436 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6437 (clobber (match_scratch:HI 0 "=r"))]
6438 "ix86_match_ccmode (insn, CCZmode)
6439 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6440{
6441 switch (get_attr_type (insn))
6442 {
6443 case TYPE_INCDEC:
6444 if (operands[2] == const1_rtx)
6445 return "inc{w}\t%0";
6446 else if (operands[2] == constm1_rtx
6447 || (GET_CODE (operands[2]) == CONST_INT
6448 && INTVAL (operands[2]) == 65535))
6449 return "dec{w}\t%0";
6450 abort();
6451
6452 default:
6453 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6454 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6455 if (GET_CODE (operands[2]) == CONST_INT
6456 && (INTVAL (operands[2]) == 128
6457 || (INTVAL (operands[2]) < 0
6458 && INTVAL (operands[2]) != -128)))
6459 {
6460 operands[2] = GEN_INT (-INTVAL (operands[2]));
6461 return "sub{w}\t{%2, %0|%0, %2}";
6462 }
6463 return "add{w}\t{%2, %0|%0, %2}";
6464 }
6465}
6466 [(set (attr "type")
6467 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6468 (const_string "incdec")
6469 (const_string "alu")))
6470 (set_attr "mode" "HI")])
6471
6472; See comments above addsi_3_imm for details.
6473(define_insn "*addhi_4"
6474 [(set (reg 17)
6475 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6476 (match_operand:HI 2 "const_int_operand" "n")))
6477 (clobber (match_scratch:HI 0 "=rm"))]
6478 "ix86_match_ccmode (insn, CCGCmode)
6479 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6480{
6481 switch (get_attr_type (insn))
6482 {
6483 case TYPE_INCDEC:
6484 if (operands[2] == constm1_rtx
6485 || (GET_CODE (operands[2]) == CONST_INT
6486 && INTVAL (operands[2]) == 65535))
6487 return "inc{w}\t%0";
6488 else if (operands[2] == const1_rtx)
6489 return "dec{w}\t%0";
6490 else
6491 abort();
6492
6493 default:
6494 if (! rtx_equal_p (operands[0], operands[1]))
6495 abort ();
6496 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6497 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6498 if ((INTVAL (operands[2]) == -128
6499 || (INTVAL (operands[2]) > 0
6500 && INTVAL (operands[2]) != 128)))
6501 return "sub{w}\t{%2, %0|%0, %2}";
6502 operands[2] = GEN_INT (-INTVAL (operands[2]));
6503 return "add{w}\t{%2, %0|%0, %2}";
6504 }
6505}
6506 [(set (attr "type")
6507 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6508 (const_string "incdec")
6509 (const_string "alu")))
6510 (set_attr "mode" "SI")])
6511
6512
6513(define_insn "*addhi_5"
6514 [(set (reg 17)
6515 (compare
6516 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6517 (match_operand:HI 2 "general_operand" "rmni"))
6518 (const_int 0)))
6519 (clobber (match_scratch:HI 0 "=r"))]
6520 "ix86_match_ccmode (insn, CCGOCmode)
6521 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6522{
6523 switch (get_attr_type (insn))
6524 {
6525 case TYPE_INCDEC:
6526 if (operands[2] == const1_rtx)
6527 return "inc{w}\t%0";
6528 else if (operands[2] == constm1_rtx
6529 || (GET_CODE (operands[2]) == CONST_INT
6530 && INTVAL (operands[2]) == 65535))
6531 return "dec{w}\t%0";
6532 abort();
6533
6534 default:
6535 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6536 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6537 if (GET_CODE (operands[2]) == CONST_INT
6538 && (INTVAL (operands[2]) == 128
6539 || (INTVAL (operands[2]) < 0
6540 && INTVAL (operands[2]) != -128)))
6541 {
6542 operands[2] = GEN_INT (-INTVAL (operands[2]));
6543 return "sub{w}\t{%2, %0|%0, %2}";
6544 }
6545 return "add{w}\t{%2, %0|%0, %2}";
6546 }
6547}
6548 [(set (attr "type")
6549 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6550 (const_string "incdec")
6551 (const_string "alu")))
6552 (set_attr "mode" "HI")])
6553
6554(define_expand "addqi3"
6555 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6556 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6557 (match_operand:QI 2 "general_operand" "")))
6558 (clobber (reg:CC 17))])]
6559 "TARGET_QIMODE_MATH"
6560 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6561
6562;; %%% Potential partial reg stall on alternative 2. What to do?
6563(define_insn "*addqi_1_lea"
6564 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6565 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6566 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6567 (clobber (reg:CC 17))]
6568 "!TARGET_PARTIAL_REG_STALL
6569 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6570{
6571 int widen = (which_alternative == 2);
6572 switch (get_attr_type (insn))
6573 {
6574 case TYPE_LEA:
6575 return "#";
6576 case TYPE_INCDEC:
6577 if (operands[2] == const1_rtx)
6578 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6579 else if (operands[2] == constm1_rtx
6580 || (GET_CODE (operands[2]) == CONST_INT
6581 && INTVAL (operands[2]) == 255))
6582 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6583 abort();
6584
6585 default:
6586 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6587 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6588 if (GET_CODE (operands[2]) == CONST_INT
6589 && (INTVAL (operands[2]) == 128
6590 || (INTVAL (operands[2]) < 0
6591 && INTVAL (operands[2]) != -128)))
6592 {
6593 operands[2] = GEN_INT (-INTVAL (operands[2]));
6594 if (widen)
6595 return "sub{l}\t{%2, %k0|%k0, %2}";
6596 else
6597 return "sub{b}\t{%2, %0|%0, %2}";
6598 }
6599 if (widen)
6600 return "add{l}\t{%k2, %k0|%k0, %k2}";
6601 else
6602 return "add{b}\t{%2, %0|%0, %2}";
6603 }
6604}
6605 [(set (attr "type")
6606 (if_then_else (eq_attr "alternative" "3")
6607 (const_string "lea")
6608 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6609 (const_string "incdec")
6610 (const_string "alu"))))
6611 (set_attr "mode" "QI,QI,SI,SI")])
6612
6613(define_insn "*addqi_1"
6614 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6615 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6616 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6617 (clobber (reg:CC 17))]
6618 "TARGET_PARTIAL_REG_STALL
6619 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6620{
6621 int widen = (which_alternative == 2);
6622 switch (get_attr_type (insn))
6623 {
6624 case TYPE_INCDEC:
6625 if (operands[2] == const1_rtx)
6626 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6627 else if (operands[2] == constm1_rtx
6628 || (GET_CODE (operands[2]) == CONST_INT
6629 && INTVAL (operands[2]) == 255))
6630 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6631 abort();
6632
6633 default:
6634 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6635 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6636 if (GET_CODE (operands[2]) == CONST_INT
6637 && (INTVAL (operands[2]) == 128
6638 || (INTVAL (operands[2]) < 0
6639 && INTVAL (operands[2]) != -128)))
6640 {
6641 operands[2] = GEN_INT (-INTVAL (operands[2]));
6642 if (widen)
6643 return "sub{l}\t{%2, %k0|%k0, %2}";
6644 else
6645 return "sub{b}\t{%2, %0|%0, %2}";
6646 }
6647 if (widen)
6648 return "add{l}\t{%k2, %k0|%k0, %k2}";
6649 else
6650 return "add{b}\t{%2, %0|%0, %2}";
6651 }
6652}
6653 [(set (attr "type")
6654 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6655 (const_string "incdec")
6656 (const_string "alu")))
6657 (set_attr "mode" "QI,QI,SI")])
6658
6659(define_insn "*addqi_2"
6660 [(set (reg 17)
6661 (compare
6662 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6663 (match_operand:QI 2 "general_operand" "qmni,qni"))
6664 (const_int 0)))
6665 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6666 (plus:QI (match_dup 1) (match_dup 2)))]
6667 "ix86_match_ccmode (insn, CCGOCmode)
6668 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6669{
6670 switch (get_attr_type (insn))
6671 {
6672 case TYPE_INCDEC:
6673 if (operands[2] == const1_rtx)
6674 return "inc{b}\t%0";
6675 else if (operands[2] == constm1_rtx
6676 || (GET_CODE (operands[2]) == CONST_INT
6677 && INTVAL (operands[2]) == 255))
6678 return "dec{b}\t%0";
6679 abort();
6680
6681 default:
6682 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6683 if (GET_CODE (operands[2]) == CONST_INT
6684 && INTVAL (operands[2]) < 0)
6685 {
6686 operands[2] = GEN_INT (-INTVAL (operands[2]));
6687 return "sub{b}\t{%2, %0|%0, %2}";
6688 }
6689 return "add{b}\t{%2, %0|%0, %2}";
6690 }
6691}
6692 [(set (attr "type")
6693 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6694 (const_string "incdec")
6695 (const_string "alu")))
6696 (set_attr "mode" "QI")])
6697
6698(define_insn "*addqi_3"
6699 [(set (reg 17)
6700 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6701 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6702 (clobber (match_scratch:QI 0 "=q"))]
6703 "ix86_match_ccmode (insn, CCZmode)
6704 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6705{
6706 switch (get_attr_type (insn))
6707 {
6708 case TYPE_INCDEC:
6709 if (operands[2] == const1_rtx)
6710 return "inc{b}\t%0";
6711 else if (operands[2] == constm1_rtx
6712 || (GET_CODE (operands[2]) == CONST_INT
6713 && INTVAL (operands[2]) == 255))
6714 return "dec{b}\t%0";
6715 abort();
6716
6717 default:
6718 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6719 if (GET_CODE (operands[2]) == CONST_INT
6720 && INTVAL (operands[2]) < 0)
6721 {
6722 operands[2] = GEN_INT (-INTVAL (operands[2]));
6723 return "sub{b}\t{%2, %0|%0, %2}";
6724 }
6725 return "add{b}\t{%2, %0|%0, %2}";
6726 }
6727}
6728 [(set (attr "type")
6729 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6730 (const_string "incdec")
6731 (const_string "alu")))
6732 (set_attr "mode" "QI")])
6733
6734; See comments above addsi_3_imm for details.
6735(define_insn "*addqi_4"
6736 [(set (reg 17)
6737 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6738 (match_operand:QI 2 "const_int_operand" "n")))
6739 (clobber (match_scratch:QI 0 "=qm"))]
6740 "ix86_match_ccmode (insn, CCGCmode)
6741 && (INTVAL (operands[2]) & 0xff) != 0x80"
6742{
6743 switch (get_attr_type (insn))
6744 {
6745 case TYPE_INCDEC:
6746 if (operands[2] == constm1_rtx
6747 || (GET_CODE (operands[2]) == CONST_INT
6748 && INTVAL (operands[2]) == 255))
6749 return "inc{b}\t%0";
6750 else if (operands[2] == const1_rtx)
6751 return "dec{b}\t%0";
6752 else
6753 abort();
6754
6755 default:
6756 if (! rtx_equal_p (operands[0], operands[1]))
6757 abort ();
6758 if (INTVAL (operands[2]) < 0)
6759 {
6760 operands[2] = GEN_INT (-INTVAL (operands[2]));
6761 return "add{b}\t{%2, %0|%0, %2}";
6762 }
6763 return "sub{b}\t{%2, %0|%0, %2}";
6764 }
6765}
6766 [(set (attr "type")
6767 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6768 (const_string "incdec")
6769 (const_string "alu")))
6770 (set_attr "mode" "QI")])
6771
6772
6773(define_insn "*addqi_5"
6774 [(set (reg 17)
6775 (compare
6776 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6777 (match_operand:QI 2 "general_operand" "qmni"))
6778 (const_int 0)))
6779 (clobber (match_scratch:QI 0 "=q"))]
6780 "ix86_match_ccmode (insn, CCGOCmode)
6781 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6782{
6783 switch (get_attr_type (insn))
6784 {
6785 case TYPE_INCDEC:
6786 if (operands[2] == const1_rtx)
6787 return "inc{b}\t%0";
6788 else if (operands[2] == constm1_rtx
6789 || (GET_CODE (operands[2]) == CONST_INT
6790 && INTVAL (operands[2]) == 255))
6791 return "dec{b}\t%0";
6792 abort();
6793
6794 default:
6795 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6796 if (GET_CODE (operands[2]) == CONST_INT
6797 && INTVAL (operands[2]) < 0)
6798 {
6799 operands[2] = GEN_INT (-INTVAL (operands[2]));
6800 return "sub{b}\t{%2, %0|%0, %2}";
6801 }
6802 return "add{b}\t{%2, %0|%0, %2}";
6803 }
6804}
6805 [(set (attr "type")
6806 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6807 (const_string "incdec")
6808 (const_string "alu")))
6809 (set_attr "mode" "QI")])
6810
6811
6812(define_insn "addqi_ext_1"
6813 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6814 (const_int 8)
6815 (const_int 8))
6816 (plus:SI
6817 (zero_extract:SI
6818 (match_operand 1 "ext_register_operand" "0")
6819 (const_int 8)
6820 (const_int 8))
6821 (match_operand:QI 2 "general_operand" "Qmn")))
6822 (clobber (reg:CC 17))]
6823 "!TARGET_64BIT"
6824{
6825 switch (get_attr_type (insn))
6826 {
6827 case TYPE_INCDEC:
6828 if (operands[2] == const1_rtx)
6829 return "inc{b}\t%h0";
6830 else if (operands[2] == constm1_rtx
6831 || (GET_CODE (operands[2]) == CONST_INT
6832 && INTVAL (operands[2]) == 255))
6833 return "dec{b}\t%h0";
6834 abort();
6835
6836 default:
6837 return "add{b}\t{%2, %h0|%h0, %2}";
6838 }
6839}
6840 [(set (attr "type")
6841 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6842 (const_string "incdec")
6843 (const_string "alu")))
6844 (set_attr "mode" "QI")])
6845
6846(define_insn "*addqi_ext_1_rex64"
6847 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6848 (const_int 8)
6849 (const_int 8))
6850 (plus:SI
6851 (zero_extract:SI
6852 (match_operand 1 "ext_register_operand" "0")
6853 (const_int 8)
6854 (const_int 8))
6855 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6856 (clobber (reg:CC 17))]
6857 "TARGET_64BIT"
6858{
6859 switch (get_attr_type (insn))
6860 {
6861 case TYPE_INCDEC:
6862 if (operands[2] == const1_rtx)
6863 return "inc{b}\t%h0";
6864 else if (operands[2] == constm1_rtx
6865 || (GET_CODE (operands[2]) == CONST_INT
6866 && INTVAL (operands[2]) == 255))
6867 return "dec{b}\t%h0";
6868 abort();
6869
6870 default:
6871 return "add{b}\t{%2, %h0|%h0, %2}";
6872 }
6873}
6874 [(set (attr "type")
6875 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6876 (const_string "incdec")
6877 (const_string "alu")))
6878 (set_attr "mode" "QI")])
6879
6880(define_insn "*addqi_ext_2"
6881 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6882 (const_int 8)
6883 (const_int 8))
6884 (plus:SI
6885 (zero_extract:SI
6886 (match_operand 1 "ext_register_operand" "%0")
6887 (const_int 8)
6888 (const_int 8))
6889 (zero_extract:SI
6890 (match_operand 2 "ext_register_operand" "Q")
6891 (const_int 8)
6892 (const_int 8))))
6893 (clobber (reg:CC 17))]
6894 ""
6895 "add{b}\t{%h2, %h0|%h0, %h2}"
6896 [(set_attr "type" "alu")
6897 (set_attr "mode" "QI")])
6898
6899;; The patterns that match these are at the end of this file.
6900
6901(define_expand "addxf3"
6902 [(set (match_operand:XF 0 "register_operand" "")
6903 (plus:XF (match_operand:XF 1 "register_operand" "")
6904 (match_operand:XF 2 "register_operand" "")))]
6905 "!TARGET_64BIT && TARGET_80387"
6906 "")
6907
6908(define_expand "addtf3"
6909 [(set (match_operand:TF 0 "register_operand" "")
6910 (plus:TF (match_operand:TF 1 "register_operand" "")
6911 (match_operand:TF 2 "register_operand" "")))]
6912 "TARGET_80387"
6913 "")
6914
6915(define_expand "adddf3"
6916 [(set (match_operand:DF 0 "register_operand" "")
6917 (plus:DF (match_operand:DF 1 "register_operand" "")
6918 (match_operand:DF 2 "nonimmediate_operand" "")))]
6919 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6920 "")
6921
6922(define_expand "addsf3"
6923 [(set (match_operand:SF 0 "register_operand" "")
6924 (plus:SF (match_operand:SF 1 "register_operand" "")
6925 (match_operand:SF 2 "nonimmediate_operand" "")))]
6926 "TARGET_80387 || TARGET_SSE_MATH"
6927 "")
6928
6929;; Subtract instructions
6930
6931;; %%% splits for subsidi3
6932
6933(define_expand "subdi3"
6934 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6935 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6936 (match_operand:DI 2 "x86_64_general_operand" "")))
6937 (clobber (reg:CC 17))])]
6938 ""
6939 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6940
6941(define_insn "*subdi3_1"
6942 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6943 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6944 (match_operand:DI 2 "general_operand" "roiF,riF")))
6945 (clobber (reg:CC 17))]
6946 "!TARGET_64BIT"
6947 "#")
6948
6949(define_split
6950 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6951 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6952 (match_operand:DI 2 "general_operand" "")))
6953 (clobber (reg:CC 17))]
6954 "!TARGET_64BIT && reload_completed"
6955 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6956 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6957 (parallel [(set (match_dup 3)
6958 (minus:SI (match_dup 4)
6959 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6960 (match_dup 5))))
6961 (clobber (reg:CC 17))])]
6962 "split_di (operands+0, 1, operands+0, operands+3);
6963 split_di (operands+1, 1, operands+1, operands+4);
6964 split_di (operands+2, 1, operands+2, operands+5);")
6965
6966(define_insn "subdi3_carry_rex64"
6967 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6968 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6969 (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6970 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6971 (clobber (reg:CC 17))]
6972 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6973 "sbb{q}\t{%2, %0|%0, %2}"
6974 [(set_attr "type" "alu")
6975 (set_attr "pent_pair" "pu")
6976 (set_attr "ppro_uops" "few")
6977 (set_attr "mode" "DI")])
6978
6979(define_insn "*subdi_1_rex64"
6980 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6981 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6982 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6983 (clobber (reg:CC 17))]
6984 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6985 "sub{q}\t{%2, %0|%0, %2}"
6986 [(set_attr "type" "alu")
6987 (set_attr "mode" "DI")])
6988
6989(define_insn "*subdi_2_rex64"
6990 [(set (reg 17)
6991 (compare
6992 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6993 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6994 (const_int 0)))
6995 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6996 (minus:DI (match_dup 1) (match_dup 2)))]
6997 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6998 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6999 "sub{q}\t{%2, %0|%0, %2}"
7000 [(set_attr "type" "alu")
7001 (set_attr "mode" "DI")])
7002
7003(define_insn "*subdi_3_rex63"
7004 [(set (reg 17)
7005 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7006 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7007 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7008 (minus:DI (match_dup 1) (match_dup 2)))]
7009 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7010 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7011 "sub{q}\t{%2, %0|%0, %2}"
7012 [(set_attr "type" "alu")
7013 (set_attr "mode" "DI")])
7014
7015
7016(define_insn "subsi3_carry"
7017 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7018 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7019 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7020 (match_operand:SI 2 "general_operand" "ri,rm"))))
7021 (clobber (reg:CC 17))]
7022 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7023 "sbb{l}\t{%2, %0|%0, %2}"
7024 [(set_attr "type" "alu")
7025 (set_attr "pent_pair" "pu")
7026 (set_attr "ppro_uops" "few")
7027 (set_attr "mode" "SI")])
7028
7029(define_insn "subsi3_carry_zext"
7030 [(set (match_operand:DI 0 "register_operand" "=rm,r")
7031 (zero_extend:DI
7032 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
7033 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7034 (match_operand:SI 2 "general_operand" "ri,rm")))))
7035 (clobber (reg:CC 17))]
7036 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7037 "sbb{l}\t{%2, %k0|%k0, %2}"
7038 [(set_attr "type" "alu")
7039 (set_attr "pent_pair" "pu")
7040 (set_attr "ppro_uops" "few")
7041 (set_attr "mode" "SI")])
7042
7043(define_expand "subsi3"
7044 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7045 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7046 (match_operand:SI 2 "general_operand" "")))
7047 (clobber (reg:CC 17))])]
7048 ""
7049 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7050
7051(define_insn "*subsi_1"
7052 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7053 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7054 (match_operand:SI 2 "general_operand" "ri,rm")))
7055 (clobber (reg:CC 17))]
7056 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7057 "sub{l}\t{%2, %0|%0, %2}"
7058 [(set_attr "type" "alu")
7059 (set_attr "mode" "SI")])
7060
7061(define_insn "*subsi_1_zext"
7062 [(set (match_operand:DI 0 "register_operand" "=r")
7063 (zero_extend:DI
7064 (minus:SI (match_operand:SI 1 "register_operand" "0")
7065 (match_operand:SI 2 "general_operand" "rim"))))
7066 (clobber (reg:CC 17))]
7067 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7068 "sub{l}\t{%2, %k0|%k0, %2}"
7069 [(set_attr "type" "alu")
7070 (set_attr "mode" "SI")])
7071
7072(define_insn "*subsi_2"
7073 [(set (reg 17)
7074 (compare
7075 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7076 (match_operand:SI 2 "general_operand" "ri,rm"))
7077 (const_int 0)))
7078 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7079 (minus:SI (match_dup 1) (match_dup 2)))]
7080 "ix86_match_ccmode (insn, CCGOCmode)
7081 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7082 "sub{l}\t{%2, %0|%0, %2}"
7083 [(set_attr "type" "alu")
7084 (set_attr "mode" "SI")])
7085
7086(define_insn "*subsi_2_zext"
7087 [(set (reg 17)
7088 (compare
7089 (minus:SI (match_operand:SI 1 "register_operand" "0")
7090 (match_operand:SI 2 "general_operand" "rim"))
7091 (const_int 0)))
7092 (set (match_operand:DI 0 "register_operand" "=r")
7093 (zero_extend:DI
7094 (minus:SI (match_dup 1)
7095 (match_dup 2))))]
7096 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7097 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7098 "sub{l}\t{%2, %k0|%k0, %2}"
7099 [(set_attr "type" "alu")
7100 (set_attr "mode" "SI")])
7101
7102(define_insn "*subsi_3"
7103 [(set (reg 17)
7104 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7105 (match_operand:SI 2 "general_operand" "ri,rm")))
7106 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7107 (minus:SI (match_dup 1) (match_dup 2)))]
7108 "ix86_match_ccmode (insn, CCmode)
7109 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7110 "sub{l}\t{%2, %0|%0, %2}"
7111 [(set_attr "type" "alu")
7112 (set_attr "mode" "SI")])
7113
7114(define_insn "*subsi_3_zext"
7115 [(set (reg 17)
7116 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7117 (match_operand:SI 2 "general_operand" "rim")))
7118 (set (match_operand:DI 0 "register_operand" "=r")
7119 (zero_extend:DI
7120 (minus:SI (match_dup 1)
7121 (match_dup 2))))]
7122 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7123 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7124 "sub{q}\t{%2, %0|%0, %2}"
7125 [(set_attr "type" "alu")
7126 (set_attr "mode" "DI")])
7127
7128(define_expand "subhi3"
7129 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7130 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7131 (match_operand:HI 2 "general_operand" "")))
7132 (clobber (reg:CC 17))])]
7133 "TARGET_HIMODE_MATH"
7134 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7135
7136(define_insn "*subhi_1"
7137 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7138 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7139 (match_operand:HI 2 "general_operand" "ri,rm")))
7140 (clobber (reg:CC 17))]
7141 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7142 "sub{w}\t{%2, %0|%0, %2}"
7143 [(set_attr "type" "alu")
7144 (set_attr "mode" "HI")])
7145
7146(define_insn "*subhi_2"
7147 [(set (reg 17)
7148 (compare
7149 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7150 (match_operand:HI 2 "general_operand" "ri,rm"))
7151 (const_int 0)))
7152 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7153 (minus:HI (match_dup 1) (match_dup 2)))]
7154 "ix86_match_ccmode (insn, CCGOCmode)
7155 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7156 "sub{w}\t{%2, %0|%0, %2}"
7157 [(set_attr "type" "alu")
7158 (set_attr "mode" "HI")])
7159
7160(define_insn "*subhi_3"
7161 [(set (reg 17)
7162 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7163 (match_operand:HI 2 "general_operand" "ri,rm")))
7164 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7165 (minus:HI (match_dup 1) (match_dup 2)))]
7166 "ix86_match_ccmode (insn, CCmode)
7167 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7168 "sub{w}\t{%2, %0|%0, %2}"
7169 [(set_attr "type" "alu")
7170 (set_attr "mode" "HI")])
7171
7172(define_expand "subqi3"
7173 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7174 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7175 (match_operand:QI 2 "general_operand" "")))
7176 (clobber (reg:CC 17))])]
7177 "TARGET_QIMODE_MATH"
7178 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7179
7180(define_insn "*subqi_1"
7181 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7182 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7183 (match_operand:QI 2 "general_operand" "qn,qmn")))
7184 (clobber (reg:CC 17))]
7185 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7186 "sub{b}\t{%2, %0|%0, %2}"
7187 [(set_attr "type" "alu")
7188 (set_attr "mode" "QI")])
7189
7190(define_insn "*subqi_2"
7191 [(set (reg 17)
7192 (compare
7193 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7194 (match_operand:QI 2 "general_operand" "qi,qm"))
7195 (const_int 0)))
7196 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7197 (minus:HI (match_dup 1) (match_dup 2)))]
7198 "ix86_match_ccmode (insn, CCGOCmode)
7199 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7200 "sub{b}\t{%2, %0|%0, %2}"
7201 [(set_attr "type" "alu")
7202 (set_attr "mode" "QI")])
7203
7204(define_insn "*subqi_3"
7205 [(set (reg 17)
7206 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7207 (match_operand:QI 2 "general_operand" "qi,qm")))
7208 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7209 (minus:HI (match_dup 1) (match_dup 2)))]
7210 "ix86_match_ccmode (insn, CCmode)
7211 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7212 "sub{b}\t{%2, %0|%0, %2}"
7213 [(set_attr "type" "alu")
7214 (set_attr "mode" "QI")])
7215
7216;; The patterns that match these are at the end of this file.
7217
7218(define_expand "subxf3"
7219 [(set (match_operand:XF 0 "register_operand" "")
7220 (minus:XF (match_operand:XF 1 "register_operand" "")
7221 (match_operand:XF 2 "register_operand" "")))]
7222 "!TARGET_64BIT && TARGET_80387"
7223 "")
7224
7225(define_expand "subtf3"
7226 [(set (match_operand:TF 0 "register_operand" "")
7227 (minus:TF (match_operand:TF 1 "register_operand" "")
7228 (match_operand:TF 2 "register_operand" "")))]
7229 "TARGET_80387"
7230 "")
7231
7232(define_expand "subdf3"
7233 [(set (match_operand:DF 0 "register_operand" "")
7234 (minus:DF (match_operand:DF 1 "register_operand" "")
7235 (match_operand:DF 2 "nonimmediate_operand" "")))]
7236 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7237 "")
7238
7239(define_expand "subsf3"
7240 [(set (match_operand:SF 0 "register_operand" "")
7241 (minus:SF (match_operand:SF 1 "register_operand" "")
7242 (match_operand:SF 2 "nonimmediate_operand" "")))]
7243 "TARGET_80387 || TARGET_SSE_MATH"
7244 "")
7245
7246;; Multiply instructions
7247
7248(define_expand "muldi3"
7249 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7250 (mult:DI (match_operand:DI 1 "register_operand" "")
7251 (match_operand:DI 2 "x86_64_general_operand" "")))
7252 (clobber (reg:CC 17))])]
7253 "TARGET_64BIT"
7254 "")
7255
7256(define_insn "*muldi3_1_rex64"
7257 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7258 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
7259 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7260 (clobber (reg:CC 17))]
7261 "TARGET_64BIT
7262 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7263 "@
7264 imul{q}\t{%2, %1, %0|%0, %1, %2}
7265 imul{q}\t{%2, %1, %0|%0, %1, %2}
7266 imul{q}\t{%2, %0|%0, %2}"
7267 [(set_attr "type" "imul")
7268 (set_attr "prefix_0f" "0,0,1")
7269 (set_attr "mode" "DI")])
7270
7271(define_expand "mulsi3"
7272 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7273 (mult:SI (match_operand:SI 1 "register_operand" "")
7274 (match_operand:SI 2 "general_operand" "")))
7275 (clobber (reg:CC 17))])]
7276 ""
7277 "")
7278
7279(define_insn "*mulsi3_1"
7280 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7281 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7282 (match_operand:SI 2 "general_operand" "K,i,mr")))
7283 (clobber (reg:CC 17))]
7284 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7285 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7286 ; there are two ways of writing the exact same machine instruction
7287 ; in assembly language. One, for example, is:
7288 ;
7289 ; imul $12, %eax
7290 ;
7291 ; while the other is:
7292 ;
7293 ; imul $12, %eax, %eax
7294 ;
7295 ; The first is simply short-hand for the latter. But, some assemblers,
7296 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7297 "@
7298 imul{l}\t{%2, %1, %0|%0, %1, %2}
7299 imul{l}\t{%2, %1, %0|%0, %1, %2}
7300 imul{l}\t{%2, %0|%0, %2}"
7301 [(set_attr "type" "imul")
7302 (set_attr "prefix_0f" "0,0,1")
7303 (set_attr "mode" "SI")])
7304
7305(define_insn "*mulsi3_1_zext"
7306 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7307 (zero_extend:DI
7308 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7309 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7310 (clobber (reg:CC 17))]
7311 "TARGET_64BIT
7312 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7313 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7314 ; there are two ways of writing the exact same machine instruction
7315 ; in assembly language. One, for example, is:
7316 ;
7317 ; imul $12, %eax
7318 ;
7319 ; while the other is:
7320 ;
7321 ; imul $12, %eax, %eax
7322 ;
7323 ; The first is simply short-hand for the latter. But, some assemblers,
7324 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7325 "@
7326 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7327 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7328 imul{l}\t{%2, %k0|%k0, %2}"
7329 [(set_attr "type" "imul")
7330 (set_attr "prefix_0f" "0,0,1")
7331 (set_attr "mode" "SI")])
7332
7333(define_expand "mulhi3"
7334 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7335 (mult:HI (match_operand:HI 1 "register_operand" "")
7336 (match_operand:HI 2 "general_operand" "")))
7337 (clobber (reg:CC 17))])]
7338 "TARGET_HIMODE_MATH"
7339 "")
7340
7341(define_insn "*mulhi3_1"
7342 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7343 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
7344 (match_operand:HI 2 "general_operand" "K,i,mr")))
7345 (clobber (reg:CC 17))]
7346 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7347 ; %%% There was a note about "Assembler has weird restrictions",
7348 ; concerning alternative 1 when op1 == op0. True?
7349 "@
7350 imul{w}\t{%2, %1, %0|%0, %1, %2}
7351 imul{w}\t{%2, %1, %0|%0, %1, %2}
7352 imul{w}\t{%2, %0|%0, %2}"
7353 [(set_attr "type" "imul")
7354 (set_attr "prefix_0f" "0,0,1")
7355 (set_attr "mode" "HI")])
7356
7335(define_insn "mulqi3"
7357(define_expand "mulqi3"
7358 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7359 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7360 (match_operand:QI 2 "register_operand" "")))
7361 (clobber (reg:CC 17))])]
7362 "TARGET_QIMODE_MATH"
7363 "")
7364
7365(define_insn "*mulqi3_1"
7336 [(set (match_operand:QI 0 "register_operand" "=a")
7366 [(set (match_operand:QI 0 "register_operand" "=a")
7337 (mult:QI (match_operand:QI 1 "register_operand" "%0")
7367 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7338 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7339 (clobber (reg:CC 17))]
7368 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7369 (clobber (reg:CC 17))]
7340 "TARGET_QIMODE_MATH"
7370 "TARGET_QIMODE_MATH
7371 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7341 "mul{b}\t%2"
7342 [(set_attr "type" "imul")
7343 (set_attr "length_immediate" "0")
7344 (set_attr "mode" "QI")])
7345
7372 "mul{b}\t%2"
7373 [(set_attr "type" "imul")
7374 (set_attr "length_immediate" "0")
7375 (set_attr "mode" "QI")])
7376
7346(define_insn "umulqihi3"
7377(define_expand "umulqihi3"
7378 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7379 (mult:HI (zero_extend:HI
7380 (match_operand:QI 1 "nonimmediate_operand" ""))
7381 (zero_extend:HI
7382 (match_operand:QI 2 "register_operand" ""))))
7383 (clobber (reg:CC 17))])]
7384 "TARGET_QIMODE_MATH"
7385 "")
7386
7387(define_insn "*umulqihi3_1"
7347 [(set (match_operand:HI 0 "register_operand" "=a")
7388 [(set (match_operand:HI 0 "register_operand" "=a")
7348 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
7389 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7349 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7350 (clobber (reg:CC 17))]
7390 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7391 (clobber (reg:CC 17))]
7351 "TARGET_QIMODE_MATH"
7392 "TARGET_QIMODE_MATH
7393 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7352 "mul{b}\t%2"
7353 [(set_attr "type" "imul")
7354 (set_attr "length_immediate" "0")
7355 (set_attr "mode" "QI")])
7356
7394 "mul{b}\t%2"
7395 [(set_attr "type" "imul")
7396 (set_attr "length_immediate" "0")
7397 (set_attr "mode" "QI")])
7398
7357(define_insn "mulqihi3"
7399(define_expand "mulqihi3"
7400 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7401 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7402 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7403 (clobber (reg:CC 17))])]
7404 "TARGET_QIMODE_MATH"
7405 "")
7406
7407(define_insn "*mulqihi3_insn"
7358 [(set (match_operand:HI 0 "register_operand" "=a")
7408 [(set (match_operand:HI 0 "register_operand" "=a")
7359 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
7409 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7360 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7361 (clobber (reg:CC 17))]
7410 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7411 (clobber (reg:CC 17))]
7362 "TARGET_QIMODE_MATH"
7412 "TARGET_QIMODE_MATH
7413 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7363 "imul{b}\t%2"
7364 [(set_attr "type" "imul")
7365 (set_attr "length_immediate" "0")
7366 (set_attr "mode" "QI")])
7367
7414 "imul{b}\t%2"
7415 [(set_attr "type" "imul")
7416 (set_attr "length_immediate" "0")
7417 (set_attr "mode" "QI")])
7418
7368(define_insn "umulditi3"
7419(define_expand "umulditi3"
7420 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7421 (mult:TI (zero_extend:TI
7422 (match_operand:DI 1 "nonimmediate_operand" ""))
7423 (zero_extend:TI
7424 (match_operand:DI 2 "register_operand" ""))))
7425 (clobber (reg:CC 17))])]
7426 "TARGET_64BIT"
7427 "")
7428
7429(define_insn "*umulditi3_insn"
7369 [(set (match_operand:TI 0 "register_operand" "=A")
7430 [(set (match_operand:TI 0 "register_operand" "=A")
7370 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7431 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7371 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7372 (clobber (reg:CC 17))]
7432 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7433 (clobber (reg:CC 17))]
7373 "TARGET_64BIT"
7434 "TARGET_64BIT
7435 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7374 "mul{q}\t%2"
7375 [(set_attr "type" "imul")
7376 (set_attr "ppro_uops" "few")
7377 (set_attr "length_immediate" "0")
7378 (set_attr "mode" "DI")])
7379
7380;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7436 "mul{q}\t%2"
7437 [(set_attr "type" "imul")
7438 (set_attr "ppro_uops" "few")
7439 (set_attr "length_immediate" "0")
7440 (set_attr "mode" "DI")])
7441
7442;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7381(define_insn "umulsidi3"
7443(define_expand "umulsidi3"
7444 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7445 (mult:DI (zero_extend:DI
7446 (match_operand:SI 1 "nonimmediate_operand" ""))
7447 (zero_extend:DI
7448 (match_operand:SI 2 "register_operand" ""))))
7449 (clobber (reg:CC 17))])]
7450 "!TARGET_64BIT"
7451 "")
7452
7453(define_insn "*umulsidi3_insn"
7382 [(set (match_operand:DI 0 "register_operand" "=A")
7454 [(set (match_operand:DI 0 "register_operand" "=A")
7383 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7455 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7384 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7385 (clobber (reg:CC 17))]
7456 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7457 (clobber (reg:CC 17))]
7386 "!TARGET_64BIT"
7458 "!TARGET_64BIT
7459 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7387 "mul{l}\t%2"
7388 [(set_attr "type" "imul")
7389 (set_attr "ppro_uops" "few")
7390 (set_attr "length_immediate" "0")
7391 (set_attr "mode" "SI")])
7392
7460 "mul{l}\t%2"
7461 [(set_attr "type" "imul")
7462 (set_attr "ppro_uops" "few")
7463 (set_attr "length_immediate" "0")
7464 (set_attr "mode" "SI")])
7465
7393(define_insn "mulditi3"
7466(define_expand "mulditi3"
7467 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7468 (mult:TI (sign_extend:TI
7469 (match_operand:DI 1 "nonimmediate_operand" ""))
7470 (sign_extend:TI
7471 (match_operand:DI 2 "register_operand" ""))))
7472 (clobber (reg:CC 17))])]
7473 "TARGET_64BIT"
7474 "")
7475
7476(define_insn "*mulditi3_insn"
7394 [(set (match_operand:TI 0 "register_operand" "=A")
7477 [(set (match_operand:TI 0 "register_operand" "=A")
7395 (mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7478 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7396 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7397 (clobber (reg:CC 17))]
7479 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7480 (clobber (reg:CC 17))]
7398 "TARGET_64BIT"
7481 "TARGET_64BIT
7482 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7399 "imul{q}\t%2"
7400 [(set_attr "type" "imul")
7401 (set_attr "length_immediate" "0")
7402 (set_attr "mode" "DI")])
7403
7483 "imul{q}\t%2"
7484 [(set_attr "type" "imul")
7485 (set_attr "length_immediate" "0")
7486 (set_attr "mode" "DI")])
7487
7404(define_insn "mulsidi3"
7488(define_expand "mulsidi3"
7489 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7490 (mult:DI (sign_extend:DI
7491 (match_operand:SI 1 "nonimmediate_operand" ""))
7492 (sign_extend:DI
7493 (match_operand:SI 2 "register_operand" ""))))
7494 (clobber (reg:CC 17))])]
7495 "!TARGET_64BIT"
7496 "")
7497
7498(define_insn "*mulsidi3_insn"
7405 [(set (match_operand:DI 0 "register_operand" "=A")
7499 [(set (match_operand:DI 0 "register_operand" "=A")
7406 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7500 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7407 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7408 (clobber (reg:CC 17))]
7501 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7502 (clobber (reg:CC 17))]
7409 "!TARGET_64BIT"
7503 "!TARGET_64BIT
7504 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7410 "imul{l}\t%2"
7411 [(set_attr "type" "imul")
7412 (set_attr "length_immediate" "0")
7413 (set_attr "mode" "SI")])
7414
7505 "imul{l}\t%2"
7506 [(set_attr "type" "imul")
7507 (set_attr "length_immediate" "0")
7508 (set_attr "mode" "SI")])
7509
7510(define_expand "umuldi3_highpart"
7511 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7512 (truncate:DI
7513 (lshiftrt:TI
7514 (mult:TI (zero_extend:TI
7515 (match_operand:DI 1 "nonimmediate_operand" ""))
7516 (zero_extend:TI
7517 (match_operand:DI 2 "register_operand" "")))
7518 (const_int 64))))
7519 (clobber (match_scratch:DI 3 ""))
7520 (clobber (reg:CC 17))])]
7521 "TARGET_64BIT"
7522 "")
7523
7415(define_insn "*umuldi3_highpart_rex64"
7416 [(set (match_operand:DI 0 "register_operand" "=d")
7417 (truncate:DI
7418 (lshiftrt:TI
7419 (mult:TI (zero_extend:TI
7524(define_insn "*umuldi3_highpart_rex64"
7525 [(set (match_operand:DI 0 "register_operand" "=d")
7526 (truncate:DI
7527 (lshiftrt:TI
7528 (mult:TI (zero_extend:TI
7420 (match_operand:DI 1 "register_operand" "%a"))
7529 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7421 (zero_extend:TI
7422 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7423 (const_int 64))))
7530 (zero_extend:TI
7531 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7532 (const_int 64))))
7424 (clobber (match_scratch:DI 3 "=a"))
7533 (clobber (match_scratch:DI 3 "=1"))
7425 (clobber (reg:CC 17))]
7534 (clobber (reg:CC 17))]
7426 "TARGET_64BIT"
7535 "TARGET_64BIT
7536 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7427 "mul{q}\t%2"
7428 [(set_attr "type" "imul")
7429 (set_attr "ppro_uops" "few")
7430 (set_attr "length_immediate" "0")
7431 (set_attr "mode" "DI")])
7432
7537 "mul{q}\t%2"
7538 [(set_attr "type" "imul")
7539 (set_attr "ppro_uops" "few")
7540 (set_attr "length_immediate" "0")
7541 (set_attr "mode" "DI")])
7542
7433(define_insn "umulsi3_highpart"
7543(define_expand "umulsi3_highpart"
7544 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7545 (truncate:SI
7546 (lshiftrt:DI
7547 (mult:DI (zero_extend:DI
7548 (match_operand:SI 1 "nonimmediate_operand" ""))
7549 (zero_extend:DI
7550 (match_operand:SI 2 "register_operand" "")))
7551 (const_int 32))))
7552 (clobber (match_scratch:SI 3 ""))
7553 (clobber (reg:CC 17))])]
7554 ""
7555 "")
7556
7557(define_insn "*umulsi3_highpart_insn"
7434 [(set (match_operand:SI 0 "register_operand" "=d")
7435 (truncate:SI
7436 (lshiftrt:DI
7437 (mult:DI (zero_extend:DI
7558 [(set (match_operand:SI 0 "register_operand" "=d")
7559 (truncate:SI
7560 (lshiftrt:DI
7561 (mult:DI (zero_extend:DI
7438 (match_operand:SI 1 "register_operand" "%a"))
7562 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7439 (zero_extend:DI
7440 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7441 (const_int 32))))
7563 (zero_extend:DI
7564 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7565 (const_int 32))))
7442 (clobber (match_scratch:SI 3 "=a"))
7566 (clobber (match_scratch:SI 3 "=1"))
7443 (clobber (reg:CC 17))]
7567 (clobber (reg:CC 17))]
7444 ""
7568 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7445 "mul{l}\t%2"
7446 [(set_attr "type" "imul")
7447 (set_attr "ppro_uops" "few")
7448 (set_attr "length_immediate" "0")
7449 (set_attr "mode" "SI")])
7450
7451(define_insn "*umulsi3_highpart_zext"
7452 [(set (match_operand:DI 0 "register_operand" "=d")
7453 (zero_extend:DI (truncate:SI
7454 (lshiftrt:DI
7455 (mult:DI (zero_extend:DI
7569 "mul{l}\t%2"
7570 [(set_attr "type" "imul")
7571 (set_attr "ppro_uops" "few")
7572 (set_attr "length_immediate" "0")
7573 (set_attr "mode" "SI")])
7574
7575(define_insn "*umulsi3_highpart_zext"
7576 [(set (match_operand:DI 0 "register_operand" "=d")
7577 (zero_extend:DI (truncate:SI
7578 (lshiftrt:DI
7579 (mult:DI (zero_extend:DI
7456 (match_operand:SI 1 "register_operand" "%a"))
7580 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7457 (zero_extend:DI
7458 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7459 (const_int 32)))))
7581 (zero_extend:DI
7582 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7583 (const_int 32)))))
7460 (clobber (match_scratch:SI 3 "=a"))
7584 (clobber (match_scratch:SI 3 "=1"))
7461 (clobber (reg:CC 17))]
7585 (clobber (reg:CC 17))]
7462 "TARGET_64BIT"
7586 "TARGET_64BIT
7587 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7463 "mul{l}\t%2"
7464 [(set_attr "type" "imul")
7465 (set_attr "ppro_uops" "few")
7466 (set_attr "length_immediate" "0")
7467 (set_attr "mode" "SI")])
7468
7588 "mul{l}\t%2"
7589 [(set_attr "type" "imul")
7590 (set_attr "ppro_uops" "few")
7591 (set_attr "length_immediate" "0")
7592 (set_attr "mode" "SI")])
7593
7594(define_expand "smuldi3_highpart"
7595 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7596 (truncate:DI
7597 (lshiftrt:TI
7598 (mult:TI (sign_extend:TI
7599 (match_operand:DI 1 "nonimmediate_operand" ""))
7600 (sign_extend:TI
7601 (match_operand:DI 2 "register_operand" "")))
7602 (const_int 64))))
7603 (clobber (match_scratch:DI 3 ""))
7604 (clobber (reg:CC 17))])]
7605 "TARGET_64BIT"
7606 "")
7607
7469(define_insn "*smuldi3_highpart_rex64"
7470 [(set (match_operand:DI 0 "register_operand" "=d")
7471 (truncate:DI
7472 (lshiftrt:TI
7473 (mult:TI (sign_extend:TI
7608(define_insn "*smuldi3_highpart_rex64"
7609 [(set (match_operand:DI 0 "register_operand" "=d")
7610 (truncate:DI
7611 (lshiftrt:TI
7612 (mult:TI (sign_extend:TI
7474 (match_operand:DI 1 "register_operand" "%a"))
7613 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7475 (sign_extend:TI
7476 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7477 (const_int 64))))
7614 (sign_extend:TI
7615 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7616 (const_int 64))))
7478 (clobber (match_scratch:DI 3 "=a"))
7617 (clobber (match_scratch:DI 3 "=1"))
7479 (clobber (reg:CC 17))]
7618 (clobber (reg:CC 17))]
7480 "TARGET_64BIT"
7619 "TARGET_64BIT
7620 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7481 "imul{q}\t%2"
7482 [(set_attr "type" "imul")
7483 (set_attr "ppro_uops" "few")
7484 (set_attr "mode" "DI")])
7485
7621 "imul{q}\t%2"
7622 [(set_attr "type" "imul")
7623 (set_attr "ppro_uops" "few")
7624 (set_attr "mode" "DI")])
7625
7486(define_insn "smulsi3_highpart"
7626(define_expand "smulsi3_highpart"
7627 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7628 (truncate:SI
7629 (lshiftrt:DI
7630 (mult:DI (sign_extend:DI
7631 (match_operand:SI 1 "nonimmediate_operand" ""))
7632 (sign_extend:DI
7633 (match_operand:SI 2 "register_operand" "")))
7634 (const_int 32))))
7635 (clobber (match_scratch:SI 3 ""))
7636 (clobber (reg:CC 17))])]
7637 ""
7638 "")
7639
7640(define_insn "*smulsi3_highpart_insn"
7487 [(set (match_operand:SI 0 "register_operand" "=d")
7488 (truncate:SI
7489 (lshiftrt:DI
7490 (mult:DI (sign_extend:DI
7641 [(set (match_operand:SI 0 "register_operand" "=d")
7642 (truncate:SI
7643 (lshiftrt:DI
7644 (mult:DI (sign_extend:DI
7491 (match_operand:SI 1 "register_operand" "%a"))
7645 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7492 (sign_extend:DI
7493 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7494 (const_int 32))))
7646 (sign_extend:DI
7647 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7648 (const_int 32))))
7495 (clobber (match_scratch:SI 3 "=a"))
7649 (clobber (match_scratch:SI 3 "=1"))
7496 (clobber (reg:CC 17))]
7650 (clobber (reg:CC 17))]
7497 ""
7651 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7498 "imul{l}\t%2"
7499 [(set_attr "type" "imul")
7500 (set_attr "ppro_uops" "few")
7501 (set_attr "mode" "SI")])
7502
7503(define_insn "*smulsi3_highpart_zext"
7504 [(set (match_operand:DI 0 "register_operand" "=d")
7505 (zero_extend:DI (truncate:SI
7506 (lshiftrt:DI
7507 (mult:DI (sign_extend:DI
7652 "imul{l}\t%2"
7653 [(set_attr "type" "imul")
7654 (set_attr "ppro_uops" "few")
7655 (set_attr "mode" "SI")])
7656
7657(define_insn "*smulsi3_highpart_zext"
7658 [(set (match_operand:DI 0 "register_operand" "=d")
7659 (zero_extend:DI (truncate:SI
7660 (lshiftrt:DI
7661 (mult:DI (sign_extend:DI
7508 (match_operand:SI 1 "register_operand" "%a"))
7662 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7509 (sign_extend:DI
7510 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7511 (const_int 32)))))
7663 (sign_extend:DI
7664 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7665 (const_int 32)))))
7512 (clobber (match_scratch:SI 3 "=a"))
7666 (clobber (match_scratch:SI 3 "=1"))
7513 (clobber (reg:CC 17))]
7667 (clobber (reg:CC 17))]
7514 "TARGET_64BIT"
7668 "TARGET_64BIT
7669 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7515 "imul{l}\t%2"
7516 [(set_attr "type" "imul")
7517 (set_attr "ppro_uops" "few")
7518 (set_attr "mode" "SI")])
7519
7520;; The patterns that match these are at the end of this file.
7521
7522(define_expand "mulxf3"
7523 [(set (match_operand:XF 0 "register_operand" "")
7524 (mult:XF (match_operand:XF 1 "register_operand" "")
7525 (match_operand:XF 2 "register_operand" "")))]
7526 "!TARGET_64BIT && TARGET_80387"
7527 "")
7528
7529(define_expand "multf3"
7530 [(set (match_operand:TF 0 "register_operand" "")
7531 (mult:TF (match_operand:TF 1 "register_operand" "")
7532 (match_operand:TF 2 "register_operand" "")))]
7533 "TARGET_80387"
7534 "")
7535
7536(define_expand "muldf3"
7537 [(set (match_operand:DF 0 "register_operand" "")
7538 (mult:DF (match_operand:DF 1 "register_operand" "")
7539 (match_operand:DF 2 "nonimmediate_operand" "")))]
7540 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7541 "")
7542
7543(define_expand "mulsf3"
7544 [(set (match_operand:SF 0 "register_operand" "")
7545 (mult:SF (match_operand:SF 1 "register_operand" "")
7546 (match_operand:SF 2 "nonimmediate_operand" "")))]
7547 "TARGET_80387 || TARGET_SSE_MATH"
7548 "")
7549
7550;; Divide instructions
7551
7552(define_insn "divqi3"
7553 [(set (match_operand:QI 0 "register_operand" "=a")
7554 (div:QI (match_operand:HI 1 "register_operand" "0")
7555 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7556 (clobber (reg:CC 17))]
7557 "TARGET_QIMODE_MATH"
7558 "idiv{b}\t%2"
7559 [(set_attr "type" "idiv")
7560 (set_attr "mode" "QI")
7561 (set_attr "ppro_uops" "few")])
7562
7563(define_insn "udivqi3"
7564 [(set (match_operand:QI 0 "register_operand" "=a")
7565 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7566 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7567 (clobber (reg:CC 17))]
7568 "TARGET_QIMODE_MATH"
7569 "div{b}\t%2"
7570 [(set_attr "type" "idiv")
7571 (set_attr "mode" "QI")
7572 (set_attr "ppro_uops" "few")])
7573
7574;; The patterns that match these are at the end of this file.
7575
7576(define_expand "divxf3"
7577 [(set (match_operand:XF 0 "register_operand" "")
7578 (div:XF (match_operand:XF 1 "register_operand" "")
7579 (match_operand:XF 2 "register_operand" "")))]
7580 "!TARGET_64BIT && TARGET_80387"
7581 "")
7582
7583(define_expand "divtf3"
7584 [(set (match_operand:TF 0 "register_operand" "")
7585 (div:TF (match_operand:TF 1 "register_operand" "")
7586 (match_operand:TF 2 "register_operand" "")))]
7587 "TARGET_80387"
7588 "")
7589
7590(define_expand "divdf3"
7591 [(set (match_operand:DF 0 "register_operand" "")
7592 (div:DF (match_operand:DF 1 "register_operand" "")
7593 (match_operand:DF 2 "nonimmediate_operand" "")))]
7594 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7595 "")
7596
7597(define_expand "divsf3"
7598 [(set (match_operand:SF 0 "register_operand" "")
7599 (div:SF (match_operand:SF 1 "register_operand" "")
7600 (match_operand:SF 2 "nonimmediate_operand" "")))]
7601 "TARGET_80387 || TARGET_SSE_MATH"
7602 "")
7603
7604;; Remainder instructions.
7605
7606(define_expand "divmoddi4"
7607 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7608 (div:DI (match_operand:DI 1 "register_operand" "")
7609 (match_operand:DI 2 "nonimmediate_operand" "")))
7610 (set (match_operand:DI 3 "register_operand" "")
7611 (mod:DI (match_dup 1) (match_dup 2)))
7612 (clobber (reg:CC 17))])]
7613 "TARGET_64BIT"
7614 "")
7615
7616;; Allow to come the parameter in eax or edx to avoid extra moves.
7617;; Penalize eax case sligthly because it results in worse scheduling
7618;; of code.
7619(define_insn "*divmoddi4_nocltd_rex64"
7620 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7621 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7622 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7623 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7624 (mod:DI (match_dup 2) (match_dup 3)))
7625 (clobber (reg:CC 17))]
7626 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7627 "#"
7628 [(set_attr "type" "multi")])
7629
7630(define_insn "*divmoddi4_cltd_rex64"
7631 [(set (match_operand:DI 0 "register_operand" "=a")
7632 (div:DI (match_operand:DI 2 "register_operand" "a")
7633 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7634 (set (match_operand:DI 1 "register_operand" "=&d")
7635 (mod:DI (match_dup 2) (match_dup 3)))
7636 (clobber (reg:CC 17))]
7637 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7638 "#"
7639 [(set_attr "type" "multi")])
7640
7641(define_insn "*divmoddi_noext_rex64"
7642 [(set (match_operand:DI 0 "register_operand" "=a")
7643 (div:DI (match_operand:DI 1 "register_operand" "0")
7644 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7645 (set (match_operand:DI 3 "register_operand" "=d")
7646 (mod:DI (match_dup 1) (match_dup 2)))
7647 (use (match_operand:DI 4 "register_operand" "3"))
7648 (clobber (reg:CC 17))]
7649 "TARGET_64BIT"
7650 "idiv{q}\t%2"
7651 [(set_attr "type" "idiv")
7652 (set_attr "mode" "DI")
7653 (set_attr "ppro_uops" "few")])
7654
7655(define_split
7656 [(set (match_operand:DI 0 "register_operand" "")
7657 (div:DI (match_operand:DI 1 "register_operand" "")
7658 (match_operand:DI 2 "nonimmediate_operand" "")))
7659 (set (match_operand:DI 3 "register_operand" "")
7660 (mod:DI (match_dup 1) (match_dup 2)))
7661 (clobber (reg:CC 17))]
7662 "TARGET_64BIT && reload_completed"
7663 [(parallel [(set (match_dup 3)
7664 (ashiftrt:DI (match_dup 4) (const_int 63)))
7665 (clobber (reg:CC 17))])
7666 (parallel [(set (match_dup 0)
7667 (div:DI (reg:DI 0) (match_dup 2)))
7668 (set (match_dup 3)
7669 (mod:DI (reg:DI 0) (match_dup 2)))
7670 (use (match_dup 3))
7671 (clobber (reg:CC 17))])]
7672{
7673 /* Avoid use of cltd in favour of a mov+shift. */
7674 if (!TARGET_USE_CLTD && !optimize_size)
7675 {
7676 if (true_regnum (operands[1]))
7677 emit_move_insn (operands[0], operands[1]);
7678 else
7679 emit_move_insn (operands[3], operands[1]);
7680 operands[4] = operands[3];
7681 }
7682 else
7683 {
7684 if (true_regnum (operands[1]))
7685 abort();
7686 operands[4] = operands[1];
7687 }
7688})
7689
7690
7691(define_expand "divmodsi4"
7692 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7693 (div:SI (match_operand:SI 1 "register_operand" "")
7694 (match_operand:SI 2 "nonimmediate_operand" "")))
7695 (set (match_operand:SI 3 "register_operand" "")
7696 (mod:SI (match_dup 1) (match_dup 2)))
7697 (clobber (reg:CC 17))])]
7698 ""
7699 "")
7700
7701;; Allow to come the parameter in eax or edx to avoid extra moves.
7702;; Penalize eax case sligthly because it results in worse scheduling
7703;; of code.
7704(define_insn "*divmodsi4_nocltd"
7705 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7706 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7707 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7708 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7709 (mod:SI (match_dup 2) (match_dup 3)))
7710 (clobber (reg:CC 17))]
7711 "!optimize_size && !TARGET_USE_CLTD"
7712 "#"
7713 [(set_attr "type" "multi")])
7714
7715(define_insn "*divmodsi4_cltd"
7716 [(set (match_operand:SI 0 "register_operand" "=a")
7717 (div:SI (match_operand:SI 2 "register_operand" "a")
7718 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7719 (set (match_operand:SI 1 "register_operand" "=&d")
7720 (mod:SI (match_dup 2) (match_dup 3)))
7721 (clobber (reg:CC 17))]
7722 "optimize_size || TARGET_USE_CLTD"
7723 "#"
7724 [(set_attr "type" "multi")])
7725
7726(define_insn "*divmodsi_noext"
7727 [(set (match_operand:SI 0 "register_operand" "=a")
7728 (div:SI (match_operand:SI 1 "register_operand" "0")
7729 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7730 (set (match_operand:SI 3 "register_operand" "=d")
7731 (mod:SI (match_dup 1) (match_dup 2)))
7732 (use (match_operand:SI 4 "register_operand" "3"))
7733 (clobber (reg:CC 17))]
7734 ""
7735 "idiv{l}\t%2"
7736 [(set_attr "type" "idiv")
7737 (set_attr "mode" "SI")
7738 (set_attr "ppro_uops" "few")])
7739
7740(define_split
7741 [(set (match_operand:SI 0 "register_operand" "")
7742 (div:SI (match_operand:SI 1 "register_operand" "")
7743 (match_operand:SI 2 "nonimmediate_operand" "")))
7744 (set (match_operand:SI 3 "register_operand" "")
7745 (mod:SI (match_dup 1) (match_dup 2)))
7746 (clobber (reg:CC 17))]
7747 "reload_completed"
7748 [(parallel [(set (match_dup 3)
7749 (ashiftrt:SI (match_dup 4) (const_int 31)))
7750 (clobber (reg:CC 17))])
7751 (parallel [(set (match_dup 0)
7752 (div:SI (reg:SI 0) (match_dup 2)))
7753 (set (match_dup 3)
7754 (mod:SI (reg:SI 0) (match_dup 2)))
7755 (use (match_dup 3))
7756 (clobber (reg:CC 17))])]
7757{
7758 /* Avoid use of cltd in favour of a mov+shift. */
7759 if (!TARGET_USE_CLTD && !optimize_size)
7760 {
7761 if (true_regnum (operands[1]))
7762 emit_move_insn (operands[0], operands[1]);
7763 else
7764 emit_move_insn (operands[3], operands[1]);
7765 operands[4] = operands[3];
7766 }
7767 else
7768 {
7769 if (true_regnum (operands[1]))
7770 abort();
7771 operands[4] = operands[1];
7772 }
7773})
7774;; %%% Split me.
7775(define_insn "divmodhi4"
7776 [(set (match_operand:HI 0 "register_operand" "=a")
7777 (div:HI (match_operand:HI 1 "register_operand" "0")
7778 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7779 (set (match_operand:HI 3 "register_operand" "=&d")
7780 (mod:HI (match_dup 1) (match_dup 2)))
7781 (clobber (reg:CC 17))]
7782 "TARGET_HIMODE_MATH"
7783 "cwtd\;idiv{w}\t%2"
7784 [(set_attr "type" "multi")
7785 (set_attr "length_immediate" "0")
7786 (set_attr "mode" "SI")])
7787
7788(define_insn "udivmoddi4"
7789 [(set (match_operand:DI 0 "register_operand" "=a")
7790 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7791 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7792 (set (match_operand:DI 3 "register_operand" "=&d")
7793 (umod:DI (match_dup 1) (match_dup 2)))
7794 (clobber (reg:CC 17))]
7795 "TARGET_64BIT"
7796 "xor{q}\t%3, %3\;div{q}\t%2"
7797 [(set_attr "type" "multi")
7798 (set_attr "length_immediate" "0")
7799 (set_attr "mode" "DI")])
7800
7801(define_insn "*udivmoddi4_noext"
7802 [(set (match_operand:DI 0 "register_operand" "=a")
7803 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7804 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7805 (set (match_operand:DI 3 "register_operand" "=d")
7806 (umod:DI (match_dup 1) (match_dup 2)))
7807 (use (match_dup 3))
7808 (clobber (reg:CC 17))]
7809 "TARGET_64BIT"
7810 "div{q}\t%2"
7811 [(set_attr "type" "idiv")
7812 (set_attr "ppro_uops" "few")
7813 (set_attr "mode" "DI")])
7814
7815(define_split
7816 [(set (match_operand:DI 0 "register_operand" "")
7817 (udiv:DI (match_operand:DI 1 "register_operand" "")
7818 (match_operand:DI 2 "nonimmediate_operand" "")))
7819 (set (match_operand:DI 3 "register_operand" "")
7820 (umod:DI (match_dup 1) (match_dup 2)))
7821 (clobber (reg:CC 17))]
7822 "TARGET_64BIT && reload_completed"
7823 [(set (match_dup 3) (const_int 0))
7824 (parallel [(set (match_dup 0)
7825 (udiv:DI (match_dup 1) (match_dup 2)))
7826 (set (match_dup 3)
7827 (umod:DI (match_dup 1) (match_dup 2)))
7828 (use (match_dup 3))
7829 (clobber (reg:CC 17))])]
7830 "")
7831
7832(define_insn "udivmodsi4"
7833 [(set (match_operand:SI 0 "register_operand" "=a")
7834 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7835 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7836 (set (match_operand:SI 3 "register_operand" "=&d")
7837 (umod:SI (match_dup 1) (match_dup 2)))
7838 (clobber (reg:CC 17))]
7839 ""
7840 "xor{l}\t%3, %3\;div{l}\t%2"
7841 [(set_attr "type" "multi")
7842 (set_attr "length_immediate" "0")
7843 (set_attr "mode" "SI")])
7844
7845(define_insn "*udivmodsi4_noext"
7846 [(set (match_operand:SI 0 "register_operand" "=a")
7847 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7848 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7849 (set (match_operand:SI 3 "register_operand" "=d")
7850 (umod:SI (match_dup 1) (match_dup 2)))
7851 (use (match_dup 3))
7852 (clobber (reg:CC 17))]
7853 ""
7854 "div{l}\t%2"
7855 [(set_attr "type" "idiv")
7856 (set_attr "ppro_uops" "few")
7857 (set_attr "mode" "SI")])
7858
7859(define_split
7860 [(set (match_operand:SI 0 "register_operand" "")
7861 (udiv:SI (match_operand:SI 1 "register_operand" "")
7862 (match_operand:SI 2 "nonimmediate_operand" "")))
7863 (set (match_operand:SI 3 "register_operand" "")
7864 (umod:SI (match_dup 1) (match_dup 2)))
7865 (clobber (reg:CC 17))]
7866 "reload_completed"
7867 [(set (match_dup 3) (const_int 0))
7868 (parallel [(set (match_dup 0)
7869 (udiv:SI (match_dup 1) (match_dup 2)))
7870 (set (match_dup 3)
7871 (umod:SI (match_dup 1) (match_dup 2)))
7872 (use (match_dup 3))
7873 (clobber (reg:CC 17))])]
7874 "")
7875
7876(define_expand "udivmodhi4"
7877 [(set (match_dup 4) (const_int 0))
7878 (parallel [(set (match_operand:HI 0 "register_operand" "")
7879 (udiv:HI (match_operand:HI 1 "register_operand" "")
7880 (match_operand:HI 2 "nonimmediate_operand" "")))
7881 (set (match_operand:HI 3 "register_operand" "")
7882 (umod:HI (match_dup 1) (match_dup 2)))
7883 (use (match_dup 4))
7884 (clobber (reg:CC 17))])]
7885 "TARGET_HIMODE_MATH"
7886 "operands[4] = gen_reg_rtx (HImode);")
7887
7888(define_insn "*udivmodhi_noext"
7889 [(set (match_operand:HI 0 "register_operand" "=a")
7890 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7891 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7892 (set (match_operand:HI 3 "register_operand" "=d")
7893 (umod:HI (match_dup 1) (match_dup 2)))
7894 (use (match_operand:HI 4 "register_operand" "3"))
7895 (clobber (reg:CC 17))]
7896 ""
7897 "div{w}\t%2"
7898 [(set_attr "type" "idiv")
7899 (set_attr "mode" "HI")
7900 (set_attr "ppro_uops" "few")])
7901
7902;; We can not use div/idiv for double division, because it causes
7903;; "division by zero" on the overflow and that's not what we expect
7904;; from truncate. Because true (non truncating) double division is
7905;; never generated, we can't create this insn anyway.
7906;
7907;(define_insn ""
7908; [(set (match_operand:SI 0 "register_operand" "=a")
7909; (truncate:SI
7910; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7911; (zero_extend:DI
7912; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7913; (set (match_operand:SI 3 "register_operand" "=d")
7914; (truncate:SI
7915; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7916; (clobber (reg:CC 17))]
7917; ""
7918; "div{l}\t{%2, %0|%0, %2}"
7919; [(set_attr "type" "idiv")
7920; (set_attr "ppro_uops" "few")])
7921
7922;;- Logical AND instructions
7923
7924;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7925;; Note that this excludes ah.
7926
7927(define_insn "*testdi_1_rex64"
7928 [(set (reg 17)
7929 (compare
7930 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
7931 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
7932 (const_int 0)))]
7933 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7934 "@
7935 test{l}\t{%k1, %k0|%k0, %k1}
7936 test{l}\t{%k1, %k0|%k0, %k1}
7937 test{q}\t{%1, %0|%0, %1}
7938 test{q}\t{%1, %0|%0, %1}
7939 test{q}\t{%1, %0|%0, %1}"
7940 [(set_attr "type" "test")
7941 (set_attr "modrm" "0,1,0,1,1")
7942 (set_attr "mode" "SI,SI,DI,DI,DI")
7943 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7944
7945(define_insn "testsi_1"
7946 [(set (reg 17)
7947 (compare
7948 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
7949 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
7950 (const_int 0)))]
7951 "ix86_match_ccmode (insn, CCNOmode)"
7952 "test{l}\t{%1, %0|%0, %1}"
7953 [(set_attr "type" "test")
7954 (set_attr "modrm" "0,1,1")
7955 (set_attr "mode" "SI")
7956 (set_attr "pent_pair" "uv,np,uv")])
7957
7958(define_expand "testsi_ccno_1"
7959 [(set (reg:CCNO 17)
7960 (compare:CCNO
7961 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7962 (match_operand:SI 1 "nonmemory_operand" ""))
7963 (const_int 0)))]
7964 ""
7965 "")
7966
7967(define_insn "*testhi_1"
7968 [(set (reg 17)
7969 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
7970 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
7971 (const_int 0)))]
7972 "ix86_match_ccmode (insn, CCNOmode)"
7973 "test{w}\t{%1, %0|%0, %1}"
7974 [(set_attr "type" "test")
7975 (set_attr "modrm" "0,1,1")
7976 (set_attr "mode" "HI")
7977 (set_attr "pent_pair" "uv,np,uv")])
7978
7979(define_expand "testqi_ccz_1"
7980 [(set (reg:CCZ 17)
7981 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7982 (match_operand:QI 1 "nonmemory_operand" ""))
7983 (const_int 0)))]
7984 ""
7985 "")
7986
7987(define_insn "*testqi_1"
7988 [(set (reg 17)
7989 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
7990 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
7991 (const_int 0)))]
7992 "ix86_match_ccmode (insn, CCNOmode)"
7993{
7994 if (which_alternative == 3)
7995 {
7996 if (GET_CODE (operands[1]) == CONST_INT
7997 && (INTVAL (operands[1]) & 0xffffff00))
7998 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7999 return "test{l}\t{%1, %k0|%k0, %1}";
8000 }
8001 return "test{b}\t{%1, %0|%0, %1}";
8002}
8003 [(set_attr "type" "test")
8004 (set_attr "modrm" "0,1,1,1")
8005 (set_attr "mode" "QI,QI,QI,SI")
8006 (set_attr "pent_pair" "uv,np,uv,np")])
8007
8008(define_expand "testqi_ext_ccno_0"
8009 [(set (reg:CCNO 17)
8010 (compare:CCNO
8011 (and:SI
8012 (zero_extract:SI
8013 (match_operand 0 "ext_register_operand" "")
8014 (const_int 8)
8015 (const_int 8))
8016 (match_operand 1 "const_int_operand" ""))
8017 (const_int 0)))]
8018 ""
8019 "")
8020
8021(define_insn "*testqi_ext_0"
8022 [(set (reg 17)
8023 (compare
8024 (and:SI
8025 (zero_extract:SI
8026 (match_operand 0 "ext_register_operand" "Q")
8027 (const_int 8)
8028 (const_int 8))
8029 (match_operand 1 "const_int_operand" "n"))
8030 (const_int 0)))]
8031 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
8032 && ix86_match_ccmode (insn, CCNOmode)"
8033 "test{b}\t{%1, %h0|%h0, %1}"
8034 [(set_attr "type" "test")
8035 (set_attr "mode" "QI")
8036 (set_attr "length_immediate" "1")
8037 (set_attr "pent_pair" "np")])
8038
8039(define_insn "*testqi_ext_1"
8040 [(set (reg 17)
8041 (compare
8042 (and:SI
8043 (zero_extract:SI
8044 (match_operand 0 "ext_register_operand" "Q")
8045 (const_int 8)
8046 (const_int 8))
8047 (zero_extend:SI
8048 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
8049 (const_int 0)))]
8050 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8051 "test{b}\t{%1, %h0|%h0, %1}"
8052 [(set_attr "type" "test")
8053 (set_attr "mode" "QI")])
8054
8055(define_insn "*testqi_ext_1_rex64"
8056 [(set (reg 17)
8057 (compare
8058 (and:SI
8059 (zero_extract:SI
8060 (match_operand 0 "ext_register_operand" "Q")
8061 (const_int 8)
8062 (const_int 8))
8063 (zero_extend:SI
8064 (match_operand:QI 1 "register_operand" "Q")))
8065 (const_int 0)))]
8066 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8067 "test{b}\t{%1, %h0|%h0, %1}"
8068 [(set_attr "type" "test")
8069 (set_attr "mode" "QI")])
8070
8071(define_insn "*testqi_ext_2"
8072 [(set (reg 17)
8073 (compare
8074 (and:SI
8075 (zero_extract:SI
8076 (match_operand 0 "ext_register_operand" "Q")
8077 (const_int 8)
8078 (const_int 8))
8079 (zero_extract:SI
8080 (match_operand 1 "ext_register_operand" "Q")
8081 (const_int 8)
8082 (const_int 8)))
8083 (const_int 0)))]
8084 "ix86_match_ccmode (insn, CCNOmode)"
8085 "test{b}\t{%h1, %h0|%h0, %h1}"
8086 [(set_attr "type" "test")
8087 (set_attr "mode" "QI")])
8088
8089;; Combine likes to form bit extractions for some tests. Humor it.
8090(define_insn "*testqi_ext_3"
8091 [(set (reg 17)
8092 (compare (zero_extract:SI
8093 (match_operand 0 "nonimmediate_operand" "rm")
8094 (match_operand:SI 1 "const_int_operand" "")
8095 (match_operand:SI 2 "const_int_operand" ""))
8096 (const_int 0)))]
8097 "ix86_match_ccmode (insn, CCNOmode)
8098 && (GET_MODE (operands[0]) == SImode
8099 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8100 || GET_MODE (operands[0]) == HImode
8101 || GET_MODE (operands[0]) == QImode)"
8102 "#")
8103
8104(define_insn "*testqi_ext_3_rex64"
8105 [(set (reg 17)
8106 (compare (zero_extract:DI
8107 (match_operand 0 "nonimmediate_operand" "rm")
8108 (match_operand:DI 1 "const_int_operand" "")
8109 (match_operand:DI 2 "const_int_operand" ""))
8110 (const_int 0)))]
8111 "TARGET_64BIT
8112 && ix86_match_ccmode (insn, CCNOmode)
8113 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8114 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8115 /* Ensure that resulting mask is zero or sign extended operand. */
8116 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8117 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8118 && INTVAL (operands[1]) > 32))
8119 && (GET_MODE (operands[0]) == SImode
8120 || GET_MODE (operands[0]) == DImode
8121 || GET_MODE (operands[0]) == HImode
8122 || GET_MODE (operands[0]) == QImode)"
8123 "#")
8124
8125(define_split
8126 [(set (reg 17)
8127 (compare (zero_extract
8128 (match_operand 0 "nonimmediate_operand" "")
8129 (match_operand 1 "const_int_operand" "")
8130 (match_operand 2 "const_int_operand" ""))
8131 (const_int 0)))]
8132 "ix86_match_ccmode (insn, CCNOmode)"
8133 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8134{
8135 HOST_WIDE_INT len = INTVAL (operands[1]);
8136 HOST_WIDE_INT pos = INTVAL (operands[2]);
8137 HOST_WIDE_INT mask;
8138 enum machine_mode mode, submode;
8139
8140 mode = GET_MODE (operands[0]);
8141 if (GET_CODE (operands[0]) == MEM)
8142 {
8143 /* ??? Combine likes to put non-volatile mem extractions in QImode
8144 no matter the size of the test. So find a mode that works. */
8145 if (! MEM_VOLATILE_P (operands[0]))
8146 {
8147 mode = smallest_mode_for_size (pos + len, MODE_INT);
8148 operands[0] = adjust_address (operands[0], mode, 0);
8149 }
8150 }
8151 else if (GET_CODE (operands[0]) == SUBREG
8152 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8153 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8154 && pos + len <= GET_MODE_BITSIZE (submode))
8155 {
8156 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8157 mode = submode;
8158 operands[0] = SUBREG_REG (operands[0]);
8159 }
8160 else if (mode == HImode && pos + len <= 8)
8161 {
8162 /* Small HImode tests can be converted to QImode. */
8163 mode = QImode;
8164 operands[0] = gen_lowpart (QImode, operands[0]);
8165 }
8166
8167 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8168 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8169
8170 operands[3] = gen_rtx_AND (mode, operands[0],
8171 GEN_INT (trunc_int_for_mode (mask, mode)));
8172})
8173
8174;; %%% This used to optimize known byte-wide and operations to memory,
8175;; and sometimes to QImode registers. If this is considered useful,
8176;; it should be done with splitters.
8177
8178(define_expand "anddi3"
8179 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8180 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8181 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8182 (clobber (reg:CC 17))]
8183 "TARGET_64BIT"
8184 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8185
8186(define_insn "*anddi_1_rex64"
8187 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8188 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8189 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8190 (clobber (reg:CC 17))]
8191 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8192{
8193 switch (get_attr_type (insn))
8194 {
8195 case TYPE_IMOVX:
8196 {
8197 enum machine_mode mode;
8198
8199 if (GET_CODE (operands[2]) != CONST_INT)
8200 abort ();
8201 if (INTVAL (operands[2]) == 0xff)
8202 mode = QImode;
8203 else if (INTVAL (operands[2]) == 0xffff)
8204 mode = HImode;
8205 else
8206 abort ();
8207
8208 operands[1] = gen_lowpart (mode, operands[1]);
8209 if (mode == QImode)
8210 return "movz{bq|x}\t{%1,%0|%0, %1}";
8211 else
8212 return "movz{wq|x}\t{%1,%0|%0, %1}";
8213 }
8214
8215 default:
8216 if (! rtx_equal_p (operands[0], operands[1]))
8217 abort ();
8218 if (get_attr_mode (insn) == MODE_SI)
8219 return "and{l}\t{%k2, %k0|%k0, %k2}";
8220 else
8221 return "and{q}\t{%2, %0|%0, %2}";
8222 }
8223}
8224 [(set_attr "type" "alu,alu,alu,imovx")
8225 (set_attr "length_immediate" "*,*,*,0")
8226 (set_attr "mode" "SI,DI,DI,DI")])
8227
8228(define_insn "*anddi_2"
8229 [(set (reg 17)
8230 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8231 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8232 (const_int 0)))
8233 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8234 (and:DI (match_dup 1) (match_dup 2)))]
8235 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8236 && ix86_binary_operator_ok (AND, DImode, operands)"
8237 "@
8238 and{l}\t{%k2, %k0|%k0, %k2}
8239 and{q}\t{%2, %0|%0, %2}
8240 and{q}\t{%2, %0|%0, %2}"
8241 [(set_attr "type" "alu")
8242 (set_attr "mode" "SI,DI,DI")])
8243
8244(define_expand "andsi3"
8245 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8246 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8247 (match_operand:SI 2 "general_operand" "")))
8248 (clobber (reg:CC 17))]
8249 ""
8250 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8251
8252(define_insn "*andsi_1"
8253 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8254 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8255 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8256 (clobber (reg:CC 17))]
8257 "ix86_binary_operator_ok (AND, SImode, operands)"
8258{
8259 switch (get_attr_type (insn))
8260 {
8261 case TYPE_IMOVX:
8262 {
8263 enum machine_mode mode;
8264
8265 if (GET_CODE (operands[2]) != CONST_INT)
8266 abort ();
8267 if (INTVAL (operands[2]) == 0xff)
8268 mode = QImode;
8269 else if (INTVAL (operands[2]) == 0xffff)
8270 mode = HImode;
8271 else
8272 abort ();
8273
8274 operands[1] = gen_lowpart (mode, operands[1]);
8275 if (mode == QImode)
8276 return "movz{bl|x}\t{%1,%0|%0, %1}";
8277 else
8278 return "movz{wl|x}\t{%1,%0|%0, %1}";
8279 }
8280
8281 default:
8282 if (! rtx_equal_p (operands[0], operands[1]))
8283 abort ();
8284 return "and{l}\t{%2, %0|%0, %2}";
8285 }
8286}
8287 [(set_attr "type" "alu,alu,imovx")
8288 (set_attr "length_immediate" "*,*,0")
8289 (set_attr "mode" "SI")])
8290
8291(define_split
8292 [(set (match_operand 0 "register_operand" "")
8293 (and (match_dup 0)
8294 (const_int -65536)))
8295 (clobber (reg:CC 17))]
8296 "optimize_size"
8297 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8298 "operands[1] = gen_lowpart (HImode, operands[0]);")
8299
8300(define_split
8301 [(set (match_operand 0 "ext_register_operand" "")
8302 (and (match_dup 0)
8303 (const_int -256)))
8304 (clobber (reg:CC 17))]
8305 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8306 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8307 "operands[1] = gen_lowpart (QImode, operands[0]);")
8308
8309(define_split
8310 [(set (match_operand 0 "ext_register_operand" "")
8311 (and (match_dup 0)
8312 (const_int -65281)))
8313 (clobber (reg:CC 17))]
8314 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8315 [(parallel [(set (zero_extract:SI (match_dup 0)
8316 (const_int 8)
8317 (const_int 8))
8318 (xor:SI
8319 (zero_extract:SI (match_dup 0)
8320 (const_int 8)
8321 (const_int 8))
8322 (zero_extract:SI (match_dup 0)
8323 (const_int 8)
8324 (const_int 8))))
8325 (clobber (reg:CC 17))])]
8326 "operands[0] = gen_lowpart (SImode, operands[0]);")
8327
8328;; See comment for addsi_1_zext why we do use nonimmediate_operand
8329(define_insn "*andsi_1_zext"
8330 [(set (match_operand:DI 0 "register_operand" "=r")
8331 (zero_extend:DI
8332 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8333 (match_operand:SI 2 "general_operand" "rim"))))
8334 (clobber (reg:CC 17))]
8335 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8336 "and{l}\t{%2, %k0|%k0, %2}"
8337 [(set_attr "type" "alu")
8338 (set_attr "mode" "SI")])
8339
8340(define_insn "*andsi_2"
8341 [(set (reg 17)
8342 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8343 (match_operand:SI 2 "general_operand" "rim,ri"))
8344 (const_int 0)))
8345 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8346 (and:SI (match_dup 1) (match_dup 2)))]
8347 "ix86_match_ccmode (insn, CCNOmode)
8348 && ix86_binary_operator_ok (AND, SImode, operands)"
8349 "and{l}\t{%2, %0|%0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "mode" "SI")])
8352
8353;; See comment for addsi_1_zext why we do use nonimmediate_operand
8354(define_insn "*andsi_2_zext"
8355 [(set (reg 17)
8356 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8357 (match_operand:SI 2 "general_operand" "rim"))
8358 (const_int 0)))
8359 (set (match_operand:DI 0 "register_operand" "=r")
8360 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8361 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8362 && ix86_binary_operator_ok (AND, SImode, operands)"
8363 "and{l}\t{%2, %k0|%k0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "mode" "SI")])
8366
8367(define_expand "andhi3"
8368 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8369 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8370 (match_operand:HI 2 "general_operand" "")))
8371 (clobber (reg:CC 17))]
8372 "TARGET_HIMODE_MATH"
8373 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8374
8375(define_insn "*andhi_1"
8376 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8377 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8378 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8379 (clobber (reg:CC 17))]
8380 "ix86_binary_operator_ok (AND, HImode, operands)"
8381{
8382 switch (get_attr_type (insn))
8383 {
8384 case TYPE_IMOVX:
8385 if (GET_CODE (operands[2]) != CONST_INT)
8386 abort ();
8387 if (INTVAL (operands[2]) == 0xff)
8388 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8389 abort ();
8390
8391 default:
8392 if (! rtx_equal_p (operands[0], operands[1]))
8393 abort ();
8394
8395 return "and{w}\t{%2, %0|%0, %2}";
8396 }
8397}
8398 [(set_attr "type" "alu,alu,imovx")
8399 (set_attr "length_immediate" "*,*,0")
8400 (set_attr "mode" "HI,HI,SI")])
8401
8402(define_insn "*andhi_2"
8403 [(set (reg 17)
8404 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8405 (match_operand:HI 2 "general_operand" "rim,ri"))
8406 (const_int 0)))
8407 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8408 (and:HI (match_dup 1) (match_dup 2)))]
8409 "ix86_match_ccmode (insn, CCNOmode)
8410 && ix86_binary_operator_ok (AND, HImode, operands)"
8411 "and{w}\t{%2, %0|%0, %2}"
8412 [(set_attr "type" "alu")
8413 (set_attr "mode" "HI")])
8414
8415(define_expand "andqi3"
8416 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8417 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8418 (match_operand:QI 2 "general_operand" "")))
8419 (clobber (reg:CC 17))]
8420 "TARGET_QIMODE_MATH"
8421 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8422
8423;; %%% Potential partial reg stall on alternative 2. What to do?
8424(define_insn "*andqi_1"
8425 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8426 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8427 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8428 (clobber (reg:CC 17))]
8429 "ix86_binary_operator_ok (AND, QImode, operands)"
8430 "@
8431 and{b}\t{%2, %0|%0, %2}
8432 and{b}\t{%2, %0|%0, %2}
8433 and{l}\t{%k2, %k0|%k0, %k2}"
8434 [(set_attr "type" "alu")
8435 (set_attr "mode" "QI,QI,SI")])
8436
8437(define_insn "*andqi_1_slp"
8438 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8439 (and:QI (match_dup 0)
8440 (match_operand:QI 1 "general_operand" "qi,qmi")))
8441 (clobber (reg:CC 17))]
8442 ""
8443 "and{b}\t{%1, %0|%0, %1}"
8444 [(set_attr "type" "alu1")
8445 (set_attr "mode" "QI")])
8446
8447(define_insn "*andqi_2"
8448 [(set (reg 17)
8449 (compare (and:QI
8450 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8451 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8452 (const_int 0)))
8453 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8454 (and:QI (match_dup 1) (match_dup 2)))]
8455 "ix86_match_ccmode (insn, CCNOmode)
8456 && ix86_binary_operator_ok (AND, QImode, operands)"
8457{
8458 if (which_alternative == 2)
8459 {
8460 if (GET_CODE (operands[2]) == CONST_INT
8461 && (INTVAL (operands[2]) & 0xffffff00))
8462 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8463 return "and{l}\t{%2, %k0|%k0, %2}";
8464 }
8465 return "and{b}\t{%2, %0|%0, %2}";
8466}
8467 [(set_attr "type" "alu")
8468 (set_attr "mode" "QI,QI,SI")])
8469
8470(define_insn "*andqi_2_slp"
8471 [(set (reg 17)
8472 (compare (and:QI
8473 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8474 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8475 (const_int 0)))
8476 (set (strict_low_part (match_dup 0))
8477 (and:QI (match_dup 0) (match_dup 1)))]
8478 "ix86_match_ccmode (insn, CCNOmode)"
8479 "and{b}\t{%1, %0|%0, %1}"
8480 [(set_attr "type" "alu1")
8481 (set_attr "mode" "QI")])
8482
8483;; ??? A bug in recog prevents it from recognizing a const_int as an
8484;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8485;; for a QImode operand, which of course failed.
8486
8487(define_insn "andqi_ext_0"
8488 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8489 (const_int 8)
8490 (const_int 8))
8491 (and:SI
8492 (zero_extract:SI
8493 (match_operand 1 "ext_register_operand" "0")
8494 (const_int 8)
8495 (const_int 8))
8496 (match_operand 2 "const_int_operand" "n")))
8497 (clobber (reg:CC 17))]
8498 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8499 "and{b}\t{%2, %h0|%h0, %2}"
8500 [(set_attr "type" "alu")
8501 (set_attr "length_immediate" "1")
8502 (set_attr "mode" "QI")])
8503
8504;; Generated by peephole translating test to and. This shows up
8505;; often in fp comparisons.
8506
8507(define_insn "*andqi_ext_0_cc"
8508 [(set (reg 17)
8509 (compare
8510 (and:SI
8511 (zero_extract:SI
8512 (match_operand 1 "ext_register_operand" "0")
8513 (const_int 8)
8514 (const_int 8))
8515 (match_operand 2 "const_int_operand" "n"))
8516 (const_int 0)))
8517 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8518 (const_int 8)
8519 (const_int 8))
8520 (and:SI
8521 (zero_extract:SI
8522 (match_dup 1)
8523 (const_int 8)
8524 (const_int 8))
8525 (match_dup 2)))]
8526 "ix86_match_ccmode (insn, CCNOmode)
8527 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8528 "and{b}\t{%2, %h0|%h0, %2}"
8529 [(set_attr "type" "alu")
8530 (set_attr "length_immediate" "1")
8531 (set_attr "mode" "QI")])
8532
8533(define_insn "*andqi_ext_1"
8534 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8535 (const_int 8)
8536 (const_int 8))
8537 (and:SI
8538 (zero_extract:SI
8539 (match_operand 1 "ext_register_operand" "0")
8540 (const_int 8)
8541 (const_int 8))
8542 (zero_extend:SI
8543 (match_operand:QI 2 "general_operand" "Qm"))))
8544 (clobber (reg:CC 17))]
8545 "!TARGET_64BIT"
8546 "and{b}\t{%2, %h0|%h0, %2}"
8547 [(set_attr "type" "alu")
8548 (set_attr "length_immediate" "0")
8549 (set_attr "mode" "QI")])
8550
8551(define_insn "*andqi_ext_1_rex64"
8552 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8553 (const_int 8)
8554 (const_int 8))
8555 (and:SI
8556 (zero_extract:SI
8557 (match_operand 1 "ext_register_operand" "0")
8558 (const_int 8)
8559 (const_int 8))
8560 (zero_extend:SI
8561 (match_operand 2 "ext_register_operand" "Q"))))
8562 (clobber (reg:CC 17))]
8563 "TARGET_64BIT"
8564 "and{b}\t{%2, %h0|%h0, %2}"
8565 [(set_attr "type" "alu")
8566 (set_attr "length_immediate" "0")
8567 (set_attr "mode" "QI")])
8568
8569(define_insn "*andqi_ext_2"
8570 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8571 (const_int 8)
8572 (const_int 8))
8573 (and:SI
8574 (zero_extract:SI
8575 (match_operand 1 "ext_register_operand" "%0")
8576 (const_int 8)
8577 (const_int 8))
8578 (zero_extract:SI
8579 (match_operand 2 "ext_register_operand" "Q")
8580 (const_int 8)
8581 (const_int 8))))
8582 (clobber (reg:CC 17))]
8583 ""
8584 "and{b}\t{%h2, %h0|%h0, %h2}"
8585 [(set_attr "type" "alu")
8586 (set_attr "length_immediate" "0")
8587 (set_attr "mode" "QI")])
8588
8589;; Logical inclusive OR instructions
8590
8591;; %%% This used to optimize known byte-wide and operations to memory.
8592;; If this is considered useful, it should be done with splitters.
8593
8594(define_expand "iordi3"
8595 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8596 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8597 (match_operand:DI 2 "x86_64_general_operand" "")))
8598 (clobber (reg:CC 17))]
8599 "TARGET_64BIT"
8600 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8601
8602(define_insn "*iordi_1_rex64"
8603 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8604 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8605 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8606 (clobber (reg:CC 17))]
8607 "TARGET_64BIT
8608 && ix86_binary_operator_ok (IOR, DImode, operands)"
8609 "or{q}\t{%2, %0|%0, %2}"
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "DI")])
8612
8613(define_insn "*iordi_2_rex64"
8614 [(set (reg 17)
8615 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8616 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8617 (const_int 0)))
8618 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8619 (ior:DI (match_dup 1) (match_dup 2)))]
8620 "TARGET_64BIT
8621 && ix86_match_ccmode (insn, CCNOmode)
8622 && ix86_binary_operator_ok (IOR, DImode, operands)"
8623 "or{q}\t{%2, %0|%0, %2}"
8624 [(set_attr "type" "alu")
8625 (set_attr "mode" "DI")])
8626
8627(define_insn "*iordi_3_rex64"
8628 [(set (reg 17)
8629 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8630 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8631 (const_int 0)))
8632 (clobber (match_scratch:DI 0 "=r"))]
8633 "TARGET_64BIT
8634 && ix86_match_ccmode (insn, CCNOmode)
8635 && ix86_binary_operator_ok (IOR, DImode, operands)"
8636 "or{q}\t{%2, %0|%0, %2}"
8637 [(set_attr "type" "alu")
8638 (set_attr "mode" "DI")])
8639
8640
8641(define_expand "iorsi3"
8642 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8643 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8644 (match_operand:SI 2 "general_operand" "")))
8645 (clobber (reg:CC 17))]
8646 ""
8647 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8648
8649(define_insn "*iorsi_1"
8650 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8651 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8652 (match_operand:SI 2 "general_operand" "ri,rmi")))
8653 (clobber (reg:CC 17))]
8654 "ix86_binary_operator_ok (IOR, SImode, operands)"
8655 "or{l}\t{%2, %0|%0, %2}"
8656 [(set_attr "type" "alu")
8657 (set_attr "mode" "SI")])
8658
8659;; See comment for addsi_1_zext why we do use nonimmediate_operand
8660(define_insn "*iorsi_1_zext"
8661 [(set (match_operand:DI 0 "register_operand" "=rm")
8662 (zero_extend:DI
8663 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8664 (match_operand:SI 2 "general_operand" "rim"))))
8665 (clobber (reg:CC 17))]
8666 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8667 "or{l}\t{%2, %k0|%k0, %2}"
8668 [(set_attr "type" "alu")
8669 (set_attr "mode" "SI")])
8670
8671(define_insn "*iorsi_1_zext_imm"
8672 [(set (match_operand:DI 0 "register_operand" "=rm")
8673 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8674 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8675 (clobber (reg:CC 17))]
8676 "TARGET_64BIT"
8677 "or{l}\t{%2, %k0|%k0, %2}"
8678 [(set_attr "type" "alu")
8679 (set_attr "mode" "SI")])
8680
8681(define_insn "*iorsi_2"
8682 [(set (reg 17)
8683 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8684 (match_operand:SI 2 "general_operand" "rim,ri"))
8685 (const_int 0)))
8686 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8687 (ior:SI (match_dup 1) (match_dup 2)))]
8688 "ix86_match_ccmode (insn, CCNOmode)
8689 && ix86_binary_operator_ok (IOR, SImode, operands)"
8690 "or{l}\t{%2, %0|%0, %2}"
8691 [(set_attr "type" "alu")
8692 (set_attr "mode" "SI")])
8693
8694;; See comment for addsi_1_zext why we do use nonimmediate_operand
8695;; ??? Special case for immediate operand is missing - it is tricky.
8696(define_insn "*iorsi_2_zext"
8697 [(set (reg 17)
8698 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8699 (match_operand:SI 2 "general_operand" "rim"))
8700 (const_int 0)))
8701 (set (match_operand:DI 0 "register_operand" "=r")
8702 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8703 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8704 && ix86_binary_operator_ok (IOR, SImode, operands)"
8705 "or{l}\t{%2, %k0|%k0, %2}"
8706 [(set_attr "type" "alu")
8707 (set_attr "mode" "SI")])
8708
8709(define_insn "*iorsi_2_zext_imm"
8710 [(set (reg 17)
8711 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8712 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8713 (const_int 0)))
8714 (set (match_operand:DI 0 "register_operand" "=r")
8715 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8716 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8717 && ix86_binary_operator_ok (IOR, SImode, operands)"
8718 "or{l}\t{%2, %k0|%k0, %2}"
8719 [(set_attr "type" "alu")
8720 (set_attr "mode" "SI")])
8721
8722(define_insn "*iorsi_3"
8723 [(set (reg 17)
8724 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8725 (match_operand:SI 2 "general_operand" "rim"))
8726 (const_int 0)))
8727 (clobber (match_scratch:SI 0 "=r"))]
8728 "ix86_match_ccmode (insn, CCNOmode)
8729 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8730 "or{l}\t{%2, %0|%0, %2}"
8731 [(set_attr "type" "alu")
8732 (set_attr "mode" "SI")])
8733
8734(define_expand "iorhi3"
8735 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8736 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8737 (match_operand:HI 2 "general_operand" "")))
8738 (clobber (reg:CC 17))]
8739 "TARGET_HIMODE_MATH"
8740 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8741
8742(define_insn "*iorhi_1"
8743 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8744 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8745 (match_operand:HI 2 "general_operand" "rmi,ri")))
8746 (clobber (reg:CC 17))]
8747 "ix86_binary_operator_ok (IOR, HImode, operands)"
8748 "or{w}\t{%2, %0|%0, %2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "mode" "HI")])
8751
8752(define_insn "*iorhi_2"
8753 [(set (reg 17)
8754 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8755 (match_operand:HI 2 "general_operand" "rim,ri"))
8756 (const_int 0)))
8757 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8758 (ior:HI (match_dup 1) (match_dup 2)))]
8759 "ix86_match_ccmode (insn, CCNOmode)
8760 && ix86_binary_operator_ok (IOR, HImode, operands)"
8761 "or{w}\t{%2, %0|%0, %2}"
8762 [(set_attr "type" "alu")
8763 (set_attr "mode" "HI")])
8764
8765(define_insn "*iorhi_3"
8766 [(set (reg 17)
8767 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8768 (match_operand:HI 2 "general_operand" "rim"))
8769 (const_int 0)))
8770 (clobber (match_scratch:HI 0 "=r"))]
8771 "ix86_match_ccmode (insn, CCNOmode)
8772 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8773 "or{w}\t{%2, %0|%0, %2}"
8774 [(set_attr "type" "alu")
8775 (set_attr "mode" "HI")])
8776
8777(define_expand "iorqi3"
8778 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8779 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8780 (match_operand:QI 2 "general_operand" "")))
8781 (clobber (reg:CC 17))]
8782 "TARGET_QIMODE_MATH"
8783 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8784
8785;; %%% Potential partial reg stall on alternative 2. What to do?
8786(define_insn "*iorqi_1"
8787 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8788 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8789 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8790 (clobber (reg:CC 17))]
8791 "ix86_binary_operator_ok (IOR, QImode, operands)"
8792 "@
8793 or{b}\t{%2, %0|%0, %2}
8794 or{b}\t{%2, %0|%0, %2}
8795 or{l}\t{%k2, %k0|%k0, %k2}"
8796 [(set_attr "type" "alu")
8797 (set_attr "mode" "QI,QI,SI")])
8798
8799(define_insn "*iorqi_1_slp"
8800 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8801 (ior:QI (match_dup 0)
8802 (match_operand:QI 1 "general_operand" "qmi,qi")))
8803 (clobber (reg:CC 17))]
8804 ""
8805 "or{b}\t{%1, %0|%0, %1}"
8806 [(set_attr "type" "alu1")
8807 (set_attr "mode" "QI")])
8808
8809(define_insn "*iorqi_2"
8810 [(set (reg 17)
8811 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8812 (match_operand:QI 2 "general_operand" "qim,qi"))
8813 (const_int 0)))
8814 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8815 (ior:QI (match_dup 1) (match_dup 2)))]
8816 "ix86_match_ccmode (insn, CCNOmode)
8817 && ix86_binary_operator_ok (IOR, QImode, operands)"
8818 "or{b}\t{%2, %0|%0, %2}"
8819 [(set_attr "type" "alu")
8820 (set_attr "mode" "QI")])
8821
8822(define_insn "*iorqi_2_slp"
8823 [(set (reg 17)
8824 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8825 (match_operand:QI 1 "general_operand" "qim,qi"))
8826 (const_int 0)))
8827 (set (strict_low_part (match_dup 0))
8828 (ior:QI (match_dup 0) (match_dup 1)))]
8829 "ix86_match_ccmode (insn, CCNOmode)"
8830 "or{b}\t{%1, %0|%0, %1}"
8831 [(set_attr "type" "alu1")
8832 (set_attr "mode" "QI")])
8833
8834(define_insn "*iorqi_3"
8835 [(set (reg 17)
8836 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8837 (match_operand:QI 2 "general_operand" "qim"))
8838 (const_int 0)))
8839 (clobber (match_scratch:QI 0 "=q"))]
8840 "ix86_match_ccmode (insn, CCNOmode)
8841 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8842 "or{b}\t{%2, %0|%0, %2}"
8843 [(set_attr "type" "alu")
8844 (set_attr "mode" "QI")])
8845
8846
8847;; Logical XOR instructions
8848
8849;; %%% This used to optimize known byte-wide and operations to memory.
8850;; If this is considered useful, it should be done with splitters.
8851
8852(define_expand "xordi3"
8853 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8854 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8855 (match_operand:DI 2 "x86_64_general_operand" "")))
8856 (clobber (reg:CC 17))]
8857 "TARGET_64BIT"
8858 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8859
8860(define_insn "*xordi_1_rex64"
8861 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8862 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8863 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8864 (clobber (reg:CC 17))]
8865 "TARGET_64BIT
8866 && ix86_binary_operator_ok (XOR, DImode, operands)"
8867 "@
8868 xor{q}\t{%2, %0|%0, %2}
8869 xor{q}\t{%2, %0|%0, %2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "mode" "DI,DI")])
8872
8873(define_insn "*xordi_2_rex64"
8874 [(set (reg 17)
8875 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8876 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8877 (const_int 0)))
8878 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8879 (xor:DI (match_dup 1) (match_dup 2)))]
8880 "TARGET_64BIT
8881 && ix86_match_ccmode (insn, CCNOmode)
8882 && ix86_binary_operator_ok (XOR, DImode, operands)"
8883 "@
8884 xor{q}\t{%2, %0|%0, %2}
8885 xor{q}\t{%2, %0|%0, %2}"
8886 [(set_attr "type" "alu")
8887 (set_attr "mode" "DI,DI")])
8888
8889(define_insn "*xordi_3_rex64"
8890 [(set (reg 17)
8891 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8892 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8893 (const_int 0)))
8894 (clobber (match_scratch:DI 0 "=r"))]
8895 "TARGET_64BIT
8896 && ix86_match_ccmode (insn, CCNOmode)
8897 && ix86_binary_operator_ok (XOR, DImode, operands)"
8898 "xor{q}\t{%2, %0|%0, %2}"
8899 [(set_attr "type" "alu")
8900 (set_attr "mode" "DI")])
8901
8902(define_expand "xorsi3"
8903 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8904 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8905 (match_operand:SI 2 "general_operand" "")))
8906 (clobber (reg:CC 17))]
8907 ""
8908 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8909
8910(define_insn "*xorsi_1"
8911 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8912 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8913 (match_operand:SI 2 "general_operand" "ri,rm")))
8914 (clobber (reg:CC 17))]
8915 "ix86_binary_operator_ok (XOR, SImode, operands)"
8916 "xor{l}\t{%2, %0|%0, %2}"
8917 [(set_attr "type" "alu")
8918 (set_attr "mode" "SI")])
8919
8920;; See comment for addsi_1_zext why we do use nonimmediate_operand
8921;; Add speccase for immediates
8922(define_insn "*xorsi_1_zext"
8923 [(set (match_operand:DI 0 "register_operand" "=r")
8924 (zero_extend:DI
8925 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8926 (match_operand:SI 2 "general_operand" "rim"))))
8927 (clobber (reg:CC 17))]
8928 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8929 "xor{l}\t{%2, %k0|%k0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "mode" "SI")])
8932
8933(define_insn "*xorsi_1_zext_imm"
8934 [(set (match_operand:DI 0 "register_operand" "=r")
8935 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8936 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8937 (clobber (reg:CC 17))]
8938 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8939 "xor{l}\t{%2, %k0|%k0, %2}"
8940 [(set_attr "type" "alu")
8941 (set_attr "mode" "SI")])
8942
8943(define_insn "*xorsi_2"
8944 [(set (reg 17)
8945 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8946 (match_operand:SI 2 "general_operand" "rim,ri"))
8947 (const_int 0)))
8948 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8949 (xor:SI (match_dup 1) (match_dup 2)))]
8950 "ix86_match_ccmode (insn, CCNOmode)
8951 && ix86_binary_operator_ok (XOR, SImode, operands)"
8952 "xor{l}\t{%2, %0|%0, %2}"
8953 [(set_attr "type" "alu")
8954 (set_attr "mode" "SI")])
8955
8956;; See comment for addsi_1_zext why we do use nonimmediate_operand
8957;; ??? Special case for immediate operand is missing - it is tricky.
8958(define_insn "*xorsi_2_zext"
8959 [(set (reg 17)
8960 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8961 (match_operand:SI 2 "general_operand" "rim"))
8962 (const_int 0)))
8963 (set (match_operand:DI 0 "register_operand" "=r")
8964 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8965 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8966 && ix86_binary_operator_ok (XOR, SImode, operands)"
8967 "xor{l}\t{%2, %k0|%k0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "SI")])
8970
8971(define_insn "*xorsi_2_zext_imm"
8972 [(set (reg 17)
8973 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8974 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8975 (const_int 0)))
8976 (set (match_operand:DI 0 "register_operand" "=r")
8977 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8978 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8979 && ix86_binary_operator_ok (XOR, SImode, operands)"
8980 "xor{l}\t{%2, %k0|%k0, %2}"
8981 [(set_attr "type" "alu")
8982 (set_attr "mode" "SI")])
8983
8984(define_insn "*xorsi_3"
8985 [(set (reg 17)
8986 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8987 (match_operand:SI 2 "general_operand" "rim"))
8988 (const_int 0)))
8989 (clobber (match_scratch:SI 0 "=r"))]
8990 "ix86_match_ccmode (insn, CCNOmode)
8991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8992 "xor{l}\t{%2, %0|%0, %2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "SI")])
8995
8996(define_expand "xorhi3"
8997 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8998 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8999 (match_operand:HI 2 "general_operand" "")))
9000 (clobber (reg:CC 17))]
9001 "TARGET_HIMODE_MATH"
9002 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9003
9004(define_insn "*xorhi_1"
9005 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9006 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9007 (match_operand:HI 2 "general_operand" "rmi,ri")))
9008 (clobber (reg:CC 17))]
9009 "ix86_binary_operator_ok (XOR, HImode, operands)"
9010 "xor{w}\t{%2, %0|%0, %2}"
9011 [(set_attr "type" "alu")
9012 (set_attr "mode" "HI")])
9013
9014(define_insn "*xorhi_2"
9015 [(set (reg 17)
9016 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9017 (match_operand:HI 2 "general_operand" "rim,ri"))
9018 (const_int 0)))
9019 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9020 (xor:HI (match_dup 1) (match_dup 2)))]
9021 "ix86_match_ccmode (insn, CCNOmode)
9022 && ix86_binary_operator_ok (XOR, HImode, operands)"
9023 "xor{w}\t{%2, %0|%0, %2}"
9024 [(set_attr "type" "alu")
9025 (set_attr "mode" "HI")])
9026
9027(define_insn "*xorhi_3"
9028 [(set (reg 17)
9029 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9030 (match_operand:HI 2 "general_operand" "rim"))
9031 (const_int 0)))
9032 (clobber (match_scratch:HI 0 "=r"))]
9033 "ix86_match_ccmode (insn, CCNOmode)
9034 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9035 "xor{w}\t{%2, %0|%0, %2}"
9036 [(set_attr "type" "alu")
9037 (set_attr "mode" "HI")])
9038
9039(define_expand "xorqi3"
9040 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9041 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9042 (match_operand:QI 2 "general_operand" "")))
9043 (clobber (reg:CC 17))]
9044 "TARGET_QIMODE_MATH"
9045 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9046
9047;; %%% Potential partial reg stall on alternative 2. What to do?
9048(define_insn "*xorqi_1"
9049 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9050 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9051 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9052 (clobber (reg:CC 17))]
9053 "ix86_binary_operator_ok (XOR, QImode, operands)"
9054 "@
9055 xor{b}\t{%2, %0|%0, %2}
9056 xor{b}\t{%2, %0|%0, %2}
9057 xor{l}\t{%k2, %k0|%k0, %k2}"
9058 [(set_attr "type" "alu")
9059 (set_attr "mode" "QI,QI,SI")])
9060
9061(define_insn "*xorqi_ext_1"
9062 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9063 (const_int 8)
9064 (const_int 8))
9065 (xor:SI
9066 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9067 (const_int 8)
9068 (const_int 8))
9069 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9070 (const_int 8)
9071 (const_int 8))))
9072 (clobber (reg:CC 17))]
9073 ""
9074 "xor{b}\t{%h2, %h0|%h0, %h2}"
9075 [(set_attr "type" "alu")
9076 (set_attr "length_immediate" "0")
9077 (set_attr "mode" "QI")])
9078
9079(define_insn "*xorqi_cc_1"
9080 [(set (reg 17)
9081 (compare
9082 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9083 (match_operand:QI 2 "general_operand" "qim,qi"))
9084 (const_int 0)))
9085 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9086 (xor:QI (match_dup 1) (match_dup 2)))]
9087 "ix86_match_ccmode (insn, CCNOmode)
9088 && ix86_binary_operator_ok (XOR, QImode, operands)"
9089 "xor{b}\t{%2, %0|%0, %2}"
9090 [(set_attr "type" "alu")
9091 (set_attr "mode" "QI")])
9092
9093(define_insn "*xorqi_cc_2"
9094 [(set (reg 17)
9095 (compare
9096 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9097 (match_operand:QI 2 "general_operand" "qim"))
9098 (const_int 0)))
9099 (clobber (match_scratch:QI 0 "=q"))]
9100 "ix86_match_ccmode (insn, CCNOmode)
9101 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9102 "xor{b}\t{%2, %0|%0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "QI")])
9105
9106(define_insn "*xorqi_cc_ext_1"
9107 [(set (reg 17)
9108 (compare
9109 (xor:SI
9110 (zero_extract:SI
9111 (match_operand 1 "ext_register_operand" "0")
9112 (const_int 8)
9113 (const_int 8))
9114 (match_operand:QI 2 "general_operand" "qmn"))
9115 (const_int 0)))
9116 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9117 (const_int 8)
9118 (const_int 8))
9119 (xor:SI
9120 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9121 (match_dup 2)))]
9122 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9123 "xor{b}\t{%2, %h0|%h0, %2}"
9124 [(set_attr "type" "alu")
9125 (set_attr "mode" "QI")])
9126
9127(define_insn "*xorqi_cc_ext_1_rex64"
9128 [(set (reg 17)
9129 (compare
9130 (xor:SI
9131 (zero_extract:SI
9132 (match_operand 1 "ext_register_operand" "0")
9133 (const_int 8)
9134 (const_int 8))
9135 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9136 (const_int 0)))
9137 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9138 (const_int 8)
9139 (const_int 8))
9140 (xor:SI
9141 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9142 (match_dup 2)))]
9143 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9144 "xor{b}\t{%2, %h0|%h0, %2}"
9145 [(set_attr "type" "alu")
9146 (set_attr "mode" "QI")])
9147
9148(define_expand "xorqi_cc_ext_1"
9149 [(parallel [
9150 (set (reg:CCNO 17)
9151 (compare:CCNO
9152 (xor:SI
9153 (zero_extract:SI
9154 (match_operand 1 "ext_register_operand" "")
9155 (const_int 8)
9156 (const_int 8))
9157 (match_operand:QI 2 "general_operand" ""))
9158 (const_int 0)))
9159 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9160 (const_int 8)
9161 (const_int 8))
9162 (xor:SI
9163 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9164 (match_dup 2)))])]
9165 ""
9166 "")
9167
9168;; Negation instructions
9169
9170(define_expand "negdi2"
9171 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9172 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9173 (clobber (reg:CC 17))])]
9174 ""
9175 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9176
9177(define_insn "*negdi2_1"
9178 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9179 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9180 (clobber (reg:CC 17))]
9181 "!TARGET_64BIT
9182 && ix86_unary_operator_ok (NEG, DImode, operands)"
9183 "#")
9184
9185(define_split
9186 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9187 (neg:DI (match_operand:DI 1 "general_operand" "")))
9188 (clobber (reg:CC 17))]
9189 "!TARGET_64BIT && reload_completed"
9190 [(parallel
9191 [(set (reg:CCZ 17)
9192 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9193 (set (match_dup 0) (neg:SI (match_dup 2)))])
9194 (parallel
9195 [(set (match_dup 1)
9196 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9197 (match_dup 3))
9198 (const_int 0)))
9199 (clobber (reg:CC 17))])
9200 (parallel
9201 [(set (match_dup 1)
9202 (neg:SI (match_dup 1)))
9203 (clobber (reg:CC 17))])]
9204 "split_di (operands+1, 1, operands+2, operands+3);
9205 split_di (operands+0, 1, operands+0, operands+1);")
9206
9207(define_insn "*negdi2_1_rex64"
9208 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9209 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9210 (clobber (reg:CC 17))]
9211 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9212 "neg{q}\t%0"
9213 [(set_attr "type" "negnot")
9214 (set_attr "mode" "DI")])
9215
9216;; The problem with neg is that it does not perform (compare x 0),
9217;; it really performs (compare 0 x), which leaves us with the zero
9218;; flag being the only useful item.
9219
9220(define_insn "*negdi2_cmpz_rex64"
9221 [(set (reg:CCZ 17)
9222 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9223 (const_int 0)))
9224 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9225 (neg:DI (match_dup 1)))]
9226 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9227 "neg{q}\t%0"
9228 [(set_attr "type" "negnot")
9229 (set_attr "mode" "DI")])
9230
9231
9232(define_expand "negsi2"
9233 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9234 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9235 (clobber (reg:CC 17))])]
9236 ""
9237 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9238
9239(define_insn "*negsi2_1"
9240 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9241 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9242 (clobber (reg:CC 17))]
9243 "ix86_unary_operator_ok (NEG, SImode, operands)"
9244 "neg{l}\t%0"
9245 [(set_attr "type" "negnot")
9246 (set_attr "mode" "SI")])
9247
9248;; Combine is quite creative about this pattern.
9249(define_insn "*negsi2_1_zext"
9250 [(set (match_operand:DI 0 "register_operand" "=r")
9251 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9252 (const_int 32)))
9253 (const_int 32)))
9254 (clobber (reg:CC 17))]
9255 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9256 "neg{l}\t%k0"
9257 [(set_attr "type" "negnot")
9258 (set_attr "mode" "SI")])
9259
9260;; The problem with neg is that it does not perform (compare x 0),
9261;; it really performs (compare 0 x), which leaves us with the zero
9262;; flag being the only useful item.
9263
9264(define_insn "*negsi2_cmpz"
9265 [(set (reg:CCZ 17)
9266 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9267 (const_int 0)))
9268 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9269 (neg:SI (match_dup 1)))]
9270 "ix86_unary_operator_ok (NEG, SImode, operands)"
9271 "neg{l}\t%0"
9272 [(set_attr "type" "negnot")
9273 (set_attr "mode" "SI")])
9274
9275(define_insn "*negsi2_cmpz_zext"
9276 [(set (reg:CCZ 17)
9277 (compare:CCZ (lshiftrt:DI
9278 (neg:DI (ashift:DI
9279 (match_operand:DI 1 "register_operand" "0")
9280 (const_int 32)))
9281 (const_int 32))
9282 (const_int 0)))
9283 (set (match_operand:DI 0 "register_operand" "=r")
9284 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9285 (const_int 32)))
9286 (const_int 32)))]
9287 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9288 "neg{l}\t%k0"
9289 [(set_attr "type" "negnot")
9290 (set_attr "mode" "SI")])
9291
9292(define_expand "neghi2"
9293 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9294 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9295 (clobber (reg:CC 17))])]
9296 "TARGET_HIMODE_MATH"
9297 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9298
9299(define_insn "*neghi2_1"
9300 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9301 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9302 (clobber (reg:CC 17))]
9303 "ix86_unary_operator_ok (NEG, HImode, operands)"
9304 "neg{w}\t%0"
9305 [(set_attr "type" "negnot")
9306 (set_attr "mode" "HI")])
9307
9308(define_insn "*neghi2_cmpz"
9309 [(set (reg:CCZ 17)
9310 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9311 (const_int 0)))
9312 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9313 (neg:HI (match_dup 1)))]
9314 "ix86_unary_operator_ok (NEG, HImode, operands)"
9315 "neg{w}\t%0"
9316 [(set_attr "type" "negnot")
9317 (set_attr "mode" "HI")])
9318
9319(define_expand "negqi2"
9320 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9321 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9322 (clobber (reg:CC 17))])]
9323 "TARGET_QIMODE_MATH"
9324 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9325
9326(define_insn "*negqi2_1"
9327 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9328 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9329 (clobber (reg:CC 17))]
9330 "ix86_unary_operator_ok (NEG, QImode, operands)"
9331 "neg{b}\t%0"
9332 [(set_attr "type" "negnot")
9333 (set_attr "mode" "QI")])
9334
9335(define_insn "*negqi2_cmpz"
9336 [(set (reg:CCZ 17)
9337 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9338 (const_int 0)))
9339 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9340 (neg:QI (match_dup 1)))]
9341 "ix86_unary_operator_ok (NEG, QImode, operands)"
9342 "neg{b}\t%0"
9343 [(set_attr "type" "negnot")
9344 (set_attr "mode" "QI")])
9345
9346;; Changing of sign for FP values is doable using integer unit too.
9347
9348(define_expand "negsf2"
9349 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9350 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9351 (clobber (reg:CC 17))])]
9352 "TARGET_80387"
9353 "if (TARGET_SSE)
9354 {
9355 /* In case operand is in memory, we will not use SSE. */
9356 if (memory_operand (operands[0], VOIDmode)
9357 && rtx_equal_p (operands[0], operands[1]))
9358 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9359 else
9360 {
9361 /* Using SSE is tricky, since we need bitwise negation of -0
9362 in register. */
9363 rtx reg = gen_reg_rtx (SFmode);
9364 rtx dest = operands[0];
9365
9366 operands[1] = force_reg (SFmode, operands[1]);
9367 operands[0] = force_reg (SFmode, operands[0]);
9368 emit_move_insn (reg,
9369 gen_lowpart (SFmode,
9370 GEN_INT (trunc_int_for_mode (0x80000000,
9371 SImode))));
9372 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9373 if (dest != operands[0])
9374 emit_move_insn (dest, operands[0]);
9375 }
9376 DONE;
9377 }
9378 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9379
9380(define_insn "negsf2_memory"
9381 [(set (match_operand:SF 0 "memory_operand" "=m")
9382 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9383 (clobber (reg:CC 17))]
9384 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9385 "#")
9386
9387(define_insn "negsf2_ifs"
9388 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9389 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9390 (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
9391 (clobber (reg:CC 17))]
9392 "TARGET_SSE
9393 && (reload_in_progress || reload_completed
9394 || (register_operand (operands[0], VOIDmode)
9395 && register_operand (operands[1], VOIDmode)))"
9396 "#")
9397
9398(define_split
9399 [(set (match_operand:SF 0 "memory_operand" "")
9400 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9401 (use (match_operand:SF 2 "" ""))
9402 (clobber (reg:CC 17))]
9403 ""
9404 [(parallel [(set (match_dup 0)
9405 (neg:SF (match_dup 1)))
9406 (clobber (reg:CC 17))])])
9407
9408(define_split
9409 [(set (match_operand:SF 0 "register_operand" "")
9410 (neg:SF (match_operand:SF 1 "register_operand" "")))
9411 (use (match_operand:SF 2 "" ""))
9412 (clobber (reg:CC 17))]
9413 "reload_completed && !SSE_REG_P (operands[0])"
9414 [(parallel [(set (match_dup 0)
9415 (neg:SF (match_dup 1)))
9416 (clobber (reg:CC 17))])])
9417
9418(define_split
9419 [(set (match_operand:SF 0 "register_operand" "")
9420 (neg:SF (match_operand:SF 1 "register_operand" "")))
9421 (use (match_operand:SF 2 "register_operand" ""))
9422 (clobber (reg:CC 17))]
9423 "reload_completed && SSE_REG_P (operands[0])"
9424 [(set (subreg:TI (match_dup 0) 0)
9425 (xor:TI (subreg:TI (match_dup 1) 0)
9426 (subreg:TI (match_dup 2) 0)))]
9427{
9428 if (operands_match_p (operands[0], operands[2]))
9429 {
9430 rtx tmp;
9431 tmp = operands[1];
9432 operands[1] = operands[2];
9433 operands[2] = tmp;
9434 }
9435})
9436
9437
9438;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9439;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9440;; to itself.
9441(define_insn "*negsf2_if"
9442 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9443 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9444 (clobber (reg:CC 17))]
9445 "TARGET_80387 && !TARGET_SSE
9446 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9447 "#")
9448
9449(define_split
9450 [(set (match_operand:SF 0 "register_operand" "")
9451 (neg:SF (match_operand:SF 1 "register_operand" "")))
9452 (clobber (reg:CC 17))]
9453 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9454 [(set (match_dup 0)
9455 (neg:SF (match_dup 1)))]
9456 "")
9457
9458(define_split
9459 [(set (match_operand:SF 0 "register_operand" "")
9460 (neg:SF (match_operand:SF 1 "register_operand" "")))
9461 (clobber (reg:CC 17))]
9462 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9463 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9464 (clobber (reg:CC 17))])]
9465 "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9466 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9467
9468(define_split
9469 [(set (match_operand 0 "memory_operand" "")
9470 (neg (match_operand 1 "memory_operand" "")))
9471 (clobber (reg:CC 17))]
9472 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9473 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9474 (clobber (reg:CC 17))])]
9475{
9476 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9477
9478 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9479 if (size >= 12)
9480 size = 10;
9481 operands[0] = adjust_address (operands[0], QImode, size - 1);
9482 operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
9483})
9484
9485(define_expand "negdf2"
9486 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9487 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9488 (clobber (reg:CC 17))])]
9489 "TARGET_80387"
9490 "if (TARGET_SSE2)
9491 {
9492 /* In case operand is in memory, we will not use SSE. */
9493 if (memory_operand (operands[0], VOIDmode)
9494 && rtx_equal_p (operands[0], operands[1]))
9495 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9496 else
9497 {
9498 /* Using SSE is tricky, since we need bitwise negation of -0
9499 in register. */
9500 rtx reg = gen_reg_rtx (DFmode);
9501#if HOST_BITS_PER_WIDE_INT >= 64
9502 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9503 DImode));
9504#else
9505 rtx imm = immed_double_const (0, 0x80000000, DImode);
9506#endif
9507 rtx dest = operands[0];
9508
9509 operands[1] = force_reg (DFmode, operands[1]);
9510 operands[0] = force_reg (DFmode, operands[0]);
9511 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9512 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9513 if (dest != operands[0])
9514 emit_move_insn (dest, operands[0]);
9515 }
9516 DONE;
9517 }
9518 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9519
9520(define_insn "negdf2_memory"
9521 [(set (match_operand:DF 0 "memory_operand" "=m")
9522 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9523 (clobber (reg:CC 17))]
9524 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9525 "#")
9526
9527(define_insn "negdf2_ifs"
9528 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9529 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9530 (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
9531 (clobber (reg:CC 17))]
9532 "!TARGET_64BIT && TARGET_SSE2
9533 && (reload_in_progress || reload_completed
9534 || (register_operand (operands[0], VOIDmode)
9535 && register_operand (operands[1], VOIDmode)))"
9536 "#")
9537
9538(define_insn "*negdf2_ifs_rex64"
9539 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
9540 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9541 (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
9542 (clobber (reg:CC 17))]
9543 "TARGET_64BIT && TARGET_SSE2
9544 && (reload_in_progress || reload_completed
9545 || (register_operand (operands[0], VOIDmode)
9546 && register_operand (operands[1], VOIDmode)))"
9547 "#")
9548
9549(define_split
9550 [(set (match_operand:DF 0 "memory_operand" "")
9551 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9552 (use (match_operand:DF 2 "" ""))
9553 (clobber (reg:CC 17))]
9554 ""
9555 [(parallel [(set (match_dup 0)
9556 (neg:DF (match_dup 1)))
9557 (clobber (reg:CC 17))])])
9558
9559(define_split
9560 [(set (match_operand:DF 0 "register_operand" "")
9561 (neg:DF (match_operand:DF 1 "register_operand" "")))
9562 (use (match_operand:DF 2 "" ""))
9563 (clobber (reg:CC 17))]
9564 "reload_completed && !SSE_REG_P (operands[0])
9565 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9566 [(parallel [(set (match_dup 0)
9567 (neg:DF (match_dup 1)))
9568 (clobber (reg:CC 17))])])
9569
9570(define_split
9571 [(set (match_operand:DF 0 "register_operand" "")
9572 (neg:DF (match_operand:DF 1 "register_operand" "")))
9573 (use (match_operand:DF 2 "" ""))
9574 (clobber (reg:CC 17))]
9575 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9576 [(parallel [(set (match_dup 0)
9577 (xor:DI (match_dup 1) (match_dup 2)))
9578 (clobber (reg:CC 17))])]
9579 "operands[0] = gen_lowpart (DImode, operands[0]);
9580 operands[1] = gen_lowpart (DImode, operands[1]);
9581 operands[2] = gen_lowpart (DImode, operands[2]);")
9582
9583(define_split
9584 [(set (match_operand:DF 0 "register_operand" "")
9585 (neg:DF (match_operand:DF 1 "register_operand" "")))
9586 (use (match_operand:DF 2 "register_operand" ""))
9587 (clobber (reg:CC 17))]
9588 "reload_completed && SSE_REG_P (operands[0])"
9589 [(set (subreg:TI (match_dup 0) 0)
9590 (xor:TI (subreg:TI (match_dup 1) 0)
9591 (subreg:TI (match_dup 2) 0)))]
9592{
9593 if (operands_match_p (operands[0], operands[2]))
9594 {
9595 rtx tmp;
9596 tmp = operands[1];
9597 operands[1] = operands[2];
9598 operands[2] = tmp;
9599 }
9600})
9601
9602;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9603;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9604;; to itself.
9605(define_insn "*negdf2_if"
9606 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9607 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9608 (clobber (reg:CC 17))]
9609 "!TARGET_64BIT && TARGET_80387
9610 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9611 "#")
9612
9613;; FIXME: We should to allow integer registers here. Problem is that
9614;; we need another scratch register to get constant from.
9615;; Forcing constant to mem if no register available in peep2 should be
9616;; safe even for PIC mode, because of RIP relative addressing.
9617(define_insn "*negdf2_if_rex64"
9618 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9619 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9620 (clobber (reg:CC 17))]
9621 "TARGET_64BIT && TARGET_80387
9622 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9623 "#")
9624
9625(define_split
9626 [(set (match_operand:DF 0 "register_operand" "")
9627 (neg:DF (match_operand:DF 1 "register_operand" "")))
9628 (clobber (reg:CC 17))]
9629 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9630 [(set (match_dup 0)
9631 (neg:DF (match_dup 1)))]
9632 "")
9633
9634(define_split
9635 [(set (match_operand:DF 0 "register_operand" "")
9636 (neg:DF (match_operand:DF 1 "register_operand" "")))
9637 (clobber (reg:CC 17))]
9638 "!TARGET_64BIT && TARGET_80387 && reload_completed
9639 && !FP_REGNO_P (REGNO (operands[0]))"
9640 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9641 (clobber (reg:CC 17))])]
9642 "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9643 split_di (operands+0, 1, operands+2, operands+3);")
9644
9645(define_expand "negxf2"
9646 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9647 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9648 (clobber (reg:CC 17))])]
9649 "!TARGET_64BIT && TARGET_80387"
9650 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9651
9652(define_expand "negtf2"
9653 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9654 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9655 (clobber (reg:CC 17))])]
9656 "TARGET_80387"
9657 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9658
9659;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9660;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9661;; to itself.
9662(define_insn "*negxf2_if"
9663 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9664 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9665 (clobber (reg:CC 17))]
9666 "!TARGET_64BIT && TARGET_80387
9667 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9668 "#")
9669
9670(define_split
9671 [(set (match_operand:XF 0 "register_operand" "")
9672 (neg:XF (match_operand:XF 1 "register_operand" "")))
9673 (clobber (reg:CC 17))]
9674 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9675 [(set (match_dup 0)
9676 (neg:XF (match_dup 1)))]
9677 "")
9678
9679(define_split
9680 [(set (match_operand:XF 0 "register_operand" "")
9681 (neg:XF (match_operand:XF 1 "register_operand" "")))
9682 (clobber (reg:CC 17))]
9683 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9684 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9685 (clobber (reg:CC 17))])]
9686 "operands[1] = GEN_INT (0x8000);
9687 operands[0] = gen_rtx_REG (SImode,
9688 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9689
9690;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9691;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9692;; to itself.
9693(define_insn "*negtf2_if"
9694 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9695 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9696 (clobber (reg:CC 17))]
9697 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9698 "#")
9699
9700(define_split
9701 [(set (match_operand:TF 0 "register_operand" "")
9702 (neg:TF (match_operand:TF 1 "register_operand" "")))
9703 (clobber (reg:CC 17))]
9704 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9705 [(set (match_dup 0)
9706 (neg:TF (match_dup 1)))]
9707 "")
9708
9709(define_split
9710 [(set (match_operand:TF 0 "register_operand" "")
9711 (neg:TF (match_operand:TF 1 "register_operand" "")))
9712 (clobber (reg:CC 17))]
9713 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9714 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9715 (clobber (reg:CC 17))])]
9716 "operands[1] = GEN_INT (0x8000);
9717 operands[0] = gen_rtx_REG (SImode,
9718 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9719
9720;; Conditionize these after reload. If they matches before reload, we
9721;; lose the clobber and ability to use integer instructions.
9722
9723(define_insn "*negsf2_1"
9724 [(set (match_operand:SF 0 "register_operand" "=f")
9725 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9726 "TARGET_80387 && reload_completed"
9727 "fchs"
9728 [(set_attr "type" "fsgn")
9729 (set_attr "mode" "SF")
9730 (set_attr "ppro_uops" "few")])
9731
9732(define_insn "*negdf2_1"
9733 [(set (match_operand:DF 0 "register_operand" "=f")
9734 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9735 "TARGET_80387 && reload_completed"
9736 "fchs"
9737 [(set_attr "type" "fsgn")
9738 (set_attr "mode" "DF")
9739 (set_attr "ppro_uops" "few")])
9740
9741(define_insn "*negextendsfdf2"
9742 [(set (match_operand:DF 0 "register_operand" "=f")
9743 (neg:DF (float_extend:DF
9744 (match_operand:SF 1 "register_operand" "0"))))]
9745 "TARGET_80387"
9746 "fchs"
9747 [(set_attr "type" "fsgn")
9748 (set_attr "mode" "DF")
9749 (set_attr "ppro_uops" "few")])
9750
9751(define_insn "*negxf2_1"
9752 [(set (match_operand:XF 0 "register_operand" "=f")
9753 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9754 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9755 "fchs"
9756 [(set_attr "type" "fsgn")
9757 (set_attr "mode" "XF")
9758 (set_attr "ppro_uops" "few")])
9759
9760(define_insn "*negextenddfxf2"
9761 [(set (match_operand:XF 0 "register_operand" "=f")
9762 (neg:XF (float_extend:XF
9763 (match_operand:DF 1 "register_operand" "0"))))]
9764 "!TARGET_64BIT && TARGET_80387"
9765 "fchs"
9766 [(set_attr "type" "fsgn")
9767 (set_attr "mode" "XF")
9768 (set_attr "ppro_uops" "few")])
9769
9770(define_insn "*negextendsfxf2"
9771 [(set (match_operand:XF 0 "register_operand" "=f")
9772 (neg:XF (float_extend:XF
9773 (match_operand:SF 1 "register_operand" "0"))))]
9774 "!TARGET_64BIT && TARGET_80387"
9775 "fchs"
9776 [(set_attr "type" "fsgn")
9777 (set_attr "mode" "XF")
9778 (set_attr "ppro_uops" "few")])
9779
9780(define_insn "*negtf2_1"
9781 [(set (match_operand:TF 0 "register_operand" "=f")
9782 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9783 "TARGET_80387 && reload_completed"
9784 "fchs"
9785 [(set_attr "type" "fsgn")
9786 (set_attr "mode" "XF")
9787 (set_attr "ppro_uops" "few")])
9788
9789(define_insn "*negextenddftf2"
9790 [(set (match_operand:TF 0 "register_operand" "=f")
9791 (neg:TF (float_extend:TF
9792 (match_operand:DF 1 "register_operand" "0"))))]
9793 "TARGET_80387"
9794 "fchs"
9795 [(set_attr "type" "fsgn")
9796 (set_attr "mode" "XF")
9797 (set_attr "ppro_uops" "few")])
9798
9799(define_insn "*negextendsftf2"
9800 [(set (match_operand:TF 0 "register_operand" "=f")
9801 (neg:TF (float_extend:TF
9802 (match_operand:SF 1 "register_operand" "0"))))]
9803 "TARGET_80387"
9804 "fchs"
9805 [(set_attr "type" "fsgn")
9806 (set_attr "mode" "XF")
9807 (set_attr "ppro_uops" "few")])
9808
9809;; Absolute value instructions
9810
9811(define_expand "abssf2"
9812 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9813 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9814 (clobber (reg:CC 17))])]
9815 "TARGET_80387"
9816 "if (TARGET_SSE)
9817 {
9818 /* In case operand is in memory, we will not use SSE. */
9819 if (memory_operand (operands[0], VOIDmode)
9820 && rtx_equal_p (operands[0], operands[1]))
9821 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9822 else
9823 {
9824 /* Using SSE is tricky, since we need bitwise negation of -0
9825 in register. */
9826 rtx reg = gen_reg_rtx (SFmode);
9827 rtx dest = operands[0];
9828
9829 operands[1] = force_reg (SFmode, operands[1]);
9830 operands[0] = force_reg (SFmode, operands[0]);
9831 emit_move_insn (reg,
9832 gen_lowpart (SFmode,
9833 GEN_INT (trunc_int_for_mode (0x80000000,
9834 SImode))));
9835 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9836 if (dest != operands[0])
9837 emit_move_insn (dest, operands[0]);
9838 }
9839 DONE;
9840 }
9841 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9842
9843(define_insn "abssf2_memory"
9844 [(set (match_operand:SF 0 "memory_operand" "=m")
9845 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9846 (clobber (reg:CC 17))]
9847 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9848 "#")
9849
9850(define_insn "abssf2_ifs"
9851 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
9852 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
9853 (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
9854 (clobber (reg:CC 17))]
9855 "TARGET_SSE
9856 && (reload_in_progress || reload_completed
9857 || (register_operand (operands[0], VOIDmode)
9858 && register_operand (operands[1], VOIDmode)))"
9859 "#")
9860
9861(define_split
9862 [(set (match_operand:SF 0 "memory_operand" "")
9863 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9864 (use (match_operand:SF 2 "" ""))
9865 (clobber (reg:CC 17))]
9866 ""
9867 [(parallel [(set (match_dup 0)
9868 (abs:SF (match_dup 1)))
9869 (clobber (reg:CC 17))])])
9870
9871(define_split
9872 [(set (match_operand:SF 0 "register_operand" "")
9873 (abs:SF (match_operand:SF 1 "register_operand" "")))
9874 (use (match_operand:SF 2 "" ""))
9875 (clobber (reg:CC 17))]
9876 "reload_completed && !SSE_REG_P (operands[0])"
9877 [(parallel [(set (match_dup 0)
9878 (abs:SF (match_dup 1)))
9879 (clobber (reg:CC 17))])])
9880
9881(define_split
9882 [(set (match_operand:SF 0 "register_operand" "")
9883 (abs:SF (match_operand:SF 1 "register_operand" "")))
9884 (use (match_operand:SF 2 "register_operand" ""))
9885 (clobber (reg:CC 17))]
9886 "reload_completed && SSE_REG_P (operands[0])"
9887 [(set (subreg:TI (match_dup 0) 0)
9888 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9889 (subreg:TI (match_dup 1) 0)))])
9890
9891;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9892;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9893;; to itself.
9894(define_insn "*abssf2_if"
9895 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9896 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9897 (clobber (reg:CC 17))]
9898 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
9899 "#")
9900
9901(define_split
9902 [(set (match_operand:SF 0 "register_operand" "")
9903 (abs:SF (match_operand:SF 1 "register_operand" "")))
9904 (clobber (reg:CC 17))]
9905 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
9906 [(set (match_dup 0)
9907 (abs:SF (match_dup 1)))]
9908 "")
9909
9910(define_split
9911 [(set (match_operand:SF 0 "register_operand" "")
9912 (abs:SF (match_operand:SF 1 "register_operand" "")))
9913 (clobber (reg:CC 17))]
9914 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9915 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9916 (clobber (reg:CC 17))])]
9917 "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
9918 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9919
9920(define_split
9921 [(set (match_operand 0 "memory_operand" "")
9922 (abs (match_operand 1 "memory_operand" "")))
9923 (clobber (reg:CC 17))]
9924 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9925 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9926 (clobber (reg:CC 17))])]
9927{
9928 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9929
9930 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9931 if (size >= 12)
9932 size = 10;
9933 operands[0] = adjust_address (operands[0], QImode, size - 1);
9934 operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
9935})
9936
9937(define_expand "absdf2"
9938 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9939 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9940 (clobber (reg:CC 17))])]
9941 "TARGET_80387"
9942 "if (TARGET_SSE2)
9943 {
9944 /* In case operand is in memory, we will not use SSE. */
9945 if (memory_operand (operands[0], VOIDmode)
9946 && rtx_equal_p (operands[0], operands[1]))
9947 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9948 else
9949 {
9950 /* Using SSE is tricky, since we need bitwise negation of -0
9951 in register. */
9952 rtx reg = gen_reg_rtx (DFmode);
9953#if HOST_BITS_PER_WIDE_INT >= 64
9954 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9955 DImode));
9956#else
9957 rtx imm = immed_double_const (0, 0x80000000, DImode);
9958#endif
9959 rtx dest = operands[0];
9960
9961 operands[1] = force_reg (DFmode, operands[1]);
9962 operands[0] = force_reg (DFmode, operands[0]);
9963 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9964 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
9965 if (dest != operands[0])
9966 emit_move_insn (dest, operands[0]);
9967 }
9968 DONE;
9969 }
9970 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9971
9972(define_insn "absdf2_memory"
9973 [(set (match_operand:DF 0 "memory_operand" "=m")
9974 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9975 (clobber (reg:CC 17))]
9976 "ix86_unary_operator_ok (ABS, DFmode, operands)"
9977 "#")
9978
9979(define_insn "absdf2_ifs"
9980 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
9981 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
9982 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
9983 (clobber (reg:CC 17))]
9984 "!TARGET_64BIT && TARGET_SSE2
9985 && (reload_in_progress || reload_completed
9986 || (register_operand (operands[0], VOIDmode)
9987 && register_operand (operands[1], VOIDmode)))"
9988 "#")
9989
9990(define_insn "*absdf2_ifs_rex64"
9991 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
9992 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
9993 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
9994 (clobber (reg:CC 17))]
9995 "TARGET_64BIT && TARGET_SSE2
9996 && (reload_in_progress || reload_completed
9997 || (register_operand (operands[0], VOIDmode)
9998 && register_operand (operands[1], VOIDmode)))"
9999 "#")
10000
10001(define_split
10002 [(set (match_operand:DF 0 "memory_operand" "")
10003 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10004 (use (match_operand:DF 2 "" ""))
10005 (clobber (reg:CC 17))]
10006 ""
10007 [(parallel [(set (match_dup 0)
10008 (abs:DF (match_dup 1)))
10009 (clobber (reg:CC 17))])])
10010
10011(define_split
10012 [(set (match_operand:DF 0 "register_operand" "")
10013 (abs:DF (match_operand:DF 1 "register_operand" "")))
10014 (use (match_operand:DF 2 "" ""))
10015 (clobber (reg:CC 17))]
10016 "reload_completed && !SSE_REG_P (operands[0])"
10017 [(parallel [(set (match_dup 0)
10018 (abs:DF (match_dup 1)))
10019 (clobber (reg:CC 17))])])
10020
10021(define_split
10022 [(set (match_operand:DF 0 "register_operand" "")
10023 (abs:DF (match_operand:DF 1 "register_operand" "")))
10024 (use (match_operand:DF 2 "register_operand" ""))
10025 (clobber (reg:CC 17))]
10026 "reload_completed && SSE_REG_P (operands[0])"
10027 [(set (subreg:TI (match_dup 0) 0)
10028 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
10029 (subreg:TI (match_dup 1) 0)))])
10030
10031
10032;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10033;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10034;; to itself.
10035(define_insn "*absdf2_if"
10036 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10037 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10038 (clobber (reg:CC 17))]
10039 "!TARGET_64BIT && TARGET_80387
10040 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10041 "#")
10042
10043;; FIXME: We should to allow integer registers here. Problem is that
10044;; we need another scratch register to get constant from.
10045;; Forcing constant to mem if no register available in peep2 should be
10046;; safe even for PIC mode, because of RIP relative addressing.
10047(define_insn "*absdf2_if_rex64"
10048 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10049 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10050 (clobber (reg:CC 17))]
10051 "TARGET_64BIT && TARGET_80387
10052 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10053 "#")
10054
10055(define_split
10056 [(set (match_operand:DF 0 "register_operand" "")
10057 (abs:DF (match_operand:DF 1 "register_operand" "")))
10058 (clobber (reg:CC 17))]
10059 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10060 [(set (match_dup 0)
10061 (abs:DF (match_dup 1)))]
10062 "")
10063
10064(define_split
10065 [(set (match_operand:DF 0 "register_operand" "")
10066 (abs:DF (match_operand:DF 1 "register_operand" "")))
10067 (clobber (reg:CC 17))]
10068 "!TARGET_64BIT && TARGET_80387 && reload_completed &&
10069 !FP_REGNO_P (REGNO (operands[0]))"
10070 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10071 (clobber (reg:CC 17))])]
10072 "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
10073 split_di (operands+0, 1, operands+2, operands+3);")
10074
10075(define_expand "absxf2"
10076 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10077 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10078 (clobber (reg:CC 17))])]
10079 "!TARGET_64BIT && TARGET_80387"
10080 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10081
10082(define_expand "abstf2"
10083 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10084 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10085 (clobber (reg:CC 17))])]
10086 "TARGET_80387"
10087 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10088
10089;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10090;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10091;; to itself.
10092(define_insn "*absxf2_if"
10093 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10094 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10095 (clobber (reg:CC 17))]
10096 "!TARGET_64BIT && TARGET_80387
10097 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10098 "#")
10099
10100(define_split
10101 [(set (match_operand:XF 0 "register_operand" "")
10102 (abs:XF (match_operand:XF 1 "register_operand" "")))
10103 (clobber (reg:CC 17))]
10104 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10105 [(set (match_dup 0)
10106 (abs:XF (match_dup 1)))]
10107 "")
10108
10109(define_split
10110 [(set (match_operand:XF 0 "register_operand" "")
10111 (abs:XF (match_operand:XF 1 "register_operand" "")))
10112 (clobber (reg:CC 17))]
10113 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10114 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10115 (clobber (reg:CC 17))])]
10116 "operands[1] = GEN_INT (~0x8000);
10117 operands[0] = gen_rtx_REG (SImode,
10118 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10119
10120(define_insn "*abstf2_if"
10121 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10122 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10123 (clobber (reg:CC 17))]
10124 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10125 "#")
10126
10127(define_split
10128 [(set (match_operand:TF 0 "register_operand" "")
10129 (abs:TF (match_operand:TF 1 "register_operand" "")))
10130 (clobber (reg:CC 17))]
10131 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10132 [(set (match_dup 0)
10133 (abs:TF (match_dup 1)))]
10134 "")
10135
10136(define_split
10137 [(set (match_operand:TF 0 "register_operand" "")
10138 (abs:TF (match_operand:TF 1 "register_operand" "")))
10139 (clobber (reg:CC 17))]
10140 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10141 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10142 (clobber (reg:CC 17))])]
10143 "operands[1] = GEN_INT (~0x8000);
10144 operands[0] = gen_rtx_REG (SImode,
10145 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10146
10147(define_insn "*abssf2_1"
10148 [(set (match_operand:SF 0 "register_operand" "=f")
10149 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10150 "TARGET_80387 && reload_completed"
10151 "fabs"
10152 [(set_attr "type" "fsgn")
10153 (set_attr "mode" "SF")])
10154
10155(define_insn "*absdf2_1"
10156 [(set (match_operand:DF 0 "register_operand" "=f")
10157 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10158 "TARGET_80387 && reload_completed"
10159 "fabs"
10160 [(set_attr "type" "fsgn")
10161 (set_attr "mode" "DF")])
10162
10163(define_insn "*absextendsfdf2"
10164 [(set (match_operand:DF 0 "register_operand" "=f")
10165 (abs:DF (float_extend:DF
10166 (match_operand:SF 1 "register_operand" "0"))))]
10167 "TARGET_80387"
10168 "fabs"
10169 [(set_attr "type" "fsgn")
10170 (set_attr "mode" "DF")])
10171
10172(define_insn "*absxf2_1"
10173 [(set (match_operand:XF 0 "register_operand" "=f")
10174 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10175 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10176 "fabs"
10177 [(set_attr "type" "fsgn")
10178 (set_attr "mode" "DF")])
10179
10180(define_insn "*absextenddfxf2"
10181 [(set (match_operand:XF 0 "register_operand" "=f")
10182 (abs:XF (float_extend:XF
10183 (match_operand:DF 1 "register_operand" "0"))))]
10184 "!TARGET_64BIT && TARGET_80387"
10185 "fabs"
10186 [(set_attr "type" "fsgn")
10187 (set_attr "mode" "XF")])
10188
10189(define_insn "*absextendsfxf2"
10190 [(set (match_operand:XF 0 "register_operand" "=f")
10191 (abs:XF (float_extend:XF
10192 (match_operand:SF 1 "register_operand" "0"))))]
10193 "!TARGET_64BIT && TARGET_80387"
10194 "fabs"
10195 [(set_attr "type" "fsgn")
10196 (set_attr "mode" "XF")])
10197
10198(define_insn "*abstf2_1"
10199 [(set (match_operand:TF 0 "register_operand" "=f")
10200 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10201 "TARGET_80387 && reload_completed"
10202 "fabs"
10203 [(set_attr "type" "fsgn")
10204 (set_attr "mode" "DF")])
10205
10206(define_insn "*absextenddftf2"
10207 [(set (match_operand:TF 0 "register_operand" "=f")
10208 (abs:TF (float_extend:TF
10209 (match_operand:DF 1 "register_operand" "0"))))]
10210 "TARGET_80387"
10211 "fabs"
10212 [(set_attr "type" "fsgn")
10213 (set_attr "mode" "XF")])
10214
10215(define_insn "*absextendsftf2"
10216 [(set (match_operand:TF 0 "register_operand" "=f")
10217 (abs:TF (float_extend:TF
10218 (match_operand:SF 1 "register_operand" "0"))))]
10219 "TARGET_80387"
10220 "fabs"
10221 [(set_attr "type" "fsgn")
10222 (set_attr "mode" "XF")])
10223
10224;; One complement instructions
10225
10226(define_expand "one_cmpldi2"
10227 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10228 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10229 "TARGET_64BIT"
10230 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10231
10232(define_insn "*one_cmpldi2_1_rex64"
10233 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10234 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10235 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10236 "not{q}\t%0"
10237 [(set_attr "type" "negnot")
10238 (set_attr "mode" "DI")])
10239
10240(define_insn "*one_cmpldi2_2_rex64"
10241 [(set (reg 17)
10242 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10243 (const_int 0)))
10244 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10245 (not:DI (match_dup 1)))]
10246 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10247 && ix86_unary_operator_ok (NOT, DImode, operands)"
10248 "#"
10249 [(set_attr "type" "alu1")
10250 (set_attr "mode" "DI")])
10251
10252(define_split
10253 [(set (reg 17)
10254 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10255 (const_int 0)))
10256 (set (match_operand:DI 0 "nonimmediate_operand" "")
10257 (not:DI (match_dup 1)))]
10258 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10259 [(parallel [(set (reg:CCNO 17)
10260 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10261 (const_int 0)))
10262 (set (match_dup 0)
10263 (xor:DI (match_dup 1) (const_int -1)))])]
10264 "")
10265
10266(define_expand "one_cmplsi2"
10267 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10268 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10269 ""
10270 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10271
10272(define_insn "*one_cmplsi2_1"
10273 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10274 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10275 "ix86_unary_operator_ok (NOT, SImode, operands)"
10276 "not{l}\t%0"
10277 [(set_attr "type" "negnot")
10278 (set_attr "mode" "SI")])
10279
10280;; ??? Currently never generated - xor is used instead.
10281(define_insn "*one_cmplsi2_1_zext"
10282 [(set (match_operand:DI 0 "register_operand" "=r")
10283 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10284 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10285 "not{l}\t%k0"
10286 [(set_attr "type" "negnot")
10287 (set_attr "mode" "SI")])
10288
10289(define_insn "*one_cmplsi2_2"
10290 [(set (reg 17)
10291 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10292 (const_int 0)))
10293 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10294 (not:SI (match_dup 1)))]
10295 "ix86_match_ccmode (insn, CCNOmode)
10296 && ix86_unary_operator_ok (NOT, SImode, operands)"
10297 "#"
10298 [(set_attr "type" "alu1")
10299 (set_attr "mode" "SI")])
10300
10301(define_split
10302 [(set (reg 17)
10303 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10304 (const_int 0)))
10305 (set (match_operand:SI 0 "nonimmediate_operand" "")
10306 (not:SI (match_dup 1)))]
10307 "ix86_match_ccmode (insn, CCNOmode)"
10308 [(parallel [(set (reg:CCNO 17)
10309 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10310 (const_int 0)))
10311 (set (match_dup 0)
10312 (xor:SI (match_dup 1) (const_int -1)))])]
10313 "")
10314
10315;; ??? Currently never generated - xor is used instead.
10316(define_insn "*one_cmplsi2_2_zext"
10317 [(set (reg 17)
10318 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10319 (const_int 0)))
10320 (set (match_operand:DI 0 "register_operand" "=r")
10321 (zero_extend:DI (not:SI (match_dup 1))))]
10322 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10323 && ix86_unary_operator_ok (NOT, SImode, operands)"
10324 "#"
10325 [(set_attr "type" "alu1")
10326 (set_attr "mode" "SI")])
10327
10328(define_split
10329 [(set (reg 17)
10330 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10331 (const_int 0)))
10332 (set (match_operand:DI 0 "register_operand" "")
10333 (zero_extend:DI (not:SI (match_dup 1))))]
10334 "ix86_match_ccmode (insn, CCNOmode)"
10335 [(parallel [(set (reg:CCNO 17)
10336 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10337 (const_int 0)))
10338 (set (match_dup 0)
10339 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10340 "")
10341
10342(define_expand "one_cmplhi2"
10343 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10344 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10345 "TARGET_HIMODE_MATH"
10346 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10347
10348(define_insn "*one_cmplhi2_1"
10349 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10350 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10351 "ix86_unary_operator_ok (NOT, HImode, operands)"
10352 "not{w}\t%0"
10353 [(set_attr "type" "negnot")
10354 (set_attr "mode" "HI")])
10355
10356(define_insn "*one_cmplhi2_2"
10357 [(set (reg 17)
10358 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10359 (const_int 0)))
10360 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10361 (not:HI (match_dup 1)))]
10362 "ix86_match_ccmode (insn, CCNOmode)
10363 && ix86_unary_operator_ok (NEG, HImode, operands)"
10364 "#"
10365 [(set_attr "type" "alu1")
10366 (set_attr "mode" "HI")])
10367
10368(define_split
10369 [(set (reg 17)
10370 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10371 (const_int 0)))
10372 (set (match_operand:HI 0 "nonimmediate_operand" "")
10373 (not:HI (match_dup 1)))]
10374 "ix86_match_ccmode (insn, CCNOmode)"
10375 [(parallel [(set (reg:CCNO 17)
10376 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10377 (const_int 0)))
10378 (set (match_dup 0)
10379 (xor:HI (match_dup 1) (const_int -1)))])]
10380 "")
10381
10382;; %%% Potential partial reg stall on alternative 1. What to do?
10383(define_expand "one_cmplqi2"
10384 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10385 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10386 "TARGET_QIMODE_MATH"
10387 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10388
10389(define_insn "*one_cmplqi2_1"
10390 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10391 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10392 "ix86_unary_operator_ok (NOT, QImode, operands)"
10393 "@
10394 not{b}\t%0
10395 not{l}\t%k0"
10396 [(set_attr "type" "negnot")
10397 (set_attr "mode" "QI,SI")])
10398
10399(define_insn "*one_cmplqi2_2"
10400 [(set (reg 17)
10401 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10402 (const_int 0)))
10403 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10404 (not:QI (match_dup 1)))]
10405 "ix86_match_ccmode (insn, CCNOmode)
10406 && ix86_unary_operator_ok (NOT, QImode, operands)"
10407 "#"
10408 [(set_attr "type" "alu1")
10409 (set_attr "mode" "QI")])
10410
10411(define_split
10412 [(set (reg 17)
10413 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10414 (const_int 0)))
10415 (set (match_operand:QI 0 "nonimmediate_operand" "")
10416 (not:QI (match_dup 1)))]
10417 "ix86_match_ccmode (insn, CCNOmode)"
10418 [(parallel [(set (reg:CCNO 17)
10419 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10420 (const_int 0)))
10421 (set (match_dup 0)
10422 (xor:QI (match_dup 1) (const_int -1)))])]
10423 "")
10424
10425;; Arithmetic shift instructions
10426
10427;; DImode shifts are implemented using the i386 "shift double" opcode,
10428;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10429;; is variable, then the count is in %cl and the "imm" operand is dropped
10430;; from the assembler input.
10431;;
10432;; This instruction shifts the target reg/mem as usual, but instead of
10433;; shifting in zeros, bits are shifted in from reg operand. If the insn
10434;; is a left shift double, bits are taken from the high order bits of
10435;; reg, else if the insn is a shift right double, bits are taken from the
10436;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10437;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10438;;
10439;; Since sh[lr]d does not change the `reg' operand, that is done
10440;; separately, making all shifts emit pairs of shift double and normal
10441;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10442;; support a 63 bit shift, each shift where the count is in a reg expands
10443;; to a pair of shifts, a branch, a shift by 32 and a label.
10444;;
10445;; If the shift count is a constant, we need never emit more than one
10446;; shift pair, instead using moves and sign extension for counts greater
10447;; than 31.
10448
10449(define_expand "ashldi3"
10450 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10451 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10452 (match_operand:QI 2 "nonmemory_operand" "")))
10453 (clobber (reg:CC 17))])]
10454 ""
10455{
10456 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10457 {
10458 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10459 DONE;
10460 }
10461 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10462 DONE;
10463})
10464
10465(define_insn "*ashldi3_1_rex64"
10466 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10467 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10468 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10469 (clobber (reg:CC 17))]
10470 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10471{
10472 switch (get_attr_type (insn))
10473 {
10474 case TYPE_ALU:
10475 if (operands[2] != const1_rtx)
10476 abort ();
10477 if (!rtx_equal_p (operands[0], operands[1]))
10478 abort ();
10479 return "add{q}\t{%0, %0|%0, %0}";
10480
10481 case TYPE_LEA:
10482 if (GET_CODE (operands[2]) != CONST_INT
10483 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10484 abort ();
10485 operands[1] = gen_rtx_MULT (DImode, operands[1],
10486 GEN_INT (1 << INTVAL (operands[2])));
10487 return "lea{q}\t{%a1, %0|%0, %a1}";
10488
10489 default:
10490 if (REG_P (operands[2]))
10491 return "sal{q}\t{%b2, %0|%0, %b2}";
10492 else if (GET_CODE (operands[2]) == CONST_INT
10493 && INTVAL (operands[2]) == 1
10494 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10495 return "sal{q}\t%0";
10496 else
10497 return "sal{q}\t{%2, %0|%0, %2}";
10498 }
10499}
10500 [(set (attr "type")
10501 (cond [(eq_attr "alternative" "1")
10502 (const_string "lea")
10503 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10504 (const_int 0))
10505 (match_operand 0 "register_operand" ""))
10506 (match_operand 2 "const1_operand" ""))
10507 (const_string "alu")
10508 ]
10509 (const_string "ishift")))
10510 (set_attr "mode" "DI")])
10511
10512;; Convert lea to the lea pattern to avoid flags dependency.
10513(define_split
10514 [(set (match_operand:DI 0 "register_operand" "")
10515 (ashift:DI (match_operand:DI 1 "register_operand" "")
10516 (match_operand:QI 2 "immediate_operand" "")))
10517 (clobber (reg:CC 17))]
10518 "TARGET_64BIT && reload_completed
10519 && true_regnum (operands[0]) != true_regnum (operands[1])"
10520 [(set (match_dup 0)
10521 (mult:DI (match_dup 1)
10522 (match_dup 2)))]
10523 "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10524 DImode));")
10525
10526;; This pattern can't accept a variable shift count, since shifts by
10527;; zero don't affect the flags. We assume that shifts by constant
10528;; zero are optimized away.
10529(define_insn "*ashldi3_cmp_rex64"
10530 [(set (reg 17)
10531 (compare
10532 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10533 (match_operand:QI 2 "immediate_operand" "e"))
10534 (const_int 0)))
10535 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10536 (ashift:DI (match_dup 1) (match_dup 2)))]
10537 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10538 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10539{
10540 switch (get_attr_type (insn))
10541 {
10542 case TYPE_ALU:
10543 if (operands[2] != const1_rtx)
10544 abort ();
10545 return "add{q}\t{%0, %0|%0, %0}";
10546
10547 default:
10548 if (REG_P (operands[2]))
10549 return "sal{q}\t{%b2, %0|%0, %b2}";
10550 else if (GET_CODE (operands[2]) == CONST_INT
10551 && INTVAL (operands[2]) == 1
10552 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10553 return "sal{q}\t%0";
10554 else
10555 return "sal{q}\t{%2, %0|%0, %2}";
10556 }
10557}
10558 [(set (attr "type")
10559 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10560 (const_int 0))
10561 (match_operand 0 "register_operand" ""))
10562 (match_operand 2 "const1_operand" ""))
10563 (const_string "alu")
10564 ]
10565 (const_string "ishift")))
10566 (set_attr "mode" "DI")])
10567
10568(define_insn "ashldi3_1"
10569 [(set (match_operand:DI 0 "register_operand" "=r")
10570 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10571 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10572 (clobber (match_scratch:SI 3 "=&r"))
10573 (clobber (reg:CC 17))]
10574 "!TARGET_64BIT && TARGET_CMOVE"
10575 "#"
10576 [(set_attr "type" "multi")])
10577
10578(define_insn "*ashldi3_2"
10579 [(set (match_operand:DI 0 "register_operand" "=r")
10580 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10581 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10582 (clobber (reg:CC 17))]
10583 "!TARGET_64BIT"
10584 "#"
10585 [(set_attr "type" "multi")])
10586
10587(define_split
10588 [(set (match_operand:DI 0 "register_operand" "")
10589 (ashift:DI (match_operand:DI 1 "register_operand" "")
10590 (match_operand:QI 2 "nonmemory_operand" "")))
10591 (clobber (match_scratch:SI 3 ""))
10592 (clobber (reg:CC 17))]
10593 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10594 [(const_int 0)]
10595 "ix86_split_ashldi (operands, operands[3]); DONE;")
10596
10597(define_split
10598 [(set (match_operand:DI 0 "register_operand" "")
10599 (ashift:DI (match_operand:DI 1 "register_operand" "")
10600 (match_operand:QI 2 "nonmemory_operand" "")))
10601 (clobber (reg:CC 17))]
10602 "!TARGET_64BIT && reload_completed"
10603 [(const_int 0)]
10604 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10605
10606(define_insn "x86_shld_1"
10607 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10608 (ior:SI (ashift:SI (match_dup 0)
10609 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10610 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10611 (minus:QI (const_int 32) (match_dup 2)))))
10612 (clobber (reg:CC 17))]
10613 ""
10614 "@
10615 shld{l}\t{%2, %1, %0|%0, %1, %2}
10616 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10617 [(set_attr "type" "ishift")
10618 (set_attr "prefix_0f" "1")
10619 (set_attr "mode" "SI")
10620 (set_attr "pent_pair" "np")
10621 (set_attr "athlon_decode" "vector")
10622 (set_attr "ppro_uops" "few")])
10623
10624(define_expand "x86_shift_adj_1"
10625 [(set (reg:CCZ 17)
10626 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10627 (const_int 32))
10628 (const_int 0)))
10629 (set (match_operand:SI 0 "register_operand" "")
10630 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10631 (match_operand:SI 1 "register_operand" "")
10632 (match_dup 0)))
10633 (set (match_dup 1)
10634 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10635 (match_operand:SI 3 "register_operand" "r")
10636 (match_dup 1)))]
10637 "TARGET_CMOVE"
10638 "")
10639
10640(define_expand "x86_shift_adj_2"
10641 [(use (match_operand:SI 0 "register_operand" ""))
10642 (use (match_operand:SI 1 "register_operand" ""))
10643 (use (match_operand:QI 2 "register_operand" ""))]
10644 ""
10645{
10646 rtx label = gen_label_rtx ();
10647 rtx tmp;
10648
10649 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10650
10651 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10652 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10653 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10654 gen_rtx_LABEL_REF (VOIDmode, label),
10655 pc_rtx);
10656 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10657 JUMP_LABEL (tmp) = label;
10658
10659 emit_move_insn (operands[0], operands[1]);
10660 emit_move_insn (operands[1], const0_rtx);
10661
10662 emit_label (label);
10663 LABEL_NUSES (label) = 1;
10664
10665 DONE;
10666})
10667
10668(define_expand "ashlsi3"
10669 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10670 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10671 (match_operand:QI 2 "nonmemory_operand" "")))
10672 (clobber (reg:CC 17))]
10673 ""
10674 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10675
10676(define_insn "*ashlsi3_1"
10677 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10678 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10679 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10680 (clobber (reg:CC 17))]
10681 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682{
10683 switch (get_attr_type (insn))
10684 {
10685 case TYPE_ALU:
10686 if (operands[2] != const1_rtx)
10687 abort ();
10688 if (!rtx_equal_p (operands[0], operands[1]))
10689 abort ();
10690 return "add{l}\t{%0, %0|%0, %0}";
10691
10692 case TYPE_LEA:
10693 return "#";
10694
10695 default:
10696 if (REG_P (operands[2]))
10697 return "sal{l}\t{%b2, %0|%0, %b2}";
10698 else if (GET_CODE (operands[2]) == CONST_INT
10699 && INTVAL (operands[2]) == 1
10700 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10701 return "sal{l}\t%0";
10702 else
10703 return "sal{l}\t{%2, %0|%0, %2}";
10704 }
10705}
10706 [(set (attr "type")
10707 (cond [(eq_attr "alternative" "1")
10708 (const_string "lea")
10709 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10710 (const_int 0))
10711 (match_operand 0 "register_operand" ""))
10712 (match_operand 2 "const1_operand" ""))
10713 (const_string "alu")
10714 ]
10715 (const_string "ishift")))
10716 (set_attr "mode" "SI")])
10717
10718;; Convert lea to the lea pattern to avoid flags dependency.
10719(define_split
10720 [(set (match_operand 0 "register_operand" "")
10721 (ashift (match_operand 1 "register_operand" "")
10722 (match_operand:QI 2 "const_int_operand" "")))
10723 (clobber (reg:CC 17))]
10724 "reload_completed
10725 && true_regnum (operands[0]) != true_regnum (operands[1])"
10726 [(const_int 0)]
10727{
10728 rtx pat;
10729 operands[0] = gen_lowpart (SImode, operands[0]);
10730 operands[1] = gen_lowpart (Pmode, operands[1]);
10731 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10732 Pmode));
10733 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10734 if (Pmode != SImode)
10735 pat = gen_rtx_SUBREG (SImode, pat, 0);
10736 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10737 DONE;
10738})
10739
10740(define_insn "*ashlsi3_1_zext"
10741 [(set (match_operand:DI 0 "register_operand" "=r,r")
10742 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10743 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10744 (clobber (reg:CC 17))]
10745 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10746{
10747 switch (get_attr_type (insn))
10748 {
10749 case TYPE_ALU:
10750 if (operands[2] != const1_rtx)
10751 abort ();
10752 return "add{l}\t{%k0, %k0|%k0, %k0}";
10753
10754 case TYPE_LEA:
10755 return "#";
10756
10757 default:
10758 if (REG_P (operands[2]))
10759 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10760 else if (GET_CODE (operands[2]) == CONST_INT
10761 && INTVAL (operands[2]) == 1
10762 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10763 return "sal{l}\t%k0";
10764 else
10765 return "sal{l}\t{%2, %k0|%k0, %2}";
10766 }
10767}
10768 [(set (attr "type")
10769 (cond [(eq_attr "alternative" "1")
10770 (const_string "lea")
10771 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10772 (const_int 0))
10773 (match_operand 2 "const1_operand" ""))
10774 (const_string "alu")
10775 ]
10776 (const_string "ishift")))
10777 (set_attr "mode" "SI")])
10778
10779;; Convert lea to the lea pattern to avoid flags dependency.
10780(define_split
10781 [(set (match_operand:DI 0 "register_operand" "")
10782 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10783 (match_operand:QI 2 "const_int_operand" ""))))
10784 (clobber (reg:CC 17))]
10785 "reload_completed
10786 && true_regnum (operands[0]) != true_regnum (operands[1])"
10787 [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10788{
10789 operands[1] = gen_lowpart (Pmode, operands[1]);
10790 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10791 Pmode));
10792})
10793
10794;; This pattern can't accept a variable shift count, since shifts by
10795;; zero don't affect the flags. We assume that shifts by constant
10796;; zero are optimized away.
10797(define_insn "*ashlsi3_cmp"
10798 [(set (reg 17)
10799 (compare
10800 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10801 (match_operand:QI 2 "immediate_operand" "I"))
10802 (const_int 0)))
10803 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10804 (ashift:SI (match_dup 1) (match_dup 2)))]
10805 "ix86_match_ccmode (insn, CCGOCmode)
10806 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10807{
10808 switch (get_attr_type (insn))
10809 {
10810 case TYPE_ALU:
10811 if (operands[2] != const1_rtx)
10812 abort ();
10813 return "add{l}\t{%0, %0|%0, %0}";
10814
10815 default:
10816 if (REG_P (operands[2]))
10817 return "sal{l}\t{%b2, %0|%0, %b2}";
10818 else if (GET_CODE (operands[2]) == CONST_INT
10819 && INTVAL (operands[2]) == 1
10820 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10821 return "sal{l}\t%0";
10822 else
10823 return "sal{l}\t{%2, %0|%0, %2}";
10824 }
10825}
10826 [(set (attr "type")
10827 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10828 (const_int 0))
10829 (match_operand 0 "register_operand" ""))
10830 (match_operand 2 "const1_operand" ""))
10831 (const_string "alu")
10832 ]
10833 (const_string "ishift")))
10834 (set_attr "mode" "SI")])
10835
10836(define_insn "*ashlsi3_cmp_zext"
10837 [(set (reg 17)
10838 (compare
10839 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10840 (match_operand:QI 2 "immediate_operand" "I"))
10841 (const_int 0)))
10842 (set (match_operand:DI 0 "register_operand" "=r")
10843 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10844 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10845 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10846{
10847 switch (get_attr_type (insn))
10848 {
10849 case TYPE_ALU:
10850 if (operands[2] != const1_rtx)
10851 abort ();
10852 return "add{l}\t{%k0, %k0|%k0, %k0}";
10853
10854 default:
10855 if (REG_P (operands[2]))
10856 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10857 else if (GET_CODE (operands[2]) == CONST_INT
10858 && INTVAL (operands[2]) == 1
10859 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10860 return "sal{l}\t%k0";
10861 else
10862 return "sal{l}\t{%2, %k0|%k0, %2}";
10863 }
10864}
10865 [(set (attr "type")
10866 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10867 (const_int 0))
10868 (match_operand 2 "const1_operand" ""))
10869 (const_string "alu")
10870 ]
10871 (const_string "ishift")))
10872 (set_attr "mode" "SI")])
10873
10874(define_expand "ashlhi3"
10875 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10876 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10877 (match_operand:QI 2 "nonmemory_operand" "")))
10878 (clobber (reg:CC 17))]
10879 "TARGET_HIMODE_MATH"
10880 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10881
10882(define_insn "*ashlhi3_1_lea"
10883 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10884 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10885 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10886 (clobber (reg:CC 17))]
10887 "!TARGET_PARTIAL_REG_STALL
10888 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10889{
10890 switch (get_attr_type (insn))
10891 {
10892 case TYPE_LEA:
10893 return "#";
10894 case TYPE_ALU:
10895 if (operands[2] != const1_rtx)
10896 abort ();
10897 return "add{w}\t{%0, %0|%0, %0}";
10898
10899 default:
10900 if (REG_P (operands[2]))
10901 return "sal{w}\t{%b2, %0|%0, %b2}";
10902 else if (GET_CODE (operands[2]) == CONST_INT
10903 && INTVAL (operands[2]) == 1
10904 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10905 return "sal{w}\t%0";
10906 else
10907 return "sal{w}\t{%2, %0|%0, %2}";
10908 }
10909}
10910 [(set (attr "type")
10911 (cond [(eq_attr "alternative" "1")
10912 (const_string "lea")
10913 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10914 (const_int 0))
10915 (match_operand 0 "register_operand" ""))
10916 (match_operand 2 "const1_operand" ""))
10917 (const_string "alu")
10918 ]
10919 (const_string "ishift")))
10920 (set_attr "mode" "HI,SI")])
10921
10922(define_insn "*ashlhi3_1"
10923 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10924 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10925 (match_operand:QI 2 "nonmemory_operand" "cI")))
10926 (clobber (reg:CC 17))]
10927 "TARGET_PARTIAL_REG_STALL
10928 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10929{
10930 switch (get_attr_type (insn))
10931 {
10932 case TYPE_ALU:
10933 if (operands[2] != const1_rtx)
10934 abort ();
10935 return "add{w}\t{%0, %0|%0, %0}";
10936
10937 default:
10938 if (REG_P (operands[2]))
10939 return "sal{w}\t{%b2, %0|%0, %b2}";
10940 else if (GET_CODE (operands[2]) == CONST_INT
10941 && INTVAL (operands[2]) == 1
10942 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10943 return "sal{w}\t%0";
10944 else
10945 return "sal{w}\t{%2, %0|%0, %2}";
10946 }
10947}
10948 [(set (attr "type")
10949 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10950 (const_int 0))
10951 (match_operand 0 "register_operand" ""))
10952 (match_operand 2 "const1_operand" ""))
10953 (const_string "alu")
10954 ]
10955 (const_string "ishift")))
10956 (set_attr "mode" "HI")])
10957
10958;; This pattern can't accept a variable shift count, since shifts by
10959;; zero don't affect the flags. We assume that shifts by constant
10960;; zero are optimized away.
10961(define_insn "*ashlhi3_cmp"
10962 [(set (reg 17)
10963 (compare
10964 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10965 (match_operand:QI 2 "immediate_operand" "I"))
10966 (const_int 0)))
10967 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10968 (ashift:HI (match_dup 1) (match_dup 2)))]
10969 "ix86_match_ccmode (insn, CCGOCmode)
10970 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10971{
10972 switch (get_attr_type (insn))
10973 {
10974 case TYPE_ALU:
10975 if (operands[2] != const1_rtx)
10976 abort ();
10977 return "add{w}\t{%0, %0|%0, %0}";
10978
10979 default:
10980 if (REG_P (operands[2]))
10981 return "sal{w}\t{%b2, %0|%0, %b2}";
10982 else if (GET_CODE (operands[2]) == CONST_INT
10983 && INTVAL (operands[2]) == 1
10984 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10985 return "sal{w}\t%0";
10986 else
10987 return "sal{w}\t{%2, %0|%0, %2}";
10988 }
10989}
10990 [(set (attr "type")
10991 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10992 (const_int 0))
10993 (match_operand 0 "register_operand" ""))
10994 (match_operand 2 "const1_operand" ""))
10995 (const_string "alu")
10996 ]
10997 (const_string "ishift")))
10998 (set_attr "mode" "HI")])
10999
11000(define_expand "ashlqi3"
11001 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11002 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11003 (match_operand:QI 2 "nonmemory_operand" "")))
11004 (clobber (reg:CC 17))]
11005 "TARGET_QIMODE_MATH"
11006 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11007
11008;; %%% Potential partial reg stall on alternative 2. What to do?
11009
11010(define_insn "*ashlqi3_1_lea"
11011 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11012 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11013 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11014 (clobber (reg:CC 17))]
11015 "!TARGET_PARTIAL_REG_STALL
11016 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11017{
11018 switch (get_attr_type (insn))
11019 {
11020 case TYPE_LEA:
11021 return "#";
11022 case TYPE_ALU:
11023 if (operands[2] != const1_rtx)
11024 abort ();
11025 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11026 return "add{l}\t{%k0, %k0|%k0, %k0}";
11027 else
11028 return "add{b}\t{%0, %0|%0, %0}";
11029
11030 default:
11031 if (REG_P (operands[2]))
11032 {
11033 if (get_attr_mode (insn) == MODE_SI)
11034 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11035 else
11036 return "sal{b}\t{%b2, %0|%0, %b2}";
11037 }
11038 else if (GET_CODE (operands[2]) == CONST_INT
11039 && INTVAL (operands[2]) == 1
11040 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11041 {
11042 if (get_attr_mode (insn) == MODE_SI)
11043 return "sal{l}\t%0";
11044 else
11045 return "sal{b}\t%0";
11046 }
11047 else
11048 {
11049 if (get_attr_mode (insn) == MODE_SI)
11050 return "sal{l}\t{%2, %k0|%k0, %2}";
11051 else
11052 return "sal{b}\t{%2, %0|%0, %2}";
11053 }
11054 }
11055}
11056 [(set (attr "type")
11057 (cond [(eq_attr "alternative" "2")
11058 (const_string "lea")
11059 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11060 (const_int 0))
11061 (match_operand 0 "register_operand" ""))
11062 (match_operand 2 "const1_operand" ""))
11063 (const_string "alu")
11064 ]
11065 (const_string "ishift")))
11066 (set_attr "mode" "QI,SI,SI")])
11067
11068(define_insn "*ashlqi3_1"
11069 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11070 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11071 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11072 (clobber (reg:CC 17))]
11073 "TARGET_PARTIAL_REG_STALL
11074 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11075{
11076 switch (get_attr_type (insn))
11077 {
11078 case TYPE_ALU:
11079 if (operands[2] != const1_rtx)
11080 abort ();
11081 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11082 return "add{l}\t{%k0, %k0|%k0, %k0}";
11083 else
11084 return "add{b}\t{%0, %0|%0, %0}";
11085
11086 default:
11087 if (REG_P (operands[2]))
11088 {
11089 if (get_attr_mode (insn) == MODE_SI)
11090 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11091 else
11092 return "sal{b}\t{%b2, %0|%0, %b2}";
11093 }
11094 else if (GET_CODE (operands[2]) == CONST_INT
11095 && INTVAL (operands[2]) == 1
11096 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11097 {
11098 if (get_attr_mode (insn) == MODE_SI)
11099 return "sal{l}\t%0";
11100 else
11101 return "sal{b}\t%0";
11102 }
11103 else
11104 {
11105 if (get_attr_mode (insn) == MODE_SI)
11106 return "sal{l}\t{%2, %k0|%k0, %2}";
11107 else
11108 return "sal{b}\t{%2, %0|%0, %2}";
11109 }
11110 }
11111}
11112 [(set (attr "type")
11113 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11114 (const_int 0))
11115 (match_operand 0 "register_operand" ""))
11116 (match_operand 2 "const1_operand" ""))
11117 (const_string "alu")
11118 ]
11119 (const_string "ishift")))
11120 (set_attr "mode" "QI,SI")])
11121
11122;; This pattern can't accept a variable shift count, since shifts by
11123;; zero don't affect the flags. We assume that shifts by constant
11124;; zero are optimized away.
11125(define_insn "*ashlqi3_cmp"
11126 [(set (reg 17)
11127 (compare
11128 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11129 (match_operand:QI 2 "immediate_operand" "I"))
11130 (const_int 0)))
11131 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11132 (ashift:QI (match_dup 1) (match_dup 2)))]
11133 "ix86_match_ccmode (insn, CCGOCmode)
11134 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11135{
11136 switch (get_attr_type (insn))
11137 {
11138 case TYPE_ALU:
11139 if (operands[2] != const1_rtx)
11140 abort ();
11141 return "add{b}\t{%0, %0|%0, %0}";
11142
11143 default:
11144 if (REG_P (operands[2]))
11145 return "sal{b}\t{%b2, %0|%0, %b2}";
11146 else if (GET_CODE (operands[2]) == CONST_INT
11147 && INTVAL (operands[2]) == 1
11148 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11149 return "sal{b}\t%0";
11150 else
11151 return "sal{b}\t{%2, %0|%0, %2}";
11152 }
11153}
11154 [(set (attr "type")
11155 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11156 (const_int 0))
11157 (match_operand 0 "register_operand" ""))
11158 (match_operand 2 "const1_operand" ""))
11159 (const_string "alu")
11160 ]
11161 (const_string "ishift")))
11162 (set_attr "mode" "QI")])
11163
11164;; See comment above `ashldi3' about how this works.
11165
11166(define_expand "ashrdi3"
11167 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11168 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11169 (match_operand:QI 2 "nonmemory_operand" "")))
11170 (clobber (reg:CC 17))])]
11171 ""
11172{
11173 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11174 {
11175 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11176 DONE;
11177 }
11178 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11179 DONE;
11180})
11181
11182(define_insn "ashrdi3_63_rex64"
11183 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11184 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11185 (match_operand:DI 2 "const_int_operand" "i,i")))
11186 (clobber (reg:CC 17))]
11187 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11188 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11189 "@
11190 {cqto|cqo}
11191 sar{q}\t{%2, %0|%0, %2}"
11192 [(set_attr "type" "imovx,ishift")
11193 (set_attr "prefix_0f" "0,*")
11194 (set_attr "length_immediate" "0,*")
11195 (set_attr "modrm" "0,1")
11196 (set_attr "mode" "DI")])
11197
11198(define_insn "*ashrdi3_1_one_bit_rex64"
11199 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11200 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11201 (match_operand:QI 2 "const_int_1_operand" "")))
11202 (clobber (reg:CC 17))]
11203 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11204 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11205 "sar{q}\t%0"
11206 [(set_attr "type" "ishift")
11207 (set (attr "length")
11208 (if_then_else (match_operand:DI 0 "register_operand" "")
11209 (const_string "2")
11210 (const_string "*")))])
11211
11212(define_insn "*ashrdi3_1_rex64"
11213 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11214 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11215 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11216 (clobber (reg:CC 17))]
11217 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11218 "@
11219 sar{q}\t{%2, %0|%0, %2}
11220 sar{q}\t{%b2, %0|%0, %b2}"
11221 [(set_attr "type" "ishift")
11222 (set_attr "mode" "DI")])
11223
11224;; This pattern can't accept a variable shift count, since shifts by
11225;; zero don't affect the flags. We assume that shifts by constant
11226;; zero are optimized away.
11227(define_insn "*ashrdi3_one_bit_cmp_rex64"
11228 [(set (reg 17)
11229 (compare
11230 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11231 (match_operand:QI 2 "const_int_1_operand" ""))
11232 (const_int 0)))
11233 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11234 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11235 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11236 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11237 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11238 "sar{q}\t%0"
11239 [(set_attr "type" "ishift")
11240 (set (attr "length")
11241 (if_then_else (match_operand:DI 0 "register_operand" "")
11242 (const_string "2")
11243 (const_string "*")))])
11244
11245;; This pattern can't accept a variable shift count, since shifts by
11246;; zero don't affect the flags. We assume that shifts by constant
11247;; zero are optimized away.
11248(define_insn "*ashrdi3_cmp_rex64"
11249 [(set (reg 17)
11250 (compare
11251 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11252 (match_operand:QI 2 "const_int_operand" "n"))
11253 (const_int 0)))
11254 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11255 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11256 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11257 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11258 "sar{q}\t{%2, %0|%0, %2}"
11259 [(set_attr "type" "ishift")
11260 (set_attr "mode" "DI")])
11261
11262
11263(define_insn "ashrdi3_1"
11264 [(set (match_operand:DI 0 "register_operand" "=r")
11265 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11266 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11267 (clobber (match_scratch:SI 3 "=&r"))
11268 (clobber (reg:CC 17))]
11269 "!TARGET_64BIT && TARGET_CMOVE"
11270 "#"
11271 [(set_attr "type" "multi")])
11272
11273(define_insn "*ashrdi3_2"
11274 [(set (match_operand:DI 0 "register_operand" "=r")
11275 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11276 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11277 (clobber (reg:CC 17))]
11278 "!TARGET_64BIT"
11279 "#"
11280 [(set_attr "type" "multi")])
11281
11282(define_split
11283 [(set (match_operand:DI 0 "register_operand" "")
11284 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11285 (match_operand:QI 2 "nonmemory_operand" "")))
11286 (clobber (match_scratch:SI 3 ""))
11287 (clobber (reg:CC 17))]
11288 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11289 [(const_int 0)]
11290 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11291
11292(define_split
11293 [(set (match_operand:DI 0 "register_operand" "")
11294 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11295 (match_operand:QI 2 "nonmemory_operand" "")))
11296 (clobber (reg:CC 17))]
11297 "!TARGET_64BIT && reload_completed"
11298 [(const_int 0)]
11299 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11300
11301(define_insn "x86_shrd_1"
11302 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11303 (ior:SI (ashiftrt:SI (match_dup 0)
11304 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11305 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11306 (minus:QI (const_int 32) (match_dup 2)))))
11307 (clobber (reg:CC 17))]
11308 ""
11309 "@
11310 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11311 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11312 [(set_attr "type" "ishift")
11313 (set_attr "prefix_0f" "1")
11314 (set_attr "pent_pair" "np")
11315 (set_attr "ppro_uops" "few")
11316 (set_attr "mode" "SI")])
11317
11318(define_expand "x86_shift_adj_3"
11319 [(use (match_operand:SI 0 "register_operand" ""))
11320 (use (match_operand:SI 1 "register_operand" ""))
11321 (use (match_operand:QI 2 "register_operand" ""))]
11322 ""
11323{
11324 rtx label = gen_label_rtx ();
11325 rtx tmp;
11326
11327 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11328
11329 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11330 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11331 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11332 gen_rtx_LABEL_REF (VOIDmode, label),
11333 pc_rtx);
11334 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11335 JUMP_LABEL (tmp) = label;
11336
11337 emit_move_insn (operands[0], operands[1]);
11338 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11339
11340 emit_label (label);
11341 LABEL_NUSES (label) = 1;
11342
11343 DONE;
11344})
11345
11346(define_insn "ashrsi3_31"
11347 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11348 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11349 (match_operand:SI 2 "const_int_operand" "i,i")))
11350 (clobber (reg:CC 17))]
11351 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11352 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11353 "@
11354 {cltd|cdq}
11355 sar{l}\t{%2, %0|%0, %2}"
11356 [(set_attr "type" "imovx,ishift")
11357 (set_attr "prefix_0f" "0,*")
11358 (set_attr "length_immediate" "0,*")
11359 (set_attr "modrm" "0,1")
11360 (set_attr "mode" "SI")])
11361
11362(define_insn "*ashrsi3_31_zext"
11363 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11364 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11365 (match_operand:SI 2 "const_int_operand" "i,i"))))
11366 (clobber (reg:CC 17))]
11367 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11368 && INTVAL (operands[2]) == 31
11369 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11370 "@
11371 {cltd|cdq}
11372 sar{l}\t{%2, %k0|%k0, %2}"
11373 [(set_attr "type" "imovx,ishift")
11374 (set_attr "prefix_0f" "0,*")
11375 (set_attr "length_immediate" "0,*")
11376 (set_attr "modrm" "0,1")
11377 (set_attr "mode" "SI")])
11378
11379(define_expand "ashrsi3"
11380 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11381 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11382 (match_operand:QI 2 "nonmemory_operand" "")))
11383 (clobber (reg:CC 17))]
11384 ""
11385 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11386
11387(define_insn "*ashrsi3_1_one_bit"
11388 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11389 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11390 (match_operand:QI 2 "const_int_1_operand" "")))
11391 (clobber (reg:CC 17))]
11392 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11393 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11394 "sar{l}\t%0"
11395 [(set_attr "type" "ishift")
11396 (set (attr "length")
11397 (if_then_else (match_operand:SI 0 "register_operand" "")
11398 (const_string "2")
11399 (const_string "*")))])
11400
11401(define_insn "*ashrsi3_1_one_bit_zext"
11402 [(set (match_operand:DI 0 "register_operand" "=r")
11403 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11404 (match_operand:QI 2 "const_int_1_operand" ""))))
11405 (clobber (reg:CC 17))]
11406 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11407 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11408 "sar{l}\t%k0"
11409 [(set_attr "type" "ishift")
11410 (set_attr "length" "2")])
11411
11412(define_insn "*ashrsi3_1"
11413 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11414 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11415 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11416 (clobber (reg:CC 17))]
11417 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11418 "@
11419 sar{l}\t{%2, %0|%0, %2}
11420 sar{l}\t{%b2, %0|%0, %b2}"
11421 [(set_attr "type" "ishift")
11422 (set_attr "mode" "SI")])
11423
11424(define_insn "*ashrsi3_1_zext"
11425 [(set (match_operand:DI 0 "register_operand" "=r,r")
11426 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11427 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11428 (clobber (reg:CC 17))]
11429 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11430 "@
11431 sar{l}\t{%2, %k0|%k0, %2}
11432 sar{l}\t{%b2, %k0|%k0, %b2}"
11433 [(set_attr "type" "ishift")
11434 (set_attr "mode" "SI")])
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 "*ashrsi3_one_bit_cmp"
11440 [(set (reg 17)
11441 (compare
11442 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11443 (match_operand:QI 2 "const_int_1_operand" ""))
11444 (const_int 0)))
11445 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11446 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11447 "ix86_match_ccmode (insn, CCGOCmode)
11448 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11449 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11450 "sar{l}\t%0"
11451 [(set_attr "type" "ishift")
11452 (set (attr "length")
11453 (if_then_else (match_operand:SI 0 "register_operand" "")
11454 (const_string "2")
11455 (const_string "*")))])
11456
11457(define_insn "*ashrsi3_one_bit_cmp_zext"
11458 [(set (reg 17)
11459 (compare
11460 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11461 (match_operand:QI 2 "const_int_1_operand" ""))
11462 (const_int 0)))
11463 (set (match_operand:DI 0 "register_operand" "=r")
11464 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11465 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11466 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11467 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11468 "sar{l}\t%k0"
11469 [(set_attr "type" "ishift")
11470 (set_attr "length" "2")])
11471
11472;; This pattern can't accept a variable shift count, since shifts by
11473;; zero don't affect the flags. We assume that shifts by constant
11474;; zero are optimized away.
11475(define_insn "*ashrsi3_cmp"
11476 [(set (reg 17)
11477 (compare
11478 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11479 (match_operand:QI 2 "immediate_operand" "I"))
11480 (const_int 0)))
11481 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11482 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11483 "ix86_match_ccmode (insn, CCGOCmode)
11484 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11485 "sar{l}\t{%2, %0|%0, %2}"
11486 [(set_attr "type" "ishift")
11487 (set_attr "mode" "SI")])
11488
11489(define_insn "*ashrsi3_cmp_zext"
11490 [(set (reg 17)
11491 (compare
11492 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11493 (match_operand:QI 2 "immediate_operand" "I"))
11494 (const_int 0)))
11495 (set (match_operand:DI 0 "register_operand" "=r")
11496 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11497 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11498 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11499 "sar{l}\t{%2, %k0|%k0, %2}"
11500 [(set_attr "type" "ishift")
11501 (set_attr "mode" "SI")])
11502
11503(define_expand "ashrhi3"
11504 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11505 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11506 (match_operand:QI 2 "nonmemory_operand" "")))
11507 (clobber (reg:CC 17))]
11508 "TARGET_HIMODE_MATH"
11509 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11510
11511(define_insn "*ashrhi3_1_one_bit"
11512 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11513 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11514 (match_operand:QI 2 "const_int_1_operand" "")))
11515 (clobber (reg:CC 17))]
11516 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11517 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11518 "sar{w}\t%0"
11519 [(set_attr "type" "ishift")
11520 (set (attr "length")
11521 (if_then_else (match_operand 0 "register_operand" "")
11522 (const_string "2")
11523 (const_string "*")))])
11524
11525(define_insn "*ashrhi3_1"
11526 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11527 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11528 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11529 (clobber (reg:CC 17))]
11530 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11531 "@
11532 sar{w}\t{%2, %0|%0, %2}
11533 sar{w}\t{%b2, %0|%0, %b2}"
11534 [(set_attr "type" "ishift")
11535 (set_attr "mode" "HI")])
11536
11537;; This pattern can't accept a variable shift count, since shifts by
11538;; zero don't affect the flags. We assume that shifts by constant
11539;; zero are optimized away.
11540(define_insn "*ashrhi3_one_bit_cmp"
11541 [(set (reg 17)
11542 (compare
11543 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11544 (match_operand:QI 2 "const_int_1_operand" ""))
11545 (const_int 0)))
11546 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11547 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11548 "ix86_match_ccmode (insn, CCGOCmode)
11549 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11550 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11551 "sar{w}\t%0"
11552 [(set_attr "type" "ishift")
11553 (set (attr "length")
11554 (if_then_else (match_operand 0 "register_operand" "")
11555 (const_string "2")
11556 (const_string "*")))])
11557
11558;; This pattern can't accept a variable shift count, since shifts by
11559;; zero don't affect the flags. We assume that shifts by constant
11560;; zero are optimized away.
11561(define_insn "*ashrhi3_cmp"
11562 [(set (reg 17)
11563 (compare
11564 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11565 (match_operand:QI 2 "immediate_operand" "I"))
11566 (const_int 0)))
11567 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11568 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11569 "ix86_match_ccmode (insn, CCGOCmode)
11570 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11571 "sar{w}\t{%2, %0|%0, %2}"
11572 [(set_attr "type" "ishift")
11573 (set_attr "mode" "HI")])
11574
11575(define_expand "ashrqi3"
11576 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11577 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11578 (match_operand:QI 2 "nonmemory_operand" "")))
11579 (clobber (reg:CC 17))]
11580 "TARGET_QIMODE_MATH"
11581 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11582
11583(define_insn "*ashrqi3_1_one_bit"
11584 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11585 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11586 (match_operand:QI 2 "const_int_1_operand" "")))
11587 (clobber (reg:CC 17))]
11588 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11589 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11590 "sar{b}\t%0"
11591 [(set_attr "type" "ishift")
11592 (set (attr "length")
11593 (if_then_else (match_operand 0 "register_operand" "")
11594 (const_string "2")
11595 (const_string "*")))])
11596
11597(define_insn "*ashrqi3_1"
11598 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11599 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11600 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11601 (clobber (reg:CC 17))]
11602 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11603 "@
11604 sar{b}\t{%2, %0|%0, %2}
11605 sar{b}\t{%b2, %0|%0, %b2}"
11606 [(set_attr "type" "ishift")
11607 (set_attr "mode" "QI")])
11608
11609;; This pattern can't accept a variable shift count, since shifts by
11610;; zero don't affect the flags. We assume that shifts by constant
11611;; zero are optimized away.
11612(define_insn "*ashrqi3_one_bit_cmp"
11613 [(set (reg 17)
11614 (compare
11615 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11616 (match_operand:QI 2 "const_int_1_operand" "I"))
11617 (const_int 0)))
11618 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11619 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11620 "ix86_match_ccmode (insn, CCGOCmode)
11621 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11622 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11623 "sar{b}\t%0"
11624 [(set_attr "type" "ishift")
11625 (set (attr "length")
11626 (if_then_else (match_operand 0 "register_operand" "")
11627 (const_string "2")
11628 (const_string "*")))])
11629
11630;; This pattern can't accept a variable shift count, since shifts by
11631;; zero don't affect the flags. We assume that shifts by constant
11632;; zero are optimized away.
11633(define_insn "*ashrqi3_cmp"
11634 [(set (reg 17)
11635 (compare
11636 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11637 (match_operand:QI 2 "immediate_operand" "I"))
11638 (const_int 0)))
11639 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11640 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11641 "ix86_match_ccmode (insn, CCGOCmode)
11642 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11643 "sar{b}\t{%2, %0|%0, %2}"
11644 [(set_attr "type" "ishift")
11645 (set_attr "mode" "QI")])
11646
11647;; Logical shift instructions
11648
11649;; See comment above `ashldi3' about how this works.
11650
11651(define_expand "lshrdi3"
11652 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11653 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11654 (match_operand:QI 2 "nonmemory_operand" "")))
11655 (clobber (reg:CC 17))])]
11656 ""
11657{
11658 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11659 {
11660 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11661 DONE;
11662 }
11663 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11664 DONE;
11665})
11666
11667(define_insn "*lshrdi3_1_one_bit_rex64"
11668 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11669 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11670 (match_operand:QI 2 "const_int_1_operand" "")))
11671 (clobber (reg:CC 17))]
11672 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11673 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11674 "shr{q}\t%0"
11675 [(set_attr "type" "ishift")
11676 (set (attr "length")
11677 (if_then_else (match_operand:DI 0 "register_operand" "")
11678 (const_string "2")
11679 (const_string "*")))])
11680
11681(define_insn "*lshrdi3_1_rex64"
11682 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11683 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11684 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11685 (clobber (reg:CC 17))]
11686 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11687 "@
11688 shr{q}\t{%2, %0|%0, %2}
11689 shr{q}\t{%b2, %0|%0, %b2}"
11690 [(set_attr "type" "ishift")
11691 (set_attr "mode" "DI")])
11692
11693;; This pattern can't accept a variable shift count, since shifts by
11694;; zero don't affect the flags. We assume that shifts by constant
11695;; zero are optimized away.
11696(define_insn "*lshrdi3_cmp_one_bit_rex64"
11697 [(set (reg 17)
11698 (compare
11699 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11700 (match_operand:QI 2 "const_int_1_operand" ""))
11701 (const_int 0)))
11702 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11703 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11704 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11705 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11706 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11707 "shr{q}\t%0"
11708 [(set_attr "type" "ishift")
11709 (set (attr "length")
11710 (if_then_else (match_operand:DI 0 "register_operand" "")
11711 (const_string "2")
11712 (const_string "*")))])
11713
11714;; This pattern can't accept a variable shift count, since shifts by
11715;; zero don't affect the flags. We assume that shifts by constant
11716;; zero are optimized away.
11717(define_insn "*lshrdi3_cmp_rex64"
11718 [(set (reg 17)
11719 (compare
11720 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11721 (match_operand:QI 2 "const_int_operand" "e"))
11722 (const_int 0)))
11723 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11724 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11725 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11726 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11727 "shr{q}\t{%2, %0|%0, %2}"
11728 [(set_attr "type" "ishift")
11729 (set_attr "mode" "DI")])
11730
11731(define_insn "lshrdi3_1"
11732 [(set (match_operand:DI 0 "register_operand" "=r")
11733 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11734 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11735 (clobber (match_scratch:SI 3 "=&r"))
11736 (clobber (reg:CC 17))]
11737 "!TARGET_64BIT && TARGET_CMOVE"
11738 "#"
11739 [(set_attr "type" "multi")])
11740
11741(define_insn "*lshrdi3_2"
11742 [(set (match_operand:DI 0 "register_operand" "=r")
11743 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11744 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11745 (clobber (reg:CC 17))]
11746 "!TARGET_64BIT"
11747 "#"
11748 [(set_attr "type" "multi")])
11749
11750(define_split
11751 [(set (match_operand:DI 0 "register_operand" "")
11752 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11753 (match_operand:QI 2 "nonmemory_operand" "")))
11754 (clobber (match_scratch:SI 3 ""))
11755 (clobber (reg:CC 17))]
11756 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11757 [(const_int 0)]
11758 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11759
11760(define_split
11761 [(set (match_operand:DI 0 "register_operand" "")
11762 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11763 (match_operand:QI 2 "nonmemory_operand" "")))
11764 (clobber (reg:CC 17))]
11765 "!TARGET_64BIT && reload_completed"
11766 [(const_int 0)]
11767 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11768
11769(define_expand "lshrsi3"
11770 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11771 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11772 (match_operand:QI 2 "nonmemory_operand" "")))
11773 (clobber (reg:CC 17))]
11774 ""
11775 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11776
11777(define_insn "*lshrsi3_1_one_bit"
11778 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11779 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11780 (match_operand:QI 2 "const_int_1_operand" "")))
11781 (clobber (reg:CC 17))]
11782 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11783 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11784 "shr{l}\t%0"
11785 [(set_attr "type" "ishift")
11786 (set (attr "length")
11787 (if_then_else (match_operand:SI 0 "register_operand" "")
11788 (const_string "2")
11789 (const_string "*")))])
11790
11791(define_insn "*lshrsi3_1_one_bit_zext"
11792 [(set (match_operand:DI 0 "register_operand" "=r")
11793 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11794 (match_operand:QI 2 "const_int_1_operand" "")))
11795 (clobber (reg:CC 17))]
11796 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11797 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11798 "shr{l}\t%k0"
11799 [(set_attr "type" "ishift")
11800 (set_attr "length" "2")])
11801
11802(define_insn "*lshrsi3_1"
11803 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11804 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11805 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11806 (clobber (reg:CC 17))]
11807 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11808 "@
11809 shr{l}\t{%2, %0|%0, %2}
11810 shr{l}\t{%b2, %0|%0, %b2}"
11811 [(set_attr "type" "ishift")
11812 (set_attr "mode" "SI")])
11813
11814(define_insn "*lshrsi3_1_zext"
11815 [(set (match_operand:DI 0 "register_operand" "=r,r")
11816 (zero_extend:DI
11817 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11818 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11819 (clobber (reg:CC 17))]
11820 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11821 "@
11822 shr{l}\t{%2, %k0|%k0, %2}
11823 shr{l}\t{%b2, %k0|%k0, %b2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "SI")])
11826
11827;; This pattern can't accept a variable shift count, since shifts by
11828;; zero don't affect the flags. We assume that shifts by constant
11829;; zero are optimized away.
11830(define_insn "*lshrsi3_one_bit_cmp"
11831 [(set (reg 17)
11832 (compare
11833 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11834 (match_operand:QI 2 "const_int_1_operand" ""))
11835 (const_int 0)))
11836 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11837 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11838 "ix86_match_ccmode (insn, CCGOCmode)
11839 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11840 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11841 "shr{l}\t%0"
11842 [(set_attr "type" "ishift")
11843 (set (attr "length")
11844 (if_then_else (match_operand:SI 0 "register_operand" "")
11845 (const_string "2")
11846 (const_string "*")))])
11847
11848(define_insn "*lshrsi3_cmp_one_bit_zext"
11849 [(set (reg 17)
11850 (compare
11851 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11852 (match_operand:QI 2 "const_int_1_operand" ""))
11853 (const_int 0)))
11854 (set (match_operand:DI 0 "register_operand" "=r")
11855 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11856 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11857 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11858 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11859 "shr{l}\t%k0"
11860 [(set_attr "type" "ishift")
11861 (set_attr "length" "2")])
11862
11863;; This pattern can't accept a variable shift count, since shifts by
11864;; zero don't affect the flags. We assume that shifts by constant
11865;; zero are optimized away.
11866(define_insn "*lshrsi3_cmp"
11867 [(set (reg 17)
11868 (compare
11869 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11870 (match_operand:QI 2 "immediate_operand" "I"))
11871 (const_int 0)))
11872 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11873 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11874 "ix86_match_ccmode (insn, CCGOCmode)
11875 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11876 "shr{l}\t{%2, %0|%0, %2}"
11877 [(set_attr "type" "ishift")
11878 (set_attr "mode" "SI")])
11879
11880(define_insn "*lshrsi3_cmp_zext"
11881 [(set (reg 17)
11882 (compare
11883 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11884 (match_operand:QI 2 "immediate_operand" "I"))
11885 (const_int 0)))
11886 (set (match_operand:DI 0 "register_operand" "=r")
11887 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11888 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11889 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11890 "shr{l}\t{%2, %k0|%k0, %2}"
11891 [(set_attr "type" "ishift")
11892 (set_attr "mode" "SI")])
11893
11894(define_expand "lshrhi3"
11895 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11896 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11897 (match_operand:QI 2 "nonmemory_operand" "")))
11898 (clobber (reg:CC 17))]
11899 "TARGET_HIMODE_MATH"
11900 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11901
11902(define_insn "*lshrhi3_1_one_bit"
11903 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11904 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11905 (match_operand:QI 2 "const_int_1_operand" "")))
11906 (clobber (reg:CC 17))]
11907 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11908 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11909 "shr{w}\t%0"
11910 [(set_attr "type" "ishift")
11911 (set (attr "length")
11912 (if_then_else (match_operand 0 "register_operand" "")
11913 (const_string "2")
11914 (const_string "*")))])
11915
11916(define_insn "*lshrhi3_1"
11917 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11918 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11919 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11920 (clobber (reg:CC 17))]
11921 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11922 "@
11923 shr{w}\t{%2, %0|%0, %2}
11924 shr{w}\t{%b2, %0|%0, %b2}"
11925 [(set_attr "type" "ishift")
11926 (set_attr "mode" "HI")])
11927
11928;; This pattern can't accept a variable shift count, since shifts by
11929;; zero don't affect the flags. We assume that shifts by constant
11930;; zero are optimized away.
11931(define_insn "*lshrhi3_one_bit_cmp"
11932 [(set (reg 17)
11933 (compare
11934 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const_int_1_operand" ""))
11936 (const_int 0)))
11937 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11938 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11939 "ix86_match_ccmode (insn, CCGOCmode)
11940 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11941 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11942 "shr{w}\t%0"
11943 [(set_attr "type" "ishift")
11944 (set (attr "length")
11945 (if_then_else (match_operand:SI 0 "register_operand" "")
11946 (const_string "2")
11947 (const_string "*")))])
11948
11949;; This pattern can't accept a variable shift count, since shifts by
11950;; zero don't affect the flags. We assume that shifts by constant
11951;; zero are optimized away.
11952(define_insn "*lshrhi3_cmp"
11953 [(set (reg 17)
11954 (compare
11955 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11956 (match_operand:QI 2 "immediate_operand" "I"))
11957 (const_int 0)))
11958 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11959 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11960 "ix86_match_ccmode (insn, CCGOCmode)
11961 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11962 "shr{w}\t{%2, %0|%0, %2}"
11963 [(set_attr "type" "ishift")
11964 (set_attr "mode" "HI")])
11965
11966(define_expand "lshrqi3"
11967 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11968 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11969 (match_operand:QI 2 "nonmemory_operand" "")))
11970 (clobber (reg:CC 17))]
11971 "TARGET_QIMODE_MATH"
11972 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11973
11974(define_insn "*lshrqi3_1_one_bit"
11975 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11976 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11977 (match_operand:QI 2 "const_int_1_operand" "")))
11978 (clobber (reg:CC 17))]
11979 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11980 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11981 "shr{b}\t%0"
11982 [(set_attr "type" "ishift")
11983 (set (attr "length")
11984 (if_then_else (match_operand 0 "register_operand" "")
11985 (const_string "2")
11986 (const_string "*")))])
11987
11988(define_insn "*lshrqi3_1"
11989 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11990 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11991 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11992 (clobber (reg:CC 17))]
11993 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11994 "@
11995 shr{b}\t{%2, %0|%0, %2}
11996 shr{b}\t{%b2, %0|%0, %b2}"
11997 [(set_attr "type" "ishift")
11998 (set_attr "mode" "QI")])
11999
12000;; This pattern can't accept a variable shift count, since shifts by
12001;; zero don't affect the flags. We assume that shifts by constant
12002;; zero are optimized away.
12003(define_insn "*lshrqi2_one_bit_cmp"
12004 [(set (reg 17)
12005 (compare
12006 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12007 (match_operand:QI 2 "const_int_1_operand" ""))
12008 (const_int 0)))
12009 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12010 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12011 "ix86_match_ccmode (insn, CCGOCmode)
12012 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
12013 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12014 "shr{b}\t%0"
12015 [(set_attr "type" "ishift")
12016 (set (attr "length")
12017 (if_then_else (match_operand:SI 0 "register_operand" "")
12018 (const_string "2")
12019 (const_string "*")))])
12020
12021;; This pattern can't accept a variable shift count, since shifts by
12022;; zero don't affect the flags. We assume that shifts by constant
12023;; zero are optimized away.
12024(define_insn "*lshrqi2_cmp"
12025 [(set (reg 17)
12026 (compare
12027 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "immediate_operand" "I"))
12029 (const_int 0)))
12030 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12031 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12032 "ix86_match_ccmode (insn, CCGOCmode)
12033 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12034 "shr{b}\t{%2, %0|%0, %2}"
12035 [(set_attr "type" "ishift")
12036 (set_attr "mode" "QI")])
12037
12038;; Rotate instructions
12039
12040(define_expand "rotldi3"
12041 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12042 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12043 (match_operand:QI 2 "nonmemory_operand" "")))
12044 (clobber (reg:CC 17))]
12045 "TARGET_64BIT"
12046 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12047
12048(define_insn "*rotlsi3_1_one_bit_rex64"
12049 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12050 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12051 (match_operand:QI 2 "const_int_1_operand" "")))
12052 (clobber (reg:CC 17))]
12053 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12054 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12055 "rol{q}\t%0"
12056 [(set_attr "type" "ishift")
12057 (set (attr "length")
12058 (if_then_else (match_operand:DI 0 "register_operand" "")
12059 (const_string "2")
12060 (const_string "*")))])
12061
12062(define_insn "*rotldi3_1_rex64"
12063 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12064 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12065 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12066 (clobber (reg:CC 17))]
12067 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12068 "@
12069 rol{q}\t{%2, %0|%0, %2}
12070 rol{q}\t{%b2, %0|%0, %b2}"
12071 [(set_attr "type" "ishift")
12072 (set_attr "mode" "DI")])
12073
12074(define_expand "rotlsi3"
12075 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12076 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12077 (match_operand:QI 2 "nonmemory_operand" "")))
12078 (clobber (reg:CC 17))]
12079 ""
12080 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12081
12082(define_insn "*rotlsi3_1_one_bit"
12083 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12084 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12085 (match_operand:QI 2 "const_int_1_operand" "")))
12086 (clobber (reg:CC 17))]
12087 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12088 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12089 "rol{l}\t%0"
12090 [(set_attr "type" "ishift")
12091 (set (attr "length")
12092 (if_then_else (match_operand:SI 0 "register_operand" "")
12093 (const_string "2")
12094 (const_string "*")))])
12095
12096(define_insn "*rotlsi3_1_one_bit_zext"
12097 [(set (match_operand:DI 0 "register_operand" "=r")
12098 (zero_extend:DI
12099 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12100 (match_operand:QI 2 "const_int_1_operand" ""))))
12101 (clobber (reg:CC 17))]
12102 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12103 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12104 "rol{l}\t%k0"
12105 [(set_attr "type" "ishift")
12106 (set_attr "length" "2")])
12107
12108(define_insn "*rotlsi3_1"
12109 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12110 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12111 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12112 (clobber (reg:CC 17))]
12113 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12114 "@
12115 rol{l}\t{%2, %0|%0, %2}
12116 rol{l}\t{%b2, %0|%0, %b2}"
12117 [(set_attr "type" "ishift")
12118 (set_attr "mode" "SI")])
12119
12120(define_insn "*rotlsi3_1_zext"
12121 [(set (match_operand:DI 0 "register_operand" "=r,r")
12122 (zero_extend:DI
12123 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12124 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12125 (clobber (reg:CC 17))]
12126 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12127 "@
12128 rol{l}\t{%2, %k0|%k0, %2}
12129 rol{l}\t{%b2, %k0|%k0, %b2}"
12130 [(set_attr "type" "ishift")
12131 (set_attr "mode" "SI")])
12132
12133(define_expand "rotlhi3"
12134 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12135 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12136 (match_operand:QI 2 "nonmemory_operand" "")))
12137 (clobber (reg:CC 17))]
12138 "TARGET_HIMODE_MATH"
12139 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12140
12141(define_insn "*rotlhi3_1_one_bit"
12142 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12143 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12144 (match_operand:QI 2 "const_int_1_operand" "")))
12145 (clobber (reg:CC 17))]
12146 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12147 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12148 "rol{w}\t%0"
12149 [(set_attr "type" "ishift")
12150 (set (attr "length")
12151 (if_then_else (match_operand 0 "register_operand" "")
12152 (const_string "2")
12153 (const_string "*")))])
12154
12155(define_insn "*rotlhi3_1"
12156 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12157 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12158 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12159 (clobber (reg:CC 17))]
12160 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12161 "@
12162 rol{w}\t{%2, %0|%0, %2}
12163 rol{w}\t{%b2, %0|%0, %b2}"
12164 [(set_attr "type" "ishift")
12165 (set_attr "mode" "HI")])
12166
12167(define_expand "rotlqi3"
12168 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12169 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12170 (match_operand:QI 2 "nonmemory_operand" "")))
12171 (clobber (reg:CC 17))]
12172 "TARGET_QIMODE_MATH"
12173 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12174
12175(define_insn "*rotlqi3_1_one_bit"
12176 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12177 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12178 (match_operand:QI 2 "const_int_1_operand" "")))
12179 (clobber (reg:CC 17))]
12180 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12181 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12182 "rol{b}\t%0"
12183 [(set_attr "type" "ishift")
12184 (set (attr "length")
12185 (if_then_else (match_operand 0 "register_operand" "")
12186 (const_string "2")
12187 (const_string "*")))])
12188
12189(define_insn "*rotlqi3_1"
12190 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12191 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12192 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12193 (clobber (reg:CC 17))]
12194 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12195 "@
12196 rol{b}\t{%2, %0|%0, %2}
12197 rol{b}\t{%b2, %0|%0, %b2}"
12198 [(set_attr "type" "ishift")
12199 (set_attr "mode" "QI")])
12200
12201(define_expand "rotrdi3"
12202 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12203 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12204 (match_operand:QI 2 "nonmemory_operand" "")))
12205 (clobber (reg:CC 17))]
12206 "TARGET_64BIT"
12207 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12208
12209(define_insn "*rotrdi3_1_one_bit_rex64"
12210 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12211 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12212 (match_operand:QI 2 "const_int_1_operand" "")))
12213 (clobber (reg:CC 17))]
12214 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12215 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12216 "ror{q}\t%0"
12217 [(set_attr "type" "ishift")
12218 (set (attr "length")
12219 (if_then_else (match_operand:DI 0 "register_operand" "")
12220 (const_string "2")
12221 (const_string "*")))])
12222
12223(define_insn "*rotrdi3_1_rex64"
12224 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12225 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12226 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12227 (clobber (reg:CC 17))]
12228 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12229 "@
12230 ror{q}\t{%2, %0|%0, %2}
12231 ror{q}\t{%b2, %0|%0, %b2}"
12232 [(set_attr "type" "ishift")
12233 (set_attr "mode" "DI")])
12234
12235(define_expand "rotrsi3"
12236 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12237 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12238 (match_operand:QI 2 "nonmemory_operand" "")))
12239 (clobber (reg:CC 17))]
12240 ""
12241 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12242
12243(define_insn "*rotrsi3_1_one_bit"
12244 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12245 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12246 (match_operand:QI 2 "const_int_1_operand" "")))
12247 (clobber (reg:CC 17))]
12248 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12249 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12250 "ror{l}\t%0"
12251 [(set_attr "type" "ishift")
12252 (set (attr "length")
12253 (if_then_else (match_operand:SI 0 "register_operand" "")
12254 (const_string "2")
12255 (const_string "*")))])
12256
12257(define_insn "*rotrsi3_1_one_bit_zext"
12258 [(set (match_operand:DI 0 "register_operand" "=r")
12259 (zero_extend:DI
12260 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12261 (match_operand:QI 2 "const_int_1_operand" ""))))
12262 (clobber (reg:CC 17))]
12263 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12264 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12265 "ror{l}\t%k0"
12266 [(set_attr "type" "ishift")
12267 (set (attr "length")
12268 (if_then_else (match_operand:SI 0 "register_operand" "")
12269 (const_string "2")
12270 (const_string "*")))])
12271
12272(define_insn "*rotrsi3_1"
12273 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12274 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12275 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12276 (clobber (reg:CC 17))]
12277 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12278 "@
12279 ror{l}\t{%2, %0|%0, %2}
12280 ror{l}\t{%b2, %0|%0, %b2}"
12281 [(set_attr "type" "ishift")
12282 (set_attr "mode" "SI")])
12283
12284(define_insn "*rotrsi3_1_zext"
12285 [(set (match_operand:DI 0 "register_operand" "=r,r")
12286 (zero_extend:DI
12287 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12288 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12289 (clobber (reg:CC 17))]
12290 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12291 "@
12292 ror{l}\t{%2, %k0|%k0, %2}
12293 ror{l}\t{%b2, %k0|%k0, %b2}"
12294 [(set_attr "type" "ishift")
12295 (set_attr "mode" "SI")])
12296
12297(define_expand "rotrhi3"
12298 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12299 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12300 (match_operand:QI 2 "nonmemory_operand" "")))
12301 (clobber (reg:CC 17))]
12302 "TARGET_HIMODE_MATH"
12303 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12304
12305(define_insn "*rotrhi3_one_bit"
12306 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12307 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12308 (match_operand:QI 2 "const_int_1_operand" "")))
12309 (clobber (reg:CC 17))]
12310 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12311 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12312 "ror{w}\t%0"
12313 [(set_attr "type" "ishift")
12314 (set (attr "length")
12315 (if_then_else (match_operand 0 "register_operand" "")
12316 (const_string "2")
12317 (const_string "*")))])
12318
12319(define_insn "*rotrhi3"
12320 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12321 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12322 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12323 (clobber (reg:CC 17))]
12324 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12325 "@
12326 ror{w}\t{%2, %0|%0, %2}
12327 ror{w}\t{%b2, %0|%0, %b2}"
12328 [(set_attr "type" "ishift")
12329 (set_attr "mode" "HI")])
12330
12331(define_expand "rotrqi3"
12332 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12333 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12334 (match_operand:QI 2 "nonmemory_operand" "")))
12335 (clobber (reg:CC 17))]
12336 "TARGET_QIMODE_MATH"
12337 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12338
12339(define_insn "*rotrqi3_1_one_bit"
12340 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12341 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12342 (match_operand:QI 2 "const_int_1_operand" "")))
12343 (clobber (reg:CC 17))]
12344 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12345 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12346 "ror{b}\t%0"
12347 [(set_attr "type" "ishift")
12348 (set (attr "length")
12349 (if_then_else (match_operand 0 "register_operand" "")
12350 (const_string "2")
12351 (const_string "*")))])
12352
12353(define_insn "*rotrqi3_1"
12354 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12355 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12356 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12357 (clobber (reg:CC 17))]
12358 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12359 "@
12360 ror{b}\t{%2, %0|%0, %2}
12361 ror{b}\t{%b2, %0|%0, %b2}"
12362 [(set_attr "type" "ishift")
12363 (set_attr "mode" "QI")])
12364
12365;; Bit set / bit test instructions
12366
12367(define_expand "extv"
12368 [(set (match_operand:SI 0 "register_operand" "")
12369 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12370 (match_operand:SI 2 "immediate_operand" "")
12371 (match_operand:SI 3 "immediate_operand" "")))]
12372 ""
12373{
12374 /* Handle extractions from %ah et al. */
12375 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12376 FAIL;
12377
12378 /* From mips.md: extract_bit_field doesn't verify that our source
12379 matches the predicate, so check it again here. */
12380 if (! register_operand (operands[1], VOIDmode))
12381 FAIL;
12382})
12383
12384(define_expand "extzv"
12385 [(set (match_operand:SI 0 "register_operand" "")
12386 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12387 (match_operand:SI 2 "immediate_operand" "")
12388 (match_operand:SI 3 "immediate_operand" "")))]
12389 ""
12390{
12391 /* Handle extractions from %ah et al. */
12392 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12393 FAIL;
12394
12395 /* From mips.md: extract_bit_field doesn't verify that our source
12396 matches the predicate, so check it again here. */
12397 if (! register_operand (operands[1], VOIDmode))
12398 FAIL;
12399})
12400
12401(define_expand "insv"
12402 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12403 (match_operand:SI 1 "immediate_operand" "")
12404 (match_operand:SI 2 "immediate_operand" ""))
12405 (match_operand:SI 3 "register_operand" ""))]
12406 ""
12407{
12408 /* Handle extractions from %ah et al. */
12409 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12410 FAIL;
12411
12412 /* From mips.md: insert_bit_field doesn't verify that our source
12413 matches the predicate, so check it again here. */
12414 if (! register_operand (operands[0], VOIDmode))
12415 FAIL;
12416})
12417
12418;; %%% bts, btr, btc, bt.
12419
12420;; Store-flag instructions.
12421
12422;; For all sCOND expanders, also expand the compare or test insn that
12423;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12424
12425;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12426;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12427;; way, which can later delete the movzx if only QImode is needed.
12428
12429(define_expand "seq"
12430 [(set (match_operand:QI 0 "register_operand" "")
12431 (eq:QI (reg:CC 17) (const_int 0)))]
12432 ""
12433 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12434
12435(define_expand "sne"
12436 [(set (match_operand:QI 0 "register_operand" "")
12437 (ne:QI (reg:CC 17) (const_int 0)))]
12438 ""
12439 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12440
12441(define_expand "sgt"
12442 [(set (match_operand:QI 0 "register_operand" "")
12443 (gt:QI (reg:CC 17) (const_int 0)))]
12444 ""
12445 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12446
12447(define_expand "sgtu"
12448 [(set (match_operand:QI 0 "register_operand" "")
12449 (gtu:QI (reg:CC 17) (const_int 0)))]
12450 ""
12451 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12452
12453(define_expand "slt"
12454 [(set (match_operand:QI 0 "register_operand" "")
12455 (lt:QI (reg:CC 17) (const_int 0)))]
12456 ""
12457 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12458
12459(define_expand "sltu"
12460 [(set (match_operand:QI 0 "register_operand" "")
12461 (ltu:QI (reg:CC 17) (const_int 0)))]
12462 ""
12463 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12464
12465(define_expand "sge"
12466 [(set (match_operand:QI 0 "register_operand" "")
12467 (ge:QI (reg:CC 17) (const_int 0)))]
12468 ""
12469 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12470
12471(define_expand "sgeu"
12472 [(set (match_operand:QI 0 "register_operand" "")
12473 (geu:QI (reg:CC 17) (const_int 0)))]
12474 ""
12475 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12476
12477(define_expand "sle"
12478 [(set (match_operand:QI 0 "register_operand" "")
12479 (le:QI (reg:CC 17) (const_int 0)))]
12480 ""
12481 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12482
12483(define_expand "sleu"
12484 [(set (match_operand:QI 0 "register_operand" "")
12485 (leu:QI (reg:CC 17) (const_int 0)))]
12486 ""
12487 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12488
12489(define_expand "sunordered"
12490 [(set (match_operand:QI 0 "register_operand" "")
12491 (unordered:QI (reg:CC 17) (const_int 0)))]
12492 "TARGET_80387 || TARGET_SSE"
12493 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12494
12495(define_expand "sordered"
12496 [(set (match_operand:QI 0 "register_operand" "")
12497 (ordered:QI (reg:CC 17) (const_int 0)))]
12498 "TARGET_80387"
12499 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12500
12501(define_expand "suneq"
12502 [(set (match_operand:QI 0 "register_operand" "")
12503 (uneq:QI (reg:CC 17) (const_int 0)))]
12504 "TARGET_80387 || TARGET_SSE"
12505 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12506
12507(define_expand "sunge"
12508 [(set (match_operand:QI 0 "register_operand" "")
12509 (unge:QI (reg:CC 17) (const_int 0)))]
12510 "TARGET_80387 || TARGET_SSE"
12511 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12512
12513(define_expand "sungt"
12514 [(set (match_operand:QI 0 "register_operand" "")
12515 (ungt:QI (reg:CC 17) (const_int 0)))]
12516 "TARGET_80387 || TARGET_SSE"
12517 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12518
12519(define_expand "sunle"
12520 [(set (match_operand:QI 0 "register_operand" "")
12521 (unle:QI (reg:CC 17) (const_int 0)))]
12522 "TARGET_80387 || TARGET_SSE"
12523 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12524
12525(define_expand "sunlt"
12526 [(set (match_operand:QI 0 "register_operand" "")
12527 (unlt:QI (reg:CC 17) (const_int 0)))]
12528 "TARGET_80387 || TARGET_SSE"
12529 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12530
12531(define_expand "sltgt"
12532 [(set (match_operand:QI 0 "register_operand" "")
12533 (ltgt:QI (reg:CC 17) (const_int 0)))]
12534 "TARGET_80387 || TARGET_SSE"
12535 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12536
12537(define_insn "*setcc_1"
12538 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12539 (match_operator:QI 1 "ix86_comparison_operator"
12540 [(reg 17) (const_int 0)]))]
12541 ""
12542 "set%C1\t%0"
12543 [(set_attr "type" "setcc")
12544 (set_attr "mode" "QI")])
12545
12546(define_insn "setcc_2"
12547 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12548 (match_operator:QI 1 "ix86_comparison_operator"
12549 [(reg 17) (const_int 0)]))]
12550 ""
12551 "set%C1\t%0"
12552 [(set_attr "type" "setcc")
12553 (set_attr "mode" "QI")])
12554
12555;; In general it is not safe to assume too much about CCmode registers,
12556;; so simplify-rtx stops when it sees a second one. Under certain
12557;; conditions this is safe on x86, so help combine not create
12558;;
12559;; seta %al
12560;; testb %al, %al
12561;; sete %al
12562
12563(define_split
12564 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12565 (ne:QI (match_operator 1 "ix86_comparison_operator"
12566 [(reg 17) (const_int 0)])
12567 (const_int 0)))]
12568 ""
12569 [(set (match_dup 0) (match_dup 1))]
12570{
12571 PUT_MODE (operands[1], QImode);
12572})
12573
12574(define_split
12575 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12576 (ne:QI (match_operator 1 "ix86_comparison_operator"
12577 [(reg 17) (const_int 0)])
12578 (const_int 0)))]
12579 ""
12580 [(set (match_dup 0) (match_dup 1))]
12581{
12582 PUT_MODE (operands[1], QImode);
12583})
12584
12585(define_split
12586 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12587 (eq:QI (match_operator 1 "ix86_comparison_operator"
12588 [(reg 17) (const_int 0)])
12589 (const_int 0)))]
12590 ""
12591 [(set (match_dup 0) (match_dup 1))]
12592{
12593 rtx new_op1 = copy_rtx (operands[1]);
12594 operands[1] = new_op1;
12595 PUT_MODE (new_op1, QImode);
12596 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12597 GET_MODE (XEXP (new_op1, 0))));
12598
12599 /* Make sure that (a) the CCmode we have for the flags is strong
12600 enough for the reversed compare or (b) we have a valid FP compare. */
12601 if (! ix86_comparison_operator (new_op1, VOIDmode))
12602 FAIL;
12603})
12604
12605(define_split
12606 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12607 (eq:QI (match_operator 1 "ix86_comparison_operator"
12608 [(reg 17) (const_int 0)])
12609 (const_int 0)))]
12610 ""
12611 [(set (match_dup 0) (match_dup 1))]
12612{
12613 rtx new_op1 = copy_rtx (operands[1]);
12614 operands[1] = new_op1;
12615 PUT_MODE (new_op1, QImode);
12616 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12617 GET_MODE (XEXP (new_op1, 0))));
12618
12619 /* Make sure that (a) the CCmode we have for the flags is strong
12620 enough for the reversed compare or (b) we have a valid FP compare. */
12621 if (! ix86_comparison_operator (new_op1, VOIDmode))
12622 FAIL;
12623})
12624
12625;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12626;; subsequent logical operations are used to imitate conditional moves.
12627;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12628;; it directly. Futher holding this value in pseudo register might bring
12629;; problem in implicit normalization in spill code.
12630;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12631;; instructions after reload by splitting the conditional move patterns.
12632
12633(define_insn "*sse_setccsf"
12634 [(set (match_operand:SF 0 "register_operand" "=x")
12635 (match_operator:SF 1 "sse_comparison_operator"
12636 [(match_operand:SF 2 "register_operand" "0")
12637 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12638 "TARGET_SSE && reload_completed"
12639 "cmp%D1ss\t{%3, %0|%0, %3}"
12640 [(set_attr "type" "sse")
12641 (set_attr "mode" "SF")])
12642
12643(define_insn "*sse_setccdf"
12644 [(set (match_operand:DF 0 "register_operand" "=Y")
12645 (match_operator:DF 1 "sse_comparison_operator"
12646 [(match_operand:DF 2 "register_operand" "0")
12647 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12648 "TARGET_SSE2 && reload_completed"
12649 "cmp%D1sd\t{%3, %0|%0, %3}"
12650 [(set_attr "type" "sse")
12651 (set_attr "mode" "DF")])
12652
12653;; Basic conditional jump instructions.
12654;; We ignore the overflow flag for signed branch instructions.
12655
12656;; For all bCOND expanders, also expand the compare or test insn that
12657;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12658
12659(define_expand "beq"
12660 [(set (pc)
12661 (if_then_else (match_dup 1)
12662 (label_ref (match_operand 0 "" ""))
12663 (pc)))]
12664 ""
12665 "ix86_expand_branch (EQ, operands[0]); DONE;")
12666
12667(define_expand "bne"
12668 [(set (pc)
12669 (if_then_else (match_dup 1)
12670 (label_ref (match_operand 0 "" ""))
12671 (pc)))]
12672 ""
12673 "ix86_expand_branch (NE, operands[0]); DONE;")
12674
12675(define_expand "bgt"
12676 [(set (pc)
12677 (if_then_else (match_dup 1)
12678 (label_ref (match_operand 0 "" ""))
12679 (pc)))]
12680 ""
12681 "ix86_expand_branch (GT, operands[0]); DONE;")
12682
12683(define_expand "bgtu"
12684 [(set (pc)
12685 (if_then_else (match_dup 1)
12686 (label_ref (match_operand 0 "" ""))
12687 (pc)))]
12688 ""
12689 "ix86_expand_branch (GTU, operands[0]); DONE;")
12690
12691(define_expand "blt"
12692 [(set (pc)
12693 (if_then_else (match_dup 1)
12694 (label_ref (match_operand 0 "" ""))
12695 (pc)))]
12696 ""
12697 "ix86_expand_branch (LT, operands[0]); DONE;")
12698
12699(define_expand "bltu"
12700 [(set (pc)
12701 (if_then_else (match_dup 1)
12702 (label_ref (match_operand 0 "" ""))
12703 (pc)))]
12704 ""
12705 "ix86_expand_branch (LTU, operands[0]); DONE;")
12706
12707(define_expand "bge"
12708 [(set (pc)
12709 (if_then_else (match_dup 1)
12710 (label_ref (match_operand 0 "" ""))
12711 (pc)))]
12712 ""
12713 "ix86_expand_branch (GE, operands[0]); DONE;")
12714
12715(define_expand "bgeu"
12716 [(set (pc)
12717 (if_then_else (match_dup 1)
12718 (label_ref (match_operand 0 "" ""))
12719 (pc)))]
12720 ""
12721 "ix86_expand_branch (GEU, operands[0]); DONE;")
12722
12723(define_expand "ble"
12724 [(set (pc)
12725 (if_then_else (match_dup 1)
12726 (label_ref (match_operand 0 "" ""))
12727 (pc)))]
12728 ""
12729 "ix86_expand_branch (LE, operands[0]); DONE;")
12730
12731(define_expand "bleu"
12732 [(set (pc)
12733 (if_then_else (match_dup 1)
12734 (label_ref (match_operand 0 "" ""))
12735 (pc)))]
12736 ""
12737 "ix86_expand_branch (LEU, operands[0]); DONE;")
12738
12739(define_expand "bunordered"
12740 [(set (pc)
12741 (if_then_else (match_dup 1)
12742 (label_ref (match_operand 0 "" ""))
12743 (pc)))]
12744 "TARGET_80387 || TARGET_SSE"
12745 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12746
12747(define_expand "bordered"
12748 [(set (pc)
12749 (if_then_else (match_dup 1)
12750 (label_ref (match_operand 0 "" ""))
12751 (pc)))]
12752 "TARGET_80387 || TARGET_SSE"
12753 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12754
12755(define_expand "buneq"
12756 [(set (pc)
12757 (if_then_else (match_dup 1)
12758 (label_ref (match_operand 0 "" ""))
12759 (pc)))]
12760 "TARGET_80387 || TARGET_SSE"
12761 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12762
12763(define_expand "bunge"
12764 [(set (pc)
12765 (if_then_else (match_dup 1)
12766 (label_ref (match_operand 0 "" ""))
12767 (pc)))]
12768 "TARGET_80387 || TARGET_SSE"
12769 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12770
12771(define_expand "bungt"
12772 [(set (pc)
12773 (if_then_else (match_dup 1)
12774 (label_ref (match_operand 0 "" ""))
12775 (pc)))]
12776 "TARGET_80387 || TARGET_SSE"
12777 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12778
12779(define_expand "bunle"
12780 [(set (pc)
12781 (if_then_else (match_dup 1)
12782 (label_ref (match_operand 0 "" ""))
12783 (pc)))]
12784 "TARGET_80387 || TARGET_SSE"
12785 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12786
12787(define_expand "bunlt"
12788 [(set (pc)
12789 (if_then_else (match_dup 1)
12790 (label_ref (match_operand 0 "" ""))
12791 (pc)))]
12792 "TARGET_80387 || TARGET_SSE"
12793 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12794
12795(define_expand "bltgt"
12796 [(set (pc)
12797 (if_then_else (match_dup 1)
12798 (label_ref (match_operand 0 "" ""))
12799 (pc)))]
12800 "TARGET_80387 || TARGET_SSE"
12801 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12802
12803(define_insn "*jcc_1"
12804 [(set (pc)
12805 (if_then_else (match_operator 1 "ix86_comparison_operator"
12806 [(reg 17) (const_int 0)])
12807 (label_ref (match_operand 0 "" ""))
12808 (pc)))]
12809 ""
12810 "%+j%C1\t%l0"
12811 [(set_attr "type" "ibr")
12812 (set (attr "prefix_0f")
12813 (if_then_else (and (ge (minus (match_dup 0) (pc))
12814 (const_int -128))
12815 (lt (minus (match_dup 0) (pc))
12816 (const_int 124)))
12817 (const_int 0)
12818 (const_int 1)))])
12819
12820(define_insn "*jcc_2"
12821 [(set (pc)
12822 (if_then_else (match_operator 1 "ix86_comparison_operator"
12823 [(reg 17) (const_int 0)])
12824 (pc)
12825 (label_ref (match_operand 0 "" ""))))]
12826 ""
12827 "%+j%c1\t%l0"
12828 [(set_attr "type" "ibr")
12829 (set (attr "prefix_0f")
12830 (if_then_else (and (ge (minus (match_dup 0) (pc))
12831 (const_int -128))
12832 (lt (minus (match_dup 0) (pc))
12833 (const_int 124)))
12834 (const_int 0)
12835 (const_int 1)))])
12836
12837;; In general it is not safe to assume too much about CCmode registers,
12838;; so simplify-rtx stops when it sees a second one. Under certain
12839;; conditions this is safe on x86, so help combine not create
12840;;
12841;; seta %al
12842;; testb %al, %al
12843;; je Lfoo
12844
12845(define_split
12846 [(set (pc)
12847 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12848 [(reg 17) (const_int 0)])
12849 (const_int 0))
12850 (label_ref (match_operand 1 "" ""))
12851 (pc)))]
12852 ""
12853 [(set (pc)
12854 (if_then_else (match_dup 0)
12855 (label_ref (match_dup 1))
12856 (pc)))]
12857{
12858 PUT_MODE (operands[0], VOIDmode);
12859})
12860
12861(define_split
12862 [(set (pc)
12863 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12864 [(reg 17) (const_int 0)])
12865 (const_int 0))
12866 (label_ref (match_operand 1 "" ""))
12867 (pc)))]
12868 ""
12869 [(set (pc)
12870 (if_then_else (match_dup 0)
12871 (label_ref (match_dup 1))
12872 (pc)))]
12873{
12874 rtx new_op0 = copy_rtx (operands[0]);
12875 operands[0] = new_op0;
12876 PUT_MODE (new_op0, VOIDmode);
12877 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
12878 GET_MODE (XEXP (new_op0, 0))));
12879
12880 /* Make sure that (a) the CCmode we have for the flags is strong
12881 enough for the reversed compare or (b) we have a valid FP compare. */
12882 if (! ix86_comparison_operator (new_op0, VOIDmode))
12883 FAIL;
12884})
12885
12886;; Define combination compare-and-branch fp compare instructions to use
12887;; during early optimization. Splitting the operation apart early makes
12888;; for bad code when we want to reverse the operation.
12889
12890(define_insn "*fp_jcc_1"
12891 [(set (pc)
12892 (if_then_else (match_operator 0 "comparison_operator"
12893 [(match_operand 1 "register_operand" "f")
12894 (match_operand 2 "register_operand" "f")])
12895 (label_ref (match_operand 3 "" ""))
12896 (pc)))
12897 (clobber (reg:CCFP 18))
12898 (clobber (reg:CCFP 17))]
12899 "TARGET_CMOVE && TARGET_80387
12900 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12901 && FLOAT_MODE_P (GET_MODE (operands[1]))
12902 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12903 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12904 "#")
12905
12906(define_insn "*fp_jcc_1_sse"
12907 [(set (pc)
12908 (if_then_else (match_operator 0 "comparison_operator"
12909 [(match_operand 1 "register_operand" "f#x,x#f")
12910 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12911 (label_ref (match_operand 3 "" ""))
12912 (pc)))
12913 (clobber (reg:CCFP 18))
12914 (clobber (reg:CCFP 17))]
12915 "TARGET_80387
12916 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12917 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12918 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12919 "#")
12920
12921(define_insn "*fp_jcc_1_sse_only"
12922 [(set (pc)
12923 (if_then_else (match_operator 0 "comparison_operator"
12924 [(match_operand 1 "register_operand" "x")
12925 (match_operand 2 "nonimmediate_operand" "xm")])
12926 (label_ref (match_operand 3 "" ""))
12927 (pc)))
12928 (clobber (reg:CCFP 18))
12929 (clobber (reg:CCFP 17))]
12930 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12931 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12932 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12933 "#")
12934
12935(define_insn "*fp_jcc_2"
12936 [(set (pc)
12937 (if_then_else (match_operator 0 "comparison_operator"
12938 [(match_operand 1 "register_operand" "f")
12939 (match_operand 2 "register_operand" "f")])
12940 (pc)
12941 (label_ref (match_operand 3 "" ""))))
12942 (clobber (reg:CCFP 18))
12943 (clobber (reg:CCFP 17))]
12944 "TARGET_CMOVE && TARGET_80387
12945 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12946 && FLOAT_MODE_P (GET_MODE (operands[1]))
12947 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12948 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12949 "#")
12950
12951(define_insn "*fp_jcc_2_sse"
12952 [(set (pc)
12953 (if_then_else (match_operator 0 "comparison_operator"
12954 [(match_operand 1 "register_operand" "f#x,x#f")
12955 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12956 (pc)
12957 (label_ref (match_operand 3 "" ""))))
12958 (clobber (reg:CCFP 18))
12959 (clobber (reg:CCFP 17))]
12960 "TARGET_80387
12961 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12962 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12963 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12964 "#")
12965
12966(define_insn "*fp_jcc_2_sse_only"
12967 [(set (pc)
12968 (if_then_else (match_operator 0 "comparison_operator"
12969 [(match_operand 1 "register_operand" "x")
12970 (match_operand 2 "nonimmediate_operand" "xm")])
12971 (pc)
12972 (label_ref (match_operand 3 "" ""))))
12973 (clobber (reg:CCFP 18))
12974 (clobber (reg:CCFP 17))]
12975 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12976 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12977 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12978 "#")
12979
12980(define_insn "*fp_jcc_3"
12981 [(set (pc)
12982 (if_then_else (match_operator 0 "comparison_operator"
12983 [(match_operand 1 "register_operand" "f")
12984 (match_operand 2 "nonimmediate_operand" "fm")])
12985 (label_ref (match_operand 3 "" ""))
12986 (pc)))
12987 (clobber (reg:CCFP 18))
12988 (clobber (reg:CCFP 17))
12989 (clobber (match_scratch:HI 4 "=a"))]
12990 "TARGET_80387
12991 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12992 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12993 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12994 && SELECT_CC_MODE (GET_CODE (operands[0]),
12995 operands[1], operands[2]) == CCFPmode
12996 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12997 "#")
12998
12999(define_insn "*fp_jcc_4"
13000 [(set (pc)
13001 (if_then_else (match_operator 0 "comparison_operator"
13002 [(match_operand 1 "register_operand" "f")
13003 (match_operand 2 "nonimmediate_operand" "fm")])
13004 (pc)
13005 (label_ref (match_operand 3 "" ""))))
13006 (clobber (reg:CCFP 18))
13007 (clobber (reg:CCFP 17))
13008 (clobber (match_scratch:HI 4 "=a"))]
13009 "TARGET_80387
13010 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13011 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13012 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13013 && SELECT_CC_MODE (GET_CODE (operands[0]),
13014 operands[1], operands[2]) == CCFPmode
13015 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13016 "#")
13017
13018(define_insn "*fp_jcc_5"
13019 [(set (pc)
13020 (if_then_else (match_operator 0 "comparison_operator"
13021 [(match_operand 1 "register_operand" "f")
13022 (match_operand 2 "register_operand" "f")])
13023 (label_ref (match_operand 3 "" ""))
13024 (pc)))
13025 (clobber (reg:CCFP 18))
13026 (clobber (reg:CCFP 17))
13027 (clobber (match_scratch:HI 4 "=a"))]
13028 "TARGET_80387
13029 && FLOAT_MODE_P (GET_MODE (operands[1]))
13030 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13031 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13032 "#")
13033
13034(define_insn "*fp_jcc_6"
13035 [(set (pc)
13036 (if_then_else (match_operator 0 "comparison_operator"
13037 [(match_operand 1 "register_operand" "f")
13038 (match_operand 2 "register_operand" "f")])
13039 (pc)
13040 (label_ref (match_operand 3 "" ""))))
13041 (clobber (reg:CCFP 18))
13042 (clobber (reg:CCFP 17))
13043 (clobber (match_scratch:HI 4 "=a"))]
13044 "TARGET_80387
13045 && FLOAT_MODE_P (GET_MODE (operands[1]))
13046 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13047 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13048 "#")
13049
13050(define_split
13051 [(set (pc)
13052 (if_then_else (match_operator 0 "comparison_operator"
13053 [(match_operand 1 "register_operand" "")
13054 (match_operand 2 "nonimmediate_operand" "")])
13055 (match_operand 3 "" "")
13056 (match_operand 4 "" "")))
13057 (clobber (reg:CCFP 18))
13058 (clobber (reg:CCFP 17))]
13059 "reload_completed"
13060 [(const_int 0)]
13061{
13062 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13063 operands[3], operands[4], NULL_RTX);
13064 DONE;
13065})
13066
13067(define_split
13068 [(set (pc)
13069 (if_then_else (match_operator 0 "comparison_operator"
13070 [(match_operand 1 "register_operand" "")
13071 (match_operand 2 "nonimmediate_operand" "")])
13072 (match_operand 3 "" "")
13073 (match_operand 4 "" "")))
13074 (clobber (reg:CCFP 18))
13075 (clobber (reg:CCFP 17))
13076 (clobber (match_scratch:HI 5 "=a"))]
13077 "reload_completed"
13078 [(set (pc)
13079 (if_then_else (match_dup 6)
13080 (match_dup 3)
13081 (match_dup 4)))]
13082{
13083 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13084 operands[3], operands[4], operands[5]);
13085 DONE;
13086})
13087
13088;; Unconditional and other jump instructions
13089
13090(define_insn "jump"
13091 [(set (pc)
13092 (label_ref (match_operand 0 "" "")))]
13093 ""
13094 "jmp\t%l0"
13095 [(set_attr "type" "ibr")])
13096
13097(define_expand "indirect_jump"
13098 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13099 ""
13100 "")
13101
13102(define_insn "*indirect_jump"
13103 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13104 "!TARGET_64BIT"
13105 "jmp\t%A0"
13106 [(set_attr "type" "ibr")
13107 (set_attr "length_immediate" "0")])
13108
13109(define_insn "*indirect_jump_rtx64"
13110 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13111 "TARGET_64BIT"
13112 "jmp\t%A0"
13113 [(set_attr "type" "ibr")
13114 (set_attr "length_immediate" "0")])
13115
13116(define_expand "tablejump"
13117 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13118 (use (label_ref (match_operand 1 "" "")))])]
13119 ""
13120{
13121 /* In PIC mode, the table entries are stored GOT-relative. Convert
13122 the relative address to an absolute address. */
13123 if (flag_pic)
13124 {
13125 if (TARGET_64BIT)
13126 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
13127 gen_rtx_LABEL_REF (Pmode, operands[1]),
13128 NULL_RTX, 0,
13129 OPTAB_DIRECT);
13130 else if (HAVE_AS_GOTOFF_IN_DATA)
13131 {
13132 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
13133 pic_offset_table_rtx, NULL_RTX,
13134 1, OPTAB_DIRECT);
13135 current_function_uses_pic_offset_table = 1;
13136 }
13137 else
13138 {
13139 operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
13140 operands[0], NULL_RTX, 1,
13141 OPTAB_DIRECT);
13142 current_function_uses_pic_offset_table = 1;
13143 }
13144 }
13145})
13146
13147(define_insn "*tablejump_1"
13148 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13149 (use (label_ref (match_operand 1 "" "")))]
13150 "!TARGET_64BIT"
13151 "jmp\t%A0"
13152 [(set_attr "type" "ibr")
13153 (set_attr "length_immediate" "0")])
13154
13155(define_insn "*tablejump_1_rtx64"
13156 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13157 (use (label_ref (match_operand 1 "" "")))]
13158 "TARGET_64BIT"
13159 "jmp\t%A0"
13160 [(set_attr "type" "ibr")
13161 (set_attr "length_immediate" "0")])
13162
13163;; Loop instruction
13164;;
13165;; This is all complicated by the fact that since this is a jump insn
13166;; we must handle our own reloads.
13167
13168(define_expand "doloop_end"
13169 [(use (match_operand 0 "" "")) ; loop pseudo
13170 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13171 (use (match_operand 2 "" "")) ; max iterations
13172 (use (match_operand 3 "" "")) ; loop level
13173 (use (match_operand 4 "" ""))] ; label
13174 "!TARGET_64BIT && TARGET_USE_LOOP"
13175 "
13176{
13177 /* Only use cloop on innermost loops. */
13178 if (INTVAL (operands[3]) > 1)
13179 FAIL;
13180 if (GET_MODE (operands[0]) != SImode)
13181 FAIL;
13182 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13183 operands[0]));
13184 DONE;
13185}")
13186
13187(define_insn "doloop_end_internal"
13188 [(set (pc)
13189 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13190 (const_int 1))
13191 (label_ref (match_operand 0 "" ""))
13192 (pc)))
13193 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13194 (plus:SI (match_dup 1)
13195 (const_int -1)))
13196 (clobber (match_scratch:SI 3 "=X,X,r"))
13197 (clobber (reg:CC 17))]
13198 "!TARGET_64BIT && TARGET_USE_LOOP"
13199{
13200 if (which_alternative != 0)
13201 return "#";
13202 if (get_attr_length (insn) == 2)
13203 return "%+loop\t%l0";
13204 else
13205 return "dec{l}\t%1\;%+jne\t%l0";
13206}
13207 [(set_attr "ppro_uops" "many")
13208 (set (attr "type")
13209 (if_then_else (and (eq_attr "alternative" "0")
13210 (and (ge (minus (match_dup 0) (pc))
13211 (const_int -128))
13212 (lt (minus (match_dup 0) (pc))
13213 (const_int 124))))
13214 (const_string "ibr")
13215 (const_string "multi")))])
13216
13217(define_split
13218 [(set (pc)
13219 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13220 (const_int 1))
13221 (match_operand 0 "" "")
13222 (pc)))
13223 (set (match_dup 1)
13224 (plus:SI (match_dup 1)
13225 (const_int -1)))
13226 (clobber (match_scratch:SI 2 ""))
13227 (clobber (reg:CC 17))]
13228 "!TARGET_64BIT && TARGET_USE_LOOP
13229 && reload_completed
13230 && REGNO (operands[1]) != 2"
13231 [(parallel [(set (reg:CCZ 17)
13232 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13233 (const_int 0)))
13234 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13235 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13236 (match_dup 0)
13237 (pc)))]
13238 "")
13239
13240(define_split
13241 [(set (pc)
13242 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13243 (const_int 1))
13244 (match_operand 0 "" "")
13245 (pc)))
13246 (set (match_operand:SI 2 "nonimmediate_operand" "")
13247 (plus:SI (match_dup 1)
13248 (const_int -1)))
13249 (clobber (match_scratch:SI 3 ""))
13250 (clobber (reg:CC 17))]
13251 "!TARGET_64BIT && TARGET_USE_LOOP
13252 && reload_completed
13253 && (! REG_P (operands[2])
13254 || ! rtx_equal_p (operands[1], operands[2]))"
13255 [(set (match_dup 3) (match_dup 1))
13256 (parallel [(set (reg:CCZ 17)
13257 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13258 (const_int 0)))
13259 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13260 (set (match_dup 2) (match_dup 3))
13261 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13262 (match_dup 0)
13263 (pc)))]
13264 "")
13265
13266;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13267
13268(define_peephole2
13269 [(set (reg 17) (match_operand 0 "" ""))
13270 (set (match_operand:QI 1 "register_operand" "")
13271 (match_operator:QI 2 "ix86_comparison_operator"
13272 [(reg 17) (const_int 0)]))
13273 (set (match_operand 3 "q_regs_operand" "")
13274 (zero_extend (match_dup 1)))]
13275 "(peep2_reg_dead_p (3, operands[1])
13276 || operands_match_p (operands[1], operands[3]))
13277 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13278 [(set (match_dup 4) (match_dup 0))
13279 (set (strict_low_part (match_dup 5))
13280 (match_dup 2))]
13281{
13282 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13283 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13284 ix86_expand_clear (operands[3]);
13285})
13286
13287;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13288
13289(define_peephole2
13290 [(set (reg 17) (match_operand 0 "" ""))
13291 (set (match_operand:QI 1 "register_operand" "")
13292 (match_operator:QI 2 "ix86_comparison_operator"
13293 [(reg 17) (const_int 0)]))
13294 (parallel [(set (match_operand 3 "q_regs_operand" "")
13295 (zero_extend (match_dup 1)))
13296 (clobber (reg:CC 17))])]
13297 "(peep2_reg_dead_p (3, operands[1])
13298 || operands_match_p (operands[1], operands[3]))
13299 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13300 [(set (match_dup 4) (match_dup 0))
13301 (set (strict_low_part (match_dup 5))
13302 (match_dup 2))]
13303{
13304 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13305 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13306 ix86_expand_clear (operands[3]);
13307})
13308
13309;; Call instructions.
13310
13311;; The predicates normally associated with named expanders are not properly
13312;; checked for calls. This is a bug in the generic code, but it isn't that
13313;; easy to fix. Ignore it for now and be prepared to fix things up.
13314
13315;; Call subroutine returning no value.
13316
13317(define_expand "call_pop"
13318 [(parallel [(call (match_operand:QI 0 "" "")
13319 (match_operand:SI 1 "" ""))
13320 (set (reg:SI 7)
13321 (plus:SI (reg:SI 7)
13322 (match_operand:SI 3 "" "")))])]
13323 "!TARGET_64BIT"
13324{
13325 if (operands[3] == const0_rtx)
13326 {
13327 emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
13328 DONE;
13329 }
13330 /* Static functions and indirect calls don't need
13331 current_function_uses_pic_offset_table. */
13332 if (flag_pic
13333 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13334 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13335 current_function_uses_pic_offset_table = 1;
13336 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13337 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13338 if (TARGET_64BIT)
13339 abort();
13340})
13341
13342(define_insn "*call_pop_0"
13343 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13344 (match_operand:SI 1 "" ""))
13345 (set (reg:SI 7) (plus:SI (reg:SI 7)
13346 (match_operand:SI 2 "immediate_operand" "")))]
13347 "!TARGET_64BIT"
13348{
13349 if (SIBLING_CALL_P (insn))
13350 return "jmp\t%P0";
13351 else
13352 return "call\t%P0";
13353}
13354 [(set_attr "type" "call")])
13355
13356(define_insn "*call_pop_1"
13357 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13358 (match_operand:SI 1 "" ""))
13359 (set (reg:SI 7) (plus:SI (reg:SI 7)
13360 (match_operand:SI 2 "immediate_operand" "i")))]
13361 "!TARGET_64BIT"
13362{
13363 if (constant_call_address_operand (operands[0], Pmode))
13364 {
13365 if (SIBLING_CALL_P (insn))
13366 return "jmp\t%P0";
13367 else
13368 return "call\t%P0";
13369 }
13370 if (SIBLING_CALL_P (insn))
13371 return "jmp\t%A0";
13372 else
13373 return "call\t%A0";
13374}
13375 [(set_attr "type" "call")])
13376
13377(define_expand "call"
13378 [(call (match_operand:QI 0 "" "")
13379 (match_operand 1 "" ""))
13380 (use (match_operand 2 "" ""))]
13381 ;; Operand 1 not used on the i386.
13382 ""
13383{
13384 rtx insn;
13385 /* Static functions and indirect calls don't need
13386 current_function_uses_pic_offset_table. */
13387 if (flag_pic
13388 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13389 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13390 current_function_uses_pic_offset_table = 1;
13391
13392 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13393 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13394 if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
13395 {
13396 rtx reg = gen_rtx_REG (QImode, 0);
13397 emit_move_insn (reg, operands[2]);
13398 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13399 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13400 DONE;
13401 }
13402 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13403 DONE;
13404})
13405
13406(define_expand "call_exp"
13407 [(call (match_operand:QI 0 "" "")
13408 (match_operand 1 "" ""))]
13409 ""
13410 "")
13411
13412(define_insn "*call_0"
13413 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13414 (match_operand 1 "" ""))]
13415 ""
13416{
13417 if (SIBLING_CALL_P (insn))
13418 return "jmp\t%P0";
13419 else
13420 return "call\t%P0";
13421}
13422 [(set_attr "type" "call")])
13423
13424(define_insn "*call_1"
13425 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13426 (match_operand 1 "" ""))]
13427 "!TARGET_64BIT"
13428{
13429 if (constant_call_address_operand (operands[0], QImode))
13430 {
13431 if (SIBLING_CALL_P (insn))
13432 return "jmp\t%P0";
13433 else
13434 return "call\t%P0";
13435 }
13436 if (SIBLING_CALL_P (insn))
13437 return "jmp\t%A0";
13438 else
13439 return "call\t%A0";
13440}
13441 [(set_attr "type" "call")])
13442
13443(define_insn "*call_1_rex64"
13444 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13445 (match_operand 1 "" ""))]
13446 "TARGET_64BIT"
13447{
13448 if (constant_call_address_operand (operands[0], QImode))
13449 {
13450 if (SIBLING_CALL_P (insn))
13451 return "jmp\t%P0";
13452 else
13453 return "call\t%P0";
13454 }
13455 if (SIBLING_CALL_P (insn))
13456 return "jmp\t%A0";
13457 else
13458 return "call\t%A0";
13459}
13460 [(set_attr "type" "call")])
13461
13462;; Call subroutine, returning value in operand 0
13463;; (which must be a hard register).
13464
13465(define_expand "call_value_pop"
13466 [(parallel [(set (match_operand 0 "" "")
13467 (call (match_operand:QI 1 "" "")
13468 (match_operand:SI 2 "" "")))
13469 (set (reg:SI 7)
13470 (plus:SI (reg:SI 7)
13471 (match_operand:SI 4 "" "")))])]
13472 "!TARGET_64BIT"
13473{
13474 if (operands[4] == const0_rtx)
13475 {
13476 emit_insn (gen_call_value (operands[0], operands[1], operands[2],
13477 constm1_rtx));
13478 DONE;
13479 }
13480 /* Static functions and indirect calls don't need
13481 current_function_uses_pic_offset_table. */
13482 if (flag_pic
13483 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13484 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13485 current_function_uses_pic_offset_table = 1;
13486 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13487 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13488})
13489
13490(define_expand "call_value"
13491 [(set (match_operand 0 "" "")
13492 (call (match_operand:QI 1 "" "")
13493 (match_operand:SI 2 "" "")))
13494 (use (match_operand:SI 3 "" ""))]
13495 ;; Operand 2 not used on the i386.
13496 ""
13497{
13498 rtx insn;
13499 /* Static functions and indirect calls don't need
13500 current_function_uses_pic_offset_table. */
13501 if (flag_pic
13502 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13503 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13504 current_function_uses_pic_offset_table = 1;
13505 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13506 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13507 if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
13508 {
13509 rtx reg = gen_rtx_REG (QImode, 0);
13510 emit_move_insn (reg, operands[3]);
13511 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13512 operands[2]));
13513 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13514 DONE;
13515 }
13516 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13517 operands[2]));
13518 DONE;
13519})
13520
13521(define_expand "call_value_exp"
13522 [(set (match_operand 0 "" "")
13523 (call (match_operand:QI 1 "" "")
13524 (match_operand:SI 2 "" "")))]
13525 ""
13526 "")
13527
13528;; Call subroutine returning any type.
13529
13530(define_expand "untyped_call"
13531 [(parallel [(call (match_operand 0 "" "")
13532 (const_int 0))
13533 (match_operand 1 "" "")
13534 (match_operand 2 "" "")])]
13535 ""
13536{
13537 int i;
13538
13539 /* In order to give reg-stack an easier job in validating two
13540 coprocessor registers as containing a possible return value,
13541 simply pretend the untyped call returns a complex long double
13542 value. */
13543
7670 "imul{l}\t%2"
7671 [(set_attr "type" "imul")
7672 (set_attr "ppro_uops" "few")
7673 (set_attr "mode" "SI")])
7674
7675;; The patterns that match these are at the end of this file.
7676
7677(define_expand "mulxf3"
7678 [(set (match_operand:XF 0 "register_operand" "")
7679 (mult:XF (match_operand:XF 1 "register_operand" "")
7680 (match_operand:XF 2 "register_operand" "")))]
7681 "!TARGET_64BIT && TARGET_80387"
7682 "")
7683
7684(define_expand "multf3"
7685 [(set (match_operand:TF 0 "register_operand" "")
7686 (mult:TF (match_operand:TF 1 "register_operand" "")
7687 (match_operand:TF 2 "register_operand" "")))]
7688 "TARGET_80387"
7689 "")
7690
7691(define_expand "muldf3"
7692 [(set (match_operand:DF 0 "register_operand" "")
7693 (mult:DF (match_operand:DF 1 "register_operand" "")
7694 (match_operand:DF 2 "nonimmediate_operand" "")))]
7695 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7696 "")
7697
7698(define_expand "mulsf3"
7699 [(set (match_operand:SF 0 "register_operand" "")
7700 (mult:SF (match_operand:SF 1 "register_operand" "")
7701 (match_operand:SF 2 "nonimmediate_operand" "")))]
7702 "TARGET_80387 || TARGET_SSE_MATH"
7703 "")
7704
7705;; Divide instructions
7706
7707(define_insn "divqi3"
7708 [(set (match_operand:QI 0 "register_operand" "=a")
7709 (div:QI (match_operand:HI 1 "register_operand" "0")
7710 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7711 (clobber (reg:CC 17))]
7712 "TARGET_QIMODE_MATH"
7713 "idiv{b}\t%2"
7714 [(set_attr "type" "idiv")
7715 (set_attr "mode" "QI")
7716 (set_attr "ppro_uops" "few")])
7717
7718(define_insn "udivqi3"
7719 [(set (match_operand:QI 0 "register_operand" "=a")
7720 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7721 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7722 (clobber (reg:CC 17))]
7723 "TARGET_QIMODE_MATH"
7724 "div{b}\t%2"
7725 [(set_attr "type" "idiv")
7726 (set_attr "mode" "QI")
7727 (set_attr "ppro_uops" "few")])
7728
7729;; The patterns that match these are at the end of this file.
7730
7731(define_expand "divxf3"
7732 [(set (match_operand:XF 0 "register_operand" "")
7733 (div:XF (match_operand:XF 1 "register_operand" "")
7734 (match_operand:XF 2 "register_operand" "")))]
7735 "!TARGET_64BIT && TARGET_80387"
7736 "")
7737
7738(define_expand "divtf3"
7739 [(set (match_operand:TF 0 "register_operand" "")
7740 (div:TF (match_operand:TF 1 "register_operand" "")
7741 (match_operand:TF 2 "register_operand" "")))]
7742 "TARGET_80387"
7743 "")
7744
7745(define_expand "divdf3"
7746 [(set (match_operand:DF 0 "register_operand" "")
7747 (div:DF (match_operand:DF 1 "register_operand" "")
7748 (match_operand:DF 2 "nonimmediate_operand" "")))]
7749 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7750 "")
7751
7752(define_expand "divsf3"
7753 [(set (match_operand:SF 0 "register_operand" "")
7754 (div:SF (match_operand:SF 1 "register_operand" "")
7755 (match_operand:SF 2 "nonimmediate_operand" "")))]
7756 "TARGET_80387 || TARGET_SSE_MATH"
7757 "")
7758
7759;; Remainder instructions.
7760
7761(define_expand "divmoddi4"
7762 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7763 (div:DI (match_operand:DI 1 "register_operand" "")
7764 (match_operand:DI 2 "nonimmediate_operand" "")))
7765 (set (match_operand:DI 3 "register_operand" "")
7766 (mod:DI (match_dup 1) (match_dup 2)))
7767 (clobber (reg:CC 17))])]
7768 "TARGET_64BIT"
7769 "")
7770
7771;; Allow to come the parameter in eax or edx to avoid extra moves.
7772;; Penalize eax case sligthly because it results in worse scheduling
7773;; of code.
7774(define_insn "*divmoddi4_nocltd_rex64"
7775 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7776 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7777 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7778 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7779 (mod:DI (match_dup 2) (match_dup 3)))
7780 (clobber (reg:CC 17))]
7781 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7782 "#"
7783 [(set_attr "type" "multi")])
7784
7785(define_insn "*divmoddi4_cltd_rex64"
7786 [(set (match_operand:DI 0 "register_operand" "=a")
7787 (div:DI (match_operand:DI 2 "register_operand" "a")
7788 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7789 (set (match_operand:DI 1 "register_operand" "=&d")
7790 (mod:DI (match_dup 2) (match_dup 3)))
7791 (clobber (reg:CC 17))]
7792 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7793 "#"
7794 [(set_attr "type" "multi")])
7795
7796(define_insn "*divmoddi_noext_rex64"
7797 [(set (match_operand:DI 0 "register_operand" "=a")
7798 (div:DI (match_operand:DI 1 "register_operand" "0")
7799 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7800 (set (match_operand:DI 3 "register_operand" "=d")
7801 (mod:DI (match_dup 1) (match_dup 2)))
7802 (use (match_operand:DI 4 "register_operand" "3"))
7803 (clobber (reg:CC 17))]
7804 "TARGET_64BIT"
7805 "idiv{q}\t%2"
7806 [(set_attr "type" "idiv")
7807 (set_attr "mode" "DI")
7808 (set_attr "ppro_uops" "few")])
7809
7810(define_split
7811 [(set (match_operand:DI 0 "register_operand" "")
7812 (div:DI (match_operand:DI 1 "register_operand" "")
7813 (match_operand:DI 2 "nonimmediate_operand" "")))
7814 (set (match_operand:DI 3 "register_operand" "")
7815 (mod:DI (match_dup 1) (match_dup 2)))
7816 (clobber (reg:CC 17))]
7817 "TARGET_64BIT && reload_completed"
7818 [(parallel [(set (match_dup 3)
7819 (ashiftrt:DI (match_dup 4) (const_int 63)))
7820 (clobber (reg:CC 17))])
7821 (parallel [(set (match_dup 0)
7822 (div:DI (reg:DI 0) (match_dup 2)))
7823 (set (match_dup 3)
7824 (mod:DI (reg:DI 0) (match_dup 2)))
7825 (use (match_dup 3))
7826 (clobber (reg:CC 17))])]
7827{
7828 /* Avoid use of cltd in favour of a mov+shift. */
7829 if (!TARGET_USE_CLTD && !optimize_size)
7830 {
7831 if (true_regnum (operands[1]))
7832 emit_move_insn (operands[0], operands[1]);
7833 else
7834 emit_move_insn (operands[3], operands[1]);
7835 operands[4] = operands[3];
7836 }
7837 else
7838 {
7839 if (true_regnum (operands[1]))
7840 abort();
7841 operands[4] = operands[1];
7842 }
7843})
7844
7845
7846(define_expand "divmodsi4"
7847 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7848 (div:SI (match_operand:SI 1 "register_operand" "")
7849 (match_operand:SI 2 "nonimmediate_operand" "")))
7850 (set (match_operand:SI 3 "register_operand" "")
7851 (mod:SI (match_dup 1) (match_dup 2)))
7852 (clobber (reg:CC 17))])]
7853 ""
7854 "")
7855
7856;; Allow to come the parameter in eax or edx to avoid extra moves.
7857;; Penalize eax case sligthly because it results in worse scheduling
7858;; of code.
7859(define_insn "*divmodsi4_nocltd"
7860 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7861 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7862 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7863 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7864 (mod:SI (match_dup 2) (match_dup 3)))
7865 (clobber (reg:CC 17))]
7866 "!optimize_size && !TARGET_USE_CLTD"
7867 "#"
7868 [(set_attr "type" "multi")])
7869
7870(define_insn "*divmodsi4_cltd"
7871 [(set (match_operand:SI 0 "register_operand" "=a")
7872 (div:SI (match_operand:SI 2 "register_operand" "a")
7873 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7874 (set (match_operand:SI 1 "register_operand" "=&d")
7875 (mod:SI (match_dup 2) (match_dup 3)))
7876 (clobber (reg:CC 17))]
7877 "optimize_size || TARGET_USE_CLTD"
7878 "#"
7879 [(set_attr "type" "multi")])
7880
7881(define_insn "*divmodsi_noext"
7882 [(set (match_operand:SI 0 "register_operand" "=a")
7883 (div:SI (match_operand:SI 1 "register_operand" "0")
7884 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7885 (set (match_operand:SI 3 "register_operand" "=d")
7886 (mod:SI (match_dup 1) (match_dup 2)))
7887 (use (match_operand:SI 4 "register_operand" "3"))
7888 (clobber (reg:CC 17))]
7889 ""
7890 "idiv{l}\t%2"
7891 [(set_attr "type" "idiv")
7892 (set_attr "mode" "SI")
7893 (set_attr "ppro_uops" "few")])
7894
7895(define_split
7896 [(set (match_operand:SI 0 "register_operand" "")
7897 (div:SI (match_operand:SI 1 "register_operand" "")
7898 (match_operand:SI 2 "nonimmediate_operand" "")))
7899 (set (match_operand:SI 3 "register_operand" "")
7900 (mod:SI (match_dup 1) (match_dup 2)))
7901 (clobber (reg:CC 17))]
7902 "reload_completed"
7903 [(parallel [(set (match_dup 3)
7904 (ashiftrt:SI (match_dup 4) (const_int 31)))
7905 (clobber (reg:CC 17))])
7906 (parallel [(set (match_dup 0)
7907 (div:SI (reg:SI 0) (match_dup 2)))
7908 (set (match_dup 3)
7909 (mod:SI (reg:SI 0) (match_dup 2)))
7910 (use (match_dup 3))
7911 (clobber (reg:CC 17))])]
7912{
7913 /* Avoid use of cltd in favour of a mov+shift. */
7914 if (!TARGET_USE_CLTD && !optimize_size)
7915 {
7916 if (true_regnum (operands[1]))
7917 emit_move_insn (operands[0], operands[1]);
7918 else
7919 emit_move_insn (operands[3], operands[1]);
7920 operands[4] = operands[3];
7921 }
7922 else
7923 {
7924 if (true_regnum (operands[1]))
7925 abort();
7926 operands[4] = operands[1];
7927 }
7928})
7929;; %%% Split me.
7930(define_insn "divmodhi4"
7931 [(set (match_operand:HI 0 "register_operand" "=a")
7932 (div:HI (match_operand:HI 1 "register_operand" "0")
7933 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7934 (set (match_operand:HI 3 "register_operand" "=&d")
7935 (mod:HI (match_dup 1) (match_dup 2)))
7936 (clobber (reg:CC 17))]
7937 "TARGET_HIMODE_MATH"
7938 "cwtd\;idiv{w}\t%2"
7939 [(set_attr "type" "multi")
7940 (set_attr "length_immediate" "0")
7941 (set_attr "mode" "SI")])
7942
7943(define_insn "udivmoddi4"
7944 [(set (match_operand:DI 0 "register_operand" "=a")
7945 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7946 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7947 (set (match_operand:DI 3 "register_operand" "=&d")
7948 (umod:DI (match_dup 1) (match_dup 2)))
7949 (clobber (reg:CC 17))]
7950 "TARGET_64BIT"
7951 "xor{q}\t%3, %3\;div{q}\t%2"
7952 [(set_attr "type" "multi")
7953 (set_attr "length_immediate" "0")
7954 (set_attr "mode" "DI")])
7955
7956(define_insn "*udivmoddi4_noext"
7957 [(set (match_operand:DI 0 "register_operand" "=a")
7958 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7959 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7960 (set (match_operand:DI 3 "register_operand" "=d")
7961 (umod:DI (match_dup 1) (match_dup 2)))
7962 (use (match_dup 3))
7963 (clobber (reg:CC 17))]
7964 "TARGET_64BIT"
7965 "div{q}\t%2"
7966 [(set_attr "type" "idiv")
7967 (set_attr "ppro_uops" "few")
7968 (set_attr "mode" "DI")])
7969
7970(define_split
7971 [(set (match_operand:DI 0 "register_operand" "")
7972 (udiv:DI (match_operand:DI 1 "register_operand" "")
7973 (match_operand:DI 2 "nonimmediate_operand" "")))
7974 (set (match_operand:DI 3 "register_operand" "")
7975 (umod:DI (match_dup 1) (match_dup 2)))
7976 (clobber (reg:CC 17))]
7977 "TARGET_64BIT && reload_completed"
7978 [(set (match_dup 3) (const_int 0))
7979 (parallel [(set (match_dup 0)
7980 (udiv:DI (match_dup 1) (match_dup 2)))
7981 (set (match_dup 3)
7982 (umod:DI (match_dup 1) (match_dup 2)))
7983 (use (match_dup 3))
7984 (clobber (reg:CC 17))])]
7985 "")
7986
7987(define_insn "udivmodsi4"
7988 [(set (match_operand:SI 0 "register_operand" "=a")
7989 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7990 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7991 (set (match_operand:SI 3 "register_operand" "=&d")
7992 (umod:SI (match_dup 1) (match_dup 2)))
7993 (clobber (reg:CC 17))]
7994 ""
7995 "xor{l}\t%3, %3\;div{l}\t%2"
7996 [(set_attr "type" "multi")
7997 (set_attr "length_immediate" "0")
7998 (set_attr "mode" "SI")])
7999
8000(define_insn "*udivmodsi4_noext"
8001 [(set (match_operand:SI 0 "register_operand" "=a")
8002 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8003 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8004 (set (match_operand:SI 3 "register_operand" "=d")
8005 (umod:SI (match_dup 1) (match_dup 2)))
8006 (use (match_dup 3))
8007 (clobber (reg:CC 17))]
8008 ""
8009 "div{l}\t%2"
8010 [(set_attr "type" "idiv")
8011 (set_attr "ppro_uops" "few")
8012 (set_attr "mode" "SI")])
8013
8014(define_split
8015 [(set (match_operand:SI 0 "register_operand" "")
8016 (udiv:SI (match_operand:SI 1 "register_operand" "")
8017 (match_operand:SI 2 "nonimmediate_operand" "")))
8018 (set (match_operand:SI 3 "register_operand" "")
8019 (umod:SI (match_dup 1) (match_dup 2)))
8020 (clobber (reg:CC 17))]
8021 "reload_completed"
8022 [(set (match_dup 3) (const_int 0))
8023 (parallel [(set (match_dup 0)
8024 (udiv:SI (match_dup 1) (match_dup 2)))
8025 (set (match_dup 3)
8026 (umod:SI (match_dup 1) (match_dup 2)))
8027 (use (match_dup 3))
8028 (clobber (reg:CC 17))])]
8029 "")
8030
8031(define_expand "udivmodhi4"
8032 [(set (match_dup 4) (const_int 0))
8033 (parallel [(set (match_operand:HI 0 "register_operand" "")
8034 (udiv:HI (match_operand:HI 1 "register_operand" "")
8035 (match_operand:HI 2 "nonimmediate_operand" "")))
8036 (set (match_operand:HI 3 "register_operand" "")
8037 (umod:HI (match_dup 1) (match_dup 2)))
8038 (use (match_dup 4))
8039 (clobber (reg:CC 17))])]
8040 "TARGET_HIMODE_MATH"
8041 "operands[4] = gen_reg_rtx (HImode);")
8042
8043(define_insn "*udivmodhi_noext"
8044 [(set (match_operand:HI 0 "register_operand" "=a")
8045 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8046 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8047 (set (match_operand:HI 3 "register_operand" "=d")
8048 (umod:HI (match_dup 1) (match_dup 2)))
8049 (use (match_operand:HI 4 "register_operand" "3"))
8050 (clobber (reg:CC 17))]
8051 ""
8052 "div{w}\t%2"
8053 [(set_attr "type" "idiv")
8054 (set_attr "mode" "HI")
8055 (set_attr "ppro_uops" "few")])
8056
8057;; We can not use div/idiv for double division, because it causes
8058;; "division by zero" on the overflow and that's not what we expect
8059;; from truncate. Because true (non truncating) double division is
8060;; never generated, we can't create this insn anyway.
8061;
8062;(define_insn ""
8063; [(set (match_operand:SI 0 "register_operand" "=a")
8064; (truncate:SI
8065; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8066; (zero_extend:DI
8067; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8068; (set (match_operand:SI 3 "register_operand" "=d")
8069; (truncate:SI
8070; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8071; (clobber (reg:CC 17))]
8072; ""
8073; "div{l}\t{%2, %0|%0, %2}"
8074; [(set_attr "type" "idiv")
8075; (set_attr "ppro_uops" "few")])
8076
8077;;- Logical AND instructions
8078
8079;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8080;; Note that this excludes ah.
8081
8082(define_insn "*testdi_1_rex64"
8083 [(set (reg 17)
8084 (compare
8085 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
8086 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
8087 (const_int 0)))]
8088 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8089 "@
8090 test{l}\t{%k1, %k0|%k0, %k1}
8091 test{l}\t{%k1, %k0|%k0, %k1}
8092 test{q}\t{%1, %0|%0, %1}
8093 test{q}\t{%1, %0|%0, %1}
8094 test{q}\t{%1, %0|%0, %1}"
8095 [(set_attr "type" "test")
8096 (set_attr "modrm" "0,1,0,1,1")
8097 (set_attr "mode" "SI,SI,DI,DI,DI")
8098 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8099
8100(define_insn "testsi_1"
8101 [(set (reg 17)
8102 (compare
8103 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
8104 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
8105 (const_int 0)))]
8106 "ix86_match_ccmode (insn, CCNOmode)"
8107 "test{l}\t{%1, %0|%0, %1}"
8108 [(set_attr "type" "test")
8109 (set_attr "modrm" "0,1,1")
8110 (set_attr "mode" "SI")
8111 (set_attr "pent_pair" "uv,np,uv")])
8112
8113(define_expand "testsi_ccno_1"
8114 [(set (reg:CCNO 17)
8115 (compare:CCNO
8116 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8117 (match_operand:SI 1 "nonmemory_operand" ""))
8118 (const_int 0)))]
8119 ""
8120 "")
8121
8122(define_insn "*testhi_1"
8123 [(set (reg 17)
8124 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
8125 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
8126 (const_int 0)))]
8127 "ix86_match_ccmode (insn, CCNOmode)"
8128 "test{w}\t{%1, %0|%0, %1}"
8129 [(set_attr "type" "test")
8130 (set_attr "modrm" "0,1,1")
8131 (set_attr "mode" "HI")
8132 (set_attr "pent_pair" "uv,np,uv")])
8133
8134(define_expand "testqi_ccz_1"
8135 [(set (reg:CCZ 17)
8136 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8137 (match_operand:QI 1 "nonmemory_operand" ""))
8138 (const_int 0)))]
8139 ""
8140 "")
8141
8142(define_insn "*testqi_1"
8143 [(set (reg 17)
8144 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
8145 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
8146 (const_int 0)))]
8147 "ix86_match_ccmode (insn, CCNOmode)"
8148{
8149 if (which_alternative == 3)
8150 {
8151 if (GET_CODE (operands[1]) == CONST_INT
8152 && (INTVAL (operands[1]) & 0xffffff00))
8153 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8154 return "test{l}\t{%1, %k0|%k0, %1}";
8155 }
8156 return "test{b}\t{%1, %0|%0, %1}";
8157}
8158 [(set_attr "type" "test")
8159 (set_attr "modrm" "0,1,1,1")
8160 (set_attr "mode" "QI,QI,QI,SI")
8161 (set_attr "pent_pair" "uv,np,uv,np")])
8162
8163(define_expand "testqi_ext_ccno_0"
8164 [(set (reg:CCNO 17)
8165 (compare:CCNO
8166 (and:SI
8167 (zero_extract:SI
8168 (match_operand 0 "ext_register_operand" "")
8169 (const_int 8)
8170 (const_int 8))
8171 (match_operand 1 "const_int_operand" ""))
8172 (const_int 0)))]
8173 ""
8174 "")
8175
8176(define_insn "*testqi_ext_0"
8177 [(set (reg 17)
8178 (compare
8179 (and:SI
8180 (zero_extract:SI
8181 (match_operand 0 "ext_register_operand" "Q")
8182 (const_int 8)
8183 (const_int 8))
8184 (match_operand 1 "const_int_operand" "n"))
8185 (const_int 0)))]
8186 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
8187 && ix86_match_ccmode (insn, CCNOmode)"
8188 "test{b}\t{%1, %h0|%h0, %1}"
8189 [(set_attr "type" "test")
8190 (set_attr "mode" "QI")
8191 (set_attr "length_immediate" "1")
8192 (set_attr "pent_pair" "np")])
8193
8194(define_insn "*testqi_ext_1"
8195 [(set (reg 17)
8196 (compare
8197 (and:SI
8198 (zero_extract:SI
8199 (match_operand 0 "ext_register_operand" "Q")
8200 (const_int 8)
8201 (const_int 8))
8202 (zero_extend:SI
8203 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
8204 (const_int 0)))]
8205 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8206 "test{b}\t{%1, %h0|%h0, %1}"
8207 [(set_attr "type" "test")
8208 (set_attr "mode" "QI")])
8209
8210(define_insn "*testqi_ext_1_rex64"
8211 [(set (reg 17)
8212 (compare
8213 (and:SI
8214 (zero_extract:SI
8215 (match_operand 0 "ext_register_operand" "Q")
8216 (const_int 8)
8217 (const_int 8))
8218 (zero_extend:SI
8219 (match_operand:QI 1 "register_operand" "Q")))
8220 (const_int 0)))]
8221 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8222 "test{b}\t{%1, %h0|%h0, %1}"
8223 [(set_attr "type" "test")
8224 (set_attr "mode" "QI")])
8225
8226(define_insn "*testqi_ext_2"
8227 [(set (reg 17)
8228 (compare
8229 (and:SI
8230 (zero_extract:SI
8231 (match_operand 0 "ext_register_operand" "Q")
8232 (const_int 8)
8233 (const_int 8))
8234 (zero_extract:SI
8235 (match_operand 1 "ext_register_operand" "Q")
8236 (const_int 8)
8237 (const_int 8)))
8238 (const_int 0)))]
8239 "ix86_match_ccmode (insn, CCNOmode)"
8240 "test{b}\t{%h1, %h0|%h0, %h1}"
8241 [(set_attr "type" "test")
8242 (set_attr "mode" "QI")])
8243
8244;; Combine likes to form bit extractions for some tests. Humor it.
8245(define_insn "*testqi_ext_3"
8246 [(set (reg 17)
8247 (compare (zero_extract:SI
8248 (match_operand 0 "nonimmediate_operand" "rm")
8249 (match_operand:SI 1 "const_int_operand" "")
8250 (match_operand:SI 2 "const_int_operand" ""))
8251 (const_int 0)))]
8252 "ix86_match_ccmode (insn, CCNOmode)
8253 && (GET_MODE (operands[0]) == SImode
8254 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8255 || GET_MODE (operands[0]) == HImode
8256 || GET_MODE (operands[0]) == QImode)"
8257 "#")
8258
8259(define_insn "*testqi_ext_3_rex64"
8260 [(set (reg 17)
8261 (compare (zero_extract:DI
8262 (match_operand 0 "nonimmediate_operand" "rm")
8263 (match_operand:DI 1 "const_int_operand" "")
8264 (match_operand:DI 2 "const_int_operand" ""))
8265 (const_int 0)))]
8266 "TARGET_64BIT
8267 && ix86_match_ccmode (insn, CCNOmode)
8268 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8269 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8270 /* Ensure that resulting mask is zero or sign extended operand. */
8271 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8272 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8273 && INTVAL (operands[1]) > 32))
8274 && (GET_MODE (operands[0]) == SImode
8275 || GET_MODE (operands[0]) == DImode
8276 || GET_MODE (operands[0]) == HImode
8277 || GET_MODE (operands[0]) == QImode)"
8278 "#")
8279
8280(define_split
8281 [(set (reg 17)
8282 (compare (zero_extract
8283 (match_operand 0 "nonimmediate_operand" "")
8284 (match_operand 1 "const_int_operand" "")
8285 (match_operand 2 "const_int_operand" ""))
8286 (const_int 0)))]
8287 "ix86_match_ccmode (insn, CCNOmode)"
8288 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8289{
8290 HOST_WIDE_INT len = INTVAL (operands[1]);
8291 HOST_WIDE_INT pos = INTVAL (operands[2]);
8292 HOST_WIDE_INT mask;
8293 enum machine_mode mode, submode;
8294
8295 mode = GET_MODE (operands[0]);
8296 if (GET_CODE (operands[0]) == MEM)
8297 {
8298 /* ??? Combine likes to put non-volatile mem extractions in QImode
8299 no matter the size of the test. So find a mode that works. */
8300 if (! MEM_VOLATILE_P (operands[0]))
8301 {
8302 mode = smallest_mode_for_size (pos + len, MODE_INT);
8303 operands[0] = adjust_address (operands[0], mode, 0);
8304 }
8305 }
8306 else if (GET_CODE (operands[0]) == SUBREG
8307 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8308 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8309 && pos + len <= GET_MODE_BITSIZE (submode))
8310 {
8311 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8312 mode = submode;
8313 operands[0] = SUBREG_REG (operands[0]);
8314 }
8315 else if (mode == HImode && pos + len <= 8)
8316 {
8317 /* Small HImode tests can be converted to QImode. */
8318 mode = QImode;
8319 operands[0] = gen_lowpart (QImode, operands[0]);
8320 }
8321
8322 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8323 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8324
8325 operands[3] = gen_rtx_AND (mode, operands[0],
8326 GEN_INT (trunc_int_for_mode (mask, mode)));
8327})
8328
8329;; %%% This used to optimize known byte-wide and operations to memory,
8330;; and sometimes to QImode registers. If this is considered useful,
8331;; it should be done with splitters.
8332
8333(define_expand "anddi3"
8334 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8335 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8336 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8337 (clobber (reg:CC 17))]
8338 "TARGET_64BIT"
8339 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8340
8341(define_insn "*anddi_1_rex64"
8342 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8343 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8344 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8345 (clobber (reg:CC 17))]
8346 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8347{
8348 switch (get_attr_type (insn))
8349 {
8350 case TYPE_IMOVX:
8351 {
8352 enum machine_mode mode;
8353
8354 if (GET_CODE (operands[2]) != CONST_INT)
8355 abort ();
8356 if (INTVAL (operands[2]) == 0xff)
8357 mode = QImode;
8358 else if (INTVAL (operands[2]) == 0xffff)
8359 mode = HImode;
8360 else
8361 abort ();
8362
8363 operands[1] = gen_lowpart (mode, operands[1]);
8364 if (mode == QImode)
8365 return "movz{bq|x}\t{%1,%0|%0, %1}";
8366 else
8367 return "movz{wq|x}\t{%1,%0|%0, %1}";
8368 }
8369
8370 default:
8371 if (! rtx_equal_p (operands[0], operands[1]))
8372 abort ();
8373 if (get_attr_mode (insn) == MODE_SI)
8374 return "and{l}\t{%k2, %k0|%k0, %k2}";
8375 else
8376 return "and{q}\t{%2, %0|%0, %2}";
8377 }
8378}
8379 [(set_attr "type" "alu,alu,alu,imovx")
8380 (set_attr "length_immediate" "*,*,*,0")
8381 (set_attr "mode" "SI,DI,DI,DI")])
8382
8383(define_insn "*anddi_2"
8384 [(set (reg 17)
8385 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8386 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8387 (const_int 0)))
8388 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8389 (and:DI (match_dup 1) (match_dup 2)))]
8390 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8391 && ix86_binary_operator_ok (AND, DImode, operands)"
8392 "@
8393 and{l}\t{%k2, %k0|%k0, %k2}
8394 and{q}\t{%2, %0|%0, %2}
8395 and{q}\t{%2, %0|%0, %2}"
8396 [(set_attr "type" "alu")
8397 (set_attr "mode" "SI,DI,DI")])
8398
8399(define_expand "andsi3"
8400 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8401 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8402 (match_operand:SI 2 "general_operand" "")))
8403 (clobber (reg:CC 17))]
8404 ""
8405 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8406
8407(define_insn "*andsi_1"
8408 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8409 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8410 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8411 (clobber (reg:CC 17))]
8412 "ix86_binary_operator_ok (AND, SImode, operands)"
8413{
8414 switch (get_attr_type (insn))
8415 {
8416 case TYPE_IMOVX:
8417 {
8418 enum machine_mode mode;
8419
8420 if (GET_CODE (operands[2]) != CONST_INT)
8421 abort ();
8422 if (INTVAL (operands[2]) == 0xff)
8423 mode = QImode;
8424 else if (INTVAL (operands[2]) == 0xffff)
8425 mode = HImode;
8426 else
8427 abort ();
8428
8429 operands[1] = gen_lowpart (mode, operands[1]);
8430 if (mode == QImode)
8431 return "movz{bl|x}\t{%1,%0|%0, %1}";
8432 else
8433 return "movz{wl|x}\t{%1,%0|%0, %1}";
8434 }
8435
8436 default:
8437 if (! rtx_equal_p (operands[0], operands[1]))
8438 abort ();
8439 return "and{l}\t{%2, %0|%0, %2}";
8440 }
8441}
8442 [(set_attr "type" "alu,alu,imovx")
8443 (set_attr "length_immediate" "*,*,0")
8444 (set_attr "mode" "SI")])
8445
8446(define_split
8447 [(set (match_operand 0 "register_operand" "")
8448 (and (match_dup 0)
8449 (const_int -65536)))
8450 (clobber (reg:CC 17))]
8451 "optimize_size"
8452 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8453 "operands[1] = gen_lowpart (HImode, operands[0]);")
8454
8455(define_split
8456 [(set (match_operand 0 "ext_register_operand" "")
8457 (and (match_dup 0)
8458 (const_int -256)))
8459 (clobber (reg:CC 17))]
8460 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8461 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8462 "operands[1] = gen_lowpart (QImode, operands[0]);")
8463
8464(define_split
8465 [(set (match_operand 0 "ext_register_operand" "")
8466 (and (match_dup 0)
8467 (const_int -65281)))
8468 (clobber (reg:CC 17))]
8469 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8470 [(parallel [(set (zero_extract:SI (match_dup 0)
8471 (const_int 8)
8472 (const_int 8))
8473 (xor:SI
8474 (zero_extract:SI (match_dup 0)
8475 (const_int 8)
8476 (const_int 8))
8477 (zero_extract:SI (match_dup 0)
8478 (const_int 8)
8479 (const_int 8))))
8480 (clobber (reg:CC 17))])]
8481 "operands[0] = gen_lowpart (SImode, operands[0]);")
8482
8483;; See comment for addsi_1_zext why we do use nonimmediate_operand
8484(define_insn "*andsi_1_zext"
8485 [(set (match_operand:DI 0 "register_operand" "=r")
8486 (zero_extend:DI
8487 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8488 (match_operand:SI 2 "general_operand" "rim"))))
8489 (clobber (reg:CC 17))]
8490 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8491 "and{l}\t{%2, %k0|%k0, %2}"
8492 [(set_attr "type" "alu")
8493 (set_attr "mode" "SI")])
8494
8495(define_insn "*andsi_2"
8496 [(set (reg 17)
8497 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8498 (match_operand:SI 2 "general_operand" "rim,ri"))
8499 (const_int 0)))
8500 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8501 (and:SI (match_dup 1) (match_dup 2)))]
8502 "ix86_match_ccmode (insn, CCNOmode)
8503 && ix86_binary_operator_ok (AND, SImode, operands)"
8504 "and{l}\t{%2, %0|%0, %2}"
8505 [(set_attr "type" "alu")
8506 (set_attr "mode" "SI")])
8507
8508;; See comment for addsi_1_zext why we do use nonimmediate_operand
8509(define_insn "*andsi_2_zext"
8510 [(set (reg 17)
8511 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8512 (match_operand:SI 2 "general_operand" "rim"))
8513 (const_int 0)))
8514 (set (match_operand:DI 0 "register_operand" "=r")
8515 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8516 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8517 && ix86_binary_operator_ok (AND, SImode, operands)"
8518 "and{l}\t{%2, %k0|%k0, %2}"
8519 [(set_attr "type" "alu")
8520 (set_attr "mode" "SI")])
8521
8522(define_expand "andhi3"
8523 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8524 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8525 (match_operand:HI 2 "general_operand" "")))
8526 (clobber (reg:CC 17))]
8527 "TARGET_HIMODE_MATH"
8528 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8529
8530(define_insn "*andhi_1"
8531 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8532 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8533 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8534 (clobber (reg:CC 17))]
8535 "ix86_binary_operator_ok (AND, HImode, operands)"
8536{
8537 switch (get_attr_type (insn))
8538 {
8539 case TYPE_IMOVX:
8540 if (GET_CODE (operands[2]) != CONST_INT)
8541 abort ();
8542 if (INTVAL (operands[2]) == 0xff)
8543 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8544 abort ();
8545
8546 default:
8547 if (! rtx_equal_p (operands[0], operands[1]))
8548 abort ();
8549
8550 return "and{w}\t{%2, %0|%0, %2}";
8551 }
8552}
8553 [(set_attr "type" "alu,alu,imovx")
8554 (set_attr "length_immediate" "*,*,0")
8555 (set_attr "mode" "HI,HI,SI")])
8556
8557(define_insn "*andhi_2"
8558 [(set (reg 17)
8559 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8560 (match_operand:HI 2 "general_operand" "rim,ri"))
8561 (const_int 0)))
8562 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8563 (and:HI (match_dup 1) (match_dup 2)))]
8564 "ix86_match_ccmode (insn, CCNOmode)
8565 && ix86_binary_operator_ok (AND, HImode, operands)"
8566 "and{w}\t{%2, %0|%0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "mode" "HI")])
8569
8570(define_expand "andqi3"
8571 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8572 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8573 (match_operand:QI 2 "general_operand" "")))
8574 (clobber (reg:CC 17))]
8575 "TARGET_QIMODE_MATH"
8576 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8577
8578;; %%% Potential partial reg stall on alternative 2. What to do?
8579(define_insn "*andqi_1"
8580 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8581 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8582 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8583 (clobber (reg:CC 17))]
8584 "ix86_binary_operator_ok (AND, QImode, operands)"
8585 "@
8586 and{b}\t{%2, %0|%0, %2}
8587 and{b}\t{%2, %0|%0, %2}
8588 and{l}\t{%k2, %k0|%k0, %k2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "mode" "QI,QI,SI")])
8591
8592(define_insn "*andqi_1_slp"
8593 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8594 (and:QI (match_dup 0)
8595 (match_operand:QI 1 "general_operand" "qi,qmi")))
8596 (clobber (reg:CC 17))]
8597 ""
8598 "and{b}\t{%1, %0|%0, %1}"
8599 [(set_attr "type" "alu1")
8600 (set_attr "mode" "QI")])
8601
8602(define_insn "*andqi_2"
8603 [(set (reg 17)
8604 (compare (and:QI
8605 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8606 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8607 (const_int 0)))
8608 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8609 (and:QI (match_dup 1) (match_dup 2)))]
8610 "ix86_match_ccmode (insn, CCNOmode)
8611 && ix86_binary_operator_ok (AND, QImode, operands)"
8612{
8613 if (which_alternative == 2)
8614 {
8615 if (GET_CODE (operands[2]) == CONST_INT
8616 && (INTVAL (operands[2]) & 0xffffff00))
8617 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8618 return "and{l}\t{%2, %k0|%k0, %2}";
8619 }
8620 return "and{b}\t{%2, %0|%0, %2}";
8621}
8622 [(set_attr "type" "alu")
8623 (set_attr "mode" "QI,QI,SI")])
8624
8625(define_insn "*andqi_2_slp"
8626 [(set (reg 17)
8627 (compare (and:QI
8628 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8629 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8630 (const_int 0)))
8631 (set (strict_low_part (match_dup 0))
8632 (and:QI (match_dup 0) (match_dup 1)))]
8633 "ix86_match_ccmode (insn, CCNOmode)"
8634 "and{b}\t{%1, %0|%0, %1}"
8635 [(set_attr "type" "alu1")
8636 (set_attr "mode" "QI")])
8637
8638;; ??? A bug in recog prevents it from recognizing a const_int as an
8639;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8640;; for a QImode operand, which of course failed.
8641
8642(define_insn "andqi_ext_0"
8643 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8644 (const_int 8)
8645 (const_int 8))
8646 (and:SI
8647 (zero_extract:SI
8648 (match_operand 1 "ext_register_operand" "0")
8649 (const_int 8)
8650 (const_int 8))
8651 (match_operand 2 "const_int_operand" "n")))
8652 (clobber (reg:CC 17))]
8653 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8654 "and{b}\t{%2, %h0|%h0, %2}"
8655 [(set_attr "type" "alu")
8656 (set_attr "length_immediate" "1")
8657 (set_attr "mode" "QI")])
8658
8659;; Generated by peephole translating test to and. This shows up
8660;; often in fp comparisons.
8661
8662(define_insn "*andqi_ext_0_cc"
8663 [(set (reg 17)
8664 (compare
8665 (and:SI
8666 (zero_extract:SI
8667 (match_operand 1 "ext_register_operand" "0")
8668 (const_int 8)
8669 (const_int 8))
8670 (match_operand 2 "const_int_operand" "n"))
8671 (const_int 0)))
8672 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8673 (const_int 8)
8674 (const_int 8))
8675 (and:SI
8676 (zero_extract:SI
8677 (match_dup 1)
8678 (const_int 8)
8679 (const_int 8))
8680 (match_dup 2)))]
8681 "ix86_match_ccmode (insn, CCNOmode)
8682 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8683 "and{b}\t{%2, %h0|%h0, %2}"
8684 [(set_attr "type" "alu")
8685 (set_attr "length_immediate" "1")
8686 (set_attr "mode" "QI")])
8687
8688(define_insn "*andqi_ext_1"
8689 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8690 (const_int 8)
8691 (const_int 8))
8692 (and:SI
8693 (zero_extract:SI
8694 (match_operand 1 "ext_register_operand" "0")
8695 (const_int 8)
8696 (const_int 8))
8697 (zero_extend:SI
8698 (match_operand:QI 2 "general_operand" "Qm"))))
8699 (clobber (reg:CC 17))]
8700 "!TARGET_64BIT"
8701 "and{b}\t{%2, %h0|%h0, %2}"
8702 [(set_attr "type" "alu")
8703 (set_attr "length_immediate" "0")
8704 (set_attr "mode" "QI")])
8705
8706(define_insn "*andqi_ext_1_rex64"
8707 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8708 (const_int 8)
8709 (const_int 8))
8710 (and:SI
8711 (zero_extract:SI
8712 (match_operand 1 "ext_register_operand" "0")
8713 (const_int 8)
8714 (const_int 8))
8715 (zero_extend:SI
8716 (match_operand 2 "ext_register_operand" "Q"))))
8717 (clobber (reg:CC 17))]
8718 "TARGET_64BIT"
8719 "and{b}\t{%2, %h0|%h0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "length_immediate" "0")
8722 (set_attr "mode" "QI")])
8723
8724(define_insn "*andqi_ext_2"
8725 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8726 (const_int 8)
8727 (const_int 8))
8728 (and:SI
8729 (zero_extract:SI
8730 (match_operand 1 "ext_register_operand" "%0")
8731 (const_int 8)
8732 (const_int 8))
8733 (zero_extract:SI
8734 (match_operand 2 "ext_register_operand" "Q")
8735 (const_int 8)
8736 (const_int 8))))
8737 (clobber (reg:CC 17))]
8738 ""
8739 "and{b}\t{%h2, %h0|%h0, %h2}"
8740 [(set_attr "type" "alu")
8741 (set_attr "length_immediate" "0")
8742 (set_attr "mode" "QI")])
8743
8744;; Logical inclusive OR instructions
8745
8746;; %%% This used to optimize known byte-wide and operations to memory.
8747;; If this is considered useful, it should be done with splitters.
8748
8749(define_expand "iordi3"
8750 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8751 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8752 (match_operand:DI 2 "x86_64_general_operand" "")))
8753 (clobber (reg:CC 17))]
8754 "TARGET_64BIT"
8755 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8756
8757(define_insn "*iordi_1_rex64"
8758 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8759 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8760 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8761 (clobber (reg:CC 17))]
8762 "TARGET_64BIT
8763 && ix86_binary_operator_ok (IOR, DImode, operands)"
8764 "or{q}\t{%2, %0|%0, %2}"
8765 [(set_attr "type" "alu")
8766 (set_attr "mode" "DI")])
8767
8768(define_insn "*iordi_2_rex64"
8769 [(set (reg 17)
8770 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8771 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8772 (const_int 0)))
8773 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8774 (ior:DI (match_dup 1) (match_dup 2)))]
8775 "TARGET_64BIT
8776 && ix86_match_ccmode (insn, CCNOmode)
8777 && ix86_binary_operator_ok (IOR, DImode, operands)"
8778 "or{q}\t{%2, %0|%0, %2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "mode" "DI")])
8781
8782(define_insn "*iordi_3_rex64"
8783 [(set (reg 17)
8784 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8785 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8786 (const_int 0)))
8787 (clobber (match_scratch:DI 0 "=r"))]
8788 "TARGET_64BIT
8789 && ix86_match_ccmode (insn, CCNOmode)
8790 && ix86_binary_operator_ok (IOR, DImode, operands)"
8791 "or{q}\t{%2, %0|%0, %2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "mode" "DI")])
8794
8795
8796(define_expand "iorsi3"
8797 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8798 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8799 (match_operand:SI 2 "general_operand" "")))
8800 (clobber (reg:CC 17))]
8801 ""
8802 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8803
8804(define_insn "*iorsi_1"
8805 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8806 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8807 (match_operand:SI 2 "general_operand" "ri,rmi")))
8808 (clobber (reg:CC 17))]
8809 "ix86_binary_operator_ok (IOR, SImode, operands)"
8810 "or{l}\t{%2, %0|%0, %2}"
8811 [(set_attr "type" "alu")
8812 (set_attr "mode" "SI")])
8813
8814;; See comment for addsi_1_zext why we do use nonimmediate_operand
8815(define_insn "*iorsi_1_zext"
8816 [(set (match_operand:DI 0 "register_operand" "=rm")
8817 (zero_extend:DI
8818 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8819 (match_operand:SI 2 "general_operand" "rim"))))
8820 (clobber (reg:CC 17))]
8821 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8822 "or{l}\t{%2, %k0|%k0, %2}"
8823 [(set_attr "type" "alu")
8824 (set_attr "mode" "SI")])
8825
8826(define_insn "*iorsi_1_zext_imm"
8827 [(set (match_operand:DI 0 "register_operand" "=rm")
8828 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8829 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8830 (clobber (reg:CC 17))]
8831 "TARGET_64BIT"
8832 "or{l}\t{%2, %k0|%k0, %2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "mode" "SI")])
8835
8836(define_insn "*iorsi_2"
8837 [(set (reg 17)
8838 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8839 (match_operand:SI 2 "general_operand" "rim,ri"))
8840 (const_int 0)))
8841 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8842 (ior:SI (match_dup 1) (match_dup 2)))]
8843 "ix86_match_ccmode (insn, CCNOmode)
8844 && ix86_binary_operator_ok (IOR, SImode, operands)"
8845 "or{l}\t{%2, %0|%0, %2}"
8846 [(set_attr "type" "alu")
8847 (set_attr "mode" "SI")])
8848
8849;; See comment for addsi_1_zext why we do use nonimmediate_operand
8850;; ??? Special case for immediate operand is missing - it is tricky.
8851(define_insn "*iorsi_2_zext"
8852 [(set (reg 17)
8853 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8854 (match_operand:SI 2 "general_operand" "rim"))
8855 (const_int 0)))
8856 (set (match_operand:DI 0 "register_operand" "=r")
8857 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8858 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8859 && ix86_binary_operator_ok (IOR, SImode, operands)"
8860 "or{l}\t{%2, %k0|%k0, %2}"
8861 [(set_attr "type" "alu")
8862 (set_attr "mode" "SI")])
8863
8864(define_insn "*iorsi_2_zext_imm"
8865 [(set (reg 17)
8866 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8867 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8868 (const_int 0)))
8869 (set (match_operand:DI 0 "register_operand" "=r")
8870 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8871 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8872 && ix86_binary_operator_ok (IOR, SImode, operands)"
8873 "or{l}\t{%2, %k0|%k0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "mode" "SI")])
8876
8877(define_insn "*iorsi_3"
8878 [(set (reg 17)
8879 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8880 (match_operand:SI 2 "general_operand" "rim"))
8881 (const_int 0)))
8882 (clobber (match_scratch:SI 0 "=r"))]
8883 "ix86_match_ccmode (insn, CCNOmode)
8884 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8885 "or{l}\t{%2, %0|%0, %2}"
8886 [(set_attr "type" "alu")
8887 (set_attr "mode" "SI")])
8888
8889(define_expand "iorhi3"
8890 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8891 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8892 (match_operand:HI 2 "general_operand" "")))
8893 (clobber (reg:CC 17))]
8894 "TARGET_HIMODE_MATH"
8895 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8896
8897(define_insn "*iorhi_1"
8898 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8899 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8900 (match_operand:HI 2 "general_operand" "rmi,ri")))
8901 (clobber (reg:CC 17))]
8902 "ix86_binary_operator_ok (IOR, HImode, operands)"
8903 "or{w}\t{%2, %0|%0, %2}"
8904 [(set_attr "type" "alu")
8905 (set_attr "mode" "HI")])
8906
8907(define_insn "*iorhi_2"
8908 [(set (reg 17)
8909 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8910 (match_operand:HI 2 "general_operand" "rim,ri"))
8911 (const_int 0)))
8912 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8913 (ior:HI (match_dup 1) (match_dup 2)))]
8914 "ix86_match_ccmode (insn, CCNOmode)
8915 && ix86_binary_operator_ok (IOR, HImode, operands)"
8916 "or{w}\t{%2, %0|%0, %2}"
8917 [(set_attr "type" "alu")
8918 (set_attr "mode" "HI")])
8919
8920(define_insn "*iorhi_3"
8921 [(set (reg 17)
8922 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8923 (match_operand:HI 2 "general_operand" "rim"))
8924 (const_int 0)))
8925 (clobber (match_scratch:HI 0 "=r"))]
8926 "ix86_match_ccmode (insn, CCNOmode)
8927 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8928 "or{w}\t{%2, %0|%0, %2}"
8929 [(set_attr "type" "alu")
8930 (set_attr "mode" "HI")])
8931
8932(define_expand "iorqi3"
8933 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8934 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8935 (match_operand:QI 2 "general_operand" "")))
8936 (clobber (reg:CC 17))]
8937 "TARGET_QIMODE_MATH"
8938 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8939
8940;; %%% Potential partial reg stall on alternative 2. What to do?
8941(define_insn "*iorqi_1"
8942 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8943 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8944 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8945 (clobber (reg:CC 17))]
8946 "ix86_binary_operator_ok (IOR, QImode, operands)"
8947 "@
8948 or{b}\t{%2, %0|%0, %2}
8949 or{b}\t{%2, %0|%0, %2}
8950 or{l}\t{%k2, %k0|%k0, %k2}"
8951 [(set_attr "type" "alu")
8952 (set_attr "mode" "QI,QI,SI")])
8953
8954(define_insn "*iorqi_1_slp"
8955 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8956 (ior:QI (match_dup 0)
8957 (match_operand:QI 1 "general_operand" "qmi,qi")))
8958 (clobber (reg:CC 17))]
8959 ""
8960 "or{b}\t{%1, %0|%0, %1}"
8961 [(set_attr "type" "alu1")
8962 (set_attr "mode" "QI")])
8963
8964(define_insn "*iorqi_2"
8965 [(set (reg 17)
8966 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8967 (match_operand:QI 2 "general_operand" "qim,qi"))
8968 (const_int 0)))
8969 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8970 (ior:QI (match_dup 1) (match_dup 2)))]
8971 "ix86_match_ccmode (insn, CCNOmode)
8972 && ix86_binary_operator_ok (IOR, QImode, operands)"
8973 "or{b}\t{%2, %0|%0, %2}"
8974 [(set_attr "type" "alu")
8975 (set_attr "mode" "QI")])
8976
8977(define_insn "*iorqi_2_slp"
8978 [(set (reg 17)
8979 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8980 (match_operand:QI 1 "general_operand" "qim,qi"))
8981 (const_int 0)))
8982 (set (strict_low_part (match_dup 0))
8983 (ior:QI (match_dup 0) (match_dup 1)))]
8984 "ix86_match_ccmode (insn, CCNOmode)"
8985 "or{b}\t{%1, %0|%0, %1}"
8986 [(set_attr "type" "alu1")
8987 (set_attr "mode" "QI")])
8988
8989(define_insn "*iorqi_3"
8990 [(set (reg 17)
8991 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8992 (match_operand:QI 2 "general_operand" "qim"))
8993 (const_int 0)))
8994 (clobber (match_scratch:QI 0 "=q"))]
8995 "ix86_match_ccmode (insn, CCNOmode)
8996 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8997 "or{b}\t{%2, %0|%0, %2}"
8998 [(set_attr "type" "alu")
8999 (set_attr "mode" "QI")])
9000
9001
9002;; Logical XOR instructions
9003
9004;; %%% This used to optimize known byte-wide and operations to memory.
9005;; If this is considered useful, it should be done with splitters.
9006
9007(define_expand "xordi3"
9008 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9009 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9010 (match_operand:DI 2 "x86_64_general_operand" "")))
9011 (clobber (reg:CC 17))]
9012 "TARGET_64BIT"
9013 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9014
9015(define_insn "*xordi_1_rex64"
9016 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9017 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9018 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9019 (clobber (reg:CC 17))]
9020 "TARGET_64BIT
9021 && ix86_binary_operator_ok (XOR, DImode, operands)"
9022 "@
9023 xor{q}\t{%2, %0|%0, %2}
9024 xor{q}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "DI,DI")])
9027
9028(define_insn "*xordi_2_rex64"
9029 [(set (reg 17)
9030 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9031 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9032 (const_int 0)))
9033 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9034 (xor:DI (match_dup 1) (match_dup 2)))]
9035 "TARGET_64BIT
9036 && ix86_match_ccmode (insn, CCNOmode)
9037 && ix86_binary_operator_ok (XOR, DImode, operands)"
9038 "@
9039 xor{q}\t{%2, %0|%0, %2}
9040 xor{q}\t{%2, %0|%0, %2}"
9041 [(set_attr "type" "alu")
9042 (set_attr "mode" "DI,DI")])
9043
9044(define_insn "*xordi_3_rex64"
9045 [(set (reg 17)
9046 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9047 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9048 (const_int 0)))
9049 (clobber (match_scratch:DI 0 "=r"))]
9050 "TARGET_64BIT
9051 && ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_binary_operator_ok (XOR, DImode, operands)"
9053 "xor{q}\t{%2, %0|%0, %2}"
9054 [(set_attr "type" "alu")
9055 (set_attr "mode" "DI")])
9056
9057(define_expand "xorsi3"
9058 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9059 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9060 (match_operand:SI 2 "general_operand" "")))
9061 (clobber (reg:CC 17))]
9062 ""
9063 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9064
9065(define_insn "*xorsi_1"
9066 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9067 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9068 (match_operand:SI 2 "general_operand" "ri,rm")))
9069 (clobber (reg:CC 17))]
9070 "ix86_binary_operator_ok (XOR, SImode, operands)"
9071 "xor{l}\t{%2, %0|%0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "mode" "SI")])
9074
9075;; See comment for addsi_1_zext why we do use nonimmediate_operand
9076;; Add speccase for immediates
9077(define_insn "*xorsi_1_zext"
9078 [(set (match_operand:DI 0 "register_operand" "=r")
9079 (zero_extend:DI
9080 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9081 (match_operand:SI 2 "general_operand" "rim"))))
9082 (clobber (reg:CC 17))]
9083 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9084 "xor{l}\t{%2, %k0|%k0, %2}"
9085 [(set_attr "type" "alu")
9086 (set_attr "mode" "SI")])
9087
9088(define_insn "*xorsi_1_zext_imm"
9089 [(set (match_operand:DI 0 "register_operand" "=r")
9090 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9091 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9092 (clobber (reg:CC 17))]
9093 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9094 "xor{l}\t{%2, %k0|%k0, %2}"
9095 [(set_attr "type" "alu")
9096 (set_attr "mode" "SI")])
9097
9098(define_insn "*xorsi_2"
9099 [(set (reg 17)
9100 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9101 (match_operand:SI 2 "general_operand" "rim,ri"))
9102 (const_int 0)))
9103 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9104 (xor:SI (match_dup 1) (match_dup 2)))]
9105 "ix86_match_ccmode (insn, CCNOmode)
9106 && ix86_binary_operator_ok (XOR, SImode, operands)"
9107 "xor{l}\t{%2, %0|%0, %2}"
9108 [(set_attr "type" "alu")
9109 (set_attr "mode" "SI")])
9110
9111;; See comment for addsi_1_zext why we do use nonimmediate_operand
9112;; ??? Special case for immediate operand is missing - it is tricky.
9113(define_insn "*xorsi_2_zext"
9114 [(set (reg 17)
9115 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9116 (match_operand:SI 2 "general_operand" "rim"))
9117 (const_int 0)))
9118 (set (match_operand:DI 0 "register_operand" "=r")
9119 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9120 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9121 && ix86_binary_operator_ok (XOR, SImode, operands)"
9122 "xor{l}\t{%2, %k0|%k0, %2}"
9123 [(set_attr "type" "alu")
9124 (set_attr "mode" "SI")])
9125
9126(define_insn "*xorsi_2_zext_imm"
9127 [(set (reg 17)
9128 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9129 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9130 (const_int 0)))
9131 (set (match_operand:DI 0 "register_operand" "=r")
9132 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9133 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9134 && ix86_binary_operator_ok (XOR, SImode, operands)"
9135 "xor{l}\t{%2, %k0|%k0, %2}"
9136 [(set_attr "type" "alu")
9137 (set_attr "mode" "SI")])
9138
9139(define_insn "*xorsi_3"
9140 [(set (reg 17)
9141 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9142 (match_operand:SI 2 "general_operand" "rim"))
9143 (const_int 0)))
9144 (clobber (match_scratch:SI 0 "=r"))]
9145 "ix86_match_ccmode (insn, CCNOmode)
9146 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9147 "xor{l}\t{%2, %0|%0, %2}"
9148 [(set_attr "type" "alu")
9149 (set_attr "mode" "SI")])
9150
9151(define_expand "xorhi3"
9152 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9153 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9154 (match_operand:HI 2 "general_operand" "")))
9155 (clobber (reg:CC 17))]
9156 "TARGET_HIMODE_MATH"
9157 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9158
9159(define_insn "*xorhi_1"
9160 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9161 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9162 (match_operand:HI 2 "general_operand" "rmi,ri")))
9163 (clobber (reg:CC 17))]
9164 "ix86_binary_operator_ok (XOR, HImode, operands)"
9165 "xor{w}\t{%2, %0|%0, %2}"
9166 [(set_attr "type" "alu")
9167 (set_attr "mode" "HI")])
9168
9169(define_insn "*xorhi_2"
9170 [(set (reg 17)
9171 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9172 (match_operand:HI 2 "general_operand" "rim,ri"))
9173 (const_int 0)))
9174 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9175 (xor:HI (match_dup 1) (match_dup 2)))]
9176 "ix86_match_ccmode (insn, CCNOmode)
9177 && ix86_binary_operator_ok (XOR, HImode, operands)"
9178 "xor{w}\t{%2, %0|%0, %2}"
9179 [(set_attr "type" "alu")
9180 (set_attr "mode" "HI")])
9181
9182(define_insn "*xorhi_3"
9183 [(set (reg 17)
9184 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9185 (match_operand:HI 2 "general_operand" "rim"))
9186 (const_int 0)))
9187 (clobber (match_scratch:HI 0 "=r"))]
9188 "ix86_match_ccmode (insn, CCNOmode)
9189 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9190 "xor{w}\t{%2, %0|%0, %2}"
9191 [(set_attr "type" "alu")
9192 (set_attr "mode" "HI")])
9193
9194(define_expand "xorqi3"
9195 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9196 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9197 (match_operand:QI 2 "general_operand" "")))
9198 (clobber (reg:CC 17))]
9199 "TARGET_QIMODE_MATH"
9200 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9201
9202;; %%% Potential partial reg stall on alternative 2. What to do?
9203(define_insn "*xorqi_1"
9204 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9205 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9206 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9207 (clobber (reg:CC 17))]
9208 "ix86_binary_operator_ok (XOR, QImode, operands)"
9209 "@
9210 xor{b}\t{%2, %0|%0, %2}
9211 xor{b}\t{%2, %0|%0, %2}
9212 xor{l}\t{%k2, %k0|%k0, %k2}"
9213 [(set_attr "type" "alu")
9214 (set_attr "mode" "QI,QI,SI")])
9215
9216(define_insn "*xorqi_ext_1"
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 (match_operand 1 "ext_register_operand" "0")
9222 (const_int 8)
9223 (const_int 8))
9224 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9225 (const_int 8)
9226 (const_int 8))))
9227 (clobber (reg:CC 17))]
9228 ""
9229 "xor{b}\t{%h2, %h0|%h0, %h2}"
9230 [(set_attr "type" "alu")
9231 (set_attr "length_immediate" "0")
9232 (set_attr "mode" "QI")])
9233
9234(define_insn "*xorqi_cc_1"
9235 [(set (reg 17)
9236 (compare
9237 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9238 (match_operand:QI 2 "general_operand" "qim,qi"))
9239 (const_int 0)))
9240 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9241 (xor:QI (match_dup 1) (match_dup 2)))]
9242 "ix86_match_ccmode (insn, CCNOmode)
9243 && ix86_binary_operator_ok (XOR, QImode, operands)"
9244 "xor{b}\t{%2, %0|%0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "mode" "QI")])
9247
9248(define_insn "*xorqi_cc_2"
9249 [(set (reg 17)
9250 (compare
9251 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9252 (match_operand:QI 2 "general_operand" "qim"))
9253 (const_int 0)))
9254 (clobber (match_scratch:QI 0 "=q"))]
9255 "ix86_match_ccmode (insn, CCNOmode)
9256 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9257 "xor{b}\t{%2, %0|%0, %2}"
9258 [(set_attr "type" "alu")
9259 (set_attr "mode" "QI")])
9260
9261(define_insn "*xorqi_cc_ext_1"
9262 [(set (reg 17)
9263 (compare
9264 (xor:SI
9265 (zero_extract:SI
9266 (match_operand 1 "ext_register_operand" "0")
9267 (const_int 8)
9268 (const_int 8))
9269 (match_operand:QI 2 "general_operand" "qmn"))
9270 (const_int 0)))
9271 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9272 (const_int 8)
9273 (const_int 8))
9274 (xor:SI
9275 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9276 (match_dup 2)))]
9277 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9278 "xor{b}\t{%2, %h0|%h0, %2}"
9279 [(set_attr "type" "alu")
9280 (set_attr "mode" "QI")])
9281
9282(define_insn "*xorqi_cc_ext_1_rex64"
9283 [(set (reg 17)
9284 (compare
9285 (xor:SI
9286 (zero_extract:SI
9287 (match_operand 1 "ext_register_operand" "0")
9288 (const_int 8)
9289 (const_int 8))
9290 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9291 (const_int 0)))
9292 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9293 (const_int 8)
9294 (const_int 8))
9295 (xor:SI
9296 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9297 (match_dup 2)))]
9298 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9299 "xor{b}\t{%2, %h0|%h0, %2}"
9300 [(set_attr "type" "alu")
9301 (set_attr "mode" "QI")])
9302
9303(define_expand "xorqi_cc_ext_1"
9304 [(parallel [
9305 (set (reg:CCNO 17)
9306 (compare:CCNO
9307 (xor:SI
9308 (zero_extract:SI
9309 (match_operand 1 "ext_register_operand" "")
9310 (const_int 8)
9311 (const_int 8))
9312 (match_operand:QI 2 "general_operand" ""))
9313 (const_int 0)))
9314 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9315 (const_int 8)
9316 (const_int 8))
9317 (xor:SI
9318 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9319 (match_dup 2)))])]
9320 ""
9321 "")
9322
9323;; Negation instructions
9324
9325(define_expand "negdi2"
9326 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9327 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9328 (clobber (reg:CC 17))])]
9329 ""
9330 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9331
9332(define_insn "*negdi2_1"
9333 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9334 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9335 (clobber (reg:CC 17))]
9336 "!TARGET_64BIT
9337 && ix86_unary_operator_ok (NEG, DImode, operands)"
9338 "#")
9339
9340(define_split
9341 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9342 (neg:DI (match_operand:DI 1 "general_operand" "")))
9343 (clobber (reg:CC 17))]
9344 "!TARGET_64BIT && reload_completed"
9345 [(parallel
9346 [(set (reg:CCZ 17)
9347 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9348 (set (match_dup 0) (neg:SI (match_dup 2)))])
9349 (parallel
9350 [(set (match_dup 1)
9351 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9352 (match_dup 3))
9353 (const_int 0)))
9354 (clobber (reg:CC 17))])
9355 (parallel
9356 [(set (match_dup 1)
9357 (neg:SI (match_dup 1)))
9358 (clobber (reg:CC 17))])]
9359 "split_di (operands+1, 1, operands+2, operands+3);
9360 split_di (operands+0, 1, operands+0, operands+1);")
9361
9362(define_insn "*negdi2_1_rex64"
9363 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9364 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9365 (clobber (reg:CC 17))]
9366 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9367 "neg{q}\t%0"
9368 [(set_attr "type" "negnot")
9369 (set_attr "mode" "DI")])
9370
9371;; The problem with neg is that it does not perform (compare x 0),
9372;; it really performs (compare 0 x), which leaves us with the zero
9373;; flag being the only useful item.
9374
9375(define_insn "*negdi2_cmpz_rex64"
9376 [(set (reg:CCZ 17)
9377 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9378 (const_int 0)))
9379 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9380 (neg:DI (match_dup 1)))]
9381 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9382 "neg{q}\t%0"
9383 [(set_attr "type" "negnot")
9384 (set_attr "mode" "DI")])
9385
9386
9387(define_expand "negsi2"
9388 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9389 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9390 (clobber (reg:CC 17))])]
9391 ""
9392 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9393
9394(define_insn "*negsi2_1"
9395 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9396 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9397 (clobber (reg:CC 17))]
9398 "ix86_unary_operator_ok (NEG, SImode, operands)"
9399 "neg{l}\t%0"
9400 [(set_attr "type" "negnot")
9401 (set_attr "mode" "SI")])
9402
9403;; Combine is quite creative about this pattern.
9404(define_insn "*negsi2_1_zext"
9405 [(set (match_operand:DI 0 "register_operand" "=r")
9406 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9407 (const_int 32)))
9408 (const_int 32)))
9409 (clobber (reg:CC 17))]
9410 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9411 "neg{l}\t%k0"
9412 [(set_attr "type" "negnot")
9413 (set_attr "mode" "SI")])
9414
9415;; The problem with neg is that it does not perform (compare x 0),
9416;; it really performs (compare 0 x), which leaves us with the zero
9417;; flag being the only useful item.
9418
9419(define_insn "*negsi2_cmpz"
9420 [(set (reg:CCZ 17)
9421 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9422 (const_int 0)))
9423 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9424 (neg:SI (match_dup 1)))]
9425 "ix86_unary_operator_ok (NEG, SImode, operands)"
9426 "neg{l}\t%0"
9427 [(set_attr "type" "negnot")
9428 (set_attr "mode" "SI")])
9429
9430(define_insn "*negsi2_cmpz_zext"
9431 [(set (reg:CCZ 17)
9432 (compare:CCZ (lshiftrt:DI
9433 (neg:DI (ashift:DI
9434 (match_operand:DI 1 "register_operand" "0")
9435 (const_int 32)))
9436 (const_int 32))
9437 (const_int 0)))
9438 (set (match_operand:DI 0 "register_operand" "=r")
9439 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9440 (const_int 32)))
9441 (const_int 32)))]
9442 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443 "neg{l}\t%k0"
9444 [(set_attr "type" "negnot")
9445 (set_attr "mode" "SI")])
9446
9447(define_expand "neghi2"
9448 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9449 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9450 (clobber (reg:CC 17))])]
9451 "TARGET_HIMODE_MATH"
9452 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9453
9454(define_insn "*neghi2_1"
9455 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9456 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9457 (clobber (reg:CC 17))]
9458 "ix86_unary_operator_ok (NEG, HImode, operands)"
9459 "neg{w}\t%0"
9460 [(set_attr "type" "negnot")
9461 (set_attr "mode" "HI")])
9462
9463(define_insn "*neghi2_cmpz"
9464 [(set (reg:CCZ 17)
9465 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9466 (const_int 0)))
9467 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9468 (neg:HI (match_dup 1)))]
9469 "ix86_unary_operator_ok (NEG, HImode, operands)"
9470 "neg{w}\t%0"
9471 [(set_attr "type" "negnot")
9472 (set_attr "mode" "HI")])
9473
9474(define_expand "negqi2"
9475 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9476 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9477 (clobber (reg:CC 17))])]
9478 "TARGET_QIMODE_MATH"
9479 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9480
9481(define_insn "*negqi2_1"
9482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9483 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9484 (clobber (reg:CC 17))]
9485 "ix86_unary_operator_ok (NEG, QImode, operands)"
9486 "neg{b}\t%0"
9487 [(set_attr "type" "negnot")
9488 (set_attr "mode" "QI")])
9489
9490(define_insn "*negqi2_cmpz"
9491 [(set (reg:CCZ 17)
9492 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9493 (const_int 0)))
9494 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9495 (neg:QI (match_dup 1)))]
9496 "ix86_unary_operator_ok (NEG, QImode, operands)"
9497 "neg{b}\t%0"
9498 [(set_attr "type" "negnot")
9499 (set_attr "mode" "QI")])
9500
9501;; Changing of sign for FP values is doable using integer unit too.
9502
9503(define_expand "negsf2"
9504 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9505 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9506 (clobber (reg:CC 17))])]
9507 "TARGET_80387"
9508 "if (TARGET_SSE)
9509 {
9510 /* In case operand is in memory, we will not use SSE. */
9511 if (memory_operand (operands[0], VOIDmode)
9512 && rtx_equal_p (operands[0], operands[1]))
9513 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9514 else
9515 {
9516 /* Using SSE is tricky, since we need bitwise negation of -0
9517 in register. */
9518 rtx reg = gen_reg_rtx (SFmode);
9519 rtx dest = operands[0];
9520
9521 operands[1] = force_reg (SFmode, operands[1]);
9522 operands[0] = force_reg (SFmode, operands[0]);
9523 emit_move_insn (reg,
9524 gen_lowpart (SFmode,
9525 GEN_INT (trunc_int_for_mode (0x80000000,
9526 SImode))));
9527 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9528 if (dest != operands[0])
9529 emit_move_insn (dest, operands[0]);
9530 }
9531 DONE;
9532 }
9533 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9534
9535(define_insn "negsf2_memory"
9536 [(set (match_operand:SF 0 "memory_operand" "=m")
9537 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9538 (clobber (reg:CC 17))]
9539 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9540 "#")
9541
9542(define_insn "negsf2_ifs"
9543 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9544 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9545 (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
9546 (clobber (reg:CC 17))]
9547 "TARGET_SSE
9548 && (reload_in_progress || reload_completed
9549 || (register_operand (operands[0], VOIDmode)
9550 && register_operand (operands[1], VOIDmode)))"
9551 "#")
9552
9553(define_split
9554 [(set (match_operand:SF 0 "memory_operand" "")
9555 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9556 (use (match_operand:SF 2 "" ""))
9557 (clobber (reg:CC 17))]
9558 ""
9559 [(parallel [(set (match_dup 0)
9560 (neg:SF (match_dup 1)))
9561 (clobber (reg:CC 17))])])
9562
9563(define_split
9564 [(set (match_operand:SF 0 "register_operand" "")
9565 (neg:SF (match_operand:SF 1 "register_operand" "")))
9566 (use (match_operand:SF 2 "" ""))
9567 (clobber (reg:CC 17))]
9568 "reload_completed && !SSE_REG_P (operands[0])"
9569 [(parallel [(set (match_dup 0)
9570 (neg:SF (match_dup 1)))
9571 (clobber (reg:CC 17))])])
9572
9573(define_split
9574 [(set (match_operand:SF 0 "register_operand" "")
9575 (neg:SF (match_operand:SF 1 "register_operand" "")))
9576 (use (match_operand:SF 2 "register_operand" ""))
9577 (clobber (reg:CC 17))]
9578 "reload_completed && SSE_REG_P (operands[0])"
9579 [(set (subreg:TI (match_dup 0) 0)
9580 (xor:TI (subreg:TI (match_dup 1) 0)
9581 (subreg:TI (match_dup 2) 0)))]
9582{
9583 if (operands_match_p (operands[0], operands[2]))
9584 {
9585 rtx tmp;
9586 tmp = operands[1];
9587 operands[1] = operands[2];
9588 operands[2] = tmp;
9589 }
9590})
9591
9592
9593;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9594;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9595;; to itself.
9596(define_insn "*negsf2_if"
9597 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9598 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9599 (clobber (reg:CC 17))]
9600 "TARGET_80387 && !TARGET_SSE
9601 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9602 "#")
9603
9604(define_split
9605 [(set (match_operand:SF 0 "register_operand" "")
9606 (neg:SF (match_operand:SF 1 "register_operand" "")))
9607 (clobber (reg:CC 17))]
9608 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9609 [(set (match_dup 0)
9610 (neg:SF (match_dup 1)))]
9611 "")
9612
9613(define_split
9614 [(set (match_operand:SF 0 "register_operand" "")
9615 (neg:SF (match_operand:SF 1 "register_operand" "")))
9616 (clobber (reg:CC 17))]
9617 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9618 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9619 (clobber (reg:CC 17))])]
9620 "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9621 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9622
9623(define_split
9624 [(set (match_operand 0 "memory_operand" "")
9625 (neg (match_operand 1 "memory_operand" "")))
9626 (clobber (reg:CC 17))]
9627 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9628 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9629 (clobber (reg:CC 17))])]
9630{
9631 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9632
9633 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9634 if (size >= 12)
9635 size = 10;
9636 operands[0] = adjust_address (operands[0], QImode, size - 1);
9637 operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
9638})
9639
9640(define_expand "negdf2"
9641 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9642 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9643 (clobber (reg:CC 17))])]
9644 "TARGET_80387"
9645 "if (TARGET_SSE2)
9646 {
9647 /* In case operand is in memory, we will not use SSE. */
9648 if (memory_operand (operands[0], VOIDmode)
9649 && rtx_equal_p (operands[0], operands[1]))
9650 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9651 else
9652 {
9653 /* Using SSE is tricky, since we need bitwise negation of -0
9654 in register. */
9655 rtx reg = gen_reg_rtx (DFmode);
9656#if HOST_BITS_PER_WIDE_INT >= 64
9657 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9658 DImode));
9659#else
9660 rtx imm = immed_double_const (0, 0x80000000, DImode);
9661#endif
9662 rtx dest = operands[0];
9663
9664 operands[1] = force_reg (DFmode, operands[1]);
9665 operands[0] = force_reg (DFmode, operands[0]);
9666 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9667 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9668 if (dest != operands[0])
9669 emit_move_insn (dest, operands[0]);
9670 }
9671 DONE;
9672 }
9673 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9674
9675(define_insn "negdf2_memory"
9676 [(set (match_operand:DF 0 "memory_operand" "=m")
9677 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9678 (clobber (reg:CC 17))]
9679 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9680 "#")
9681
9682(define_insn "negdf2_ifs"
9683 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9684 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9685 (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
9686 (clobber (reg:CC 17))]
9687 "!TARGET_64BIT && TARGET_SSE2
9688 && (reload_in_progress || reload_completed
9689 || (register_operand (operands[0], VOIDmode)
9690 && register_operand (operands[1], VOIDmode)))"
9691 "#")
9692
9693(define_insn "*negdf2_ifs_rex64"
9694 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
9695 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9696 (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
9697 (clobber (reg:CC 17))]
9698 "TARGET_64BIT && TARGET_SSE2
9699 && (reload_in_progress || reload_completed
9700 || (register_operand (operands[0], VOIDmode)
9701 && register_operand (operands[1], VOIDmode)))"
9702 "#")
9703
9704(define_split
9705 [(set (match_operand:DF 0 "memory_operand" "")
9706 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9707 (use (match_operand:DF 2 "" ""))
9708 (clobber (reg:CC 17))]
9709 ""
9710 [(parallel [(set (match_dup 0)
9711 (neg:DF (match_dup 1)))
9712 (clobber (reg:CC 17))])])
9713
9714(define_split
9715 [(set (match_operand:DF 0 "register_operand" "")
9716 (neg:DF (match_operand:DF 1 "register_operand" "")))
9717 (use (match_operand:DF 2 "" ""))
9718 (clobber (reg:CC 17))]
9719 "reload_completed && !SSE_REG_P (operands[0])
9720 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9721 [(parallel [(set (match_dup 0)
9722 (neg:DF (match_dup 1)))
9723 (clobber (reg:CC 17))])])
9724
9725(define_split
9726 [(set (match_operand:DF 0 "register_operand" "")
9727 (neg:DF (match_operand:DF 1 "register_operand" "")))
9728 (use (match_operand:DF 2 "" ""))
9729 (clobber (reg:CC 17))]
9730 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9731 [(parallel [(set (match_dup 0)
9732 (xor:DI (match_dup 1) (match_dup 2)))
9733 (clobber (reg:CC 17))])]
9734 "operands[0] = gen_lowpart (DImode, operands[0]);
9735 operands[1] = gen_lowpart (DImode, operands[1]);
9736 operands[2] = gen_lowpart (DImode, operands[2]);")
9737
9738(define_split
9739 [(set (match_operand:DF 0 "register_operand" "")
9740 (neg:DF (match_operand:DF 1 "register_operand" "")))
9741 (use (match_operand:DF 2 "register_operand" ""))
9742 (clobber (reg:CC 17))]
9743 "reload_completed && SSE_REG_P (operands[0])"
9744 [(set (subreg:TI (match_dup 0) 0)
9745 (xor:TI (subreg:TI (match_dup 1) 0)
9746 (subreg:TI (match_dup 2) 0)))]
9747{
9748 if (operands_match_p (operands[0], operands[2]))
9749 {
9750 rtx tmp;
9751 tmp = operands[1];
9752 operands[1] = operands[2];
9753 operands[2] = tmp;
9754 }
9755})
9756
9757;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9758;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9759;; to itself.
9760(define_insn "*negdf2_if"
9761 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9762 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9763 (clobber (reg:CC 17))]
9764 "!TARGET_64BIT && TARGET_80387
9765 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9766 "#")
9767
9768;; FIXME: We should to allow integer registers here. Problem is that
9769;; we need another scratch register to get constant from.
9770;; Forcing constant to mem if no register available in peep2 should be
9771;; safe even for PIC mode, because of RIP relative addressing.
9772(define_insn "*negdf2_if_rex64"
9773 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9774 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9775 (clobber (reg:CC 17))]
9776 "TARGET_64BIT && TARGET_80387
9777 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9778 "#")
9779
9780(define_split
9781 [(set (match_operand:DF 0 "register_operand" "")
9782 (neg:DF (match_operand:DF 1 "register_operand" "")))
9783 (clobber (reg:CC 17))]
9784 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9785 [(set (match_dup 0)
9786 (neg:DF (match_dup 1)))]
9787 "")
9788
9789(define_split
9790 [(set (match_operand:DF 0 "register_operand" "")
9791 (neg:DF (match_operand:DF 1 "register_operand" "")))
9792 (clobber (reg:CC 17))]
9793 "!TARGET_64BIT && TARGET_80387 && reload_completed
9794 && !FP_REGNO_P (REGNO (operands[0]))"
9795 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9796 (clobber (reg:CC 17))])]
9797 "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9798 split_di (operands+0, 1, operands+2, operands+3);")
9799
9800(define_expand "negxf2"
9801 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9802 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9803 (clobber (reg:CC 17))])]
9804 "!TARGET_64BIT && TARGET_80387"
9805 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9806
9807(define_expand "negtf2"
9808 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9809 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9810 (clobber (reg:CC 17))])]
9811 "TARGET_80387"
9812 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9813
9814;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9815;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9816;; to itself.
9817(define_insn "*negxf2_if"
9818 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9819 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9820 (clobber (reg:CC 17))]
9821 "!TARGET_64BIT && TARGET_80387
9822 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9823 "#")
9824
9825(define_split
9826 [(set (match_operand:XF 0 "register_operand" "")
9827 (neg:XF (match_operand:XF 1 "register_operand" "")))
9828 (clobber (reg:CC 17))]
9829 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9830 [(set (match_dup 0)
9831 (neg:XF (match_dup 1)))]
9832 "")
9833
9834(define_split
9835 [(set (match_operand:XF 0 "register_operand" "")
9836 (neg:XF (match_operand:XF 1 "register_operand" "")))
9837 (clobber (reg:CC 17))]
9838 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9839 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9840 (clobber (reg:CC 17))])]
9841 "operands[1] = GEN_INT (0x8000);
9842 operands[0] = gen_rtx_REG (SImode,
9843 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9844
9845;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9846;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9847;; to itself.
9848(define_insn "*negtf2_if"
9849 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9850 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9851 (clobber (reg:CC 17))]
9852 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9853 "#")
9854
9855(define_split
9856 [(set (match_operand:TF 0 "register_operand" "")
9857 (neg:TF (match_operand:TF 1 "register_operand" "")))
9858 (clobber (reg:CC 17))]
9859 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9860 [(set (match_dup 0)
9861 (neg:TF (match_dup 1)))]
9862 "")
9863
9864(define_split
9865 [(set (match_operand:TF 0 "register_operand" "")
9866 (neg:TF (match_operand:TF 1 "register_operand" "")))
9867 (clobber (reg:CC 17))]
9868 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9869 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9870 (clobber (reg:CC 17))])]
9871 "operands[1] = GEN_INT (0x8000);
9872 operands[0] = gen_rtx_REG (SImode,
9873 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9874
9875;; Conditionize these after reload. If they matches before reload, we
9876;; lose the clobber and ability to use integer instructions.
9877
9878(define_insn "*negsf2_1"
9879 [(set (match_operand:SF 0 "register_operand" "=f")
9880 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9881 "TARGET_80387 && reload_completed"
9882 "fchs"
9883 [(set_attr "type" "fsgn")
9884 (set_attr "mode" "SF")
9885 (set_attr "ppro_uops" "few")])
9886
9887(define_insn "*negdf2_1"
9888 [(set (match_operand:DF 0 "register_operand" "=f")
9889 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9890 "TARGET_80387 && reload_completed"
9891 "fchs"
9892 [(set_attr "type" "fsgn")
9893 (set_attr "mode" "DF")
9894 (set_attr "ppro_uops" "few")])
9895
9896(define_insn "*negextendsfdf2"
9897 [(set (match_operand:DF 0 "register_operand" "=f")
9898 (neg:DF (float_extend:DF
9899 (match_operand:SF 1 "register_operand" "0"))))]
9900 "TARGET_80387"
9901 "fchs"
9902 [(set_attr "type" "fsgn")
9903 (set_attr "mode" "DF")
9904 (set_attr "ppro_uops" "few")])
9905
9906(define_insn "*negxf2_1"
9907 [(set (match_operand:XF 0 "register_operand" "=f")
9908 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9909 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9910 "fchs"
9911 [(set_attr "type" "fsgn")
9912 (set_attr "mode" "XF")
9913 (set_attr "ppro_uops" "few")])
9914
9915(define_insn "*negextenddfxf2"
9916 [(set (match_operand:XF 0 "register_operand" "=f")
9917 (neg:XF (float_extend:XF
9918 (match_operand:DF 1 "register_operand" "0"))))]
9919 "!TARGET_64BIT && TARGET_80387"
9920 "fchs"
9921 [(set_attr "type" "fsgn")
9922 (set_attr "mode" "XF")
9923 (set_attr "ppro_uops" "few")])
9924
9925(define_insn "*negextendsfxf2"
9926 [(set (match_operand:XF 0 "register_operand" "=f")
9927 (neg:XF (float_extend:XF
9928 (match_operand:SF 1 "register_operand" "0"))))]
9929 "!TARGET_64BIT && TARGET_80387"
9930 "fchs"
9931 [(set_attr "type" "fsgn")
9932 (set_attr "mode" "XF")
9933 (set_attr "ppro_uops" "few")])
9934
9935(define_insn "*negtf2_1"
9936 [(set (match_operand:TF 0 "register_operand" "=f")
9937 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9938 "TARGET_80387 && reload_completed"
9939 "fchs"
9940 [(set_attr "type" "fsgn")
9941 (set_attr "mode" "XF")
9942 (set_attr "ppro_uops" "few")])
9943
9944(define_insn "*negextenddftf2"
9945 [(set (match_operand:TF 0 "register_operand" "=f")
9946 (neg:TF (float_extend:TF
9947 (match_operand:DF 1 "register_operand" "0"))))]
9948 "TARGET_80387"
9949 "fchs"
9950 [(set_attr "type" "fsgn")
9951 (set_attr "mode" "XF")
9952 (set_attr "ppro_uops" "few")])
9953
9954(define_insn "*negextendsftf2"
9955 [(set (match_operand:TF 0 "register_operand" "=f")
9956 (neg:TF (float_extend:TF
9957 (match_operand:SF 1 "register_operand" "0"))))]
9958 "TARGET_80387"
9959 "fchs"
9960 [(set_attr "type" "fsgn")
9961 (set_attr "mode" "XF")
9962 (set_attr "ppro_uops" "few")])
9963
9964;; Absolute value instructions
9965
9966(define_expand "abssf2"
9967 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9968 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9969 (clobber (reg:CC 17))])]
9970 "TARGET_80387"
9971 "if (TARGET_SSE)
9972 {
9973 /* In case operand is in memory, we will not use SSE. */
9974 if (memory_operand (operands[0], VOIDmode)
9975 && rtx_equal_p (operands[0], operands[1]))
9976 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9977 else
9978 {
9979 /* Using SSE is tricky, since we need bitwise negation of -0
9980 in register. */
9981 rtx reg = gen_reg_rtx (SFmode);
9982 rtx dest = operands[0];
9983
9984 operands[1] = force_reg (SFmode, operands[1]);
9985 operands[0] = force_reg (SFmode, operands[0]);
9986 emit_move_insn (reg,
9987 gen_lowpart (SFmode,
9988 GEN_INT (trunc_int_for_mode (0x80000000,
9989 SImode))));
9990 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9991 if (dest != operands[0])
9992 emit_move_insn (dest, operands[0]);
9993 }
9994 DONE;
9995 }
9996 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9997
9998(define_insn "abssf2_memory"
9999 [(set (match_operand:SF 0 "memory_operand" "=m")
10000 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10001 (clobber (reg:CC 17))]
10002 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10003 "#")
10004
10005(define_insn "abssf2_ifs"
10006 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
10007 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
10008 (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
10009 (clobber (reg:CC 17))]
10010 "TARGET_SSE
10011 && (reload_in_progress || reload_completed
10012 || (register_operand (operands[0], VOIDmode)
10013 && register_operand (operands[1], VOIDmode)))"
10014 "#")
10015
10016(define_split
10017 [(set (match_operand:SF 0 "memory_operand" "")
10018 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10019 (use (match_operand:SF 2 "" ""))
10020 (clobber (reg:CC 17))]
10021 ""
10022 [(parallel [(set (match_dup 0)
10023 (abs:SF (match_dup 1)))
10024 (clobber (reg:CC 17))])])
10025
10026(define_split
10027 [(set (match_operand:SF 0 "register_operand" "")
10028 (abs:SF (match_operand:SF 1 "register_operand" "")))
10029 (use (match_operand:SF 2 "" ""))
10030 (clobber (reg:CC 17))]
10031 "reload_completed && !SSE_REG_P (operands[0])"
10032 [(parallel [(set (match_dup 0)
10033 (abs:SF (match_dup 1)))
10034 (clobber (reg:CC 17))])])
10035
10036(define_split
10037 [(set (match_operand:SF 0 "register_operand" "")
10038 (abs:SF (match_operand:SF 1 "register_operand" "")))
10039 (use (match_operand:SF 2 "register_operand" ""))
10040 (clobber (reg:CC 17))]
10041 "reload_completed && SSE_REG_P (operands[0])"
10042 [(set (subreg:TI (match_dup 0) 0)
10043 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
10044 (subreg:TI (match_dup 1) 0)))])
10045
10046;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10047;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10048;; to itself.
10049(define_insn "*abssf2_if"
10050 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10051 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10052 (clobber (reg:CC 17))]
10053 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10054 "#")
10055
10056(define_split
10057 [(set (match_operand:SF 0 "register_operand" "")
10058 (abs:SF (match_operand:SF 1 "register_operand" "")))
10059 (clobber (reg:CC 17))]
10060 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
10061 [(set (match_dup 0)
10062 (abs:SF (match_dup 1)))]
10063 "")
10064
10065(define_split
10066 [(set (match_operand:SF 0 "register_operand" "")
10067 (abs:SF (match_operand:SF 1 "register_operand" "")))
10068 (clobber (reg:CC 17))]
10069 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10070 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10071 (clobber (reg:CC 17))])]
10072 "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
10073 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
10074
10075(define_split
10076 [(set (match_operand 0 "memory_operand" "")
10077 (abs (match_operand 1 "memory_operand" "")))
10078 (clobber (reg:CC 17))]
10079 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10080 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10081 (clobber (reg:CC 17))])]
10082{
10083 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10084
10085 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10086 if (size >= 12)
10087 size = 10;
10088 operands[0] = adjust_address (operands[0], QImode, size - 1);
10089 operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
10090})
10091
10092(define_expand "absdf2"
10093 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10094 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10095 (clobber (reg:CC 17))])]
10096 "TARGET_80387"
10097 "if (TARGET_SSE2)
10098 {
10099 /* In case operand is in memory, we will not use SSE. */
10100 if (memory_operand (operands[0], VOIDmode)
10101 && rtx_equal_p (operands[0], operands[1]))
10102 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10103 else
10104 {
10105 /* Using SSE is tricky, since we need bitwise negation of -0
10106 in register. */
10107 rtx reg = gen_reg_rtx (DFmode);
10108#if HOST_BITS_PER_WIDE_INT >= 64
10109 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
10110 DImode));
10111#else
10112 rtx imm = immed_double_const (0, 0x80000000, DImode);
10113#endif
10114 rtx dest = operands[0];
10115
10116 operands[1] = force_reg (DFmode, operands[1]);
10117 operands[0] = force_reg (DFmode, operands[0]);
10118 emit_move_insn (reg, gen_lowpart (DFmode, imm));
10119 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10120 if (dest != operands[0])
10121 emit_move_insn (dest, operands[0]);
10122 }
10123 DONE;
10124 }
10125 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10126
10127(define_insn "absdf2_memory"
10128 [(set (match_operand:DF 0 "memory_operand" "=m")
10129 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10130 (clobber (reg:CC 17))]
10131 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10132 "#")
10133
10134(define_insn "absdf2_ifs"
10135 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
10136 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
10137 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
10138 (clobber (reg:CC 17))]
10139 "!TARGET_64BIT && TARGET_SSE2
10140 && (reload_in_progress || reload_completed
10141 || (register_operand (operands[0], VOIDmode)
10142 && register_operand (operands[1], VOIDmode)))"
10143 "#")
10144
10145(define_insn "*absdf2_ifs_rex64"
10146 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
10147 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
10148 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
10149 (clobber (reg:CC 17))]
10150 "TARGET_64BIT && TARGET_SSE2
10151 && (reload_in_progress || reload_completed
10152 || (register_operand (operands[0], VOIDmode)
10153 && register_operand (operands[1], VOIDmode)))"
10154 "#")
10155
10156(define_split
10157 [(set (match_operand:DF 0 "memory_operand" "")
10158 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10159 (use (match_operand:DF 2 "" ""))
10160 (clobber (reg:CC 17))]
10161 ""
10162 [(parallel [(set (match_dup 0)
10163 (abs:DF (match_dup 1)))
10164 (clobber (reg:CC 17))])])
10165
10166(define_split
10167 [(set (match_operand:DF 0 "register_operand" "")
10168 (abs:DF (match_operand:DF 1 "register_operand" "")))
10169 (use (match_operand:DF 2 "" ""))
10170 (clobber (reg:CC 17))]
10171 "reload_completed && !SSE_REG_P (operands[0])"
10172 [(parallel [(set (match_dup 0)
10173 (abs:DF (match_dup 1)))
10174 (clobber (reg:CC 17))])])
10175
10176(define_split
10177 [(set (match_operand:DF 0 "register_operand" "")
10178 (abs:DF (match_operand:DF 1 "register_operand" "")))
10179 (use (match_operand:DF 2 "register_operand" ""))
10180 (clobber (reg:CC 17))]
10181 "reload_completed && SSE_REG_P (operands[0])"
10182 [(set (subreg:TI (match_dup 0) 0)
10183 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
10184 (subreg:TI (match_dup 1) 0)))])
10185
10186
10187;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10188;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10189;; to itself.
10190(define_insn "*absdf2_if"
10191 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10192 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10193 (clobber (reg:CC 17))]
10194 "!TARGET_64BIT && TARGET_80387
10195 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10196 "#")
10197
10198;; FIXME: We should to allow integer registers here. Problem is that
10199;; we need another scratch register to get constant from.
10200;; Forcing constant to mem if no register available in peep2 should be
10201;; safe even for PIC mode, because of RIP relative addressing.
10202(define_insn "*absdf2_if_rex64"
10203 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10204 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10205 (clobber (reg:CC 17))]
10206 "TARGET_64BIT && TARGET_80387
10207 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10208 "#")
10209
10210(define_split
10211 [(set (match_operand:DF 0 "register_operand" "")
10212 (abs:DF (match_operand:DF 1 "register_operand" "")))
10213 (clobber (reg:CC 17))]
10214 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10215 [(set (match_dup 0)
10216 (abs:DF (match_dup 1)))]
10217 "")
10218
10219(define_split
10220 [(set (match_operand:DF 0 "register_operand" "")
10221 (abs:DF (match_operand:DF 1 "register_operand" "")))
10222 (clobber (reg:CC 17))]
10223 "!TARGET_64BIT && TARGET_80387 && reload_completed &&
10224 !FP_REGNO_P (REGNO (operands[0]))"
10225 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10226 (clobber (reg:CC 17))])]
10227 "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
10228 split_di (operands+0, 1, operands+2, operands+3);")
10229
10230(define_expand "absxf2"
10231 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10232 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10233 (clobber (reg:CC 17))])]
10234 "!TARGET_64BIT && TARGET_80387"
10235 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10236
10237(define_expand "abstf2"
10238 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10239 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10240 (clobber (reg:CC 17))])]
10241 "TARGET_80387"
10242 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10243
10244;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10245;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10246;; to itself.
10247(define_insn "*absxf2_if"
10248 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10249 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10250 (clobber (reg:CC 17))]
10251 "!TARGET_64BIT && TARGET_80387
10252 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10253 "#")
10254
10255(define_split
10256 [(set (match_operand:XF 0 "register_operand" "")
10257 (abs:XF (match_operand:XF 1 "register_operand" "")))
10258 (clobber (reg:CC 17))]
10259 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10260 [(set (match_dup 0)
10261 (abs:XF (match_dup 1)))]
10262 "")
10263
10264(define_split
10265 [(set (match_operand:XF 0 "register_operand" "")
10266 (abs:XF (match_operand:XF 1 "register_operand" "")))
10267 (clobber (reg:CC 17))]
10268 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10269 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10270 (clobber (reg:CC 17))])]
10271 "operands[1] = GEN_INT (~0x8000);
10272 operands[0] = gen_rtx_REG (SImode,
10273 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10274
10275(define_insn "*abstf2_if"
10276 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10277 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10278 (clobber (reg:CC 17))]
10279 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10280 "#")
10281
10282(define_split
10283 [(set (match_operand:TF 0 "register_operand" "")
10284 (abs:TF (match_operand:TF 1 "register_operand" "")))
10285 (clobber (reg:CC 17))]
10286 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10287 [(set (match_dup 0)
10288 (abs:TF (match_dup 1)))]
10289 "")
10290
10291(define_split
10292 [(set (match_operand:TF 0 "register_operand" "")
10293 (abs:TF (match_operand:TF 1 "register_operand" "")))
10294 (clobber (reg:CC 17))]
10295 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10296 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10297 (clobber (reg:CC 17))])]
10298 "operands[1] = GEN_INT (~0x8000);
10299 operands[0] = gen_rtx_REG (SImode,
10300 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10301
10302(define_insn "*abssf2_1"
10303 [(set (match_operand:SF 0 "register_operand" "=f")
10304 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10305 "TARGET_80387 && reload_completed"
10306 "fabs"
10307 [(set_attr "type" "fsgn")
10308 (set_attr "mode" "SF")])
10309
10310(define_insn "*absdf2_1"
10311 [(set (match_operand:DF 0 "register_operand" "=f")
10312 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10313 "TARGET_80387 && reload_completed"
10314 "fabs"
10315 [(set_attr "type" "fsgn")
10316 (set_attr "mode" "DF")])
10317
10318(define_insn "*absextendsfdf2"
10319 [(set (match_operand:DF 0 "register_operand" "=f")
10320 (abs:DF (float_extend:DF
10321 (match_operand:SF 1 "register_operand" "0"))))]
10322 "TARGET_80387"
10323 "fabs"
10324 [(set_attr "type" "fsgn")
10325 (set_attr "mode" "DF")])
10326
10327(define_insn "*absxf2_1"
10328 [(set (match_operand:XF 0 "register_operand" "=f")
10329 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10330 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10331 "fabs"
10332 [(set_attr "type" "fsgn")
10333 (set_attr "mode" "DF")])
10334
10335(define_insn "*absextenddfxf2"
10336 [(set (match_operand:XF 0 "register_operand" "=f")
10337 (abs:XF (float_extend:XF
10338 (match_operand:DF 1 "register_operand" "0"))))]
10339 "!TARGET_64BIT && TARGET_80387"
10340 "fabs"
10341 [(set_attr "type" "fsgn")
10342 (set_attr "mode" "XF")])
10343
10344(define_insn "*absextendsfxf2"
10345 [(set (match_operand:XF 0 "register_operand" "=f")
10346 (abs:XF (float_extend:XF
10347 (match_operand:SF 1 "register_operand" "0"))))]
10348 "!TARGET_64BIT && TARGET_80387"
10349 "fabs"
10350 [(set_attr "type" "fsgn")
10351 (set_attr "mode" "XF")])
10352
10353(define_insn "*abstf2_1"
10354 [(set (match_operand:TF 0 "register_operand" "=f")
10355 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10356 "TARGET_80387 && reload_completed"
10357 "fabs"
10358 [(set_attr "type" "fsgn")
10359 (set_attr "mode" "DF")])
10360
10361(define_insn "*absextenddftf2"
10362 [(set (match_operand:TF 0 "register_operand" "=f")
10363 (abs:TF (float_extend:TF
10364 (match_operand:DF 1 "register_operand" "0"))))]
10365 "TARGET_80387"
10366 "fabs"
10367 [(set_attr "type" "fsgn")
10368 (set_attr "mode" "XF")])
10369
10370(define_insn "*absextendsftf2"
10371 [(set (match_operand:TF 0 "register_operand" "=f")
10372 (abs:TF (float_extend:TF
10373 (match_operand:SF 1 "register_operand" "0"))))]
10374 "TARGET_80387"
10375 "fabs"
10376 [(set_attr "type" "fsgn")
10377 (set_attr "mode" "XF")])
10378
10379;; One complement instructions
10380
10381(define_expand "one_cmpldi2"
10382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10384 "TARGET_64BIT"
10385 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10386
10387(define_insn "*one_cmpldi2_1_rex64"
10388 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10389 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10390 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10391 "not{q}\t%0"
10392 [(set_attr "type" "negnot")
10393 (set_attr "mode" "DI")])
10394
10395(define_insn "*one_cmpldi2_2_rex64"
10396 [(set (reg 17)
10397 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10398 (const_int 0)))
10399 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10400 (not:DI (match_dup 1)))]
10401 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10402 && ix86_unary_operator_ok (NOT, DImode, operands)"
10403 "#"
10404 [(set_attr "type" "alu1")
10405 (set_attr "mode" "DI")])
10406
10407(define_split
10408 [(set (reg 17)
10409 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10410 (const_int 0)))
10411 (set (match_operand:DI 0 "nonimmediate_operand" "")
10412 (not:DI (match_dup 1)))]
10413 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10414 [(parallel [(set (reg:CCNO 17)
10415 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10416 (const_int 0)))
10417 (set (match_dup 0)
10418 (xor:DI (match_dup 1) (const_int -1)))])]
10419 "")
10420
10421(define_expand "one_cmplsi2"
10422 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10423 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10424 ""
10425 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10426
10427(define_insn "*one_cmplsi2_1"
10428 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10429 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10430 "ix86_unary_operator_ok (NOT, SImode, operands)"
10431 "not{l}\t%0"
10432 [(set_attr "type" "negnot")
10433 (set_attr "mode" "SI")])
10434
10435;; ??? Currently never generated - xor is used instead.
10436(define_insn "*one_cmplsi2_1_zext"
10437 [(set (match_operand:DI 0 "register_operand" "=r")
10438 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10439 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10440 "not{l}\t%k0"
10441 [(set_attr "type" "negnot")
10442 (set_attr "mode" "SI")])
10443
10444(define_insn "*one_cmplsi2_2"
10445 [(set (reg 17)
10446 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10447 (const_int 0)))
10448 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10449 (not:SI (match_dup 1)))]
10450 "ix86_match_ccmode (insn, CCNOmode)
10451 && ix86_unary_operator_ok (NOT, SImode, operands)"
10452 "#"
10453 [(set_attr "type" "alu1")
10454 (set_attr "mode" "SI")])
10455
10456(define_split
10457 [(set (reg 17)
10458 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10459 (const_int 0)))
10460 (set (match_operand:SI 0 "nonimmediate_operand" "")
10461 (not:SI (match_dup 1)))]
10462 "ix86_match_ccmode (insn, CCNOmode)"
10463 [(parallel [(set (reg:CCNO 17)
10464 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10465 (const_int 0)))
10466 (set (match_dup 0)
10467 (xor:SI (match_dup 1) (const_int -1)))])]
10468 "")
10469
10470;; ??? Currently never generated - xor is used instead.
10471(define_insn "*one_cmplsi2_2_zext"
10472 [(set (reg 17)
10473 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10474 (const_int 0)))
10475 (set (match_operand:DI 0 "register_operand" "=r")
10476 (zero_extend:DI (not:SI (match_dup 1))))]
10477 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10478 && ix86_unary_operator_ok (NOT, SImode, operands)"
10479 "#"
10480 [(set_attr "type" "alu1")
10481 (set_attr "mode" "SI")])
10482
10483(define_split
10484 [(set (reg 17)
10485 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10486 (const_int 0)))
10487 (set (match_operand:DI 0 "register_operand" "")
10488 (zero_extend:DI (not:SI (match_dup 1))))]
10489 "ix86_match_ccmode (insn, CCNOmode)"
10490 [(parallel [(set (reg:CCNO 17)
10491 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10492 (const_int 0)))
10493 (set (match_dup 0)
10494 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10495 "")
10496
10497(define_expand "one_cmplhi2"
10498 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10499 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10500 "TARGET_HIMODE_MATH"
10501 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10502
10503(define_insn "*one_cmplhi2_1"
10504 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10505 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10506 "ix86_unary_operator_ok (NOT, HImode, operands)"
10507 "not{w}\t%0"
10508 [(set_attr "type" "negnot")
10509 (set_attr "mode" "HI")])
10510
10511(define_insn "*one_cmplhi2_2"
10512 [(set (reg 17)
10513 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10514 (const_int 0)))
10515 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10516 (not:HI (match_dup 1)))]
10517 "ix86_match_ccmode (insn, CCNOmode)
10518 && ix86_unary_operator_ok (NEG, HImode, operands)"
10519 "#"
10520 [(set_attr "type" "alu1")
10521 (set_attr "mode" "HI")])
10522
10523(define_split
10524 [(set (reg 17)
10525 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10526 (const_int 0)))
10527 (set (match_operand:HI 0 "nonimmediate_operand" "")
10528 (not:HI (match_dup 1)))]
10529 "ix86_match_ccmode (insn, CCNOmode)"
10530 [(parallel [(set (reg:CCNO 17)
10531 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10532 (const_int 0)))
10533 (set (match_dup 0)
10534 (xor:HI (match_dup 1) (const_int -1)))])]
10535 "")
10536
10537;; %%% Potential partial reg stall on alternative 1. What to do?
10538(define_expand "one_cmplqi2"
10539 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10540 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10541 "TARGET_QIMODE_MATH"
10542 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10543
10544(define_insn "*one_cmplqi2_1"
10545 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10546 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10547 "ix86_unary_operator_ok (NOT, QImode, operands)"
10548 "@
10549 not{b}\t%0
10550 not{l}\t%k0"
10551 [(set_attr "type" "negnot")
10552 (set_attr "mode" "QI,SI")])
10553
10554(define_insn "*one_cmplqi2_2"
10555 [(set (reg 17)
10556 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10557 (const_int 0)))
10558 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10559 (not:QI (match_dup 1)))]
10560 "ix86_match_ccmode (insn, CCNOmode)
10561 && ix86_unary_operator_ok (NOT, QImode, operands)"
10562 "#"
10563 [(set_attr "type" "alu1")
10564 (set_attr "mode" "QI")])
10565
10566(define_split
10567 [(set (reg 17)
10568 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10569 (const_int 0)))
10570 (set (match_operand:QI 0 "nonimmediate_operand" "")
10571 (not:QI (match_dup 1)))]
10572 "ix86_match_ccmode (insn, CCNOmode)"
10573 [(parallel [(set (reg:CCNO 17)
10574 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10575 (const_int 0)))
10576 (set (match_dup 0)
10577 (xor:QI (match_dup 1) (const_int -1)))])]
10578 "")
10579
10580;; Arithmetic shift instructions
10581
10582;; DImode shifts are implemented using the i386 "shift double" opcode,
10583;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10584;; is variable, then the count is in %cl and the "imm" operand is dropped
10585;; from the assembler input.
10586;;
10587;; This instruction shifts the target reg/mem as usual, but instead of
10588;; shifting in zeros, bits are shifted in from reg operand. If the insn
10589;; is a left shift double, bits are taken from the high order bits of
10590;; reg, else if the insn is a shift right double, bits are taken from the
10591;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10592;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10593;;
10594;; Since sh[lr]d does not change the `reg' operand, that is done
10595;; separately, making all shifts emit pairs of shift double and normal
10596;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10597;; support a 63 bit shift, each shift where the count is in a reg expands
10598;; to a pair of shifts, a branch, a shift by 32 and a label.
10599;;
10600;; If the shift count is a constant, we need never emit more than one
10601;; shift pair, instead using moves and sign extension for counts greater
10602;; than 31.
10603
10604(define_expand "ashldi3"
10605 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10606 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10607 (match_operand:QI 2 "nonmemory_operand" "")))
10608 (clobber (reg:CC 17))])]
10609 ""
10610{
10611 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10612 {
10613 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10614 DONE;
10615 }
10616 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10617 DONE;
10618})
10619
10620(define_insn "*ashldi3_1_rex64"
10621 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10622 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10623 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10624 (clobber (reg:CC 17))]
10625 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10626{
10627 switch (get_attr_type (insn))
10628 {
10629 case TYPE_ALU:
10630 if (operands[2] != const1_rtx)
10631 abort ();
10632 if (!rtx_equal_p (operands[0], operands[1]))
10633 abort ();
10634 return "add{q}\t{%0, %0|%0, %0}";
10635
10636 case TYPE_LEA:
10637 if (GET_CODE (operands[2]) != CONST_INT
10638 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10639 abort ();
10640 operands[1] = gen_rtx_MULT (DImode, operands[1],
10641 GEN_INT (1 << INTVAL (operands[2])));
10642 return "lea{q}\t{%a1, %0|%0, %a1}";
10643
10644 default:
10645 if (REG_P (operands[2]))
10646 return "sal{q}\t{%b2, %0|%0, %b2}";
10647 else if (GET_CODE (operands[2]) == CONST_INT
10648 && INTVAL (operands[2]) == 1
10649 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10650 return "sal{q}\t%0";
10651 else
10652 return "sal{q}\t{%2, %0|%0, %2}";
10653 }
10654}
10655 [(set (attr "type")
10656 (cond [(eq_attr "alternative" "1")
10657 (const_string "lea")
10658 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10659 (const_int 0))
10660 (match_operand 0 "register_operand" ""))
10661 (match_operand 2 "const1_operand" ""))
10662 (const_string "alu")
10663 ]
10664 (const_string "ishift")))
10665 (set_attr "mode" "DI")])
10666
10667;; Convert lea to the lea pattern to avoid flags dependency.
10668(define_split
10669 [(set (match_operand:DI 0 "register_operand" "")
10670 (ashift:DI (match_operand:DI 1 "register_operand" "")
10671 (match_operand:QI 2 "immediate_operand" "")))
10672 (clobber (reg:CC 17))]
10673 "TARGET_64BIT && reload_completed
10674 && true_regnum (operands[0]) != true_regnum (operands[1])"
10675 [(set (match_dup 0)
10676 (mult:DI (match_dup 1)
10677 (match_dup 2)))]
10678 "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10679 DImode));")
10680
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.
10684(define_insn "*ashldi3_cmp_rex64"
10685 [(set (reg 17)
10686 (compare
10687 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10688 (match_operand:QI 2 "immediate_operand" "e"))
10689 (const_int 0)))
10690 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10691 (ashift:DI (match_dup 1) (match_dup 2)))]
10692 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10693 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10694{
10695 switch (get_attr_type (insn))
10696 {
10697 case TYPE_ALU:
10698 if (operands[2] != const1_rtx)
10699 abort ();
10700 return "add{q}\t{%0, %0|%0, %0}";
10701
10702 default:
10703 if (REG_P (operands[2]))
10704 return "sal{q}\t{%b2, %0|%0, %b2}";
10705 else if (GET_CODE (operands[2]) == CONST_INT
10706 && INTVAL (operands[2]) == 1
10707 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10708 return "sal{q}\t%0";
10709 else
10710 return "sal{q}\t{%2, %0|%0, %2}";
10711 }
10712}
10713 [(set (attr "type")
10714 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10715 (const_int 0))
10716 (match_operand 0 "register_operand" ""))
10717 (match_operand 2 "const1_operand" ""))
10718 (const_string "alu")
10719 ]
10720 (const_string "ishift")))
10721 (set_attr "mode" "DI")])
10722
10723(define_insn "ashldi3_1"
10724 [(set (match_operand:DI 0 "register_operand" "=r")
10725 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10726 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10727 (clobber (match_scratch:SI 3 "=&r"))
10728 (clobber (reg:CC 17))]
10729 "!TARGET_64BIT && TARGET_CMOVE"
10730 "#"
10731 [(set_attr "type" "multi")])
10732
10733(define_insn "*ashldi3_2"
10734 [(set (match_operand:DI 0 "register_operand" "=r")
10735 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10736 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10737 (clobber (reg:CC 17))]
10738 "!TARGET_64BIT"
10739 "#"
10740 [(set_attr "type" "multi")])
10741
10742(define_split
10743 [(set (match_operand:DI 0 "register_operand" "")
10744 (ashift:DI (match_operand:DI 1 "register_operand" "")
10745 (match_operand:QI 2 "nonmemory_operand" "")))
10746 (clobber (match_scratch:SI 3 ""))
10747 (clobber (reg:CC 17))]
10748 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10749 [(const_int 0)]
10750 "ix86_split_ashldi (operands, operands[3]); DONE;")
10751
10752(define_split
10753 [(set (match_operand:DI 0 "register_operand" "")
10754 (ashift:DI (match_operand:DI 1 "register_operand" "")
10755 (match_operand:QI 2 "nonmemory_operand" "")))
10756 (clobber (reg:CC 17))]
10757 "!TARGET_64BIT && reload_completed"
10758 [(const_int 0)]
10759 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10760
10761(define_insn "x86_shld_1"
10762 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10763 (ior:SI (ashift:SI (match_dup 0)
10764 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10765 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10766 (minus:QI (const_int 32) (match_dup 2)))))
10767 (clobber (reg:CC 17))]
10768 ""
10769 "@
10770 shld{l}\t{%2, %1, %0|%0, %1, %2}
10771 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10772 [(set_attr "type" "ishift")
10773 (set_attr "prefix_0f" "1")
10774 (set_attr "mode" "SI")
10775 (set_attr "pent_pair" "np")
10776 (set_attr "athlon_decode" "vector")
10777 (set_attr "ppro_uops" "few")])
10778
10779(define_expand "x86_shift_adj_1"
10780 [(set (reg:CCZ 17)
10781 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10782 (const_int 32))
10783 (const_int 0)))
10784 (set (match_operand:SI 0 "register_operand" "")
10785 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10786 (match_operand:SI 1 "register_operand" "")
10787 (match_dup 0)))
10788 (set (match_dup 1)
10789 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10790 (match_operand:SI 3 "register_operand" "r")
10791 (match_dup 1)))]
10792 "TARGET_CMOVE"
10793 "")
10794
10795(define_expand "x86_shift_adj_2"
10796 [(use (match_operand:SI 0 "register_operand" ""))
10797 (use (match_operand:SI 1 "register_operand" ""))
10798 (use (match_operand:QI 2 "register_operand" ""))]
10799 ""
10800{
10801 rtx label = gen_label_rtx ();
10802 rtx tmp;
10803
10804 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10805
10806 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10807 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10808 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10809 gen_rtx_LABEL_REF (VOIDmode, label),
10810 pc_rtx);
10811 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10812 JUMP_LABEL (tmp) = label;
10813
10814 emit_move_insn (operands[0], operands[1]);
10815 emit_move_insn (operands[1], const0_rtx);
10816
10817 emit_label (label);
10818 LABEL_NUSES (label) = 1;
10819
10820 DONE;
10821})
10822
10823(define_expand "ashlsi3"
10824 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10825 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10826 (match_operand:QI 2 "nonmemory_operand" "")))
10827 (clobber (reg:CC 17))]
10828 ""
10829 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10830
10831(define_insn "*ashlsi3_1"
10832 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10833 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10834 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10835 (clobber (reg:CC 17))]
10836 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10837{
10838 switch (get_attr_type (insn))
10839 {
10840 case TYPE_ALU:
10841 if (operands[2] != const1_rtx)
10842 abort ();
10843 if (!rtx_equal_p (operands[0], operands[1]))
10844 abort ();
10845 return "add{l}\t{%0, %0|%0, %0}";
10846
10847 case TYPE_LEA:
10848 return "#";
10849
10850 default:
10851 if (REG_P (operands[2]))
10852 return "sal{l}\t{%b2, %0|%0, %b2}";
10853 else if (GET_CODE (operands[2]) == CONST_INT
10854 && INTVAL (operands[2]) == 1
10855 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10856 return "sal{l}\t%0";
10857 else
10858 return "sal{l}\t{%2, %0|%0, %2}";
10859 }
10860}
10861 [(set (attr "type")
10862 (cond [(eq_attr "alternative" "1")
10863 (const_string "lea")
10864 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10865 (const_int 0))
10866 (match_operand 0 "register_operand" ""))
10867 (match_operand 2 "const1_operand" ""))
10868 (const_string "alu")
10869 ]
10870 (const_string "ishift")))
10871 (set_attr "mode" "SI")])
10872
10873;; Convert lea to the lea pattern to avoid flags dependency.
10874(define_split
10875 [(set (match_operand 0 "register_operand" "")
10876 (ashift (match_operand 1 "register_operand" "")
10877 (match_operand:QI 2 "const_int_operand" "")))
10878 (clobber (reg:CC 17))]
10879 "reload_completed
10880 && true_regnum (operands[0]) != true_regnum (operands[1])"
10881 [(const_int 0)]
10882{
10883 rtx pat;
10884 operands[0] = gen_lowpart (SImode, operands[0]);
10885 operands[1] = gen_lowpart (Pmode, operands[1]);
10886 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10887 Pmode));
10888 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10889 if (Pmode != SImode)
10890 pat = gen_rtx_SUBREG (SImode, pat, 0);
10891 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10892 DONE;
10893})
10894
10895(define_insn "*ashlsi3_1_zext"
10896 [(set (match_operand:DI 0 "register_operand" "=r,r")
10897 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10898 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10899 (clobber (reg:CC 17))]
10900 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10901{
10902 switch (get_attr_type (insn))
10903 {
10904 case TYPE_ALU:
10905 if (operands[2] != const1_rtx)
10906 abort ();
10907 return "add{l}\t{%k0, %k0|%k0, %k0}";
10908
10909 case TYPE_LEA:
10910 return "#";
10911
10912 default:
10913 if (REG_P (operands[2]))
10914 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10915 else if (GET_CODE (operands[2]) == CONST_INT
10916 && INTVAL (operands[2]) == 1
10917 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10918 return "sal{l}\t%k0";
10919 else
10920 return "sal{l}\t{%2, %k0|%k0, %2}";
10921 }
10922}
10923 [(set (attr "type")
10924 (cond [(eq_attr "alternative" "1")
10925 (const_string "lea")
10926 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10927 (const_int 0))
10928 (match_operand 2 "const1_operand" ""))
10929 (const_string "alu")
10930 ]
10931 (const_string "ishift")))
10932 (set_attr "mode" "SI")])
10933
10934;; Convert lea to the lea pattern to avoid flags dependency.
10935(define_split
10936 [(set (match_operand:DI 0 "register_operand" "")
10937 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10938 (match_operand:QI 2 "const_int_operand" ""))))
10939 (clobber (reg:CC 17))]
10940 "reload_completed
10941 && true_regnum (operands[0]) != true_regnum (operands[1])"
10942 [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10943{
10944 operands[1] = gen_lowpart (Pmode, operands[1]);
10945 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10946 Pmode));
10947})
10948
10949;; This pattern can't accept a variable shift count, since shifts by
10950;; zero don't affect the flags. We assume that shifts by constant
10951;; zero are optimized away.
10952(define_insn "*ashlsi3_cmp"
10953 [(set (reg 17)
10954 (compare
10955 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10956 (match_operand:QI 2 "immediate_operand" "I"))
10957 (const_int 0)))
10958 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10959 (ashift:SI (match_dup 1) (match_dup 2)))]
10960 "ix86_match_ccmode (insn, CCGOCmode)
10961 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10962{
10963 switch (get_attr_type (insn))
10964 {
10965 case TYPE_ALU:
10966 if (operands[2] != const1_rtx)
10967 abort ();
10968 return "add{l}\t{%0, %0|%0, %0}";
10969
10970 default:
10971 if (REG_P (operands[2]))
10972 return "sal{l}\t{%b2, %0|%0, %b2}";
10973 else if (GET_CODE (operands[2]) == CONST_INT
10974 && INTVAL (operands[2]) == 1
10975 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10976 return "sal{l}\t%0";
10977 else
10978 return "sal{l}\t{%2, %0|%0, %2}";
10979 }
10980}
10981 [(set (attr "type")
10982 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10983 (const_int 0))
10984 (match_operand 0 "register_operand" ""))
10985 (match_operand 2 "const1_operand" ""))
10986 (const_string "alu")
10987 ]
10988 (const_string "ishift")))
10989 (set_attr "mode" "SI")])
10990
10991(define_insn "*ashlsi3_cmp_zext"
10992 [(set (reg 17)
10993 (compare
10994 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10995 (match_operand:QI 2 "immediate_operand" "I"))
10996 (const_int 0)))
10997 (set (match_operand:DI 0 "register_operand" "=r")
10998 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10999 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11000 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11001{
11002 switch (get_attr_type (insn))
11003 {
11004 case TYPE_ALU:
11005 if (operands[2] != const1_rtx)
11006 abort ();
11007 return "add{l}\t{%k0, %k0|%k0, %k0}";
11008
11009 default:
11010 if (REG_P (operands[2]))
11011 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11012 else if (GET_CODE (operands[2]) == CONST_INT
11013 && INTVAL (operands[2]) == 1
11014 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11015 return "sal{l}\t%k0";
11016 else
11017 return "sal{l}\t{%2, %k0|%k0, %2}";
11018 }
11019}
11020 [(set (attr "type")
11021 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11022 (const_int 0))
11023 (match_operand 2 "const1_operand" ""))
11024 (const_string "alu")
11025 ]
11026 (const_string "ishift")))
11027 (set_attr "mode" "SI")])
11028
11029(define_expand "ashlhi3"
11030 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11031 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11032 (match_operand:QI 2 "nonmemory_operand" "")))
11033 (clobber (reg:CC 17))]
11034 "TARGET_HIMODE_MATH"
11035 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11036
11037(define_insn "*ashlhi3_1_lea"
11038 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11039 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11040 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11041 (clobber (reg:CC 17))]
11042 "!TARGET_PARTIAL_REG_STALL
11043 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11044{
11045 switch (get_attr_type (insn))
11046 {
11047 case TYPE_LEA:
11048 return "#";
11049 case TYPE_ALU:
11050 if (operands[2] != const1_rtx)
11051 abort ();
11052 return "add{w}\t{%0, %0|%0, %0}";
11053
11054 default:
11055 if (REG_P (operands[2]))
11056 return "sal{w}\t{%b2, %0|%0, %b2}";
11057 else if (GET_CODE (operands[2]) == CONST_INT
11058 && INTVAL (operands[2]) == 1
11059 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11060 return "sal{w}\t%0";
11061 else
11062 return "sal{w}\t{%2, %0|%0, %2}";
11063 }
11064}
11065 [(set (attr "type")
11066 (cond [(eq_attr "alternative" "1")
11067 (const_string "lea")
11068 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11069 (const_int 0))
11070 (match_operand 0 "register_operand" ""))
11071 (match_operand 2 "const1_operand" ""))
11072 (const_string "alu")
11073 ]
11074 (const_string "ishift")))
11075 (set_attr "mode" "HI,SI")])
11076
11077(define_insn "*ashlhi3_1"
11078 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11079 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11080 (match_operand:QI 2 "nonmemory_operand" "cI")))
11081 (clobber (reg:CC 17))]
11082 "TARGET_PARTIAL_REG_STALL
11083 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11084{
11085 switch (get_attr_type (insn))
11086 {
11087 case TYPE_ALU:
11088 if (operands[2] != const1_rtx)
11089 abort ();
11090 return "add{w}\t{%0, %0|%0, %0}";
11091
11092 default:
11093 if (REG_P (operands[2]))
11094 return "sal{w}\t{%b2, %0|%0, %b2}";
11095 else if (GET_CODE (operands[2]) == CONST_INT
11096 && INTVAL (operands[2]) == 1
11097 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11098 return "sal{w}\t%0";
11099 else
11100 return "sal{w}\t{%2, %0|%0, %2}";
11101 }
11102}
11103 [(set (attr "type")
11104 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11105 (const_int 0))
11106 (match_operand 0 "register_operand" ""))
11107 (match_operand 2 "const1_operand" ""))
11108 (const_string "alu")
11109 ]
11110 (const_string "ishift")))
11111 (set_attr "mode" "HI")])
11112
11113;; This pattern can't accept a variable shift count, since shifts by
11114;; zero don't affect the flags. We assume that shifts by constant
11115;; zero are optimized away.
11116(define_insn "*ashlhi3_cmp"
11117 [(set (reg 17)
11118 (compare
11119 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11120 (match_operand:QI 2 "immediate_operand" "I"))
11121 (const_int 0)))
11122 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11123 (ashift:HI (match_dup 1) (match_dup 2)))]
11124 "ix86_match_ccmode (insn, CCGOCmode)
11125 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11126{
11127 switch (get_attr_type (insn))
11128 {
11129 case TYPE_ALU:
11130 if (operands[2] != const1_rtx)
11131 abort ();
11132 return "add{w}\t{%0, %0|%0, %0}";
11133
11134 default:
11135 if (REG_P (operands[2]))
11136 return "sal{w}\t{%b2, %0|%0, %b2}";
11137 else if (GET_CODE (operands[2]) == CONST_INT
11138 && INTVAL (operands[2]) == 1
11139 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11140 return "sal{w}\t%0";
11141 else
11142 return "sal{w}\t{%2, %0|%0, %2}";
11143 }
11144}
11145 [(set (attr "type")
11146 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11147 (const_int 0))
11148 (match_operand 0 "register_operand" ""))
11149 (match_operand 2 "const1_operand" ""))
11150 (const_string "alu")
11151 ]
11152 (const_string "ishift")))
11153 (set_attr "mode" "HI")])
11154
11155(define_expand "ashlqi3"
11156 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11157 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11158 (match_operand:QI 2 "nonmemory_operand" "")))
11159 (clobber (reg:CC 17))]
11160 "TARGET_QIMODE_MATH"
11161 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11162
11163;; %%% Potential partial reg stall on alternative 2. What to do?
11164
11165(define_insn "*ashlqi3_1_lea"
11166 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11167 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11168 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11169 (clobber (reg:CC 17))]
11170 "!TARGET_PARTIAL_REG_STALL
11171 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11172{
11173 switch (get_attr_type (insn))
11174 {
11175 case TYPE_LEA:
11176 return "#";
11177 case TYPE_ALU:
11178 if (operands[2] != const1_rtx)
11179 abort ();
11180 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11181 return "add{l}\t{%k0, %k0|%k0, %k0}";
11182 else
11183 return "add{b}\t{%0, %0|%0, %0}";
11184
11185 default:
11186 if (REG_P (operands[2]))
11187 {
11188 if (get_attr_mode (insn) == MODE_SI)
11189 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11190 else
11191 return "sal{b}\t{%b2, %0|%0, %b2}";
11192 }
11193 else if (GET_CODE (operands[2]) == CONST_INT
11194 && INTVAL (operands[2]) == 1
11195 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11196 {
11197 if (get_attr_mode (insn) == MODE_SI)
11198 return "sal{l}\t%0";
11199 else
11200 return "sal{b}\t%0";
11201 }
11202 else
11203 {
11204 if (get_attr_mode (insn) == MODE_SI)
11205 return "sal{l}\t{%2, %k0|%k0, %2}";
11206 else
11207 return "sal{b}\t{%2, %0|%0, %2}";
11208 }
11209 }
11210}
11211 [(set (attr "type")
11212 (cond [(eq_attr "alternative" "2")
11213 (const_string "lea")
11214 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11215 (const_int 0))
11216 (match_operand 0 "register_operand" ""))
11217 (match_operand 2 "const1_operand" ""))
11218 (const_string "alu")
11219 ]
11220 (const_string "ishift")))
11221 (set_attr "mode" "QI,SI,SI")])
11222
11223(define_insn "*ashlqi3_1"
11224 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11225 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11226 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11227 (clobber (reg:CC 17))]
11228 "TARGET_PARTIAL_REG_STALL
11229 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11230{
11231 switch (get_attr_type (insn))
11232 {
11233 case TYPE_ALU:
11234 if (operands[2] != const1_rtx)
11235 abort ();
11236 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11237 return "add{l}\t{%k0, %k0|%k0, %k0}";
11238 else
11239 return "add{b}\t{%0, %0|%0, %0}";
11240
11241 default:
11242 if (REG_P (operands[2]))
11243 {
11244 if (get_attr_mode (insn) == MODE_SI)
11245 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11246 else
11247 return "sal{b}\t{%b2, %0|%0, %b2}";
11248 }
11249 else if (GET_CODE (operands[2]) == CONST_INT
11250 && INTVAL (operands[2]) == 1
11251 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11252 {
11253 if (get_attr_mode (insn) == MODE_SI)
11254 return "sal{l}\t%0";
11255 else
11256 return "sal{b}\t%0";
11257 }
11258 else
11259 {
11260 if (get_attr_mode (insn) == MODE_SI)
11261 return "sal{l}\t{%2, %k0|%k0, %2}";
11262 else
11263 return "sal{b}\t{%2, %0|%0, %2}";
11264 }
11265 }
11266}
11267 [(set (attr "type")
11268 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11269 (const_int 0))
11270 (match_operand 0 "register_operand" ""))
11271 (match_operand 2 "const1_operand" ""))
11272 (const_string "alu")
11273 ]
11274 (const_string "ishift")))
11275 (set_attr "mode" "QI,SI")])
11276
11277;; This pattern can't accept a variable shift count, since shifts by
11278;; zero don't affect the flags. We assume that shifts by constant
11279;; zero are optimized away.
11280(define_insn "*ashlqi3_cmp"
11281 [(set (reg 17)
11282 (compare
11283 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11284 (match_operand:QI 2 "immediate_operand" "I"))
11285 (const_int 0)))
11286 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11287 (ashift:QI (match_dup 1) (match_dup 2)))]
11288 "ix86_match_ccmode (insn, CCGOCmode)
11289 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11290{
11291 switch (get_attr_type (insn))
11292 {
11293 case TYPE_ALU:
11294 if (operands[2] != const1_rtx)
11295 abort ();
11296 return "add{b}\t{%0, %0|%0, %0}";
11297
11298 default:
11299 if (REG_P (operands[2]))
11300 return "sal{b}\t{%b2, %0|%0, %b2}";
11301 else if (GET_CODE (operands[2]) == CONST_INT
11302 && INTVAL (operands[2]) == 1
11303 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11304 return "sal{b}\t%0";
11305 else
11306 return "sal{b}\t{%2, %0|%0, %2}";
11307 }
11308}
11309 [(set (attr "type")
11310 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11311 (const_int 0))
11312 (match_operand 0 "register_operand" ""))
11313 (match_operand 2 "const1_operand" ""))
11314 (const_string "alu")
11315 ]
11316 (const_string "ishift")))
11317 (set_attr "mode" "QI")])
11318
11319;; See comment above `ashldi3' about how this works.
11320
11321(define_expand "ashrdi3"
11322 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11323 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11324 (match_operand:QI 2 "nonmemory_operand" "")))
11325 (clobber (reg:CC 17))])]
11326 ""
11327{
11328 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11329 {
11330 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11331 DONE;
11332 }
11333 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11334 DONE;
11335})
11336
11337(define_insn "ashrdi3_63_rex64"
11338 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11339 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11340 (match_operand:DI 2 "const_int_operand" "i,i")))
11341 (clobber (reg:CC 17))]
11342 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11343 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11344 "@
11345 {cqto|cqo}
11346 sar{q}\t{%2, %0|%0, %2}"
11347 [(set_attr "type" "imovx,ishift")
11348 (set_attr "prefix_0f" "0,*")
11349 (set_attr "length_immediate" "0,*")
11350 (set_attr "modrm" "0,1")
11351 (set_attr "mode" "DI")])
11352
11353(define_insn "*ashrdi3_1_one_bit_rex64"
11354 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11355 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11356 (match_operand:QI 2 "const_int_1_operand" "")))
11357 (clobber (reg:CC 17))]
11358 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11359 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11360 "sar{q}\t%0"
11361 [(set_attr "type" "ishift")
11362 (set (attr "length")
11363 (if_then_else (match_operand:DI 0 "register_operand" "")
11364 (const_string "2")
11365 (const_string "*")))])
11366
11367(define_insn "*ashrdi3_1_rex64"
11368 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11369 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11370 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11371 (clobber (reg:CC 17))]
11372 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11373 "@
11374 sar{q}\t{%2, %0|%0, %2}
11375 sar{q}\t{%b2, %0|%0, %b2}"
11376 [(set_attr "type" "ishift")
11377 (set_attr "mode" "DI")])
11378
11379;; This pattern can't accept a variable shift count, since shifts by
11380;; zero don't affect the flags. We assume that shifts by constant
11381;; zero are optimized away.
11382(define_insn "*ashrdi3_one_bit_cmp_rex64"
11383 [(set (reg 17)
11384 (compare
11385 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11386 (match_operand:QI 2 "const_int_1_operand" ""))
11387 (const_int 0)))
11388 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11389 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11390 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11391 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11392 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11393 "sar{q}\t%0"
11394 [(set_attr "type" "ishift")
11395 (set (attr "length")
11396 (if_then_else (match_operand:DI 0 "register_operand" "")
11397 (const_string "2")
11398 (const_string "*")))])
11399
11400;; This pattern can't accept a variable shift count, since shifts by
11401;; zero don't affect the flags. We assume that shifts by constant
11402;; zero are optimized away.
11403(define_insn "*ashrdi3_cmp_rex64"
11404 [(set (reg 17)
11405 (compare
11406 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11407 (match_operand:QI 2 "const_int_operand" "n"))
11408 (const_int 0)))
11409 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11410 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11411 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11412 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11413 "sar{q}\t{%2, %0|%0, %2}"
11414 [(set_attr "type" "ishift")
11415 (set_attr "mode" "DI")])
11416
11417
11418(define_insn "ashrdi3_1"
11419 [(set (match_operand:DI 0 "register_operand" "=r")
11420 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11421 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11422 (clobber (match_scratch:SI 3 "=&r"))
11423 (clobber (reg:CC 17))]
11424 "!TARGET_64BIT && TARGET_CMOVE"
11425 "#"
11426 [(set_attr "type" "multi")])
11427
11428(define_insn "*ashrdi3_2"
11429 [(set (match_operand:DI 0 "register_operand" "=r")
11430 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11431 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11432 (clobber (reg:CC 17))]
11433 "!TARGET_64BIT"
11434 "#"
11435 [(set_attr "type" "multi")])
11436
11437(define_split
11438 [(set (match_operand:DI 0 "register_operand" "")
11439 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11440 (match_operand:QI 2 "nonmemory_operand" "")))
11441 (clobber (match_scratch:SI 3 ""))
11442 (clobber (reg:CC 17))]
11443 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11444 [(const_int 0)]
11445 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11446
11447(define_split
11448 [(set (match_operand:DI 0 "register_operand" "")
11449 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11450 (match_operand:QI 2 "nonmemory_operand" "")))
11451 (clobber (reg:CC 17))]
11452 "!TARGET_64BIT && reload_completed"
11453 [(const_int 0)]
11454 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11455
11456(define_insn "x86_shrd_1"
11457 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11458 (ior:SI (ashiftrt:SI (match_dup 0)
11459 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11460 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11461 (minus:QI (const_int 32) (match_dup 2)))))
11462 (clobber (reg:CC 17))]
11463 ""
11464 "@
11465 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11466 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11467 [(set_attr "type" "ishift")
11468 (set_attr "prefix_0f" "1")
11469 (set_attr "pent_pair" "np")
11470 (set_attr "ppro_uops" "few")
11471 (set_attr "mode" "SI")])
11472
11473(define_expand "x86_shift_adj_3"
11474 [(use (match_operand:SI 0 "register_operand" ""))
11475 (use (match_operand:SI 1 "register_operand" ""))
11476 (use (match_operand:QI 2 "register_operand" ""))]
11477 ""
11478{
11479 rtx label = gen_label_rtx ();
11480 rtx tmp;
11481
11482 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11483
11484 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11485 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11486 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11487 gen_rtx_LABEL_REF (VOIDmode, label),
11488 pc_rtx);
11489 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11490 JUMP_LABEL (tmp) = label;
11491
11492 emit_move_insn (operands[0], operands[1]);
11493 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11494
11495 emit_label (label);
11496 LABEL_NUSES (label) = 1;
11497
11498 DONE;
11499})
11500
11501(define_insn "ashrsi3_31"
11502 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11503 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11504 (match_operand:SI 2 "const_int_operand" "i,i")))
11505 (clobber (reg:CC 17))]
11506 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11507 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11508 "@
11509 {cltd|cdq}
11510 sar{l}\t{%2, %0|%0, %2}"
11511 [(set_attr "type" "imovx,ishift")
11512 (set_attr "prefix_0f" "0,*")
11513 (set_attr "length_immediate" "0,*")
11514 (set_attr "modrm" "0,1")
11515 (set_attr "mode" "SI")])
11516
11517(define_insn "*ashrsi3_31_zext"
11518 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11519 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11520 (match_operand:SI 2 "const_int_operand" "i,i"))))
11521 (clobber (reg:CC 17))]
11522 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11523 && INTVAL (operands[2]) == 31
11524 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11525 "@
11526 {cltd|cdq}
11527 sar{l}\t{%2, %k0|%k0, %2}"
11528 [(set_attr "type" "imovx,ishift")
11529 (set_attr "prefix_0f" "0,*")
11530 (set_attr "length_immediate" "0,*")
11531 (set_attr "modrm" "0,1")
11532 (set_attr "mode" "SI")])
11533
11534(define_expand "ashrsi3"
11535 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11536 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11537 (match_operand:QI 2 "nonmemory_operand" "")))
11538 (clobber (reg:CC 17))]
11539 ""
11540 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11541
11542(define_insn "*ashrsi3_1_one_bit"
11543 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11544 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11545 (match_operand:QI 2 "const_int_1_operand" "")))
11546 (clobber (reg:CC 17))]
11547 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11548 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11549 "sar{l}\t%0"
11550 [(set_attr "type" "ishift")
11551 (set (attr "length")
11552 (if_then_else (match_operand:SI 0 "register_operand" "")
11553 (const_string "2")
11554 (const_string "*")))])
11555
11556(define_insn "*ashrsi3_1_one_bit_zext"
11557 [(set (match_operand:DI 0 "register_operand" "=r")
11558 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11559 (match_operand:QI 2 "const_int_1_operand" ""))))
11560 (clobber (reg:CC 17))]
11561 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11562 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11563 "sar{l}\t%k0"
11564 [(set_attr "type" "ishift")
11565 (set_attr "length" "2")])
11566
11567(define_insn "*ashrsi3_1"
11568 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11569 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11570 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11571 (clobber (reg:CC 17))]
11572 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11573 "@
11574 sar{l}\t{%2, %0|%0, %2}
11575 sar{l}\t{%b2, %0|%0, %b2}"
11576 [(set_attr "type" "ishift")
11577 (set_attr "mode" "SI")])
11578
11579(define_insn "*ashrsi3_1_zext"
11580 [(set (match_operand:DI 0 "register_operand" "=r,r")
11581 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11582 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11583 (clobber (reg:CC 17))]
11584 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11585 "@
11586 sar{l}\t{%2, %k0|%k0, %2}
11587 sar{l}\t{%b2, %k0|%k0, %b2}"
11588 [(set_attr "type" "ishift")
11589 (set_attr "mode" "SI")])
11590
11591;; This pattern can't accept a variable shift count, since shifts by
11592;; zero don't affect the flags. We assume that shifts by constant
11593;; zero are optimized away.
11594(define_insn "*ashrsi3_one_bit_cmp"
11595 [(set (reg 17)
11596 (compare
11597 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11598 (match_operand:QI 2 "const_int_1_operand" ""))
11599 (const_int 0)))
11600 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11601 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11602 "ix86_match_ccmode (insn, CCGOCmode)
11603 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11604 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11605 "sar{l}\t%0"
11606 [(set_attr "type" "ishift")
11607 (set (attr "length")
11608 (if_then_else (match_operand:SI 0 "register_operand" "")
11609 (const_string "2")
11610 (const_string "*")))])
11611
11612(define_insn "*ashrsi3_one_bit_cmp_zext"
11613 [(set (reg 17)
11614 (compare
11615 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11616 (match_operand:QI 2 "const_int_1_operand" ""))
11617 (const_int 0)))
11618 (set (match_operand:DI 0 "register_operand" "=r")
11619 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11620 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11621 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11622 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11623 "sar{l}\t%k0"
11624 [(set_attr "type" "ishift")
11625 (set_attr "length" "2")])
11626
11627;; This pattern can't accept a variable shift count, since shifts by
11628;; zero don't affect the flags. We assume that shifts by constant
11629;; zero are optimized away.
11630(define_insn "*ashrsi3_cmp"
11631 [(set (reg 17)
11632 (compare
11633 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11634 (match_operand:QI 2 "immediate_operand" "I"))
11635 (const_int 0)))
11636 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11637 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11638 "ix86_match_ccmode (insn, CCGOCmode)
11639 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11640 "sar{l}\t{%2, %0|%0, %2}"
11641 [(set_attr "type" "ishift")
11642 (set_attr "mode" "SI")])
11643
11644(define_insn "*ashrsi3_cmp_zext"
11645 [(set (reg 17)
11646 (compare
11647 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11648 (match_operand:QI 2 "immediate_operand" "I"))
11649 (const_int 0)))
11650 (set (match_operand:DI 0 "register_operand" "=r")
11651 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11652 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11653 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11654 "sar{l}\t{%2, %k0|%k0, %2}"
11655 [(set_attr "type" "ishift")
11656 (set_attr "mode" "SI")])
11657
11658(define_expand "ashrhi3"
11659 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11660 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11661 (match_operand:QI 2 "nonmemory_operand" "")))
11662 (clobber (reg:CC 17))]
11663 "TARGET_HIMODE_MATH"
11664 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11665
11666(define_insn "*ashrhi3_1_one_bit"
11667 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11668 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11669 (match_operand:QI 2 "const_int_1_operand" "")))
11670 (clobber (reg:CC 17))]
11671 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11672 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11673 "sar{w}\t%0"
11674 [(set_attr "type" "ishift")
11675 (set (attr "length")
11676 (if_then_else (match_operand 0 "register_operand" "")
11677 (const_string "2")
11678 (const_string "*")))])
11679
11680(define_insn "*ashrhi3_1"
11681 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11682 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11683 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11684 (clobber (reg:CC 17))]
11685 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11686 "@
11687 sar{w}\t{%2, %0|%0, %2}
11688 sar{w}\t{%b2, %0|%0, %b2}"
11689 [(set_attr "type" "ishift")
11690 (set_attr "mode" "HI")])
11691
11692;; This pattern can't accept a variable shift count, since shifts by
11693;; zero don't affect the flags. We assume that shifts by constant
11694;; zero are optimized away.
11695(define_insn "*ashrhi3_one_bit_cmp"
11696 [(set (reg 17)
11697 (compare
11698 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11699 (match_operand:QI 2 "const_int_1_operand" ""))
11700 (const_int 0)))
11701 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11702 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11703 "ix86_match_ccmode (insn, CCGOCmode)
11704 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11705 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11706 "sar{w}\t%0"
11707 [(set_attr "type" "ishift")
11708 (set (attr "length")
11709 (if_then_else (match_operand 0 "register_operand" "")
11710 (const_string "2")
11711 (const_string "*")))])
11712
11713;; This pattern can't accept a variable shift count, since shifts by
11714;; zero don't affect the flags. We assume that shifts by constant
11715;; zero are optimized away.
11716(define_insn "*ashrhi3_cmp"
11717 [(set (reg 17)
11718 (compare
11719 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11720 (match_operand:QI 2 "immediate_operand" "I"))
11721 (const_int 0)))
11722 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11723 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11724 "ix86_match_ccmode (insn, CCGOCmode)
11725 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11726 "sar{w}\t{%2, %0|%0, %2}"
11727 [(set_attr "type" "ishift")
11728 (set_attr "mode" "HI")])
11729
11730(define_expand "ashrqi3"
11731 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11732 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11733 (match_operand:QI 2 "nonmemory_operand" "")))
11734 (clobber (reg:CC 17))]
11735 "TARGET_QIMODE_MATH"
11736 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11737
11738(define_insn "*ashrqi3_1_one_bit"
11739 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11740 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11741 (match_operand:QI 2 "const_int_1_operand" "")))
11742 (clobber (reg:CC 17))]
11743 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11744 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11745 "sar{b}\t%0"
11746 [(set_attr "type" "ishift")
11747 (set (attr "length")
11748 (if_then_else (match_operand 0 "register_operand" "")
11749 (const_string "2")
11750 (const_string "*")))])
11751
11752(define_insn "*ashrqi3_1"
11753 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11754 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11755 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11756 (clobber (reg:CC 17))]
11757 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11758 "@
11759 sar{b}\t{%2, %0|%0, %2}
11760 sar{b}\t{%b2, %0|%0, %b2}"
11761 [(set_attr "type" "ishift")
11762 (set_attr "mode" "QI")])
11763
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.
11767(define_insn "*ashrqi3_one_bit_cmp"
11768 [(set (reg 17)
11769 (compare
11770 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11771 (match_operand:QI 2 "const_int_1_operand" "I"))
11772 (const_int 0)))
11773 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11774 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11775 "ix86_match_ccmode (insn, CCGOCmode)
11776 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11777 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11778 "sar{b}\t%0"
11779 [(set_attr "type" "ishift")
11780 (set (attr "length")
11781 (if_then_else (match_operand 0 "register_operand" "")
11782 (const_string "2")
11783 (const_string "*")))])
11784
11785;; This pattern can't accept a variable shift count, since shifts by
11786;; zero don't affect the flags. We assume that shifts by constant
11787;; zero are optimized away.
11788(define_insn "*ashrqi3_cmp"
11789 [(set (reg 17)
11790 (compare
11791 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11792 (match_operand:QI 2 "immediate_operand" "I"))
11793 (const_int 0)))
11794 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11795 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11796 "ix86_match_ccmode (insn, CCGOCmode)
11797 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11798 "sar{b}\t{%2, %0|%0, %2}"
11799 [(set_attr "type" "ishift")
11800 (set_attr "mode" "QI")])
11801
11802;; Logical shift instructions
11803
11804;; See comment above `ashldi3' about how this works.
11805
11806(define_expand "lshrdi3"
11807 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11808 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11809 (match_operand:QI 2 "nonmemory_operand" "")))
11810 (clobber (reg:CC 17))])]
11811 ""
11812{
11813 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11814 {
11815 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11816 DONE;
11817 }
11818 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11819 DONE;
11820})
11821
11822(define_insn "*lshrdi3_1_one_bit_rex64"
11823 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11824 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11825 (match_operand:QI 2 "const_int_1_operand" "")))
11826 (clobber (reg:CC 17))]
11827 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11828 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11829 "shr{q}\t%0"
11830 [(set_attr "type" "ishift")
11831 (set (attr "length")
11832 (if_then_else (match_operand:DI 0 "register_operand" "")
11833 (const_string "2")
11834 (const_string "*")))])
11835
11836(define_insn "*lshrdi3_1_rex64"
11837 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11838 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11839 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11840 (clobber (reg:CC 17))]
11841 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11842 "@
11843 shr{q}\t{%2, %0|%0, %2}
11844 shr{q}\t{%b2, %0|%0, %b2}"
11845 [(set_attr "type" "ishift")
11846 (set_attr "mode" "DI")])
11847
11848;; This pattern can't accept a variable shift count, since shifts by
11849;; zero don't affect the flags. We assume that shifts by constant
11850;; zero are optimized away.
11851(define_insn "*lshrdi3_cmp_one_bit_rex64"
11852 [(set (reg 17)
11853 (compare
11854 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11855 (match_operand:QI 2 "const_int_1_operand" ""))
11856 (const_int 0)))
11857 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11858 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11859 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11860 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11861 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11862 "shr{q}\t%0"
11863 [(set_attr "type" "ishift")
11864 (set (attr "length")
11865 (if_then_else (match_operand:DI 0 "register_operand" "")
11866 (const_string "2")
11867 (const_string "*")))])
11868
11869;; This pattern can't accept a variable shift count, since shifts by
11870;; zero don't affect the flags. We assume that shifts by constant
11871;; zero are optimized away.
11872(define_insn "*lshrdi3_cmp_rex64"
11873 [(set (reg 17)
11874 (compare
11875 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11876 (match_operand:QI 2 "const_int_operand" "e"))
11877 (const_int 0)))
11878 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11879 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11880 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11881 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11882 "shr{q}\t{%2, %0|%0, %2}"
11883 [(set_attr "type" "ishift")
11884 (set_attr "mode" "DI")])
11885
11886(define_insn "lshrdi3_1"
11887 [(set (match_operand:DI 0 "register_operand" "=r")
11888 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11889 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11890 (clobber (match_scratch:SI 3 "=&r"))
11891 (clobber (reg:CC 17))]
11892 "!TARGET_64BIT && TARGET_CMOVE"
11893 "#"
11894 [(set_attr "type" "multi")])
11895
11896(define_insn "*lshrdi3_2"
11897 [(set (match_operand:DI 0 "register_operand" "=r")
11898 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11899 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11900 (clobber (reg:CC 17))]
11901 "!TARGET_64BIT"
11902 "#"
11903 [(set_attr "type" "multi")])
11904
11905(define_split
11906 [(set (match_operand:DI 0 "register_operand" "")
11907 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11908 (match_operand:QI 2 "nonmemory_operand" "")))
11909 (clobber (match_scratch:SI 3 ""))
11910 (clobber (reg:CC 17))]
11911 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11912 [(const_int 0)]
11913 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11914
11915(define_split
11916 [(set (match_operand:DI 0 "register_operand" "")
11917 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11918 (match_operand:QI 2 "nonmemory_operand" "")))
11919 (clobber (reg:CC 17))]
11920 "!TARGET_64BIT && reload_completed"
11921 [(const_int 0)]
11922 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11923
11924(define_expand "lshrsi3"
11925 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11926 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11927 (match_operand:QI 2 "nonmemory_operand" "")))
11928 (clobber (reg:CC 17))]
11929 ""
11930 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11931
11932(define_insn "*lshrsi3_1_one_bit"
11933 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11934 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const_int_1_operand" "")))
11936 (clobber (reg:CC 17))]
11937 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11938 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11939 "shr{l}\t%0"
11940 [(set_attr "type" "ishift")
11941 (set (attr "length")
11942 (if_then_else (match_operand:SI 0 "register_operand" "")
11943 (const_string "2")
11944 (const_string "*")))])
11945
11946(define_insn "*lshrsi3_1_one_bit_zext"
11947 [(set (match_operand:DI 0 "register_operand" "=r")
11948 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11949 (match_operand:QI 2 "const_int_1_operand" "")))
11950 (clobber (reg:CC 17))]
11951 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11952 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11953 "shr{l}\t%k0"
11954 [(set_attr "type" "ishift")
11955 (set_attr "length" "2")])
11956
11957(define_insn "*lshrsi3_1"
11958 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11959 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11960 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11961 (clobber (reg:CC 17))]
11962 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11963 "@
11964 shr{l}\t{%2, %0|%0, %2}
11965 shr{l}\t{%b2, %0|%0, %b2}"
11966 [(set_attr "type" "ishift")
11967 (set_attr "mode" "SI")])
11968
11969(define_insn "*lshrsi3_1_zext"
11970 [(set (match_operand:DI 0 "register_operand" "=r,r")
11971 (zero_extend:DI
11972 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11973 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11974 (clobber (reg:CC 17))]
11975 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11976 "@
11977 shr{l}\t{%2, %k0|%k0, %2}
11978 shr{l}\t{%b2, %k0|%k0, %b2}"
11979 [(set_attr "type" "ishift")
11980 (set_attr "mode" "SI")])
11981
11982;; This pattern can't accept a variable shift count, since shifts by
11983;; zero don't affect the flags. We assume that shifts by constant
11984;; zero are optimized away.
11985(define_insn "*lshrsi3_one_bit_cmp"
11986 [(set (reg 17)
11987 (compare
11988 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11989 (match_operand:QI 2 "const_int_1_operand" ""))
11990 (const_int 0)))
11991 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11992 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11993 "ix86_match_ccmode (insn, CCGOCmode)
11994 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11995 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11996 "shr{l}\t%0"
11997 [(set_attr "type" "ishift")
11998 (set (attr "length")
11999 (if_then_else (match_operand:SI 0 "register_operand" "")
12000 (const_string "2")
12001 (const_string "*")))])
12002
12003(define_insn "*lshrsi3_cmp_one_bit_zext"
12004 [(set (reg 17)
12005 (compare
12006 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12007 (match_operand:QI 2 "const_int_1_operand" ""))
12008 (const_int 0)))
12009 (set (match_operand:DI 0 "register_operand" "=r")
12010 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12011 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12012 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
12013 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12014 "shr{l}\t%k0"
12015 [(set_attr "type" "ishift")
12016 (set_attr "length" "2")])
12017
12018;; This pattern can't accept a variable shift count, since shifts by
12019;; zero don't affect the flags. We assume that shifts by constant
12020;; zero are optimized away.
12021(define_insn "*lshrsi3_cmp"
12022 [(set (reg 17)
12023 (compare
12024 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12025 (match_operand:QI 2 "immediate_operand" "I"))
12026 (const_int 0)))
12027 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12028 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12029 "ix86_match_ccmode (insn, CCGOCmode)
12030 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12031 "shr{l}\t{%2, %0|%0, %2}"
12032 [(set_attr "type" "ishift")
12033 (set_attr "mode" "SI")])
12034
12035(define_insn "*lshrsi3_cmp_zext"
12036 [(set (reg 17)
12037 (compare
12038 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12039 (match_operand:QI 2 "immediate_operand" "I"))
12040 (const_int 0)))
12041 (set (match_operand:DI 0 "register_operand" "=r")
12042 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12043 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12044 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12045 "shr{l}\t{%2, %k0|%k0, %2}"
12046 [(set_attr "type" "ishift")
12047 (set_attr "mode" "SI")])
12048
12049(define_expand "lshrhi3"
12050 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12051 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12052 (match_operand:QI 2 "nonmemory_operand" "")))
12053 (clobber (reg:CC 17))]
12054 "TARGET_HIMODE_MATH"
12055 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12056
12057(define_insn "*lshrhi3_1_one_bit"
12058 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12059 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12060 (match_operand:QI 2 "const_int_1_operand" "")))
12061 (clobber (reg:CC 17))]
12062 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12063 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12064 "shr{w}\t%0"
12065 [(set_attr "type" "ishift")
12066 (set (attr "length")
12067 (if_then_else (match_operand 0 "register_operand" "")
12068 (const_string "2")
12069 (const_string "*")))])
12070
12071(define_insn "*lshrhi3_1"
12072 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12073 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12074 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12075 (clobber (reg:CC 17))]
12076 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12077 "@
12078 shr{w}\t{%2, %0|%0, %2}
12079 shr{w}\t{%b2, %0|%0, %b2}"
12080 [(set_attr "type" "ishift")
12081 (set_attr "mode" "HI")])
12082
12083;; This pattern can't accept a variable shift count, since shifts by
12084;; zero don't affect the flags. We assume that shifts by constant
12085;; zero are optimized away.
12086(define_insn "*lshrhi3_one_bit_cmp"
12087 [(set (reg 17)
12088 (compare
12089 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12090 (match_operand:QI 2 "const_int_1_operand" ""))
12091 (const_int 0)))
12092 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12093 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12094 "ix86_match_ccmode (insn, CCGOCmode)
12095 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
12096 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12097 "shr{w}\t%0"
12098 [(set_attr "type" "ishift")
12099 (set (attr "length")
12100 (if_then_else (match_operand:SI 0 "register_operand" "")
12101 (const_string "2")
12102 (const_string "*")))])
12103
12104;; This pattern can't accept a variable shift count, since shifts by
12105;; zero don't affect the flags. We assume that shifts by constant
12106;; zero are optimized away.
12107(define_insn "*lshrhi3_cmp"
12108 [(set (reg 17)
12109 (compare
12110 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12111 (match_operand:QI 2 "immediate_operand" "I"))
12112 (const_int 0)))
12113 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12114 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12115 "ix86_match_ccmode (insn, CCGOCmode)
12116 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12117 "shr{w}\t{%2, %0|%0, %2}"
12118 [(set_attr "type" "ishift")
12119 (set_attr "mode" "HI")])
12120
12121(define_expand "lshrqi3"
12122 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12123 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12124 (match_operand:QI 2 "nonmemory_operand" "")))
12125 (clobber (reg:CC 17))]
12126 "TARGET_QIMODE_MATH"
12127 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12128
12129(define_insn "*lshrqi3_1_one_bit"
12130 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12131 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12132 (match_operand:QI 2 "const_int_1_operand" "")))
12133 (clobber (reg:CC 17))]
12134 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12135 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12136 "shr{b}\t%0"
12137 [(set_attr "type" "ishift")
12138 (set (attr "length")
12139 (if_then_else (match_operand 0 "register_operand" "")
12140 (const_string "2")
12141 (const_string "*")))])
12142
12143(define_insn "*lshrqi3_1"
12144 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12145 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12146 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12147 (clobber (reg:CC 17))]
12148 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12149 "@
12150 shr{b}\t{%2, %0|%0, %2}
12151 shr{b}\t{%b2, %0|%0, %b2}"
12152 [(set_attr "type" "ishift")
12153 (set_attr "mode" "QI")])
12154
12155;; This pattern can't accept a variable shift count, since shifts by
12156;; zero don't affect the flags. We assume that shifts by constant
12157;; zero are optimized away.
12158(define_insn "*lshrqi2_one_bit_cmp"
12159 [(set (reg 17)
12160 (compare
12161 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12162 (match_operand:QI 2 "const_int_1_operand" ""))
12163 (const_int 0)))
12164 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12165 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12166 "ix86_match_ccmode (insn, CCGOCmode)
12167 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
12168 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12169 "shr{b}\t%0"
12170 [(set_attr "type" "ishift")
12171 (set (attr "length")
12172 (if_then_else (match_operand:SI 0 "register_operand" "")
12173 (const_string "2")
12174 (const_string "*")))])
12175
12176;; This pattern can't accept a variable shift count, since shifts by
12177;; zero don't affect the flags. We assume that shifts by constant
12178;; zero are optimized away.
12179(define_insn "*lshrqi2_cmp"
12180 [(set (reg 17)
12181 (compare
12182 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12183 (match_operand:QI 2 "immediate_operand" "I"))
12184 (const_int 0)))
12185 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12186 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12187 "ix86_match_ccmode (insn, CCGOCmode)
12188 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12189 "shr{b}\t{%2, %0|%0, %2}"
12190 [(set_attr "type" "ishift")
12191 (set_attr "mode" "QI")])
12192
12193;; Rotate instructions
12194
12195(define_expand "rotldi3"
12196 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12197 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12198 (match_operand:QI 2 "nonmemory_operand" "")))
12199 (clobber (reg:CC 17))]
12200 "TARGET_64BIT"
12201 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12202
12203(define_insn "*rotlsi3_1_one_bit_rex64"
12204 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12205 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12206 (match_operand:QI 2 "const_int_1_operand" "")))
12207 (clobber (reg:CC 17))]
12208 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12209 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12210 "rol{q}\t%0"
12211 [(set_attr "type" "ishift")
12212 (set (attr "length")
12213 (if_then_else (match_operand:DI 0 "register_operand" "")
12214 (const_string "2")
12215 (const_string "*")))])
12216
12217(define_insn "*rotldi3_1_rex64"
12218 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12219 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12220 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12221 (clobber (reg:CC 17))]
12222 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12223 "@
12224 rol{q}\t{%2, %0|%0, %2}
12225 rol{q}\t{%b2, %0|%0, %b2}"
12226 [(set_attr "type" "ishift")
12227 (set_attr "mode" "DI")])
12228
12229(define_expand "rotlsi3"
12230 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12231 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12232 (match_operand:QI 2 "nonmemory_operand" "")))
12233 (clobber (reg:CC 17))]
12234 ""
12235 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12236
12237(define_insn "*rotlsi3_1_one_bit"
12238 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12239 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const_int_1_operand" "")))
12241 (clobber (reg:CC 17))]
12242 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12243 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12244 "rol{l}\t%0"
12245 [(set_attr "type" "ishift")
12246 (set (attr "length")
12247 (if_then_else (match_operand:SI 0 "register_operand" "")
12248 (const_string "2")
12249 (const_string "*")))])
12250
12251(define_insn "*rotlsi3_1_one_bit_zext"
12252 [(set (match_operand:DI 0 "register_operand" "=r")
12253 (zero_extend:DI
12254 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12255 (match_operand:QI 2 "const_int_1_operand" ""))))
12256 (clobber (reg:CC 17))]
12257 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12258 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12259 "rol{l}\t%k0"
12260 [(set_attr "type" "ishift")
12261 (set_attr "length" "2")])
12262
12263(define_insn "*rotlsi3_1"
12264 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12265 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12266 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12267 (clobber (reg:CC 17))]
12268 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12269 "@
12270 rol{l}\t{%2, %0|%0, %2}
12271 rol{l}\t{%b2, %0|%0, %b2}"
12272 [(set_attr "type" "ishift")
12273 (set_attr "mode" "SI")])
12274
12275(define_insn "*rotlsi3_1_zext"
12276 [(set (match_operand:DI 0 "register_operand" "=r,r")
12277 (zero_extend:DI
12278 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12279 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12280 (clobber (reg:CC 17))]
12281 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12282 "@
12283 rol{l}\t{%2, %k0|%k0, %2}
12284 rol{l}\t{%b2, %k0|%k0, %b2}"
12285 [(set_attr "type" "ishift")
12286 (set_attr "mode" "SI")])
12287
12288(define_expand "rotlhi3"
12289 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12290 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12291 (match_operand:QI 2 "nonmemory_operand" "")))
12292 (clobber (reg:CC 17))]
12293 "TARGET_HIMODE_MATH"
12294 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12295
12296(define_insn "*rotlhi3_1_one_bit"
12297 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12298 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12299 (match_operand:QI 2 "const_int_1_operand" "")))
12300 (clobber (reg:CC 17))]
12301 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12302 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12303 "rol{w}\t%0"
12304 [(set_attr "type" "ishift")
12305 (set (attr "length")
12306 (if_then_else (match_operand 0 "register_operand" "")
12307 (const_string "2")
12308 (const_string "*")))])
12309
12310(define_insn "*rotlhi3_1"
12311 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12312 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12313 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12314 (clobber (reg:CC 17))]
12315 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12316 "@
12317 rol{w}\t{%2, %0|%0, %2}
12318 rol{w}\t{%b2, %0|%0, %b2}"
12319 [(set_attr "type" "ishift")
12320 (set_attr "mode" "HI")])
12321
12322(define_expand "rotlqi3"
12323 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12324 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12325 (match_operand:QI 2 "nonmemory_operand" "")))
12326 (clobber (reg:CC 17))]
12327 "TARGET_QIMODE_MATH"
12328 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12329
12330(define_insn "*rotlqi3_1_one_bit"
12331 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12332 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12333 (match_operand:QI 2 "const_int_1_operand" "")))
12334 (clobber (reg:CC 17))]
12335 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12336 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12337 "rol{b}\t%0"
12338 [(set_attr "type" "ishift")
12339 (set (attr "length")
12340 (if_then_else (match_operand 0 "register_operand" "")
12341 (const_string "2")
12342 (const_string "*")))])
12343
12344(define_insn "*rotlqi3_1"
12345 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12346 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12347 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12348 (clobber (reg:CC 17))]
12349 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12350 "@
12351 rol{b}\t{%2, %0|%0, %2}
12352 rol{b}\t{%b2, %0|%0, %b2}"
12353 [(set_attr "type" "ishift")
12354 (set_attr "mode" "QI")])
12355
12356(define_expand "rotrdi3"
12357 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12358 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12359 (match_operand:QI 2 "nonmemory_operand" "")))
12360 (clobber (reg:CC 17))]
12361 "TARGET_64BIT"
12362 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12363
12364(define_insn "*rotrdi3_1_one_bit_rex64"
12365 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12366 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12367 (match_operand:QI 2 "const_int_1_operand" "")))
12368 (clobber (reg:CC 17))]
12369 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12370 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12371 "ror{q}\t%0"
12372 [(set_attr "type" "ishift")
12373 (set (attr "length")
12374 (if_then_else (match_operand:DI 0 "register_operand" "")
12375 (const_string "2")
12376 (const_string "*")))])
12377
12378(define_insn "*rotrdi3_1_rex64"
12379 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12380 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12381 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12382 (clobber (reg:CC 17))]
12383 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12384 "@
12385 ror{q}\t{%2, %0|%0, %2}
12386 ror{q}\t{%b2, %0|%0, %b2}"
12387 [(set_attr "type" "ishift")
12388 (set_attr "mode" "DI")])
12389
12390(define_expand "rotrsi3"
12391 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12392 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12393 (match_operand:QI 2 "nonmemory_operand" "")))
12394 (clobber (reg:CC 17))]
12395 ""
12396 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12397
12398(define_insn "*rotrsi3_1_one_bit"
12399 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12400 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12401 (match_operand:QI 2 "const_int_1_operand" "")))
12402 (clobber (reg:CC 17))]
12403 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12404 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12405 "ror{l}\t%0"
12406 [(set_attr "type" "ishift")
12407 (set (attr "length")
12408 (if_then_else (match_operand:SI 0 "register_operand" "")
12409 (const_string "2")
12410 (const_string "*")))])
12411
12412(define_insn "*rotrsi3_1_one_bit_zext"
12413 [(set (match_operand:DI 0 "register_operand" "=r")
12414 (zero_extend:DI
12415 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12416 (match_operand:QI 2 "const_int_1_operand" ""))))
12417 (clobber (reg:CC 17))]
12418 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12419 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12420 "ror{l}\t%k0"
12421 [(set_attr "type" "ishift")
12422 (set (attr "length")
12423 (if_then_else (match_operand:SI 0 "register_operand" "")
12424 (const_string "2")
12425 (const_string "*")))])
12426
12427(define_insn "*rotrsi3_1"
12428 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12429 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12430 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12431 (clobber (reg:CC 17))]
12432 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12433 "@
12434 ror{l}\t{%2, %0|%0, %2}
12435 ror{l}\t{%b2, %0|%0, %b2}"
12436 [(set_attr "type" "ishift")
12437 (set_attr "mode" "SI")])
12438
12439(define_insn "*rotrsi3_1_zext"
12440 [(set (match_operand:DI 0 "register_operand" "=r,r")
12441 (zero_extend:DI
12442 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12443 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12444 (clobber (reg:CC 17))]
12445 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12446 "@
12447 ror{l}\t{%2, %k0|%k0, %2}
12448 ror{l}\t{%b2, %k0|%k0, %b2}"
12449 [(set_attr "type" "ishift")
12450 (set_attr "mode" "SI")])
12451
12452(define_expand "rotrhi3"
12453 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12454 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12455 (match_operand:QI 2 "nonmemory_operand" "")))
12456 (clobber (reg:CC 17))]
12457 "TARGET_HIMODE_MATH"
12458 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12459
12460(define_insn "*rotrhi3_one_bit"
12461 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12462 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12463 (match_operand:QI 2 "const_int_1_operand" "")))
12464 (clobber (reg:CC 17))]
12465 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12466 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12467 "ror{w}\t%0"
12468 [(set_attr "type" "ishift")
12469 (set (attr "length")
12470 (if_then_else (match_operand 0 "register_operand" "")
12471 (const_string "2")
12472 (const_string "*")))])
12473
12474(define_insn "*rotrhi3"
12475 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12476 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12477 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478 (clobber (reg:CC 17))]
12479 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12480 "@
12481 ror{w}\t{%2, %0|%0, %2}
12482 ror{w}\t{%b2, %0|%0, %b2}"
12483 [(set_attr "type" "ishift")
12484 (set_attr "mode" "HI")])
12485
12486(define_expand "rotrqi3"
12487 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12488 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12489 (match_operand:QI 2 "nonmemory_operand" "")))
12490 (clobber (reg:CC 17))]
12491 "TARGET_QIMODE_MATH"
12492 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12493
12494(define_insn "*rotrqi3_1_one_bit"
12495 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12496 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12497 (match_operand:QI 2 "const_int_1_operand" "")))
12498 (clobber (reg:CC 17))]
12499 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12500 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12501 "ror{b}\t%0"
12502 [(set_attr "type" "ishift")
12503 (set (attr "length")
12504 (if_then_else (match_operand 0 "register_operand" "")
12505 (const_string "2")
12506 (const_string "*")))])
12507
12508(define_insn "*rotrqi3_1"
12509 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12510 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12511 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12512 (clobber (reg:CC 17))]
12513 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12514 "@
12515 ror{b}\t{%2, %0|%0, %2}
12516 ror{b}\t{%b2, %0|%0, %b2}"
12517 [(set_attr "type" "ishift")
12518 (set_attr "mode" "QI")])
12519
12520;; Bit set / bit test instructions
12521
12522(define_expand "extv"
12523 [(set (match_operand:SI 0 "register_operand" "")
12524 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12525 (match_operand:SI 2 "immediate_operand" "")
12526 (match_operand:SI 3 "immediate_operand" "")))]
12527 ""
12528{
12529 /* Handle extractions from %ah et al. */
12530 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12531 FAIL;
12532
12533 /* From mips.md: extract_bit_field doesn't verify that our source
12534 matches the predicate, so check it again here. */
12535 if (! register_operand (operands[1], VOIDmode))
12536 FAIL;
12537})
12538
12539(define_expand "extzv"
12540 [(set (match_operand:SI 0 "register_operand" "")
12541 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12542 (match_operand:SI 2 "immediate_operand" "")
12543 (match_operand:SI 3 "immediate_operand" "")))]
12544 ""
12545{
12546 /* Handle extractions from %ah et al. */
12547 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12548 FAIL;
12549
12550 /* From mips.md: extract_bit_field doesn't verify that our source
12551 matches the predicate, so check it again here. */
12552 if (! register_operand (operands[1], VOIDmode))
12553 FAIL;
12554})
12555
12556(define_expand "insv"
12557 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12558 (match_operand:SI 1 "immediate_operand" "")
12559 (match_operand:SI 2 "immediate_operand" ""))
12560 (match_operand:SI 3 "register_operand" ""))]
12561 ""
12562{
12563 /* Handle extractions from %ah et al. */
12564 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12565 FAIL;
12566
12567 /* From mips.md: insert_bit_field doesn't verify that our source
12568 matches the predicate, so check it again here. */
12569 if (! register_operand (operands[0], VOIDmode))
12570 FAIL;
12571})
12572
12573;; %%% bts, btr, btc, bt.
12574
12575;; Store-flag instructions.
12576
12577;; For all sCOND expanders, also expand the compare or test insn that
12578;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12579
12580;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12581;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12582;; way, which can later delete the movzx if only QImode is needed.
12583
12584(define_expand "seq"
12585 [(set (match_operand:QI 0 "register_operand" "")
12586 (eq:QI (reg:CC 17) (const_int 0)))]
12587 ""
12588 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12589
12590(define_expand "sne"
12591 [(set (match_operand:QI 0 "register_operand" "")
12592 (ne:QI (reg:CC 17) (const_int 0)))]
12593 ""
12594 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12595
12596(define_expand "sgt"
12597 [(set (match_operand:QI 0 "register_operand" "")
12598 (gt:QI (reg:CC 17) (const_int 0)))]
12599 ""
12600 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12601
12602(define_expand "sgtu"
12603 [(set (match_operand:QI 0 "register_operand" "")
12604 (gtu:QI (reg:CC 17) (const_int 0)))]
12605 ""
12606 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12607
12608(define_expand "slt"
12609 [(set (match_operand:QI 0 "register_operand" "")
12610 (lt:QI (reg:CC 17) (const_int 0)))]
12611 ""
12612 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12613
12614(define_expand "sltu"
12615 [(set (match_operand:QI 0 "register_operand" "")
12616 (ltu:QI (reg:CC 17) (const_int 0)))]
12617 ""
12618 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12619
12620(define_expand "sge"
12621 [(set (match_operand:QI 0 "register_operand" "")
12622 (ge:QI (reg:CC 17) (const_int 0)))]
12623 ""
12624 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12625
12626(define_expand "sgeu"
12627 [(set (match_operand:QI 0 "register_operand" "")
12628 (geu:QI (reg:CC 17) (const_int 0)))]
12629 ""
12630 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12631
12632(define_expand "sle"
12633 [(set (match_operand:QI 0 "register_operand" "")
12634 (le:QI (reg:CC 17) (const_int 0)))]
12635 ""
12636 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12637
12638(define_expand "sleu"
12639 [(set (match_operand:QI 0 "register_operand" "")
12640 (leu:QI (reg:CC 17) (const_int 0)))]
12641 ""
12642 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12643
12644(define_expand "sunordered"
12645 [(set (match_operand:QI 0 "register_operand" "")
12646 (unordered:QI (reg:CC 17) (const_int 0)))]
12647 "TARGET_80387 || TARGET_SSE"
12648 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12649
12650(define_expand "sordered"
12651 [(set (match_operand:QI 0 "register_operand" "")
12652 (ordered:QI (reg:CC 17) (const_int 0)))]
12653 "TARGET_80387"
12654 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12655
12656(define_expand "suneq"
12657 [(set (match_operand:QI 0 "register_operand" "")
12658 (uneq:QI (reg:CC 17) (const_int 0)))]
12659 "TARGET_80387 || TARGET_SSE"
12660 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12661
12662(define_expand "sunge"
12663 [(set (match_operand:QI 0 "register_operand" "")
12664 (unge:QI (reg:CC 17) (const_int 0)))]
12665 "TARGET_80387 || TARGET_SSE"
12666 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12667
12668(define_expand "sungt"
12669 [(set (match_operand:QI 0 "register_operand" "")
12670 (ungt:QI (reg:CC 17) (const_int 0)))]
12671 "TARGET_80387 || TARGET_SSE"
12672 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12673
12674(define_expand "sunle"
12675 [(set (match_operand:QI 0 "register_operand" "")
12676 (unle:QI (reg:CC 17) (const_int 0)))]
12677 "TARGET_80387 || TARGET_SSE"
12678 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12679
12680(define_expand "sunlt"
12681 [(set (match_operand:QI 0 "register_operand" "")
12682 (unlt:QI (reg:CC 17) (const_int 0)))]
12683 "TARGET_80387 || TARGET_SSE"
12684 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12685
12686(define_expand "sltgt"
12687 [(set (match_operand:QI 0 "register_operand" "")
12688 (ltgt:QI (reg:CC 17) (const_int 0)))]
12689 "TARGET_80387 || TARGET_SSE"
12690 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12691
12692(define_insn "*setcc_1"
12693 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12694 (match_operator:QI 1 "ix86_comparison_operator"
12695 [(reg 17) (const_int 0)]))]
12696 ""
12697 "set%C1\t%0"
12698 [(set_attr "type" "setcc")
12699 (set_attr "mode" "QI")])
12700
12701(define_insn "setcc_2"
12702 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12703 (match_operator:QI 1 "ix86_comparison_operator"
12704 [(reg 17) (const_int 0)]))]
12705 ""
12706 "set%C1\t%0"
12707 [(set_attr "type" "setcc")
12708 (set_attr "mode" "QI")])
12709
12710;; In general it is not safe to assume too much about CCmode registers,
12711;; so simplify-rtx stops when it sees a second one. Under certain
12712;; conditions this is safe on x86, so help combine not create
12713;;
12714;; seta %al
12715;; testb %al, %al
12716;; sete %al
12717
12718(define_split
12719 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12720 (ne:QI (match_operator 1 "ix86_comparison_operator"
12721 [(reg 17) (const_int 0)])
12722 (const_int 0)))]
12723 ""
12724 [(set (match_dup 0) (match_dup 1))]
12725{
12726 PUT_MODE (operands[1], QImode);
12727})
12728
12729(define_split
12730 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12731 (ne:QI (match_operator 1 "ix86_comparison_operator"
12732 [(reg 17) (const_int 0)])
12733 (const_int 0)))]
12734 ""
12735 [(set (match_dup 0) (match_dup 1))]
12736{
12737 PUT_MODE (operands[1], QImode);
12738})
12739
12740(define_split
12741 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12742 (eq:QI (match_operator 1 "ix86_comparison_operator"
12743 [(reg 17) (const_int 0)])
12744 (const_int 0)))]
12745 ""
12746 [(set (match_dup 0) (match_dup 1))]
12747{
12748 rtx new_op1 = copy_rtx (operands[1]);
12749 operands[1] = new_op1;
12750 PUT_MODE (new_op1, QImode);
12751 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12752 GET_MODE (XEXP (new_op1, 0))));
12753
12754 /* Make sure that (a) the CCmode we have for the flags is strong
12755 enough for the reversed compare or (b) we have a valid FP compare. */
12756 if (! ix86_comparison_operator (new_op1, VOIDmode))
12757 FAIL;
12758})
12759
12760(define_split
12761 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12762 (eq:QI (match_operator 1 "ix86_comparison_operator"
12763 [(reg 17) (const_int 0)])
12764 (const_int 0)))]
12765 ""
12766 [(set (match_dup 0) (match_dup 1))]
12767{
12768 rtx new_op1 = copy_rtx (operands[1]);
12769 operands[1] = new_op1;
12770 PUT_MODE (new_op1, QImode);
12771 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12772 GET_MODE (XEXP (new_op1, 0))));
12773
12774 /* Make sure that (a) the CCmode we have for the flags is strong
12775 enough for the reversed compare or (b) we have a valid FP compare. */
12776 if (! ix86_comparison_operator (new_op1, VOIDmode))
12777 FAIL;
12778})
12779
12780;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12781;; subsequent logical operations are used to imitate conditional moves.
12782;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12783;; it directly. Futher holding this value in pseudo register might bring
12784;; problem in implicit normalization in spill code.
12785;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12786;; instructions after reload by splitting the conditional move patterns.
12787
12788(define_insn "*sse_setccsf"
12789 [(set (match_operand:SF 0 "register_operand" "=x")
12790 (match_operator:SF 1 "sse_comparison_operator"
12791 [(match_operand:SF 2 "register_operand" "0")
12792 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12793 "TARGET_SSE && reload_completed"
12794 "cmp%D1ss\t{%3, %0|%0, %3}"
12795 [(set_attr "type" "sse")
12796 (set_attr "mode" "SF")])
12797
12798(define_insn "*sse_setccdf"
12799 [(set (match_operand:DF 0 "register_operand" "=Y")
12800 (match_operator:DF 1 "sse_comparison_operator"
12801 [(match_operand:DF 2 "register_operand" "0")
12802 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12803 "TARGET_SSE2 && reload_completed"
12804 "cmp%D1sd\t{%3, %0|%0, %3}"
12805 [(set_attr "type" "sse")
12806 (set_attr "mode" "DF")])
12807
12808;; Basic conditional jump instructions.
12809;; We ignore the overflow flag for signed branch instructions.
12810
12811;; For all bCOND expanders, also expand the compare or test insn that
12812;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12813
12814(define_expand "beq"
12815 [(set (pc)
12816 (if_then_else (match_dup 1)
12817 (label_ref (match_operand 0 "" ""))
12818 (pc)))]
12819 ""
12820 "ix86_expand_branch (EQ, operands[0]); DONE;")
12821
12822(define_expand "bne"
12823 [(set (pc)
12824 (if_then_else (match_dup 1)
12825 (label_ref (match_operand 0 "" ""))
12826 (pc)))]
12827 ""
12828 "ix86_expand_branch (NE, operands[0]); DONE;")
12829
12830(define_expand "bgt"
12831 [(set (pc)
12832 (if_then_else (match_dup 1)
12833 (label_ref (match_operand 0 "" ""))
12834 (pc)))]
12835 ""
12836 "ix86_expand_branch (GT, operands[0]); DONE;")
12837
12838(define_expand "bgtu"
12839 [(set (pc)
12840 (if_then_else (match_dup 1)
12841 (label_ref (match_operand 0 "" ""))
12842 (pc)))]
12843 ""
12844 "ix86_expand_branch (GTU, operands[0]); DONE;")
12845
12846(define_expand "blt"
12847 [(set (pc)
12848 (if_then_else (match_dup 1)
12849 (label_ref (match_operand 0 "" ""))
12850 (pc)))]
12851 ""
12852 "ix86_expand_branch (LT, operands[0]); DONE;")
12853
12854(define_expand "bltu"
12855 [(set (pc)
12856 (if_then_else (match_dup 1)
12857 (label_ref (match_operand 0 "" ""))
12858 (pc)))]
12859 ""
12860 "ix86_expand_branch (LTU, operands[0]); DONE;")
12861
12862(define_expand "bge"
12863 [(set (pc)
12864 (if_then_else (match_dup 1)
12865 (label_ref (match_operand 0 "" ""))
12866 (pc)))]
12867 ""
12868 "ix86_expand_branch (GE, operands[0]); DONE;")
12869
12870(define_expand "bgeu"
12871 [(set (pc)
12872 (if_then_else (match_dup 1)
12873 (label_ref (match_operand 0 "" ""))
12874 (pc)))]
12875 ""
12876 "ix86_expand_branch (GEU, operands[0]); DONE;")
12877
12878(define_expand "ble"
12879 [(set (pc)
12880 (if_then_else (match_dup 1)
12881 (label_ref (match_operand 0 "" ""))
12882 (pc)))]
12883 ""
12884 "ix86_expand_branch (LE, operands[0]); DONE;")
12885
12886(define_expand "bleu"
12887 [(set (pc)
12888 (if_then_else (match_dup 1)
12889 (label_ref (match_operand 0 "" ""))
12890 (pc)))]
12891 ""
12892 "ix86_expand_branch (LEU, operands[0]); DONE;")
12893
12894(define_expand "bunordered"
12895 [(set (pc)
12896 (if_then_else (match_dup 1)
12897 (label_ref (match_operand 0 "" ""))
12898 (pc)))]
12899 "TARGET_80387 || TARGET_SSE"
12900 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12901
12902(define_expand "bordered"
12903 [(set (pc)
12904 (if_then_else (match_dup 1)
12905 (label_ref (match_operand 0 "" ""))
12906 (pc)))]
12907 "TARGET_80387 || TARGET_SSE"
12908 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12909
12910(define_expand "buneq"
12911 [(set (pc)
12912 (if_then_else (match_dup 1)
12913 (label_ref (match_operand 0 "" ""))
12914 (pc)))]
12915 "TARGET_80387 || TARGET_SSE"
12916 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12917
12918(define_expand "bunge"
12919 [(set (pc)
12920 (if_then_else (match_dup 1)
12921 (label_ref (match_operand 0 "" ""))
12922 (pc)))]
12923 "TARGET_80387 || TARGET_SSE"
12924 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12925
12926(define_expand "bungt"
12927 [(set (pc)
12928 (if_then_else (match_dup 1)
12929 (label_ref (match_operand 0 "" ""))
12930 (pc)))]
12931 "TARGET_80387 || TARGET_SSE"
12932 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12933
12934(define_expand "bunle"
12935 [(set (pc)
12936 (if_then_else (match_dup 1)
12937 (label_ref (match_operand 0 "" ""))
12938 (pc)))]
12939 "TARGET_80387 || TARGET_SSE"
12940 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12941
12942(define_expand "bunlt"
12943 [(set (pc)
12944 (if_then_else (match_dup 1)
12945 (label_ref (match_operand 0 "" ""))
12946 (pc)))]
12947 "TARGET_80387 || TARGET_SSE"
12948 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12949
12950(define_expand "bltgt"
12951 [(set (pc)
12952 (if_then_else (match_dup 1)
12953 (label_ref (match_operand 0 "" ""))
12954 (pc)))]
12955 "TARGET_80387 || TARGET_SSE"
12956 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12957
12958(define_insn "*jcc_1"
12959 [(set (pc)
12960 (if_then_else (match_operator 1 "ix86_comparison_operator"
12961 [(reg 17) (const_int 0)])
12962 (label_ref (match_operand 0 "" ""))
12963 (pc)))]
12964 ""
12965 "%+j%C1\t%l0"
12966 [(set_attr "type" "ibr")
12967 (set (attr "prefix_0f")
12968 (if_then_else (and (ge (minus (match_dup 0) (pc))
12969 (const_int -128))
12970 (lt (minus (match_dup 0) (pc))
12971 (const_int 124)))
12972 (const_int 0)
12973 (const_int 1)))])
12974
12975(define_insn "*jcc_2"
12976 [(set (pc)
12977 (if_then_else (match_operator 1 "ix86_comparison_operator"
12978 [(reg 17) (const_int 0)])
12979 (pc)
12980 (label_ref (match_operand 0 "" ""))))]
12981 ""
12982 "%+j%c1\t%l0"
12983 [(set_attr "type" "ibr")
12984 (set (attr "prefix_0f")
12985 (if_then_else (and (ge (minus (match_dup 0) (pc))
12986 (const_int -128))
12987 (lt (minus (match_dup 0) (pc))
12988 (const_int 124)))
12989 (const_int 0)
12990 (const_int 1)))])
12991
12992;; In general it is not safe to assume too much about CCmode registers,
12993;; so simplify-rtx stops when it sees a second one. Under certain
12994;; conditions this is safe on x86, so help combine not create
12995;;
12996;; seta %al
12997;; testb %al, %al
12998;; je Lfoo
12999
13000(define_split
13001 [(set (pc)
13002 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13003 [(reg 17) (const_int 0)])
13004 (const_int 0))
13005 (label_ref (match_operand 1 "" ""))
13006 (pc)))]
13007 ""
13008 [(set (pc)
13009 (if_then_else (match_dup 0)
13010 (label_ref (match_dup 1))
13011 (pc)))]
13012{
13013 PUT_MODE (operands[0], VOIDmode);
13014})
13015
13016(define_split
13017 [(set (pc)
13018 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13019 [(reg 17) (const_int 0)])
13020 (const_int 0))
13021 (label_ref (match_operand 1 "" ""))
13022 (pc)))]
13023 ""
13024 [(set (pc)
13025 (if_then_else (match_dup 0)
13026 (label_ref (match_dup 1))
13027 (pc)))]
13028{
13029 rtx new_op0 = copy_rtx (operands[0]);
13030 operands[0] = new_op0;
13031 PUT_MODE (new_op0, VOIDmode);
13032 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13033 GET_MODE (XEXP (new_op0, 0))));
13034
13035 /* Make sure that (a) the CCmode we have for the flags is strong
13036 enough for the reversed compare or (b) we have a valid FP compare. */
13037 if (! ix86_comparison_operator (new_op0, VOIDmode))
13038 FAIL;
13039})
13040
13041;; Define combination compare-and-branch fp compare instructions to use
13042;; during early optimization. Splitting the operation apart early makes
13043;; for bad code when we want to reverse the operation.
13044
13045(define_insn "*fp_jcc_1"
13046 [(set (pc)
13047 (if_then_else (match_operator 0 "comparison_operator"
13048 [(match_operand 1 "register_operand" "f")
13049 (match_operand 2 "register_operand" "f")])
13050 (label_ref (match_operand 3 "" ""))
13051 (pc)))
13052 (clobber (reg:CCFP 18))
13053 (clobber (reg:CCFP 17))]
13054 "TARGET_CMOVE && TARGET_80387
13055 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13056 && FLOAT_MODE_P (GET_MODE (operands[1]))
13057 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13058 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13059 "#")
13060
13061(define_insn "*fp_jcc_1_sse"
13062 [(set (pc)
13063 (if_then_else (match_operator 0 "comparison_operator"
13064 [(match_operand 1 "register_operand" "f#x,x#f")
13065 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13066 (label_ref (match_operand 3 "" ""))
13067 (pc)))
13068 (clobber (reg:CCFP 18))
13069 (clobber (reg:CCFP 17))]
13070 "TARGET_80387
13071 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13072 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13073 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13074 "#")
13075
13076(define_insn "*fp_jcc_1_sse_only"
13077 [(set (pc)
13078 (if_then_else (match_operator 0 "comparison_operator"
13079 [(match_operand 1 "register_operand" "x")
13080 (match_operand 2 "nonimmediate_operand" "xm")])
13081 (label_ref (match_operand 3 "" ""))
13082 (pc)))
13083 (clobber (reg:CCFP 18))
13084 (clobber (reg:CCFP 17))]
13085 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13086 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13087 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13088 "#")
13089
13090(define_insn "*fp_jcc_2"
13091 [(set (pc)
13092 (if_then_else (match_operator 0 "comparison_operator"
13093 [(match_operand 1 "register_operand" "f")
13094 (match_operand 2 "register_operand" "f")])
13095 (pc)
13096 (label_ref (match_operand 3 "" ""))))
13097 (clobber (reg:CCFP 18))
13098 (clobber (reg:CCFP 17))]
13099 "TARGET_CMOVE && TARGET_80387
13100 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13101 && FLOAT_MODE_P (GET_MODE (operands[1]))
13102 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13103 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13104 "#")
13105
13106(define_insn "*fp_jcc_2_sse"
13107 [(set (pc)
13108 (if_then_else (match_operator 0 "comparison_operator"
13109 [(match_operand 1 "register_operand" "f#x,x#f")
13110 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13111 (pc)
13112 (label_ref (match_operand 3 "" ""))))
13113 (clobber (reg:CCFP 18))
13114 (clobber (reg:CCFP 17))]
13115 "TARGET_80387
13116 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13117 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13118 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13119 "#")
13120
13121(define_insn "*fp_jcc_2_sse_only"
13122 [(set (pc)
13123 (if_then_else (match_operator 0 "comparison_operator"
13124 [(match_operand 1 "register_operand" "x")
13125 (match_operand 2 "nonimmediate_operand" "xm")])
13126 (pc)
13127 (label_ref (match_operand 3 "" ""))))
13128 (clobber (reg:CCFP 18))
13129 (clobber (reg:CCFP 17))]
13130 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13131 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13132 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13133 "#")
13134
13135(define_insn "*fp_jcc_3"
13136 [(set (pc)
13137 (if_then_else (match_operator 0 "comparison_operator"
13138 [(match_operand 1 "register_operand" "f")
13139 (match_operand 2 "nonimmediate_operand" "fm")])
13140 (label_ref (match_operand 3 "" ""))
13141 (pc)))
13142 (clobber (reg:CCFP 18))
13143 (clobber (reg:CCFP 17))
13144 (clobber (match_scratch:HI 4 "=a"))]
13145 "TARGET_80387
13146 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13147 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13148 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13149 && SELECT_CC_MODE (GET_CODE (operands[0]),
13150 operands[1], operands[2]) == CCFPmode
13151 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13152 "#")
13153
13154(define_insn "*fp_jcc_4"
13155 [(set (pc)
13156 (if_then_else (match_operator 0 "comparison_operator"
13157 [(match_operand 1 "register_operand" "f")
13158 (match_operand 2 "nonimmediate_operand" "fm")])
13159 (pc)
13160 (label_ref (match_operand 3 "" ""))))
13161 (clobber (reg:CCFP 18))
13162 (clobber (reg:CCFP 17))
13163 (clobber (match_scratch:HI 4 "=a"))]
13164 "TARGET_80387
13165 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13166 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13167 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13168 && SELECT_CC_MODE (GET_CODE (operands[0]),
13169 operands[1], operands[2]) == CCFPmode
13170 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13171 "#")
13172
13173(define_insn "*fp_jcc_5"
13174 [(set (pc)
13175 (if_then_else (match_operator 0 "comparison_operator"
13176 [(match_operand 1 "register_operand" "f")
13177 (match_operand 2 "register_operand" "f")])
13178 (label_ref (match_operand 3 "" ""))
13179 (pc)))
13180 (clobber (reg:CCFP 18))
13181 (clobber (reg:CCFP 17))
13182 (clobber (match_scratch:HI 4 "=a"))]
13183 "TARGET_80387
13184 && FLOAT_MODE_P (GET_MODE (operands[1]))
13185 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13186 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13187 "#")
13188
13189(define_insn "*fp_jcc_6"
13190 [(set (pc)
13191 (if_then_else (match_operator 0 "comparison_operator"
13192 [(match_operand 1 "register_operand" "f")
13193 (match_operand 2 "register_operand" "f")])
13194 (pc)
13195 (label_ref (match_operand 3 "" ""))))
13196 (clobber (reg:CCFP 18))
13197 (clobber (reg:CCFP 17))
13198 (clobber (match_scratch:HI 4 "=a"))]
13199 "TARGET_80387
13200 && FLOAT_MODE_P (GET_MODE (operands[1]))
13201 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13202 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13203 "#")
13204
13205(define_split
13206 [(set (pc)
13207 (if_then_else (match_operator 0 "comparison_operator"
13208 [(match_operand 1 "register_operand" "")
13209 (match_operand 2 "nonimmediate_operand" "")])
13210 (match_operand 3 "" "")
13211 (match_operand 4 "" "")))
13212 (clobber (reg:CCFP 18))
13213 (clobber (reg:CCFP 17))]
13214 "reload_completed"
13215 [(const_int 0)]
13216{
13217 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13218 operands[3], operands[4], NULL_RTX);
13219 DONE;
13220})
13221
13222(define_split
13223 [(set (pc)
13224 (if_then_else (match_operator 0 "comparison_operator"
13225 [(match_operand 1 "register_operand" "")
13226 (match_operand 2 "nonimmediate_operand" "")])
13227 (match_operand 3 "" "")
13228 (match_operand 4 "" "")))
13229 (clobber (reg:CCFP 18))
13230 (clobber (reg:CCFP 17))
13231 (clobber (match_scratch:HI 5 "=a"))]
13232 "reload_completed"
13233 [(set (pc)
13234 (if_then_else (match_dup 6)
13235 (match_dup 3)
13236 (match_dup 4)))]
13237{
13238 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13239 operands[3], operands[4], operands[5]);
13240 DONE;
13241})
13242
13243;; Unconditional and other jump instructions
13244
13245(define_insn "jump"
13246 [(set (pc)
13247 (label_ref (match_operand 0 "" "")))]
13248 ""
13249 "jmp\t%l0"
13250 [(set_attr "type" "ibr")])
13251
13252(define_expand "indirect_jump"
13253 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13254 ""
13255 "")
13256
13257(define_insn "*indirect_jump"
13258 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13259 "!TARGET_64BIT"
13260 "jmp\t%A0"
13261 [(set_attr "type" "ibr")
13262 (set_attr "length_immediate" "0")])
13263
13264(define_insn "*indirect_jump_rtx64"
13265 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13266 "TARGET_64BIT"
13267 "jmp\t%A0"
13268 [(set_attr "type" "ibr")
13269 (set_attr "length_immediate" "0")])
13270
13271(define_expand "tablejump"
13272 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13273 (use (label_ref (match_operand 1 "" "")))])]
13274 ""
13275{
13276 /* In PIC mode, the table entries are stored GOT-relative. Convert
13277 the relative address to an absolute address. */
13278 if (flag_pic)
13279 {
13280 if (TARGET_64BIT)
13281 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
13282 gen_rtx_LABEL_REF (Pmode, operands[1]),
13283 NULL_RTX, 0,
13284 OPTAB_DIRECT);
13285 else if (HAVE_AS_GOTOFF_IN_DATA)
13286 {
13287 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
13288 pic_offset_table_rtx, NULL_RTX,
13289 1, OPTAB_DIRECT);
13290 current_function_uses_pic_offset_table = 1;
13291 }
13292 else
13293 {
13294 operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
13295 operands[0], NULL_RTX, 1,
13296 OPTAB_DIRECT);
13297 current_function_uses_pic_offset_table = 1;
13298 }
13299 }
13300})
13301
13302(define_insn "*tablejump_1"
13303 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13304 (use (label_ref (match_operand 1 "" "")))]
13305 "!TARGET_64BIT"
13306 "jmp\t%A0"
13307 [(set_attr "type" "ibr")
13308 (set_attr "length_immediate" "0")])
13309
13310(define_insn "*tablejump_1_rtx64"
13311 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13312 (use (label_ref (match_operand 1 "" "")))]
13313 "TARGET_64BIT"
13314 "jmp\t%A0"
13315 [(set_attr "type" "ibr")
13316 (set_attr "length_immediate" "0")])
13317
13318;; Loop instruction
13319;;
13320;; This is all complicated by the fact that since this is a jump insn
13321;; we must handle our own reloads.
13322
13323(define_expand "doloop_end"
13324 [(use (match_operand 0 "" "")) ; loop pseudo
13325 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13326 (use (match_operand 2 "" "")) ; max iterations
13327 (use (match_operand 3 "" "")) ; loop level
13328 (use (match_operand 4 "" ""))] ; label
13329 "!TARGET_64BIT && TARGET_USE_LOOP"
13330 "
13331{
13332 /* Only use cloop on innermost loops. */
13333 if (INTVAL (operands[3]) > 1)
13334 FAIL;
13335 if (GET_MODE (operands[0]) != SImode)
13336 FAIL;
13337 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13338 operands[0]));
13339 DONE;
13340}")
13341
13342(define_insn "doloop_end_internal"
13343 [(set (pc)
13344 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13345 (const_int 1))
13346 (label_ref (match_operand 0 "" ""))
13347 (pc)))
13348 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13349 (plus:SI (match_dup 1)
13350 (const_int -1)))
13351 (clobber (match_scratch:SI 3 "=X,X,r"))
13352 (clobber (reg:CC 17))]
13353 "!TARGET_64BIT && TARGET_USE_LOOP"
13354{
13355 if (which_alternative != 0)
13356 return "#";
13357 if (get_attr_length (insn) == 2)
13358 return "%+loop\t%l0";
13359 else
13360 return "dec{l}\t%1\;%+jne\t%l0";
13361}
13362 [(set_attr "ppro_uops" "many")
13363 (set (attr "type")
13364 (if_then_else (and (eq_attr "alternative" "0")
13365 (and (ge (minus (match_dup 0) (pc))
13366 (const_int -128))
13367 (lt (minus (match_dup 0) (pc))
13368 (const_int 124))))
13369 (const_string "ibr")
13370 (const_string "multi")))])
13371
13372(define_split
13373 [(set (pc)
13374 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13375 (const_int 1))
13376 (match_operand 0 "" "")
13377 (pc)))
13378 (set (match_dup 1)
13379 (plus:SI (match_dup 1)
13380 (const_int -1)))
13381 (clobber (match_scratch:SI 2 ""))
13382 (clobber (reg:CC 17))]
13383 "!TARGET_64BIT && TARGET_USE_LOOP
13384 && reload_completed
13385 && REGNO (operands[1]) != 2"
13386 [(parallel [(set (reg:CCZ 17)
13387 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13388 (const_int 0)))
13389 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13390 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13391 (match_dup 0)
13392 (pc)))]
13393 "")
13394
13395(define_split
13396 [(set (pc)
13397 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13398 (const_int 1))
13399 (match_operand 0 "" "")
13400 (pc)))
13401 (set (match_operand:SI 2 "nonimmediate_operand" "")
13402 (plus:SI (match_dup 1)
13403 (const_int -1)))
13404 (clobber (match_scratch:SI 3 ""))
13405 (clobber (reg:CC 17))]
13406 "!TARGET_64BIT && TARGET_USE_LOOP
13407 && reload_completed
13408 && (! REG_P (operands[2])
13409 || ! rtx_equal_p (operands[1], operands[2]))"
13410 [(set (match_dup 3) (match_dup 1))
13411 (parallel [(set (reg:CCZ 17)
13412 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13413 (const_int 0)))
13414 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13415 (set (match_dup 2) (match_dup 3))
13416 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13417 (match_dup 0)
13418 (pc)))]
13419 "")
13420
13421;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13422
13423(define_peephole2
13424 [(set (reg 17) (match_operand 0 "" ""))
13425 (set (match_operand:QI 1 "register_operand" "")
13426 (match_operator:QI 2 "ix86_comparison_operator"
13427 [(reg 17) (const_int 0)]))
13428 (set (match_operand 3 "q_regs_operand" "")
13429 (zero_extend (match_dup 1)))]
13430 "(peep2_reg_dead_p (3, operands[1])
13431 || operands_match_p (operands[1], operands[3]))
13432 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13433 [(set (match_dup 4) (match_dup 0))
13434 (set (strict_low_part (match_dup 5))
13435 (match_dup 2))]
13436{
13437 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13438 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13439 ix86_expand_clear (operands[3]);
13440})
13441
13442;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13443
13444(define_peephole2
13445 [(set (reg 17) (match_operand 0 "" ""))
13446 (set (match_operand:QI 1 "register_operand" "")
13447 (match_operator:QI 2 "ix86_comparison_operator"
13448 [(reg 17) (const_int 0)]))
13449 (parallel [(set (match_operand 3 "q_regs_operand" "")
13450 (zero_extend (match_dup 1)))
13451 (clobber (reg:CC 17))])]
13452 "(peep2_reg_dead_p (3, operands[1])
13453 || operands_match_p (operands[1], operands[3]))
13454 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13455 [(set (match_dup 4) (match_dup 0))
13456 (set (strict_low_part (match_dup 5))
13457 (match_dup 2))]
13458{
13459 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13460 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13461 ix86_expand_clear (operands[3]);
13462})
13463
13464;; Call instructions.
13465
13466;; The predicates normally associated with named expanders are not properly
13467;; checked for calls. This is a bug in the generic code, but it isn't that
13468;; easy to fix. Ignore it for now and be prepared to fix things up.
13469
13470;; Call subroutine returning no value.
13471
13472(define_expand "call_pop"
13473 [(parallel [(call (match_operand:QI 0 "" "")
13474 (match_operand:SI 1 "" ""))
13475 (set (reg:SI 7)
13476 (plus:SI (reg:SI 7)
13477 (match_operand:SI 3 "" "")))])]
13478 "!TARGET_64BIT"
13479{
13480 if (operands[3] == const0_rtx)
13481 {
13482 emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
13483 DONE;
13484 }
13485 /* Static functions and indirect calls don't need
13486 current_function_uses_pic_offset_table. */
13487 if (flag_pic
13488 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13489 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13490 current_function_uses_pic_offset_table = 1;
13491 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13492 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13493 if (TARGET_64BIT)
13494 abort();
13495})
13496
13497(define_insn "*call_pop_0"
13498 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13499 (match_operand:SI 1 "" ""))
13500 (set (reg:SI 7) (plus:SI (reg:SI 7)
13501 (match_operand:SI 2 "immediate_operand" "")))]
13502 "!TARGET_64BIT"
13503{
13504 if (SIBLING_CALL_P (insn))
13505 return "jmp\t%P0";
13506 else
13507 return "call\t%P0";
13508}
13509 [(set_attr "type" "call")])
13510
13511(define_insn "*call_pop_1"
13512 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13513 (match_operand:SI 1 "" ""))
13514 (set (reg:SI 7) (plus:SI (reg:SI 7)
13515 (match_operand:SI 2 "immediate_operand" "i")))]
13516 "!TARGET_64BIT"
13517{
13518 if (constant_call_address_operand (operands[0], Pmode))
13519 {
13520 if (SIBLING_CALL_P (insn))
13521 return "jmp\t%P0";
13522 else
13523 return "call\t%P0";
13524 }
13525 if (SIBLING_CALL_P (insn))
13526 return "jmp\t%A0";
13527 else
13528 return "call\t%A0";
13529}
13530 [(set_attr "type" "call")])
13531
13532(define_expand "call"
13533 [(call (match_operand:QI 0 "" "")
13534 (match_operand 1 "" ""))
13535 (use (match_operand 2 "" ""))]
13536 ;; Operand 1 not used on the i386.
13537 ""
13538{
13539 rtx insn;
13540 /* Static functions and indirect calls don't need
13541 current_function_uses_pic_offset_table. */
13542 if (flag_pic
13543 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13544 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13545 current_function_uses_pic_offset_table = 1;
13546
13547 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13548 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13549 if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
13550 {
13551 rtx reg = gen_rtx_REG (QImode, 0);
13552 emit_move_insn (reg, operands[2]);
13553 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13554 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13555 DONE;
13556 }
13557 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13558 DONE;
13559})
13560
13561(define_expand "call_exp"
13562 [(call (match_operand:QI 0 "" "")
13563 (match_operand 1 "" ""))]
13564 ""
13565 "")
13566
13567(define_insn "*call_0"
13568 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13569 (match_operand 1 "" ""))]
13570 ""
13571{
13572 if (SIBLING_CALL_P (insn))
13573 return "jmp\t%P0";
13574 else
13575 return "call\t%P0";
13576}
13577 [(set_attr "type" "call")])
13578
13579(define_insn "*call_1"
13580 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13581 (match_operand 1 "" ""))]
13582 "!TARGET_64BIT"
13583{
13584 if (constant_call_address_operand (operands[0], QImode))
13585 {
13586 if (SIBLING_CALL_P (insn))
13587 return "jmp\t%P0";
13588 else
13589 return "call\t%P0";
13590 }
13591 if (SIBLING_CALL_P (insn))
13592 return "jmp\t%A0";
13593 else
13594 return "call\t%A0";
13595}
13596 [(set_attr "type" "call")])
13597
13598(define_insn "*call_1_rex64"
13599 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13600 (match_operand 1 "" ""))]
13601 "TARGET_64BIT"
13602{
13603 if (constant_call_address_operand (operands[0], QImode))
13604 {
13605 if (SIBLING_CALL_P (insn))
13606 return "jmp\t%P0";
13607 else
13608 return "call\t%P0";
13609 }
13610 if (SIBLING_CALL_P (insn))
13611 return "jmp\t%A0";
13612 else
13613 return "call\t%A0";
13614}
13615 [(set_attr "type" "call")])
13616
13617;; Call subroutine, returning value in operand 0
13618;; (which must be a hard register).
13619
13620(define_expand "call_value_pop"
13621 [(parallel [(set (match_operand 0 "" "")
13622 (call (match_operand:QI 1 "" "")
13623 (match_operand:SI 2 "" "")))
13624 (set (reg:SI 7)
13625 (plus:SI (reg:SI 7)
13626 (match_operand:SI 4 "" "")))])]
13627 "!TARGET_64BIT"
13628{
13629 if (operands[4] == const0_rtx)
13630 {
13631 emit_insn (gen_call_value (operands[0], operands[1], operands[2],
13632 constm1_rtx));
13633 DONE;
13634 }
13635 /* Static functions and indirect calls don't need
13636 current_function_uses_pic_offset_table. */
13637 if (flag_pic
13638 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13639 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13640 current_function_uses_pic_offset_table = 1;
13641 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13642 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13643})
13644
13645(define_expand "call_value"
13646 [(set (match_operand 0 "" "")
13647 (call (match_operand:QI 1 "" "")
13648 (match_operand:SI 2 "" "")))
13649 (use (match_operand:SI 3 "" ""))]
13650 ;; Operand 2 not used on the i386.
13651 ""
13652{
13653 rtx insn;
13654 /* Static functions and indirect calls don't need
13655 current_function_uses_pic_offset_table. */
13656 if (flag_pic
13657 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13658 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13659 current_function_uses_pic_offset_table = 1;
13660 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13661 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13662 if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
13663 {
13664 rtx reg = gen_rtx_REG (QImode, 0);
13665 emit_move_insn (reg, operands[3]);
13666 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13667 operands[2]));
13668 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13669 DONE;
13670 }
13671 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13672 operands[2]));
13673 DONE;
13674})
13675
13676(define_expand "call_value_exp"
13677 [(set (match_operand 0 "" "")
13678 (call (match_operand:QI 1 "" "")
13679 (match_operand:SI 2 "" "")))]
13680 ""
13681 "")
13682
13683;; Call subroutine returning any type.
13684
13685(define_expand "untyped_call"
13686 [(parallel [(call (match_operand 0 "" "")
13687 (const_int 0))
13688 (match_operand 1 "" "")
13689 (match_operand 2 "" "")])]
13690 ""
13691{
13692 int i;
13693
13694 /* In order to give reg-stack an easier job in validating two
13695 coprocessor registers as containing a possible return value,
13696 simply pretend the untyped call returns a complex long double
13697 value. */
13698
13544 emit_call_insn (TARGET_80387
13699 emit_call_insn (TARGET_FLOAT_RETURNS_IN_80387
13545 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
13546 operands[0], const0_rtx,
13547 GEN_INT (SSE_REGPARM_MAX - 1))
13548 : gen_call (operands[0], const0_rtx,
13549 GEN_INT (SSE_REGPARM_MAX - 1)));
13550
13551 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13552 {
13553 rtx set = XVECEXP (operands[2], 0, i);
13554 emit_move_insn (SET_DEST (set), SET_SRC (set));
13555 }
13556
13557 /* The optimizer does not know that the call sets the function value
13558 registers we stored in the result block. We avoid problems by
13559 claiming that all hard registers are used and clobbered at this
13560 point. */
13561 emit_insn (gen_blockage ());
13562
13563 DONE;
13564})
13565
13566;; Prologue and epilogue instructions
13567
13568;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13569;; all of memory. This blocks insns from being moved across this point.
13570
13571(define_insn "blockage"
13572 [(unspec_volatile [(const_int 0)] 0)]
13573 ""
13574 ""
13575 [(set_attr "length" "0")])
13576
13577;; Insn emitted into the body of a function to return from a function.
13578;; This is only done if the function's epilogue is known to be simple.
13579;; See comments for ix86_can_use_return_insn_p in i386.c.
13580
13581(define_expand "return"
13582 [(return)]
13583 "ix86_can_use_return_insn_p ()"
13584{
13585 if (current_function_pops_args)
13586 {
13587 rtx popc = GEN_INT (current_function_pops_args);
13588 emit_jump_insn (gen_return_pop_internal (popc));
13589 DONE;
13590 }
13591})
13592
13593(define_insn "return_internal"
13594 [(return)]
13595 "reload_completed"
13596 "ret"
13597 [(set_attr "length" "1")
13598 (set_attr "length_immediate" "0")
13599 (set_attr "modrm" "0")])
13600
13601(define_insn "return_pop_internal"
13602 [(return)
13603 (use (match_operand:SI 0 "const_int_operand" ""))]
13604 "reload_completed"
13605 "ret\t%0"
13606 [(set_attr "length" "3")
13607 (set_attr "length_immediate" "2")
13608 (set_attr "modrm" "0")])
13609
13610(define_insn "return_indirect_internal"
13611 [(return)
13612 (use (match_operand:SI 0 "register_operand" "r"))]
13613 "reload_completed"
13614 "jmp\t%A0"
13615 [(set_attr "type" "ibr")
13616 (set_attr "length_immediate" "0")])
13617
13618(define_insn "nop"
13619 [(const_int 0)]
13620 ""
13621 "nop"
13622 [(set_attr "length" "1")
13623 (set_attr "length_immediate" "0")
13624 (set_attr "modrm" "0")
13625 (set_attr "ppro_uops" "one")])
13626
13627(define_expand "prologue"
13628 [(const_int 1)]
13629 ""
13630 "ix86_expand_prologue (); DONE;")
13631
13632(define_insn "prologue_set_got"
13633 [(set (match_operand:SI 0 "register_operand" "=r")
13634 (unspec_volatile:SI
13635 [(plus:SI (match_dup 0)
13636 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
13637 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
13638 (clobber (reg:CC 17))]
13639 "!TARGET_64BIT"
13640{
13641 if (GET_CODE (operands[2]) == LABEL_REF)
13642 operands[2] = XEXP (operands[2], 0);
13643 if (TARGET_DEEP_BRANCH_PREDICTION)
13644 return "add{l}\t{%1, %0|%0, %1}";
13645 else
13646 return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
13647}
13648 [(set_attr "type" "alu")
13649 ; Since this insn may have two constant operands, we must set the
13650 ; length manually.
13651 (set_attr "length_immediate" "4")
13652 (set_attr "mode" "SI")])
13653
13654(define_insn "prologue_get_pc"
13655 [(set (match_operand:SI 0 "register_operand" "=r")
13656 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
13657 "!TARGET_64BIT"
13658{
13659 if (GET_CODE (operands[1]) == LABEL_REF)
13660 operands[1] = XEXP (operands[1], 0);
13661 output_asm_insn ("call\t%X1", operands);
13662 if (! TARGET_DEEP_BRANCH_PREDICTION)
13663 {
13664 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
13665 CODE_LABEL_NUMBER (operands[1]));
13666 }
13667 RET;
13668}
13669 [(set_attr "type" "multi")])
13670
13671(define_expand "epilogue"
13672 [(const_int 1)]
13673 ""
13674 "ix86_expand_epilogue (1); DONE;")
13675
13676(define_expand "sibcall_epilogue"
13677 [(const_int 1)]
13678 ""
13679 "ix86_expand_epilogue (0); DONE;")
13680
13681(define_expand "eh_return"
13682 [(use (match_operand 0 "register_operand" ""))
13683 (use (match_operand 1 "register_operand" ""))]
13684 ""
13685{
13686 rtx tmp, sa = operands[0], ra = operands[1];
13687
13688 /* Tricky bit: we write the address of the handler to which we will
13689 be returning into someone else's stack frame, one word below the
13690 stack address we wish to restore. */
13691 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13692 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13693 tmp = gen_rtx_MEM (Pmode, tmp);
13694 emit_move_insn (tmp, ra);
13695
13696 if (Pmode == SImode)
13697 emit_insn (gen_eh_return_si (sa));
13698 else
13699 emit_insn (gen_eh_return_di (sa));
13700 emit_barrier ();
13701 DONE;
13702})
13703
13704(define_insn_and_split "eh_return_si"
13705 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
13706 "!TARGET_64BIT"
13707 "#"
13708 "reload_completed"
13709 [(const_int 1)]
13710 "ix86_expand_epilogue (2); DONE;")
13711
13712(define_insn_and_split "eh_return_di"
13713 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
13714 "TARGET_64BIT"
13715 "#"
13716 "reload_completed"
13717 [(const_int 1)]
13718 "ix86_expand_epilogue (2); DONE;")
13719
13720(define_insn "leave"
13721 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13722 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13723 (clobber (mem:BLK (scratch)))]
13724 "!TARGET_64BIT"
13725 "leave"
13726 [(set_attr "length_immediate" "0")
13727 (set_attr "length" "1")
13728 (set_attr "modrm" "0")
13729 (set_attr "modrm" "0")
13730 (set_attr "athlon_decode" "vector")
13731 (set_attr "ppro_uops" "few")])
13732
13733(define_insn "leave_rex64"
13734 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13735 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13736 (clobber (mem:BLK (scratch)))]
13737 "TARGET_64BIT"
13738 "leave"
13739 [(set_attr "length_immediate" "0")
13740 (set_attr "length" "1")
13741 (set_attr "modrm" "0")
13742 (set_attr "modrm" "0")
13743 (set_attr "athlon_decode" "vector")
13744 (set_attr "ppro_uops" "few")])
13745
13746(define_expand "ffssi2"
13747 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13748 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13749 ""
13750{
13751 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13752 rtx in = operands[1];
13753
13754 if (TARGET_CMOVE)
13755 {
13756 emit_move_insn (tmp, constm1_rtx);
13757 emit_insn (gen_ffssi_1 (out, in));
13758 emit_insn (gen_rtx_SET (VOIDmode, out,
13759 gen_rtx_IF_THEN_ELSE (SImode,
13760 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13761 const0_rtx),
13762 tmp,
13763 out)));
13764 emit_insn (gen_addsi3 (out, out, const1_rtx));
13765 emit_move_insn (operands[0], out);
13766 }
13767
13768 /* Pentium bsf instruction is extremly slow. The following code is
13769 recommended by the Intel Optimizing Manual as a reasonable replacement:
13770 TEST EAX,EAX
13771 JZ SHORT BS2
13772 XOR ECX,ECX
13773 MOV DWORD PTR [TEMP+4],ECX
13774 SUB ECX,EAX
13775 AND EAX,ECX
13776 MOV DWORD PTR [TEMP],EAX
13777 FILD QWORD PTR [TEMP]
13778 FSTP QWORD PTR [TEMP]
13779 WAIT ; WAIT only needed for compatibility with
13780 ; earlier processors
13781 MOV ECX, DWORD PTR [TEMP+4]
13782 SHR ECX,20
13783 SUB ECX,3FFH
13784 TEST EAX,EAX ; clear zero flag
13785 BS2:
13786 Following piece of code expand ffs to similar beast.
13787 */
13788
13789 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13790 {
13791 rtx label = gen_label_rtx ();
13792 rtx lo, hi;
13793 rtx mem = assign_386_stack_local (DImode, 0);
13794 rtx fptmp = gen_reg_rtx (DFmode);
13795 split_di (&mem, 1, &lo, &hi);
13796
13797 emit_move_insn (out, const0_rtx);
13798
13799 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
13800
13801 emit_move_insn (hi, out);
13802 emit_insn (gen_subsi3 (out, out, in));
13803 emit_insn (gen_andsi3 (out, out, in));
13804 emit_move_insn (lo, out);
13805 emit_insn (gen_floatdidf2 (fptmp,mem));
13806 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13807 emit_move_insn (out, hi);
13808 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
13809 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
13810
13811 emit_label (label);
13812 LABEL_NUSES (label) = 1;
13813
13814 emit_move_insn (operands[0], out);
13815 }
13816 else
13817 {
13818 emit_move_insn (tmp, const0_rtx);
13819 emit_insn (gen_ffssi_1 (out, in));
13820 emit_insn (gen_rtx_SET (VOIDmode,
13821 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
13822 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
13823 const0_rtx)));
13824 emit_insn (gen_negsi2 (tmp, tmp));
13825 emit_insn (gen_iorsi3 (out, out, tmp));
13826 emit_insn (gen_addsi3 (out, out, const1_rtx));
13827 emit_move_insn (operands[0], out);
13828 }
13829 DONE;
13830})
13831
13832(define_insn "ffssi_1"
13833 [(set (reg:CCZ 17)
13834 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13835 (const_int 0)))
13836 (set (match_operand:SI 0 "register_operand" "=r")
13837 (unspec:SI [(match_dup 1)] 5))]
13838 ""
13839 "bsf{l}\t{%1, %0|%0, %1}"
13840 [(set_attr "prefix_0f" "1")
13841 (set_attr "ppro_uops" "few")])
13842
13843;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13844;; and slower than the two-byte movzx insn needed to do the work in SImode.
13845
13846;; These patterns match the binary 387 instructions for addM3, subM3,
13847;; mulM3 and divM3. There are three patterns for each of DFmode and
13848;; SFmode. The first is the normal insn, the second the same insn but
13849;; with one operand a conversion, and the third the same insn but with
13850;; the other operand a conversion. The conversion may be SFmode or
13851;; SImode if the target mode DFmode, but only SImode if the target mode
13852;; is SFmode.
13853
13854;; Gcc is slightly more smart about handling normal two address instructions
13855;; so use special patterns for add and mull.
13856(define_insn "*fop_sf_comm_nosse"
13857 [(set (match_operand:SF 0 "register_operand" "=f")
13858 (match_operator:SF 3 "binary_fp_operator"
13700 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
13701 operands[0], const0_rtx,
13702 GEN_INT (SSE_REGPARM_MAX - 1))
13703 : gen_call (operands[0], const0_rtx,
13704 GEN_INT (SSE_REGPARM_MAX - 1)));
13705
13706 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13707 {
13708 rtx set = XVECEXP (operands[2], 0, i);
13709 emit_move_insn (SET_DEST (set), SET_SRC (set));
13710 }
13711
13712 /* The optimizer does not know that the call sets the function value
13713 registers we stored in the result block. We avoid problems by
13714 claiming that all hard registers are used and clobbered at this
13715 point. */
13716 emit_insn (gen_blockage ());
13717
13718 DONE;
13719})
13720
13721;; Prologue and epilogue instructions
13722
13723;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13724;; all of memory. This blocks insns from being moved across this point.
13725
13726(define_insn "blockage"
13727 [(unspec_volatile [(const_int 0)] 0)]
13728 ""
13729 ""
13730 [(set_attr "length" "0")])
13731
13732;; Insn emitted into the body of a function to return from a function.
13733;; This is only done if the function's epilogue is known to be simple.
13734;; See comments for ix86_can_use_return_insn_p in i386.c.
13735
13736(define_expand "return"
13737 [(return)]
13738 "ix86_can_use_return_insn_p ()"
13739{
13740 if (current_function_pops_args)
13741 {
13742 rtx popc = GEN_INT (current_function_pops_args);
13743 emit_jump_insn (gen_return_pop_internal (popc));
13744 DONE;
13745 }
13746})
13747
13748(define_insn "return_internal"
13749 [(return)]
13750 "reload_completed"
13751 "ret"
13752 [(set_attr "length" "1")
13753 (set_attr "length_immediate" "0")
13754 (set_attr "modrm" "0")])
13755
13756(define_insn "return_pop_internal"
13757 [(return)
13758 (use (match_operand:SI 0 "const_int_operand" ""))]
13759 "reload_completed"
13760 "ret\t%0"
13761 [(set_attr "length" "3")
13762 (set_attr "length_immediate" "2")
13763 (set_attr "modrm" "0")])
13764
13765(define_insn "return_indirect_internal"
13766 [(return)
13767 (use (match_operand:SI 0 "register_operand" "r"))]
13768 "reload_completed"
13769 "jmp\t%A0"
13770 [(set_attr "type" "ibr")
13771 (set_attr "length_immediate" "0")])
13772
13773(define_insn "nop"
13774 [(const_int 0)]
13775 ""
13776 "nop"
13777 [(set_attr "length" "1")
13778 (set_attr "length_immediate" "0")
13779 (set_attr "modrm" "0")
13780 (set_attr "ppro_uops" "one")])
13781
13782(define_expand "prologue"
13783 [(const_int 1)]
13784 ""
13785 "ix86_expand_prologue (); DONE;")
13786
13787(define_insn "prologue_set_got"
13788 [(set (match_operand:SI 0 "register_operand" "=r")
13789 (unspec_volatile:SI
13790 [(plus:SI (match_dup 0)
13791 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
13792 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
13793 (clobber (reg:CC 17))]
13794 "!TARGET_64BIT"
13795{
13796 if (GET_CODE (operands[2]) == LABEL_REF)
13797 operands[2] = XEXP (operands[2], 0);
13798 if (TARGET_DEEP_BRANCH_PREDICTION)
13799 return "add{l}\t{%1, %0|%0, %1}";
13800 else
13801 return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
13802}
13803 [(set_attr "type" "alu")
13804 ; Since this insn may have two constant operands, we must set the
13805 ; length manually.
13806 (set_attr "length_immediate" "4")
13807 (set_attr "mode" "SI")])
13808
13809(define_insn "prologue_get_pc"
13810 [(set (match_operand:SI 0 "register_operand" "=r")
13811 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
13812 "!TARGET_64BIT"
13813{
13814 if (GET_CODE (operands[1]) == LABEL_REF)
13815 operands[1] = XEXP (operands[1], 0);
13816 output_asm_insn ("call\t%X1", operands);
13817 if (! TARGET_DEEP_BRANCH_PREDICTION)
13818 {
13819 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
13820 CODE_LABEL_NUMBER (operands[1]));
13821 }
13822 RET;
13823}
13824 [(set_attr "type" "multi")])
13825
13826(define_expand "epilogue"
13827 [(const_int 1)]
13828 ""
13829 "ix86_expand_epilogue (1); DONE;")
13830
13831(define_expand "sibcall_epilogue"
13832 [(const_int 1)]
13833 ""
13834 "ix86_expand_epilogue (0); DONE;")
13835
13836(define_expand "eh_return"
13837 [(use (match_operand 0 "register_operand" ""))
13838 (use (match_operand 1 "register_operand" ""))]
13839 ""
13840{
13841 rtx tmp, sa = operands[0], ra = operands[1];
13842
13843 /* Tricky bit: we write the address of the handler to which we will
13844 be returning into someone else's stack frame, one word below the
13845 stack address we wish to restore. */
13846 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13847 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13848 tmp = gen_rtx_MEM (Pmode, tmp);
13849 emit_move_insn (tmp, ra);
13850
13851 if (Pmode == SImode)
13852 emit_insn (gen_eh_return_si (sa));
13853 else
13854 emit_insn (gen_eh_return_di (sa));
13855 emit_barrier ();
13856 DONE;
13857})
13858
13859(define_insn_and_split "eh_return_si"
13860 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
13861 "!TARGET_64BIT"
13862 "#"
13863 "reload_completed"
13864 [(const_int 1)]
13865 "ix86_expand_epilogue (2); DONE;")
13866
13867(define_insn_and_split "eh_return_di"
13868 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
13869 "TARGET_64BIT"
13870 "#"
13871 "reload_completed"
13872 [(const_int 1)]
13873 "ix86_expand_epilogue (2); DONE;")
13874
13875(define_insn "leave"
13876 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13877 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13878 (clobber (mem:BLK (scratch)))]
13879 "!TARGET_64BIT"
13880 "leave"
13881 [(set_attr "length_immediate" "0")
13882 (set_attr "length" "1")
13883 (set_attr "modrm" "0")
13884 (set_attr "modrm" "0")
13885 (set_attr "athlon_decode" "vector")
13886 (set_attr "ppro_uops" "few")])
13887
13888(define_insn "leave_rex64"
13889 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13890 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13891 (clobber (mem:BLK (scratch)))]
13892 "TARGET_64BIT"
13893 "leave"
13894 [(set_attr "length_immediate" "0")
13895 (set_attr "length" "1")
13896 (set_attr "modrm" "0")
13897 (set_attr "modrm" "0")
13898 (set_attr "athlon_decode" "vector")
13899 (set_attr "ppro_uops" "few")])
13900
13901(define_expand "ffssi2"
13902 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13903 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13904 ""
13905{
13906 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13907 rtx in = operands[1];
13908
13909 if (TARGET_CMOVE)
13910 {
13911 emit_move_insn (tmp, constm1_rtx);
13912 emit_insn (gen_ffssi_1 (out, in));
13913 emit_insn (gen_rtx_SET (VOIDmode, out,
13914 gen_rtx_IF_THEN_ELSE (SImode,
13915 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13916 const0_rtx),
13917 tmp,
13918 out)));
13919 emit_insn (gen_addsi3 (out, out, const1_rtx));
13920 emit_move_insn (operands[0], out);
13921 }
13922
13923 /* Pentium bsf instruction is extremly slow. The following code is
13924 recommended by the Intel Optimizing Manual as a reasonable replacement:
13925 TEST EAX,EAX
13926 JZ SHORT BS2
13927 XOR ECX,ECX
13928 MOV DWORD PTR [TEMP+4],ECX
13929 SUB ECX,EAX
13930 AND EAX,ECX
13931 MOV DWORD PTR [TEMP],EAX
13932 FILD QWORD PTR [TEMP]
13933 FSTP QWORD PTR [TEMP]
13934 WAIT ; WAIT only needed for compatibility with
13935 ; earlier processors
13936 MOV ECX, DWORD PTR [TEMP+4]
13937 SHR ECX,20
13938 SUB ECX,3FFH
13939 TEST EAX,EAX ; clear zero flag
13940 BS2:
13941 Following piece of code expand ffs to similar beast.
13942 */
13943
13944 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13945 {
13946 rtx label = gen_label_rtx ();
13947 rtx lo, hi;
13948 rtx mem = assign_386_stack_local (DImode, 0);
13949 rtx fptmp = gen_reg_rtx (DFmode);
13950 split_di (&mem, 1, &lo, &hi);
13951
13952 emit_move_insn (out, const0_rtx);
13953
13954 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
13955
13956 emit_move_insn (hi, out);
13957 emit_insn (gen_subsi3 (out, out, in));
13958 emit_insn (gen_andsi3 (out, out, in));
13959 emit_move_insn (lo, out);
13960 emit_insn (gen_floatdidf2 (fptmp,mem));
13961 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13962 emit_move_insn (out, hi);
13963 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
13964 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
13965
13966 emit_label (label);
13967 LABEL_NUSES (label) = 1;
13968
13969 emit_move_insn (operands[0], out);
13970 }
13971 else
13972 {
13973 emit_move_insn (tmp, const0_rtx);
13974 emit_insn (gen_ffssi_1 (out, in));
13975 emit_insn (gen_rtx_SET (VOIDmode,
13976 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
13977 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
13978 const0_rtx)));
13979 emit_insn (gen_negsi2 (tmp, tmp));
13980 emit_insn (gen_iorsi3 (out, out, tmp));
13981 emit_insn (gen_addsi3 (out, out, const1_rtx));
13982 emit_move_insn (operands[0], out);
13983 }
13984 DONE;
13985})
13986
13987(define_insn "ffssi_1"
13988 [(set (reg:CCZ 17)
13989 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13990 (const_int 0)))
13991 (set (match_operand:SI 0 "register_operand" "=r")
13992 (unspec:SI [(match_dup 1)] 5))]
13993 ""
13994 "bsf{l}\t{%1, %0|%0, %1}"
13995 [(set_attr "prefix_0f" "1")
13996 (set_attr "ppro_uops" "few")])
13997
13998;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13999;; and slower than the two-byte movzx insn needed to do the work in SImode.
14000
14001;; These patterns match the binary 387 instructions for addM3, subM3,
14002;; mulM3 and divM3. There are three patterns for each of DFmode and
14003;; SFmode. The first is the normal insn, the second the same insn but
14004;; with one operand a conversion, and the third the same insn but with
14005;; the other operand a conversion. The conversion may be SFmode or
14006;; SImode if the target mode DFmode, but only SImode if the target mode
14007;; is SFmode.
14008
14009;; Gcc is slightly more smart about handling normal two address instructions
14010;; so use special patterns for add and mull.
14011(define_insn "*fop_sf_comm_nosse"
14012 [(set (match_operand:SF 0 "register_operand" "=f")
14013 (match_operator:SF 3 "binary_fp_operator"
13859 [(match_operand:SF 1 "register_operand" "%0")
14014 [(match_operand:SF 1 "nonimmediate_operand" "%0")
13860 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13861 "TARGET_80387 && !TARGET_SSE_MATH
14015 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14016 "TARGET_80387 && !TARGET_SSE_MATH
13862 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14017 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14018 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13863 "* return output_387_binary_op (insn, operands);"
13864 [(set (attr "type")
13865 (if_then_else (match_operand:SF 3 "mult_operator" "")
13866 (const_string "fmul")
13867 (const_string "fop")))
13868 (set_attr "mode" "SF")])
13869
13870(define_insn "*fop_sf_comm"
13871 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13872 (match_operator:SF 3 "binary_fp_operator"
14019 "* return output_387_binary_op (insn, operands);"
14020 [(set (attr "type")
14021 (if_then_else (match_operand:SF 3 "mult_operator" "")
14022 (const_string "fmul")
14023 (const_string "fop")))
14024 (set_attr "mode" "SF")])
14025
14026(define_insn "*fop_sf_comm"
14027 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14028 (match_operator:SF 3 "binary_fp_operator"
13873 [(match_operand:SF 1 "register_operand" "%0,0")
14029 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13874 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13875 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14030 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14031 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13876 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14032 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14033 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13877 "* return output_387_binary_op (insn, operands);"
13878 [(set (attr "type")
13879 (if_then_else (eq_attr "alternative" "1")
13880 (const_string "sse")
13881 (if_then_else (match_operand:SF 3 "mult_operator" "")
13882 (const_string "fmul")
13883 (const_string "fop"))))
13884 (set_attr "mode" "SF")])
13885
13886(define_insn "*fop_sf_comm_sse"
13887 [(set (match_operand:SF 0 "register_operand" "=x")
13888 (match_operator:SF 3 "binary_fp_operator"
14034 "* return output_387_binary_op (insn, operands);"
14035 [(set (attr "type")
14036 (if_then_else (eq_attr "alternative" "1")
14037 (const_string "sse")
14038 (if_then_else (match_operand:SF 3 "mult_operator" "")
14039 (const_string "fmul")
14040 (const_string "fop"))))
14041 (set_attr "mode" "SF")])
14042
14043(define_insn "*fop_sf_comm_sse"
14044 [(set (match_operand:SF 0 "register_operand" "=x")
14045 (match_operator:SF 3 "binary_fp_operator"
13889 [(match_operand:SF 1 "register_operand" "%0")
14046 [(match_operand:SF 1 "nonimmediate_operand" "%0")
13890 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14047 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13891 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14048 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14049 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13892 "* return output_387_binary_op (insn, operands);"
13893 [(set_attr "type" "sse")
13894 (set_attr "mode" "SF")])
13895
13896(define_insn "*fop_df_comm_nosse"
13897 [(set (match_operand:DF 0 "register_operand" "=f")
13898 (match_operator:DF 3 "binary_fp_operator"
14050 "* return output_387_binary_op (insn, operands);"
14051 [(set_attr "type" "sse")
14052 (set_attr "mode" "SF")])
14053
14054(define_insn "*fop_df_comm_nosse"
14055 [(set (match_operand:DF 0 "register_operand" "=f")
14056 (match_operator:DF 3 "binary_fp_operator"
13899 [(match_operand:DF 1 "register_operand" "%0")
14057 [(match_operand:DF 1 "nonimmediate_operand" "%0")
13900 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
13901 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14058 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14059 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
13902 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14060 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14061 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13903 "* return output_387_binary_op (insn, operands);"
13904 [(set (attr "type")
13905 (if_then_else (match_operand:SF 3 "mult_operator" "")
13906 (const_string "fmul")
13907 (const_string "fop")))
13908 (set_attr "mode" "DF")])
13909
13910(define_insn "*fop_df_comm"
13911 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
13912 (match_operator:DF 3 "binary_fp_operator"
14062 "* return output_387_binary_op (insn, operands);"
14063 [(set (attr "type")
14064 (if_then_else (match_operand:SF 3 "mult_operator" "")
14065 (const_string "fmul")
14066 (const_string "fop")))
14067 (set_attr "mode" "DF")])
14068
14069(define_insn "*fop_df_comm"
14070 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14071 (match_operator:DF 3 "binary_fp_operator"
13913 [(match_operand:DF 1 "register_operand" "%0,0")
14072 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
13914 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
13915 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14073 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14074 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
13916 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14075 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14076 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13917 "* return output_387_binary_op (insn, operands);"
13918 [(set (attr "type")
13919 (if_then_else (eq_attr "alternative" "1")
13920 (const_string "sse")
13921 (if_then_else (match_operand:SF 3 "mult_operator" "")
13922 (const_string "fmul")
13923 (const_string "fop"))))
13924 (set_attr "mode" "DF")])
13925
13926(define_insn "*fop_df_comm_sse"
13927 [(set (match_operand:DF 0 "register_operand" "=Y")
13928 (match_operator:DF 3 "binary_fp_operator"
14077 "* return output_387_binary_op (insn, operands);"
14078 [(set (attr "type")
14079 (if_then_else (eq_attr "alternative" "1")
14080 (const_string "sse")
14081 (if_then_else (match_operand:SF 3 "mult_operator" "")
14082 (const_string "fmul")
14083 (const_string "fop"))))
14084 (set_attr "mode" "DF")])
14085
14086(define_insn "*fop_df_comm_sse"
14087 [(set (match_operand:DF 0 "register_operand" "=Y")
14088 (match_operator:DF 3 "binary_fp_operator"
13929 [(match_operand:DF 1 "register_operand" "%0")
14089 [(match_operand:DF 1 "nonimmediate_operand" "%0")
13930 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13931 "TARGET_SSE2 && TARGET_SSE_MATH
14090 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14091 "TARGET_SSE2 && TARGET_SSE_MATH
13932 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14092 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14093 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13933 "* return output_387_binary_op (insn, operands);"
13934 [(set_attr "type" "sse")
13935 (set_attr "mode" "DF")])
13936
13937(define_insn "*fop_xf_comm"
13938 [(set (match_operand:XF 0 "register_operand" "=f")
13939 (match_operator:XF 3 "binary_fp_operator"
13940 [(match_operand:XF 1 "register_operand" "%0")
13941 (match_operand:XF 2 "register_operand" "f")]))]
13942 "!TARGET_64BIT && TARGET_80387
13943 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13944 "* return output_387_binary_op (insn, operands);"
13945 [(set (attr "type")
13946 (if_then_else (match_operand:XF 3 "mult_operator" "")
13947 (const_string "fmul")
13948 (const_string "fop")))
13949 (set_attr "mode" "XF")])
13950
13951(define_insn "*fop_tf_comm"
13952 [(set (match_operand:TF 0 "register_operand" "=f")
13953 (match_operator:TF 3 "binary_fp_operator"
13954 [(match_operand:TF 1 "register_operand" "%0")
13955 (match_operand:TF 2 "register_operand" "f")]))]
13956 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13957 "* return output_387_binary_op (insn, operands);"
13958 [(set (attr "type")
13959 (if_then_else (match_operand:TF 3 "mult_operator" "")
13960 (const_string "fmul")
13961 (const_string "fop")))
13962 (set_attr "mode" "XF")])
13963
13964(define_insn "*fop_sf_1_nosse"
13965 [(set (match_operand:SF 0 "register_operand" "=f,f")
13966 (match_operator:SF 3 "binary_fp_operator"
13967 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
13968 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
13969 "TARGET_80387 && !TARGET_SSE_MATH
13970 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13971 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13972 "* return output_387_binary_op (insn, operands);"
13973 [(set (attr "type")
13974 (cond [(match_operand:SF 3 "mult_operator" "")
13975 (const_string "fmul")
13976 (match_operand:SF 3 "div_operator" "")
13977 (const_string "fdiv")
13978 ]
13979 (const_string "fop")))
13980 (set_attr "mode" "SF")])
13981
13982(define_insn "*fop_sf_1"
13983 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13984 (match_operator:SF 3 "binary_fp_operator"
13985 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13986 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13987 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13988 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13989 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13990 "* return output_387_binary_op (insn, operands);"
13991 [(set (attr "type")
13992 (cond [(eq_attr "alternative" "2")
13993 (const_string "sse")
13994 (match_operand:SF 3 "mult_operator" "")
13995 (const_string "fmul")
13996 (match_operand:SF 3 "div_operator" "")
13997 (const_string "fdiv")
13998 ]
13999 (const_string "fop")))
14000 (set_attr "mode" "SF")])
14001
14002(define_insn "*fop_sf_1_sse"
14003 [(set (match_operand:SF 0 "register_operand" "=x")
14004 (match_operator:SF 3 "binary_fp_operator"
14005 [(match_operand:SF 1 "register_operand" "0")
14006 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14007 "TARGET_SSE_MATH
14008 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14009 "* return output_387_binary_op (insn, operands);"
14010 [(set_attr "type" "sse")
14011 (set_attr "mode" "SF")])
14012
14013;; ??? Add SSE splitters for these!
14014(define_insn "*fop_sf_2"
14015 [(set (match_operand:SF 0 "register_operand" "=f,f")
14016 (match_operator:SF 3 "binary_fp_operator"
14017 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14018 (match_operand:SF 2 "register_operand" "0,0")]))]
14019 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14020 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14021 [(set (attr "type")
14022 (cond [(match_operand:SF 3 "mult_operator" "")
14023 (const_string "fmul")
14024 (match_operand:SF 3 "div_operator" "")
14025 (const_string "fdiv")
14026 ]
14027 (const_string "fop")))
14028 (set_attr "fp_int_src" "true")
14029 (set_attr "ppro_uops" "many")
14030 (set_attr "mode" "SI")])
14031
14032(define_insn "*fop_sf_3"
14033 [(set (match_operand:SF 0 "register_operand" "=f,f")
14034 (match_operator:SF 3 "binary_fp_operator"
14035 [(match_operand:SF 1 "register_operand" "0,0")
14036 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14037 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14038 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14039 [(set (attr "type")
14040 (cond [(match_operand:SF 3 "mult_operator" "")
14041 (const_string "fmul")
14042 (match_operand:SF 3 "div_operator" "")
14043 (const_string "fdiv")
14044 ]
14045 (const_string "fop")))
14046 (set_attr "fp_int_src" "true")
14047 (set_attr "ppro_uops" "many")
14048 (set_attr "mode" "SI")])
14049
14050(define_insn "*fop_df_1_nosse"
14051 [(set (match_operand:DF 0 "register_operand" "=f,f")
14052 (match_operator:DF 3 "binary_fp_operator"
14053 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14054 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14055 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14056 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14057 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14058 "* return output_387_binary_op (insn, operands);"
14059 [(set (attr "type")
14060 (cond [(match_operand:DF 3 "mult_operator" "")
14061 (const_string "fmul")
14062 (match_operand:DF 3 "div_operator" "")
14063 (const_string "fdiv")
14064 ]
14065 (const_string "fop")))
14066 (set_attr "mode" "DF")])
14067
14068
14069(define_insn "*fop_df_1"
14070 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14071 (match_operator:DF 3 "binary_fp_operator"
14072 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14073 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14074 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14075 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14076 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14077 "* return output_387_binary_op (insn, operands);"
14078 [(set (attr "type")
14079 (cond [(eq_attr "alternative" "2")
14080 (const_string "sse")
14081 (match_operand:DF 3 "mult_operator" "")
14082 (const_string "fmul")
14083 (match_operand:DF 3 "div_operator" "")
14084 (const_string "fdiv")
14085 ]
14086 (const_string "fop")))
14087 (set_attr "mode" "DF")])
14088
14089(define_insn "*fop_df_1_sse"
14090 [(set (match_operand:DF 0 "register_operand" "=Y")
14091 (match_operator:DF 3 "binary_fp_operator"
14092 [(match_operand:DF 1 "register_operand" "0")
14093 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14094 "TARGET_SSE2 && TARGET_SSE_MATH
14095 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14096 "* return output_387_binary_op (insn, operands);"
14097 [(set_attr "type" "sse")])
14098
14099;; ??? Add SSE splitters for these!
14100(define_insn "*fop_df_2"
14101 [(set (match_operand:DF 0 "register_operand" "=f,f")
14102 (match_operator:DF 3 "binary_fp_operator"
14103 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14104 (match_operand:DF 2 "register_operand" "0,0")]))]
14105 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14106 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14107 [(set (attr "type")
14108 (cond [(match_operand:DF 3 "mult_operator" "")
14109 (const_string "fmul")
14110 (match_operand:DF 3 "div_operator" "")
14111 (const_string "fdiv")
14112 ]
14113 (const_string "fop")))
14114 (set_attr "fp_int_src" "true")
14115 (set_attr "ppro_uops" "many")
14116 (set_attr "mode" "SI")])
14117
14118(define_insn "*fop_df_3"
14119 [(set (match_operand:DF 0 "register_operand" "=f,f")
14120 (match_operator:DF 3 "binary_fp_operator"
14121 [(match_operand:DF 1 "register_operand" "0,0")
14122 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14123 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14124 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14125 [(set (attr "type")
14126 (cond [(match_operand:DF 3 "mult_operator" "")
14127 (const_string "fmul")
14128 (match_operand:DF 3 "div_operator" "")
14129 (const_string "fdiv")
14130 ]
14131 (const_string "fop")))
14132 (set_attr "fp_int_src" "true")
14133 (set_attr "ppro_uops" "many")
14134 (set_attr "mode" "SI")])
14135
14136(define_insn "*fop_df_4"
14137 [(set (match_operand:DF 0 "register_operand" "=f,f")
14138 (match_operator:DF 3 "binary_fp_operator"
14139 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14140 (match_operand:DF 2 "register_operand" "0,f")]))]
14141 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14142 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14143 "* return output_387_binary_op (insn, operands);"
14144 [(set (attr "type")
14145 (cond [(match_operand:DF 3 "mult_operator" "")
14146 (const_string "fmul")
14147 (match_operand:DF 3 "div_operator" "")
14148 (const_string "fdiv")
14149 ]
14150 (const_string "fop")))
14151 (set_attr "mode" "SF")])
14152
14153(define_insn "*fop_df_5"
14154 [(set (match_operand:DF 0 "register_operand" "=f,f")
14155 (match_operator:DF 3 "binary_fp_operator"
14156 [(match_operand:DF 1 "register_operand" "0,f")
14157 (float_extend:DF
14158 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14159 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14160 "* return output_387_binary_op (insn, operands);"
14161 [(set (attr "type")
14162 (cond [(match_operand:DF 3 "mult_operator" "")
14163 (const_string "fmul")
14164 (match_operand:DF 3 "div_operator" "")
14165 (const_string "fdiv")
14166 ]
14167 (const_string "fop")))
14168 (set_attr "mode" "SF")])
14169
14170(define_insn "*fop_xf_1"
14171 [(set (match_operand:XF 0 "register_operand" "=f,f")
14172 (match_operator:XF 3 "binary_fp_operator"
14173 [(match_operand:XF 1 "register_operand" "0,f")
14174 (match_operand:XF 2 "register_operand" "f,0")]))]
14175 "!TARGET_64BIT && TARGET_80387
14176 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14177 "* return output_387_binary_op (insn, operands);"
14178 [(set (attr "type")
14179 (cond [(match_operand:XF 3 "mult_operator" "")
14180 (const_string "fmul")
14181 (match_operand:XF 3 "div_operator" "")
14182 (const_string "fdiv")
14183 ]
14184 (const_string "fop")))
14185 (set_attr "mode" "XF")])
14186
14187(define_insn "*fop_tf_1"
14188 [(set (match_operand:TF 0 "register_operand" "=f,f")
14189 (match_operator:TF 3 "binary_fp_operator"
14190 [(match_operand:TF 1 "register_operand" "0,f")
14191 (match_operand:TF 2 "register_operand" "f,0")]))]
14192 "TARGET_80387
14193 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14194 "* return output_387_binary_op (insn, operands);"
14195 [(set (attr "type")
14196 (cond [(match_operand:TF 3 "mult_operator" "")
14197 (const_string "fmul")
14198 (match_operand:TF 3 "div_operator" "")
14199 (const_string "fdiv")
14200 ]
14201 (const_string "fop")))
14202 (set_attr "mode" "XF")])
14203
14204(define_insn "*fop_xf_2"
14205 [(set (match_operand:XF 0 "register_operand" "=f,f")
14206 (match_operator:XF 3 "binary_fp_operator"
14207 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14208 (match_operand:XF 2 "register_operand" "0,0")]))]
14209 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14210 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14211 [(set (attr "type")
14212 (cond [(match_operand:XF 3 "mult_operator" "")
14213 (const_string "fmul")
14214 (match_operand:XF 3 "div_operator" "")
14215 (const_string "fdiv")
14216 ]
14217 (const_string "fop")))
14218 (set_attr "fp_int_src" "true")
14219 (set_attr "mode" "SI")
14220 (set_attr "ppro_uops" "many")])
14221
14222(define_insn "*fop_tf_2"
14223 [(set (match_operand:TF 0 "register_operand" "=f,f")
14224 (match_operator:TF 3 "binary_fp_operator"
14225 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14226 (match_operand:TF 2 "register_operand" "0,0")]))]
14227 "TARGET_80387 && TARGET_USE_FIOP"
14228 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14229 [(set (attr "type")
14230 (cond [(match_operand:TF 3 "mult_operator" "")
14231 (const_string "fmul")
14232 (match_operand:TF 3 "div_operator" "")
14233 (const_string "fdiv")
14234 ]
14235 (const_string "fop")))
14236 (set_attr "fp_int_src" "true")
14237 (set_attr "mode" "SI")
14238 (set_attr "ppro_uops" "many")])
14239
14240(define_insn "*fop_xf_3"
14241 [(set (match_operand:XF 0 "register_operand" "=f,f")
14242 (match_operator:XF 3 "binary_fp_operator"
14243 [(match_operand:XF 1 "register_operand" "0,0")
14244 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14245 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14246 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14247 [(set (attr "type")
14248 (cond [(match_operand:XF 3 "mult_operator" "")
14249 (const_string "fmul")
14250 (match_operand:XF 3 "div_operator" "")
14251 (const_string "fdiv")
14252 ]
14253 (const_string "fop")))
14254 (set_attr "fp_int_src" "true")
14255 (set_attr "mode" "SI")
14256 (set_attr "ppro_uops" "many")])
14257
14258(define_insn "*fop_tf_3"
14259 [(set (match_operand:TF 0 "register_operand" "=f,f")
14260 (match_operator:TF 3 "binary_fp_operator"
14261 [(match_operand:TF 1 "register_operand" "0,0")
14262 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14263 "TARGET_80387 && TARGET_USE_FIOP"
14264 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14265 [(set (attr "type")
14266 (cond [(match_operand:TF 3 "mult_operator" "")
14267 (const_string "fmul")
14268 (match_operand:TF 3 "div_operator" "")
14269 (const_string "fdiv")
14270 ]
14271 (const_string "fop")))
14272 (set_attr "fp_int_src" "true")
14273 (set_attr "mode" "SI")
14274 (set_attr "ppro_uops" "many")])
14275
14276(define_insn "*fop_xf_4"
14277 [(set (match_operand:XF 0 "register_operand" "=f,f")
14278 (match_operator:XF 3 "binary_fp_operator"
14279 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14280 (match_operand:XF 2 "register_operand" "0,f")]))]
14281 "!TARGET_64BIT && TARGET_80387"
14282 "* return output_387_binary_op (insn, operands);"
14283 [(set (attr "type")
14284 (cond [(match_operand:XF 3 "mult_operator" "")
14285 (const_string "fmul")
14286 (match_operand:XF 3 "div_operator" "")
14287 (const_string "fdiv")
14288 ]
14289 (const_string "fop")))
14290 (set_attr "mode" "SF")])
14291
14292(define_insn "*fop_tf_4"
14293 [(set (match_operand:TF 0 "register_operand" "=f,f")
14294 (match_operator:TF 3 "binary_fp_operator"
14295 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14296 (match_operand:TF 2 "register_operand" "0,f")]))]
14297 "TARGET_80387"
14298 "* return output_387_binary_op (insn, operands);"
14299 [(set (attr "type")
14300 (cond [(match_operand:TF 3 "mult_operator" "")
14301 (const_string "fmul")
14302 (match_operand:TF 3 "div_operator" "")
14303 (const_string "fdiv")
14304 ]
14305 (const_string "fop")))
14306 (set_attr "mode" "SF")])
14307
14308(define_insn "*fop_xf_5"
14309 [(set (match_operand:XF 0 "register_operand" "=f,f")
14310 (match_operator:XF 3 "binary_fp_operator"
14311 [(match_operand:XF 1 "register_operand" "0,f")
14312 (float_extend:XF
14313 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14314 "!TARGET_64BIT && TARGET_80387"
14315 "* return output_387_binary_op (insn, operands);"
14316 [(set (attr "type")
14317 (cond [(match_operand:XF 3 "mult_operator" "")
14318 (const_string "fmul")
14319 (match_operand:XF 3 "div_operator" "")
14320 (const_string "fdiv")
14321 ]
14322 (const_string "fop")))
14323 (set_attr "mode" "SF")])
14324
14325(define_insn "*fop_tf_5"
14326 [(set (match_operand:TF 0 "register_operand" "=f,f")
14327 (match_operator:TF 3 "binary_fp_operator"
14328 [(match_operand:TF 1 "register_operand" "0,f")
14329 (float_extend:TF
14330 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14331 "TARGET_80387"
14332 "* return output_387_binary_op (insn, operands);"
14333 [(set (attr "type")
14334 (cond [(match_operand:TF 3 "mult_operator" "")
14335 (const_string "fmul")
14336 (match_operand:TF 3 "div_operator" "")
14337 (const_string "fdiv")
14338 ]
14339 (const_string "fop")))
14340 (set_attr "mode" "SF")])
14341
14342(define_insn "*fop_xf_6"
14343 [(set (match_operand:XF 0 "register_operand" "=f,f")
14344 (match_operator:XF 3 "binary_fp_operator"
14345 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14346 (match_operand:XF 2 "register_operand" "0,f")]))]
14347 "!TARGET_64BIT && TARGET_80387"
14348 "* return output_387_binary_op (insn, operands);"
14349 [(set (attr "type")
14350 (cond [(match_operand:XF 3 "mult_operator" "")
14351 (const_string "fmul")
14352 (match_operand:XF 3 "div_operator" "")
14353 (const_string "fdiv")
14354 ]
14355 (const_string "fop")))
14356 (set_attr "mode" "DF")])
14357
14358(define_insn "*fop_tf_6"
14359 [(set (match_operand:TF 0 "register_operand" "=f,f")
14360 (match_operator:TF 3 "binary_fp_operator"
14361 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14362 (match_operand:TF 2 "register_operand" "0,f")]))]
14363 "TARGET_80387"
14364 "* return output_387_binary_op (insn, operands);"
14365 [(set (attr "type")
14366 (cond [(match_operand:TF 3 "mult_operator" "")
14367 (const_string "fmul")
14368 (match_operand:TF 3 "div_operator" "")
14369 (const_string "fdiv")
14370 ]
14371 (const_string "fop")))
14372 (set_attr "mode" "DF")])
14373
14374(define_insn "*fop_xf_7"
14375 [(set (match_operand:XF 0 "register_operand" "=f,f")
14376 (match_operator:XF 3 "binary_fp_operator"
14377 [(match_operand:XF 1 "register_operand" "0,f")
14378 (float_extend:XF
14379 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14380 "!TARGET_64BIT && TARGET_80387"
14381 "* return output_387_binary_op (insn, operands);"
14382 [(set (attr "type")
14383 (cond [(match_operand:XF 3 "mult_operator" "")
14384 (const_string "fmul")
14385 (match_operand:XF 3 "div_operator" "")
14386 (const_string "fdiv")
14387 ]
14388 (const_string "fop")))
14389 (set_attr "mode" "DF")])
14390
14391(define_insn "*fop_tf_7"
14392 [(set (match_operand:TF 0 "register_operand" "=f,f")
14393 (match_operator:TF 3 "binary_fp_operator"
14394 [(match_operand:TF 1 "register_operand" "0,f")
14395 (float_extend:TF
14396 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14397 "TARGET_80387"
14398 "* return output_387_binary_op (insn, operands);"
14399 [(set (attr "type")
14400 (cond [(match_operand:TF 3 "mult_operator" "")
14401 (const_string "fmul")
14402 (match_operand:TF 3 "div_operator" "")
14403 (const_string "fdiv")
14404 ]
14405 (const_string "fop")))
14406 (set_attr "mode" "DF")])
14407
14408(define_split
14409 [(set (match_operand 0 "register_operand" "")
14410 (match_operator 3 "binary_fp_operator"
14411 [(float (match_operand:SI 1 "register_operand" ""))
14412 (match_operand 2 "register_operand" "")]))]
14413 "TARGET_80387 && reload_completed
14414 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14415 [(const_int 0)]
14416{
14417 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14418 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14419 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14420 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14421 GET_MODE (operands[3]),
14422 operands[4],
14423 operands[2])));
14424 ix86_free_from_memory (GET_MODE (operands[1]));
14425 DONE;
14426})
14427
14428(define_split
14429 [(set (match_operand 0 "register_operand" "")
14430 (match_operator 3 "binary_fp_operator"
14431 [(match_operand 1 "register_operand" "")
14432 (float (match_operand:SI 2 "register_operand" ""))]))]
14433 "TARGET_80387 && reload_completed
14434 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14435 [(const_int 0)]
14436{
14437 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14438 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14439 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14440 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14441 GET_MODE (operands[3]),
14442 operands[1],
14443 operands[4])));
14444 ix86_free_from_memory (GET_MODE (operands[2]));
14445 DONE;
14446})
14447
14448;; FPU special functions.
14449
14450(define_expand "sqrtsf2"
14451 [(set (match_operand:SF 0 "register_operand" "")
14452 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14453 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14454{
14455 if (!TARGET_SSE_MATH)
14456 operands[1] = force_reg (SFmode, operands[1]);
14457})
14458
14459(define_insn "sqrtsf2_1"
14460 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14461 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14462 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14463 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14464 "@
14465 fsqrt
14466 sqrtss\t{%1, %0|%0, %1}"
14467 [(set_attr "type" "fpspc,sse")
14468 (set_attr "mode" "SF,SF")
14469 (set_attr "athlon_decode" "direct,*")])
14470
14471(define_insn "sqrtsf2_1_sse_only"
14472 [(set (match_operand:SF 0 "register_operand" "=x")
14473 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14474 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14475 "sqrtss\t{%1, %0|%0, %1}"
14476 [(set_attr "type" "sse")
14477 (set_attr "mode" "SF")
14478 (set_attr "athlon_decode" "*")])
14479
14480(define_insn "sqrtsf2_i387"
14481 [(set (match_operand:SF 0 "register_operand" "=f")
14482 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14483 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14484 && !TARGET_SSE_MATH"
14485 "fsqrt"
14486 [(set_attr "type" "fpspc")
14487 (set_attr "mode" "SF")
14488 (set_attr "athlon_decode" "direct")])
14489
14490(define_expand "sqrtdf2"
14491 [(set (match_operand:DF 0 "register_operand" "")
14492 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14493 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14494 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14495{
14496 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14497 operands[1] = force_reg (DFmode, operands[1]);
14498})
14499
14500(define_insn "sqrtdf2_1"
14501 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14502 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14503 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14504 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14505 "@
14506 fsqrt
14507 sqrtsd\t{%1, %0|%0, %1}"
14508 [(set_attr "type" "fpspc,sse")
14509 (set_attr "mode" "DF,DF")
14510 (set_attr "athlon_decode" "direct,*")])
14511
14512(define_insn "sqrtdf2_1_sse_only"
14513 [(set (match_operand:DF 0 "register_operand" "=Y")
14514 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14515 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14516 "sqrtsd\t{%1, %0|%0, %1}"
14517 [(set_attr "type" "sse")
14518 (set_attr "mode" "DF")
14519 (set_attr "athlon_decode" "*")])
14520
14521(define_insn "sqrtdf2_i387"
14522 [(set (match_operand:DF 0 "register_operand" "=f")
14523 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14524 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14525 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14526 "fsqrt"
14527 [(set_attr "type" "fpspc")
14528 (set_attr "mode" "DF")
14529 (set_attr "athlon_decode" "direct")])
14530
14531(define_insn "*sqrtextendsfdf2"
14532 [(set (match_operand:DF 0 "register_operand" "=f")
14533 (sqrt:DF (float_extend:DF
14534 (match_operand:SF 1 "register_operand" "0"))))]
14535 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14536 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14537 "fsqrt"
14538 [(set_attr "type" "fpspc")
14539 (set_attr "mode" "DF")
14540 (set_attr "athlon_decode" "direct")])
14541
14542(define_insn "sqrtxf2"
14543 [(set (match_operand:XF 0 "register_operand" "=f")
14544 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14545 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14546 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14547 "fsqrt"
14548 [(set_attr "type" "fpspc")
14549 (set_attr "mode" "XF")
14550 (set_attr "athlon_decode" "direct")])
14551
14552(define_insn "sqrttf2"
14553 [(set (match_operand:TF 0 "register_operand" "=f")
14554 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14555 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14556 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14557 "fsqrt"
14558 [(set_attr "type" "fpspc")
14559 (set_attr "mode" "XF")
14560 (set_attr "athlon_decode" "direct")])
14561
14562(define_insn "*sqrtextenddfxf2"
14563 [(set (match_operand:XF 0 "register_operand" "=f")
14564 (sqrt:XF (float_extend:XF
14565 (match_operand:DF 1 "register_operand" "0"))))]
14094 "* return output_387_binary_op (insn, operands);"
14095 [(set_attr "type" "sse")
14096 (set_attr "mode" "DF")])
14097
14098(define_insn "*fop_xf_comm"
14099 [(set (match_operand:XF 0 "register_operand" "=f")
14100 (match_operator:XF 3 "binary_fp_operator"
14101 [(match_operand:XF 1 "register_operand" "%0")
14102 (match_operand:XF 2 "register_operand" "f")]))]
14103 "!TARGET_64BIT && TARGET_80387
14104 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14105 "* return output_387_binary_op (insn, operands);"
14106 [(set (attr "type")
14107 (if_then_else (match_operand:XF 3 "mult_operator" "")
14108 (const_string "fmul")
14109 (const_string "fop")))
14110 (set_attr "mode" "XF")])
14111
14112(define_insn "*fop_tf_comm"
14113 [(set (match_operand:TF 0 "register_operand" "=f")
14114 (match_operator:TF 3 "binary_fp_operator"
14115 [(match_operand:TF 1 "register_operand" "%0")
14116 (match_operand:TF 2 "register_operand" "f")]))]
14117 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14118 "* return output_387_binary_op (insn, operands);"
14119 [(set (attr "type")
14120 (if_then_else (match_operand:TF 3 "mult_operator" "")
14121 (const_string "fmul")
14122 (const_string "fop")))
14123 (set_attr "mode" "XF")])
14124
14125(define_insn "*fop_sf_1_nosse"
14126 [(set (match_operand:SF 0 "register_operand" "=f,f")
14127 (match_operator:SF 3 "binary_fp_operator"
14128 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14129 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14130 "TARGET_80387 && !TARGET_SSE_MATH
14131 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14132 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14133 "* return output_387_binary_op (insn, operands);"
14134 [(set (attr "type")
14135 (cond [(match_operand:SF 3 "mult_operator" "")
14136 (const_string "fmul")
14137 (match_operand:SF 3 "div_operator" "")
14138 (const_string "fdiv")
14139 ]
14140 (const_string "fop")))
14141 (set_attr "mode" "SF")])
14142
14143(define_insn "*fop_sf_1"
14144 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14145 (match_operator:SF 3 "binary_fp_operator"
14146 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14147 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14148 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14149 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14150 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14151 "* return output_387_binary_op (insn, operands);"
14152 [(set (attr "type")
14153 (cond [(eq_attr "alternative" "2")
14154 (const_string "sse")
14155 (match_operand:SF 3 "mult_operator" "")
14156 (const_string "fmul")
14157 (match_operand:SF 3 "div_operator" "")
14158 (const_string "fdiv")
14159 ]
14160 (const_string "fop")))
14161 (set_attr "mode" "SF")])
14162
14163(define_insn "*fop_sf_1_sse"
14164 [(set (match_operand:SF 0 "register_operand" "=x")
14165 (match_operator:SF 3 "binary_fp_operator"
14166 [(match_operand:SF 1 "register_operand" "0")
14167 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14168 "TARGET_SSE_MATH
14169 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14170 "* return output_387_binary_op (insn, operands);"
14171 [(set_attr "type" "sse")
14172 (set_attr "mode" "SF")])
14173
14174;; ??? Add SSE splitters for these!
14175(define_insn "*fop_sf_2"
14176 [(set (match_operand:SF 0 "register_operand" "=f,f")
14177 (match_operator:SF 3 "binary_fp_operator"
14178 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14179 (match_operand:SF 2 "register_operand" "0,0")]))]
14180 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14181 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14182 [(set (attr "type")
14183 (cond [(match_operand:SF 3 "mult_operator" "")
14184 (const_string "fmul")
14185 (match_operand:SF 3 "div_operator" "")
14186 (const_string "fdiv")
14187 ]
14188 (const_string "fop")))
14189 (set_attr "fp_int_src" "true")
14190 (set_attr "ppro_uops" "many")
14191 (set_attr "mode" "SI")])
14192
14193(define_insn "*fop_sf_3"
14194 [(set (match_operand:SF 0 "register_operand" "=f,f")
14195 (match_operator:SF 3 "binary_fp_operator"
14196 [(match_operand:SF 1 "register_operand" "0,0")
14197 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14198 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14199 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14200 [(set (attr "type")
14201 (cond [(match_operand:SF 3 "mult_operator" "")
14202 (const_string "fmul")
14203 (match_operand:SF 3 "div_operator" "")
14204 (const_string "fdiv")
14205 ]
14206 (const_string "fop")))
14207 (set_attr "fp_int_src" "true")
14208 (set_attr "ppro_uops" "many")
14209 (set_attr "mode" "SI")])
14210
14211(define_insn "*fop_df_1_nosse"
14212 [(set (match_operand:DF 0 "register_operand" "=f,f")
14213 (match_operator:DF 3 "binary_fp_operator"
14214 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14215 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14216 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14217 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14218 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14219 "* return output_387_binary_op (insn, operands);"
14220 [(set (attr "type")
14221 (cond [(match_operand:DF 3 "mult_operator" "")
14222 (const_string "fmul")
14223 (match_operand:DF 3 "div_operator" "")
14224 (const_string "fdiv")
14225 ]
14226 (const_string "fop")))
14227 (set_attr "mode" "DF")])
14228
14229
14230(define_insn "*fop_df_1"
14231 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14232 (match_operator:DF 3 "binary_fp_operator"
14233 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14234 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14235 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14236 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14237 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14238 "* return output_387_binary_op (insn, operands);"
14239 [(set (attr "type")
14240 (cond [(eq_attr "alternative" "2")
14241 (const_string "sse")
14242 (match_operand:DF 3 "mult_operator" "")
14243 (const_string "fmul")
14244 (match_operand:DF 3 "div_operator" "")
14245 (const_string "fdiv")
14246 ]
14247 (const_string "fop")))
14248 (set_attr "mode" "DF")])
14249
14250(define_insn "*fop_df_1_sse"
14251 [(set (match_operand:DF 0 "register_operand" "=Y")
14252 (match_operator:DF 3 "binary_fp_operator"
14253 [(match_operand:DF 1 "register_operand" "0")
14254 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14255 "TARGET_SSE2 && TARGET_SSE_MATH
14256 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14257 "* return output_387_binary_op (insn, operands);"
14258 [(set_attr "type" "sse")])
14259
14260;; ??? Add SSE splitters for these!
14261(define_insn "*fop_df_2"
14262 [(set (match_operand:DF 0 "register_operand" "=f,f")
14263 (match_operator:DF 3 "binary_fp_operator"
14264 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14265 (match_operand:DF 2 "register_operand" "0,0")]))]
14266 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14267 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14268 [(set (attr "type")
14269 (cond [(match_operand:DF 3 "mult_operator" "")
14270 (const_string "fmul")
14271 (match_operand:DF 3 "div_operator" "")
14272 (const_string "fdiv")
14273 ]
14274 (const_string "fop")))
14275 (set_attr "fp_int_src" "true")
14276 (set_attr "ppro_uops" "many")
14277 (set_attr "mode" "SI")])
14278
14279(define_insn "*fop_df_3"
14280 [(set (match_operand:DF 0 "register_operand" "=f,f")
14281 (match_operator:DF 3 "binary_fp_operator"
14282 [(match_operand:DF 1 "register_operand" "0,0")
14283 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14284 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14285 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14286 [(set (attr "type")
14287 (cond [(match_operand:DF 3 "mult_operator" "")
14288 (const_string "fmul")
14289 (match_operand:DF 3 "div_operator" "")
14290 (const_string "fdiv")
14291 ]
14292 (const_string "fop")))
14293 (set_attr "fp_int_src" "true")
14294 (set_attr "ppro_uops" "many")
14295 (set_attr "mode" "SI")])
14296
14297(define_insn "*fop_df_4"
14298 [(set (match_operand:DF 0 "register_operand" "=f,f")
14299 (match_operator:DF 3 "binary_fp_operator"
14300 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14301 (match_operand:DF 2 "register_operand" "0,f")]))]
14302 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14303 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14304 "* return output_387_binary_op (insn, operands);"
14305 [(set (attr "type")
14306 (cond [(match_operand:DF 3 "mult_operator" "")
14307 (const_string "fmul")
14308 (match_operand:DF 3 "div_operator" "")
14309 (const_string "fdiv")
14310 ]
14311 (const_string "fop")))
14312 (set_attr "mode" "SF")])
14313
14314(define_insn "*fop_df_5"
14315 [(set (match_operand:DF 0 "register_operand" "=f,f")
14316 (match_operator:DF 3 "binary_fp_operator"
14317 [(match_operand:DF 1 "register_operand" "0,f")
14318 (float_extend:DF
14319 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14320 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14321 "* return output_387_binary_op (insn, operands);"
14322 [(set (attr "type")
14323 (cond [(match_operand:DF 3 "mult_operator" "")
14324 (const_string "fmul")
14325 (match_operand:DF 3 "div_operator" "")
14326 (const_string "fdiv")
14327 ]
14328 (const_string "fop")))
14329 (set_attr "mode" "SF")])
14330
14331(define_insn "*fop_xf_1"
14332 [(set (match_operand:XF 0 "register_operand" "=f,f")
14333 (match_operator:XF 3 "binary_fp_operator"
14334 [(match_operand:XF 1 "register_operand" "0,f")
14335 (match_operand:XF 2 "register_operand" "f,0")]))]
14336 "!TARGET_64BIT && TARGET_80387
14337 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14338 "* return output_387_binary_op (insn, operands);"
14339 [(set (attr "type")
14340 (cond [(match_operand:XF 3 "mult_operator" "")
14341 (const_string "fmul")
14342 (match_operand:XF 3 "div_operator" "")
14343 (const_string "fdiv")
14344 ]
14345 (const_string "fop")))
14346 (set_attr "mode" "XF")])
14347
14348(define_insn "*fop_tf_1"
14349 [(set (match_operand:TF 0 "register_operand" "=f,f")
14350 (match_operator:TF 3 "binary_fp_operator"
14351 [(match_operand:TF 1 "register_operand" "0,f")
14352 (match_operand:TF 2 "register_operand" "f,0")]))]
14353 "TARGET_80387
14354 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14355 "* return output_387_binary_op (insn, operands);"
14356 [(set (attr "type")
14357 (cond [(match_operand:TF 3 "mult_operator" "")
14358 (const_string "fmul")
14359 (match_operand:TF 3 "div_operator" "")
14360 (const_string "fdiv")
14361 ]
14362 (const_string "fop")))
14363 (set_attr "mode" "XF")])
14364
14365(define_insn "*fop_xf_2"
14366 [(set (match_operand:XF 0 "register_operand" "=f,f")
14367 (match_operator:XF 3 "binary_fp_operator"
14368 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14369 (match_operand:XF 2 "register_operand" "0,0")]))]
14370 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14371 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14372 [(set (attr "type")
14373 (cond [(match_operand:XF 3 "mult_operator" "")
14374 (const_string "fmul")
14375 (match_operand:XF 3 "div_operator" "")
14376 (const_string "fdiv")
14377 ]
14378 (const_string "fop")))
14379 (set_attr "fp_int_src" "true")
14380 (set_attr "mode" "SI")
14381 (set_attr "ppro_uops" "many")])
14382
14383(define_insn "*fop_tf_2"
14384 [(set (match_operand:TF 0 "register_operand" "=f,f")
14385 (match_operator:TF 3 "binary_fp_operator"
14386 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14387 (match_operand:TF 2 "register_operand" "0,0")]))]
14388 "TARGET_80387 && TARGET_USE_FIOP"
14389 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14390 [(set (attr "type")
14391 (cond [(match_operand:TF 3 "mult_operator" "")
14392 (const_string "fmul")
14393 (match_operand:TF 3 "div_operator" "")
14394 (const_string "fdiv")
14395 ]
14396 (const_string "fop")))
14397 (set_attr "fp_int_src" "true")
14398 (set_attr "mode" "SI")
14399 (set_attr "ppro_uops" "many")])
14400
14401(define_insn "*fop_xf_3"
14402 [(set (match_operand:XF 0 "register_operand" "=f,f")
14403 (match_operator:XF 3 "binary_fp_operator"
14404 [(match_operand:XF 1 "register_operand" "0,0")
14405 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14406 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14407 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14408 [(set (attr "type")
14409 (cond [(match_operand:XF 3 "mult_operator" "")
14410 (const_string "fmul")
14411 (match_operand:XF 3 "div_operator" "")
14412 (const_string "fdiv")
14413 ]
14414 (const_string "fop")))
14415 (set_attr "fp_int_src" "true")
14416 (set_attr "mode" "SI")
14417 (set_attr "ppro_uops" "many")])
14418
14419(define_insn "*fop_tf_3"
14420 [(set (match_operand:TF 0 "register_operand" "=f,f")
14421 (match_operator:TF 3 "binary_fp_operator"
14422 [(match_operand:TF 1 "register_operand" "0,0")
14423 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14424 "TARGET_80387 && TARGET_USE_FIOP"
14425 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14426 [(set (attr "type")
14427 (cond [(match_operand:TF 3 "mult_operator" "")
14428 (const_string "fmul")
14429 (match_operand:TF 3 "div_operator" "")
14430 (const_string "fdiv")
14431 ]
14432 (const_string "fop")))
14433 (set_attr "fp_int_src" "true")
14434 (set_attr "mode" "SI")
14435 (set_attr "ppro_uops" "many")])
14436
14437(define_insn "*fop_xf_4"
14438 [(set (match_operand:XF 0 "register_operand" "=f,f")
14439 (match_operator:XF 3 "binary_fp_operator"
14440 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14441 (match_operand:XF 2 "register_operand" "0,f")]))]
14442 "!TARGET_64BIT && TARGET_80387"
14443 "* return output_387_binary_op (insn, operands);"
14444 [(set (attr "type")
14445 (cond [(match_operand:XF 3 "mult_operator" "")
14446 (const_string "fmul")
14447 (match_operand:XF 3 "div_operator" "")
14448 (const_string "fdiv")
14449 ]
14450 (const_string "fop")))
14451 (set_attr "mode" "SF")])
14452
14453(define_insn "*fop_tf_4"
14454 [(set (match_operand:TF 0 "register_operand" "=f,f")
14455 (match_operator:TF 3 "binary_fp_operator"
14456 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14457 (match_operand:TF 2 "register_operand" "0,f")]))]
14458 "TARGET_80387"
14459 "* return output_387_binary_op (insn, operands);"
14460 [(set (attr "type")
14461 (cond [(match_operand:TF 3 "mult_operator" "")
14462 (const_string "fmul")
14463 (match_operand:TF 3 "div_operator" "")
14464 (const_string "fdiv")
14465 ]
14466 (const_string "fop")))
14467 (set_attr "mode" "SF")])
14468
14469(define_insn "*fop_xf_5"
14470 [(set (match_operand:XF 0 "register_operand" "=f,f")
14471 (match_operator:XF 3 "binary_fp_operator"
14472 [(match_operand:XF 1 "register_operand" "0,f")
14473 (float_extend:XF
14474 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14475 "!TARGET_64BIT && TARGET_80387"
14476 "* return output_387_binary_op (insn, operands);"
14477 [(set (attr "type")
14478 (cond [(match_operand:XF 3 "mult_operator" "")
14479 (const_string "fmul")
14480 (match_operand:XF 3 "div_operator" "")
14481 (const_string "fdiv")
14482 ]
14483 (const_string "fop")))
14484 (set_attr "mode" "SF")])
14485
14486(define_insn "*fop_tf_5"
14487 [(set (match_operand:TF 0 "register_operand" "=f,f")
14488 (match_operator:TF 3 "binary_fp_operator"
14489 [(match_operand:TF 1 "register_operand" "0,f")
14490 (float_extend:TF
14491 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14492 "TARGET_80387"
14493 "* return output_387_binary_op (insn, operands);"
14494 [(set (attr "type")
14495 (cond [(match_operand:TF 3 "mult_operator" "")
14496 (const_string "fmul")
14497 (match_operand:TF 3 "div_operator" "")
14498 (const_string "fdiv")
14499 ]
14500 (const_string "fop")))
14501 (set_attr "mode" "SF")])
14502
14503(define_insn "*fop_xf_6"
14504 [(set (match_operand:XF 0 "register_operand" "=f,f")
14505 (match_operator:XF 3 "binary_fp_operator"
14506 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14507 (match_operand:XF 2 "register_operand" "0,f")]))]
14508 "!TARGET_64BIT && TARGET_80387"
14509 "* return output_387_binary_op (insn, operands);"
14510 [(set (attr "type")
14511 (cond [(match_operand:XF 3 "mult_operator" "")
14512 (const_string "fmul")
14513 (match_operand:XF 3 "div_operator" "")
14514 (const_string "fdiv")
14515 ]
14516 (const_string "fop")))
14517 (set_attr "mode" "DF")])
14518
14519(define_insn "*fop_tf_6"
14520 [(set (match_operand:TF 0 "register_operand" "=f,f")
14521 (match_operator:TF 3 "binary_fp_operator"
14522 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14523 (match_operand:TF 2 "register_operand" "0,f")]))]
14524 "TARGET_80387"
14525 "* return output_387_binary_op (insn, operands);"
14526 [(set (attr "type")
14527 (cond [(match_operand:TF 3 "mult_operator" "")
14528 (const_string "fmul")
14529 (match_operand:TF 3 "div_operator" "")
14530 (const_string "fdiv")
14531 ]
14532 (const_string "fop")))
14533 (set_attr "mode" "DF")])
14534
14535(define_insn "*fop_xf_7"
14536 [(set (match_operand:XF 0 "register_operand" "=f,f")
14537 (match_operator:XF 3 "binary_fp_operator"
14538 [(match_operand:XF 1 "register_operand" "0,f")
14539 (float_extend:XF
14540 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14541 "!TARGET_64BIT && TARGET_80387"
14542 "* return output_387_binary_op (insn, operands);"
14543 [(set (attr "type")
14544 (cond [(match_operand:XF 3 "mult_operator" "")
14545 (const_string "fmul")
14546 (match_operand:XF 3 "div_operator" "")
14547 (const_string "fdiv")
14548 ]
14549 (const_string "fop")))
14550 (set_attr "mode" "DF")])
14551
14552(define_insn "*fop_tf_7"
14553 [(set (match_operand:TF 0 "register_operand" "=f,f")
14554 (match_operator:TF 3 "binary_fp_operator"
14555 [(match_operand:TF 1 "register_operand" "0,f")
14556 (float_extend:TF
14557 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14558 "TARGET_80387"
14559 "* return output_387_binary_op (insn, operands);"
14560 [(set (attr "type")
14561 (cond [(match_operand:TF 3 "mult_operator" "")
14562 (const_string "fmul")
14563 (match_operand:TF 3 "div_operator" "")
14564 (const_string "fdiv")
14565 ]
14566 (const_string "fop")))
14567 (set_attr "mode" "DF")])
14568
14569(define_split
14570 [(set (match_operand 0 "register_operand" "")
14571 (match_operator 3 "binary_fp_operator"
14572 [(float (match_operand:SI 1 "register_operand" ""))
14573 (match_operand 2 "register_operand" "")]))]
14574 "TARGET_80387 && reload_completed
14575 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14576 [(const_int 0)]
14577{
14578 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14579 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14580 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14581 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14582 GET_MODE (operands[3]),
14583 operands[4],
14584 operands[2])));
14585 ix86_free_from_memory (GET_MODE (operands[1]));
14586 DONE;
14587})
14588
14589(define_split
14590 [(set (match_operand 0 "register_operand" "")
14591 (match_operator 3 "binary_fp_operator"
14592 [(match_operand 1 "register_operand" "")
14593 (float (match_operand:SI 2 "register_operand" ""))]))]
14594 "TARGET_80387 && reload_completed
14595 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14596 [(const_int 0)]
14597{
14598 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
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[1],
14604 operands[4])));
14605 ix86_free_from_memory (GET_MODE (operands[2]));
14606 DONE;
14607})
14608
14609;; FPU special functions.
14610
14611(define_expand "sqrtsf2"
14612 [(set (match_operand:SF 0 "register_operand" "")
14613 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14614 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14615{
14616 if (!TARGET_SSE_MATH)
14617 operands[1] = force_reg (SFmode, operands[1]);
14618})
14619
14620(define_insn "sqrtsf2_1"
14621 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14622 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14623 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14624 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14625 "@
14626 fsqrt
14627 sqrtss\t{%1, %0|%0, %1}"
14628 [(set_attr "type" "fpspc,sse")
14629 (set_attr "mode" "SF,SF")
14630 (set_attr "athlon_decode" "direct,*")])
14631
14632(define_insn "sqrtsf2_1_sse_only"
14633 [(set (match_operand:SF 0 "register_operand" "=x")
14634 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14635 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14636 "sqrtss\t{%1, %0|%0, %1}"
14637 [(set_attr "type" "sse")
14638 (set_attr "mode" "SF")
14639 (set_attr "athlon_decode" "*")])
14640
14641(define_insn "sqrtsf2_i387"
14642 [(set (match_operand:SF 0 "register_operand" "=f")
14643 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14644 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14645 && !TARGET_SSE_MATH"
14646 "fsqrt"
14647 [(set_attr "type" "fpspc")
14648 (set_attr "mode" "SF")
14649 (set_attr "athlon_decode" "direct")])
14650
14651(define_expand "sqrtdf2"
14652 [(set (match_operand:DF 0 "register_operand" "")
14653 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14654 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14655 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14656{
14657 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14658 operands[1] = force_reg (DFmode, operands[1]);
14659})
14660
14661(define_insn "sqrtdf2_1"
14662 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14663 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14664 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14665 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14666 "@
14667 fsqrt
14668 sqrtsd\t{%1, %0|%0, %1}"
14669 [(set_attr "type" "fpspc,sse")
14670 (set_attr "mode" "DF,DF")
14671 (set_attr "athlon_decode" "direct,*")])
14672
14673(define_insn "sqrtdf2_1_sse_only"
14674 [(set (match_operand:DF 0 "register_operand" "=Y")
14675 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14676 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14677 "sqrtsd\t{%1, %0|%0, %1}"
14678 [(set_attr "type" "sse")
14679 (set_attr "mode" "DF")
14680 (set_attr "athlon_decode" "*")])
14681
14682(define_insn "sqrtdf2_i387"
14683 [(set (match_operand:DF 0 "register_operand" "=f")
14684 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14685 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14686 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14687 "fsqrt"
14688 [(set_attr "type" "fpspc")
14689 (set_attr "mode" "DF")
14690 (set_attr "athlon_decode" "direct")])
14691
14692(define_insn "*sqrtextendsfdf2"
14693 [(set (match_operand:DF 0 "register_operand" "=f")
14694 (sqrt:DF (float_extend:DF
14695 (match_operand:SF 1 "register_operand" "0"))))]
14696 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14697 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14698 "fsqrt"
14699 [(set_attr "type" "fpspc")
14700 (set_attr "mode" "DF")
14701 (set_attr "athlon_decode" "direct")])
14702
14703(define_insn "sqrtxf2"
14704 [(set (match_operand:XF 0 "register_operand" "=f")
14705 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14706 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14707 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14708 "fsqrt"
14709 [(set_attr "type" "fpspc")
14710 (set_attr "mode" "XF")
14711 (set_attr "athlon_decode" "direct")])
14712
14713(define_insn "sqrttf2"
14714 [(set (match_operand:TF 0 "register_operand" "=f")
14715 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14716 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14717 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14718 "fsqrt"
14719 [(set_attr "type" "fpspc")
14720 (set_attr "mode" "XF")
14721 (set_attr "athlon_decode" "direct")])
14722
14723(define_insn "*sqrtextenddfxf2"
14724 [(set (match_operand:XF 0 "register_operand" "=f")
14725 (sqrt:XF (float_extend:XF
14726 (match_operand:DF 1 "register_operand" "0"))))]
14566 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
14727 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14567 "fsqrt"
14568 [(set_attr "type" "fpspc")
14569 (set_attr "mode" "XF")
14570 (set_attr "athlon_decode" "direct")])
14571
14572(define_insn "*sqrtextenddftf2"
14573 [(set (match_operand:TF 0 "register_operand" "=f")
14574 (sqrt:TF (float_extend:TF
14575 (match_operand:DF 1 "register_operand" "0"))))]
14576 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14577 "fsqrt"
14578 [(set_attr "type" "fpspc")
14579 (set_attr "mode" "XF")
14580 (set_attr "athlon_decode" "direct")])
14581
14582(define_insn "*sqrtextendsfxf2"
14583 [(set (match_operand:XF 0 "register_operand" "=f")
14584 (sqrt:XF (float_extend:XF
14585 (match_operand:SF 1 "register_operand" "0"))))]
14728 "fsqrt"
14729 [(set_attr "type" "fpspc")
14730 (set_attr "mode" "XF")
14731 (set_attr "athlon_decode" "direct")])
14732
14733(define_insn "*sqrtextenddftf2"
14734 [(set (match_operand:TF 0 "register_operand" "=f")
14735 (sqrt:TF (float_extend:TF
14736 (match_operand:DF 1 "register_operand" "0"))))]
14737 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14738 "fsqrt"
14739 [(set_attr "type" "fpspc")
14740 (set_attr "mode" "XF")
14741 (set_attr "athlon_decode" "direct")])
14742
14743(define_insn "*sqrtextendsfxf2"
14744 [(set (match_operand:XF 0 "register_operand" "=f")
14745 (sqrt:XF (float_extend:XF
14746 (match_operand:SF 1 "register_operand" "0"))))]
14586 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
14747 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14587 "fsqrt"
14588 [(set_attr "type" "fpspc")
14589 (set_attr "mode" "XF")
14590 (set_attr "athlon_decode" "direct")])
14591
14592(define_insn "*sqrtextendsftf2"
14593 [(set (match_operand:TF 0 "register_operand" "=f")
14594 (sqrt:TF (float_extend:TF
14595 (match_operand:SF 1 "register_operand" "0"))))]
14596 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14597 "fsqrt"
14598 [(set_attr "type" "fpspc")
14599 (set_attr "mode" "XF")
14600 (set_attr "athlon_decode" "direct")])
14601
14602(define_insn "sindf2"
14603 [(set (match_operand:DF 0 "register_operand" "=f")
14604 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
14605 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14606 && flag_unsafe_math_optimizations"
14607 "fsin"
14608 [(set_attr "type" "fpspc")
14609 (set_attr "mode" "DF")])
14610
14611(define_insn "sinsf2"
14612 [(set (match_operand:SF 0 "register_operand" "=f")
14613 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
14614 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14615 && flag_unsafe_math_optimizations"
14616 "fsin"
14617 [(set_attr "type" "fpspc")
14618 (set_attr "mode" "SF")])
14619
14620(define_insn "*sinextendsfdf2"
14621 [(set (match_operand:DF 0 "register_operand" "=f")
14622 (unspec:DF [(float_extend:DF
14623 (match_operand:SF 1 "register_operand" "0"))] 1))]
14624 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14625 && flag_unsafe_math_optimizations"
14626 "fsin"
14627 [(set_attr "type" "fpspc")
14628 (set_attr "mode" "DF")])
14629
14630(define_insn "sinxf2"
14631 [(set (match_operand:XF 0 "register_operand" "=f")
14632 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
14748 "fsqrt"
14749 [(set_attr "type" "fpspc")
14750 (set_attr "mode" "XF")
14751 (set_attr "athlon_decode" "direct")])
14752
14753(define_insn "*sqrtextendsftf2"
14754 [(set (match_operand:TF 0 "register_operand" "=f")
14755 (sqrt:TF (float_extend:TF
14756 (match_operand:SF 1 "register_operand" "0"))))]
14757 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14758 "fsqrt"
14759 [(set_attr "type" "fpspc")
14760 (set_attr "mode" "XF")
14761 (set_attr "athlon_decode" "direct")])
14762
14763(define_insn "sindf2"
14764 [(set (match_operand:DF 0 "register_operand" "=f")
14765 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
14766 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14767 && flag_unsafe_math_optimizations"
14768 "fsin"
14769 [(set_attr "type" "fpspc")
14770 (set_attr "mode" "DF")])
14771
14772(define_insn "sinsf2"
14773 [(set (match_operand:SF 0 "register_operand" "=f")
14774 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
14775 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14776 && flag_unsafe_math_optimizations"
14777 "fsin"
14778 [(set_attr "type" "fpspc")
14779 (set_attr "mode" "SF")])
14780
14781(define_insn "*sinextendsfdf2"
14782 [(set (match_operand:DF 0 "register_operand" "=f")
14783 (unspec:DF [(float_extend:DF
14784 (match_operand:SF 1 "register_operand" "0"))] 1))]
14785 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14786 && flag_unsafe_math_optimizations"
14787 "fsin"
14788 [(set_attr "type" "fpspc")
14789 (set_attr "mode" "DF")])
14790
14791(define_insn "sinxf2"
14792 [(set (match_operand:XF 0 "register_operand" "=f")
14793 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
14633 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387
14794 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14634 && flag_unsafe_math_optimizations"
14635 "fsin"
14636 [(set_attr "type" "fpspc")
14637 (set_attr "mode" "XF")])
14638
14639(define_insn "sintf2"
14640 [(set (match_operand:TF 0 "register_operand" "=f")
14641 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
14642 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14643 && flag_unsafe_math_optimizations"
14644 "fsin"
14645 [(set_attr "type" "fpspc")
14646 (set_attr "mode" "XF")])
14647
14648(define_insn "cosdf2"
14649 [(set (match_operand:DF 0 "register_operand" "=f")
14650 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
14651 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14652 && flag_unsafe_math_optimizations"
14653 "fcos"
14654 [(set_attr "type" "fpspc")
14655 (set_attr "mode" "DF")])
14656
14657(define_insn "cossf2"
14658 [(set (match_operand:SF 0 "register_operand" "=f")
14659 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
14660 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14661 && flag_unsafe_math_optimizations"
14662 "fcos"
14663 [(set_attr "type" "fpspc")
14664 (set_attr "mode" "SF")])
14665
14666(define_insn "*cosextendsfdf2"
14667 [(set (match_operand:DF 0 "register_operand" "=f")
14668 (unspec:DF [(float_extend:DF
14669 (match_operand:SF 1 "register_operand" "0"))] 2))]
14670 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14671 && flag_unsafe_math_optimizations"
14672 "fcos"
14673 [(set_attr "type" "fpspc")
14674 (set_attr "mode" "DF")])
14675
14676(define_insn "cosxf2"
14677 [(set (match_operand:XF 0 "register_operand" "=f")
14678 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
14679 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14680 && flag_unsafe_math_optimizations"
14681 "fcos"
14682 [(set_attr "type" "fpspc")
14683 (set_attr "mode" "XF")])
14684
14685(define_insn "costf2"
14686 [(set (match_operand:TF 0 "register_operand" "=f")
14687 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
14688 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14689 && flag_unsafe_math_optimizations"
14690 "fcos"
14691 [(set_attr "type" "fpspc")
14692 (set_attr "mode" "XF")])
14693
14694;; Block operation instructions
14695
14696(define_insn "cld"
14697 [(set (reg:SI 19) (const_int 0))]
14698 ""
14699 "cld"
14700 [(set_attr "type" "cld")])
14701
14702(define_expand "movstrsi"
14703 [(use (match_operand:BLK 0 "memory_operand" ""))
14704 (use (match_operand:BLK 1 "memory_operand" ""))
14705 (use (match_operand:SI 2 "nonmemory_operand" ""))
14706 (use (match_operand:SI 3 "const_int_operand" ""))]
14707 ""
14708{
14709 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14710 DONE;
14711 else
14712 FAIL;
14713})
14714
14715(define_expand "movstrdi"
14716 [(use (match_operand:BLK 0 "memory_operand" ""))
14717 (use (match_operand:BLK 1 "memory_operand" ""))
14718 (use (match_operand:DI 2 "nonmemory_operand" ""))
14719 (use (match_operand:DI 3 "const_int_operand" ""))]
14720 "TARGET_64BIT"
14721{
14722 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14723 DONE;
14724 else
14725 FAIL;
14726})
14727
14728;; Most CPUs don't like single string operations
14729;; Handle this case here to simplify previous expander.
14730
14731(define_expand "strmovdi_rex64"
14732 [(set (match_dup 2)
14733 (mem:DI (match_operand:DI 1 "register_operand" "")))
14734 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14735 (match_dup 2))
14736 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14737 (clobber (reg:CC 17))])
14738 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14739 (clobber (reg:CC 17))])]
14740 "TARGET_64BIT"
14741{
14742 if (TARGET_SINGLE_STRINGOP || optimize_size)
14743 {
14744 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14745 operands[1]));
14746 DONE;
14747 }
14748 else
14749 operands[2] = gen_reg_rtx (DImode);
14750})
14751
14752
14753(define_expand "strmovsi"
14754 [(set (match_dup 2)
14755 (mem:SI (match_operand:SI 1 "register_operand" "")))
14756 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14757 (match_dup 2))
14758 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14759 (clobber (reg:CC 17))])
14760 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14761 (clobber (reg:CC 17))])]
14762 ""
14763{
14764 if (TARGET_64BIT)
14765 {
14766 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14767 DONE;
14768 }
14769 if (TARGET_SINGLE_STRINGOP || optimize_size)
14770 {
14771 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14772 operands[1]));
14773 DONE;
14774 }
14775 else
14776 operands[2] = gen_reg_rtx (SImode);
14777})
14778
14779(define_expand "strmovsi_rex64"
14780 [(set (match_dup 2)
14781 (mem:SI (match_operand:DI 1 "register_operand" "")))
14782 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14783 (match_dup 2))
14784 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14785 (clobber (reg:CC 17))])
14786 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14787 (clobber (reg:CC 17))])]
14788 "TARGET_64BIT"
14789{
14790 if (TARGET_SINGLE_STRINGOP || optimize_size)
14791 {
14792 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14793 operands[1]));
14794 DONE;
14795 }
14796 else
14797 operands[2] = gen_reg_rtx (SImode);
14798})
14799
14800(define_expand "strmovhi"
14801 [(set (match_dup 2)
14802 (mem:HI (match_operand:SI 1 "register_operand" "")))
14803 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14804 (match_dup 2))
14805 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14806 (clobber (reg:CC 17))])
14807 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14808 (clobber (reg:CC 17))])]
14809 ""
14810{
14811 if (TARGET_64BIT)
14812 {
14813 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14814 DONE;
14815 }
14816 if (TARGET_SINGLE_STRINGOP || optimize_size)
14817 {
14818 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14819 operands[1]));
14820 DONE;
14821 }
14822 else
14823 operands[2] = gen_reg_rtx (HImode);
14824})
14825
14826(define_expand "strmovhi_rex64"
14827 [(set (match_dup 2)
14828 (mem:HI (match_operand:DI 1 "register_operand" "")))
14829 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14830 (match_dup 2))
14831 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14832 (clobber (reg:CC 17))])
14833 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14834 (clobber (reg:CC 17))])]
14835 "TARGET_64BIT"
14836{
14837 if (TARGET_SINGLE_STRINGOP || optimize_size)
14838 {
14839 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
14840 operands[1]));
14841 DONE;
14842 }
14843 else
14844 operands[2] = gen_reg_rtx (HImode);
14845})
14846
14847(define_expand "strmovqi"
14848 [(set (match_dup 2)
14849 (mem:QI (match_operand:SI 1 "register_operand" "")))
14850 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
14851 (match_dup 2))
14852 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14853 (clobber (reg:CC 17))])
14854 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
14855 (clobber (reg:CC 17))])]
14856 ""
14857{
14858 if (TARGET_64BIT)
14859 {
14860 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
14861 DONE;
14862 }
14863 if (TARGET_SINGLE_STRINGOP || optimize_size)
14864 {
14865 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
14866 operands[1]));
14867 DONE;
14868 }
14869 else
14870 operands[2] = gen_reg_rtx (QImode);
14871})
14872
14873(define_expand "strmovqi_rex64"
14874 [(set (match_dup 2)
14875 (mem:QI (match_operand:DI 1 "register_operand" "")))
14876 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
14877 (match_dup 2))
14878 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14879 (clobber (reg:CC 17))])
14880 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
14881 (clobber (reg:CC 17))])]
14882 "TARGET_64BIT"
14883{
14884 if (TARGET_SINGLE_STRINGOP || optimize_size)
14885 {
14886 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
14887 operands[1]));
14888 DONE;
14889 }
14890 else
14891 operands[2] = gen_reg_rtx (QImode);
14892})
14893
14894(define_insn "strmovdi_rex_1"
14895 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
14896 (mem:DI (match_operand:DI 3 "register_operand" "1")))
14897 (set (match_operand:DI 0 "register_operand" "=D")
14898 (plus:DI (match_dup 2)
14899 (const_int 8)))
14900 (set (match_operand:DI 1 "register_operand" "=S")
14901 (plus:DI (match_dup 3)
14902 (const_int 8)))
14903 (use (reg:SI 19))]
14904 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14905 "movsq"
14906 [(set_attr "type" "str")
14907 (set_attr "mode" "DI")
14908 (set_attr "memory" "both")])
14909
14910(define_insn "strmovsi_1"
14911 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
14912 (mem:SI (match_operand:SI 3 "register_operand" "1")))
14913 (set (match_operand:SI 0 "register_operand" "=D")
14914 (plus:SI (match_dup 2)
14915 (const_int 4)))
14916 (set (match_operand:SI 1 "register_operand" "=S")
14917 (plus:SI (match_dup 3)
14918 (const_int 4)))
14919 (use (reg:SI 19))]
14920 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14921 "{movsl|movsd}"
14922 [(set_attr "type" "str")
14923 (set_attr "mode" "SI")
14924 (set_attr "memory" "both")])
14925
14926(define_insn "strmovsi_rex_1"
14927 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
14928 (mem:SI (match_operand:DI 3 "register_operand" "1")))
14929 (set (match_operand:DI 0 "register_operand" "=D")
14930 (plus:DI (match_dup 2)
14931 (const_int 4)))
14932 (set (match_operand:DI 1 "register_operand" "=S")
14933 (plus:DI (match_dup 3)
14934 (const_int 4)))
14935 (use (reg:SI 19))]
14936 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14937 "{movsl|movsd}"
14938 [(set_attr "type" "str")
14939 (set_attr "mode" "SI")
14940 (set_attr "memory" "both")])
14941
14942(define_insn "strmovhi_1"
14943 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
14944 (mem:HI (match_operand:SI 3 "register_operand" "1")))
14945 (set (match_operand:SI 0 "register_operand" "=D")
14946 (plus:SI (match_dup 2)
14947 (const_int 2)))
14948 (set (match_operand:SI 1 "register_operand" "=S")
14949 (plus:SI (match_dup 3)
14950 (const_int 2)))
14951 (use (reg:SI 19))]
14952 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14953 "movsw"
14954 [(set_attr "type" "str")
14955 (set_attr "memory" "both")
14956 (set_attr "mode" "HI")])
14957
14958(define_insn "strmovhi_rex_1"
14959 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
14960 (mem:HI (match_operand:DI 3 "register_operand" "1")))
14961 (set (match_operand:DI 0 "register_operand" "=D")
14962 (plus:DI (match_dup 2)
14963 (const_int 2)))
14964 (set (match_operand:DI 1 "register_operand" "=S")
14965 (plus:DI (match_dup 3)
14966 (const_int 2)))
14967 (use (reg:SI 19))]
14968 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14969 "movsw"
14970 [(set_attr "type" "str")
14971 (set_attr "memory" "both")
14972 (set_attr "mode" "HI")])
14973
14974(define_insn "strmovqi_1"
14975 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
14976 (mem:QI (match_operand:SI 3 "register_operand" "1")))
14977 (set (match_operand:SI 0 "register_operand" "=D")
14978 (plus:SI (match_dup 2)
14979 (const_int 1)))
14980 (set (match_operand:SI 1 "register_operand" "=S")
14981 (plus:SI (match_dup 3)
14982 (const_int 1)))
14983 (use (reg:SI 19))]
14984 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14985 "movsb"
14986 [(set_attr "type" "str")
14987 (set_attr "memory" "both")
14988 (set_attr "mode" "QI")])
14989
14990(define_insn "strmovqi_rex_1"
14991 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
14992 (mem:QI (match_operand:DI 3 "register_operand" "1")))
14993 (set (match_operand:DI 0 "register_operand" "=D")
14994 (plus:DI (match_dup 2)
14995 (const_int 1)))
14996 (set (match_operand:DI 1 "register_operand" "=S")
14997 (plus:DI (match_dup 3)
14998 (const_int 1)))
14999 (use (reg:SI 19))]
15000 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15001 "movsb"
15002 [(set_attr "type" "str")
15003 (set_attr "memory" "both")
15004 (set_attr "mode" "QI")])
15005
15006(define_insn "rep_movdi_rex64"
15007 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15008 (set (match_operand:DI 0 "register_operand" "=D")
15009 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15010 (const_int 3))
15011 (match_operand:DI 3 "register_operand" "0")))
15012 (set (match_operand:DI 1 "register_operand" "=S")
15013 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15014 (match_operand:DI 4 "register_operand" "1")))
15015 (set (mem:BLK (match_dup 3))
15016 (mem:BLK (match_dup 4)))
15017 (use (match_dup 5))
15018 (use (reg:SI 19))]
15019 "TARGET_64BIT"
15020 "{rep\;movsq|rep movsq}"
15021 [(set_attr "type" "str")
15022 (set_attr "prefix_rep" "1")
15023 (set_attr "memory" "both")
15024 (set_attr "mode" "DI")])
15025
15026(define_insn "rep_movsi"
15027 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15028 (set (match_operand:SI 0 "register_operand" "=D")
15029 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15030 (const_int 2))
15031 (match_operand:SI 3 "register_operand" "0")))
15032 (set (match_operand:SI 1 "register_operand" "=S")
15033 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15034 (match_operand:SI 4 "register_operand" "1")))
15035 (set (mem:BLK (match_dup 3))
15036 (mem:BLK (match_dup 4)))
15037 (use (match_dup 5))
15038 (use (reg:SI 19))]
15039 "!TARGET_64BIT"
15040 "{rep\;movsl|rep movsd}"
15041 [(set_attr "type" "str")
15042 (set_attr "prefix_rep" "1")
15043 (set_attr "memory" "both")
15044 (set_attr "mode" "SI")])
15045
15046(define_insn "rep_movsi_rex64"
15047 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15048 (set (match_operand:DI 0 "register_operand" "=D")
15049 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15050 (const_int 2))
15051 (match_operand:DI 3 "register_operand" "0")))
15052 (set (match_operand:DI 1 "register_operand" "=S")
15053 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15054 (match_operand:DI 4 "register_operand" "1")))
15055 (set (mem:BLK (match_dup 3))
15056 (mem:BLK (match_dup 4)))
15057 (use (match_dup 5))
15058 (use (reg:SI 19))]
15059 "TARGET_64BIT"
15060 "{rep\;movsl|rep movsd}"
15061 [(set_attr "type" "str")
15062 (set_attr "prefix_rep" "1")
15063 (set_attr "memory" "both")
15064 (set_attr "mode" "SI")])
15065
15066(define_insn "rep_movqi"
15067 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15068 (set (match_operand:SI 0 "register_operand" "=D")
15069 (plus:SI (match_operand:SI 3 "register_operand" "0")
15070 (match_operand:SI 5 "register_operand" "2")))
15071 (set (match_operand:SI 1 "register_operand" "=S")
15072 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15073 (set (mem:BLK (match_dup 3))
15074 (mem:BLK (match_dup 4)))
15075 (use (match_dup 5))
15076 (use (reg:SI 19))]
15077 "!TARGET_64BIT"
15078 "{rep\;movsb|rep movsb}"
15079 [(set_attr "type" "str")
15080 (set_attr "prefix_rep" "1")
15081 (set_attr "memory" "both")
15082 (set_attr "mode" "SI")])
15083
15084(define_insn "rep_movqi_rex64"
15085 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15086 (set (match_operand:DI 0 "register_operand" "=D")
15087 (plus:DI (match_operand:DI 3 "register_operand" "0")
15088 (match_operand:DI 5 "register_operand" "2")))
15089 (set (match_operand:DI 1 "register_operand" "=S")
15090 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15091 (set (mem:BLK (match_dup 3))
15092 (mem:BLK (match_dup 4)))
15093 (use (match_dup 5))
15094 (use (reg:SI 19))]
15095 "TARGET_64BIT"
15096 "{rep\;movsb|rep movsb}"
15097 [(set_attr "type" "str")
15098 (set_attr "prefix_rep" "1")
15099 (set_attr "memory" "both")
15100 (set_attr "mode" "SI")])
15101
15102(define_expand "clrstrsi"
15103 [(use (match_operand:BLK 0 "memory_operand" ""))
15104 (use (match_operand:SI 1 "nonmemory_operand" ""))
15105 (use (match_operand 2 "const_int_operand" ""))]
15106 ""
15107{
15108 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15109 DONE;
15110 else
15111 FAIL;
15112})
15113
15114(define_expand "clrstrdi"
15115 [(use (match_operand:BLK 0 "memory_operand" ""))
15116 (use (match_operand:DI 1 "nonmemory_operand" ""))
15117 (use (match_operand 2 "const_int_operand" ""))]
15118 "TARGET_64BIT"
15119{
15120 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15121 DONE;
15122 else
15123 FAIL;
15124})
15125
15126;; Most CPUs don't like single string operations
15127;; Handle this case here to simplify previous expander.
15128
15129(define_expand "strsetdi_rex64"
15130 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15131 (match_operand:DI 1 "register_operand" ""))
15132 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15133 (clobber (reg:CC 17))])]
15134 "TARGET_64BIT"
15135{
15136 if (TARGET_SINGLE_STRINGOP || optimize_size)
15137 {
15138 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15139 DONE;
15140 }
15141})
15142
15143(define_expand "strsetsi"
15144 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15145 (match_operand:SI 1 "register_operand" ""))
15146 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15147 (clobber (reg:CC 17))])]
15148 ""
15149{
15150 if (TARGET_64BIT)
15151 {
15152 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15153 DONE;
15154 }
15155 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15156 {
15157 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15158 DONE;
15159 }
15160})
15161
15162(define_expand "strsetsi_rex64"
15163 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15164 (match_operand:SI 1 "register_operand" ""))
15165 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15166 (clobber (reg:CC 17))])]
15167 "TARGET_64BIT"
15168{
15169 if (TARGET_SINGLE_STRINGOP || optimize_size)
15170 {
15171 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15172 DONE;
15173 }
15174})
15175
15176(define_expand "strsethi"
15177 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15178 (match_operand:HI 1 "register_operand" ""))
15179 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15180 (clobber (reg:CC 17))])]
15181 ""
15182{
15183 if (TARGET_64BIT)
15184 {
15185 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15186 DONE;
15187 }
15188 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15189 {
15190 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15191 DONE;
15192 }
15193})
15194
15195(define_expand "strsethi_rex64"
15196 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15197 (match_operand:HI 1 "register_operand" ""))
15198 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15199 (clobber (reg:CC 17))])]
15200 "TARGET_64BIT"
15201{
15202 if (TARGET_SINGLE_STRINGOP || optimize_size)
15203 {
15204 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15205 DONE;
15206 }
15207})
15208
15209(define_expand "strsetqi"
15210 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15211 (match_operand:QI 1 "register_operand" ""))
15212 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15213 (clobber (reg:CC 17))])]
15214 ""
15215{
15216 if (TARGET_64BIT)
15217 {
15218 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
15219 DONE;
15220 }
15221 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15222 {
15223 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
15224 DONE;
15225 }
15226})
15227
15228(define_expand "strsetqi_rex64"
15229 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
15230 (match_operand:QI 1 "register_operand" ""))
15231 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15232 (clobber (reg:CC 17))])]
15233 "TARGET_64BIT"
15234{
15235 if (TARGET_SINGLE_STRINGOP || optimize_size)
15236 {
15237 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15238 DONE;
15239 }
15240})
15241
15242(define_insn "strsetdi_rex_1"
15243 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15244 (match_operand:SI 2 "register_operand" "a"))
15245 (set (match_operand:DI 0 "register_operand" "=D")
15246 (plus:DI (match_dup 1)
15247 (const_int 8)))
15248 (use (reg:SI 19))]
15249 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15250 "stosq"
15251 [(set_attr "type" "str")
15252 (set_attr "memory" "store")
15253 (set_attr "mode" "DI")])
15254
15255(define_insn "strsetsi_1"
15256 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15257 (match_operand:SI 2 "register_operand" "a"))
15258 (set (match_operand:SI 0 "register_operand" "=D")
15259 (plus:SI (match_dup 1)
15260 (const_int 4)))
15261 (use (reg:SI 19))]
15262 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15263 "{stosl|stosd}"
15264 [(set_attr "type" "str")
15265 (set_attr "memory" "store")
15266 (set_attr "mode" "SI")])
15267
15268(define_insn "strsetsi_rex_1"
15269 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15270 (match_operand:SI 2 "register_operand" "a"))
15271 (set (match_operand:DI 0 "register_operand" "=D")
15272 (plus:DI (match_dup 1)
15273 (const_int 4)))
15274 (use (reg:SI 19))]
15275 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15276 "{stosl|stosd}"
15277 [(set_attr "type" "str")
15278 (set_attr "memory" "store")
15279 (set_attr "mode" "SI")])
15280
15281(define_insn "strsethi_1"
15282 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15283 (match_operand:HI 2 "register_operand" "a"))
15284 (set (match_operand:SI 0 "register_operand" "=D")
15285 (plus:SI (match_dup 1)
15286 (const_int 2)))
15287 (use (reg:SI 19))]
15288 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15289 "stosw"
15290 [(set_attr "type" "str")
15291 (set_attr "memory" "store")
15292 (set_attr "mode" "HI")])
15293
15294(define_insn "strsethi_rex_1"
15295 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15296 (match_operand:HI 2 "register_operand" "a"))
15297 (set (match_operand:DI 0 "register_operand" "=D")
15298 (plus:DI (match_dup 1)
15299 (const_int 2)))
15300 (use (reg:SI 19))]
15301 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15302 "stosw"
15303 [(set_attr "type" "str")
15304 (set_attr "memory" "store")
15305 (set_attr "mode" "HI")])
15306
15307(define_insn "strsetqi_1"
15308 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15309 (match_operand:QI 2 "register_operand" "a"))
15310 (set (match_operand:SI 0 "register_operand" "=D")
15311 (plus:SI (match_dup 1)
15312 (const_int 1)))
15313 (use (reg:SI 19))]
15314 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15315 "stosb"
15316 [(set_attr "type" "str")
15317 (set_attr "memory" "store")
15318 (set_attr "mode" "QI")])
15319
15320(define_insn "strsetqi_rex_1"
15321 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15322 (match_operand:QI 2 "register_operand" "a"))
15323 (set (match_operand:DI 0 "register_operand" "=D")
15324 (plus:DI (match_dup 1)
15325 (const_int 1)))
15326 (use (reg:SI 19))]
15327 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15328 "stosb"
15329 [(set_attr "type" "str")
15330 (set_attr "memory" "store")
15331 (set_attr "mode" "QI")])
15332
15333(define_insn "rep_stosdi_rex64"
15334 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15335 (set (match_operand:DI 0 "register_operand" "=D")
15336 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15337 (const_int 3))
15338 (match_operand:DI 3 "register_operand" "0")))
15339 (set (mem:BLK (match_dup 3))
15340 (const_int 0))
15341 (use (match_operand:DI 2 "register_operand" "a"))
15342 (use (match_dup 4))
15343 (use (reg:SI 19))]
15344 "TARGET_64BIT"
15345 "{rep\;stosq|rep stosq}"
15346 [(set_attr "type" "str")
15347 (set_attr "prefix_rep" "1")
15348 (set_attr "memory" "store")
15349 (set_attr "mode" "DI")])
15350
15351(define_insn "rep_stossi"
15352 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15353 (set (match_operand:SI 0 "register_operand" "=D")
15354 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15355 (const_int 2))
15356 (match_operand:SI 3 "register_operand" "0")))
15357 (set (mem:BLK (match_dup 3))
15358 (const_int 0))
15359 (use (match_operand:SI 2 "register_operand" "a"))
15360 (use (match_dup 4))
15361 (use (reg:SI 19))]
15362 "!TARGET_64BIT"
15363 "{rep\;stosl|rep stosd}"
15364 [(set_attr "type" "str")
15365 (set_attr "prefix_rep" "1")
15366 (set_attr "memory" "store")
15367 (set_attr "mode" "SI")])
15368
15369(define_insn "rep_stossi_rex64"
15370 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15371 (set (match_operand:DI 0 "register_operand" "=D")
15372 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15373 (const_int 2))
15374 (match_operand:DI 3 "register_operand" "0")))
15375 (set (mem:BLK (match_dup 3))
15376 (const_int 0))
15377 (use (match_operand:SI 2 "register_operand" "a"))
15378 (use (match_dup 4))
15379 (use (reg:SI 19))]
15380 "TARGET_64BIT"
15381 "{rep\;stosl|rep stosd}"
15382 [(set_attr "type" "str")
15383 (set_attr "prefix_rep" "1")
15384 (set_attr "memory" "store")
15385 (set_attr "mode" "SI")])
15386
15387(define_insn "rep_stosqi"
15388 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15389 (set (match_operand:SI 0 "register_operand" "=D")
15390 (plus:SI (match_operand:SI 3 "register_operand" "0")
15391 (match_operand:SI 4 "register_operand" "1")))
15392 (set (mem:BLK (match_dup 3))
15393 (const_int 0))
15394 (use (match_operand:QI 2 "register_operand" "a"))
15395 (use (match_dup 4))
15396 (use (reg:SI 19))]
15397 "!TARGET_64BIT"
15398 "{rep\;stosb|rep stosb}"
15399 [(set_attr "type" "str")
15400 (set_attr "prefix_rep" "1")
15401 (set_attr "memory" "store")
15402 (set_attr "mode" "QI")])
15403
15404(define_insn "rep_stosqi_rex64"
15405 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15406 (set (match_operand:DI 0 "register_operand" "=D")
15407 (plus:DI (match_operand:DI 3 "register_operand" "0")
15408 (match_operand:DI 4 "register_operand" "1")))
15409 (set (mem:BLK (match_dup 3))
15410 (const_int 0))
15411 (use (match_operand:QI 2 "register_operand" "a"))
15412 (use (match_dup 4))
15413 (use (reg:DI 19))]
15414 "TARGET_64BIT"
15415 "{rep\;stosb|rep stosb}"
15416 [(set_attr "type" "str")
15417 (set_attr "prefix_rep" "1")
15418 (set_attr "memory" "store")
15419 (set_attr "mode" "QI")])
15420
15421(define_expand "cmpstrsi"
15422 [(set (match_operand:SI 0 "register_operand" "")
15423 (compare:SI (match_operand:BLK 1 "general_operand" "")
15424 (match_operand:BLK 2 "general_operand" "")))
15425 (use (match_operand 3 "general_operand" ""))
15426 (use (match_operand 4 "immediate_operand" ""))]
15427 ""
15428{
15429 rtx addr1, addr2, out, outlow, count, countreg, align;
15430
15431 out = operands[0];
15432 if (GET_CODE (out) != REG)
15433 out = gen_reg_rtx (SImode);
15434
15435 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15436 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15437
15438 count = operands[3];
15439 countreg = ix86_zero_extend_to_Pmode (count);
15440
15441 /* %%% Iff we are testing strict equality, we can use known alignment
15442 to good advantage. This may be possible with combine, particularly
15443 once cc0 is dead. */
15444 align = operands[4];
15445
15446 emit_insn (gen_cld ());
15447 if (GET_CODE (count) == CONST_INT)
15448 {
15449 if (INTVAL (count) == 0)
15450 {
15451 emit_move_insn (operands[0], const0_rtx);
15452 DONE;
15453 }
15454 if (TARGET_64BIT)
15455 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15456 addr1, addr2, countreg));
15457 else
15458 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15459 addr1, addr2, countreg));
15460 }
15461 else
15462 {
15463 if (TARGET_64BIT)
15464 {
15465 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15466 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15467 addr1, addr2, countreg));
15468 }
15469 else
15470 {
15471 emit_insn (gen_cmpsi_1 (countreg, countreg));
15472 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15473 addr1, addr2, countreg));
15474 }
15475 }
15476
15477 outlow = gen_lowpart (QImode, out);
15478 emit_insn (gen_cmpintqi (outlow));
15479 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15480
15481 if (operands[0] != out)
15482 emit_move_insn (operands[0], out);
15483
15484 DONE;
15485})
15486
15487;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15488
15489(define_expand "cmpintqi"
15490 [(set (match_dup 1)
15491 (gtu:QI (reg:CC 17) (const_int 0)))
15492 (set (match_dup 2)
15493 (ltu:QI (reg:CC 17) (const_int 0)))
15494 (parallel [(set (match_operand:QI 0 "register_operand" "")
15495 (minus:QI (match_dup 1)
15496 (match_dup 2)))
15497 (clobber (reg:CC 17))])]
15498 ""
15499 "operands[1] = gen_reg_rtx (QImode);
15500 operands[2] = gen_reg_rtx (QImode);")
15501
15502;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15503;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15504
15505(define_insn "cmpstrqi_nz_1"
15506 [(set (reg:CC 17)
15507 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15508 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15509 (use (match_operand:SI 6 "register_operand" "2"))
15510 (use (match_operand:SI 3 "immediate_operand" "i"))
15511 (use (reg:SI 19))
15512 (clobber (match_operand:SI 0 "register_operand" "=S"))
15513 (clobber (match_operand:SI 1 "register_operand" "=D"))
15514 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15515 "!TARGET_64BIT"
15516 "repz{\;| }cmpsb"
15517 [(set_attr "type" "str")
15518 (set_attr "mode" "QI")
15519 (set_attr "prefix_rep" "1")])
15520
15521(define_insn "cmpstrqi_nz_rex_1"
15522 [(set (reg:CC 17)
15523 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15524 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15525 (use (match_operand:DI 6 "register_operand" "2"))
15526 (use (match_operand:SI 3 "immediate_operand" "i"))
15527 (use (reg:SI 19))
15528 (clobber (match_operand:DI 0 "register_operand" "=S"))
15529 (clobber (match_operand:DI 1 "register_operand" "=D"))
15530 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15531 "TARGET_64BIT"
15532 "repz{\;| }cmpsb"
15533 [(set_attr "type" "str")
15534 (set_attr "mode" "QI")
15535 (set_attr "prefix_rep" "1")])
15536
15537;; The same, but the count is not known to not be zero.
15538
15539(define_insn "cmpstrqi_1"
15540 [(set (reg:CC 17)
15541 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15542 (const_int 0))
15543 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15544 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15545 (const_int 0)))
15546 (use (match_operand:SI 3 "immediate_operand" "i"))
15547 (use (reg:CC 17))
15548 (use (reg:SI 19))
15549 (clobber (match_operand:SI 0 "register_operand" "=S"))
15550 (clobber (match_operand:SI 1 "register_operand" "=D"))
15551 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15552 "!TARGET_64BIT"
15553 "repz{\;| }cmpsb"
15554 [(set_attr "type" "str")
15555 (set_attr "mode" "QI")
15556 (set_attr "prefix_rep" "1")])
15557
15558(define_insn "cmpstrqi_rex_1"
15559 [(set (reg:CC 17)
15560 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15561 (const_int 0))
15562 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15563 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15564 (const_int 0)))
15565 (use (match_operand:SI 3 "immediate_operand" "i"))
15566 (use (reg:CC 17))
15567 (use (reg:SI 19))
15568 (clobber (match_operand:DI 0 "register_operand" "=S"))
15569 (clobber (match_operand:DI 1 "register_operand" "=D"))
15570 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15571 "TARGET_64BIT"
15572 "repz{\;| }cmpsb"
15573 [(set_attr "type" "str")
15574 (set_attr "mode" "QI")
15575 (set_attr "prefix_rep" "1")])
15576
15577(define_expand "strlensi"
15578 [(set (match_operand:SI 0 "register_operand" "")
15579 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15580 (match_operand:QI 2 "immediate_operand" "")
15581 (match_operand 3 "immediate_operand" "")] 0))]
15582 ""
15583{
15584 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15585 DONE;
15586 else
15587 FAIL;
15588})
15589
15590(define_expand "strlendi"
15591 [(set (match_operand:DI 0 "register_operand" "")
15592 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15593 (match_operand:QI 2 "immediate_operand" "")
15594 (match_operand 3 "immediate_operand" "")] 0))]
15595 ""
15596{
15597 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15598 DONE;
15599 else
15600 FAIL;
15601})
15602
15603(define_insn "strlenqi_1"
15604 [(set (match_operand:SI 0 "register_operand" "=&c")
15605 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15606 (match_operand:QI 2 "register_operand" "a")
15607 (match_operand:SI 3 "immediate_operand" "i")
15608 (match_operand:SI 4 "register_operand" "0")] 0))
15609 (use (reg:SI 19))
15610 (clobber (match_operand:SI 1 "register_operand" "=D"))
15611 (clobber (reg:CC 17))]
15612 "!TARGET_64BIT"
15613 "repnz{\;| }scasb"
15614 [(set_attr "type" "str")
15615 (set_attr "mode" "QI")
15616 (set_attr "prefix_rep" "1")])
15617
15618(define_insn "strlenqi_rex_1"
15619 [(set (match_operand:DI 0 "register_operand" "=&c")
15620 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15621 (match_operand:QI 2 "register_operand" "a")
15622 (match_operand:DI 3 "immediate_operand" "i")
15623 (match_operand:DI 4 "register_operand" "0")] 0))
15624 (use (reg:SI 19))
15625 (clobber (match_operand:DI 1 "register_operand" "=D"))
15626 (clobber (reg:CC 17))]
15627 "TARGET_64BIT"
15628 "repnz{\;| }scasb"
15629 [(set_attr "type" "str")
15630 (set_attr "mode" "QI")
15631 (set_attr "prefix_rep" "1")])
15632
15633;; Peephole optimizations to clean up after cmpstr*. This should be
15634;; handled in combine, but it is not currently up to the task.
15635;; When used for their truth value, the cmpstr* expanders generate
15636;; code like this:
15637;;
15638;; repz cmpsb
15639;; seta %al
15640;; setb %dl
15641;; cmpb %al, %dl
15642;; jcc label
15643;;
15644;; The intermediate three instructions are unnecessary.
15645
15646;; This one handles cmpstr*_nz_1...
15647(define_peephole2
15648 [(parallel[
15649 (set (reg:CC 17)
15650 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15651 (mem:BLK (match_operand 5 "register_operand" ""))))
15652 (use (match_operand 6 "register_operand" ""))
15653 (use (match_operand:SI 3 "immediate_operand" ""))
15654 (use (reg:SI 19))
15655 (clobber (match_operand 0 "register_operand" ""))
15656 (clobber (match_operand 1 "register_operand" ""))
15657 (clobber (match_operand 2 "register_operand" ""))])
15658 (set (match_operand:QI 7 "register_operand" "")
15659 (gtu:QI (reg:CC 17) (const_int 0)))
15660 (set (match_operand:QI 8 "register_operand" "")
15661 (ltu:QI (reg:CC 17) (const_int 0)))
15662 (set (reg 17)
15663 (compare (match_dup 7) (match_dup 8)))
15664 ]
15665 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15666 [(parallel[
15667 (set (reg:CC 17)
15668 (compare:CC (mem:BLK (match_dup 4))
15669 (mem:BLK (match_dup 5))))
15670 (use (match_dup 6))
15671 (use (match_dup 3))
15672 (use (reg:SI 19))
15673 (clobber (match_dup 0))
15674 (clobber (match_dup 1))
15675 (clobber (match_dup 2))])]
15676 "")
15677
15678;; ...and this one handles cmpstr*_1.
15679(define_peephole2
15680 [(parallel[
15681 (set (reg:CC 17)
15682 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15683 (const_int 0))
15684 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15685 (mem:BLK (match_operand 5 "register_operand" "")))
15686 (const_int 0)))
15687 (use (match_operand:SI 3 "immediate_operand" ""))
15688 (use (reg:CC 17))
15689 (use (reg:SI 19))
15690 (clobber (match_operand 0 "register_operand" ""))
15691 (clobber (match_operand 1 "register_operand" ""))
15692 (clobber (match_operand 2 "register_operand" ""))])
15693 (set (match_operand:QI 7 "register_operand" "")
15694 (gtu:QI (reg:CC 17) (const_int 0)))
15695 (set (match_operand:QI 8 "register_operand" "")
15696 (ltu:QI (reg:CC 17) (const_int 0)))
15697 (set (reg 17)
15698 (compare (match_dup 7) (match_dup 8)))
15699 ]
15700 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15701 [(parallel[
15702 (set (reg:CC 17)
15703 (if_then_else:CC (ne (match_dup 6)
15704 (const_int 0))
15705 (compare:CC (mem:BLK (match_dup 4))
15706 (mem:BLK (match_dup 5)))
15707 (const_int 0)))
15708 (use (match_dup 3))
15709 (use (reg:CC 17))
15710 (use (reg:SI 19))
15711 (clobber (match_dup 0))
15712 (clobber (match_dup 1))
15713 (clobber (match_dup 2))])]
15714 "")
15715
15716
15717
15718;; Conditional move instructions.
15719
15720(define_expand "movdicc"
15721 [(set (match_operand:DI 0 "register_operand" "")
15722 (if_then_else:DI (match_operand 1 "comparison_operator" "")
15723 (match_operand:DI 2 "general_operand" "")
15724 (match_operand:DI 3 "general_operand" "")))]
15725 "TARGET_64BIT"
15726 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15727
15728(define_insn "x86_movdicc_0_m1_rex64"
15729 [(set (match_operand:DI 0 "register_operand" "=r")
15730 (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15731 (const_int -1)
15732 (const_int 0)))
15733 (clobber (reg:CC 17))]
15734 "TARGET_64BIT"
15735 "sbb{q}\t%0, %0"
15736 ; Since we don't have the proper number of operands for an alu insn,
15737 ; fill in all the blanks.
15738 [(set_attr "type" "alu")
15739 (set_attr "memory" "none")
15740 (set_attr "imm_disp" "false")
15741 (set_attr "mode" "DI")
15742 (set_attr "length_immediate" "0")])
15743
15744(define_insn "*movdicc_c_rex64"
15745 [(set (match_operand:DI 0 "register_operand" "=r,r")
15746 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
15747 [(reg 17) (const_int 0)])
15748 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15749 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15750 "TARGET_64BIT && TARGET_CMOVE
15751 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15752 "@
14795 && flag_unsafe_math_optimizations"
14796 "fsin"
14797 [(set_attr "type" "fpspc")
14798 (set_attr "mode" "XF")])
14799
14800(define_insn "sintf2"
14801 [(set (match_operand:TF 0 "register_operand" "=f")
14802 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
14803 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14804 && flag_unsafe_math_optimizations"
14805 "fsin"
14806 [(set_attr "type" "fpspc")
14807 (set_attr "mode" "XF")])
14808
14809(define_insn "cosdf2"
14810 [(set (match_operand:DF 0 "register_operand" "=f")
14811 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
14812 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14813 && flag_unsafe_math_optimizations"
14814 "fcos"
14815 [(set_attr "type" "fpspc")
14816 (set_attr "mode" "DF")])
14817
14818(define_insn "cossf2"
14819 [(set (match_operand:SF 0 "register_operand" "=f")
14820 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
14821 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14822 && flag_unsafe_math_optimizations"
14823 "fcos"
14824 [(set_attr "type" "fpspc")
14825 (set_attr "mode" "SF")])
14826
14827(define_insn "*cosextendsfdf2"
14828 [(set (match_operand:DF 0 "register_operand" "=f")
14829 (unspec:DF [(float_extend:DF
14830 (match_operand:SF 1 "register_operand" "0"))] 2))]
14831 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14832 && flag_unsafe_math_optimizations"
14833 "fcos"
14834 [(set_attr "type" "fpspc")
14835 (set_attr "mode" "DF")])
14836
14837(define_insn "cosxf2"
14838 [(set (match_operand:XF 0 "register_operand" "=f")
14839 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
14840 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14841 && flag_unsafe_math_optimizations"
14842 "fcos"
14843 [(set_attr "type" "fpspc")
14844 (set_attr "mode" "XF")])
14845
14846(define_insn "costf2"
14847 [(set (match_operand:TF 0 "register_operand" "=f")
14848 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
14849 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14850 && flag_unsafe_math_optimizations"
14851 "fcos"
14852 [(set_attr "type" "fpspc")
14853 (set_attr "mode" "XF")])
14854
14855;; Block operation instructions
14856
14857(define_insn "cld"
14858 [(set (reg:SI 19) (const_int 0))]
14859 ""
14860 "cld"
14861 [(set_attr "type" "cld")])
14862
14863(define_expand "movstrsi"
14864 [(use (match_operand:BLK 0 "memory_operand" ""))
14865 (use (match_operand:BLK 1 "memory_operand" ""))
14866 (use (match_operand:SI 2 "nonmemory_operand" ""))
14867 (use (match_operand:SI 3 "const_int_operand" ""))]
14868 ""
14869{
14870 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14871 DONE;
14872 else
14873 FAIL;
14874})
14875
14876(define_expand "movstrdi"
14877 [(use (match_operand:BLK 0 "memory_operand" ""))
14878 (use (match_operand:BLK 1 "memory_operand" ""))
14879 (use (match_operand:DI 2 "nonmemory_operand" ""))
14880 (use (match_operand:DI 3 "const_int_operand" ""))]
14881 "TARGET_64BIT"
14882{
14883 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14884 DONE;
14885 else
14886 FAIL;
14887})
14888
14889;; Most CPUs don't like single string operations
14890;; Handle this case here to simplify previous expander.
14891
14892(define_expand "strmovdi_rex64"
14893 [(set (match_dup 2)
14894 (mem:DI (match_operand:DI 1 "register_operand" "")))
14895 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14896 (match_dup 2))
14897 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14898 (clobber (reg:CC 17))])
14899 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14900 (clobber (reg:CC 17))])]
14901 "TARGET_64BIT"
14902{
14903 if (TARGET_SINGLE_STRINGOP || optimize_size)
14904 {
14905 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14906 operands[1]));
14907 DONE;
14908 }
14909 else
14910 operands[2] = gen_reg_rtx (DImode);
14911})
14912
14913
14914(define_expand "strmovsi"
14915 [(set (match_dup 2)
14916 (mem:SI (match_operand:SI 1 "register_operand" "")))
14917 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14918 (match_dup 2))
14919 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14920 (clobber (reg:CC 17))])
14921 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14922 (clobber (reg:CC 17))])]
14923 ""
14924{
14925 if (TARGET_64BIT)
14926 {
14927 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14928 DONE;
14929 }
14930 if (TARGET_SINGLE_STRINGOP || optimize_size)
14931 {
14932 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14933 operands[1]));
14934 DONE;
14935 }
14936 else
14937 operands[2] = gen_reg_rtx (SImode);
14938})
14939
14940(define_expand "strmovsi_rex64"
14941 [(set (match_dup 2)
14942 (mem:SI (match_operand:DI 1 "register_operand" "")))
14943 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14944 (match_dup 2))
14945 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14946 (clobber (reg:CC 17))])
14947 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14948 (clobber (reg:CC 17))])]
14949 "TARGET_64BIT"
14950{
14951 if (TARGET_SINGLE_STRINGOP || optimize_size)
14952 {
14953 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14954 operands[1]));
14955 DONE;
14956 }
14957 else
14958 operands[2] = gen_reg_rtx (SImode);
14959})
14960
14961(define_expand "strmovhi"
14962 [(set (match_dup 2)
14963 (mem:HI (match_operand:SI 1 "register_operand" "")))
14964 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14965 (match_dup 2))
14966 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14967 (clobber (reg:CC 17))])
14968 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14969 (clobber (reg:CC 17))])]
14970 ""
14971{
14972 if (TARGET_64BIT)
14973 {
14974 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14975 DONE;
14976 }
14977 if (TARGET_SINGLE_STRINGOP || optimize_size)
14978 {
14979 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14980 operands[1]));
14981 DONE;
14982 }
14983 else
14984 operands[2] = gen_reg_rtx (HImode);
14985})
14986
14987(define_expand "strmovhi_rex64"
14988 [(set (match_dup 2)
14989 (mem:HI (match_operand:DI 1 "register_operand" "")))
14990 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14991 (match_dup 2))
14992 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14993 (clobber (reg:CC 17))])
14994 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14995 (clobber (reg:CC 17))])]
14996 "TARGET_64BIT"
14997{
14998 if (TARGET_SINGLE_STRINGOP || optimize_size)
14999 {
15000 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15001 operands[1]));
15002 DONE;
15003 }
15004 else
15005 operands[2] = gen_reg_rtx (HImode);
15006})
15007
15008(define_expand "strmovqi"
15009 [(set (match_dup 2)
15010 (mem:QI (match_operand:SI 1 "register_operand" "")))
15011 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15012 (match_dup 2))
15013 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15014 (clobber (reg:CC 17))])
15015 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15016 (clobber (reg:CC 17))])]
15017 ""
15018{
15019 if (TARGET_64BIT)
15020 {
15021 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15022 DONE;
15023 }
15024 if (TARGET_SINGLE_STRINGOP || optimize_size)
15025 {
15026 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15027 operands[1]));
15028 DONE;
15029 }
15030 else
15031 operands[2] = gen_reg_rtx (QImode);
15032})
15033
15034(define_expand "strmovqi_rex64"
15035 [(set (match_dup 2)
15036 (mem:QI (match_operand:DI 1 "register_operand" "")))
15037 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15038 (match_dup 2))
15039 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15040 (clobber (reg:CC 17))])
15041 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15042 (clobber (reg:CC 17))])]
15043 "TARGET_64BIT"
15044{
15045 if (TARGET_SINGLE_STRINGOP || optimize_size)
15046 {
15047 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15048 operands[1]));
15049 DONE;
15050 }
15051 else
15052 operands[2] = gen_reg_rtx (QImode);
15053})
15054
15055(define_insn "strmovdi_rex_1"
15056 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15057 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15058 (set (match_operand:DI 0 "register_operand" "=D")
15059 (plus:DI (match_dup 2)
15060 (const_int 8)))
15061 (set (match_operand:DI 1 "register_operand" "=S")
15062 (plus:DI (match_dup 3)
15063 (const_int 8)))
15064 (use (reg:SI 19))]
15065 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15066 "movsq"
15067 [(set_attr "type" "str")
15068 (set_attr "mode" "DI")
15069 (set_attr "memory" "both")])
15070
15071(define_insn "strmovsi_1"
15072 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15073 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15074 (set (match_operand:SI 0 "register_operand" "=D")
15075 (plus:SI (match_dup 2)
15076 (const_int 4)))
15077 (set (match_operand:SI 1 "register_operand" "=S")
15078 (plus:SI (match_dup 3)
15079 (const_int 4)))
15080 (use (reg:SI 19))]
15081 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15082 "{movsl|movsd}"
15083 [(set_attr "type" "str")
15084 (set_attr "mode" "SI")
15085 (set_attr "memory" "both")])
15086
15087(define_insn "strmovsi_rex_1"
15088 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15089 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15090 (set (match_operand:DI 0 "register_operand" "=D")
15091 (plus:DI (match_dup 2)
15092 (const_int 4)))
15093 (set (match_operand:DI 1 "register_operand" "=S")
15094 (plus:DI (match_dup 3)
15095 (const_int 4)))
15096 (use (reg:SI 19))]
15097 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15098 "{movsl|movsd}"
15099 [(set_attr "type" "str")
15100 (set_attr "mode" "SI")
15101 (set_attr "memory" "both")])
15102
15103(define_insn "strmovhi_1"
15104 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15105 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15106 (set (match_operand:SI 0 "register_operand" "=D")
15107 (plus:SI (match_dup 2)
15108 (const_int 2)))
15109 (set (match_operand:SI 1 "register_operand" "=S")
15110 (plus:SI (match_dup 3)
15111 (const_int 2)))
15112 (use (reg:SI 19))]
15113 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15114 "movsw"
15115 [(set_attr "type" "str")
15116 (set_attr "memory" "both")
15117 (set_attr "mode" "HI")])
15118
15119(define_insn "strmovhi_rex_1"
15120 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15121 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15122 (set (match_operand:DI 0 "register_operand" "=D")
15123 (plus:DI (match_dup 2)
15124 (const_int 2)))
15125 (set (match_operand:DI 1 "register_operand" "=S")
15126 (plus:DI (match_dup 3)
15127 (const_int 2)))
15128 (use (reg:SI 19))]
15129 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15130 "movsw"
15131 [(set_attr "type" "str")
15132 (set_attr "memory" "both")
15133 (set_attr "mode" "HI")])
15134
15135(define_insn "strmovqi_1"
15136 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15137 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15138 (set (match_operand:SI 0 "register_operand" "=D")
15139 (plus:SI (match_dup 2)
15140 (const_int 1)))
15141 (set (match_operand:SI 1 "register_operand" "=S")
15142 (plus:SI (match_dup 3)
15143 (const_int 1)))
15144 (use (reg:SI 19))]
15145 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15146 "movsb"
15147 [(set_attr "type" "str")
15148 (set_attr "memory" "both")
15149 (set_attr "mode" "QI")])
15150
15151(define_insn "strmovqi_rex_1"
15152 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15153 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15154 (set (match_operand:DI 0 "register_operand" "=D")
15155 (plus:DI (match_dup 2)
15156 (const_int 1)))
15157 (set (match_operand:DI 1 "register_operand" "=S")
15158 (plus:DI (match_dup 3)
15159 (const_int 1)))
15160 (use (reg:SI 19))]
15161 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15162 "movsb"
15163 [(set_attr "type" "str")
15164 (set_attr "memory" "both")
15165 (set_attr "mode" "QI")])
15166
15167(define_insn "rep_movdi_rex64"
15168 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15169 (set (match_operand:DI 0 "register_operand" "=D")
15170 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15171 (const_int 3))
15172 (match_operand:DI 3 "register_operand" "0")))
15173 (set (match_operand:DI 1 "register_operand" "=S")
15174 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15175 (match_operand:DI 4 "register_operand" "1")))
15176 (set (mem:BLK (match_dup 3))
15177 (mem:BLK (match_dup 4)))
15178 (use (match_dup 5))
15179 (use (reg:SI 19))]
15180 "TARGET_64BIT"
15181 "{rep\;movsq|rep movsq}"
15182 [(set_attr "type" "str")
15183 (set_attr "prefix_rep" "1")
15184 (set_attr "memory" "both")
15185 (set_attr "mode" "DI")])
15186
15187(define_insn "rep_movsi"
15188 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15189 (set (match_operand:SI 0 "register_operand" "=D")
15190 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15191 (const_int 2))
15192 (match_operand:SI 3 "register_operand" "0")))
15193 (set (match_operand:SI 1 "register_operand" "=S")
15194 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15195 (match_operand:SI 4 "register_operand" "1")))
15196 (set (mem:BLK (match_dup 3))
15197 (mem:BLK (match_dup 4)))
15198 (use (match_dup 5))
15199 (use (reg:SI 19))]
15200 "!TARGET_64BIT"
15201 "{rep\;movsl|rep movsd}"
15202 [(set_attr "type" "str")
15203 (set_attr "prefix_rep" "1")
15204 (set_attr "memory" "both")
15205 (set_attr "mode" "SI")])
15206
15207(define_insn "rep_movsi_rex64"
15208 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15209 (set (match_operand:DI 0 "register_operand" "=D")
15210 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15211 (const_int 2))
15212 (match_operand:DI 3 "register_operand" "0")))
15213 (set (match_operand:DI 1 "register_operand" "=S")
15214 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15215 (match_operand:DI 4 "register_operand" "1")))
15216 (set (mem:BLK (match_dup 3))
15217 (mem:BLK (match_dup 4)))
15218 (use (match_dup 5))
15219 (use (reg:SI 19))]
15220 "TARGET_64BIT"
15221 "{rep\;movsl|rep movsd}"
15222 [(set_attr "type" "str")
15223 (set_attr "prefix_rep" "1")
15224 (set_attr "memory" "both")
15225 (set_attr "mode" "SI")])
15226
15227(define_insn "rep_movqi"
15228 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15229 (set (match_operand:SI 0 "register_operand" "=D")
15230 (plus:SI (match_operand:SI 3 "register_operand" "0")
15231 (match_operand:SI 5 "register_operand" "2")))
15232 (set (match_operand:SI 1 "register_operand" "=S")
15233 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15234 (set (mem:BLK (match_dup 3))
15235 (mem:BLK (match_dup 4)))
15236 (use (match_dup 5))
15237 (use (reg:SI 19))]
15238 "!TARGET_64BIT"
15239 "{rep\;movsb|rep movsb}"
15240 [(set_attr "type" "str")
15241 (set_attr "prefix_rep" "1")
15242 (set_attr "memory" "both")
15243 (set_attr "mode" "SI")])
15244
15245(define_insn "rep_movqi_rex64"
15246 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15247 (set (match_operand:DI 0 "register_operand" "=D")
15248 (plus:DI (match_operand:DI 3 "register_operand" "0")
15249 (match_operand:DI 5 "register_operand" "2")))
15250 (set (match_operand:DI 1 "register_operand" "=S")
15251 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15252 (set (mem:BLK (match_dup 3))
15253 (mem:BLK (match_dup 4)))
15254 (use (match_dup 5))
15255 (use (reg:SI 19))]
15256 "TARGET_64BIT"
15257 "{rep\;movsb|rep movsb}"
15258 [(set_attr "type" "str")
15259 (set_attr "prefix_rep" "1")
15260 (set_attr "memory" "both")
15261 (set_attr "mode" "SI")])
15262
15263(define_expand "clrstrsi"
15264 [(use (match_operand:BLK 0 "memory_operand" ""))
15265 (use (match_operand:SI 1 "nonmemory_operand" ""))
15266 (use (match_operand 2 "const_int_operand" ""))]
15267 ""
15268{
15269 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15270 DONE;
15271 else
15272 FAIL;
15273})
15274
15275(define_expand "clrstrdi"
15276 [(use (match_operand:BLK 0 "memory_operand" ""))
15277 (use (match_operand:DI 1 "nonmemory_operand" ""))
15278 (use (match_operand 2 "const_int_operand" ""))]
15279 "TARGET_64BIT"
15280{
15281 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15282 DONE;
15283 else
15284 FAIL;
15285})
15286
15287;; Most CPUs don't like single string operations
15288;; Handle this case here to simplify previous expander.
15289
15290(define_expand "strsetdi_rex64"
15291 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15292 (match_operand:DI 1 "register_operand" ""))
15293 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15294 (clobber (reg:CC 17))])]
15295 "TARGET_64BIT"
15296{
15297 if (TARGET_SINGLE_STRINGOP || optimize_size)
15298 {
15299 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15300 DONE;
15301 }
15302})
15303
15304(define_expand "strsetsi"
15305 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15306 (match_operand:SI 1 "register_operand" ""))
15307 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15308 (clobber (reg:CC 17))])]
15309 ""
15310{
15311 if (TARGET_64BIT)
15312 {
15313 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15314 DONE;
15315 }
15316 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15317 {
15318 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15319 DONE;
15320 }
15321})
15322
15323(define_expand "strsetsi_rex64"
15324 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15325 (match_operand:SI 1 "register_operand" ""))
15326 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15327 (clobber (reg:CC 17))])]
15328 "TARGET_64BIT"
15329{
15330 if (TARGET_SINGLE_STRINGOP || optimize_size)
15331 {
15332 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15333 DONE;
15334 }
15335})
15336
15337(define_expand "strsethi"
15338 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15339 (match_operand:HI 1 "register_operand" ""))
15340 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15341 (clobber (reg:CC 17))])]
15342 ""
15343{
15344 if (TARGET_64BIT)
15345 {
15346 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15347 DONE;
15348 }
15349 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15350 {
15351 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15352 DONE;
15353 }
15354})
15355
15356(define_expand "strsethi_rex64"
15357 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15358 (match_operand:HI 1 "register_operand" ""))
15359 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15360 (clobber (reg:CC 17))])]
15361 "TARGET_64BIT"
15362{
15363 if (TARGET_SINGLE_STRINGOP || optimize_size)
15364 {
15365 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15366 DONE;
15367 }
15368})
15369
15370(define_expand "strsetqi"
15371 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15372 (match_operand:QI 1 "register_operand" ""))
15373 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15374 (clobber (reg:CC 17))])]
15375 ""
15376{
15377 if (TARGET_64BIT)
15378 {
15379 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
15380 DONE;
15381 }
15382 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15383 {
15384 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
15385 DONE;
15386 }
15387})
15388
15389(define_expand "strsetqi_rex64"
15390 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
15391 (match_operand:QI 1 "register_operand" ""))
15392 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15393 (clobber (reg:CC 17))])]
15394 "TARGET_64BIT"
15395{
15396 if (TARGET_SINGLE_STRINGOP || optimize_size)
15397 {
15398 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15399 DONE;
15400 }
15401})
15402
15403(define_insn "strsetdi_rex_1"
15404 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15405 (match_operand:SI 2 "register_operand" "a"))
15406 (set (match_operand:DI 0 "register_operand" "=D")
15407 (plus:DI (match_dup 1)
15408 (const_int 8)))
15409 (use (reg:SI 19))]
15410 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15411 "stosq"
15412 [(set_attr "type" "str")
15413 (set_attr "memory" "store")
15414 (set_attr "mode" "DI")])
15415
15416(define_insn "strsetsi_1"
15417 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15418 (match_operand:SI 2 "register_operand" "a"))
15419 (set (match_operand:SI 0 "register_operand" "=D")
15420 (plus:SI (match_dup 1)
15421 (const_int 4)))
15422 (use (reg:SI 19))]
15423 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15424 "{stosl|stosd}"
15425 [(set_attr "type" "str")
15426 (set_attr "memory" "store")
15427 (set_attr "mode" "SI")])
15428
15429(define_insn "strsetsi_rex_1"
15430 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15431 (match_operand:SI 2 "register_operand" "a"))
15432 (set (match_operand:DI 0 "register_operand" "=D")
15433 (plus:DI (match_dup 1)
15434 (const_int 4)))
15435 (use (reg:SI 19))]
15436 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15437 "{stosl|stosd}"
15438 [(set_attr "type" "str")
15439 (set_attr "memory" "store")
15440 (set_attr "mode" "SI")])
15441
15442(define_insn "strsethi_1"
15443 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15444 (match_operand:HI 2 "register_operand" "a"))
15445 (set (match_operand:SI 0 "register_operand" "=D")
15446 (plus:SI (match_dup 1)
15447 (const_int 2)))
15448 (use (reg:SI 19))]
15449 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15450 "stosw"
15451 [(set_attr "type" "str")
15452 (set_attr "memory" "store")
15453 (set_attr "mode" "HI")])
15454
15455(define_insn "strsethi_rex_1"
15456 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15457 (match_operand:HI 2 "register_operand" "a"))
15458 (set (match_operand:DI 0 "register_operand" "=D")
15459 (plus:DI (match_dup 1)
15460 (const_int 2)))
15461 (use (reg:SI 19))]
15462 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15463 "stosw"
15464 [(set_attr "type" "str")
15465 (set_attr "memory" "store")
15466 (set_attr "mode" "HI")])
15467
15468(define_insn "strsetqi_1"
15469 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15470 (match_operand:QI 2 "register_operand" "a"))
15471 (set (match_operand:SI 0 "register_operand" "=D")
15472 (plus:SI (match_dup 1)
15473 (const_int 1)))
15474 (use (reg:SI 19))]
15475 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15476 "stosb"
15477 [(set_attr "type" "str")
15478 (set_attr "memory" "store")
15479 (set_attr "mode" "QI")])
15480
15481(define_insn "strsetqi_rex_1"
15482 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15483 (match_operand:QI 2 "register_operand" "a"))
15484 (set (match_operand:DI 0 "register_operand" "=D")
15485 (plus:DI (match_dup 1)
15486 (const_int 1)))
15487 (use (reg:SI 19))]
15488 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15489 "stosb"
15490 [(set_attr "type" "str")
15491 (set_attr "memory" "store")
15492 (set_attr "mode" "QI")])
15493
15494(define_insn "rep_stosdi_rex64"
15495 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15496 (set (match_operand:DI 0 "register_operand" "=D")
15497 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15498 (const_int 3))
15499 (match_operand:DI 3 "register_operand" "0")))
15500 (set (mem:BLK (match_dup 3))
15501 (const_int 0))
15502 (use (match_operand:DI 2 "register_operand" "a"))
15503 (use (match_dup 4))
15504 (use (reg:SI 19))]
15505 "TARGET_64BIT"
15506 "{rep\;stosq|rep stosq}"
15507 [(set_attr "type" "str")
15508 (set_attr "prefix_rep" "1")
15509 (set_attr "memory" "store")
15510 (set_attr "mode" "DI")])
15511
15512(define_insn "rep_stossi"
15513 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15514 (set (match_operand:SI 0 "register_operand" "=D")
15515 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15516 (const_int 2))
15517 (match_operand:SI 3 "register_operand" "0")))
15518 (set (mem:BLK (match_dup 3))
15519 (const_int 0))
15520 (use (match_operand:SI 2 "register_operand" "a"))
15521 (use (match_dup 4))
15522 (use (reg:SI 19))]
15523 "!TARGET_64BIT"
15524 "{rep\;stosl|rep stosd}"
15525 [(set_attr "type" "str")
15526 (set_attr "prefix_rep" "1")
15527 (set_attr "memory" "store")
15528 (set_attr "mode" "SI")])
15529
15530(define_insn "rep_stossi_rex64"
15531 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15532 (set (match_operand:DI 0 "register_operand" "=D")
15533 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15534 (const_int 2))
15535 (match_operand:DI 3 "register_operand" "0")))
15536 (set (mem:BLK (match_dup 3))
15537 (const_int 0))
15538 (use (match_operand:SI 2 "register_operand" "a"))
15539 (use (match_dup 4))
15540 (use (reg:SI 19))]
15541 "TARGET_64BIT"
15542 "{rep\;stosl|rep stosd}"
15543 [(set_attr "type" "str")
15544 (set_attr "prefix_rep" "1")
15545 (set_attr "memory" "store")
15546 (set_attr "mode" "SI")])
15547
15548(define_insn "rep_stosqi"
15549 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15550 (set (match_operand:SI 0 "register_operand" "=D")
15551 (plus:SI (match_operand:SI 3 "register_operand" "0")
15552 (match_operand:SI 4 "register_operand" "1")))
15553 (set (mem:BLK (match_dup 3))
15554 (const_int 0))
15555 (use (match_operand:QI 2 "register_operand" "a"))
15556 (use (match_dup 4))
15557 (use (reg:SI 19))]
15558 "!TARGET_64BIT"
15559 "{rep\;stosb|rep stosb}"
15560 [(set_attr "type" "str")
15561 (set_attr "prefix_rep" "1")
15562 (set_attr "memory" "store")
15563 (set_attr "mode" "QI")])
15564
15565(define_insn "rep_stosqi_rex64"
15566 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15567 (set (match_operand:DI 0 "register_operand" "=D")
15568 (plus:DI (match_operand:DI 3 "register_operand" "0")
15569 (match_operand:DI 4 "register_operand" "1")))
15570 (set (mem:BLK (match_dup 3))
15571 (const_int 0))
15572 (use (match_operand:QI 2 "register_operand" "a"))
15573 (use (match_dup 4))
15574 (use (reg:DI 19))]
15575 "TARGET_64BIT"
15576 "{rep\;stosb|rep stosb}"
15577 [(set_attr "type" "str")
15578 (set_attr "prefix_rep" "1")
15579 (set_attr "memory" "store")
15580 (set_attr "mode" "QI")])
15581
15582(define_expand "cmpstrsi"
15583 [(set (match_operand:SI 0 "register_operand" "")
15584 (compare:SI (match_operand:BLK 1 "general_operand" "")
15585 (match_operand:BLK 2 "general_operand" "")))
15586 (use (match_operand 3 "general_operand" ""))
15587 (use (match_operand 4 "immediate_operand" ""))]
15588 ""
15589{
15590 rtx addr1, addr2, out, outlow, count, countreg, align;
15591
15592 out = operands[0];
15593 if (GET_CODE (out) != REG)
15594 out = gen_reg_rtx (SImode);
15595
15596 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15597 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15598
15599 count = operands[3];
15600 countreg = ix86_zero_extend_to_Pmode (count);
15601
15602 /* %%% Iff we are testing strict equality, we can use known alignment
15603 to good advantage. This may be possible with combine, particularly
15604 once cc0 is dead. */
15605 align = operands[4];
15606
15607 emit_insn (gen_cld ());
15608 if (GET_CODE (count) == CONST_INT)
15609 {
15610 if (INTVAL (count) == 0)
15611 {
15612 emit_move_insn (operands[0], const0_rtx);
15613 DONE;
15614 }
15615 if (TARGET_64BIT)
15616 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15617 addr1, addr2, countreg));
15618 else
15619 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15620 addr1, addr2, countreg));
15621 }
15622 else
15623 {
15624 if (TARGET_64BIT)
15625 {
15626 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15627 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15628 addr1, addr2, countreg));
15629 }
15630 else
15631 {
15632 emit_insn (gen_cmpsi_1 (countreg, countreg));
15633 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15634 addr1, addr2, countreg));
15635 }
15636 }
15637
15638 outlow = gen_lowpart (QImode, out);
15639 emit_insn (gen_cmpintqi (outlow));
15640 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15641
15642 if (operands[0] != out)
15643 emit_move_insn (operands[0], out);
15644
15645 DONE;
15646})
15647
15648;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15649
15650(define_expand "cmpintqi"
15651 [(set (match_dup 1)
15652 (gtu:QI (reg:CC 17) (const_int 0)))
15653 (set (match_dup 2)
15654 (ltu:QI (reg:CC 17) (const_int 0)))
15655 (parallel [(set (match_operand:QI 0 "register_operand" "")
15656 (minus:QI (match_dup 1)
15657 (match_dup 2)))
15658 (clobber (reg:CC 17))])]
15659 ""
15660 "operands[1] = gen_reg_rtx (QImode);
15661 operands[2] = gen_reg_rtx (QImode);")
15662
15663;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15664;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15665
15666(define_insn "cmpstrqi_nz_1"
15667 [(set (reg:CC 17)
15668 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15669 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15670 (use (match_operand:SI 6 "register_operand" "2"))
15671 (use (match_operand:SI 3 "immediate_operand" "i"))
15672 (use (reg:SI 19))
15673 (clobber (match_operand:SI 0 "register_operand" "=S"))
15674 (clobber (match_operand:SI 1 "register_operand" "=D"))
15675 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15676 "!TARGET_64BIT"
15677 "repz{\;| }cmpsb"
15678 [(set_attr "type" "str")
15679 (set_attr "mode" "QI")
15680 (set_attr "prefix_rep" "1")])
15681
15682(define_insn "cmpstrqi_nz_rex_1"
15683 [(set (reg:CC 17)
15684 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15685 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15686 (use (match_operand:DI 6 "register_operand" "2"))
15687 (use (match_operand:SI 3 "immediate_operand" "i"))
15688 (use (reg:SI 19))
15689 (clobber (match_operand:DI 0 "register_operand" "=S"))
15690 (clobber (match_operand:DI 1 "register_operand" "=D"))
15691 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15692 "TARGET_64BIT"
15693 "repz{\;| }cmpsb"
15694 [(set_attr "type" "str")
15695 (set_attr "mode" "QI")
15696 (set_attr "prefix_rep" "1")])
15697
15698;; The same, but the count is not known to not be zero.
15699
15700(define_insn "cmpstrqi_1"
15701 [(set (reg:CC 17)
15702 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15703 (const_int 0))
15704 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15705 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15706 (const_int 0)))
15707 (use (match_operand:SI 3 "immediate_operand" "i"))
15708 (use (reg:CC 17))
15709 (use (reg:SI 19))
15710 (clobber (match_operand:SI 0 "register_operand" "=S"))
15711 (clobber (match_operand:SI 1 "register_operand" "=D"))
15712 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15713 "!TARGET_64BIT"
15714 "repz{\;| }cmpsb"
15715 [(set_attr "type" "str")
15716 (set_attr "mode" "QI")
15717 (set_attr "prefix_rep" "1")])
15718
15719(define_insn "cmpstrqi_rex_1"
15720 [(set (reg:CC 17)
15721 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15722 (const_int 0))
15723 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15724 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15725 (const_int 0)))
15726 (use (match_operand:SI 3 "immediate_operand" "i"))
15727 (use (reg:CC 17))
15728 (use (reg:SI 19))
15729 (clobber (match_operand:DI 0 "register_operand" "=S"))
15730 (clobber (match_operand:DI 1 "register_operand" "=D"))
15731 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15732 "TARGET_64BIT"
15733 "repz{\;| }cmpsb"
15734 [(set_attr "type" "str")
15735 (set_attr "mode" "QI")
15736 (set_attr "prefix_rep" "1")])
15737
15738(define_expand "strlensi"
15739 [(set (match_operand:SI 0 "register_operand" "")
15740 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15741 (match_operand:QI 2 "immediate_operand" "")
15742 (match_operand 3 "immediate_operand" "")] 0))]
15743 ""
15744{
15745 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15746 DONE;
15747 else
15748 FAIL;
15749})
15750
15751(define_expand "strlendi"
15752 [(set (match_operand:DI 0 "register_operand" "")
15753 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15754 (match_operand:QI 2 "immediate_operand" "")
15755 (match_operand 3 "immediate_operand" "")] 0))]
15756 ""
15757{
15758 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15759 DONE;
15760 else
15761 FAIL;
15762})
15763
15764(define_insn "strlenqi_1"
15765 [(set (match_operand:SI 0 "register_operand" "=&c")
15766 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15767 (match_operand:QI 2 "register_operand" "a")
15768 (match_operand:SI 3 "immediate_operand" "i")
15769 (match_operand:SI 4 "register_operand" "0")] 0))
15770 (use (reg:SI 19))
15771 (clobber (match_operand:SI 1 "register_operand" "=D"))
15772 (clobber (reg:CC 17))]
15773 "!TARGET_64BIT"
15774 "repnz{\;| }scasb"
15775 [(set_attr "type" "str")
15776 (set_attr "mode" "QI")
15777 (set_attr "prefix_rep" "1")])
15778
15779(define_insn "strlenqi_rex_1"
15780 [(set (match_operand:DI 0 "register_operand" "=&c")
15781 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15782 (match_operand:QI 2 "register_operand" "a")
15783 (match_operand:DI 3 "immediate_operand" "i")
15784 (match_operand:DI 4 "register_operand" "0")] 0))
15785 (use (reg:SI 19))
15786 (clobber (match_operand:DI 1 "register_operand" "=D"))
15787 (clobber (reg:CC 17))]
15788 "TARGET_64BIT"
15789 "repnz{\;| }scasb"
15790 [(set_attr "type" "str")
15791 (set_attr "mode" "QI")
15792 (set_attr "prefix_rep" "1")])
15793
15794;; Peephole optimizations to clean up after cmpstr*. This should be
15795;; handled in combine, but it is not currently up to the task.
15796;; When used for their truth value, the cmpstr* expanders generate
15797;; code like this:
15798;;
15799;; repz cmpsb
15800;; seta %al
15801;; setb %dl
15802;; cmpb %al, %dl
15803;; jcc label
15804;;
15805;; The intermediate three instructions are unnecessary.
15806
15807;; This one handles cmpstr*_nz_1...
15808(define_peephole2
15809 [(parallel[
15810 (set (reg:CC 17)
15811 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15812 (mem:BLK (match_operand 5 "register_operand" ""))))
15813 (use (match_operand 6 "register_operand" ""))
15814 (use (match_operand:SI 3 "immediate_operand" ""))
15815 (use (reg:SI 19))
15816 (clobber (match_operand 0 "register_operand" ""))
15817 (clobber (match_operand 1 "register_operand" ""))
15818 (clobber (match_operand 2 "register_operand" ""))])
15819 (set (match_operand:QI 7 "register_operand" "")
15820 (gtu:QI (reg:CC 17) (const_int 0)))
15821 (set (match_operand:QI 8 "register_operand" "")
15822 (ltu:QI (reg:CC 17) (const_int 0)))
15823 (set (reg 17)
15824 (compare (match_dup 7) (match_dup 8)))
15825 ]
15826 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15827 [(parallel[
15828 (set (reg:CC 17)
15829 (compare:CC (mem:BLK (match_dup 4))
15830 (mem:BLK (match_dup 5))))
15831 (use (match_dup 6))
15832 (use (match_dup 3))
15833 (use (reg:SI 19))
15834 (clobber (match_dup 0))
15835 (clobber (match_dup 1))
15836 (clobber (match_dup 2))])]
15837 "")
15838
15839;; ...and this one handles cmpstr*_1.
15840(define_peephole2
15841 [(parallel[
15842 (set (reg:CC 17)
15843 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15844 (const_int 0))
15845 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15846 (mem:BLK (match_operand 5 "register_operand" "")))
15847 (const_int 0)))
15848 (use (match_operand:SI 3 "immediate_operand" ""))
15849 (use (reg:CC 17))
15850 (use (reg:SI 19))
15851 (clobber (match_operand 0 "register_operand" ""))
15852 (clobber (match_operand 1 "register_operand" ""))
15853 (clobber (match_operand 2 "register_operand" ""))])
15854 (set (match_operand:QI 7 "register_operand" "")
15855 (gtu:QI (reg:CC 17) (const_int 0)))
15856 (set (match_operand:QI 8 "register_operand" "")
15857 (ltu:QI (reg:CC 17) (const_int 0)))
15858 (set (reg 17)
15859 (compare (match_dup 7) (match_dup 8)))
15860 ]
15861 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15862 [(parallel[
15863 (set (reg:CC 17)
15864 (if_then_else:CC (ne (match_dup 6)
15865 (const_int 0))
15866 (compare:CC (mem:BLK (match_dup 4))
15867 (mem:BLK (match_dup 5)))
15868 (const_int 0)))
15869 (use (match_dup 3))
15870 (use (reg:CC 17))
15871 (use (reg:SI 19))
15872 (clobber (match_dup 0))
15873 (clobber (match_dup 1))
15874 (clobber (match_dup 2))])]
15875 "")
15876
15877
15878
15879;; Conditional move instructions.
15880
15881(define_expand "movdicc"
15882 [(set (match_operand:DI 0 "register_operand" "")
15883 (if_then_else:DI (match_operand 1 "comparison_operator" "")
15884 (match_operand:DI 2 "general_operand" "")
15885 (match_operand:DI 3 "general_operand" "")))]
15886 "TARGET_64BIT"
15887 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15888
15889(define_insn "x86_movdicc_0_m1_rex64"
15890 [(set (match_operand:DI 0 "register_operand" "=r")
15891 (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15892 (const_int -1)
15893 (const_int 0)))
15894 (clobber (reg:CC 17))]
15895 "TARGET_64BIT"
15896 "sbb{q}\t%0, %0"
15897 ; Since we don't have the proper number of operands for an alu insn,
15898 ; fill in all the blanks.
15899 [(set_attr "type" "alu")
15900 (set_attr "memory" "none")
15901 (set_attr "imm_disp" "false")
15902 (set_attr "mode" "DI")
15903 (set_attr "length_immediate" "0")])
15904
15905(define_insn "*movdicc_c_rex64"
15906 [(set (match_operand:DI 0 "register_operand" "=r,r")
15907 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
15908 [(reg 17) (const_int 0)])
15909 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15910 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15911 "TARGET_64BIT && TARGET_CMOVE
15912 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15913 "@
15753 cmov%C1\t{%2, %0|%0, %2}
15754 cmov%c1\t{%3, %0|%0, %3}"
15914 cmov%O2%C1\t{%2, %0|%0, %2}
15915 cmov%O2%c1\t{%3, %0|%0, %3}"
15755 [(set_attr "type" "icmov")
15756 (set_attr "mode" "DI")])
15757
15758(define_expand "movsicc"
15759 [(set (match_operand:SI 0 "register_operand" "")
15760 (if_then_else:SI (match_operand 1 "comparison_operator" "")
15761 (match_operand:SI 2 "general_operand" "")
15762 (match_operand:SI 3 "general_operand" "")))]
15763 ""
15764 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15765
15766;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15767;; the register first winds up with `sbbl $0,reg', which is also weird.
15768;; So just document what we're doing explicitly.
15769
15770(define_insn "x86_movsicc_0_m1"
15771 [(set (match_operand:SI 0 "register_operand" "=r")
15772 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15773 (const_int -1)
15774 (const_int 0)))
15775 (clobber (reg:CC 17))]
15776 ""
15777 "sbb{l}\t%0, %0"
15778 ; Since we don't have the proper number of operands for an alu insn,
15779 ; fill in all the blanks.
15780 [(set_attr "type" "alu")
15781 (set_attr "memory" "none")
15782 (set_attr "imm_disp" "false")
15783 (set_attr "mode" "SI")
15784 (set_attr "length_immediate" "0")])
15785
15786(define_insn "*movsicc_noc"
15787 [(set (match_operand:SI 0 "register_operand" "=r,r")
15788 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
15789 [(reg 17) (const_int 0)])
15790 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15791 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
15792 "TARGET_CMOVE
15793 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15794 "@
15916 [(set_attr "type" "icmov")
15917 (set_attr "mode" "DI")])
15918
15919(define_expand "movsicc"
15920 [(set (match_operand:SI 0 "register_operand" "")
15921 (if_then_else:SI (match_operand 1 "comparison_operator" "")
15922 (match_operand:SI 2 "general_operand" "")
15923 (match_operand:SI 3 "general_operand" "")))]
15924 ""
15925 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15926
15927;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15928;; the register first winds up with `sbbl $0,reg', which is also weird.
15929;; So just document what we're doing explicitly.
15930
15931(define_insn "x86_movsicc_0_m1"
15932 [(set (match_operand:SI 0 "register_operand" "=r")
15933 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15934 (const_int -1)
15935 (const_int 0)))
15936 (clobber (reg:CC 17))]
15937 ""
15938 "sbb{l}\t%0, %0"
15939 ; Since we don't have the proper number of operands for an alu insn,
15940 ; fill in all the blanks.
15941 [(set_attr "type" "alu")
15942 (set_attr "memory" "none")
15943 (set_attr "imm_disp" "false")
15944 (set_attr "mode" "SI")
15945 (set_attr "length_immediate" "0")])
15946
15947(define_insn "*movsicc_noc"
15948 [(set (match_operand:SI 0 "register_operand" "=r,r")
15949 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
15950 [(reg 17) (const_int 0)])
15951 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15952 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
15953 "TARGET_CMOVE
15954 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15955 "@
15795 cmov%C1\t{%2, %0|%0, %2}
15796 cmov%c1\t{%3, %0|%0, %3}"
15956 cmov%O2%C1\t{%2, %0|%0, %2}
15957 cmov%O2%c1\t{%3, %0|%0, %3}"
15797 [(set_attr "type" "icmov")
15798 (set_attr "mode" "SI")])
15799
15800(define_expand "movhicc"
15801 [(set (match_operand:HI 0 "register_operand" "")
15802 (if_then_else:HI (match_operand 1 "comparison_operator" "")
15803 (match_operand:HI 2 "nonimmediate_operand" "")
15804 (match_operand:HI 3 "nonimmediate_operand" "")))]
15805 "TARGET_CMOVE && TARGET_HIMODE_MATH"
15806 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15807
15808(define_insn "*movhicc_noc"
15809 [(set (match_operand:HI 0 "register_operand" "=r,r")
15810 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
15811 [(reg 17) (const_int 0)])
15812 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15813 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
15814 "TARGET_CMOVE
15815 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15816 "@
15958 [(set_attr "type" "icmov")
15959 (set_attr "mode" "SI")])
15960
15961(define_expand "movhicc"
15962 [(set (match_operand:HI 0 "register_operand" "")
15963 (if_then_else:HI (match_operand 1 "comparison_operator" "")
15964 (match_operand:HI 2 "nonimmediate_operand" "")
15965 (match_operand:HI 3 "nonimmediate_operand" "")))]
15966 "TARGET_CMOVE && TARGET_HIMODE_MATH"
15967 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15968
15969(define_insn "*movhicc_noc"
15970 [(set (match_operand:HI 0 "register_operand" "=r,r")
15971 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
15972 [(reg 17) (const_int 0)])
15973 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15974 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
15975 "TARGET_CMOVE
15976 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15977 "@
15817 cmov%C1\t{%2, %0|%0, %2}
15818 cmov%c1\t{%3, %0|%0, %3}"
15978 cmov%O2%C1\t{%2, %0|%0, %2}
15979 cmov%O2%c1\t{%3, %0|%0, %3}"
15819 [(set_attr "type" "icmov")
15820 (set_attr "mode" "HI")])
15821
15822(define_expand "movsfcc"
15823 [(set (match_operand:SF 0 "register_operand" "")
15824 (if_then_else:SF (match_operand 1 "comparison_operator" "")
15825 (match_operand:SF 2 "register_operand" "")
15826 (match_operand:SF 3 "register_operand" "")))]
15827 "TARGET_CMOVE"
15828 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15829
15830(define_insn "*movsfcc_1"
15831 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15832 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15833 [(reg 17) (const_int 0)])
15834 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15835 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15836 "TARGET_CMOVE
15837 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15838 "@
15839 fcmov%F1\t{%2, %0|%0, %2}
15840 fcmov%f1\t{%3, %0|%0, %3}
15980 [(set_attr "type" "icmov")
15981 (set_attr "mode" "HI")])
15982
15983(define_expand "movsfcc"
15984 [(set (match_operand:SF 0 "register_operand" "")
15985 (if_then_else:SF (match_operand 1 "comparison_operator" "")
15986 (match_operand:SF 2 "register_operand" "")
15987 (match_operand:SF 3 "register_operand" "")))]
15988 "TARGET_CMOVE"
15989 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15990
15991(define_insn "*movsfcc_1"
15992 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15993 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15994 [(reg 17) (const_int 0)])
15995 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15996 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15997 "TARGET_CMOVE
15998 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15999 "@
16000 fcmov%F1\t{%2, %0|%0, %2}
16001 fcmov%f1\t{%3, %0|%0, %3}
15841 cmov%C1\t{%2, %0|%0, %2}
15842 cmov%c1\t{%3, %0|%0, %3}"
16002 cmov%O2%C1\t{%2, %0|%0, %2}
16003 cmov%O2%c1\t{%3, %0|%0, %3}"
15843 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15844 (set_attr "mode" "SF,SF,SI,SI")])
15845
15846(define_expand "movdfcc"
15847 [(set (match_operand:DF 0 "register_operand" "")
15848 (if_then_else:DF (match_operand 1 "comparison_operator" "")
15849 (match_operand:DF 2 "register_operand" "")
15850 (match_operand:DF 3 "register_operand" "")))]
15851 "TARGET_CMOVE"
15852 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15853
15854(define_insn "*movdfcc_1"
15855 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15856 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15857 [(reg 17) (const_int 0)])
15858 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15859 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15860 "!TARGET_64BIT && TARGET_CMOVE
15861 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15862 "@
15863 fcmov%F1\t{%2, %0|%0, %2}
15864 fcmov%f1\t{%3, %0|%0, %3}
15865 #
15866 #"
15867 [(set_attr "type" "fcmov,fcmov,multi,multi")
15868 (set_attr "mode" "DF")])
15869
15870(define_insn "*movdfcc_1_rex64"
15871 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15872 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15873 [(reg 17) (const_int 0)])
15874 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15875 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15876 "TARGET_64BIT && TARGET_CMOVE
15877 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15878 "@
15879 fcmov%F1\t{%2, %0|%0, %2}
15880 fcmov%f1\t{%3, %0|%0, %3}
16004 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16005 (set_attr "mode" "SF,SF,SI,SI")])
16006
16007(define_expand "movdfcc"
16008 [(set (match_operand:DF 0 "register_operand" "")
16009 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16010 (match_operand:DF 2 "register_operand" "")
16011 (match_operand:DF 3 "register_operand" "")))]
16012 "TARGET_CMOVE"
16013 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16014
16015(define_insn "*movdfcc_1"
16016 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16017 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16018 [(reg 17) (const_int 0)])
16019 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16020 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16021 "!TARGET_64BIT && TARGET_CMOVE
16022 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16023 "@
16024 fcmov%F1\t{%2, %0|%0, %2}
16025 fcmov%f1\t{%3, %0|%0, %3}
16026 #
16027 #"
16028 [(set_attr "type" "fcmov,fcmov,multi,multi")
16029 (set_attr "mode" "DF")])
16030
16031(define_insn "*movdfcc_1_rex64"
16032 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16033 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16034 [(reg 17) (const_int 0)])
16035 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16036 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16037 "TARGET_64BIT && TARGET_CMOVE
16038 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16039 "@
16040 fcmov%F1\t{%2, %0|%0, %2}
16041 fcmov%f1\t{%3, %0|%0, %3}
15881 cmov%C1\t{%2, %0|%0, %2}
15882 cmov%c1\t{%3, %0|%0, %3}"
16042 cmov%O2%C1\t{%2, %0|%0, %2}
16043 cmov%O2%c1\t{%3, %0|%0, %3}"
15883 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15884 (set_attr "mode" "DF")])
15885
15886(define_split
15887 [(set (match_operand:DF 0 "register_operand" "")
15888 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15889 [(match_operand 4 "" "") (const_int 0)])
15890 (match_operand:DF 2 "nonimmediate_operand" "")
15891 (match_operand:DF 3 "nonimmediate_operand" "")))]
15892 "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
15893 [(set (match_dup 2)
15894 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15895 (match_dup 5)
15896 (match_dup 7)))
15897 (set (match_dup 3)
15898 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15899 (match_dup 6)
15900 (match_dup 8)))]
15901 "split_di (operands+2, 1, operands+5, operands+6);
15902 split_di (operands+3, 1, operands+7, operands+8);
15903 split_di (operands, 1, operands+2, operands+3);")
15904
15905(define_expand "movxfcc"
15906 [(set (match_operand:XF 0 "register_operand" "")
15907 (if_then_else:XF (match_operand 1 "comparison_operator" "")
15908 (match_operand:XF 2 "register_operand" "")
15909 (match_operand:XF 3 "register_operand" "")))]
15910 "!TARGET_64BIT && TARGET_CMOVE"
15911 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15912
15913(define_expand "movtfcc"
15914 [(set (match_operand:TF 0 "register_operand" "")
15915 (if_then_else:TF (match_operand 1 "comparison_operator" "")
15916 (match_operand:TF 2 "register_operand" "")
15917 (match_operand:TF 3 "register_operand" "")))]
15918 "TARGET_CMOVE"
15919 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15920
15921(define_insn "*movxfcc_1"
15922 [(set (match_operand:XF 0 "register_operand" "=f,f")
15923 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15924 [(reg 17) (const_int 0)])
15925 (match_operand:XF 2 "register_operand" "f,0")
15926 (match_operand:XF 3 "register_operand" "0,f")))]
15927 "!TARGET_64BIT && TARGET_CMOVE"
15928 "@
15929 fcmov%F1\t{%2, %0|%0, %2}
15930 fcmov%f1\t{%3, %0|%0, %3}"
15931 [(set_attr "type" "fcmov")
15932 (set_attr "mode" "XF")])
15933
15934(define_insn "*movtfcc_1"
15935 [(set (match_operand:TF 0 "register_operand" "=f,f")
15936 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
15937 [(reg 17) (const_int 0)])
15938 (match_operand:TF 2 "register_operand" "f,0")
15939 (match_operand:TF 3 "register_operand" "0,f")))]
15940 "TARGET_CMOVE"
15941 "@
15942 fcmov%F1\t{%2, %0|%0, %2}
15943 fcmov%f1\t{%3, %0|%0, %3}"
15944 [(set_attr "type" "fcmov")
15945 (set_attr "mode" "XF")])
15946
15947(define_expand "minsf3"
15948 [(parallel [
15949 (set (match_operand:SF 0 "register_operand" "")
15950 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15951 (match_operand:SF 2 "nonimmediate_operand" ""))
15952 (match_dup 1)
15953 (match_dup 2)))
15954 (clobber (reg:CC 17))])]
15955 "TARGET_SSE"
15956 "")
15957
15958(define_insn "*minsf"
15959 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15960 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
15961 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15962 (match_dup 1)
15963 (match_dup 2)))
15964 (clobber (reg:CC 17))]
15965 "TARGET_SSE && TARGET_IEEE_FP"
15966 "#")
15967
15968(define_insn "*minsf_nonieee"
15969 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16044 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16045 (set_attr "mode" "DF")])
16046
16047(define_split
16048 [(set (match_operand:DF 0 "register_operand" "")
16049 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16050 [(match_operand 4 "" "") (const_int 0)])
16051 (match_operand:DF 2 "nonimmediate_operand" "")
16052 (match_operand:DF 3 "nonimmediate_operand" "")))]
16053 "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
16054 [(set (match_dup 2)
16055 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16056 (match_dup 5)
16057 (match_dup 7)))
16058 (set (match_dup 3)
16059 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16060 (match_dup 6)
16061 (match_dup 8)))]
16062 "split_di (operands+2, 1, operands+5, operands+6);
16063 split_di (operands+3, 1, operands+7, operands+8);
16064 split_di (operands, 1, operands+2, operands+3);")
16065
16066(define_expand "movxfcc"
16067 [(set (match_operand:XF 0 "register_operand" "")
16068 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16069 (match_operand:XF 2 "register_operand" "")
16070 (match_operand:XF 3 "register_operand" "")))]
16071 "!TARGET_64BIT && TARGET_CMOVE"
16072 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16073
16074(define_expand "movtfcc"
16075 [(set (match_operand:TF 0 "register_operand" "")
16076 (if_then_else:TF (match_operand 1 "comparison_operator" "")
16077 (match_operand:TF 2 "register_operand" "")
16078 (match_operand:TF 3 "register_operand" "")))]
16079 "TARGET_CMOVE"
16080 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16081
16082(define_insn "*movxfcc_1"
16083 [(set (match_operand:XF 0 "register_operand" "=f,f")
16084 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16085 [(reg 17) (const_int 0)])
16086 (match_operand:XF 2 "register_operand" "f,0")
16087 (match_operand:XF 3 "register_operand" "0,f")))]
16088 "!TARGET_64BIT && TARGET_CMOVE"
16089 "@
16090 fcmov%F1\t{%2, %0|%0, %2}
16091 fcmov%f1\t{%3, %0|%0, %3}"
16092 [(set_attr "type" "fcmov")
16093 (set_attr "mode" "XF")])
16094
16095(define_insn "*movtfcc_1"
16096 [(set (match_operand:TF 0 "register_operand" "=f,f")
16097 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
16098 [(reg 17) (const_int 0)])
16099 (match_operand:TF 2 "register_operand" "f,0")
16100 (match_operand:TF 3 "register_operand" "0,f")))]
16101 "TARGET_CMOVE"
16102 "@
16103 fcmov%F1\t{%2, %0|%0, %2}
16104 fcmov%f1\t{%3, %0|%0, %3}"
16105 [(set_attr "type" "fcmov")
16106 (set_attr "mode" "XF")])
16107
16108(define_expand "minsf3"
16109 [(parallel [
16110 (set (match_operand:SF 0 "register_operand" "")
16111 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16112 (match_operand:SF 2 "nonimmediate_operand" ""))
16113 (match_dup 1)
16114 (match_dup 2)))
16115 (clobber (reg:CC 17))])]
16116 "TARGET_SSE"
16117 "")
16118
16119(define_insn "*minsf"
16120 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16121 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16122 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16123 (match_dup 1)
16124 (match_dup 2)))
16125 (clobber (reg:CC 17))]
16126 "TARGET_SSE && TARGET_IEEE_FP"
16127 "#")
16128
16129(define_insn "*minsf_nonieee"
16130 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15970 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
16131 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
15971 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
15972 (match_dup 1)
15973 (match_dup 2)))
15974 (clobber (reg:CC 17))]
16132 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16133 (match_dup 1)
16134 (match_dup 2)))
16135 (clobber (reg:CC 17))]
15975 "TARGET_SSE && !TARGET_IEEE_FP"
16136 "TARGET_SSE && !TARGET_IEEE_FP
16137 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15976 "#")
15977
15978(define_split
15979 [(set (match_operand:SF 0 "register_operand" "")
15980 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15981 (match_operand:SF 2 "nonimmediate_operand" ""))
15982 (match_operand:SF 3 "register_operand" "")
15983 (match_operand:SF 4 "nonimmediate_operand" "")))
15984 (clobber (reg:CC 17))]
15985 "SSE_REG_P (operands[0]) && reload_completed
15986 && ((operands_match_p (operands[1], operands[3])
15987 && operands_match_p (operands[2], operands[4]))
15988 || (operands_match_p (operands[1], operands[4])
15989 && operands_match_p (operands[2], operands[3])))"
15990 [(set (match_dup 0)
15991 (if_then_else:SF (lt (match_dup 1)
15992 (match_dup 2))
15993 (match_dup 1)
15994 (match_dup 2)))])
15995
15996;; We can't represent the LT test directly. Do this by swapping the operands.
15997
15998(define_split
15999 [(set (match_operand:SF 0 "register_operand" "")
16000 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16001 (match_operand:SF 2 "register_operand" ""))
16002 (match_operand:SF 3 "register_operand" "")
16003 (match_operand:SF 4 "register_operand" "")))
16004 (clobber (reg:CC 17))]
16005 "FP_REG_P (operands[0]) && reload_completed
16006 && ((operands_match_p (operands[1], operands[3])
16007 && operands_match_p (operands[2], operands[4]))
16008 || (operands_match_p (operands[1], operands[4])
16009 && operands_match_p (operands[2], operands[3])))"
16010 [(set (reg:CCFP 17)
16011 (compare:CCFP (match_dup 2)
16012 (match_dup 1)))
16013 (set (match_dup 0)
16014 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16015 (match_dup 1)
16016 (match_dup 2)))])
16017
16018(define_insn "*minsf_sse"
16019 [(set (match_operand:SF 0 "register_operand" "=x")
16020 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16021 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16022 (match_dup 1)
16023 (match_dup 2)))]
16024 "TARGET_SSE && reload_completed"
16025 "minss\t{%2, %0|%0, %2}"
16026 [(set_attr "type" "sse")
16027 (set_attr "mode" "SF")])
16028
16029(define_expand "mindf3"
16030 [(parallel [
16031 (set (match_operand:DF 0 "register_operand" "")
16032 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16033 (match_operand:DF 2 "nonimmediate_operand" ""))
16034 (match_dup 1)
16035 (match_dup 2)))
16036 (clobber (reg:CC 17))])]
16037 "TARGET_SSE2 && TARGET_SSE_MATH"
16038 "#")
16039
16040(define_insn "*mindf"
16041 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16042 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16043 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16044 (match_dup 1)
16045 (match_dup 2)))
16046 (clobber (reg:CC 17))]
16047 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16048 "#")
16049
16050(define_insn "*mindf_nonieee"
16051 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16138 "#")
16139
16140(define_split
16141 [(set (match_operand:SF 0 "register_operand" "")
16142 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16143 (match_operand:SF 2 "nonimmediate_operand" ""))
16144 (match_operand:SF 3 "register_operand" "")
16145 (match_operand:SF 4 "nonimmediate_operand" "")))
16146 (clobber (reg:CC 17))]
16147 "SSE_REG_P (operands[0]) && reload_completed
16148 && ((operands_match_p (operands[1], operands[3])
16149 && operands_match_p (operands[2], operands[4]))
16150 || (operands_match_p (operands[1], operands[4])
16151 && operands_match_p (operands[2], operands[3])))"
16152 [(set (match_dup 0)
16153 (if_then_else:SF (lt (match_dup 1)
16154 (match_dup 2))
16155 (match_dup 1)
16156 (match_dup 2)))])
16157
16158;; We can't represent the LT test directly. Do this by swapping the operands.
16159
16160(define_split
16161 [(set (match_operand:SF 0 "register_operand" "")
16162 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16163 (match_operand:SF 2 "register_operand" ""))
16164 (match_operand:SF 3 "register_operand" "")
16165 (match_operand:SF 4 "register_operand" "")))
16166 (clobber (reg:CC 17))]
16167 "FP_REG_P (operands[0]) && reload_completed
16168 && ((operands_match_p (operands[1], operands[3])
16169 && operands_match_p (operands[2], operands[4]))
16170 || (operands_match_p (operands[1], operands[4])
16171 && operands_match_p (operands[2], operands[3])))"
16172 [(set (reg:CCFP 17)
16173 (compare:CCFP (match_dup 2)
16174 (match_dup 1)))
16175 (set (match_dup 0)
16176 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16177 (match_dup 1)
16178 (match_dup 2)))])
16179
16180(define_insn "*minsf_sse"
16181 [(set (match_operand:SF 0 "register_operand" "=x")
16182 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16183 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16184 (match_dup 1)
16185 (match_dup 2)))]
16186 "TARGET_SSE && reload_completed"
16187 "minss\t{%2, %0|%0, %2}"
16188 [(set_attr "type" "sse")
16189 (set_attr "mode" "SF")])
16190
16191(define_expand "mindf3"
16192 [(parallel [
16193 (set (match_operand:DF 0 "register_operand" "")
16194 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16195 (match_operand:DF 2 "nonimmediate_operand" ""))
16196 (match_dup 1)
16197 (match_dup 2)))
16198 (clobber (reg:CC 17))])]
16199 "TARGET_SSE2 && TARGET_SSE_MATH"
16200 "#")
16201
16202(define_insn "*mindf"
16203 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16204 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16205 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16206 (match_dup 1)
16207 (match_dup 2)))
16208 (clobber (reg:CC 17))]
16209 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16210 "#")
16211
16212(define_insn "*mindf_nonieee"
16213 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16052 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
16214 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16053 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16054 (match_dup 1)
16055 (match_dup 2)))
16056 (clobber (reg:CC 17))]
16215 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16216 (match_dup 1)
16217 (match_dup 2)))
16218 (clobber (reg:CC 17))]
16057 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP"
16219 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16220 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16058 "#")
16059
16060(define_split
16061 [(set (match_operand:DF 0 "register_operand" "")
16062 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16063 (match_operand:DF 2 "nonimmediate_operand" ""))
16064 (match_operand:DF 3 "register_operand" "")
16065 (match_operand:DF 4 "nonimmediate_operand" "")))
16066 (clobber (reg:CC 17))]
16067 "SSE_REG_P (operands[0]) && reload_completed
16068 && ((operands_match_p (operands[1], operands[3])
16069 && operands_match_p (operands[2], operands[4]))
16070 || (operands_match_p (operands[1], operands[4])
16071 && operands_match_p (operands[2], operands[3])))"
16072 [(set (match_dup 0)
16073 (if_then_else:DF (lt (match_dup 1)
16074 (match_dup 2))
16075 (match_dup 1)
16076 (match_dup 2)))])
16077
16078;; We can't represent the LT test directly. Do this by swapping the operands.
16079(define_split
16080 [(set (match_operand:DF 0 "register_operand" "")
16081 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16082 (match_operand:DF 2 "register_operand" ""))
16083 (match_operand:DF 3 "register_operand" "")
16084 (match_operand:DF 4 "register_operand" "")))
16085 (clobber (reg:CC 17))]
16086 "FP_REG_P (operands[0]) && reload_completed
16087 && ((operands_match_p (operands[1], operands[3])
16088 && operands_match_p (operands[2], operands[4]))
16089 || (operands_match_p (operands[1], operands[4])
16090 && operands_match_p (operands[2], operands[3])))"
16091 [(set (reg:CCFP 17)
16092 (compare:CCFP (match_dup 2)
16093 (match_dup 2)))
16094 (set (match_dup 0)
16095 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16096 (match_dup 1)
16097 (match_dup 2)))])
16098
16099(define_insn "*mindf_sse"
16100 [(set (match_operand:DF 0 "register_operand" "=Y")
16101 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16102 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16103 (match_dup 1)
16104 (match_dup 2)))]
16105 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16106 "minsd\t{%2, %0|%0, %2}"
16107 [(set_attr "type" "sse")
16108 (set_attr "mode" "DF")])
16109
16110(define_expand "maxsf3"
16111 [(parallel [
16112 (set (match_operand:SF 0 "register_operand" "")
16113 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16114 (match_operand:SF 2 "nonimmediate_operand" ""))
16115 (match_dup 1)
16116 (match_dup 2)))
16117 (clobber (reg:CC 17))])]
16118 "TARGET_SSE"
16119 "#")
16120
16121(define_insn "*maxsf"
16122 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16123 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16124 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16125 (match_dup 1)
16126 (match_dup 2)))
16127 (clobber (reg:CC 17))]
16128 "TARGET_SSE && TARGET_IEEE_FP"
16129 "#")
16130
16131(define_insn "*maxsf_nonieee"
16132 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16221 "#")
16222
16223(define_split
16224 [(set (match_operand:DF 0 "register_operand" "")
16225 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16226 (match_operand:DF 2 "nonimmediate_operand" ""))
16227 (match_operand:DF 3 "register_operand" "")
16228 (match_operand:DF 4 "nonimmediate_operand" "")))
16229 (clobber (reg:CC 17))]
16230 "SSE_REG_P (operands[0]) && reload_completed
16231 && ((operands_match_p (operands[1], operands[3])
16232 && operands_match_p (operands[2], operands[4]))
16233 || (operands_match_p (operands[1], operands[4])
16234 && operands_match_p (operands[2], operands[3])))"
16235 [(set (match_dup 0)
16236 (if_then_else:DF (lt (match_dup 1)
16237 (match_dup 2))
16238 (match_dup 1)
16239 (match_dup 2)))])
16240
16241;; We can't represent the LT test directly. Do this by swapping the operands.
16242(define_split
16243 [(set (match_operand:DF 0 "register_operand" "")
16244 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16245 (match_operand:DF 2 "register_operand" ""))
16246 (match_operand:DF 3 "register_operand" "")
16247 (match_operand:DF 4 "register_operand" "")))
16248 (clobber (reg:CC 17))]
16249 "FP_REG_P (operands[0]) && reload_completed
16250 && ((operands_match_p (operands[1], operands[3])
16251 && operands_match_p (operands[2], operands[4]))
16252 || (operands_match_p (operands[1], operands[4])
16253 && operands_match_p (operands[2], operands[3])))"
16254 [(set (reg:CCFP 17)
16255 (compare:CCFP (match_dup 2)
16256 (match_dup 2)))
16257 (set (match_dup 0)
16258 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16259 (match_dup 1)
16260 (match_dup 2)))])
16261
16262(define_insn "*mindf_sse"
16263 [(set (match_operand:DF 0 "register_operand" "=Y")
16264 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16265 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16266 (match_dup 1)
16267 (match_dup 2)))]
16268 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16269 "minsd\t{%2, %0|%0, %2}"
16270 [(set_attr "type" "sse")
16271 (set_attr "mode" "DF")])
16272
16273(define_expand "maxsf3"
16274 [(parallel [
16275 (set (match_operand:SF 0 "register_operand" "")
16276 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16277 (match_operand:SF 2 "nonimmediate_operand" ""))
16278 (match_dup 1)
16279 (match_dup 2)))
16280 (clobber (reg:CC 17))])]
16281 "TARGET_SSE"
16282 "#")
16283
16284(define_insn "*maxsf"
16285 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16286 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16287 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16288 (match_dup 1)
16289 (match_dup 2)))
16290 (clobber (reg:CC 17))]
16291 "TARGET_SSE && TARGET_IEEE_FP"
16292 "#")
16293
16294(define_insn "*maxsf_nonieee"
16295 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16133 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
16296 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16134 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16135 (match_dup 1)
16136 (match_dup 2)))
16137 (clobber (reg:CC 17))]
16297 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16298 (match_dup 1)
16299 (match_dup 2)))
16300 (clobber (reg:CC 17))]
16138 "TARGET_SSE && !TARGET_IEEE_FP"
16301 "TARGET_SSE && !TARGET_IEEE_FP
16302 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16139 "#")
16140
16141(define_split
16142 [(set (match_operand:SF 0 "register_operand" "")
16143 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16144 (match_operand:SF 2 "nonimmediate_operand" ""))
16145 (match_operand:SF 3 "register_operand" "")
16146 (match_operand:SF 4 "nonimmediate_operand" "")))
16147 (clobber (reg:CC 17))]
16148 "SSE_REG_P (operands[0]) && reload_completed
16149 && ((operands_match_p (operands[1], operands[3])
16150 && operands_match_p (operands[2], operands[4]))
16151 || (operands_match_p (operands[1], operands[4])
16152 && operands_match_p (operands[2], operands[3])))"
16153 [(set (match_dup 0)
16154 (if_then_else:SF (gt (match_dup 1)
16155 (match_dup 2))
16156 (match_dup 1)
16157 (match_dup 2)))])
16158
16159(define_split
16160 [(set (match_operand:SF 0 "register_operand" "")
16161 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16162 (match_operand:SF 2 "register_operand" ""))
16163 (match_operand:SF 3 "register_operand" "")
16164 (match_operand:SF 4 "register_operand" "")))
16165 (clobber (reg:CC 17))]
16166 "FP_REG_P (operands[0]) && reload_completed
16167 && ((operands_match_p (operands[1], operands[3])
16168 && operands_match_p (operands[2], operands[4]))
16169 || (operands_match_p (operands[1], operands[4])
16170 && operands_match_p (operands[2], operands[3])))"
16171 [(set (reg:CCFP 17)
16172 (compare:CCFP (match_dup 1)
16173 (match_dup 2)))
16174 (set (match_dup 0)
16175 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16176 (match_dup 1)
16177 (match_dup 2)))])
16178
16179(define_insn "*maxsf_sse"
16180 [(set (match_operand:SF 0 "register_operand" "=x")
16181 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16182 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16183 (match_dup 1)
16184 (match_dup 2)))]
16185 "TARGET_SSE && reload_completed"
16186 "maxss\t{%2, %0|%0, %2}"
16187 [(set_attr "type" "sse")
16188 (set_attr "mode" "SF")])
16189
16190(define_expand "maxdf3"
16191 [(parallel [
16192 (set (match_operand:DF 0 "register_operand" "")
16193 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16194 (match_operand:DF 2 "nonimmediate_operand" ""))
16195 (match_dup 1)
16196 (match_dup 2)))
16197 (clobber (reg:CC 17))])]
16198 "TARGET_SSE2 && TARGET_SSE_MATH"
16199 "#")
16200
16201(define_insn "*maxdf"
16202 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16203 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16204 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16205 (match_dup 1)
16206 (match_dup 2)))
16207 (clobber (reg:CC 17))]
16208 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16209 "#")
16210
16211(define_insn "*maxdf_nonieee"
16212 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16303 "#")
16304
16305(define_split
16306 [(set (match_operand:SF 0 "register_operand" "")
16307 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16308 (match_operand:SF 2 "nonimmediate_operand" ""))
16309 (match_operand:SF 3 "register_operand" "")
16310 (match_operand:SF 4 "nonimmediate_operand" "")))
16311 (clobber (reg:CC 17))]
16312 "SSE_REG_P (operands[0]) && reload_completed
16313 && ((operands_match_p (operands[1], operands[3])
16314 && operands_match_p (operands[2], operands[4]))
16315 || (operands_match_p (operands[1], operands[4])
16316 && operands_match_p (operands[2], operands[3])))"
16317 [(set (match_dup 0)
16318 (if_then_else:SF (gt (match_dup 1)
16319 (match_dup 2))
16320 (match_dup 1)
16321 (match_dup 2)))])
16322
16323(define_split
16324 [(set (match_operand:SF 0 "register_operand" "")
16325 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16326 (match_operand:SF 2 "register_operand" ""))
16327 (match_operand:SF 3 "register_operand" "")
16328 (match_operand:SF 4 "register_operand" "")))
16329 (clobber (reg:CC 17))]
16330 "FP_REG_P (operands[0]) && reload_completed
16331 && ((operands_match_p (operands[1], operands[3])
16332 && operands_match_p (operands[2], operands[4]))
16333 || (operands_match_p (operands[1], operands[4])
16334 && operands_match_p (operands[2], operands[3])))"
16335 [(set (reg:CCFP 17)
16336 (compare:CCFP (match_dup 1)
16337 (match_dup 2)))
16338 (set (match_dup 0)
16339 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16340 (match_dup 1)
16341 (match_dup 2)))])
16342
16343(define_insn "*maxsf_sse"
16344 [(set (match_operand:SF 0 "register_operand" "=x")
16345 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16346 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16347 (match_dup 1)
16348 (match_dup 2)))]
16349 "TARGET_SSE && reload_completed"
16350 "maxss\t{%2, %0|%0, %2}"
16351 [(set_attr "type" "sse")
16352 (set_attr "mode" "SF")])
16353
16354(define_expand "maxdf3"
16355 [(parallel [
16356 (set (match_operand:DF 0 "register_operand" "")
16357 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16358 (match_operand:DF 2 "nonimmediate_operand" ""))
16359 (match_dup 1)
16360 (match_dup 2)))
16361 (clobber (reg:CC 17))])]
16362 "TARGET_SSE2 && TARGET_SSE_MATH"
16363 "#")
16364
16365(define_insn "*maxdf"
16366 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16367 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16368 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16369 (match_dup 1)
16370 (match_dup 2)))
16371 (clobber (reg:CC 17))]
16372 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16373 "#")
16374
16375(define_insn "*maxdf_nonieee"
16376 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16213 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
16377 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16214 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16215 (match_dup 1)
16216 (match_dup 2)))
16217 (clobber (reg:CC 17))]
16378 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16379 (match_dup 1)
16380 (match_dup 2)))
16381 (clobber (reg:CC 17))]
16218 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP"
16382 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16383 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16219 "#")
16220
16221(define_split
16222 [(set (match_operand:DF 0 "register_operand" "")
16223 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16224 (match_operand:DF 2 "nonimmediate_operand" ""))
16225 (match_operand:DF 3 "register_operand" "")
16226 (match_operand:DF 4 "nonimmediate_operand" "")))
16227 (clobber (reg:CC 17))]
16228 "SSE_REG_P (operands[0]) && reload_completed
16229 && ((operands_match_p (operands[1], operands[3])
16230 && operands_match_p (operands[2], operands[4]))
16231 || (operands_match_p (operands[1], operands[4])
16232 && operands_match_p (operands[2], operands[3])))"
16233 [(set (match_dup 0)
16234 (if_then_else:DF (gt (match_dup 1)
16235 (match_dup 2))
16236 (match_dup 1)
16237 (match_dup 2)))])
16238
16239(define_split
16240 [(set (match_operand:DF 0 "register_operand" "")
16241 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16242 (match_operand:DF 2 "register_operand" ""))
16243 (match_operand:DF 3 "register_operand" "")
16244 (match_operand:DF 4 "register_operand" "")))
16245 (clobber (reg:CC 17))]
16246 "FP_REG_P (operands[0]) && reload_completed
16247 && ((operands_match_p (operands[1], operands[3])
16248 && operands_match_p (operands[2], operands[4]))
16249 || (operands_match_p (operands[1], operands[4])
16250 && operands_match_p (operands[2], operands[3])))"
16251 [(set (reg:CCFP 17)
16252 (compare:CCFP (match_dup 1)
16253 (match_dup 2)))
16254 (set (match_dup 0)
16255 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16256 (match_dup 1)
16257 (match_dup 2)))])
16258
16259(define_insn "*maxdf_sse"
16260 [(set (match_operand:DF 0 "register_operand" "=Y")
16261 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16262 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16263 (match_dup 1)
16264 (match_dup 2)))]
16265 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16266 "maxsd\t{%2, %0|%0, %2}"
16267 [(set_attr "type" "sse")
16268 (set_attr "mode" "DF")])
16269
16270;; Misc patterns (?)
16271
16272;; This pattern exists to put a dependency on all ebp-based memory accesses.
16273;; Otherwise there will be nothing to keep
16274;;
16275;; [(set (reg ebp) (reg esp))]
16276;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16277;; (clobber (eflags)]
16278;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16279;;
16280;; in proper program order.
16281(define_expand "pro_epilogue_adjust_stack"
16282 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
16283 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16284 (match_operand:SI 2 "immediate_operand" "i,i")))
16285 (clobber (reg:CC 17))
16286 (clobber (mem:BLK (scratch)))])]
16287 ""
16288{
16289 if (TARGET_64BIT)
16290 {
16291 emit_insn (gen_pro_epilogue_adjust_stack_rex64
16292 (operands[0], operands[1], operands[2]));
16293 DONE;
16294 }
16295})
16296
16297(define_insn "*pro_epilogue_adjust_stack_1"
16298 [(set (match_operand:SI 0 "register_operand" "=r,r")
16299 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16300 (match_operand:SI 2 "immediate_operand" "i,i")))
16301 (clobber (reg:CC 17))
16302 (clobber (mem:BLK (scratch)))]
16303 "!TARGET_64BIT"
16304{
16305 switch (get_attr_type (insn))
16306 {
16307 case TYPE_IMOV:
16308 return "mov{l}\t{%1, %0|%0, %1}";
16309
16310 case TYPE_ALU:
16311 if (GET_CODE (operands[2]) == CONST_INT
16312 && (INTVAL (operands[2]) == 128
16313 || (INTVAL (operands[2]) < 0
16314 && INTVAL (operands[2]) != -128)))
16315 {
16316 operands[2] = GEN_INT (-INTVAL (operands[2]));
16317 return "sub{l}\t{%2, %0|%0, %2}";
16318 }
16319 return "add{l}\t{%2, %0|%0, %2}";
16320
16321 case TYPE_LEA:
16322 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16323 return "lea{l}\t{%a2, %0|%0, %a2}";
16324
16325 default:
16326 abort ();
16327 }
16328}
16329 [(set (attr "type")
16330 (cond [(eq_attr "alternative" "0")
16331 (const_string "alu")
16332 (match_operand:SI 2 "const0_operand" "")
16333 (const_string "imov")
16334 ]
16335 (const_string "lea")))
16336 (set_attr "mode" "SI")])
16337
16338(define_insn "pro_epilogue_adjust_stack_rex64"
16339 [(set (match_operand:DI 0 "register_operand" "=r,r")
16340 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16341 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16342 (clobber (reg:CC 17))
16343 (clobber (mem:BLK (scratch)))]
16344 "TARGET_64BIT"
16345{
16346 switch (get_attr_type (insn))
16347 {
16348 case TYPE_IMOV:
16349 return "mov{q}\t{%1, %0|%0, %1}";
16350
16351 case TYPE_ALU:
16352 if (GET_CODE (operands[2]) == CONST_INT
16353 && (INTVAL (operands[2]) == 128
16354 || (INTVAL (operands[2]) < 0
16355 && INTVAL (operands[2]) != -128)))
16356 {
16357 operands[2] = GEN_INT (-INTVAL (operands[2]));
16358 return "sub{q}\t{%2, %0|%0, %2}";
16359 }
16360 return "add{q}\t{%2, %0|%0, %2}";
16361
16362 case TYPE_LEA:
16363 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16364 return "lea{q}\t{%a2, %0|%0, %a2}";
16365
16366 default:
16367 abort ();
16368 }
16369}
16370 [(set (attr "type")
16371 (cond [(eq_attr "alternative" "0")
16372 (const_string "alu")
16373 (match_operand:DI 2 "const0_operand" "")
16374 (const_string "imov")
16375 ]
16376 (const_string "lea")))
16377 (set_attr "mode" "DI")])
16378
16379
16380;; Placeholder for the conditional moves. This one is split either to SSE
16381;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16382;; fact is that compares supported by the cmp??ss instructions are exactly
16383;; swapped of those supported by cmove sequence.
16384;; The EQ/NE comparisons also needs bit care, since they are not directly
16385;; supported by i387 comparisons and we do need to emit two conditional moves
16386;; in tandem.
16387
16388(define_insn "sse_movsfcc"
16389 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16390 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16391 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16392 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16393 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16394 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16395 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16396 (clobber (reg:CC 17))]
16397 "TARGET_SSE
16398 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16399 && (!TARGET_IEEE_FP
16400 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16401 "#")
16402
16403(define_insn "sse_movsfcc_eq"
16404 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16405 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16406 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16407 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16408 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16409 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16410 (clobber (reg:CC 17))]
16411 "TARGET_SSE
16412 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16413 "#")
16414
16415(define_insn "sse_movdfcc"
16416 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16417 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16418 [(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16419 (match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16420 (match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16421 (match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16422 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16423 (clobber (reg:CC 17))]
16424 "TARGET_SSE2
16425 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16426 && (!TARGET_IEEE_FP
16427 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16428 "#")
16429
16430(define_insn "sse_movdfcc_eq"
16431 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16432 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16433 (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16434 (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16435 (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16436 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16437 (clobber (reg:CC 17))]
16438 "TARGET_SSE
16439 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16440 "#")
16441
16442;; For non-sse moves just expand the usual cmove sequence.
16443(define_split
16444 [(set (match_operand 0 "register_operand" "")
16445 (if_then_else (match_operator 1 "comparison_operator"
16446 [(match_operand 4 "nonimmediate_operand" "")
16447 (match_operand 5 "register_operand" "")])
16448 (match_operand 2 "nonimmediate_operand" "")
16449 (match_operand 3 "nonimmediate_operand" "")))
16450 (clobber (match_operand 6 "" ""))
16451 (clobber (reg:CC 17))]
16452 "!SSE_REG_P (operands[0]) && reload_completed
16453 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16454 [(const_int 0)]
16455{
16456 ix86_compare_op0 = operands[5];
16457 ix86_compare_op1 = operands[4];
16458 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16459 VOIDmode, operands[5], operands[4]);
16460 ix86_expand_fp_movcc (operands);
16461 DONE;
16462})
16463
16464;; Split SSE based conditional move into seqence:
16465;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
16466;; and op2, op0 - zero op2 if comparison was false
16467;; nand op0, op3 - load op3 to op0 if comparison was false
16468;; or op2, op0 - get the non-zero one into the result.
16469(define_split
16470 [(set (match_operand 0 "register_operand" "")
16471 (if_then_else (match_operator 1 "sse_comparison_operator"
16472 [(match_operand 4 "register_operand" "")
16473 (match_operand 5 "nonimmediate_operand" "")])
16474 (match_operand 2 "register_operand" "")
16475 (match_operand 3 "register_operand" "")))
16476 (clobber (match_operand 6 "" ""))
16477 (clobber (reg:CC 17))]
16478 "SSE_REG_P (operands[0]) && reload_completed"
16479 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16480 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
16481 (subreg:TI (match_dup 4) 0)))
16482 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
16483 (subreg:TI (match_dup 3) 0)))
16484 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16485 (subreg:TI (match_dup 7) 0)))]
16486{
16487 PUT_MODE (operands[1], GET_MODE (operands[0]));
16488 if (operands_match_p (operands[0], operands[4]))
16489 operands[6] = operands[4], operands[7] = operands[2];
16490 else
16491 operands[6] = operands[2], operands[7] = operands[4];
16492})
16493
16494;; Special case of conditional move we can handle effectivly.
16495;; Do not brother with the integer/floating point case, since these are
16496;; bot considerably slower, unlike in the generic case.
16497(define_insn "*sse_movsfcc_const0_1"
16498 [(set (match_operand:SF 0 "register_operand" "=x")
16499 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16500 [(match_operand:SF 4 "register_operand" "0")
16501 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16502 (match_operand:SF 2 "register_operand" "x")
16503 (match_operand:SF 3 "const0_operand" "X")))]
16504 "TARGET_SSE"
16505 "#")
16506
16507(define_insn "*sse_movsfcc_const0_2"
16508 [(set (match_operand:SF 0 "register_operand" "=x")
16509 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16510 [(match_operand:SF 4 "register_operand" "0")
16511 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16512 (match_operand:SF 2 "const0_operand" "X")
16513 (match_operand:SF 3 "register_operand" "x")))]
16514 "TARGET_SSE"
16515 "#")
16516
16517(define_insn "*sse_movsfcc_const0_3"
16518 [(set (match_operand:SF 0 "register_operand" "=x")
16519 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16520 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16521 (match_operand:SF 5 "register_operand" "0")])
16522 (match_operand:SF 2 "register_operand" "x")
16523 (match_operand:SF 3 "const0_operand" "X")))]
16524 "TARGET_SSE"
16525 "#")
16526
16527(define_insn "*sse_movsfcc_const0_4"
16528 [(set (match_operand:SF 0 "register_operand" "=x")
16529 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16530 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16531 (match_operand:SF 5 "register_operand" "0")])
16532 (match_operand:SF 2 "const0_operand" "X")
16533 (match_operand:SF 3 "register_operand" "x")))]
16534 "TARGET_SSE"
16535 "#")
16536
16537(define_insn "*sse_movdfcc_const0_1"
16538 [(set (match_operand:SF 0 "register_operand" "=x")
16539 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16540 [(match_operand:SF 4 "register_operand" "0")
16541 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16542 (match_operand:SF 2 "register_operand" "x")
16543 (match_operand:SF 3 "const0_operand" "X")))]
16544 "TARGET_SSE2"
16545 "#")
16546
16547(define_insn "*sse_movdfcc_const0_2"
16548 [(set (match_operand:SF 0 "register_operand" "=x")
16549 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16550 [(match_operand:SF 4 "register_operand" "0")
16551 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16552 (match_operand:SF 2 "const0_operand" "X")
16553 (match_operand:SF 3 "register_operand" "x")))]
16554 "TARGET_SSE2"
16555 "#")
16556
16557(define_insn "*sse_movdfcc_const0_3"
16558 [(set (match_operand:SF 0 "register_operand" "=x")
16559 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16560 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16561 (match_operand:SF 5 "register_operand" "0")])
16562 (match_operand:SF 2 "register_operand" "x")
16563 (match_operand:SF 3 "const0_operand" "X")))]
16564 "TARGET_SSE2"
16565 "#")
16566
16567(define_insn "*sse_movdfcc_const0_4"
16568 [(set (match_operand:SF 0 "register_operand" "=x")
16569 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16570 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16571 (match_operand:SF 5 "register_operand" "0")])
16572 (match_operand:SF 2 "const0_operand" "X")
16573 (match_operand:SF 3 "register_operand" "x")))]
16574 "TARGET_SSE2"
16575 "#")
16576
16577(define_split
16578 [(set (match_operand 0 "register_operand" "")
16579 (if_then_else (match_operator 1 "comparison_operator"
16580 [(match_operand 4 "register_operand" "")
16581 (match_operand 5 "nonimmediate_operand" "")])
16582 (match_operand 2 "nonmemory_operand" "")
16583 (match_operand 3 "nonmemory_operand" "")))]
16584 "SSE_REG_P (operands[0]) && reload_completed
16585 && (const0_operand (operands[2], GET_MODE (operands[0]))
16586 || const0_operand (operands[3], GET_MODE (operands[0])))"
16587 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16588 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16589 (subreg:TI (match_dup 7) 0)))]
16590{
16591 PUT_MODE (operands[1], GET_MODE (operands[0]));
16592 if (!sse_comparison_operator (operands[1], VOIDmode))
16593 {
16594 rtx tmp = operands[5];
16595 operands[5] = operands[4];
16596 operands[4] = tmp;
16597 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16598 }
16599 if (const0_operand (operands[2], GET_MODE (operands[0])))
16600 {
16601 operands[7] = operands[3];
16602 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16603 0));
16604 }
16605 else
16606 {
16607 operands[7] = operands[2];
16608 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16609 }
16610})
16611
16612(define_expand "allocate_stack_worker"
16613 [(match_operand:SI 0 "register_operand" "")]
16614 "TARGET_STACK_PROBE"
16615{
16616 if (TARGET_64BIT)
16617 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16618 else
16619 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16620 DONE;
16621})
16622
16623(define_insn "allocate_stack_worker_1"
16624 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
16625 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
16626 (clobber (match_dup 0))
16627 (clobber (reg:CC 17))]
16628 "!TARGET_64BIT && TARGET_STACK_PROBE"
16629 "call\t__alloca"
16630 [(set_attr "type" "multi")
16631 (set_attr "length" "5")])
16632
16633(define_insn "allocate_stack_worker_rex64"
16634 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
16635 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16636 (clobber (match_dup 0))
16637 (clobber (reg:CC 17))]
16638 "TARGET_64BIT && TARGET_STACK_PROBE"
16639 "call\t__alloca"
16640 [(set_attr "type" "multi")
16641 (set_attr "length" "5")])
16642
16643(define_expand "allocate_stack"
16644 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16645 (minus:SI (reg:SI 7)
16646 (match_operand:SI 1 "general_operand" "")))
16647 (clobber (reg:CC 17))])
16648 (parallel [(set (reg:SI 7)
16649 (minus:SI (reg:SI 7) (match_dup 1)))
16650 (clobber (reg:CC 17))])]
16651 "TARGET_STACK_PROBE"
16652{
16653#ifdef CHECK_STACK_LIMIT
16654 if (GET_CODE (operands[1]) == CONST_INT
16655 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16656 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
16657 operands[1]));
16658 else
16659#endif
16660 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
16661 operands[1])));
16662
16663 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16664 DONE;
16665})
16666
16667(define_expand "builtin_setjmp_receiver"
16668 [(label_ref (match_operand 0 "" ""))]
16669 "!TARGET_64BIT && flag_pic"
16670{
16671 load_pic_register ();
16672 DONE;
16673})
16674
16675;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16676
16677(define_split
16678 [(set (match_operand 0 "register_operand" "")
16679 (match_operator 3 "promotable_binary_operator"
16680 [(match_operand 1 "register_operand" "")
16681 (match_operand 2 "aligned_operand" "")]))
16682 (clobber (reg:CC 17))]
16683 "! TARGET_PARTIAL_REG_STALL && reload_completed
16684 && ((GET_MODE (operands[0]) == HImode
16685 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
16686 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16687 || (GET_MODE (operands[0]) == QImode
16688 && (TARGET_PROMOTE_QImode || optimize_size)))"
16689 [(parallel [(set (match_dup 0)
16690 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16691 (clobber (reg:CC 17))])]
16692 "operands[0] = gen_lowpart (SImode, operands[0]);
16693 operands[1] = gen_lowpart (SImode, operands[1]);
16694 if (GET_CODE (operands[3]) != ASHIFT)
16695 operands[2] = gen_lowpart (SImode, operands[2]);
16696 PUT_MODE (operands[3], SImode);")
16697
16698(define_split
16699 [(set (reg 17)
16700 (compare (and (match_operand 1 "aligned_operand" "")
16701 (match_operand 2 "const_int_operand" ""))
16702 (const_int 0)))
16703 (set (match_operand 0 "register_operand" "")
16704 (and (match_dup 1) (match_dup 2)))]
16705 "! TARGET_PARTIAL_REG_STALL && reload_completed
16706 && ix86_match_ccmode (insn, CCNOmode)
16707 && (GET_MODE (operands[0]) == HImode
16708 || (GET_MODE (operands[0]) == QImode
16709 && (TARGET_PROMOTE_QImode || optimize_size)))"
16710 [(parallel [(set (reg:CCNO 17)
16711 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16712 (const_int 0)))
16713 (set (match_dup 0)
16714 (and:SI (match_dup 1) (match_dup 2)))])]
16715 "operands[2]
16716 = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
16717 & GET_MODE_MASK (GET_MODE (operands[0])),
16718 SImode));
16719 operands[0] = gen_lowpart (SImode, operands[0]);
16720 operands[1] = gen_lowpart (SImode, operands[1]);")
16721
16722(define_split
16723 [(set (reg 17)
16724 (compare (and (match_operand 0 "aligned_operand" "")
16725 (match_operand 1 "const_int_operand" ""))
16726 (const_int 0)))]
16727 "! TARGET_PARTIAL_REG_STALL && reload_completed
16728 && ix86_match_ccmode (insn, CCNOmode)
16729 && (GET_MODE (operands[0]) == HImode
16730 || (GET_MODE (operands[0]) == QImode
16731 && (TARGET_PROMOTE_QImode || optimize_size)))"
16732 [(set (reg:CCNO 17)
16733 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16734 (const_int 0)))]
16735 "operands[1]
16736 = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
16737 & GET_MODE_MASK (GET_MODE (operands[0])),
16738 SImode));
16739 operands[0] = gen_lowpart (SImode, operands[0]);")
16740
16741(define_split
16742 [(set (match_operand 0 "register_operand" "")
16743 (neg (match_operand 1 "register_operand" "")))
16744 (clobber (reg:CC 17))]
16745 "! TARGET_PARTIAL_REG_STALL && reload_completed
16746 && (GET_MODE (operands[0]) == HImode
16747 || (GET_MODE (operands[0]) == QImode
16748 && (TARGET_PROMOTE_QImode || optimize_size)))"
16749 [(parallel [(set (match_dup 0)
16750 (neg:SI (match_dup 1)))
16751 (clobber (reg:CC 17))])]
16752 "operands[0] = gen_lowpart (SImode, operands[0]);
16753 operands[1] = gen_lowpart (SImode, operands[1]);")
16754
16755(define_split
16756 [(set (match_operand 0 "register_operand" "")
16757 (not (match_operand 1 "register_operand" "")))]
16758 "! TARGET_PARTIAL_REG_STALL && reload_completed
16759 && (GET_MODE (operands[0]) == HImode
16760 || (GET_MODE (operands[0]) == QImode
16761 && (TARGET_PROMOTE_QImode || optimize_size)))"
16762 [(set (match_dup 0)
16763 (not:SI (match_dup 1)))]
16764 "operands[0] = gen_lowpart (SImode, operands[0]);
16765 operands[1] = gen_lowpart (SImode, operands[1]);")
16766
16767(define_split
16768 [(set (match_operand 0 "register_operand" "")
16769 (if_then_else (match_operator 1 "comparison_operator"
16770 [(reg 17) (const_int 0)])
16771 (match_operand 2 "register_operand" "")
16772 (match_operand 3 "register_operand" "")))]
16773 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16774 && (GET_MODE (operands[0]) == HImode
16775 || (GET_MODE (operands[0]) == QImode
16776 && (TARGET_PROMOTE_QImode || optimize_size)))"
16777 [(set (match_dup 0)
16778 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16779 "operands[0] = gen_lowpart (SImode, operands[0]);
16780 operands[2] = gen_lowpart (SImode, operands[2]);
16781 operands[3] = gen_lowpart (SImode, operands[3]);")
16782
16783
16784;; RTL Peephole optimizations, run before sched2. These primarily look to
16785;; transform a complex memory operation into two memory to register operations.
16786
16787;; Don't push memory operands
16788(define_peephole2
16789 [(set (match_operand:SI 0 "push_operand" "")
16790 (match_operand:SI 1 "memory_operand" ""))
16791 (match_scratch:SI 2 "r")]
16792 "! optimize_size && ! TARGET_PUSH_MEMORY"
16793 [(set (match_dup 2) (match_dup 1))
16794 (set (match_dup 0) (match_dup 2))]
16795 "")
16796
16797(define_peephole2
16798 [(set (match_operand:DI 0 "push_operand" "")
16799 (match_operand:DI 1 "memory_operand" ""))
16800 (match_scratch:DI 2 "r")]
16801 "! optimize_size && ! TARGET_PUSH_MEMORY"
16802 [(set (match_dup 2) (match_dup 1))
16803 (set (match_dup 0) (match_dup 2))]
16804 "")
16805
16806;; We need to handle SFmode only, because DFmode and XFmode is split to
16807;; SImode pushes.
16808(define_peephole2
16809 [(set (match_operand:SF 0 "push_operand" "")
16810 (match_operand:SF 1 "memory_operand" ""))
16811 (match_scratch:SF 2 "r")]
16812 "! optimize_size && ! TARGET_PUSH_MEMORY"
16813 [(set (match_dup 2) (match_dup 1))
16814 (set (match_dup 0) (match_dup 2))]
16815 "")
16816
16817(define_peephole2
16818 [(set (match_operand:HI 0 "push_operand" "")
16819 (match_operand:HI 1 "memory_operand" ""))
16820 (match_scratch:HI 2 "r")]
16821 "! optimize_size && ! TARGET_PUSH_MEMORY"
16822 [(set (match_dup 2) (match_dup 1))
16823 (set (match_dup 0) (match_dup 2))]
16824 "")
16825
16826(define_peephole2
16827 [(set (match_operand:QI 0 "push_operand" "")
16828 (match_operand:QI 1 "memory_operand" ""))
16829 (match_scratch:QI 2 "q")]
16830 "! optimize_size && ! TARGET_PUSH_MEMORY"
16831 [(set (match_dup 2) (match_dup 1))
16832 (set (match_dup 0) (match_dup 2))]
16833 "")
16834
16835;; Don't move an immediate directly to memory when the instruction
16836;; gets too big.
16837(define_peephole2
16838 [(match_scratch:SI 1 "r")
16839 (set (match_operand:SI 0 "memory_operand" "")
16840 (const_int 0))]
16841 "! optimize_size
16842 && ! TARGET_USE_MOV0
16843 && TARGET_SPLIT_LONG_MOVES
16844 && get_attr_length (insn) >= ix86_cost->large_insn
16845 && peep2_regno_dead_p (0, FLAGS_REG)"
16846 [(parallel [(set (match_dup 1) (const_int 0))
16847 (clobber (reg:CC 17))])
16848 (set (match_dup 0) (match_dup 1))]
16849 "")
16850
16851(define_peephole2
16852 [(match_scratch:HI 1 "r")
16853 (set (match_operand:HI 0 "memory_operand" "")
16854 (const_int 0))]
16855 "! optimize_size
16856 && ! TARGET_USE_MOV0
16857 && TARGET_SPLIT_LONG_MOVES
16858 && get_attr_length (insn) >= ix86_cost->large_insn
16859 && peep2_regno_dead_p (0, FLAGS_REG)"
16860 [(parallel [(set (match_dup 2) (const_int 0))
16861 (clobber (reg:CC 17))])
16862 (set (match_dup 0) (match_dup 1))]
16863 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16864
16865(define_peephole2
16866 [(match_scratch:QI 1 "q")
16867 (set (match_operand:QI 0 "memory_operand" "")
16868 (const_int 0))]
16869 "! optimize_size
16870 && ! TARGET_USE_MOV0
16871 && TARGET_SPLIT_LONG_MOVES
16872 && get_attr_length (insn) >= ix86_cost->large_insn
16873 && peep2_regno_dead_p (0, FLAGS_REG)"
16874 [(parallel [(set (match_dup 2) (const_int 0))
16875 (clobber (reg:CC 17))])
16876 (set (match_dup 0) (match_dup 1))]
16877 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16878
16879(define_peephole2
16880 [(match_scratch:SI 2 "r")
16881 (set (match_operand:SI 0 "memory_operand" "")
16882 (match_operand:SI 1 "immediate_operand" ""))]
16883 "! optimize_size
16884 && get_attr_length (insn) >= ix86_cost->large_insn
16885 && TARGET_SPLIT_LONG_MOVES"
16886 [(set (match_dup 2) (match_dup 1))
16887 (set (match_dup 0) (match_dup 2))]
16888 "")
16889
16890(define_peephole2
16891 [(match_scratch:HI 2 "r")
16892 (set (match_operand:HI 0 "memory_operand" "")
16893 (match_operand:HI 1 "immediate_operand" ""))]
16894 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16895 && TARGET_SPLIT_LONG_MOVES"
16896 [(set (match_dup 2) (match_dup 1))
16897 (set (match_dup 0) (match_dup 2))]
16898 "")
16899
16900(define_peephole2
16901 [(match_scratch:QI 2 "q")
16902 (set (match_operand:QI 0 "memory_operand" "")
16903 (match_operand:QI 1 "immediate_operand" ""))]
16904 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16905 && TARGET_SPLIT_LONG_MOVES"
16906 [(set (match_dup 2) (match_dup 1))
16907 (set (match_dup 0) (match_dup 2))]
16908 "")
16909
16910;; Don't compare memory with zero, load and use a test instead.
16911(define_peephole2
16912 [(set (reg 17)
16913 (compare (match_operand:SI 0 "memory_operand" "")
16914 (const_int 0)))
16915 (match_scratch:SI 3 "r")]
16916 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
16917 [(set (match_dup 3) (match_dup 0))
16918 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
16919 "")
16920
16921;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16922;; Don't split NOTs with a displacement operand, because resulting XOR
16923;; will not be pariable anyway.
16924;;
16925;; On AMD K6, NOT is vector decoded with memory operand that can not be
16926;; represented using a modRM byte. The XOR replacement is long decoded,
16927;; so this split helps here as well.
16928;;
16929;; Note: Can't do this as a regular split because we can't get proper
16930;; lifetime information then.
16931
16932(define_peephole2
16933 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16934 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16935 "!optimize_size
16936 && peep2_regno_dead_p (0, FLAGS_REG)
16937 && ((TARGET_PENTIUM
16938 && (GET_CODE (operands[0]) != MEM
16939 || !memory_displacement_operand (operands[0], SImode)))
16940 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
16941 [(parallel [(set (match_dup 0)
16942 (xor:SI (match_dup 1) (const_int -1)))
16943 (clobber (reg:CC 17))])]
16944 "")
16945
16946(define_peephole2
16947 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16948 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16949 "!optimize_size
16950 && peep2_regno_dead_p (0, FLAGS_REG)
16951 && ((TARGET_PENTIUM
16952 && (GET_CODE (operands[0]) != MEM
16953 || !memory_displacement_operand (operands[0], HImode)))
16954 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
16955 [(parallel [(set (match_dup 0)
16956 (xor:HI (match_dup 1) (const_int -1)))
16957 (clobber (reg:CC 17))])]
16958 "")
16959
16960(define_peephole2
16961 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16962 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16963 "!optimize_size
16964 && peep2_regno_dead_p (0, FLAGS_REG)
16965 && ((TARGET_PENTIUM
16966 && (GET_CODE (operands[0]) != MEM
16967 || !memory_displacement_operand (operands[0], QImode)))
16968 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
16969 [(parallel [(set (match_dup 0)
16970 (xor:QI (match_dup 1) (const_int -1)))
16971 (clobber (reg:CC 17))])]
16972 "")
16973
16974;; Non pairable "test imm, reg" instructions can be translated to
16975;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16976;; byte opcode instead of two, have a short form for byte operands),
16977;; so do it for other CPUs as well. Given that the value was dead,
16978;; this should not create any new dependencies. Pass on the sub-word
16979;; versions if we're concerned about partial register stalls.
16980
16981(define_peephole2
16982 [(set (reg 17)
16983 (compare (and:SI (match_operand:SI 0 "register_operand" "")
16984 (match_operand:SI 1 "immediate_operand" ""))
16985 (const_int 0)))]
16986 "ix86_match_ccmode (insn, CCNOmode)
16987 && (true_regnum (operands[0]) != 0
16988 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
16989 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16990 [(parallel
16991 [(set (reg:CCNO 17)
16992 (compare:CCNO (and:SI (match_dup 0)
16993 (match_dup 1))
16994 (const_int 0)))
16995 (set (match_dup 0)
16996 (and:SI (match_dup 0) (match_dup 1)))])]
16997 "")
16998
16999;; We don't need to handle HImode case, because it will be promoted to SImode
17000;; on ! TARGET_PARTIAL_REG_STALL
17001
17002(define_peephole2
17003 [(set (reg 17)
17004 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17005 (match_operand:QI 1 "immediate_operand" ""))
17006 (const_int 0)))]
17007 "! TARGET_PARTIAL_REG_STALL
17008 && ix86_match_ccmode (insn, CCNOmode)
17009 && true_regnum (operands[0]) != 0
17010 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17011 [(parallel
17012 [(set (reg:CCNO 17)
17013 (compare:CCNO (and:QI (match_dup 0)
17014 (match_dup 1))
17015 (const_int 0)))
17016 (set (match_dup 0)
17017 (and:QI (match_dup 0) (match_dup 1)))])]
17018 "")
17019
17020(define_peephole2
17021 [(set (reg 17)
17022 (compare
17023 (and:SI
17024 (zero_extract:SI
17025 (match_operand 0 "ext_register_operand" "")
17026 (const_int 8)
17027 (const_int 8))
17028 (match_operand 1 "const_int_operand" ""))
17029 (const_int 0)))]
17030 "! TARGET_PARTIAL_REG_STALL
17031 && ix86_match_ccmode (insn, CCNOmode)
17032 && true_regnum (operands[0]) != 0
17033 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17034 [(parallel [(set (reg:CCNO 17)
17035 (compare:CCNO
17036 (and:SI
17037 (zero_extract:SI
17038 (match_dup 0)
17039 (const_int 8)
17040 (const_int 8))
17041 (match_dup 1))
17042 (const_int 0)))
17043 (set (zero_extract:SI (match_dup 0)
17044 (const_int 8)
17045 (const_int 8))
17046 (and:SI
17047 (zero_extract:SI
17048 (match_dup 0)
17049 (const_int 8)
17050 (const_int 8))
17051 (match_dup 1)))])]
17052 "")
17053
17054;; Don't do logical operations with memory inputs.
17055(define_peephole2
17056 [(match_scratch:SI 2 "r")
17057 (parallel [(set (match_operand:SI 0 "register_operand" "")
17058 (match_operator:SI 3 "arith_or_logical_operator"
17059 [(match_dup 0)
17060 (match_operand:SI 1 "memory_operand" "")]))
17061 (clobber (reg:CC 17))])]
17062 "! optimize_size && ! TARGET_READ_MODIFY"
17063 [(set (match_dup 2) (match_dup 1))
17064 (parallel [(set (match_dup 0)
17065 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17066 (clobber (reg:CC 17))])]
17067 "")
17068
17069(define_peephole2
17070 [(match_scratch:SI 2 "r")
17071 (parallel [(set (match_operand:SI 0 "register_operand" "")
17072 (match_operator:SI 3 "arith_or_logical_operator"
17073 [(match_operand:SI 1 "memory_operand" "")
17074 (match_dup 0)]))
17075 (clobber (reg:CC 17))])]
17076 "! optimize_size && ! TARGET_READ_MODIFY"
17077 [(set (match_dup 2) (match_dup 1))
17078 (parallel [(set (match_dup 0)
17079 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17080 (clobber (reg:CC 17))])]
17081 "")
17082
17083; Don't do logical operations with memory outputs
17084;
17085; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17086; instruction into two 1-uop insns plus a 2-uop insn. That last has
17087; the same decoder scheduling characteristics as the original.
17088
17089(define_peephole2
17090 [(match_scratch:SI 2 "r")
17091 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17092 (match_operator:SI 3 "arith_or_logical_operator"
17093 [(match_dup 0)
17094 (match_operand:SI 1 "nonmemory_operand" "")]))
17095 (clobber (reg:CC 17))])]
17096 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17097 [(set (match_dup 2) (match_dup 0))
17098 (parallel [(set (match_dup 2)
17099 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17100 (clobber (reg:CC 17))])
17101 (set (match_dup 0) (match_dup 2))]
17102 "")
17103
17104(define_peephole2
17105 [(match_scratch:SI 2 "r")
17106 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17107 (match_operator:SI 3 "arith_or_logical_operator"
17108 [(match_operand:SI 1 "nonmemory_operand" "")
17109 (match_dup 0)]))
17110 (clobber (reg:CC 17))])]
17111 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17112 [(set (match_dup 2) (match_dup 0))
17113 (parallel [(set (match_dup 2)
17114 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17115 (clobber (reg:CC 17))])
17116 (set (match_dup 0) (match_dup 2))]
17117 "")
17118
17119;; Attempt to always use XOR for zeroing registers.
17120(define_peephole2
17121 [(set (match_operand 0 "register_operand" "")
17122 (const_int 0))]
17123 "(GET_MODE (operands[0]) == QImode
17124 || GET_MODE (operands[0]) == HImode
17125 || GET_MODE (operands[0]) == SImode
17126 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17127 && (! TARGET_USE_MOV0 || optimize_size)
17128 && peep2_regno_dead_p (0, FLAGS_REG)"
17129 [(parallel [(set (match_dup 0) (const_int 0))
17130 (clobber (reg:CC 17))])]
17131 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17132 true_regnum (operands[0]));")
17133
17134(define_peephole2
17135 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17136 (const_int 0))]
17137 "(GET_MODE (operands[0]) == QImode
17138 || GET_MODE (operands[0]) == HImode)
17139 && (! TARGET_USE_MOV0 || optimize_size)
17140 && peep2_regno_dead_p (0, FLAGS_REG)"
17141 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17142 (clobber (reg:CC 17))])])
17143
17144;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17145(define_peephole2
17146 [(set (match_operand 0 "register_operand" "")
17147 (const_int -1))]
17148 "(GET_MODE (operands[0]) == HImode
17149 || GET_MODE (operands[0]) == SImode
17150 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17151 && (optimize_size || TARGET_PENTIUM)
17152 && peep2_regno_dead_p (0, FLAGS_REG)"
17153 [(parallel [(set (match_dup 0) (const_int -1))
17154 (clobber (reg:CC 17))])]
17155 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17156 true_regnum (operands[0]));")
17157
17158;; Attempt to convert simple leas to adds. These can be created by
17159;; move expanders.
17160(define_peephole2
17161 [(set (match_operand:SI 0 "register_operand" "")
17162 (plus:SI (match_dup 0)
17163 (match_operand:SI 1 "nonmemory_operand" "")))]
17164 "peep2_regno_dead_p (0, FLAGS_REG)"
17165 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17166 (clobber (reg:CC 17))])]
17167 "")
17168
17169(define_peephole2
17170 [(set (match_operand:SI 0 "register_operand" "")
17171 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17172 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17173 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17174 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17175 (clobber (reg:CC 17))])]
17176 "operands[2] = gen_lowpart (SImode, operands[2]);")
17177
17178(define_peephole2
17179 [(set (match_operand:DI 0 "register_operand" "")
17180 (plus:DI (match_dup 0)
17181 (match_operand:DI 1 "x86_64_general_operand" "")))]
17182 "peep2_regno_dead_p (0, FLAGS_REG)"
17183 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17184 (clobber (reg:CC 17))])]
17185 "")
17186
17187(define_peephole2
17188 [(set (match_operand:SI 0 "register_operand" "")
17189 (mult:SI (match_dup 0)
17190 (match_operand:SI 1 "const_int_operand" "")))]
17191 "exact_log2 (INTVAL (operands[1])) >= 0
17192 && peep2_regno_dead_p (0, FLAGS_REG)"
17193 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17194 (clobber (reg:CC 17))])]
17195 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17196
17197(define_peephole2
17198 [(set (match_operand:DI 0 "register_operand" "")
17199 (mult:DI (match_dup 0)
17200 (match_operand:DI 1 "const_int_operand" "")))]
17201 "exact_log2 (INTVAL (operands[1])) >= 0
17202 && peep2_regno_dead_p (0, FLAGS_REG)"
17203 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17204 (clobber (reg:CC 17))])]
17205 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17206
17207(define_peephole2
17208 [(set (match_operand:SI 0 "register_operand" "")
17209 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17210 (match_operand:DI 2 "const_int_operand" "")) 0))]
17211 "exact_log2 (INTVAL (operands[1])) >= 0
17212 && REGNO (operands[0]) == REGNO (operands[1])
17213 && peep2_regno_dead_p (0, FLAGS_REG)"
17214 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17215 (clobber (reg:CC 17))])]
17216 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17217
17218;; The ESP adjustments can be done by the push and pop instructions. Resulting
17219;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17220;; many CPUs it is also faster, since special hardware to avoid esp
17221;; dependencies is present.
17222
17223;; While some of these conversions may be done using splitters, we use peepholes
17224;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17225
17226;; Convert prologue esp subtractions to push.
17227;; We need register to push. In order to keep verify_flow_info happy we have
17228;; two choices
17229;; - use scratch and clobber it in order to avoid dependencies
17230;; - use already live register
17231;; We can't use the second way right now, since there is no reliable way how to
17232;; verify that given register is live. First choice will also most likely in
17233;; fewer dependencies. On the place of esp adjustments it is very likely that
17234;; call clobbered registers are dead. We may want to use base pointer as an
17235;; alternative when no register is available later.
17236
17237(define_peephole2
17238 [(match_scratch:SI 0 "r")
17239 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17240 (clobber (reg:CC 17))
17241 (clobber (mem:BLK (scratch)))])]
17242 "optimize_size || !TARGET_SUB_ESP_4"
17243 [(clobber (match_dup 0))
17244 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17245 (clobber (mem:BLK (scratch)))])])
17246
17247(define_peephole2
17248 [(match_scratch:SI 0 "r")
17249 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17250 (clobber (reg:CC 17))
17251 (clobber (mem:BLK (scratch)))])]
17252 "optimize_size || !TARGET_SUB_ESP_8"
17253 [(clobber (match_dup 0))
17254 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17255 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17256 (clobber (mem:BLK (scratch)))])])
17257
17258;; Convert esp subtractions to push.
17259(define_peephole2
17260 [(match_scratch:SI 0 "r")
17261 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17262 (clobber (reg:CC 17))])]
17263 "optimize_size || !TARGET_SUB_ESP_4"
17264 [(clobber (match_dup 0))
17265 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17266
17267(define_peephole2
17268 [(match_scratch:SI 0 "r")
17269 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17270 (clobber (reg:CC 17))])]
17271 "optimize_size || !TARGET_SUB_ESP_8"
17272 [(clobber (match_dup 0))
17273 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17274 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17275
17276;; Convert epilogue deallocator to pop.
17277(define_peephole2
17278 [(match_scratch:SI 0 "r")
17279 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17280 (clobber (reg:CC 17))
17281 (clobber (mem:BLK (scratch)))])]
17282 "optimize_size || !TARGET_ADD_ESP_4"
17283 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17284 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17285 (clobber (mem:BLK (scratch)))])]
17286 "")
17287
17288;; Two pops case is tricky, since pop causes dependency on destination register.
17289;; We use two registers if available.
17290(define_peephole2
17291 [(match_scratch:SI 0 "r")
17292 (match_scratch:SI 1 "r")
17293 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17294 (clobber (reg:CC 17))
17295 (clobber (mem:BLK (scratch)))])]
17296 "optimize_size || !TARGET_ADD_ESP_8"
17297 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17298 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17299 (clobber (mem:BLK (scratch)))])
17300 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17301 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17302 "")
17303
17304(define_peephole2
17305 [(match_scratch:SI 0 "r")
17306 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17307 (clobber (reg:CC 17))
17308 (clobber (mem:BLK (scratch)))])]
17309 "optimize_size"
17310 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17311 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17312 (clobber (mem:BLK (scratch)))])
17313 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17314 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17315 "")
17316
17317;; Convert esp additions to pop.
17318(define_peephole2
17319 [(match_scratch:SI 0 "r")
17320 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17321 (clobber (reg:CC 17))])]
17322 ""
17323 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17324 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17325 "")
17326
17327;; Two pops case is tricky, since pop causes dependency on destination register.
17328;; We use two registers if available.
17329(define_peephole2
17330 [(match_scratch:SI 0 "r")
17331 (match_scratch:SI 1 "r")
17332 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17333 (clobber (reg:CC 17))])]
17334 ""
17335 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17336 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17337 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17338 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17339 "")
17340
17341(define_peephole2
17342 [(match_scratch:SI 0 "r")
17343 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17344 (clobber (reg:CC 17))])]
17345 "optimize_size"
17346 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17347 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17348 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17349 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17350 "")
17351
17352;; Convert compares with 1 to shorter inc/dec operations when CF is not
17353;; required and register dies.
17354(define_peephole2
17355 [(set (reg 17)
17356 (compare (match_operand:SI 0 "register_operand" "")
17357 (match_operand:SI 1 "incdec_operand" "")))]
17358 "ix86_match_ccmode (insn, CCGCmode)
17359 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17360 [(parallel [(set (reg:CCGC 17)
17361 (compare:CCGC (match_dup 0)
17362 (match_dup 1)))
17363 (clobber (match_dup 0))])]
17364 "")
17365
17366(define_peephole2
17367 [(set (reg 17)
17368 (compare (match_operand:HI 0 "register_operand" "")
17369 (match_operand:HI 1 "incdec_operand" "")))]
17370 "ix86_match_ccmode (insn, CCGCmode)
17371 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17372 [(parallel [(set (reg:CCGC 17)
17373 (compare:CCGC (match_dup 0)
17374 (match_dup 1)))
17375 (clobber (match_dup 0))])]
17376 "")
17377
17378(define_peephole2
17379 [(set (reg 17)
17380 (compare (match_operand:QI 0 "register_operand" "")
17381 (match_operand:QI 1 "incdec_operand" "")))]
17382 "ix86_match_ccmode (insn, CCGCmode)
17383 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17384 [(parallel [(set (reg:CCGC 17)
17385 (compare:CCGC (match_dup 0)
17386 (match_dup 1)))
17387 (clobber (match_dup 0))])]
17388 "")
17389
17390;; Convert compares with 128 to shorter add -128
17391(define_peephole2
17392 [(set (reg 17)
17393 (compare (match_operand:SI 0 "register_operand" "")
17394 (const_int 128)))]
17395 "ix86_match_ccmode (insn, CCGCmode)
17396 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17397 [(parallel [(set (reg:CCGC 17)
17398 (compare:CCGC (match_dup 0)
17399 (const_int 128)))
17400 (clobber (match_dup 0))])]
17401 "")
17402
17403(define_peephole2
17404 [(set (reg 17)
17405 (compare (match_operand:HI 0 "register_operand" "")
17406 (const_int 128)))]
17407 "ix86_match_ccmode (insn, CCGCmode)
17408 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17409 [(parallel [(set (reg:CCGC 17)
17410 (compare:CCGC (match_dup 0)
17411 (const_int 128)))
17412 (clobber (match_dup 0))])]
17413 "")
17414
17415(define_peephole2
17416 [(match_scratch:DI 0 "r")
17417 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17418 (clobber (reg:CC 17))
17419 (clobber (mem:BLK (scratch)))])]
17420 "optimize_size || !TARGET_SUB_ESP_4"
17421 [(clobber (match_dup 0))
17422 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17423 (clobber (mem:BLK (scratch)))])])
17424
17425(define_peephole2
17426 [(match_scratch:DI 0 "r")
17427 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17428 (clobber (reg:CC 17))
17429 (clobber (mem:BLK (scratch)))])]
17430 "optimize_size || !TARGET_SUB_ESP_8"
17431 [(clobber (match_dup 0))
17432 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17433 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17434 (clobber (mem:BLK (scratch)))])])
17435
17436;; Convert esp subtractions to push.
17437(define_peephole2
17438 [(match_scratch:DI 0 "r")
17439 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17440 (clobber (reg:CC 17))])]
17441 "optimize_size || !TARGET_SUB_ESP_4"
17442 [(clobber (match_dup 0))
17443 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17444
17445(define_peephole2
17446 [(match_scratch:DI 0 "r")
17447 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17448 (clobber (reg:CC 17))])]
17449 "optimize_size || !TARGET_SUB_ESP_8"
17450 [(clobber (match_dup 0))
17451 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17452 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17453
17454;; Convert epilogue deallocator to pop.
17455(define_peephole2
17456 [(match_scratch:DI 0 "r")
17457 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17458 (clobber (reg:CC 17))
17459 (clobber (mem:BLK (scratch)))])]
17460 "optimize_size || !TARGET_ADD_ESP_4"
17461 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17462 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17463 (clobber (mem:BLK (scratch)))])]
17464 "")
17465
17466;; Two pops case is tricky, since pop causes dependency on destination register.
17467;; We use two registers if available.
17468(define_peephole2
17469 [(match_scratch:DI 0 "r")
17470 (match_scratch:DI 1 "r")
17471 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17472 (clobber (reg:CC 17))
17473 (clobber (mem:BLK (scratch)))])]
17474 "optimize_size || !TARGET_ADD_ESP_8"
17475 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17476 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17477 (clobber (mem:BLK (scratch)))])
17478 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17479 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17480 "")
17481
17482(define_peephole2
17483 [(match_scratch:DI 0 "r")
17484 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17485 (clobber (reg:CC 17))
17486 (clobber (mem:BLK (scratch)))])]
17487 "optimize_size"
17488 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17489 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17490 (clobber (mem:BLK (scratch)))])
17491 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17492 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17493 "")
17494
17495;; Convert esp additions to pop.
17496(define_peephole2
17497 [(match_scratch:DI 0 "r")
17498 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17499 (clobber (reg:CC 17))])]
17500 ""
17501 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17502 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17503 "")
17504
17505;; Two pops case is tricky, since pop causes dependency on destination register.
17506;; We use two registers if available.
17507(define_peephole2
17508 [(match_scratch:DI 0 "r")
17509 (match_scratch:DI 1 "r")
17510 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17511 (clobber (reg:CC 17))])]
17512 ""
17513 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17514 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17515 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17516 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17517 "")
17518
17519(define_peephole2
17520 [(match_scratch:DI 0 "r")
17521 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17522 (clobber (reg:CC 17))])]
17523 "optimize_size"
17524 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17525 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17526 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17527 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17528 "")
17529
17530;; Call-value patterns last so that the wildcard operand does not
17531;; disrupt insn-recog's switch tables.
17532
17533(define_insn "*call_value_pop_0"
17534 [(set (match_operand 0 "" "")
17535 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17536 (match_operand:SI 2 "" "")))
17537 (set (reg:SI 7) (plus:SI (reg:SI 7)
17538 (match_operand:SI 3 "immediate_operand" "")))]
17539 "!TARGET_64BIT"
17540{
17541 if (SIBLING_CALL_P (insn))
17542 return "jmp\t%P1";
17543 else
17544 return "call\t%P1";
17545}
17546 [(set_attr "type" "callv")])
17547
17548(define_insn "*call_value_pop_1"
17549 [(set (match_operand 0 "" "")
17550 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17551 (match_operand:SI 2 "" "")))
17552 (set (reg:SI 7) (plus:SI (reg:SI 7)
17553 (match_operand:SI 3 "immediate_operand" "i")))]
17554 "!TARGET_64BIT"
17555{
17556 if (constant_call_address_operand (operands[1], QImode))
17557 {
17558 if (SIBLING_CALL_P (insn))
17559 return "jmp\t%P1";
17560 else
17561 return "call\t%P1";
17562 }
17563 if (SIBLING_CALL_P (insn))
17564 return "jmp\t%A1";
17565 else
17566 return "call\t%A1";
17567}
17568 [(set_attr "type" "callv")])
17569
17570(define_insn "*call_value_0"
17571 [(set (match_operand 0 "" "")
17572 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17573 (match_operand:SI 2 "" "")))]
17574 "!TARGET_64BIT"
17575{
17576 if (SIBLING_CALL_P (insn))
17577 return "jmp\t%P1";
17578 else
17579 return "call\t%P1";
17580}
17581 [(set_attr "type" "callv")])
17582
17583(define_insn "*call_value_0_rex64"
17584 [(set (match_operand 0 "" "")
17585 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17586 (match_operand:DI 2 "const_int_operand" "")))]
17587 "TARGET_64BIT"
17588{
17589 if (SIBLING_CALL_P (insn))
17590 return "jmp\t%P1";
17591 else
17592 return "call\t%P1";
17593}
17594 [(set_attr "type" "callv")])
17595
17596(define_insn "*call_value_1"
17597 [(set (match_operand 0 "" "")
17598 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17599 (match_operand:SI 2 "" "")))]
17600 "!TARGET_64BIT"
17601{
17602 if (constant_call_address_operand (operands[1], QImode))
17603 {
17604 if (SIBLING_CALL_P (insn))
17605 return "jmp\t%P1";
17606 else
17607 return "call\t%P1";
17608 }
17609 if (SIBLING_CALL_P (insn))
17610 return "jmp\t%*%1";
17611 else
17612 return "call\t%*%1";
17613}
17614 [(set_attr "type" "callv")])
17615
17616(define_insn "*call_value_1_rex64"
17617 [(set (match_operand 0 "" "")
17618 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17619 (match_operand:DI 2 "" "")))]
17620 "TARGET_64BIT"
17621{
17622 if (constant_call_address_operand (operands[1], QImode))
17623 {
17624 if (SIBLING_CALL_P (insn))
17625 return "jmp\t%P1";
17626 else
17627 return "call\t%P1";
17628 }
17629 if (SIBLING_CALL_P (insn))
17630 return "jmp\t%A1";
17631 else
17632 return "call\t%A1";
17633}
17634 [(set_attr "type" "callv")])
17635
17636(define_insn "trap"
17637 [(trap_if (const_int 1) (const_int 5))]
17638 ""
17639 "int\t$5")
17640
17641;;; ix86 doesn't have conditional trap instructions, but we fake them
17642;;; for the sake of bounds checking. By emitting bounds checks as
17643;;; conditional traps rather than as conditional jumps around
17644;;; unconditional traps we avoid introducing spurious basic-block
17645;;; boundaries and facilitate elimination of redundant checks. In
17646;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17647;;; interrupt 5.
17648;;;
17649;;; FIXME: Static branch prediction rules for ix86 are such that
17650;;; forward conditional branches predict as untaken. As implemented
17651;;; below, pseudo conditional traps violate that rule. We should use
17652;;; .pushsection/.popsection to place all of the `int 5's in a special
17653;;; section loaded at the end of the text segment and branch forward
17654;;; there on bounds-failure, and then jump back immediately (in case
17655;;; the system chooses to ignore bounds violations, or to report
17656;;; violations and continue execution).
17657
17658(define_expand "conditional_trap"
17659 [(trap_if (match_operator 0 "comparison_operator"
17660 [(match_dup 2) (const_int 0)])
17661 (match_operand 1 "const_int_operand" ""))]
17662 ""
17663{
17664 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
17665 ix86_expand_compare (GET_CODE (operands[0]),
17666 NULL, NULL),
17667 operands[1]));
17668 DONE;
17669})
17670
17671(define_insn "*conditional_trap_1"
17672 [(trap_if (match_operator 0 "comparison_operator"
17673 [(reg 17) (const_int 0)])
17674 (match_operand 1 "const_int_operand" ""))]
17675 ""
17676{
17677 operands[2] = gen_label_rtx ();
17678 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
17679 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
17680 CODE_LABEL_NUMBER (operands[2]));
17681 RET;
17682})
17683
17684 ;; Pentium III SIMD instructions.
17685
17686;; Moves for SSE/MMX regs.
17687
17688(define_insn "movv4sf_internal"
17689 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17690 (match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
17691 "TARGET_SSE"
17692 ;; @@@ let's try to use movaps here.
17693 "movaps\t{%1, %0|%0, %1}"
17694 [(set_attr "type" "sse")])
17695
17696(define_insn "movv4si_internal"
17697 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17698 (match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
17699 "TARGET_SSE"
17700 ;; @@@ let's try to use movaps here.
17701 "movaps\t{%1, %0|%0, %1}"
17702 [(set_attr "type" "sse")])
17703
17704(define_insn "movv8qi_internal"
17705 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17706 (match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
17707 "TARGET_MMX"
17708 "movq\t{%1, %0|%0, %1}"
17709 [(set_attr "type" "mmx")])
17710
17711(define_insn "movv4hi_internal"
17712 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17713 (match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
17714 "TARGET_MMX"
17715 "movq\t{%1, %0|%0, %1}"
17716 [(set_attr "type" "mmx")])
17717
17718(define_insn "movv2si_internal"
17719 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17720 (match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
17721 "TARGET_MMX"
17722 "movq\t{%1, %0|%0, %1}"
17723 [(set_attr "type" "mmx")])
17724
17725(define_insn "movv2sf_internal"
17726 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
17727 (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
17728 "TARGET_3DNOW"
17729 "movq\\t{%1, %0|%0, %1}"
17730 [(set_attr "type" "mmx")])
17731
17732(define_expand "movti"
17733 [(set (match_operand:TI 0 "general_operand" "")
17734 (match_operand:TI 1 "general_operand" ""))]
17735 "TARGET_SSE || TARGET_64BIT"
17736{
17737 if (TARGET_64BIT)
17738 ix86_expand_move (TImode, operands);
17739 else
17740 ix86_expand_vector_move (TImode, operands);
17741 DONE;
17742})
17743
17744(define_expand "movv4sf"
17745 [(set (match_operand:V4SF 0 "general_operand" "")
17746 (match_operand:V4SF 1 "general_operand" ""))]
17747 "TARGET_SSE"
17748{
17749 ix86_expand_vector_move (V4SFmode, operands);
17750 DONE;
17751})
17752
17753(define_expand "movv4si"
17754 [(set (match_operand:V4SI 0 "general_operand" "")
17755 (match_operand:V4SI 1 "general_operand" ""))]
17756 "TARGET_MMX"
17757{
17758 ix86_expand_vector_move (V4SImode, operands);
17759 DONE;
17760})
17761
17762(define_expand "movv2si"
17763 [(set (match_operand:V2SI 0 "general_operand" "")
17764 (match_operand:V2SI 1 "general_operand" ""))]
17765 "TARGET_MMX"
17766{
17767 ix86_expand_vector_move (V2SImode, operands);
17768 DONE;
17769})
17770
17771(define_expand "movv4hi"
17772 [(set (match_operand:V4HI 0 "general_operand" "")
17773 (match_operand:V4HI 1 "general_operand" ""))]
17774 "TARGET_MMX"
17775{
17776 ix86_expand_vector_move (V4HImode, operands);
17777 DONE;
17778})
17779
17780(define_expand "movv8qi"
17781 [(set (match_operand:V8QI 0 "general_operand" "")
17782 (match_operand:V8QI 1 "general_operand" ""))]
17783 "TARGET_MMX"
17784{
17785 ix86_expand_vector_move (V8QImode, operands);
17786 DONE;
17787})
17788
17789(define_expand "movv2sf"
17790 [(set (match_operand:V2SF 0 "general_operand" "")
17791 (match_operand:V2SF 1 "general_operand" ""))]
17792 "TARGET_3DNOW"
17793{
17794 ix86_expand_vector_move (V2SFmode, operands);
17795 DONE;
17796})
17797
17798(define_insn_and_split "*pushti"
17799 [(set (match_operand:TI 0 "push_operand" "=<")
17800 (match_operand:TI 1 "nonmemory_operand" "x"))]
17801 "TARGET_SSE"
17802 "#"
17803 ""
17804 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17805 (set (mem:TI (reg:SI 7)) (match_dup 1))]
17806 ""
17807 [(set_attr "type" "sse")])
17808
17809(define_insn_and_split "*pushv4sf"
17810 [(set (match_operand:V4SF 0 "push_operand" "=<")
17811 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
17812 "TARGET_SSE"
17813 "#"
17814 ""
17815 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17816 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17817 ""
17818 [(set_attr "type" "sse")])
17819
17820(define_insn_and_split "*pushv4si"
17821 [(set (match_operand:V4SI 0 "push_operand" "=<")
17822 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
17823 "TARGET_SSE"
17824 "#"
17825 ""
17826 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17827 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17828 ""
17829 [(set_attr "type" "sse")])
17830
17831(define_insn_and_split "*pushv2si"
17832 [(set (match_operand:V2SI 0 "push_operand" "=<")
17833 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
17834 "TARGET_MMX"
17835 "#"
17836 ""
17837 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17838 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
17839 ""
17840 [(set_attr "type" "mmx")])
17841
17842(define_insn_and_split "*pushv4hi"
17843 [(set (match_operand:V4HI 0 "push_operand" "=<")
17844 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
17845 "TARGET_MMX"
17846 "#"
17847 ""
17848 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17849 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
17850 ""
17851 [(set_attr "type" "mmx")])
17852
17853(define_insn_and_split "*pushv8qi"
17854 [(set (match_operand:V8QI 0 "push_operand" "=<")
17855 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
17856 "TARGET_MMX"
17857 "#"
17858 ""
17859 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17860 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
17861 ""
17862 [(set_attr "type" "mmx")])
17863
17864(define_insn_and_split "*pushv2sf"
17865 [(set (match_operand:V2SF 0 "push_operand" "=<")
17866 (match_operand:V2SF 1 "nonmemory_operand" "y"))]
17867 "TARGET_3DNOW"
17868 "#"
17869 ""
17870 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17871 (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
17872 ""
17873 [(set_attr "type" "mmx")])
17874
17875(define_insn "movti_internal"
17876 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
17877 (match_operand:TI 1 "general_operand" "O,xm,x"))]
17878 "TARGET_SSE && !TARGET_64BIT"
17879 "@
17880 xorps\t%0, %0
17881 movaps\t{%1, %0|%0, %1}
17882 movaps\t{%1, %0|%0, %1}"
17883 [(set_attr "type" "sse")])
17884
17885(define_insn "*movti_rex64"
17886 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
17887 (match_operand:TI 1 "general_operand" "riFo,riF,O,x,m"))]
17888 "TARGET_64BIT
17889 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17890 "@
17891 #
17892 #
17893 xorps\t%0, %0
17894 movaps\\t{%1, %0|%0, %1}
17895 movaps\\t{%1, %0|%0, %1}"
17896 [(set_attr "type" "*,*,sse,sse,sse")
17897 (set_attr "mode" "TI")])
17898
17899(define_split
17900 [(set (match_operand:TI 0 "nonimmediate_operand" "")
17901 (match_operand:TI 1 "general_operand" ""))]
17902 "reload_completed && !SSE_REG_P (operands[0])
17903 && !SSE_REG_P (operands[1])"
17904 [(const_int 0)]
17905 "ix86_split_long_move (operands); DONE;")
17906
17907;; These two patterns are useful for specifying exactly whether to use
17908;; movaps or movups
17909(define_insn "sse_movaps"
17910 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17911 (unspec:V4SF
17912 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 38))]
17913 "TARGET_SSE"
17914 "@
17915 movaps\t{%1, %0|%0, %1}
17916 movaps\t{%1, %0|%0, %1}"
17917 [(set_attr "type" "sse")])
17918
17919(define_insn "sse_movups"
17920 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17921 (unspec:V4SF
17922 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 39))]
17923 "TARGET_SSE"
17924 "@
17925 movups\t{%1, %0|%0, %1}
17926 movups\t{%1, %0|%0, %1}"
17927 [(set_attr "type" "sse")])
17928
17929
17930;; SSE Strange Moves.
17931
17932(define_insn "sse_movmskps"
17933 [(set (match_operand:SI 0 "register_operand" "=r")
17934 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
17935 "TARGET_SSE"
17936 "movmskps\t{%1, %0|%0, %1}"
17937 [(set_attr "type" "sse")])
17938
17939(define_insn "mmx_pmovmskb"
17940 [(set (match_operand:SI 0 "register_operand" "=r")
17941 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
17942 "TARGET_SSE || TARGET_3DNOW_A"
17943 "pmovmskb\t{%1, %0|%0, %1}"
17944 [(set_attr "type" "sse")])
17945
17946(define_insn "mmx_maskmovq"
17947 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
17948 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
17949 (match_operand:V8QI 2 "register_operand" "y")] 32))]
16384 "#")
16385
16386(define_split
16387 [(set (match_operand:DF 0 "register_operand" "")
16388 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16389 (match_operand:DF 2 "nonimmediate_operand" ""))
16390 (match_operand:DF 3 "register_operand" "")
16391 (match_operand:DF 4 "nonimmediate_operand" "")))
16392 (clobber (reg:CC 17))]
16393 "SSE_REG_P (operands[0]) && reload_completed
16394 && ((operands_match_p (operands[1], operands[3])
16395 && operands_match_p (operands[2], operands[4]))
16396 || (operands_match_p (operands[1], operands[4])
16397 && operands_match_p (operands[2], operands[3])))"
16398 [(set (match_dup 0)
16399 (if_then_else:DF (gt (match_dup 1)
16400 (match_dup 2))
16401 (match_dup 1)
16402 (match_dup 2)))])
16403
16404(define_split
16405 [(set (match_operand:DF 0 "register_operand" "")
16406 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16407 (match_operand:DF 2 "register_operand" ""))
16408 (match_operand:DF 3 "register_operand" "")
16409 (match_operand:DF 4 "register_operand" "")))
16410 (clobber (reg:CC 17))]
16411 "FP_REG_P (operands[0]) && reload_completed
16412 && ((operands_match_p (operands[1], operands[3])
16413 && operands_match_p (operands[2], operands[4]))
16414 || (operands_match_p (operands[1], operands[4])
16415 && operands_match_p (operands[2], operands[3])))"
16416 [(set (reg:CCFP 17)
16417 (compare:CCFP (match_dup 1)
16418 (match_dup 2)))
16419 (set (match_dup 0)
16420 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16421 (match_dup 1)
16422 (match_dup 2)))])
16423
16424(define_insn "*maxdf_sse"
16425 [(set (match_operand:DF 0 "register_operand" "=Y")
16426 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16427 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16428 (match_dup 1)
16429 (match_dup 2)))]
16430 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16431 "maxsd\t{%2, %0|%0, %2}"
16432 [(set_attr "type" "sse")
16433 (set_attr "mode" "DF")])
16434
16435;; Misc patterns (?)
16436
16437;; This pattern exists to put a dependency on all ebp-based memory accesses.
16438;; Otherwise there will be nothing to keep
16439;;
16440;; [(set (reg ebp) (reg esp))]
16441;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16442;; (clobber (eflags)]
16443;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16444;;
16445;; in proper program order.
16446(define_expand "pro_epilogue_adjust_stack"
16447 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
16448 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16449 (match_operand:SI 2 "immediate_operand" "i,i")))
16450 (clobber (reg:CC 17))
16451 (clobber (mem:BLK (scratch)))])]
16452 ""
16453{
16454 if (TARGET_64BIT)
16455 {
16456 emit_insn (gen_pro_epilogue_adjust_stack_rex64
16457 (operands[0], operands[1], operands[2]));
16458 DONE;
16459 }
16460})
16461
16462(define_insn "*pro_epilogue_adjust_stack_1"
16463 [(set (match_operand:SI 0 "register_operand" "=r,r")
16464 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16465 (match_operand:SI 2 "immediate_operand" "i,i")))
16466 (clobber (reg:CC 17))
16467 (clobber (mem:BLK (scratch)))]
16468 "!TARGET_64BIT"
16469{
16470 switch (get_attr_type (insn))
16471 {
16472 case TYPE_IMOV:
16473 return "mov{l}\t{%1, %0|%0, %1}";
16474
16475 case TYPE_ALU:
16476 if (GET_CODE (operands[2]) == CONST_INT
16477 && (INTVAL (operands[2]) == 128
16478 || (INTVAL (operands[2]) < 0
16479 && INTVAL (operands[2]) != -128)))
16480 {
16481 operands[2] = GEN_INT (-INTVAL (operands[2]));
16482 return "sub{l}\t{%2, %0|%0, %2}";
16483 }
16484 return "add{l}\t{%2, %0|%0, %2}";
16485
16486 case TYPE_LEA:
16487 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16488 return "lea{l}\t{%a2, %0|%0, %a2}";
16489
16490 default:
16491 abort ();
16492 }
16493}
16494 [(set (attr "type")
16495 (cond [(eq_attr "alternative" "0")
16496 (const_string "alu")
16497 (match_operand:SI 2 "const0_operand" "")
16498 (const_string "imov")
16499 ]
16500 (const_string "lea")))
16501 (set_attr "mode" "SI")])
16502
16503(define_insn "pro_epilogue_adjust_stack_rex64"
16504 [(set (match_operand:DI 0 "register_operand" "=r,r")
16505 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16506 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16507 (clobber (reg:CC 17))
16508 (clobber (mem:BLK (scratch)))]
16509 "TARGET_64BIT"
16510{
16511 switch (get_attr_type (insn))
16512 {
16513 case TYPE_IMOV:
16514 return "mov{q}\t{%1, %0|%0, %1}";
16515
16516 case TYPE_ALU:
16517 if (GET_CODE (operands[2]) == CONST_INT
16518 && (INTVAL (operands[2]) == 128
16519 || (INTVAL (operands[2]) < 0
16520 && INTVAL (operands[2]) != -128)))
16521 {
16522 operands[2] = GEN_INT (-INTVAL (operands[2]));
16523 return "sub{q}\t{%2, %0|%0, %2}";
16524 }
16525 return "add{q}\t{%2, %0|%0, %2}";
16526
16527 case TYPE_LEA:
16528 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16529 return "lea{q}\t{%a2, %0|%0, %a2}";
16530
16531 default:
16532 abort ();
16533 }
16534}
16535 [(set (attr "type")
16536 (cond [(eq_attr "alternative" "0")
16537 (const_string "alu")
16538 (match_operand:DI 2 "const0_operand" "")
16539 (const_string "imov")
16540 ]
16541 (const_string "lea")))
16542 (set_attr "mode" "DI")])
16543
16544
16545;; Placeholder for the conditional moves. This one is split either to SSE
16546;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16547;; fact is that compares supported by the cmp??ss instructions are exactly
16548;; swapped of those supported by cmove sequence.
16549;; The EQ/NE comparisons also needs bit care, since they are not directly
16550;; supported by i387 comparisons and we do need to emit two conditional moves
16551;; in tandem.
16552
16553(define_insn "sse_movsfcc"
16554 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16555 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16556 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16557 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16558 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16559 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16560 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16561 (clobber (reg:CC 17))]
16562 "TARGET_SSE
16563 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16564 && (!TARGET_IEEE_FP
16565 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16566 "#")
16567
16568(define_insn "sse_movsfcc_eq"
16569 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16570 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16571 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16572 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16573 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16574 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16575 (clobber (reg:CC 17))]
16576 "TARGET_SSE
16577 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16578 "#")
16579
16580(define_insn "sse_movdfcc"
16581 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16582 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16583 [(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16584 (match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16585 (match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16586 (match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16587 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16588 (clobber (reg:CC 17))]
16589 "TARGET_SSE2
16590 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16591 && (!TARGET_IEEE_FP
16592 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16593 "#")
16594
16595(define_insn "sse_movdfcc_eq"
16596 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16597 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16598 (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16599 (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16600 (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16601 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16602 (clobber (reg:CC 17))]
16603 "TARGET_SSE
16604 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16605 "#")
16606
16607;; For non-sse moves just expand the usual cmove sequence.
16608(define_split
16609 [(set (match_operand 0 "register_operand" "")
16610 (if_then_else (match_operator 1 "comparison_operator"
16611 [(match_operand 4 "nonimmediate_operand" "")
16612 (match_operand 5 "register_operand" "")])
16613 (match_operand 2 "nonimmediate_operand" "")
16614 (match_operand 3 "nonimmediate_operand" "")))
16615 (clobber (match_operand 6 "" ""))
16616 (clobber (reg:CC 17))]
16617 "!SSE_REG_P (operands[0]) && reload_completed
16618 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16619 [(const_int 0)]
16620{
16621 ix86_compare_op0 = operands[5];
16622 ix86_compare_op1 = operands[4];
16623 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16624 VOIDmode, operands[5], operands[4]);
16625 ix86_expand_fp_movcc (operands);
16626 DONE;
16627})
16628
16629;; Split SSE based conditional move into seqence:
16630;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
16631;; and op2, op0 - zero op2 if comparison was false
16632;; nand op0, op3 - load op3 to op0 if comparison was false
16633;; or op2, op0 - get the non-zero one into the result.
16634(define_split
16635 [(set (match_operand 0 "register_operand" "")
16636 (if_then_else (match_operator 1 "sse_comparison_operator"
16637 [(match_operand 4 "register_operand" "")
16638 (match_operand 5 "nonimmediate_operand" "")])
16639 (match_operand 2 "register_operand" "")
16640 (match_operand 3 "register_operand" "")))
16641 (clobber (match_operand 6 "" ""))
16642 (clobber (reg:CC 17))]
16643 "SSE_REG_P (operands[0]) && reload_completed"
16644 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16645 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
16646 (subreg:TI (match_dup 4) 0)))
16647 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
16648 (subreg:TI (match_dup 3) 0)))
16649 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16650 (subreg:TI (match_dup 7) 0)))]
16651{
16652 PUT_MODE (operands[1], GET_MODE (operands[0]));
16653 if (operands_match_p (operands[0], operands[4]))
16654 operands[6] = operands[4], operands[7] = operands[2];
16655 else
16656 operands[6] = operands[2], operands[7] = operands[4];
16657})
16658
16659;; Special case of conditional move we can handle effectivly.
16660;; Do not brother with the integer/floating point case, since these are
16661;; bot considerably slower, unlike in the generic case.
16662(define_insn "*sse_movsfcc_const0_1"
16663 [(set (match_operand:SF 0 "register_operand" "=x")
16664 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16665 [(match_operand:SF 4 "register_operand" "0")
16666 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16667 (match_operand:SF 2 "register_operand" "x")
16668 (match_operand:SF 3 "const0_operand" "X")))]
16669 "TARGET_SSE"
16670 "#")
16671
16672(define_insn "*sse_movsfcc_const0_2"
16673 [(set (match_operand:SF 0 "register_operand" "=x")
16674 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16675 [(match_operand:SF 4 "register_operand" "0")
16676 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16677 (match_operand:SF 2 "const0_operand" "X")
16678 (match_operand:SF 3 "register_operand" "x")))]
16679 "TARGET_SSE"
16680 "#")
16681
16682(define_insn "*sse_movsfcc_const0_3"
16683 [(set (match_operand:SF 0 "register_operand" "=x")
16684 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16685 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16686 (match_operand:SF 5 "register_operand" "0")])
16687 (match_operand:SF 2 "register_operand" "x")
16688 (match_operand:SF 3 "const0_operand" "X")))]
16689 "TARGET_SSE"
16690 "#")
16691
16692(define_insn "*sse_movsfcc_const0_4"
16693 [(set (match_operand:SF 0 "register_operand" "=x")
16694 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16695 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16696 (match_operand:SF 5 "register_operand" "0")])
16697 (match_operand:SF 2 "const0_operand" "X")
16698 (match_operand:SF 3 "register_operand" "x")))]
16699 "TARGET_SSE"
16700 "#")
16701
16702(define_insn "*sse_movdfcc_const0_1"
16703 [(set (match_operand:SF 0 "register_operand" "=x")
16704 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16705 [(match_operand:SF 4 "register_operand" "0")
16706 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16707 (match_operand:SF 2 "register_operand" "x")
16708 (match_operand:SF 3 "const0_operand" "X")))]
16709 "TARGET_SSE2"
16710 "#")
16711
16712(define_insn "*sse_movdfcc_const0_2"
16713 [(set (match_operand:SF 0 "register_operand" "=x")
16714 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16715 [(match_operand:SF 4 "register_operand" "0")
16716 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16717 (match_operand:SF 2 "const0_operand" "X")
16718 (match_operand:SF 3 "register_operand" "x")))]
16719 "TARGET_SSE2"
16720 "#")
16721
16722(define_insn "*sse_movdfcc_const0_3"
16723 [(set (match_operand:SF 0 "register_operand" "=x")
16724 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16725 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16726 (match_operand:SF 5 "register_operand" "0")])
16727 (match_operand:SF 2 "register_operand" "x")
16728 (match_operand:SF 3 "const0_operand" "X")))]
16729 "TARGET_SSE2"
16730 "#")
16731
16732(define_insn "*sse_movdfcc_const0_4"
16733 [(set (match_operand:SF 0 "register_operand" "=x")
16734 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16735 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16736 (match_operand:SF 5 "register_operand" "0")])
16737 (match_operand:SF 2 "const0_operand" "X")
16738 (match_operand:SF 3 "register_operand" "x")))]
16739 "TARGET_SSE2"
16740 "#")
16741
16742(define_split
16743 [(set (match_operand 0 "register_operand" "")
16744 (if_then_else (match_operator 1 "comparison_operator"
16745 [(match_operand 4 "register_operand" "")
16746 (match_operand 5 "nonimmediate_operand" "")])
16747 (match_operand 2 "nonmemory_operand" "")
16748 (match_operand 3 "nonmemory_operand" "")))]
16749 "SSE_REG_P (operands[0]) && reload_completed
16750 && (const0_operand (operands[2], GET_MODE (operands[0]))
16751 || const0_operand (operands[3], GET_MODE (operands[0])))"
16752 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16753 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16754 (subreg:TI (match_dup 7) 0)))]
16755{
16756 PUT_MODE (operands[1], GET_MODE (operands[0]));
16757 if (!sse_comparison_operator (operands[1], VOIDmode))
16758 {
16759 rtx tmp = operands[5];
16760 operands[5] = operands[4];
16761 operands[4] = tmp;
16762 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16763 }
16764 if (const0_operand (operands[2], GET_MODE (operands[0])))
16765 {
16766 operands[7] = operands[3];
16767 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16768 0));
16769 }
16770 else
16771 {
16772 operands[7] = operands[2];
16773 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16774 }
16775})
16776
16777(define_expand "allocate_stack_worker"
16778 [(match_operand:SI 0 "register_operand" "")]
16779 "TARGET_STACK_PROBE"
16780{
16781 if (TARGET_64BIT)
16782 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16783 else
16784 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16785 DONE;
16786})
16787
16788(define_insn "allocate_stack_worker_1"
16789 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
16790 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
16791 (clobber (match_dup 0))
16792 (clobber (reg:CC 17))]
16793 "!TARGET_64BIT && TARGET_STACK_PROBE"
16794 "call\t__alloca"
16795 [(set_attr "type" "multi")
16796 (set_attr "length" "5")])
16797
16798(define_insn "allocate_stack_worker_rex64"
16799 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
16800 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16801 (clobber (match_dup 0))
16802 (clobber (reg:CC 17))]
16803 "TARGET_64BIT && TARGET_STACK_PROBE"
16804 "call\t__alloca"
16805 [(set_attr "type" "multi")
16806 (set_attr "length" "5")])
16807
16808(define_expand "allocate_stack"
16809 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16810 (minus:SI (reg:SI 7)
16811 (match_operand:SI 1 "general_operand" "")))
16812 (clobber (reg:CC 17))])
16813 (parallel [(set (reg:SI 7)
16814 (minus:SI (reg:SI 7) (match_dup 1)))
16815 (clobber (reg:CC 17))])]
16816 "TARGET_STACK_PROBE"
16817{
16818#ifdef CHECK_STACK_LIMIT
16819 if (GET_CODE (operands[1]) == CONST_INT
16820 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16821 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
16822 operands[1]));
16823 else
16824#endif
16825 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
16826 operands[1])));
16827
16828 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16829 DONE;
16830})
16831
16832(define_expand "builtin_setjmp_receiver"
16833 [(label_ref (match_operand 0 "" ""))]
16834 "!TARGET_64BIT && flag_pic"
16835{
16836 load_pic_register ();
16837 DONE;
16838})
16839
16840;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16841
16842(define_split
16843 [(set (match_operand 0 "register_operand" "")
16844 (match_operator 3 "promotable_binary_operator"
16845 [(match_operand 1 "register_operand" "")
16846 (match_operand 2 "aligned_operand" "")]))
16847 (clobber (reg:CC 17))]
16848 "! TARGET_PARTIAL_REG_STALL && reload_completed
16849 && ((GET_MODE (operands[0]) == HImode
16850 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
16851 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16852 || (GET_MODE (operands[0]) == QImode
16853 && (TARGET_PROMOTE_QImode || optimize_size)))"
16854 [(parallel [(set (match_dup 0)
16855 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16856 (clobber (reg:CC 17))])]
16857 "operands[0] = gen_lowpart (SImode, operands[0]);
16858 operands[1] = gen_lowpart (SImode, operands[1]);
16859 if (GET_CODE (operands[3]) != ASHIFT)
16860 operands[2] = gen_lowpart (SImode, operands[2]);
16861 PUT_MODE (operands[3], SImode);")
16862
16863(define_split
16864 [(set (reg 17)
16865 (compare (and (match_operand 1 "aligned_operand" "")
16866 (match_operand 2 "const_int_operand" ""))
16867 (const_int 0)))
16868 (set (match_operand 0 "register_operand" "")
16869 (and (match_dup 1) (match_dup 2)))]
16870 "! TARGET_PARTIAL_REG_STALL && reload_completed
16871 && ix86_match_ccmode (insn, CCNOmode)
16872 && (GET_MODE (operands[0]) == HImode
16873 || (GET_MODE (operands[0]) == QImode
16874 && (TARGET_PROMOTE_QImode || optimize_size)))"
16875 [(parallel [(set (reg:CCNO 17)
16876 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16877 (const_int 0)))
16878 (set (match_dup 0)
16879 (and:SI (match_dup 1) (match_dup 2)))])]
16880 "operands[2]
16881 = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
16882 & GET_MODE_MASK (GET_MODE (operands[0])),
16883 SImode));
16884 operands[0] = gen_lowpart (SImode, operands[0]);
16885 operands[1] = gen_lowpart (SImode, operands[1]);")
16886
16887(define_split
16888 [(set (reg 17)
16889 (compare (and (match_operand 0 "aligned_operand" "")
16890 (match_operand 1 "const_int_operand" ""))
16891 (const_int 0)))]
16892 "! TARGET_PARTIAL_REG_STALL && reload_completed
16893 && ix86_match_ccmode (insn, CCNOmode)
16894 && (GET_MODE (operands[0]) == HImode
16895 || (GET_MODE (operands[0]) == QImode
16896 && (TARGET_PROMOTE_QImode || optimize_size)))"
16897 [(set (reg:CCNO 17)
16898 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16899 (const_int 0)))]
16900 "operands[1]
16901 = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
16902 & GET_MODE_MASK (GET_MODE (operands[0])),
16903 SImode));
16904 operands[0] = gen_lowpart (SImode, operands[0]);")
16905
16906(define_split
16907 [(set (match_operand 0 "register_operand" "")
16908 (neg (match_operand 1 "register_operand" "")))
16909 (clobber (reg:CC 17))]
16910 "! TARGET_PARTIAL_REG_STALL && reload_completed
16911 && (GET_MODE (operands[0]) == HImode
16912 || (GET_MODE (operands[0]) == QImode
16913 && (TARGET_PROMOTE_QImode || optimize_size)))"
16914 [(parallel [(set (match_dup 0)
16915 (neg:SI (match_dup 1)))
16916 (clobber (reg:CC 17))])]
16917 "operands[0] = gen_lowpart (SImode, operands[0]);
16918 operands[1] = gen_lowpart (SImode, operands[1]);")
16919
16920(define_split
16921 [(set (match_operand 0 "register_operand" "")
16922 (not (match_operand 1 "register_operand" "")))]
16923 "! TARGET_PARTIAL_REG_STALL && reload_completed
16924 && (GET_MODE (operands[0]) == HImode
16925 || (GET_MODE (operands[0]) == QImode
16926 && (TARGET_PROMOTE_QImode || optimize_size)))"
16927 [(set (match_dup 0)
16928 (not:SI (match_dup 1)))]
16929 "operands[0] = gen_lowpart (SImode, operands[0]);
16930 operands[1] = gen_lowpart (SImode, operands[1]);")
16931
16932(define_split
16933 [(set (match_operand 0 "register_operand" "")
16934 (if_then_else (match_operator 1 "comparison_operator"
16935 [(reg 17) (const_int 0)])
16936 (match_operand 2 "register_operand" "")
16937 (match_operand 3 "register_operand" "")))]
16938 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16939 && (GET_MODE (operands[0]) == HImode
16940 || (GET_MODE (operands[0]) == QImode
16941 && (TARGET_PROMOTE_QImode || optimize_size)))"
16942 [(set (match_dup 0)
16943 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16944 "operands[0] = gen_lowpart (SImode, operands[0]);
16945 operands[2] = gen_lowpart (SImode, operands[2]);
16946 operands[3] = gen_lowpart (SImode, operands[3]);")
16947
16948
16949;; RTL Peephole optimizations, run before sched2. These primarily look to
16950;; transform a complex memory operation into two memory to register operations.
16951
16952;; Don't push memory operands
16953(define_peephole2
16954 [(set (match_operand:SI 0 "push_operand" "")
16955 (match_operand:SI 1 "memory_operand" ""))
16956 (match_scratch:SI 2 "r")]
16957 "! optimize_size && ! TARGET_PUSH_MEMORY"
16958 [(set (match_dup 2) (match_dup 1))
16959 (set (match_dup 0) (match_dup 2))]
16960 "")
16961
16962(define_peephole2
16963 [(set (match_operand:DI 0 "push_operand" "")
16964 (match_operand:DI 1 "memory_operand" ""))
16965 (match_scratch:DI 2 "r")]
16966 "! optimize_size && ! TARGET_PUSH_MEMORY"
16967 [(set (match_dup 2) (match_dup 1))
16968 (set (match_dup 0) (match_dup 2))]
16969 "")
16970
16971;; We need to handle SFmode only, because DFmode and XFmode is split to
16972;; SImode pushes.
16973(define_peephole2
16974 [(set (match_operand:SF 0 "push_operand" "")
16975 (match_operand:SF 1 "memory_operand" ""))
16976 (match_scratch:SF 2 "r")]
16977 "! optimize_size && ! TARGET_PUSH_MEMORY"
16978 [(set (match_dup 2) (match_dup 1))
16979 (set (match_dup 0) (match_dup 2))]
16980 "")
16981
16982(define_peephole2
16983 [(set (match_operand:HI 0 "push_operand" "")
16984 (match_operand:HI 1 "memory_operand" ""))
16985 (match_scratch:HI 2 "r")]
16986 "! optimize_size && ! TARGET_PUSH_MEMORY"
16987 [(set (match_dup 2) (match_dup 1))
16988 (set (match_dup 0) (match_dup 2))]
16989 "")
16990
16991(define_peephole2
16992 [(set (match_operand:QI 0 "push_operand" "")
16993 (match_operand:QI 1 "memory_operand" ""))
16994 (match_scratch:QI 2 "q")]
16995 "! optimize_size && ! TARGET_PUSH_MEMORY"
16996 [(set (match_dup 2) (match_dup 1))
16997 (set (match_dup 0) (match_dup 2))]
16998 "")
16999
17000;; Don't move an immediate directly to memory when the instruction
17001;; gets too big.
17002(define_peephole2
17003 [(match_scratch:SI 1 "r")
17004 (set (match_operand:SI 0 "memory_operand" "")
17005 (const_int 0))]
17006 "! optimize_size
17007 && ! TARGET_USE_MOV0
17008 && TARGET_SPLIT_LONG_MOVES
17009 && get_attr_length (insn) >= ix86_cost->large_insn
17010 && peep2_regno_dead_p (0, FLAGS_REG)"
17011 [(parallel [(set (match_dup 1) (const_int 0))
17012 (clobber (reg:CC 17))])
17013 (set (match_dup 0) (match_dup 1))]
17014 "")
17015
17016(define_peephole2
17017 [(match_scratch:HI 1 "r")
17018 (set (match_operand:HI 0 "memory_operand" "")
17019 (const_int 0))]
17020 "! optimize_size
17021 && ! TARGET_USE_MOV0
17022 && TARGET_SPLIT_LONG_MOVES
17023 && get_attr_length (insn) >= ix86_cost->large_insn
17024 && peep2_regno_dead_p (0, FLAGS_REG)"
17025 [(parallel [(set (match_dup 2) (const_int 0))
17026 (clobber (reg:CC 17))])
17027 (set (match_dup 0) (match_dup 1))]
17028 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
17029
17030(define_peephole2
17031 [(match_scratch:QI 1 "q")
17032 (set (match_operand:QI 0 "memory_operand" "")
17033 (const_int 0))]
17034 "! optimize_size
17035 && ! TARGET_USE_MOV0
17036 && TARGET_SPLIT_LONG_MOVES
17037 && get_attr_length (insn) >= ix86_cost->large_insn
17038 && peep2_regno_dead_p (0, FLAGS_REG)"
17039 [(parallel [(set (match_dup 2) (const_int 0))
17040 (clobber (reg:CC 17))])
17041 (set (match_dup 0) (match_dup 1))]
17042 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
17043
17044(define_peephole2
17045 [(match_scratch:SI 2 "r")
17046 (set (match_operand:SI 0 "memory_operand" "")
17047 (match_operand:SI 1 "immediate_operand" ""))]
17048 "! optimize_size
17049 && get_attr_length (insn) >= ix86_cost->large_insn
17050 && TARGET_SPLIT_LONG_MOVES"
17051 [(set (match_dup 2) (match_dup 1))
17052 (set (match_dup 0) (match_dup 2))]
17053 "")
17054
17055(define_peephole2
17056 [(match_scratch:HI 2 "r")
17057 (set (match_operand:HI 0 "memory_operand" "")
17058 (match_operand:HI 1 "immediate_operand" ""))]
17059 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17060 && TARGET_SPLIT_LONG_MOVES"
17061 [(set (match_dup 2) (match_dup 1))
17062 (set (match_dup 0) (match_dup 2))]
17063 "")
17064
17065(define_peephole2
17066 [(match_scratch:QI 2 "q")
17067 (set (match_operand:QI 0 "memory_operand" "")
17068 (match_operand:QI 1 "immediate_operand" ""))]
17069 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17070 && TARGET_SPLIT_LONG_MOVES"
17071 [(set (match_dup 2) (match_dup 1))
17072 (set (match_dup 0) (match_dup 2))]
17073 "")
17074
17075;; Don't compare memory with zero, load and use a test instead.
17076(define_peephole2
17077 [(set (reg 17)
17078 (compare (match_operand:SI 0 "memory_operand" "")
17079 (const_int 0)))
17080 (match_scratch:SI 3 "r")]
17081 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17082 [(set (match_dup 3) (match_dup 0))
17083 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17084 "")
17085
17086;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17087;; Don't split NOTs with a displacement operand, because resulting XOR
17088;; will not be pariable anyway.
17089;;
17090;; On AMD K6, NOT is vector decoded with memory operand that can not be
17091;; represented using a modRM byte. The XOR replacement is long decoded,
17092;; so this split helps here as well.
17093;;
17094;; Note: Can't do this as a regular split because we can't get proper
17095;; lifetime information then.
17096
17097(define_peephole2
17098 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17099 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17100 "!optimize_size
17101 && peep2_regno_dead_p (0, FLAGS_REG)
17102 && ((TARGET_PENTIUM
17103 && (GET_CODE (operands[0]) != MEM
17104 || !memory_displacement_operand (operands[0], SImode)))
17105 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17106 [(parallel [(set (match_dup 0)
17107 (xor:SI (match_dup 1) (const_int -1)))
17108 (clobber (reg:CC 17))])]
17109 "")
17110
17111(define_peephole2
17112 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17113 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17114 "!optimize_size
17115 && peep2_regno_dead_p (0, FLAGS_REG)
17116 && ((TARGET_PENTIUM
17117 && (GET_CODE (operands[0]) != MEM
17118 || !memory_displacement_operand (operands[0], HImode)))
17119 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17120 [(parallel [(set (match_dup 0)
17121 (xor:HI (match_dup 1) (const_int -1)))
17122 (clobber (reg:CC 17))])]
17123 "")
17124
17125(define_peephole2
17126 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17127 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17128 "!optimize_size
17129 && peep2_regno_dead_p (0, FLAGS_REG)
17130 && ((TARGET_PENTIUM
17131 && (GET_CODE (operands[0]) != MEM
17132 || !memory_displacement_operand (operands[0], QImode)))
17133 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17134 [(parallel [(set (match_dup 0)
17135 (xor:QI (match_dup 1) (const_int -1)))
17136 (clobber (reg:CC 17))])]
17137 "")
17138
17139;; Non pairable "test imm, reg" instructions can be translated to
17140;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17141;; byte opcode instead of two, have a short form for byte operands),
17142;; so do it for other CPUs as well. Given that the value was dead,
17143;; this should not create any new dependencies. Pass on the sub-word
17144;; versions if we're concerned about partial register stalls.
17145
17146(define_peephole2
17147 [(set (reg 17)
17148 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17149 (match_operand:SI 1 "immediate_operand" ""))
17150 (const_int 0)))]
17151 "ix86_match_ccmode (insn, CCNOmode)
17152 && (true_regnum (operands[0]) != 0
17153 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
17154 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17155 [(parallel
17156 [(set (reg:CCNO 17)
17157 (compare:CCNO (and:SI (match_dup 0)
17158 (match_dup 1))
17159 (const_int 0)))
17160 (set (match_dup 0)
17161 (and:SI (match_dup 0) (match_dup 1)))])]
17162 "")
17163
17164;; We don't need to handle HImode case, because it will be promoted to SImode
17165;; on ! TARGET_PARTIAL_REG_STALL
17166
17167(define_peephole2
17168 [(set (reg 17)
17169 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17170 (match_operand:QI 1 "immediate_operand" ""))
17171 (const_int 0)))]
17172 "! TARGET_PARTIAL_REG_STALL
17173 && ix86_match_ccmode (insn, CCNOmode)
17174 && true_regnum (operands[0]) != 0
17175 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17176 [(parallel
17177 [(set (reg:CCNO 17)
17178 (compare:CCNO (and:QI (match_dup 0)
17179 (match_dup 1))
17180 (const_int 0)))
17181 (set (match_dup 0)
17182 (and:QI (match_dup 0) (match_dup 1)))])]
17183 "")
17184
17185(define_peephole2
17186 [(set (reg 17)
17187 (compare
17188 (and:SI
17189 (zero_extract:SI
17190 (match_operand 0 "ext_register_operand" "")
17191 (const_int 8)
17192 (const_int 8))
17193 (match_operand 1 "const_int_operand" ""))
17194 (const_int 0)))]
17195 "! TARGET_PARTIAL_REG_STALL
17196 && ix86_match_ccmode (insn, CCNOmode)
17197 && true_regnum (operands[0]) != 0
17198 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17199 [(parallel [(set (reg:CCNO 17)
17200 (compare:CCNO
17201 (and:SI
17202 (zero_extract:SI
17203 (match_dup 0)
17204 (const_int 8)
17205 (const_int 8))
17206 (match_dup 1))
17207 (const_int 0)))
17208 (set (zero_extract:SI (match_dup 0)
17209 (const_int 8)
17210 (const_int 8))
17211 (and:SI
17212 (zero_extract:SI
17213 (match_dup 0)
17214 (const_int 8)
17215 (const_int 8))
17216 (match_dup 1)))])]
17217 "")
17218
17219;; Don't do logical operations with memory inputs.
17220(define_peephole2
17221 [(match_scratch:SI 2 "r")
17222 (parallel [(set (match_operand:SI 0 "register_operand" "")
17223 (match_operator:SI 3 "arith_or_logical_operator"
17224 [(match_dup 0)
17225 (match_operand:SI 1 "memory_operand" "")]))
17226 (clobber (reg:CC 17))])]
17227 "! optimize_size && ! TARGET_READ_MODIFY"
17228 [(set (match_dup 2) (match_dup 1))
17229 (parallel [(set (match_dup 0)
17230 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17231 (clobber (reg:CC 17))])]
17232 "")
17233
17234(define_peephole2
17235 [(match_scratch:SI 2 "r")
17236 (parallel [(set (match_operand:SI 0 "register_operand" "")
17237 (match_operator:SI 3 "arith_or_logical_operator"
17238 [(match_operand:SI 1 "memory_operand" "")
17239 (match_dup 0)]))
17240 (clobber (reg:CC 17))])]
17241 "! optimize_size && ! TARGET_READ_MODIFY"
17242 [(set (match_dup 2) (match_dup 1))
17243 (parallel [(set (match_dup 0)
17244 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17245 (clobber (reg:CC 17))])]
17246 "")
17247
17248; Don't do logical operations with memory outputs
17249;
17250; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17251; instruction into two 1-uop insns plus a 2-uop insn. That last has
17252; the same decoder scheduling characteristics as the original.
17253
17254(define_peephole2
17255 [(match_scratch:SI 2 "r")
17256 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17257 (match_operator:SI 3 "arith_or_logical_operator"
17258 [(match_dup 0)
17259 (match_operand:SI 1 "nonmemory_operand" "")]))
17260 (clobber (reg:CC 17))])]
17261 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17262 [(set (match_dup 2) (match_dup 0))
17263 (parallel [(set (match_dup 2)
17264 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17265 (clobber (reg:CC 17))])
17266 (set (match_dup 0) (match_dup 2))]
17267 "")
17268
17269(define_peephole2
17270 [(match_scratch:SI 2 "r")
17271 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17272 (match_operator:SI 3 "arith_or_logical_operator"
17273 [(match_operand:SI 1 "nonmemory_operand" "")
17274 (match_dup 0)]))
17275 (clobber (reg:CC 17))])]
17276 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17277 [(set (match_dup 2) (match_dup 0))
17278 (parallel [(set (match_dup 2)
17279 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17280 (clobber (reg:CC 17))])
17281 (set (match_dup 0) (match_dup 2))]
17282 "")
17283
17284;; Attempt to always use XOR for zeroing registers.
17285(define_peephole2
17286 [(set (match_operand 0 "register_operand" "")
17287 (const_int 0))]
17288 "(GET_MODE (operands[0]) == QImode
17289 || GET_MODE (operands[0]) == HImode
17290 || GET_MODE (operands[0]) == SImode
17291 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17292 && (! TARGET_USE_MOV0 || optimize_size)
17293 && peep2_regno_dead_p (0, FLAGS_REG)"
17294 [(parallel [(set (match_dup 0) (const_int 0))
17295 (clobber (reg:CC 17))])]
17296 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17297 true_regnum (operands[0]));")
17298
17299(define_peephole2
17300 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17301 (const_int 0))]
17302 "(GET_MODE (operands[0]) == QImode
17303 || GET_MODE (operands[0]) == HImode)
17304 && (! TARGET_USE_MOV0 || optimize_size)
17305 && peep2_regno_dead_p (0, FLAGS_REG)"
17306 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17307 (clobber (reg:CC 17))])])
17308
17309;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17310(define_peephole2
17311 [(set (match_operand 0 "register_operand" "")
17312 (const_int -1))]
17313 "(GET_MODE (operands[0]) == HImode
17314 || GET_MODE (operands[0]) == SImode
17315 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17316 && (optimize_size || TARGET_PENTIUM)
17317 && peep2_regno_dead_p (0, FLAGS_REG)"
17318 [(parallel [(set (match_dup 0) (const_int -1))
17319 (clobber (reg:CC 17))])]
17320 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17321 true_regnum (operands[0]));")
17322
17323;; Attempt to convert simple leas to adds. These can be created by
17324;; move expanders.
17325(define_peephole2
17326 [(set (match_operand:SI 0 "register_operand" "")
17327 (plus:SI (match_dup 0)
17328 (match_operand:SI 1 "nonmemory_operand" "")))]
17329 "peep2_regno_dead_p (0, FLAGS_REG)"
17330 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17331 (clobber (reg:CC 17))])]
17332 "")
17333
17334(define_peephole2
17335 [(set (match_operand:SI 0 "register_operand" "")
17336 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17337 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17338 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17339 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17340 (clobber (reg:CC 17))])]
17341 "operands[2] = gen_lowpart (SImode, operands[2]);")
17342
17343(define_peephole2
17344 [(set (match_operand:DI 0 "register_operand" "")
17345 (plus:DI (match_dup 0)
17346 (match_operand:DI 1 "x86_64_general_operand" "")))]
17347 "peep2_regno_dead_p (0, FLAGS_REG)"
17348 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17349 (clobber (reg:CC 17))])]
17350 "")
17351
17352(define_peephole2
17353 [(set (match_operand:SI 0 "register_operand" "")
17354 (mult:SI (match_dup 0)
17355 (match_operand:SI 1 "const_int_operand" "")))]
17356 "exact_log2 (INTVAL (operands[1])) >= 0
17357 && peep2_regno_dead_p (0, FLAGS_REG)"
17358 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17359 (clobber (reg:CC 17))])]
17360 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17361
17362(define_peephole2
17363 [(set (match_operand:DI 0 "register_operand" "")
17364 (mult:DI (match_dup 0)
17365 (match_operand:DI 1 "const_int_operand" "")))]
17366 "exact_log2 (INTVAL (operands[1])) >= 0
17367 && peep2_regno_dead_p (0, FLAGS_REG)"
17368 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17369 (clobber (reg:CC 17))])]
17370 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17371
17372(define_peephole2
17373 [(set (match_operand:SI 0 "register_operand" "")
17374 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17375 (match_operand:DI 2 "const_int_operand" "")) 0))]
17376 "exact_log2 (INTVAL (operands[1])) >= 0
17377 && REGNO (operands[0]) == REGNO (operands[1])
17378 && peep2_regno_dead_p (0, FLAGS_REG)"
17379 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17380 (clobber (reg:CC 17))])]
17381 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17382
17383;; The ESP adjustments can be done by the push and pop instructions. Resulting
17384;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17385;; many CPUs it is also faster, since special hardware to avoid esp
17386;; dependencies is present.
17387
17388;; While some of these conversions may be done using splitters, we use peepholes
17389;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17390
17391;; Convert prologue esp subtractions to push.
17392;; We need register to push. In order to keep verify_flow_info happy we have
17393;; two choices
17394;; - use scratch and clobber it in order to avoid dependencies
17395;; - use already live register
17396;; We can't use the second way right now, since there is no reliable way how to
17397;; verify that given register is live. First choice will also most likely in
17398;; fewer dependencies. On the place of esp adjustments it is very likely that
17399;; call clobbered registers are dead. We may want to use base pointer as an
17400;; alternative when no register is available later.
17401
17402(define_peephole2
17403 [(match_scratch:SI 0 "r")
17404 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17405 (clobber (reg:CC 17))
17406 (clobber (mem:BLK (scratch)))])]
17407 "optimize_size || !TARGET_SUB_ESP_4"
17408 [(clobber (match_dup 0))
17409 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17410 (clobber (mem:BLK (scratch)))])])
17411
17412(define_peephole2
17413 [(match_scratch:SI 0 "r")
17414 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17415 (clobber (reg:CC 17))
17416 (clobber (mem:BLK (scratch)))])]
17417 "optimize_size || !TARGET_SUB_ESP_8"
17418 [(clobber (match_dup 0))
17419 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17420 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17421 (clobber (mem:BLK (scratch)))])])
17422
17423;; Convert esp subtractions to push.
17424(define_peephole2
17425 [(match_scratch:SI 0 "r")
17426 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17427 (clobber (reg:CC 17))])]
17428 "optimize_size || !TARGET_SUB_ESP_4"
17429 [(clobber (match_dup 0))
17430 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17431
17432(define_peephole2
17433 [(match_scratch:SI 0 "r")
17434 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17435 (clobber (reg:CC 17))])]
17436 "optimize_size || !TARGET_SUB_ESP_8"
17437 [(clobber (match_dup 0))
17438 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17439 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17440
17441;; Convert epilogue deallocator to pop.
17442(define_peephole2
17443 [(match_scratch:SI 0 "r")
17444 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17445 (clobber (reg:CC 17))
17446 (clobber (mem:BLK (scratch)))])]
17447 "optimize_size || !TARGET_ADD_ESP_4"
17448 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17449 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17450 (clobber (mem:BLK (scratch)))])]
17451 "")
17452
17453;; Two pops case is tricky, since pop causes dependency on destination register.
17454;; We use two registers if available.
17455(define_peephole2
17456 [(match_scratch:SI 0 "r")
17457 (match_scratch:SI 1 "r")
17458 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17459 (clobber (reg:CC 17))
17460 (clobber (mem:BLK (scratch)))])]
17461 "optimize_size || !TARGET_ADD_ESP_8"
17462 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17463 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17464 (clobber (mem:BLK (scratch)))])
17465 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17466 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17467 "")
17468
17469(define_peephole2
17470 [(match_scratch:SI 0 "r")
17471 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17472 (clobber (reg:CC 17))
17473 (clobber (mem:BLK (scratch)))])]
17474 "optimize_size"
17475 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17476 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17477 (clobber (mem:BLK (scratch)))])
17478 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17479 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17480 "")
17481
17482;; Convert esp additions to pop.
17483(define_peephole2
17484 [(match_scratch:SI 0 "r")
17485 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17486 (clobber (reg:CC 17))])]
17487 ""
17488 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17489 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17490 "")
17491
17492;; Two pops case is tricky, since pop causes dependency on destination register.
17493;; We use two registers if available.
17494(define_peephole2
17495 [(match_scratch:SI 0 "r")
17496 (match_scratch:SI 1 "r")
17497 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17498 (clobber (reg:CC 17))])]
17499 ""
17500 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17501 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17502 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17503 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17504 "")
17505
17506(define_peephole2
17507 [(match_scratch:SI 0 "r")
17508 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17509 (clobber (reg:CC 17))])]
17510 "optimize_size"
17511 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17512 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17513 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17514 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17515 "")
17516
17517;; Convert compares with 1 to shorter inc/dec operations when CF is not
17518;; required and register dies.
17519(define_peephole2
17520 [(set (reg 17)
17521 (compare (match_operand:SI 0 "register_operand" "")
17522 (match_operand:SI 1 "incdec_operand" "")))]
17523 "ix86_match_ccmode (insn, CCGCmode)
17524 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17525 [(parallel [(set (reg:CCGC 17)
17526 (compare:CCGC (match_dup 0)
17527 (match_dup 1)))
17528 (clobber (match_dup 0))])]
17529 "")
17530
17531(define_peephole2
17532 [(set (reg 17)
17533 (compare (match_operand:HI 0 "register_operand" "")
17534 (match_operand:HI 1 "incdec_operand" "")))]
17535 "ix86_match_ccmode (insn, CCGCmode)
17536 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17537 [(parallel [(set (reg:CCGC 17)
17538 (compare:CCGC (match_dup 0)
17539 (match_dup 1)))
17540 (clobber (match_dup 0))])]
17541 "")
17542
17543(define_peephole2
17544 [(set (reg 17)
17545 (compare (match_operand:QI 0 "register_operand" "")
17546 (match_operand:QI 1 "incdec_operand" "")))]
17547 "ix86_match_ccmode (insn, CCGCmode)
17548 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17549 [(parallel [(set (reg:CCGC 17)
17550 (compare:CCGC (match_dup 0)
17551 (match_dup 1)))
17552 (clobber (match_dup 0))])]
17553 "")
17554
17555;; Convert compares with 128 to shorter add -128
17556(define_peephole2
17557 [(set (reg 17)
17558 (compare (match_operand:SI 0 "register_operand" "")
17559 (const_int 128)))]
17560 "ix86_match_ccmode (insn, CCGCmode)
17561 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17562 [(parallel [(set (reg:CCGC 17)
17563 (compare:CCGC (match_dup 0)
17564 (const_int 128)))
17565 (clobber (match_dup 0))])]
17566 "")
17567
17568(define_peephole2
17569 [(set (reg 17)
17570 (compare (match_operand:HI 0 "register_operand" "")
17571 (const_int 128)))]
17572 "ix86_match_ccmode (insn, CCGCmode)
17573 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17574 [(parallel [(set (reg:CCGC 17)
17575 (compare:CCGC (match_dup 0)
17576 (const_int 128)))
17577 (clobber (match_dup 0))])]
17578 "")
17579
17580(define_peephole2
17581 [(match_scratch:DI 0 "r")
17582 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17583 (clobber (reg:CC 17))
17584 (clobber (mem:BLK (scratch)))])]
17585 "optimize_size || !TARGET_SUB_ESP_4"
17586 [(clobber (match_dup 0))
17587 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17588 (clobber (mem:BLK (scratch)))])])
17589
17590(define_peephole2
17591 [(match_scratch:DI 0 "r")
17592 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17593 (clobber (reg:CC 17))
17594 (clobber (mem:BLK (scratch)))])]
17595 "optimize_size || !TARGET_SUB_ESP_8"
17596 [(clobber (match_dup 0))
17597 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17598 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17599 (clobber (mem:BLK (scratch)))])])
17600
17601;; Convert esp subtractions to push.
17602(define_peephole2
17603 [(match_scratch:DI 0 "r")
17604 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17605 (clobber (reg:CC 17))])]
17606 "optimize_size || !TARGET_SUB_ESP_4"
17607 [(clobber (match_dup 0))
17608 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17609
17610(define_peephole2
17611 [(match_scratch:DI 0 "r")
17612 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17613 (clobber (reg:CC 17))])]
17614 "optimize_size || !TARGET_SUB_ESP_8"
17615 [(clobber (match_dup 0))
17616 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17617 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17618
17619;; Convert epilogue deallocator to pop.
17620(define_peephole2
17621 [(match_scratch:DI 0 "r")
17622 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17623 (clobber (reg:CC 17))
17624 (clobber (mem:BLK (scratch)))])]
17625 "optimize_size || !TARGET_ADD_ESP_4"
17626 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17627 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17628 (clobber (mem:BLK (scratch)))])]
17629 "")
17630
17631;; Two pops case is tricky, since pop causes dependency on destination register.
17632;; We use two registers if available.
17633(define_peephole2
17634 [(match_scratch:DI 0 "r")
17635 (match_scratch:DI 1 "r")
17636 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17637 (clobber (reg:CC 17))
17638 (clobber (mem:BLK (scratch)))])]
17639 "optimize_size || !TARGET_ADD_ESP_8"
17640 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17641 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17642 (clobber (mem:BLK (scratch)))])
17643 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17644 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17645 "")
17646
17647(define_peephole2
17648 [(match_scratch:DI 0 "r")
17649 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17650 (clobber (reg:CC 17))
17651 (clobber (mem:BLK (scratch)))])]
17652 "optimize_size"
17653 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17654 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17655 (clobber (mem:BLK (scratch)))])
17656 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17657 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17658 "")
17659
17660;; Convert esp additions to pop.
17661(define_peephole2
17662 [(match_scratch:DI 0 "r")
17663 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17664 (clobber (reg:CC 17))])]
17665 ""
17666 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17667 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17668 "")
17669
17670;; Two pops case is tricky, since pop causes dependency on destination register.
17671;; We use two registers if available.
17672(define_peephole2
17673 [(match_scratch:DI 0 "r")
17674 (match_scratch:DI 1 "r")
17675 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17676 (clobber (reg:CC 17))])]
17677 ""
17678 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17679 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17680 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17681 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17682 "")
17683
17684(define_peephole2
17685 [(match_scratch:DI 0 "r")
17686 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17687 (clobber (reg:CC 17))])]
17688 "optimize_size"
17689 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17690 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17691 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17692 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17693 "")
17694
17695;; Call-value patterns last so that the wildcard operand does not
17696;; disrupt insn-recog's switch tables.
17697
17698(define_insn "*call_value_pop_0"
17699 [(set (match_operand 0 "" "")
17700 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17701 (match_operand:SI 2 "" "")))
17702 (set (reg:SI 7) (plus:SI (reg:SI 7)
17703 (match_operand:SI 3 "immediate_operand" "")))]
17704 "!TARGET_64BIT"
17705{
17706 if (SIBLING_CALL_P (insn))
17707 return "jmp\t%P1";
17708 else
17709 return "call\t%P1";
17710}
17711 [(set_attr "type" "callv")])
17712
17713(define_insn "*call_value_pop_1"
17714 [(set (match_operand 0 "" "")
17715 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17716 (match_operand:SI 2 "" "")))
17717 (set (reg:SI 7) (plus:SI (reg:SI 7)
17718 (match_operand:SI 3 "immediate_operand" "i")))]
17719 "!TARGET_64BIT"
17720{
17721 if (constant_call_address_operand (operands[1], QImode))
17722 {
17723 if (SIBLING_CALL_P (insn))
17724 return "jmp\t%P1";
17725 else
17726 return "call\t%P1";
17727 }
17728 if (SIBLING_CALL_P (insn))
17729 return "jmp\t%A1";
17730 else
17731 return "call\t%A1";
17732}
17733 [(set_attr "type" "callv")])
17734
17735(define_insn "*call_value_0"
17736 [(set (match_operand 0 "" "")
17737 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17738 (match_operand:SI 2 "" "")))]
17739 "!TARGET_64BIT"
17740{
17741 if (SIBLING_CALL_P (insn))
17742 return "jmp\t%P1";
17743 else
17744 return "call\t%P1";
17745}
17746 [(set_attr "type" "callv")])
17747
17748(define_insn "*call_value_0_rex64"
17749 [(set (match_operand 0 "" "")
17750 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17751 (match_operand:DI 2 "const_int_operand" "")))]
17752 "TARGET_64BIT"
17753{
17754 if (SIBLING_CALL_P (insn))
17755 return "jmp\t%P1";
17756 else
17757 return "call\t%P1";
17758}
17759 [(set_attr "type" "callv")])
17760
17761(define_insn "*call_value_1"
17762 [(set (match_operand 0 "" "")
17763 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17764 (match_operand:SI 2 "" "")))]
17765 "!TARGET_64BIT"
17766{
17767 if (constant_call_address_operand (operands[1], QImode))
17768 {
17769 if (SIBLING_CALL_P (insn))
17770 return "jmp\t%P1";
17771 else
17772 return "call\t%P1";
17773 }
17774 if (SIBLING_CALL_P (insn))
17775 return "jmp\t%*%1";
17776 else
17777 return "call\t%*%1";
17778}
17779 [(set_attr "type" "callv")])
17780
17781(define_insn "*call_value_1_rex64"
17782 [(set (match_operand 0 "" "")
17783 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17784 (match_operand:DI 2 "" "")))]
17785 "TARGET_64BIT"
17786{
17787 if (constant_call_address_operand (operands[1], QImode))
17788 {
17789 if (SIBLING_CALL_P (insn))
17790 return "jmp\t%P1";
17791 else
17792 return "call\t%P1";
17793 }
17794 if (SIBLING_CALL_P (insn))
17795 return "jmp\t%A1";
17796 else
17797 return "call\t%A1";
17798}
17799 [(set_attr "type" "callv")])
17800
17801(define_insn "trap"
17802 [(trap_if (const_int 1) (const_int 5))]
17803 ""
17804 "int\t$5")
17805
17806;;; ix86 doesn't have conditional trap instructions, but we fake them
17807;;; for the sake of bounds checking. By emitting bounds checks as
17808;;; conditional traps rather than as conditional jumps around
17809;;; unconditional traps we avoid introducing spurious basic-block
17810;;; boundaries and facilitate elimination of redundant checks. In
17811;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17812;;; interrupt 5.
17813;;;
17814;;; FIXME: Static branch prediction rules for ix86 are such that
17815;;; forward conditional branches predict as untaken. As implemented
17816;;; below, pseudo conditional traps violate that rule. We should use
17817;;; .pushsection/.popsection to place all of the `int 5's in a special
17818;;; section loaded at the end of the text segment and branch forward
17819;;; there on bounds-failure, and then jump back immediately (in case
17820;;; the system chooses to ignore bounds violations, or to report
17821;;; violations and continue execution).
17822
17823(define_expand "conditional_trap"
17824 [(trap_if (match_operator 0 "comparison_operator"
17825 [(match_dup 2) (const_int 0)])
17826 (match_operand 1 "const_int_operand" ""))]
17827 ""
17828{
17829 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
17830 ix86_expand_compare (GET_CODE (operands[0]),
17831 NULL, NULL),
17832 operands[1]));
17833 DONE;
17834})
17835
17836(define_insn "*conditional_trap_1"
17837 [(trap_if (match_operator 0 "comparison_operator"
17838 [(reg 17) (const_int 0)])
17839 (match_operand 1 "const_int_operand" ""))]
17840 ""
17841{
17842 operands[2] = gen_label_rtx ();
17843 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
17844 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
17845 CODE_LABEL_NUMBER (operands[2]));
17846 RET;
17847})
17848
17849 ;; Pentium III SIMD instructions.
17850
17851;; Moves for SSE/MMX regs.
17852
17853(define_insn "movv4sf_internal"
17854 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17855 (match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
17856 "TARGET_SSE"
17857 ;; @@@ let's try to use movaps here.
17858 "movaps\t{%1, %0|%0, %1}"
17859 [(set_attr "type" "sse")])
17860
17861(define_insn "movv4si_internal"
17862 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17863 (match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
17864 "TARGET_SSE"
17865 ;; @@@ let's try to use movaps here.
17866 "movaps\t{%1, %0|%0, %1}"
17867 [(set_attr "type" "sse")])
17868
17869(define_insn "movv8qi_internal"
17870 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17871 (match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
17872 "TARGET_MMX"
17873 "movq\t{%1, %0|%0, %1}"
17874 [(set_attr "type" "mmx")])
17875
17876(define_insn "movv4hi_internal"
17877 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17878 (match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
17879 "TARGET_MMX"
17880 "movq\t{%1, %0|%0, %1}"
17881 [(set_attr "type" "mmx")])
17882
17883(define_insn "movv2si_internal"
17884 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17885 (match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
17886 "TARGET_MMX"
17887 "movq\t{%1, %0|%0, %1}"
17888 [(set_attr "type" "mmx")])
17889
17890(define_insn "movv2sf_internal"
17891 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
17892 (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
17893 "TARGET_3DNOW"
17894 "movq\\t{%1, %0|%0, %1}"
17895 [(set_attr "type" "mmx")])
17896
17897(define_expand "movti"
17898 [(set (match_operand:TI 0 "general_operand" "")
17899 (match_operand:TI 1 "general_operand" ""))]
17900 "TARGET_SSE || TARGET_64BIT"
17901{
17902 if (TARGET_64BIT)
17903 ix86_expand_move (TImode, operands);
17904 else
17905 ix86_expand_vector_move (TImode, operands);
17906 DONE;
17907})
17908
17909(define_expand "movv4sf"
17910 [(set (match_operand:V4SF 0 "general_operand" "")
17911 (match_operand:V4SF 1 "general_operand" ""))]
17912 "TARGET_SSE"
17913{
17914 ix86_expand_vector_move (V4SFmode, operands);
17915 DONE;
17916})
17917
17918(define_expand "movv4si"
17919 [(set (match_operand:V4SI 0 "general_operand" "")
17920 (match_operand:V4SI 1 "general_operand" ""))]
17921 "TARGET_MMX"
17922{
17923 ix86_expand_vector_move (V4SImode, operands);
17924 DONE;
17925})
17926
17927(define_expand "movv2si"
17928 [(set (match_operand:V2SI 0 "general_operand" "")
17929 (match_operand:V2SI 1 "general_operand" ""))]
17930 "TARGET_MMX"
17931{
17932 ix86_expand_vector_move (V2SImode, operands);
17933 DONE;
17934})
17935
17936(define_expand "movv4hi"
17937 [(set (match_operand:V4HI 0 "general_operand" "")
17938 (match_operand:V4HI 1 "general_operand" ""))]
17939 "TARGET_MMX"
17940{
17941 ix86_expand_vector_move (V4HImode, operands);
17942 DONE;
17943})
17944
17945(define_expand "movv8qi"
17946 [(set (match_operand:V8QI 0 "general_operand" "")
17947 (match_operand:V8QI 1 "general_operand" ""))]
17948 "TARGET_MMX"
17949{
17950 ix86_expand_vector_move (V8QImode, operands);
17951 DONE;
17952})
17953
17954(define_expand "movv2sf"
17955 [(set (match_operand:V2SF 0 "general_operand" "")
17956 (match_operand:V2SF 1 "general_operand" ""))]
17957 "TARGET_3DNOW"
17958{
17959 ix86_expand_vector_move (V2SFmode, operands);
17960 DONE;
17961})
17962
17963(define_insn_and_split "*pushti"
17964 [(set (match_operand:TI 0 "push_operand" "=<")
17965 (match_operand:TI 1 "nonmemory_operand" "x"))]
17966 "TARGET_SSE"
17967 "#"
17968 ""
17969 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17970 (set (mem:TI (reg:SI 7)) (match_dup 1))]
17971 ""
17972 [(set_attr "type" "sse")])
17973
17974(define_insn_and_split "*pushv4sf"
17975 [(set (match_operand:V4SF 0 "push_operand" "=<")
17976 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
17977 "TARGET_SSE"
17978 "#"
17979 ""
17980 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17981 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17982 ""
17983 [(set_attr "type" "sse")])
17984
17985(define_insn_and_split "*pushv4si"
17986 [(set (match_operand:V4SI 0 "push_operand" "=<")
17987 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
17988 "TARGET_SSE"
17989 "#"
17990 ""
17991 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17992 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17993 ""
17994 [(set_attr "type" "sse")])
17995
17996(define_insn_and_split "*pushv2si"
17997 [(set (match_operand:V2SI 0 "push_operand" "=<")
17998 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
17999 "TARGET_MMX"
18000 "#"
18001 ""
18002 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18003 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
18004 ""
18005 [(set_attr "type" "mmx")])
18006
18007(define_insn_and_split "*pushv4hi"
18008 [(set (match_operand:V4HI 0 "push_operand" "=<")
18009 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
18010 "TARGET_MMX"
18011 "#"
18012 ""
18013 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18014 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
18015 ""
18016 [(set_attr "type" "mmx")])
18017
18018(define_insn_and_split "*pushv8qi"
18019 [(set (match_operand:V8QI 0 "push_operand" "=<")
18020 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
18021 "TARGET_MMX"
18022 "#"
18023 ""
18024 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18025 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
18026 ""
18027 [(set_attr "type" "mmx")])
18028
18029(define_insn_and_split "*pushv2sf"
18030 [(set (match_operand:V2SF 0 "push_operand" "=<")
18031 (match_operand:V2SF 1 "nonmemory_operand" "y"))]
18032 "TARGET_3DNOW"
18033 "#"
18034 ""
18035 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18036 (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
18037 ""
18038 [(set_attr "type" "mmx")])
18039
18040(define_insn "movti_internal"
18041 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18042 (match_operand:TI 1 "general_operand" "O,xm,x"))]
18043 "TARGET_SSE && !TARGET_64BIT"
18044 "@
18045 xorps\t%0, %0
18046 movaps\t{%1, %0|%0, %1}
18047 movaps\t{%1, %0|%0, %1}"
18048 [(set_attr "type" "sse")])
18049
18050(define_insn "*movti_rex64"
18051 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
18052 (match_operand:TI 1 "general_operand" "riFo,riF,O,x,m"))]
18053 "TARGET_64BIT
18054 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18055 "@
18056 #
18057 #
18058 xorps\t%0, %0
18059 movaps\\t{%1, %0|%0, %1}
18060 movaps\\t{%1, %0|%0, %1}"
18061 [(set_attr "type" "*,*,sse,sse,sse")
18062 (set_attr "mode" "TI")])
18063
18064(define_split
18065 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18066 (match_operand:TI 1 "general_operand" ""))]
18067 "reload_completed && !SSE_REG_P (operands[0])
18068 && !SSE_REG_P (operands[1])"
18069 [(const_int 0)]
18070 "ix86_split_long_move (operands); DONE;")
18071
18072;; These two patterns are useful for specifying exactly whether to use
18073;; movaps or movups
18074(define_insn "sse_movaps"
18075 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18076 (unspec:V4SF
18077 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 38))]
18078 "TARGET_SSE"
18079 "@
18080 movaps\t{%1, %0|%0, %1}
18081 movaps\t{%1, %0|%0, %1}"
18082 [(set_attr "type" "sse")])
18083
18084(define_insn "sse_movups"
18085 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18086 (unspec:V4SF
18087 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 39))]
18088 "TARGET_SSE"
18089 "@
18090 movups\t{%1, %0|%0, %1}
18091 movups\t{%1, %0|%0, %1}"
18092 [(set_attr "type" "sse")])
18093
18094
18095;; SSE Strange Moves.
18096
18097(define_insn "sse_movmskps"
18098 [(set (match_operand:SI 0 "register_operand" "=r")
18099 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
18100 "TARGET_SSE"
18101 "movmskps\t{%1, %0|%0, %1}"
18102 [(set_attr "type" "sse")])
18103
18104(define_insn "mmx_pmovmskb"
18105 [(set (match_operand:SI 0 "register_operand" "=r")
18106 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
18107 "TARGET_SSE || TARGET_3DNOW_A"
18108 "pmovmskb\t{%1, %0|%0, %1}"
18109 [(set_attr "type" "sse")])
18110
18111(define_insn "mmx_maskmovq"
18112 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
18113 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18114 (match_operand:V8QI 2 "register_operand" "y")] 32))]
17950 "TARGET_SSE || TARGET_3DNOW_A"
18115 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
17951 ;; @@@ check ordering of operands in intel/nonintel syntax
17952 "maskmovq\t{%2, %1|%1, %2}"
17953 [(set_attr "type" "sse")])
17954
18116 ;; @@@ check ordering of operands in intel/nonintel syntax
18117 "maskmovq\t{%2, %1|%1, %2}"
18118 [(set_attr "type" "sse")])
18119
18120(define_insn "mmx_maskmovq_rex"
18121 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
18122 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18123 (match_operand:V8QI 2 "register_operand" "y")] 32))]
18124 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
18125 ;; @@@ check ordering of operands in intel/nonintel syntax
18126 "maskmovq\t{%2, %1|%1, %2}"
18127 [(set_attr "type" "sse")])
18128
17955(define_insn "sse_movntv4sf"
17956 [(set (match_operand:V4SF 0 "memory_operand" "=m")
17957 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
17958 "TARGET_SSE"
17959 "movntps\t{%1, %0|%0, %1}"
17960 [(set_attr "type" "sse")])
17961
17962(define_insn "sse_movntdi"
17963 [(set (match_operand:DI 0 "memory_operand" "=m")
17964 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
17965 "TARGET_SSE || TARGET_3DNOW_A"
17966 "movntq\t{%1, %0|%0, %1}"
17967 [(set_attr "type" "sse")])
17968
17969(define_insn "sse_movhlps"
17970 [(set (match_operand:V4SF 0 "register_operand" "=x")
17971 (vec_merge:V4SF
17972 (match_operand:V4SF 1 "register_operand" "0")
17973 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17974 (parallel [(const_int 2)
17975 (const_int 3)
17976 (const_int 0)
17977 (const_int 1)]))
17978 (const_int 3)))]
17979 "TARGET_SSE"
17980 "movhlps\t{%2, %0|%0, %2}"
17981 [(set_attr "type" "sse")])
17982
17983(define_insn "sse_movlhps"
17984 [(set (match_operand:V4SF 0 "register_operand" "=x")
17985 (vec_merge:V4SF
17986 (match_operand:V4SF 1 "register_operand" "0")
17987 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17988 (parallel [(const_int 2)
17989 (const_int 3)
17990 (const_int 0)
17991 (const_int 1)]))
17992 (const_int 12)))]
17993 "TARGET_SSE"
17994 "movlhps\t{%2, %0|%0, %2}"
17995 [(set_attr "type" "sse")])
17996
17997(define_insn "sse_movhps"
17998 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17999 (vec_merge:V4SF
18000 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18001 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18002 (const_int 12)))]
18003 "TARGET_SSE
18004 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18005 "movhps\t{%2, %0|%0, %2}"
18006 [(set_attr "type" "sse")])
18007
18008(define_insn "sse_movlps"
18009 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18010 (vec_merge:V4SF
18011 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18012 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18013 (const_int 3)))]
18014 "TARGET_SSE
18015 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18016 "movlps\t{%2, %0|%0, %2}"
18017 [(set_attr "type" "sse")])
18018
18019(define_insn "sse_loadss"
18020 [(set (match_operand:V4SF 0 "register_operand" "=x")
18021 (vec_merge:V4SF
18022 (match_operand:V4SF 1 "memory_operand" "m")
18023 (vec_duplicate:V4SF (float:SF (const_int 0)))
18024 (const_int 1)))]
18025 "TARGET_SSE"
18026 "movss\t{%1, %0|%0, %1}"
18027 [(set_attr "type" "sse")])
18028
18029(define_insn "sse_movss"
18030 [(set (match_operand:V4SF 0 "register_operand" "=x")
18031 (vec_merge:V4SF
18032 (match_operand:V4SF 1 "register_operand" "0")
18033 (match_operand:V4SF 2 "register_operand" "x")
18034 (const_int 1)))]
18035 "TARGET_SSE"
18036 "movss\t{%2, %0|%0, %2}"
18037 [(set_attr "type" "sse")])
18038
18039(define_insn "sse_storess"
18040 [(set (match_operand:SF 0 "memory_operand" "=m")
18041 (vec_select:SF
18042 (match_operand:V4SF 1 "register_operand" "x")
18043 (parallel [(const_int 0)])))]
18044 "TARGET_SSE"
18045 "movss\t{%1, %0|%0, %1}"
18046 [(set_attr "type" "sse")])
18047
18048(define_insn "sse_shufps"
18049 [(set (match_operand:V4SF 0 "register_operand" "=x")
18050 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
18051 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
18052 (match_operand:SI 3 "immediate_operand" "i")] 41))]
18053 "TARGET_SSE"
18054 ;; @@@ check operand order for intel/nonintel syntax
18055 "shufps\t{%3, %2, %0|%0, %2, %3}"
18056 [(set_attr "type" "sse")])
18057
18058
18059;; SSE arithmetic
18060
18061(define_insn "addv4sf3"
18062 [(set (match_operand:V4SF 0 "register_operand" "=x")
18063 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18064 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18065 "TARGET_SSE"
18066 "addps\t{%2, %0|%0, %2}"
18067 [(set_attr "type" "sse")])
18068
18069(define_insn "vmaddv4sf3"
18070 [(set (match_operand:V4SF 0 "register_operand" "=x")
18071 (vec_merge:V4SF
18072 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18073 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18074 (match_dup 1)
18075 (const_int 1)))]
18076 "TARGET_SSE"
18077 "addss\t{%2, %0|%0, %2}"
18078 [(set_attr "type" "sse")])
18079
18080(define_insn "subv4sf3"
18081 [(set (match_operand:V4SF 0 "register_operand" "=x")
18082 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18083 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18084 "TARGET_SSE"
18085 "subps\t{%2, %0|%0, %2}"
18086 [(set_attr "type" "sse")])
18087
18088(define_insn "vmsubv4sf3"
18089 [(set (match_operand:V4SF 0 "register_operand" "=x")
18090 (vec_merge:V4SF
18091 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18092 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18093 (match_dup 1)
18094 (const_int 1)))]
18095 "TARGET_SSE"
18096 "subss\t{%2, %0|%0, %2}"
18097 [(set_attr "type" "sse")])
18098
18099(define_insn "mulv4sf3"
18100 [(set (match_operand:V4SF 0 "register_operand" "=x")
18101 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18102 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18103 "TARGET_SSE"
18104 "mulps\t{%2, %0|%0, %2}"
18105 [(set_attr "type" "sse")])
18106
18107(define_insn "vmmulv4sf3"
18108 [(set (match_operand:V4SF 0 "register_operand" "=x")
18109 (vec_merge:V4SF
18110 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18111 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18112 (match_dup 1)
18113 (const_int 1)))]
18114 "TARGET_SSE"
18115 "mulss\t{%2, %0|%0, %2}"
18116 [(set_attr "type" "sse")])
18117
18118(define_insn "divv4sf3"
18119 [(set (match_operand:V4SF 0 "register_operand" "=x")
18120 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18121 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18122 "TARGET_SSE"
18123 "divps\t{%2, %0|%0, %2}"
18124 [(set_attr "type" "sse")])
18125
18126(define_insn "vmdivv4sf3"
18127 [(set (match_operand:V4SF 0 "register_operand" "=x")
18128 (vec_merge:V4SF
18129 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18130 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18131 (match_dup 1)
18132 (const_int 1)))]
18133 "TARGET_SSE"
18134 "divss\t{%2, %0|%0, %2}"
18135 [(set_attr "type" "sse")])
18136
18137
18138;; SSE square root/reciprocal
18139
18140(define_insn "rcpv4sf2"
18141 [(set (match_operand:V4SF 0 "register_operand" "=x")
18142 (unspec:V4SF
18143 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42))]
18144 "TARGET_SSE"
18145 "rcpps\t{%1, %0|%0, %1}"
18146 [(set_attr "type" "sse")])
18147
18148(define_insn "vmrcpv4sf2"
18149 [(set (match_operand:V4SF 0 "register_operand" "=x")
18150 (vec_merge:V4SF
18151 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42)
18152 (match_operand:V4SF 2 "register_operand" "0")
18153 (const_int 1)))]
18154 "TARGET_SSE"
18155 "rcpss\t{%1, %0|%0, %1}"
18156 [(set_attr "type" "sse")])
18157
18158(define_insn "rsqrtv4sf2"
18159 [(set (match_operand:V4SF 0 "register_operand" "=x")
18160 (unspec:V4SF
18161 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43))]
18162 "TARGET_SSE"
18163 "rsqrtps\t{%1, %0|%0, %1}"
18164 [(set_attr "type" "sse")])
18165
18166(define_insn "vmrsqrtv4sf2"
18167 [(set (match_operand:V4SF 0 "register_operand" "=x")
18168 (vec_merge:V4SF
18169 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43)
18170 (match_operand:V4SF 2 "register_operand" "0")
18171 (const_int 1)))]
18172 "TARGET_SSE"
18173 "rsqrtss\t{%1, %0|%0, %1}"
18174 [(set_attr "type" "sse")])
18175
18176(define_insn "sqrtv4sf2"
18177 [(set (match_operand:V4SF 0 "register_operand" "=x")
18178 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
18179 "TARGET_SSE"
18180 "sqrtps\t{%1, %0|%0, %1}"
18181 [(set_attr "type" "sse")])
18182
18183(define_insn "vmsqrtv4sf2"
18184 [(set (match_operand:V4SF 0 "register_operand" "=x")
18185 (vec_merge:V4SF
18186 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18187 (match_operand:V4SF 2 "register_operand" "0")
18188 (const_int 1)))]
18189 "TARGET_SSE"
18190 "sqrtss\t{%1, %0|%0, %1}"
18191 [(set_attr "type" "sse")])
18192
18193;; SSE logical operations.
18194
18195;; These are not called andti3 etc. because we really really don't want
18196;; the compiler to widen DImode ands to TImode ands and then try to move
18197;; into DImode subregs of SSE registers, and them together, and move out
18198;; of DImode subregs again!
18199
18200(define_insn "*sse_andti3_df_1"
18201 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18202 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18203 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18204 "TARGET_SSE2"
18205 "andpd\t{%2, %0|%0, %2}"
18206 [(set_attr "type" "sse")])
18207
18208(define_insn "*sse_andti3_df_2"
18209 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18210 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18211 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18212 "TARGET_SSE2"
18213 "andpd\t{%2, %0|%0, %2}"
18214 [(set_attr "type" "sse")])
18215
18216(define_insn "*sse_andti3_sf_1"
18217 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18218 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18219 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18220 "TARGET_SSE"
18221 "andps\t{%2, %0|%0, %2}"
18222 [(set_attr "type" "sse")])
18223
18224(define_insn "*sse_andti3_sf_2"
18225 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18226 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18227 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18228 "TARGET_SSE"
18229 "andps\t{%2, %0|%0, %2}"
18230 [(set_attr "type" "sse")])
18231
18232(define_insn "sse_andti3"
18233 [(set (match_operand:TI 0 "register_operand" "=x")
18129(define_insn "sse_movntv4sf"
18130 [(set (match_operand:V4SF 0 "memory_operand" "=m")
18131 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
18132 "TARGET_SSE"
18133 "movntps\t{%1, %0|%0, %1}"
18134 [(set_attr "type" "sse")])
18135
18136(define_insn "sse_movntdi"
18137 [(set (match_operand:DI 0 "memory_operand" "=m")
18138 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
18139 "TARGET_SSE || TARGET_3DNOW_A"
18140 "movntq\t{%1, %0|%0, %1}"
18141 [(set_attr "type" "sse")])
18142
18143(define_insn "sse_movhlps"
18144 [(set (match_operand:V4SF 0 "register_operand" "=x")
18145 (vec_merge:V4SF
18146 (match_operand:V4SF 1 "register_operand" "0")
18147 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18148 (parallel [(const_int 2)
18149 (const_int 3)
18150 (const_int 0)
18151 (const_int 1)]))
18152 (const_int 3)))]
18153 "TARGET_SSE"
18154 "movhlps\t{%2, %0|%0, %2}"
18155 [(set_attr "type" "sse")])
18156
18157(define_insn "sse_movlhps"
18158 [(set (match_operand:V4SF 0 "register_operand" "=x")
18159 (vec_merge:V4SF
18160 (match_operand:V4SF 1 "register_operand" "0")
18161 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18162 (parallel [(const_int 2)
18163 (const_int 3)
18164 (const_int 0)
18165 (const_int 1)]))
18166 (const_int 12)))]
18167 "TARGET_SSE"
18168 "movlhps\t{%2, %0|%0, %2}"
18169 [(set_attr "type" "sse")])
18170
18171(define_insn "sse_movhps"
18172 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18173 (vec_merge:V4SF
18174 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18175 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18176 (const_int 12)))]
18177 "TARGET_SSE
18178 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18179 "movhps\t{%2, %0|%0, %2}"
18180 [(set_attr "type" "sse")])
18181
18182(define_insn "sse_movlps"
18183 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18184 (vec_merge:V4SF
18185 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18186 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18187 (const_int 3)))]
18188 "TARGET_SSE
18189 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18190 "movlps\t{%2, %0|%0, %2}"
18191 [(set_attr "type" "sse")])
18192
18193(define_insn "sse_loadss"
18194 [(set (match_operand:V4SF 0 "register_operand" "=x")
18195 (vec_merge:V4SF
18196 (match_operand:V4SF 1 "memory_operand" "m")
18197 (vec_duplicate:V4SF (float:SF (const_int 0)))
18198 (const_int 1)))]
18199 "TARGET_SSE"
18200 "movss\t{%1, %0|%0, %1}"
18201 [(set_attr "type" "sse")])
18202
18203(define_insn "sse_movss"
18204 [(set (match_operand:V4SF 0 "register_operand" "=x")
18205 (vec_merge:V4SF
18206 (match_operand:V4SF 1 "register_operand" "0")
18207 (match_operand:V4SF 2 "register_operand" "x")
18208 (const_int 1)))]
18209 "TARGET_SSE"
18210 "movss\t{%2, %0|%0, %2}"
18211 [(set_attr "type" "sse")])
18212
18213(define_insn "sse_storess"
18214 [(set (match_operand:SF 0 "memory_operand" "=m")
18215 (vec_select:SF
18216 (match_operand:V4SF 1 "register_operand" "x")
18217 (parallel [(const_int 0)])))]
18218 "TARGET_SSE"
18219 "movss\t{%1, %0|%0, %1}"
18220 [(set_attr "type" "sse")])
18221
18222(define_insn "sse_shufps"
18223 [(set (match_operand:V4SF 0 "register_operand" "=x")
18224 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
18225 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
18226 (match_operand:SI 3 "immediate_operand" "i")] 41))]
18227 "TARGET_SSE"
18228 ;; @@@ check operand order for intel/nonintel syntax
18229 "shufps\t{%3, %2, %0|%0, %2, %3}"
18230 [(set_attr "type" "sse")])
18231
18232
18233;; SSE arithmetic
18234
18235(define_insn "addv4sf3"
18236 [(set (match_operand:V4SF 0 "register_operand" "=x")
18237 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18238 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18239 "TARGET_SSE"
18240 "addps\t{%2, %0|%0, %2}"
18241 [(set_attr "type" "sse")])
18242
18243(define_insn "vmaddv4sf3"
18244 [(set (match_operand:V4SF 0 "register_operand" "=x")
18245 (vec_merge:V4SF
18246 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18247 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18248 (match_dup 1)
18249 (const_int 1)))]
18250 "TARGET_SSE"
18251 "addss\t{%2, %0|%0, %2}"
18252 [(set_attr "type" "sse")])
18253
18254(define_insn "subv4sf3"
18255 [(set (match_operand:V4SF 0 "register_operand" "=x")
18256 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18257 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18258 "TARGET_SSE"
18259 "subps\t{%2, %0|%0, %2}"
18260 [(set_attr "type" "sse")])
18261
18262(define_insn "vmsubv4sf3"
18263 [(set (match_operand:V4SF 0 "register_operand" "=x")
18264 (vec_merge:V4SF
18265 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18266 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18267 (match_dup 1)
18268 (const_int 1)))]
18269 "TARGET_SSE"
18270 "subss\t{%2, %0|%0, %2}"
18271 [(set_attr "type" "sse")])
18272
18273(define_insn "mulv4sf3"
18274 [(set (match_operand:V4SF 0 "register_operand" "=x")
18275 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18276 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18277 "TARGET_SSE"
18278 "mulps\t{%2, %0|%0, %2}"
18279 [(set_attr "type" "sse")])
18280
18281(define_insn "vmmulv4sf3"
18282 [(set (match_operand:V4SF 0 "register_operand" "=x")
18283 (vec_merge:V4SF
18284 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18285 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18286 (match_dup 1)
18287 (const_int 1)))]
18288 "TARGET_SSE"
18289 "mulss\t{%2, %0|%0, %2}"
18290 [(set_attr "type" "sse")])
18291
18292(define_insn "divv4sf3"
18293 [(set (match_operand:V4SF 0 "register_operand" "=x")
18294 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18295 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18296 "TARGET_SSE"
18297 "divps\t{%2, %0|%0, %2}"
18298 [(set_attr "type" "sse")])
18299
18300(define_insn "vmdivv4sf3"
18301 [(set (match_operand:V4SF 0 "register_operand" "=x")
18302 (vec_merge:V4SF
18303 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18304 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18305 (match_dup 1)
18306 (const_int 1)))]
18307 "TARGET_SSE"
18308 "divss\t{%2, %0|%0, %2}"
18309 [(set_attr "type" "sse")])
18310
18311
18312;; SSE square root/reciprocal
18313
18314(define_insn "rcpv4sf2"
18315 [(set (match_operand:V4SF 0 "register_operand" "=x")
18316 (unspec:V4SF
18317 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42))]
18318 "TARGET_SSE"
18319 "rcpps\t{%1, %0|%0, %1}"
18320 [(set_attr "type" "sse")])
18321
18322(define_insn "vmrcpv4sf2"
18323 [(set (match_operand:V4SF 0 "register_operand" "=x")
18324 (vec_merge:V4SF
18325 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42)
18326 (match_operand:V4SF 2 "register_operand" "0")
18327 (const_int 1)))]
18328 "TARGET_SSE"
18329 "rcpss\t{%1, %0|%0, %1}"
18330 [(set_attr "type" "sse")])
18331
18332(define_insn "rsqrtv4sf2"
18333 [(set (match_operand:V4SF 0 "register_operand" "=x")
18334 (unspec:V4SF
18335 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43))]
18336 "TARGET_SSE"
18337 "rsqrtps\t{%1, %0|%0, %1}"
18338 [(set_attr "type" "sse")])
18339
18340(define_insn "vmrsqrtv4sf2"
18341 [(set (match_operand:V4SF 0 "register_operand" "=x")
18342 (vec_merge:V4SF
18343 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43)
18344 (match_operand:V4SF 2 "register_operand" "0")
18345 (const_int 1)))]
18346 "TARGET_SSE"
18347 "rsqrtss\t{%1, %0|%0, %1}"
18348 [(set_attr "type" "sse")])
18349
18350(define_insn "sqrtv4sf2"
18351 [(set (match_operand:V4SF 0 "register_operand" "=x")
18352 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
18353 "TARGET_SSE"
18354 "sqrtps\t{%1, %0|%0, %1}"
18355 [(set_attr "type" "sse")])
18356
18357(define_insn "vmsqrtv4sf2"
18358 [(set (match_operand:V4SF 0 "register_operand" "=x")
18359 (vec_merge:V4SF
18360 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18361 (match_operand:V4SF 2 "register_operand" "0")
18362 (const_int 1)))]
18363 "TARGET_SSE"
18364 "sqrtss\t{%1, %0|%0, %1}"
18365 [(set_attr "type" "sse")])
18366
18367;; SSE logical operations.
18368
18369;; These are not called andti3 etc. because we really really don't want
18370;; the compiler to widen DImode ands to TImode ands and then try to move
18371;; into DImode subregs of SSE registers, and them together, and move out
18372;; of DImode subregs again!
18373
18374(define_insn "*sse_andti3_df_1"
18375 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18376 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18377 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18378 "TARGET_SSE2"
18379 "andpd\t{%2, %0|%0, %2}"
18380 [(set_attr "type" "sse")])
18381
18382(define_insn "*sse_andti3_df_2"
18383 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18384 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18385 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18386 "TARGET_SSE2"
18387 "andpd\t{%2, %0|%0, %2}"
18388 [(set_attr "type" "sse")])
18389
18390(define_insn "*sse_andti3_sf_1"
18391 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18392 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18393 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18394 "TARGET_SSE"
18395 "andps\t{%2, %0|%0, %2}"
18396 [(set_attr "type" "sse")])
18397
18398(define_insn "*sse_andti3_sf_2"
18399 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18400 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18401 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18402 "TARGET_SSE"
18403 "andps\t{%2, %0|%0, %2}"
18404 [(set_attr "type" "sse")])
18405
18406(define_insn "sse_andti3"
18407 [(set (match_operand:TI 0 "register_operand" "=x")
18234 (and:TI (match_operand:TI 1 "register_operand" "%0")
18408 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18235 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18409 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18236 "TARGET_SSE && !TARGET_SSE2"
18410 "TARGET_SSE && !TARGET_SSE2
18411 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18237 "andps\t{%2, %0|%0, %2}"
18238 [(set_attr "type" "sse")])
18239
18240(define_insn "*sse_andti3_sse2"
18241 [(set (match_operand:TI 0 "register_operand" "=x")
18412 "andps\t{%2, %0|%0, %2}"
18413 [(set_attr "type" "sse")])
18414
18415(define_insn "*sse_andti3_sse2"
18416 [(set (match_operand:TI 0 "register_operand" "=x")
18242 (and:TI (match_operand:TI 1 "register_operand" "%0")
18417 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18243 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18418 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18244 "TARGET_SSE2"
18419 "TARGET_SSE2
18420 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18245 "pand\t{%2, %0|%0, %2}"
18246 [(set_attr "type" "sse")])
18247
18248(define_insn "*sse_nandti3_df"
18249 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18250 (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
18251 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18252 "TARGET_SSE2"
18253 "andnpd\t{%2, %0|%0, %2}"
18254 [(set_attr "type" "sse")])
18255
18256(define_insn "*sse_nandti3_sf"
18257 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18258 (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
18259 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18260 "TARGET_SSE"
18261 "andnps\t{%2, %0|%0, %2}"
18262 [(set_attr "type" "sse")])
18263
18264(define_insn "sse_nandti3"
18265 [(set (match_operand:TI 0 "register_operand" "=x")
18266 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18267 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18268 "TARGET_SSE && !TARGET_SSE2"
18269 "andnps\t{%2, %0|%0, %2}"
18270 [(set_attr "type" "sse")])
18271
18272(define_insn "*sse_nandti3_sse2"
18273 [(set (match_operand:TI 0 "register_operand" "=x")
18274 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18275 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18276 "TARGET_SSE2"
18277 "pnand\t{%2, %0|%0, %2}"
18278 [(set_attr "type" "sse")])
18279
18280(define_insn "*sse_iorti3_df_1"
18281 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18282 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18283 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18284 "TARGET_SSE2"
18285 "orpd\t{%2, %0|%0, %2}"
18286 [(set_attr "type" "sse")])
18287
18288(define_insn "*sse_iorti3_df_2"
18289 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18290 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18291 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18292 "TARGET_SSE2"
18293 "orpd\t{%2, %0|%0, %2}"
18294 [(set_attr "type" "sse")])
18295
18296(define_insn "*sse_iorti3_sf_1"
18297 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18298 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18299 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18300 "TARGET_SSE"
18301 "orps\t{%2, %0|%0, %2}"
18302 [(set_attr "type" "sse")])
18303
18304(define_insn "*sse_iorti3_sf_2"
18305 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18306 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18307 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18308 "TARGET_SSE"
18309 "orps\t{%2, %0|%0, %2}"
18310 [(set_attr "type" "sse")])
18311
18312(define_insn "sse_iorti3"
18313 [(set (match_operand:TI 0 "register_operand" "=x")
18421 "pand\t{%2, %0|%0, %2}"
18422 [(set_attr "type" "sse")])
18423
18424(define_insn "*sse_nandti3_df"
18425 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18426 (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
18427 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18428 "TARGET_SSE2"
18429 "andnpd\t{%2, %0|%0, %2}"
18430 [(set_attr "type" "sse")])
18431
18432(define_insn "*sse_nandti3_sf"
18433 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18434 (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
18435 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18436 "TARGET_SSE"
18437 "andnps\t{%2, %0|%0, %2}"
18438 [(set_attr "type" "sse")])
18439
18440(define_insn "sse_nandti3"
18441 [(set (match_operand:TI 0 "register_operand" "=x")
18442 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18443 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18444 "TARGET_SSE && !TARGET_SSE2"
18445 "andnps\t{%2, %0|%0, %2}"
18446 [(set_attr "type" "sse")])
18447
18448(define_insn "*sse_nandti3_sse2"
18449 [(set (match_operand:TI 0 "register_operand" "=x")
18450 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18451 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18452 "TARGET_SSE2"
18453 "pnand\t{%2, %0|%0, %2}"
18454 [(set_attr "type" "sse")])
18455
18456(define_insn "*sse_iorti3_df_1"
18457 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18458 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18459 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18460 "TARGET_SSE2"
18461 "orpd\t{%2, %0|%0, %2}"
18462 [(set_attr "type" "sse")])
18463
18464(define_insn "*sse_iorti3_df_2"
18465 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18466 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18467 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18468 "TARGET_SSE2"
18469 "orpd\t{%2, %0|%0, %2}"
18470 [(set_attr "type" "sse")])
18471
18472(define_insn "*sse_iorti3_sf_1"
18473 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18474 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18475 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18476 "TARGET_SSE"
18477 "orps\t{%2, %0|%0, %2}"
18478 [(set_attr "type" "sse")])
18479
18480(define_insn "*sse_iorti3_sf_2"
18481 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18482 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18483 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18484 "TARGET_SSE"
18485 "orps\t{%2, %0|%0, %2}"
18486 [(set_attr "type" "sse")])
18487
18488(define_insn "sse_iorti3"
18489 [(set (match_operand:TI 0 "register_operand" "=x")
18314 (ior:TI (match_operand:TI 1 "register_operand" "%0")
18490 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18315 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18491 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18316 "TARGET_SSE && !TARGET_SSE2"
18492 "TARGET_SSE && !TARGET_SSE2
18493 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18317 "orps\t{%2, %0|%0, %2}"
18318 [(set_attr "type" "sse")])
18319
18320(define_insn "*sse_iorti3_sse2"
18321 [(set (match_operand:TI 0 "register_operand" "=x")
18494 "orps\t{%2, %0|%0, %2}"
18495 [(set_attr "type" "sse")])
18496
18497(define_insn "*sse_iorti3_sse2"
18498 [(set (match_operand:TI 0 "register_operand" "=x")
18322 (ior:TI (match_operand:TI 1 "register_operand" "%0")
18499 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18323 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18500 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18324 "TARGET_SSE2"
18501 "TARGET_SSE2
18502 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18325 "por\t{%2, %0|%0, %2}"
18326 [(set_attr "type" "sse")])
18327
18328(define_insn "*sse_xorti3_df_1"
18329 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18330 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18331 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18332 "TARGET_SSE2"
18333 "xorpd\t{%2, %0|%0, %2}"
18334 [(set_attr "type" "sse")])
18335
18336(define_insn "*sse_xorti3_df_2"
18337 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18338 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18339 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18340 "TARGET_SSE2"
18341 "xorpd\t{%2, %0|%0, %2}"
18342 [(set_attr "type" "sse")])
18343
18344(define_insn "*sse_xorti3_sf_1"
18345 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18346 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18347 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18348 "TARGET_SSE"
18349 "xorps\t{%2, %0|%0, %2}"
18350 [(set_attr "type" "sse")])
18351
18352(define_insn "*sse_xorti3_sf_2"
18353 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18354 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18355 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18356 "TARGET_SSE"
18357 "xorps\t{%2, %0|%0, %2}"
18358 [(set_attr "type" "sse")])
18359
18360(define_insn "sse_xorti3"
18361 [(set (match_operand:TI 0 "register_operand" "=x")
18503 "por\t{%2, %0|%0, %2}"
18504 [(set_attr "type" "sse")])
18505
18506(define_insn "*sse_xorti3_df_1"
18507 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18508 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18509 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18510 "TARGET_SSE2"
18511 "xorpd\t{%2, %0|%0, %2}"
18512 [(set_attr "type" "sse")])
18513
18514(define_insn "*sse_xorti3_df_2"
18515 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18516 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18517 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18518 "TARGET_SSE2"
18519 "xorpd\t{%2, %0|%0, %2}"
18520 [(set_attr "type" "sse")])
18521
18522(define_insn "*sse_xorti3_sf_1"
18523 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18524 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18525 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18526 "TARGET_SSE"
18527 "xorps\t{%2, %0|%0, %2}"
18528 [(set_attr "type" "sse")])
18529
18530(define_insn "*sse_xorti3_sf_2"
18531 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18532 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18533 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18534 "TARGET_SSE"
18535 "xorps\t{%2, %0|%0, %2}"
18536 [(set_attr "type" "sse")])
18537
18538(define_insn "sse_xorti3"
18539 [(set (match_operand:TI 0 "register_operand" "=x")
18362 (xor:TI (match_operand:TI 1 "register_operand" "%0")
18540 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18363 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18541 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18364 "TARGET_SSE && !TARGET_SSE2"
18542 "TARGET_SSE && !TARGET_SSE2
18543 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18365 "xorps\t{%2, %0|%0, %2}"
18366 [(set_attr "type" "sse")])
18367
18368(define_insn "*sse_xorti3_sse2"
18369 [(set (match_operand:TI 0 "register_operand" "=x")
18544 "xorps\t{%2, %0|%0, %2}"
18545 [(set_attr "type" "sse")])
18546
18547(define_insn "*sse_xorti3_sse2"
18548 [(set (match_operand:TI 0 "register_operand" "=x")
18370 (xor:TI (match_operand:TI 1 "register_operand" "%0")
18549 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18371 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18550 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18372 "TARGET_SSE2"
18551 "TARGET_SSE2
18552 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18373 "pxor\t{%2, %0|%0, %2}"
18374 [(set_attr "type" "sse")])
18375
18376;; Use xor, but don't show input operands so they aren't live before
18377;; this insn.
18378(define_insn "sse_clrv4sf"
18379 [(set (match_operand:V4SF 0 "register_operand" "=x")
18380 (unspec:V4SF [(const_int 0)] 45))]
18381 "TARGET_SSE"
18382 "xorps\t{%0, %0|%0, %0}"
18383 [(set_attr "type" "sse")
18384 (set_attr "memory" "none")])
18385
18386;; SSE mask-generating compares
18387
18388(define_insn "maskcmpv4sf3"
18389 [(set (match_operand:V4SI 0 "register_operand" "=x")
18390 (match_operator:V4SI 3 "sse_comparison_operator"
18391 [(match_operand:V4SF 1 "register_operand" "0")
18392 (match_operand:V4SF 2 "register_operand" "x")]))]
18393 "TARGET_SSE"
18394 "cmp%D3ps\t{%2, %0|%0, %2}"
18395 [(set_attr "type" "sse")])
18396
18397(define_insn "maskncmpv4sf3"
18398 [(set (match_operand:V4SI 0 "register_operand" "=x")
18399 (not:V4SI
18400 (match_operator:V4SI 3 "sse_comparison_operator"
18401 [(match_operand:V4SF 1 "register_operand" "0")
18402 (match_operand:V4SF 2 "register_operand" "x")])))]
18403 "TARGET_SSE"
18404{
18405 if (GET_CODE (operands[3]) == UNORDERED)
18406 return "cmpordps\t{%2, %0|%0, %2}";
18407 else
18408 return "cmpn%D3ps\t{%2, %0|%0, %2}";
18409}
18410 [(set_attr "type" "sse")])
18411
18412(define_insn "vmmaskcmpv4sf3"
18413 [(set (match_operand:V4SI 0 "register_operand" "=x")
18414 (vec_merge:V4SI
18415 (match_operator:V4SI 3 "sse_comparison_operator"
18416 [(match_operand:V4SF 1 "register_operand" "0")
18417 (match_operand:V4SF 2 "register_operand" "x")])
18418 (match_dup 1)
18419 (const_int 1)))]
18420 "TARGET_SSE"
18421 "cmp%D3ss\t{%2, %0|%0, %2}"
18422 [(set_attr "type" "sse")])
18423
18424(define_insn "vmmaskncmpv4sf3"
18425 [(set (match_operand:V4SI 0 "register_operand" "=x")
18426 (vec_merge:V4SI
18427 (not:V4SI
18428 (match_operator:V4SI 3 "sse_comparison_operator"
18429 [(match_operand:V4SF 1 "register_operand" "0")
18430 (match_operand:V4SF 2 "register_operand" "x")]))
18431 (subreg:V4SI (match_dup 1) 0)
18432 (const_int 1)))]
18433 "TARGET_SSE"
18434{
18435 if (GET_CODE (operands[3]) == UNORDERED)
18436 return "cmpordss\t{%2, %0|%0, %2}";
18437 else
18438 return "cmpn%D3ss\t{%2, %0|%0, %2}";
18439}
18440 [(set_attr "type" "sse")])
18441
18442(define_insn "sse_comi"
18443 [(set (reg:CCFP 17)
18444 (match_operator:CCFP 2 "sse_comparison_operator"
18445 [(vec_select:SF
18446 (match_operand:V4SF 0 "register_operand" "x")
18447 (parallel [(const_int 0)]))
18448 (vec_select:SF
18449 (match_operand:V4SF 1 "register_operand" "x")
18450 (parallel [(const_int 0)]))]))]
18451 "TARGET_SSE"
18452 "comiss\t{%1, %0|%0, %1}"
18453 [(set_attr "type" "sse")])
18454
18455(define_insn "sse_ucomi"
18456 [(set (reg:CCFPU 17)
18457 (match_operator:CCFPU 2 "sse_comparison_operator"
18458 [(vec_select:SF
18459 (match_operand:V4SF 0 "register_operand" "x")
18460 (parallel [(const_int 0)]))
18461 (vec_select:SF
18462 (match_operand:V4SF 1 "register_operand" "x")
18463 (parallel [(const_int 0)]))]))]
18464 "TARGET_SSE"
18465 "ucomiss\t{%1, %0|%0, %1}"
18466 [(set_attr "type" "sse")])
18467
18468
18469;; SSE unpack
18470
18471(define_insn "sse_unpckhps"
18472 [(set (match_operand:V4SF 0 "register_operand" "=x")
18473 (vec_merge:V4SF
18474 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18475 (parallel [(const_int 2)
18476 (const_int 0)
18477 (const_int 3)
18478 (const_int 1)]))
18479 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18480 (parallel [(const_int 0)
18481 (const_int 2)
18482 (const_int 1)
18483 (const_int 3)]))
18484 (const_int 5)))]
18485 "TARGET_SSE"
18486 "unpckhps\t{%2, %0|%0, %2}"
18487 [(set_attr "type" "sse")])
18488
18489(define_insn "sse_unpcklps"
18490 [(set (match_operand:V4SF 0 "register_operand" "=x")
18491 (vec_merge:V4SF
18492 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18493 (parallel [(const_int 0)
18494 (const_int 2)
18495 (const_int 1)
18496 (const_int 3)]))
18497 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18498 (parallel [(const_int 2)
18499 (const_int 0)
18500 (const_int 3)
18501 (const_int 1)]))
18502 (const_int 5)))]
18503 "TARGET_SSE"
18504 "unpcklps\t{%2, %0|%0, %2}"
18505 [(set_attr "type" "sse")])
18506
18507
18508;; SSE min/max
18509
18510(define_insn "smaxv4sf3"
18511 [(set (match_operand:V4SF 0 "register_operand" "=x")
18512 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18513 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18514 "TARGET_SSE"
18515 "maxps\t{%2, %0|%0, %2}"
18516 [(set_attr "type" "sse")])
18517
18518(define_insn "vmsmaxv4sf3"
18519 [(set (match_operand:V4SF 0 "register_operand" "=x")
18520 (vec_merge:V4SF
18521 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18522 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18523 (match_dup 1)
18524 (const_int 1)))]
18525 "TARGET_SSE"
18526 "maxss\t{%2, %0|%0, %2}"
18527 [(set_attr "type" "sse")])
18528
18529(define_insn "sminv4sf3"
18530 [(set (match_operand:V4SF 0 "register_operand" "=x")
18531 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18532 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18533 "TARGET_SSE"
18534 "minps\t{%2, %0|%0, %2}"
18535 [(set_attr "type" "sse")])
18536
18537(define_insn "vmsminv4sf3"
18538 [(set (match_operand:V4SF 0 "register_operand" "=x")
18539 (vec_merge:V4SF
18540 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18541 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18542 (match_dup 1)
18543 (const_int 1)))]
18544 "TARGET_SSE"
18545 "minss\t{%2, %0|%0, %2}"
18546 [(set_attr "type" "sse")])
18547
18548
18549;; SSE <-> integer/MMX conversions
18550
18551(define_insn "cvtpi2ps"
18552 [(set (match_operand:V4SF 0 "register_operand" "=x")
18553 (vec_merge:V4SF
18554 (match_operand:V4SF 1 "register_operand" "0")
18555 (vec_duplicate:V4SF
18556 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
18557 (const_int 12)))]
18558 "TARGET_SSE"
18559 "cvtpi2ps\t{%2, %0|%0, %2}"
18560 [(set_attr "type" "sse")])
18561
18562(define_insn "cvtps2pi"
18563 [(set (match_operand:V2SI 0 "register_operand" "=y")
18564 (vec_select:V2SI
18565 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18566 (parallel [(const_int 0) (const_int 1)])))]
18567 "TARGET_SSE"
18568 "cvtps2pi\t{%1, %0|%0, %1}"
18569 [(set_attr "type" "sse")])
18570
18571(define_insn "cvttps2pi"
18572 [(set (match_operand:V2SI 0 "register_operand" "=y")
18573 (vec_select:V2SI
18574 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
18575 (parallel [(const_int 0) (const_int 1)])))]
18576 "TARGET_SSE"
18577 "cvttps2pi\t{%1, %0|%0, %1}"
18578 [(set_attr "type" "sse")])
18579
18580(define_insn "cvtsi2ss"
18581 [(set (match_operand:V4SF 0 "register_operand" "=x")
18582 (vec_merge:V4SF
18583 (match_operand:V4SF 1 "register_operand" "0")
18584 (vec_duplicate:V4SF
18585 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
18586 (const_int 14)))]
18587 "TARGET_SSE"
18588 "cvtsi2ss\t{%2, %0|%0, %2}"
18589 [(set_attr "type" "sse")])
18590
18591(define_insn "cvtss2si"
18592 [(set (match_operand:SI 0 "register_operand" "=r")
18593 (vec_select:SI
18594 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18595 (parallel [(const_int 0)])))]
18596 "TARGET_SSE"
18597 "cvtss2si\t{%1, %0|%0, %1}"
18598 [(set_attr "type" "sse")])
18599
18600(define_insn "cvttss2si"
18601 [(set (match_operand:SI 0 "register_operand" "=r")
18602 (vec_select:SI
18603 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
18604 (parallel [(const_int 0)])))]
18605 "TARGET_SSE"
18606 "cvttss2si\t{%1, %0|%0, %1}"
18607 [(set_attr "type" "sse")])
18608
18609
18610;; MMX insns
18611
18612;; MMX arithmetic
18613
18614(define_insn "addv8qi3"
18615 [(set (match_operand:V8QI 0 "register_operand" "=y")
18616 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18617 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18618 "TARGET_MMX"
18619 "paddb\t{%2, %0|%0, %2}"
18620 [(set_attr "type" "mmx")])
18621
18622(define_insn "addv4hi3"
18623 [(set (match_operand:V4HI 0 "register_operand" "=y")
18624 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18625 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18626 "TARGET_MMX"
18627 "paddw\t{%2, %0|%0, %2}"
18628 [(set_attr "type" "mmx")])
18629
18630(define_insn "addv2si3"
18631 [(set (match_operand:V2SI 0 "register_operand" "=y")
18632 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18633 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18634 "TARGET_MMX"
18635 "paddd\t{%2, %0|%0, %2}"
18636 [(set_attr "type" "mmx")])
18637
18638(define_insn "ssaddv8qi3"
18639 [(set (match_operand:V8QI 0 "register_operand" "=y")
18640 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18641 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18642 "TARGET_MMX"
18643 "paddsb\t{%2, %0|%0, %2}"
18644 [(set_attr "type" "mmx")])
18645
18646(define_insn "ssaddv4hi3"
18647 [(set (match_operand:V4HI 0 "register_operand" "=y")
18648 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18649 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18650 "TARGET_MMX"
18651 "paddsw\t{%2, %0|%0, %2}"
18652 [(set_attr "type" "mmx")])
18653
18654(define_insn "usaddv8qi3"
18655 [(set (match_operand:V8QI 0 "register_operand" "=y")
18656 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18657 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18658 "TARGET_MMX"
18659 "paddusb\t{%2, %0|%0, %2}"
18660 [(set_attr "type" "mmx")])
18661
18662(define_insn "usaddv4hi3"
18663 [(set (match_operand:V4HI 0 "register_operand" "=y")
18664 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18665 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18666 "TARGET_MMX"
18667 "paddusw\t{%2, %0|%0, %2}"
18668 [(set_attr "type" "mmx")])
18669
18670(define_insn "subv8qi3"
18671 [(set (match_operand:V8QI 0 "register_operand" "=y")
18672 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18673 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18674 "TARGET_MMX"
18675 "psubb\t{%2, %0|%0, %2}"
18676 [(set_attr "type" "mmx")])
18677
18678(define_insn "subv4hi3"
18679 [(set (match_operand:V4HI 0 "register_operand" "=y")
18680 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18681 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18682 "TARGET_MMX"
18683 "psubw\t{%2, %0|%0, %2}"
18684 [(set_attr "type" "mmx")])
18685
18686(define_insn "subv2si3"
18687 [(set (match_operand:V2SI 0 "register_operand" "=y")
18688 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18689 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18690 "TARGET_MMX"
18691 "psubd\t{%2, %0|%0, %2}"
18692 [(set_attr "type" "mmx")])
18693
18694(define_insn "sssubv8qi3"
18695 [(set (match_operand:V8QI 0 "register_operand" "=y")
18696 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18697 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18698 "TARGET_MMX"
18699 "psubsb\t{%2, %0|%0, %2}"
18700 [(set_attr "type" "mmx")])
18701
18702(define_insn "sssubv4hi3"
18703 [(set (match_operand:V4HI 0 "register_operand" "=y")
18704 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18705 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18706 "TARGET_MMX"
18707 "psubsw\t{%2, %0|%0, %2}"
18708 [(set_attr "type" "mmx")])
18709
18710(define_insn "ussubv8qi3"
18711 [(set (match_operand:V8QI 0 "register_operand" "=y")
18712 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18713 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18714 "TARGET_MMX"
18715 "psubusb\t{%2, %0|%0, %2}"
18716 [(set_attr "type" "mmx")])
18717
18718(define_insn "ussubv4hi3"
18719 [(set (match_operand:V4HI 0 "register_operand" "=y")
18720 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18721 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18722 "TARGET_MMX"
18723 "psubusw\t{%2, %0|%0, %2}"
18724 [(set_attr "type" "mmx")])
18725
18726(define_insn "mulv4hi3"
18727 [(set (match_operand:V4HI 0 "register_operand" "=y")
18728 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18729 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18730 "TARGET_MMX"
18731 "pmullw\t{%2, %0|%0, %2}"
18732 [(set_attr "type" "mmx")])
18733
18734(define_insn "smulv4hi3_highpart"
18735 [(set (match_operand:V4HI 0 "register_operand" "=y")
18736 (truncate:V4HI
18737 (lshiftrt:V4SI
18738 (mult:V4SI (sign_extend:V4SI
18739 (match_operand:V4HI 1 "register_operand" "0"))
18740 (sign_extend:V4SI
18741 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18742 (const_int 16))))]
18743 "TARGET_MMX"
18744 "pmulhw\t{%2, %0|%0, %2}"
18745 [(set_attr "type" "mmx")])
18746
18747(define_insn "umulv4hi3_highpart"
18748 [(set (match_operand:V4HI 0 "register_operand" "=y")
18749 (truncate:V4HI
18750 (lshiftrt:V4SI
18751 (mult:V4SI (zero_extend:V4SI
18752 (match_operand:V4HI 1 "register_operand" "0"))
18753 (zero_extend:V4SI
18754 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18755 (const_int 16))))]
18756 "TARGET_SSE || TARGET_3DNOW_A"
18757 "pmulhuw\t{%2, %0|%0, %2}"
18758 [(set_attr "type" "mmx")])
18759
18760(define_insn "mmx_pmaddwd"
18761 [(set (match_operand:V2SI 0 "register_operand" "=y")
18762 (plus:V2SI
18763 (mult:V2SI
18764 (sign_extend:V2SI
18765 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18766 (parallel [(const_int 0) (const_int 2)])))
18767 (sign_extend:V2SI
18768 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18769 (parallel [(const_int 0) (const_int 2)]))))
18770 (mult:V2SI
18771 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18772 (parallel [(const_int 1)
18773 (const_int 3)])))
18774 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18775 (parallel [(const_int 1)
18776 (const_int 3)]))))))]
18777 "TARGET_MMX"
18778 "pmaddwd\t{%2, %0|%0, %2}"
18779 [(set_attr "type" "mmx")])
18780
18781
18782;; MMX logical operations
18783;; Note we don't want to declare these as regular iordi3 insns to prevent
18784;; normal code that also wants to use the FPU from getting broken.
18785;; The UNSPECs are there to prevent the combiner from getting overly clever.
18786(define_insn "mmx_iordi3"
18787 [(set (match_operand:DI 0 "register_operand" "=y")
18788 (unspec:DI
18789 [(ior:DI (match_operand:DI 1 "register_operand" "0")
18790 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18791 "TARGET_MMX"
18792 "por\t{%2, %0|%0, %2}"
18793 [(set_attr "type" "mmx")])
18794
18795(define_insn "mmx_xordi3"
18796 [(set (match_operand:DI 0 "register_operand" "=y")
18797 (unspec:DI
18798 [(xor:DI (match_operand:DI 1 "register_operand" "0")
18799 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18800 "TARGET_MMX"
18801 "pxor\t{%2, %0|%0, %2}"
18802 [(set_attr "type" "mmx")
18803 (set_attr "memory" "none")])
18804
18805;; Same as pxor, but don't show input operands so that we don't think
18806;; they are live.
18807(define_insn "mmx_clrdi"
18808 [(set (match_operand:DI 0 "register_operand" "=y")
18809 (unspec:DI [(const_int 0)] 45))]
18810 "TARGET_MMX"
18811 "pxor\t{%0, %0|%0, %0}"
18812 [(set_attr "type" "mmx")
18813 (set_attr "memory" "none")])
18814
18815(define_insn "mmx_anddi3"
18816 [(set (match_operand:DI 0 "register_operand" "=y")
18817 (unspec:DI
18818 [(and:DI (match_operand:DI 1 "register_operand" "0")
18819 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18820 "TARGET_MMX"
18821 "pand\t{%2, %0|%0, %2}"
18822 [(set_attr "type" "mmx")])
18823
18824(define_insn "mmx_nanddi3"
18825 [(set (match_operand:DI 0 "register_operand" "=y")
18826 (unspec:DI
18827 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
18828 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18829 "TARGET_MMX"
18830 "pandn\t{%2, %0|%0, %2}"
18831 [(set_attr "type" "mmx")])
18832
18833
18834;; MMX unsigned averages/sum of absolute differences
18835
18836(define_insn "mmx_uavgv8qi3"
18837 [(set (match_operand:V8QI 0 "register_operand" "=y")
18838 (ashiftrt:V8QI
18839 (plus:V8QI (plus:V8QI
18840 (match_operand:V8QI 1 "register_operand" "0")
18841 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
18553 "pxor\t{%2, %0|%0, %2}"
18554 [(set_attr "type" "sse")])
18555
18556;; Use xor, but don't show input operands so they aren't live before
18557;; this insn.
18558(define_insn "sse_clrv4sf"
18559 [(set (match_operand:V4SF 0 "register_operand" "=x")
18560 (unspec:V4SF [(const_int 0)] 45))]
18561 "TARGET_SSE"
18562 "xorps\t{%0, %0|%0, %0}"
18563 [(set_attr "type" "sse")
18564 (set_attr "memory" "none")])
18565
18566;; SSE mask-generating compares
18567
18568(define_insn "maskcmpv4sf3"
18569 [(set (match_operand:V4SI 0 "register_operand" "=x")
18570 (match_operator:V4SI 3 "sse_comparison_operator"
18571 [(match_operand:V4SF 1 "register_operand" "0")
18572 (match_operand:V4SF 2 "register_operand" "x")]))]
18573 "TARGET_SSE"
18574 "cmp%D3ps\t{%2, %0|%0, %2}"
18575 [(set_attr "type" "sse")])
18576
18577(define_insn "maskncmpv4sf3"
18578 [(set (match_operand:V4SI 0 "register_operand" "=x")
18579 (not:V4SI
18580 (match_operator:V4SI 3 "sse_comparison_operator"
18581 [(match_operand:V4SF 1 "register_operand" "0")
18582 (match_operand:V4SF 2 "register_operand" "x")])))]
18583 "TARGET_SSE"
18584{
18585 if (GET_CODE (operands[3]) == UNORDERED)
18586 return "cmpordps\t{%2, %0|%0, %2}";
18587 else
18588 return "cmpn%D3ps\t{%2, %0|%0, %2}";
18589}
18590 [(set_attr "type" "sse")])
18591
18592(define_insn "vmmaskcmpv4sf3"
18593 [(set (match_operand:V4SI 0 "register_operand" "=x")
18594 (vec_merge:V4SI
18595 (match_operator:V4SI 3 "sse_comparison_operator"
18596 [(match_operand:V4SF 1 "register_operand" "0")
18597 (match_operand:V4SF 2 "register_operand" "x")])
18598 (match_dup 1)
18599 (const_int 1)))]
18600 "TARGET_SSE"
18601 "cmp%D3ss\t{%2, %0|%0, %2}"
18602 [(set_attr "type" "sse")])
18603
18604(define_insn "vmmaskncmpv4sf3"
18605 [(set (match_operand:V4SI 0 "register_operand" "=x")
18606 (vec_merge:V4SI
18607 (not:V4SI
18608 (match_operator:V4SI 3 "sse_comparison_operator"
18609 [(match_operand:V4SF 1 "register_operand" "0")
18610 (match_operand:V4SF 2 "register_operand" "x")]))
18611 (subreg:V4SI (match_dup 1) 0)
18612 (const_int 1)))]
18613 "TARGET_SSE"
18614{
18615 if (GET_CODE (operands[3]) == UNORDERED)
18616 return "cmpordss\t{%2, %0|%0, %2}";
18617 else
18618 return "cmpn%D3ss\t{%2, %0|%0, %2}";
18619}
18620 [(set_attr "type" "sse")])
18621
18622(define_insn "sse_comi"
18623 [(set (reg:CCFP 17)
18624 (match_operator:CCFP 2 "sse_comparison_operator"
18625 [(vec_select:SF
18626 (match_operand:V4SF 0 "register_operand" "x")
18627 (parallel [(const_int 0)]))
18628 (vec_select:SF
18629 (match_operand:V4SF 1 "register_operand" "x")
18630 (parallel [(const_int 0)]))]))]
18631 "TARGET_SSE"
18632 "comiss\t{%1, %0|%0, %1}"
18633 [(set_attr "type" "sse")])
18634
18635(define_insn "sse_ucomi"
18636 [(set (reg:CCFPU 17)
18637 (match_operator:CCFPU 2 "sse_comparison_operator"
18638 [(vec_select:SF
18639 (match_operand:V4SF 0 "register_operand" "x")
18640 (parallel [(const_int 0)]))
18641 (vec_select:SF
18642 (match_operand:V4SF 1 "register_operand" "x")
18643 (parallel [(const_int 0)]))]))]
18644 "TARGET_SSE"
18645 "ucomiss\t{%1, %0|%0, %1}"
18646 [(set_attr "type" "sse")])
18647
18648
18649;; SSE unpack
18650
18651(define_insn "sse_unpckhps"
18652 [(set (match_operand:V4SF 0 "register_operand" "=x")
18653 (vec_merge:V4SF
18654 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18655 (parallel [(const_int 2)
18656 (const_int 0)
18657 (const_int 3)
18658 (const_int 1)]))
18659 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18660 (parallel [(const_int 0)
18661 (const_int 2)
18662 (const_int 1)
18663 (const_int 3)]))
18664 (const_int 5)))]
18665 "TARGET_SSE"
18666 "unpckhps\t{%2, %0|%0, %2}"
18667 [(set_attr "type" "sse")])
18668
18669(define_insn "sse_unpcklps"
18670 [(set (match_operand:V4SF 0 "register_operand" "=x")
18671 (vec_merge:V4SF
18672 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18673 (parallel [(const_int 0)
18674 (const_int 2)
18675 (const_int 1)
18676 (const_int 3)]))
18677 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18678 (parallel [(const_int 2)
18679 (const_int 0)
18680 (const_int 3)
18681 (const_int 1)]))
18682 (const_int 5)))]
18683 "TARGET_SSE"
18684 "unpcklps\t{%2, %0|%0, %2}"
18685 [(set_attr "type" "sse")])
18686
18687
18688;; SSE min/max
18689
18690(define_insn "smaxv4sf3"
18691 [(set (match_operand:V4SF 0 "register_operand" "=x")
18692 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18693 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18694 "TARGET_SSE"
18695 "maxps\t{%2, %0|%0, %2}"
18696 [(set_attr "type" "sse")])
18697
18698(define_insn "vmsmaxv4sf3"
18699 [(set (match_operand:V4SF 0 "register_operand" "=x")
18700 (vec_merge:V4SF
18701 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18702 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18703 (match_dup 1)
18704 (const_int 1)))]
18705 "TARGET_SSE"
18706 "maxss\t{%2, %0|%0, %2}"
18707 [(set_attr "type" "sse")])
18708
18709(define_insn "sminv4sf3"
18710 [(set (match_operand:V4SF 0 "register_operand" "=x")
18711 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18712 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18713 "TARGET_SSE"
18714 "minps\t{%2, %0|%0, %2}"
18715 [(set_attr "type" "sse")])
18716
18717(define_insn "vmsminv4sf3"
18718 [(set (match_operand:V4SF 0 "register_operand" "=x")
18719 (vec_merge:V4SF
18720 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18721 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18722 (match_dup 1)
18723 (const_int 1)))]
18724 "TARGET_SSE"
18725 "minss\t{%2, %0|%0, %2}"
18726 [(set_attr "type" "sse")])
18727
18728
18729;; SSE <-> integer/MMX conversions
18730
18731(define_insn "cvtpi2ps"
18732 [(set (match_operand:V4SF 0 "register_operand" "=x")
18733 (vec_merge:V4SF
18734 (match_operand:V4SF 1 "register_operand" "0")
18735 (vec_duplicate:V4SF
18736 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
18737 (const_int 12)))]
18738 "TARGET_SSE"
18739 "cvtpi2ps\t{%2, %0|%0, %2}"
18740 [(set_attr "type" "sse")])
18741
18742(define_insn "cvtps2pi"
18743 [(set (match_operand:V2SI 0 "register_operand" "=y")
18744 (vec_select:V2SI
18745 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18746 (parallel [(const_int 0) (const_int 1)])))]
18747 "TARGET_SSE"
18748 "cvtps2pi\t{%1, %0|%0, %1}"
18749 [(set_attr "type" "sse")])
18750
18751(define_insn "cvttps2pi"
18752 [(set (match_operand:V2SI 0 "register_operand" "=y")
18753 (vec_select:V2SI
18754 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
18755 (parallel [(const_int 0) (const_int 1)])))]
18756 "TARGET_SSE"
18757 "cvttps2pi\t{%1, %0|%0, %1}"
18758 [(set_attr "type" "sse")])
18759
18760(define_insn "cvtsi2ss"
18761 [(set (match_operand:V4SF 0 "register_operand" "=x")
18762 (vec_merge:V4SF
18763 (match_operand:V4SF 1 "register_operand" "0")
18764 (vec_duplicate:V4SF
18765 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
18766 (const_int 14)))]
18767 "TARGET_SSE"
18768 "cvtsi2ss\t{%2, %0|%0, %2}"
18769 [(set_attr "type" "sse")])
18770
18771(define_insn "cvtss2si"
18772 [(set (match_operand:SI 0 "register_operand" "=r")
18773 (vec_select:SI
18774 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18775 (parallel [(const_int 0)])))]
18776 "TARGET_SSE"
18777 "cvtss2si\t{%1, %0|%0, %1}"
18778 [(set_attr "type" "sse")])
18779
18780(define_insn "cvttss2si"
18781 [(set (match_operand:SI 0 "register_operand" "=r")
18782 (vec_select:SI
18783 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
18784 (parallel [(const_int 0)])))]
18785 "TARGET_SSE"
18786 "cvttss2si\t{%1, %0|%0, %1}"
18787 [(set_attr "type" "sse")])
18788
18789
18790;; MMX insns
18791
18792;; MMX arithmetic
18793
18794(define_insn "addv8qi3"
18795 [(set (match_operand:V8QI 0 "register_operand" "=y")
18796 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18797 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18798 "TARGET_MMX"
18799 "paddb\t{%2, %0|%0, %2}"
18800 [(set_attr "type" "mmx")])
18801
18802(define_insn "addv4hi3"
18803 [(set (match_operand:V4HI 0 "register_operand" "=y")
18804 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18805 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18806 "TARGET_MMX"
18807 "paddw\t{%2, %0|%0, %2}"
18808 [(set_attr "type" "mmx")])
18809
18810(define_insn "addv2si3"
18811 [(set (match_operand:V2SI 0 "register_operand" "=y")
18812 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18813 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18814 "TARGET_MMX"
18815 "paddd\t{%2, %0|%0, %2}"
18816 [(set_attr "type" "mmx")])
18817
18818(define_insn "ssaddv8qi3"
18819 [(set (match_operand:V8QI 0 "register_operand" "=y")
18820 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18821 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18822 "TARGET_MMX"
18823 "paddsb\t{%2, %0|%0, %2}"
18824 [(set_attr "type" "mmx")])
18825
18826(define_insn "ssaddv4hi3"
18827 [(set (match_operand:V4HI 0 "register_operand" "=y")
18828 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18829 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18830 "TARGET_MMX"
18831 "paddsw\t{%2, %0|%0, %2}"
18832 [(set_attr "type" "mmx")])
18833
18834(define_insn "usaddv8qi3"
18835 [(set (match_operand:V8QI 0 "register_operand" "=y")
18836 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18837 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18838 "TARGET_MMX"
18839 "paddusb\t{%2, %0|%0, %2}"
18840 [(set_attr "type" "mmx")])
18841
18842(define_insn "usaddv4hi3"
18843 [(set (match_operand:V4HI 0 "register_operand" "=y")
18844 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18845 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18846 "TARGET_MMX"
18847 "paddusw\t{%2, %0|%0, %2}"
18848 [(set_attr "type" "mmx")])
18849
18850(define_insn "subv8qi3"
18851 [(set (match_operand:V8QI 0 "register_operand" "=y")
18852 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18853 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18854 "TARGET_MMX"
18855 "psubb\t{%2, %0|%0, %2}"
18856 [(set_attr "type" "mmx")])
18857
18858(define_insn "subv4hi3"
18859 [(set (match_operand:V4HI 0 "register_operand" "=y")
18860 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18861 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18862 "TARGET_MMX"
18863 "psubw\t{%2, %0|%0, %2}"
18864 [(set_attr "type" "mmx")])
18865
18866(define_insn "subv2si3"
18867 [(set (match_operand:V2SI 0 "register_operand" "=y")
18868 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18869 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18870 "TARGET_MMX"
18871 "psubd\t{%2, %0|%0, %2}"
18872 [(set_attr "type" "mmx")])
18873
18874(define_insn "sssubv8qi3"
18875 [(set (match_operand:V8QI 0 "register_operand" "=y")
18876 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18877 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18878 "TARGET_MMX"
18879 "psubsb\t{%2, %0|%0, %2}"
18880 [(set_attr "type" "mmx")])
18881
18882(define_insn "sssubv4hi3"
18883 [(set (match_operand:V4HI 0 "register_operand" "=y")
18884 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18885 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18886 "TARGET_MMX"
18887 "psubsw\t{%2, %0|%0, %2}"
18888 [(set_attr "type" "mmx")])
18889
18890(define_insn "ussubv8qi3"
18891 [(set (match_operand:V8QI 0 "register_operand" "=y")
18892 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18893 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18894 "TARGET_MMX"
18895 "psubusb\t{%2, %0|%0, %2}"
18896 [(set_attr "type" "mmx")])
18897
18898(define_insn "ussubv4hi3"
18899 [(set (match_operand:V4HI 0 "register_operand" "=y")
18900 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18901 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18902 "TARGET_MMX"
18903 "psubusw\t{%2, %0|%0, %2}"
18904 [(set_attr "type" "mmx")])
18905
18906(define_insn "mulv4hi3"
18907 [(set (match_operand:V4HI 0 "register_operand" "=y")
18908 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18909 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18910 "TARGET_MMX"
18911 "pmullw\t{%2, %0|%0, %2}"
18912 [(set_attr "type" "mmx")])
18913
18914(define_insn "smulv4hi3_highpart"
18915 [(set (match_operand:V4HI 0 "register_operand" "=y")
18916 (truncate:V4HI
18917 (lshiftrt:V4SI
18918 (mult:V4SI (sign_extend:V4SI
18919 (match_operand:V4HI 1 "register_operand" "0"))
18920 (sign_extend:V4SI
18921 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18922 (const_int 16))))]
18923 "TARGET_MMX"
18924 "pmulhw\t{%2, %0|%0, %2}"
18925 [(set_attr "type" "mmx")])
18926
18927(define_insn "umulv4hi3_highpart"
18928 [(set (match_operand:V4HI 0 "register_operand" "=y")
18929 (truncate:V4HI
18930 (lshiftrt:V4SI
18931 (mult:V4SI (zero_extend:V4SI
18932 (match_operand:V4HI 1 "register_operand" "0"))
18933 (zero_extend:V4SI
18934 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18935 (const_int 16))))]
18936 "TARGET_SSE || TARGET_3DNOW_A"
18937 "pmulhuw\t{%2, %0|%0, %2}"
18938 [(set_attr "type" "mmx")])
18939
18940(define_insn "mmx_pmaddwd"
18941 [(set (match_operand:V2SI 0 "register_operand" "=y")
18942 (plus:V2SI
18943 (mult:V2SI
18944 (sign_extend:V2SI
18945 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18946 (parallel [(const_int 0) (const_int 2)])))
18947 (sign_extend:V2SI
18948 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18949 (parallel [(const_int 0) (const_int 2)]))))
18950 (mult:V2SI
18951 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18952 (parallel [(const_int 1)
18953 (const_int 3)])))
18954 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18955 (parallel [(const_int 1)
18956 (const_int 3)]))))))]
18957 "TARGET_MMX"
18958 "pmaddwd\t{%2, %0|%0, %2}"
18959 [(set_attr "type" "mmx")])
18960
18961
18962;; MMX logical operations
18963;; Note we don't want to declare these as regular iordi3 insns to prevent
18964;; normal code that also wants to use the FPU from getting broken.
18965;; The UNSPECs are there to prevent the combiner from getting overly clever.
18966(define_insn "mmx_iordi3"
18967 [(set (match_operand:DI 0 "register_operand" "=y")
18968 (unspec:DI
18969 [(ior:DI (match_operand:DI 1 "register_operand" "0")
18970 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18971 "TARGET_MMX"
18972 "por\t{%2, %0|%0, %2}"
18973 [(set_attr "type" "mmx")])
18974
18975(define_insn "mmx_xordi3"
18976 [(set (match_operand:DI 0 "register_operand" "=y")
18977 (unspec:DI
18978 [(xor:DI (match_operand:DI 1 "register_operand" "0")
18979 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18980 "TARGET_MMX"
18981 "pxor\t{%2, %0|%0, %2}"
18982 [(set_attr "type" "mmx")
18983 (set_attr "memory" "none")])
18984
18985;; Same as pxor, but don't show input operands so that we don't think
18986;; they are live.
18987(define_insn "mmx_clrdi"
18988 [(set (match_operand:DI 0 "register_operand" "=y")
18989 (unspec:DI [(const_int 0)] 45))]
18990 "TARGET_MMX"
18991 "pxor\t{%0, %0|%0, %0}"
18992 [(set_attr "type" "mmx")
18993 (set_attr "memory" "none")])
18994
18995(define_insn "mmx_anddi3"
18996 [(set (match_operand:DI 0 "register_operand" "=y")
18997 (unspec:DI
18998 [(and:DI (match_operand:DI 1 "register_operand" "0")
18999 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
19000 "TARGET_MMX"
19001 "pand\t{%2, %0|%0, %2}"
19002 [(set_attr "type" "mmx")])
19003
19004(define_insn "mmx_nanddi3"
19005 [(set (match_operand:DI 0 "register_operand" "=y")
19006 (unspec:DI
19007 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
19008 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
19009 "TARGET_MMX"
19010 "pandn\t{%2, %0|%0, %2}"
19011 [(set_attr "type" "mmx")])
19012
19013
19014;; MMX unsigned averages/sum of absolute differences
19015
19016(define_insn "mmx_uavgv8qi3"
19017 [(set (match_operand:V8QI 0 "register_operand" "=y")
19018 (ashiftrt:V8QI
19019 (plus:V8QI (plus:V8QI
19020 (match_operand:V8QI 1 "register_operand" "0")
19021 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
18842 (vec_const:V8QI (parallel [(const_int 1)
18843 (const_int 1)
18844 (const_int 1)
18845 (const_int 1)
18846 (const_int 1)
18847 (const_int 1)
18848 (const_int 1)
18849 (const_int 1)])))
19022 (const_vector:V8QI [(const_int 1)
19023 (const_int 1)
19024 (const_int 1)
19025 (const_int 1)
19026 (const_int 1)
19027 (const_int 1)
19028 (const_int 1)
19029 (const_int 1)]))
18850 (const_int 1)))]
18851 "TARGET_SSE || TARGET_3DNOW_A"
18852 "pavgb\t{%2, %0|%0, %2}"
18853 [(set_attr "type" "sse")])
18854
18855(define_insn "mmx_uavgv4hi3"
18856 [(set (match_operand:V4HI 0 "register_operand" "=y")
18857 (ashiftrt:V4HI
18858 (plus:V4HI (plus:V4HI
18859 (match_operand:V4HI 1 "register_operand" "0")
18860 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
19030 (const_int 1)))]
19031 "TARGET_SSE || TARGET_3DNOW_A"
19032 "pavgb\t{%2, %0|%0, %2}"
19033 [(set_attr "type" "sse")])
19034
19035(define_insn "mmx_uavgv4hi3"
19036 [(set (match_operand:V4HI 0 "register_operand" "=y")
19037 (ashiftrt:V4HI
19038 (plus:V4HI (plus:V4HI
19039 (match_operand:V4HI 1 "register_operand" "0")
19040 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
18861 (vec_const:V4HI (parallel [(const_int 1)
18862 (const_int 1)
18863 (const_int 1)
18864 (const_int 1)])))
19041 (const_vector:V4HI [(const_int 1)
19042 (const_int 1)
19043 (const_int 1)
19044 (const_int 1)]))
18865 (const_int 1)))]
18866 "TARGET_SSE || TARGET_3DNOW_A"
18867 "pavgw\t{%2, %0|%0, %2}"
18868 [(set_attr "type" "sse")])
18869
18870(define_insn "mmx_psadbw"
18871 [(set (match_operand:V8QI 0 "register_operand" "=y")
18872 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18873 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
18874 "TARGET_SSE || TARGET_3DNOW_A"
18875 "psadbw\t{%2, %0|%0, %2}"
18876 [(set_attr "type" "sse")])
18877
18878
18879;; MMX insert/extract/shuffle
18880
18881(define_insn "mmx_pinsrw"
18882 [(set (match_operand:V4HI 0 "register_operand" "=y")
18883 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
18884 (vec_duplicate:V4HI
18885 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
18886 (match_operand:SI 3 "immediate_operand" "i")))]
18887 "TARGET_SSE || TARGET_3DNOW_A"
18888 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
18889 [(set_attr "type" "sse")])
18890
18891(define_insn "mmx_pextrw"
18892 [(set (match_operand:SI 0 "register_operand" "=r")
18893 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
18894 (parallel
18895 [(match_operand:SI 2 "immediate_operand" "i")]))))]
18896 "TARGET_SSE || TARGET_3DNOW_A"
18897 "pextrw\t{%2, %1, %0|%0, %1, %2}"
18898 [(set_attr "type" "sse")])
18899
18900(define_insn "mmx_pshufw"
18901 [(set (match_operand:V4HI 0 "register_operand" "=y")
18902 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
18903 (match_operand:SI 2 "immediate_operand" "i")] 41))]
18904 "TARGET_SSE || TARGET_3DNOW_A"
18905 "pshufw\t{%2, %1, %0|%0, %1, %2}"
18906 [(set_attr "type" "sse")])
18907
18908
18909;; MMX mask-generating comparisons
18910
18911(define_insn "eqv8qi3"
18912 [(set (match_operand:V8QI 0 "register_operand" "=y")
18913 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
18914 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18915 "TARGET_MMX"
18916 "pcmpeqb\t{%2, %0|%0, %2}"
18917 [(set_attr "type" "mmx")])
18918
18919(define_insn "eqv4hi3"
18920 [(set (match_operand:V4HI 0 "register_operand" "=y")
18921 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
18922 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18923 "TARGET_MMX"
18924 "pcmpeqw\t{%2, %0|%0, %2}"
18925 [(set_attr "type" "mmx")])
18926
18927(define_insn "eqv2si3"
18928 [(set (match_operand:V2SI 0 "register_operand" "=y")
18929 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
18930 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18931 "TARGET_MMX"
18932 "pcmpeqd\t{%2, %0|%0, %2}"
18933 [(set_attr "type" "mmx")])
18934
18935(define_insn "gtv8qi3"
18936 [(set (match_operand:V8QI 0 "register_operand" "=y")
18937 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
18938 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18939 "TARGET_MMX"
18940 "pcmpgtb\t{%2, %0|%0, %2}"
18941 [(set_attr "type" "mmx")])
18942
18943(define_insn "gtv4hi3"
18944 [(set (match_operand:V4HI 0 "register_operand" "=y")
18945 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18946 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18947 "TARGET_MMX"
18948 "pcmpgtw\t{%2, %0|%0, %2}"
18949 [(set_attr "type" "mmx")])
18950
18951(define_insn "gtv2si3"
18952 [(set (match_operand:V2SI 0 "register_operand" "=y")
18953 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18954 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18955 "TARGET_MMX"
18956 "pcmpgtd\t{%2, %0|%0, %2}"
18957 [(set_attr "type" "mmx")])
18958
18959
18960;; MMX max/min insns
18961
18962(define_insn "umaxv8qi3"
18963 [(set (match_operand:V8QI 0 "register_operand" "=y")
18964 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
18965 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18966 "TARGET_SSE || TARGET_3DNOW_A"
18967 "pmaxub\t{%2, %0|%0, %2}"
18968 [(set_attr "type" "sse")])
18969
18970(define_insn "smaxv4hi3"
18971 [(set (match_operand:V4HI 0 "register_operand" "=y")
18972 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
18973 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18974 "TARGET_SSE || TARGET_3DNOW_A"
18975 "pmaxsw\t{%2, %0|%0, %2}"
18976 [(set_attr "type" "sse")])
18977
18978(define_insn "uminv8qi3"
18979 [(set (match_operand:V8QI 0 "register_operand" "=y")
18980 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
18981 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18982 "TARGET_SSE || TARGET_3DNOW_A"
18983 "pminub\t{%2, %0|%0, %2}"
18984 [(set_attr "type" "sse")])
18985
18986(define_insn "sminv4hi3"
18987 [(set (match_operand:V4HI 0 "register_operand" "=y")
18988 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
18989 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18990 "TARGET_SSE || TARGET_3DNOW_A"
18991 "pminsw\t{%2, %0|%0, %2}"
18992 [(set_attr "type" "sse")])
18993
18994
18995;; MMX shifts
18996
18997(define_insn "ashrv4hi3"
18998 [(set (match_operand:V4HI 0 "register_operand" "=y")
18999 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19000 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19001 "TARGET_MMX"
19002 "psraw\t{%2, %0|%0, %2}"
19003 [(set_attr "type" "mmx")])
19004
19005(define_insn "ashrv2si3"
19006 [(set (match_operand:V2SI 0 "register_operand" "=y")
19007 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19008 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19009 "TARGET_MMX"
19010 "psrad\t{%2, %0|%0, %2}"
19011 [(set_attr "type" "mmx")])
19012
19013(define_insn "lshrv4hi3"
19014 [(set (match_operand:V4HI 0 "register_operand" "=y")
19015 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19016 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19017 "TARGET_MMX"
19018 "psrlw\t{%2, %0|%0, %2}"
19019 [(set_attr "type" "mmx")])
19020
19021(define_insn "lshrv2si3"
19022 [(set (match_operand:V2SI 0 "register_operand" "=y")
19023 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19024 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19025 "TARGET_MMX"
19026 "psrld\t{%2, %0|%0, %2}"
19027 [(set_attr "type" "mmx")])
19028
19029;; See logical MMX insns.
19030(define_insn "mmx_lshrdi3"
19031 [(set (match_operand:DI 0 "register_operand" "=y")
19032 (unspec:DI
19033 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
19034 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
19035 "TARGET_MMX"
19036 "psrlq\t{%2, %0|%0, %2}"
19037 [(set_attr "type" "mmx")])
19038
19039(define_insn "ashlv4hi3"
19040 [(set (match_operand:V4HI 0 "register_operand" "=y")
19041 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
19042 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19043 "TARGET_MMX"
19044 "psllw\t{%2, %0|%0, %2}"
19045 [(set_attr "type" "mmx")])
19046
19047(define_insn "ashlv2si3"
19048 [(set (match_operand:V2SI 0 "register_operand" "=y")
19049 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
19050 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19051 "TARGET_MMX"
19052 "pslld\t{%2, %0|%0, %2}"
19053 [(set_attr "type" "mmx")])
19054
19055;; See logical MMX insns.
19056(define_insn "mmx_ashldi3"
19057 [(set (match_operand:DI 0 "register_operand" "=y")
19058 (unspec:DI
19059 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
19060 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
19061 "TARGET_MMX"
19062 "psllq\t{%2, %0|%0, %2}"
19063 [(set_attr "type" "mmx")])
19064
19065
19066;; MMX pack/unpack insns.
19067
19068(define_insn "mmx_packsswb"
19069 [(set (match_operand:V8QI 0 "register_operand" "=y")
19070 (vec_concat:V8QI
19071 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19072 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19073 "TARGET_MMX"
19074 "packsswb\t{%2, %0|%0, %2}"
19075 [(set_attr "type" "mmx")])
19076
19077(define_insn "mmx_packssdw"
19078 [(set (match_operand:V4HI 0 "register_operand" "=y")
19079 (vec_concat:V4HI
19080 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
19081 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
19082 "TARGET_MMX"
19083 "packssdw\t{%2, %0|%0, %2}"
19084 [(set_attr "type" "mmx")])
19085
19086(define_insn "mmx_packuswb"
19087 [(set (match_operand:V8QI 0 "register_operand" "=y")
19088 (vec_concat:V8QI
19089 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19090 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19091 "TARGET_MMX"
19092 "packuswb\t{%2, %0|%0, %2}"
19093 [(set_attr "type" "mmx")])
19094
19095(define_insn "mmx_punpckhbw"
19096 [(set (match_operand:V8QI 0 "register_operand" "=y")
19097 (vec_merge:V8QI
19098 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19099 (parallel [(const_int 4)
19100 (const_int 0)
19101 (const_int 5)
19102 (const_int 1)
19103 (const_int 6)
19104 (const_int 2)
19105 (const_int 7)
19106 (const_int 3)]))
19107 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19108 (parallel [(const_int 0)
19109 (const_int 4)
19110 (const_int 1)
19111 (const_int 5)
19112 (const_int 2)
19113 (const_int 6)
19114 (const_int 3)
19115 (const_int 7)]))
19116 (const_int 85)))]
19117 "TARGET_MMX"
19118 "punpckhbw\t{%2, %0|%0, %2}"
19119 [(set_attr "type" "mmx")])
19120
19121(define_insn "mmx_punpckhwd"
19122 [(set (match_operand:V4HI 0 "register_operand" "=y")
19123 (vec_merge:V4HI
19124 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19125 (parallel [(const_int 0)
19126 (const_int 2)
19127 (const_int 1)
19128 (const_int 3)]))
19129 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19130 (parallel [(const_int 2)
19131 (const_int 0)
19132 (const_int 3)
19133 (const_int 1)]))
19134 (const_int 5)))]
19135 "TARGET_MMX"
19136 "punpckhwd\t{%2, %0|%0, %2}"
19137 [(set_attr "type" "mmx")])
19138
19139(define_insn "mmx_punpckhdq"
19140 [(set (match_operand:V2SI 0 "register_operand" "=y")
19141 (vec_merge:V2SI
19142 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19143 (parallel [(const_int 0)
19144 (const_int 1)]))
19145 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19146 (parallel [(const_int 1)
19147 (const_int 0)]))
19148 (const_int 1)))]
19149 "TARGET_MMX"
19150 "punpckhdq\t{%2, %0|%0, %2}"
19151 [(set_attr "type" "mmx")])
19152
19153(define_insn "mmx_punpcklbw"
19154 [(set (match_operand:V8QI 0 "register_operand" "=y")
19155 (vec_merge:V8QI
19156 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19157 (parallel [(const_int 0)
19158 (const_int 4)
19159 (const_int 1)
19160 (const_int 5)
19161 (const_int 2)
19162 (const_int 6)
19163 (const_int 3)
19164 (const_int 7)]))
19165 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19166 (parallel [(const_int 4)
19167 (const_int 0)
19168 (const_int 5)
19169 (const_int 1)
19170 (const_int 6)
19171 (const_int 2)
19172 (const_int 7)
19173 (const_int 3)]))
19174 (const_int 85)))]
19175 "TARGET_MMX"
19176 "punpcklbw\t{%2, %0|%0, %2}"
19177 [(set_attr "type" "mmx")])
19178
19179(define_insn "mmx_punpcklwd"
19180 [(set (match_operand:V4HI 0 "register_operand" "=y")
19181 (vec_merge:V4HI
19182 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19183 (parallel [(const_int 2)
19184 (const_int 0)
19185 (const_int 3)
19186 (const_int 1)]))
19187 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19188 (parallel [(const_int 0)
19189 (const_int 2)
19190 (const_int 1)
19191 (const_int 3)]))
19192 (const_int 5)))]
19193 "TARGET_MMX"
19194 "punpcklwd\t{%2, %0|%0, %2}"
19195 [(set_attr "type" "mmx")])
19196
19197(define_insn "mmx_punpckldq"
19198 [(set (match_operand:V2SI 0 "register_operand" "=y")
19199 (vec_merge:V2SI
19200 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19201 (parallel [(const_int 1)
19202 (const_int 0)]))
19203 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19204 (parallel [(const_int 0)
19205 (const_int 1)]))
19206 (const_int 1)))]
19207 "TARGET_MMX"
19208 "punpckldq\t{%2, %0|%0, %2}"
19209 [(set_attr "type" "mmx")])
19210
19211
19212;; Miscellaneous stuff
19213
19214(define_insn "emms"
19215 [(unspec_volatile [(const_int 0)] 31)
19216 (clobber (reg:XF 8))
19217 (clobber (reg:XF 9))
19218 (clobber (reg:XF 10))
19219 (clobber (reg:XF 11))
19220 (clobber (reg:XF 12))
19221 (clobber (reg:XF 13))
19222 (clobber (reg:XF 14))
19223 (clobber (reg:XF 15))
19224 (clobber (reg:DI 29))
19225 (clobber (reg:DI 30))
19226 (clobber (reg:DI 31))
19227 (clobber (reg:DI 32))
19228 (clobber (reg:DI 33))
19229 (clobber (reg:DI 34))
19230 (clobber (reg:DI 35))
19231 (clobber (reg:DI 36))]
19232 "TARGET_MMX"
19233 "emms"
19234 [(set_attr "type" "mmx")
19235 (set_attr "memory" "unknown")])
19236
19237(define_insn "ldmxcsr"
19238 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
19239 "TARGET_MMX"
19240 "ldmxcsr\t%0"
19241 [(set_attr "type" "mmx")
19242 (set_attr "memory" "load")])
19243
19244(define_insn "stmxcsr"
19245 [(set (match_operand:SI 0 "memory_operand" "=m")
19246 (unspec_volatile:SI [(const_int 0)] 40))]
19247 "TARGET_MMX"
19248 "stmxcsr\t%0"
19249 [(set_attr "type" "mmx")
19250 (set_attr "memory" "store")])
19251
19252(define_expand "sfence"
19253 [(set (match_dup 0)
19254 (unspec:BLK [(match_dup 0)] 44))]
19255 "TARGET_SSE || TARGET_3DNOW_A"
19256{
19257 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19258 MEM_VOLATILE_P (operands[0]) = 1;
19259})
19260
19261(define_insn "*sfence_insn"
19262 [(set (match_operand:BLK 0 "" "")
19263 (unspec:BLK [(match_dup 0)] 44))]
19264 "TARGET_SSE || TARGET_3DNOW_A"
19265 "sfence"
19266 [(set_attr "type" "sse")
19267 (set_attr "memory" "unknown")])
19268
19269(define_expand "sse_prologue_save"
19270 [(parallel [(set (match_operand:BLK 0 "" "")
19271 (unspec:BLK [(reg:DI 21)
19272 (reg:DI 22)
19273 (reg:DI 23)
19274 (reg:DI 24)
19275 (reg:DI 25)
19276 (reg:DI 26)
19277 (reg:DI 27)
19278 (reg:DI 28)] 13))
19279 (use (match_operand:DI 1 "register_operand" ""))
19280 (use (match_operand:DI 2 "immediate_operand" ""))
19281 (use (label_ref:DI (match_operand 3 "" "")))])]
19282 "TARGET_64BIT"
19283 "")
19284
19285(define_insn "*sse_prologue_save_insn"
19286 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19287 (match_operand:DI 4 "const_int_operand" "n")))
19288 (unspec:BLK [(reg:DI 21)
19289 (reg:DI 22)
19290 (reg:DI 23)
19291 (reg:DI 24)
19292 (reg:DI 25)
19293 (reg:DI 26)
19294 (reg:DI 27)
19295 (reg:DI 28)] 13))
19296 (use (match_operand:DI 1 "register_operand" "r"))
19297 (use (match_operand:DI 2 "const_int_operand" "i"))
19298 (use (label_ref:DI (match_operand 3 "" "X")))]
19299 "TARGET_64BIT
19300 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19301 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19302 "*
19303{
19304 int i;
19305 operands[0] = gen_rtx_MEM (Pmode,
19306 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19307 output_asm_insn (\"jmp\\t%A1\", operands);
19308 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19309 {
19310 operands[4] = adjust_address (operands[0], DImode, i*16);
19311 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19312 PUT_MODE (operands[4], TImode);
19313 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19314 output_asm_insn (\"rex\", operands);
19315 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19316 }
19317 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
19318 CODE_LABEL_NUMBER (operands[3]));
19319 RET;
19320}
19321 "
19322 [(set_attr "type" "other")
19323 (set_attr "length_immediate" "0")
19324 (set_attr "length_address" "0")
19325 (set_attr "length" "135")
19326 (set_attr "memory" "store")
19327 (set_attr "modrm" "0")
19328 (set_attr "mode" "DI")])
19329
19330;; 3Dnow! instructions
19331
19332(define_insn "addv2sf3"
19333 [(set (match_operand:V2SF 0 "register_operand" "=y")
19334 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19335 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19336 "TARGET_3DNOW"
19337 "pfadd\\t{%2, %0|%0, %2}"
19338 [(set_attr "type" "mmx")])
19339
19340(define_insn "subv2sf3"
19341 [(set (match_operand:V2SF 0 "register_operand" "=y")
19342 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19343 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19344 "TARGET_3DNOW"
19345 "pfsub\\t{%2, %0|%0, %2}"
19346 [(set_attr "type" "mmx")])
19347
19348(define_insn "subrv2sf3"
19349 [(set (match_operand:V2SF 0 "register_operand" "=y")
19350 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
19351 (match_operand:V2SF 1 "register_operand" "0")))]
19352 "TARGET_3DNOW"
19353 "pfsubr\\t{%2, %0|%0, %2}"
19354 [(set_attr "type" "mmx")])
19355
19356(define_insn "gtv2sf3"
19357 [(set (match_operand:V2SI 0 "register_operand" "=y")
19358 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
19359 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19360 "TARGET_3DNOW"
19361 "pfcmpgt\\t{%2, %0|%0, %2}"
19362 [(set_attr "type" "mmx")])
19363
19364(define_insn "gev2sf3"
19365 [(set (match_operand:V2SI 0 "register_operand" "=y")
19366 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
19367 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19368 "TARGET_3DNOW"
19369 "pfcmpge\\t{%2, %0|%0, %2}"
19370 [(set_attr "type" "mmx")])
19371
19372(define_insn "eqv2sf3"
19373 [(set (match_operand:V2SI 0 "register_operand" "=y")
19374 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
19375 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19376 "TARGET_3DNOW"
19377 "pfcmpeq\\t{%2, %0|%0, %2}"
19378 [(set_attr "type" "mmx")])
19379
19380(define_insn "pfmaxv2sf3"
19381 [(set (match_operand:V2SF 0 "register_operand" "=y")
19382 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
19383 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19384 "TARGET_3DNOW"
19385 "pfmax\\t{%2, %0|%0, %2}"
19386 [(set_attr "type" "mmx")])
19387
19388(define_insn "pfminv2sf3"
19389 [(set (match_operand:V2SF 0 "register_operand" "=y")
19390 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
19391 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19392 "TARGET_3DNOW"
19393 "pfmin\\t{%2, %0|%0, %2}"
19394 [(set_attr "type" "mmx")])
19395
19396(define_insn "mulv2sf3"
19397 [(set (match_operand:V2SF 0 "register_operand" "=y")
19398 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
19399 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19400 "TARGET_3DNOW"
19401 "pfmul\\t{%2, %0|%0, %2}"
19402 [(set_attr "type" "mmx")])
19403
19404(define_insn "femms"
19405 [(unspec_volatile [(const_int 0)] 46)
19406 (clobber (reg:XF 8))
19407 (clobber (reg:XF 9))
19408 (clobber (reg:XF 10))
19409 (clobber (reg:XF 11))
19410 (clobber (reg:XF 12))
19411 (clobber (reg:XF 13))
19412 (clobber (reg:XF 14))
19413 (clobber (reg:XF 15))
19414 (clobber (reg:DI 29))
19415 (clobber (reg:DI 30))
19416 (clobber (reg:DI 31))
19417 (clobber (reg:DI 32))
19418 (clobber (reg:DI 33))
19419 (clobber (reg:DI 34))
19420 (clobber (reg:DI 35))
19421 (clobber (reg:DI 36))]
19422 "TARGET_3DNOW"
19423 "femms"
19424 [(set_attr "type" "mmx")])
19425
19426(define_insn "pf2id"
19427 [(set (match_operand:V2SI 0 "register_operand" "=y")
19428 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
19429 "TARGET_3DNOW"
19430 "pf2id\\t{%1, %0|%0, %1}"
19431 [(set_attr "type" "mmx")])
19432
19433(define_insn "pf2iw"
19434 [(set (match_operand:V2SI 0 "register_operand" "=y")
19435 (sign_extend:V2SI
19436 (ss_truncate:V2HI
19437 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
19438 "TARGET_3DNOW_A"
19439 "pf2iw\\t{%1, %0|%0, %1}"
19440 [(set_attr "type" "mmx")])
19441
19442(define_insn "pfacc"
19443 [(set (match_operand:V2SF 0 "register_operand" "=y")
19444 (vec_concat:V2SF
19445 (plus:SF
19446 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19447 (parallel [(const_int 0)]))
19448 (vec_select:SF (match_dup 1)
19449 (parallel [(const_int 1)])))
19450 (plus:SF
19451 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19452 (parallel [(const_int 0)]))
19453 (vec_select:SF (match_dup 2)
19454 (parallel [(const_int 1)])))))]
19455 "TARGET_3DNOW"
19456 "pfacc\\t{%2, %0|%0, %2}"
19457 [(set_attr "type" "mmx")])
19458
19459(define_insn "pfnacc"
19460 [(set (match_operand:V2SF 0 "register_operand" "=y")
19461 (vec_concat:V2SF
19462 (minus:SF
19463 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19464 (parallel [(const_int 0)]))
19465 (vec_select:SF (match_dup 1)
19466 (parallel [(const_int 1)])))
19467 (minus:SF
19468 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19469 (parallel [(const_int 0)]))
19470 (vec_select:SF (match_dup 2)
19471 (parallel [(const_int 1)])))))]
19472 "TARGET_3DNOW_A"
19473 "pfnacc\\t{%2, %0|%0, %2}"
19474 [(set_attr "type" "mmx")])
19475
19476(define_insn "pfpnacc"
19477 [(set (match_operand:V2SF 0 "register_operand" "=y")
19478 (vec_concat:V2SF
19479 (minus:SF
19480 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19481 (parallel [(const_int 0)]))
19482 (vec_select:SF (match_dup 1)
19483 (parallel [(const_int 1)])))
19484 (plus:SF
19485 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19486 (parallel [(const_int 0)]))
19487 (vec_select:SF (match_dup 2)
19488 (parallel [(const_int 1)])))))]
19489 "TARGET_3DNOW_A"
19490 "pfpnacc\\t{%2, %0|%0, %2}"
19491 [(set_attr "type" "mmx")])
19492
19493(define_insn "pi2fw"
19494 [(set (match_operand:V2SF 0 "register_operand" "=y")
19495 (float:V2SF
19496 (vec_concat:V2SI
19497 (sign_extend:SI
19498 (truncate:HI
19499 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19500 (parallel [(const_int 0)]))))
19501 (sign_extend:SI
19502 (truncate:HI
19503 (vec_select:SI (match_dup 1)
19504 (parallel [(const_int 1)])))))))]
19505 "TARGET_3DNOW_A"
19506 "pi2fw\\t{%1, %0|%0, %1}"
19507 [(set_attr "type" "mmx")])
19508
19509(define_insn "floatv2si2"
19510 [(set (match_operand:V2SF 0 "register_operand" "=y")
19511 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
19512 "TARGET_3DNOW"
19513 "pi2fd\\t{%1, %0|%0, %1}"
19514 [(set_attr "type" "mmx")])
19515
19516;; This insn is identical to pavgb in operation, but the opcode is
19517;; different. To avoid accidentally matching pavgb, use an unspec.
19518
19519(define_insn "pavgusb"
19520 [(set (match_operand:V8QI 0 "register_operand" "=y")
19521 (unspec:V8QI
19522 [(match_operand:V8QI 1 "register_operand" "0")
19523 (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
19524 "TARGET_3DNOW"
19525 "pavgusb\\t{%2, %0|%0, %2}"
19526 [(set_attr "type" "mmx")])
19527
19528;; 3DNow reciprical and sqrt
19529
19530(define_insn "pfrcpv2sf2"
19531 [(set (match_operand:V2SF 0 "register_operand" "=y")
19532 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
19533 "TARGET_3DNOW"
19534 "pfrcp\\t{%1, %0|%0, %1}"
19535 [(set_attr "type" "mmx")])
19536
19537(define_insn "pfrcpit1v2sf3"
19538 [(set (match_operand:V2SF 0 "register_operand" "=y")
19539 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19540 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
19541 "TARGET_3DNOW"
19542 "pfrcpit1\\t{%2, %0|%0, %2}"
19543 [(set_attr "type" "mmx")])
19544
19545(define_insn "pfrcpit2v2sf3"
19546 [(set (match_operand:V2SF 0 "register_operand" "=y")
19547 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19548 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
19549 "TARGET_3DNOW"
19550 "pfrcpit2\\t{%2, %0|%0, %2}"
19551 [(set_attr "type" "mmx")])
19552
19553(define_insn "pfrsqrtv2sf2"
19554 [(set (match_operand:V2SF 0 "register_operand" "=y")
19555 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
19556 "TARGET_3DNOW"
19557 "pfrsqrt\\t{%1, %0|%0, %1}"
19558 [(set_attr "type" "mmx")])
19559
19560(define_insn "pfrsqit1v2sf3"
19561 [(set (match_operand:V2SF 0 "register_operand" "=y")
19562 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19563 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
19564 "TARGET_3DNOW"
19565 "pfrsqit1\\t{%2, %0|%0, %2}"
19566 [(set_attr "type" "mmx")])
19567
19568(define_insn "pmulhrwv4hi3"
19569 [(set (match_operand:V4HI 0 "register_operand" "=y")
19570 (truncate:V4HI
19571 (lshiftrt:V4SI
19572 (plus:V4SI
19573 (mult:V4SI
19574 (sign_extend:V4SI
19575 (match_operand:V4HI 1 "register_operand" "0"))
19576 (sign_extend:V4SI
19577 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19045 (const_int 1)))]
19046 "TARGET_SSE || TARGET_3DNOW_A"
19047 "pavgw\t{%2, %0|%0, %2}"
19048 [(set_attr "type" "sse")])
19049
19050(define_insn "mmx_psadbw"
19051 [(set (match_operand:V8QI 0 "register_operand" "=y")
19052 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19053 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
19054 "TARGET_SSE || TARGET_3DNOW_A"
19055 "psadbw\t{%2, %0|%0, %2}"
19056 [(set_attr "type" "sse")])
19057
19058
19059;; MMX insert/extract/shuffle
19060
19061(define_insn "mmx_pinsrw"
19062 [(set (match_operand:V4HI 0 "register_operand" "=y")
19063 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
19064 (vec_duplicate:V4HI
19065 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
19066 (match_operand:SI 3 "immediate_operand" "i")))]
19067 "TARGET_SSE || TARGET_3DNOW_A"
19068 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
19069 [(set_attr "type" "sse")])
19070
19071(define_insn "mmx_pextrw"
19072 [(set (match_operand:SI 0 "register_operand" "=r")
19073 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
19074 (parallel
19075 [(match_operand:SI 2 "immediate_operand" "i")]))))]
19076 "TARGET_SSE || TARGET_3DNOW_A"
19077 "pextrw\t{%2, %1, %0|%0, %1, %2}"
19078 [(set_attr "type" "sse")])
19079
19080(define_insn "mmx_pshufw"
19081 [(set (match_operand:V4HI 0 "register_operand" "=y")
19082 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
19083 (match_operand:SI 2 "immediate_operand" "i")] 41))]
19084 "TARGET_SSE || TARGET_3DNOW_A"
19085 "pshufw\t{%2, %1, %0|%0, %1, %2}"
19086 [(set_attr "type" "sse")])
19087
19088
19089;; MMX mask-generating comparisons
19090
19091(define_insn "eqv8qi3"
19092 [(set (match_operand:V8QI 0 "register_operand" "=y")
19093 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
19094 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19095 "TARGET_MMX"
19096 "pcmpeqb\t{%2, %0|%0, %2}"
19097 [(set_attr "type" "mmx")])
19098
19099(define_insn "eqv4hi3"
19100 [(set (match_operand:V4HI 0 "register_operand" "=y")
19101 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
19102 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19103 "TARGET_MMX"
19104 "pcmpeqw\t{%2, %0|%0, %2}"
19105 [(set_attr "type" "mmx")])
19106
19107(define_insn "eqv2si3"
19108 [(set (match_operand:V2SI 0 "register_operand" "=y")
19109 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
19110 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19111 "TARGET_MMX"
19112 "pcmpeqd\t{%2, %0|%0, %2}"
19113 [(set_attr "type" "mmx")])
19114
19115(define_insn "gtv8qi3"
19116 [(set (match_operand:V8QI 0 "register_operand" "=y")
19117 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
19118 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19119 "TARGET_MMX"
19120 "pcmpgtb\t{%2, %0|%0, %2}"
19121 [(set_attr "type" "mmx")])
19122
19123(define_insn "gtv4hi3"
19124 [(set (match_operand:V4HI 0 "register_operand" "=y")
19125 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19126 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19127 "TARGET_MMX"
19128 "pcmpgtw\t{%2, %0|%0, %2}"
19129 [(set_attr "type" "mmx")])
19130
19131(define_insn "gtv2si3"
19132 [(set (match_operand:V2SI 0 "register_operand" "=y")
19133 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19134 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19135 "TARGET_MMX"
19136 "pcmpgtd\t{%2, %0|%0, %2}"
19137 [(set_attr "type" "mmx")])
19138
19139
19140;; MMX max/min insns
19141
19142(define_insn "umaxv8qi3"
19143 [(set (match_operand:V8QI 0 "register_operand" "=y")
19144 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
19145 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19146 "TARGET_SSE || TARGET_3DNOW_A"
19147 "pmaxub\t{%2, %0|%0, %2}"
19148 [(set_attr "type" "sse")])
19149
19150(define_insn "smaxv4hi3"
19151 [(set (match_operand:V4HI 0 "register_operand" "=y")
19152 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
19153 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19154 "TARGET_SSE || TARGET_3DNOW_A"
19155 "pmaxsw\t{%2, %0|%0, %2}"
19156 [(set_attr "type" "sse")])
19157
19158(define_insn "uminv8qi3"
19159 [(set (match_operand:V8QI 0 "register_operand" "=y")
19160 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
19161 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19162 "TARGET_SSE || TARGET_3DNOW_A"
19163 "pminub\t{%2, %0|%0, %2}"
19164 [(set_attr "type" "sse")])
19165
19166(define_insn "sminv4hi3"
19167 [(set (match_operand:V4HI 0 "register_operand" "=y")
19168 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
19169 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19170 "TARGET_SSE || TARGET_3DNOW_A"
19171 "pminsw\t{%2, %0|%0, %2}"
19172 [(set_attr "type" "sse")])
19173
19174
19175;; MMX shifts
19176
19177(define_insn "ashrv4hi3"
19178 [(set (match_operand:V4HI 0 "register_operand" "=y")
19179 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19180 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19181 "TARGET_MMX"
19182 "psraw\t{%2, %0|%0, %2}"
19183 [(set_attr "type" "mmx")])
19184
19185(define_insn "ashrv2si3"
19186 [(set (match_operand:V2SI 0 "register_operand" "=y")
19187 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19188 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19189 "TARGET_MMX"
19190 "psrad\t{%2, %0|%0, %2}"
19191 [(set_attr "type" "mmx")])
19192
19193(define_insn "lshrv4hi3"
19194 [(set (match_operand:V4HI 0 "register_operand" "=y")
19195 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19196 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19197 "TARGET_MMX"
19198 "psrlw\t{%2, %0|%0, %2}"
19199 [(set_attr "type" "mmx")])
19200
19201(define_insn "lshrv2si3"
19202 [(set (match_operand:V2SI 0 "register_operand" "=y")
19203 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19204 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19205 "TARGET_MMX"
19206 "psrld\t{%2, %0|%0, %2}"
19207 [(set_attr "type" "mmx")])
19208
19209;; See logical MMX insns.
19210(define_insn "mmx_lshrdi3"
19211 [(set (match_operand:DI 0 "register_operand" "=y")
19212 (unspec:DI
19213 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
19214 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
19215 "TARGET_MMX"
19216 "psrlq\t{%2, %0|%0, %2}"
19217 [(set_attr "type" "mmx")])
19218
19219(define_insn "ashlv4hi3"
19220 [(set (match_operand:V4HI 0 "register_operand" "=y")
19221 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
19222 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19223 "TARGET_MMX"
19224 "psllw\t{%2, %0|%0, %2}"
19225 [(set_attr "type" "mmx")])
19226
19227(define_insn "ashlv2si3"
19228 [(set (match_operand:V2SI 0 "register_operand" "=y")
19229 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
19230 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19231 "TARGET_MMX"
19232 "pslld\t{%2, %0|%0, %2}"
19233 [(set_attr "type" "mmx")])
19234
19235;; See logical MMX insns.
19236(define_insn "mmx_ashldi3"
19237 [(set (match_operand:DI 0 "register_operand" "=y")
19238 (unspec:DI
19239 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
19240 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
19241 "TARGET_MMX"
19242 "psllq\t{%2, %0|%0, %2}"
19243 [(set_attr "type" "mmx")])
19244
19245
19246;; MMX pack/unpack insns.
19247
19248(define_insn "mmx_packsswb"
19249 [(set (match_operand:V8QI 0 "register_operand" "=y")
19250 (vec_concat:V8QI
19251 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19252 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19253 "TARGET_MMX"
19254 "packsswb\t{%2, %0|%0, %2}"
19255 [(set_attr "type" "mmx")])
19256
19257(define_insn "mmx_packssdw"
19258 [(set (match_operand:V4HI 0 "register_operand" "=y")
19259 (vec_concat:V4HI
19260 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
19261 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
19262 "TARGET_MMX"
19263 "packssdw\t{%2, %0|%0, %2}"
19264 [(set_attr "type" "mmx")])
19265
19266(define_insn "mmx_packuswb"
19267 [(set (match_operand:V8QI 0 "register_operand" "=y")
19268 (vec_concat:V8QI
19269 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19270 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19271 "TARGET_MMX"
19272 "packuswb\t{%2, %0|%0, %2}"
19273 [(set_attr "type" "mmx")])
19274
19275(define_insn "mmx_punpckhbw"
19276 [(set (match_operand:V8QI 0 "register_operand" "=y")
19277 (vec_merge:V8QI
19278 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19279 (parallel [(const_int 4)
19280 (const_int 0)
19281 (const_int 5)
19282 (const_int 1)
19283 (const_int 6)
19284 (const_int 2)
19285 (const_int 7)
19286 (const_int 3)]))
19287 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19288 (parallel [(const_int 0)
19289 (const_int 4)
19290 (const_int 1)
19291 (const_int 5)
19292 (const_int 2)
19293 (const_int 6)
19294 (const_int 3)
19295 (const_int 7)]))
19296 (const_int 85)))]
19297 "TARGET_MMX"
19298 "punpckhbw\t{%2, %0|%0, %2}"
19299 [(set_attr "type" "mmx")])
19300
19301(define_insn "mmx_punpckhwd"
19302 [(set (match_operand:V4HI 0 "register_operand" "=y")
19303 (vec_merge:V4HI
19304 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19305 (parallel [(const_int 0)
19306 (const_int 2)
19307 (const_int 1)
19308 (const_int 3)]))
19309 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19310 (parallel [(const_int 2)
19311 (const_int 0)
19312 (const_int 3)
19313 (const_int 1)]))
19314 (const_int 5)))]
19315 "TARGET_MMX"
19316 "punpckhwd\t{%2, %0|%0, %2}"
19317 [(set_attr "type" "mmx")])
19318
19319(define_insn "mmx_punpckhdq"
19320 [(set (match_operand:V2SI 0 "register_operand" "=y")
19321 (vec_merge:V2SI
19322 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19323 (parallel [(const_int 0)
19324 (const_int 1)]))
19325 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19326 (parallel [(const_int 1)
19327 (const_int 0)]))
19328 (const_int 1)))]
19329 "TARGET_MMX"
19330 "punpckhdq\t{%2, %0|%0, %2}"
19331 [(set_attr "type" "mmx")])
19332
19333(define_insn "mmx_punpcklbw"
19334 [(set (match_operand:V8QI 0 "register_operand" "=y")
19335 (vec_merge:V8QI
19336 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19337 (parallel [(const_int 0)
19338 (const_int 4)
19339 (const_int 1)
19340 (const_int 5)
19341 (const_int 2)
19342 (const_int 6)
19343 (const_int 3)
19344 (const_int 7)]))
19345 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19346 (parallel [(const_int 4)
19347 (const_int 0)
19348 (const_int 5)
19349 (const_int 1)
19350 (const_int 6)
19351 (const_int 2)
19352 (const_int 7)
19353 (const_int 3)]))
19354 (const_int 85)))]
19355 "TARGET_MMX"
19356 "punpcklbw\t{%2, %0|%0, %2}"
19357 [(set_attr "type" "mmx")])
19358
19359(define_insn "mmx_punpcklwd"
19360 [(set (match_operand:V4HI 0 "register_operand" "=y")
19361 (vec_merge:V4HI
19362 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19363 (parallel [(const_int 2)
19364 (const_int 0)
19365 (const_int 3)
19366 (const_int 1)]))
19367 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19368 (parallel [(const_int 0)
19369 (const_int 2)
19370 (const_int 1)
19371 (const_int 3)]))
19372 (const_int 5)))]
19373 "TARGET_MMX"
19374 "punpcklwd\t{%2, %0|%0, %2}"
19375 [(set_attr "type" "mmx")])
19376
19377(define_insn "mmx_punpckldq"
19378 [(set (match_operand:V2SI 0 "register_operand" "=y")
19379 (vec_merge:V2SI
19380 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19381 (parallel [(const_int 1)
19382 (const_int 0)]))
19383 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19384 (parallel [(const_int 0)
19385 (const_int 1)]))
19386 (const_int 1)))]
19387 "TARGET_MMX"
19388 "punpckldq\t{%2, %0|%0, %2}"
19389 [(set_attr "type" "mmx")])
19390
19391
19392;; Miscellaneous stuff
19393
19394(define_insn "emms"
19395 [(unspec_volatile [(const_int 0)] 31)
19396 (clobber (reg:XF 8))
19397 (clobber (reg:XF 9))
19398 (clobber (reg:XF 10))
19399 (clobber (reg:XF 11))
19400 (clobber (reg:XF 12))
19401 (clobber (reg:XF 13))
19402 (clobber (reg:XF 14))
19403 (clobber (reg:XF 15))
19404 (clobber (reg:DI 29))
19405 (clobber (reg:DI 30))
19406 (clobber (reg:DI 31))
19407 (clobber (reg:DI 32))
19408 (clobber (reg:DI 33))
19409 (clobber (reg:DI 34))
19410 (clobber (reg:DI 35))
19411 (clobber (reg:DI 36))]
19412 "TARGET_MMX"
19413 "emms"
19414 [(set_attr "type" "mmx")
19415 (set_attr "memory" "unknown")])
19416
19417(define_insn "ldmxcsr"
19418 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
19419 "TARGET_MMX"
19420 "ldmxcsr\t%0"
19421 [(set_attr "type" "mmx")
19422 (set_attr "memory" "load")])
19423
19424(define_insn "stmxcsr"
19425 [(set (match_operand:SI 0 "memory_operand" "=m")
19426 (unspec_volatile:SI [(const_int 0)] 40))]
19427 "TARGET_MMX"
19428 "stmxcsr\t%0"
19429 [(set_attr "type" "mmx")
19430 (set_attr "memory" "store")])
19431
19432(define_expand "sfence"
19433 [(set (match_dup 0)
19434 (unspec:BLK [(match_dup 0)] 44))]
19435 "TARGET_SSE || TARGET_3DNOW_A"
19436{
19437 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19438 MEM_VOLATILE_P (operands[0]) = 1;
19439})
19440
19441(define_insn "*sfence_insn"
19442 [(set (match_operand:BLK 0 "" "")
19443 (unspec:BLK [(match_dup 0)] 44))]
19444 "TARGET_SSE || TARGET_3DNOW_A"
19445 "sfence"
19446 [(set_attr "type" "sse")
19447 (set_attr "memory" "unknown")])
19448
19449(define_expand "sse_prologue_save"
19450 [(parallel [(set (match_operand:BLK 0 "" "")
19451 (unspec:BLK [(reg:DI 21)
19452 (reg:DI 22)
19453 (reg:DI 23)
19454 (reg:DI 24)
19455 (reg:DI 25)
19456 (reg:DI 26)
19457 (reg:DI 27)
19458 (reg:DI 28)] 13))
19459 (use (match_operand:DI 1 "register_operand" ""))
19460 (use (match_operand:DI 2 "immediate_operand" ""))
19461 (use (label_ref:DI (match_operand 3 "" "")))])]
19462 "TARGET_64BIT"
19463 "")
19464
19465(define_insn "*sse_prologue_save_insn"
19466 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19467 (match_operand:DI 4 "const_int_operand" "n")))
19468 (unspec:BLK [(reg:DI 21)
19469 (reg:DI 22)
19470 (reg:DI 23)
19471 (reg:DI 24)
19472 (reg:DI 25)
19473 (reg:DI 26)
19474 (reg:DI 27)
19475 (reg:DI 28)] 13))
19476 (use (match_operand:DI 1 "register_operand" "r"))
19477 (use (match_operand:DI 2 "const_int_operand" "i"))
19478 (use (label_ref:DI (match_operand 3 "" "X")))]
19479 "TARGET_64BIT
19480 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19481 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19482 "*
19483{
19484 int i;
19485 operands[0] = gen_rtx_MEM (Pmode,
19486 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19487 output_asm_insn (\"jmp\\t%A1\", operands);
19488 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19489 {
19490 operands[4] = adjust_address (operands[0], DImode, i*16);
19491 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19492 PUT_MODE (operands[4], TImode);
19493 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19494 output_asm_insn (\"rex\", operands);
19495 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19496 }
19497 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
19498 CODE_LABEL_NUMBER (operands[3]));
19499 RET;
19500}
19501 "
19502 [(set_attr "type" "other")
19503 (set_attr "length_immediate" "0")
19504 (set_attr "length_address" "0")
19505 (set_attr "length" "135")
19506 (set_attr "memory" "store")
19507 (set_attr "modrm" "0")
19508 (set_attr "mode" "DI")])
19509
19510;; 3Dnow! instructions
19511
19512(define_insn "addv2sf3"
19513 [(set (match_operand:V2SF 0 "register_operand" "=y")
19514 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19515 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19516 "TARGET_3DNOW"
19517 "pfadd\\t{%2, %0|%0, %2}"
19518 [(set_attr "type" "mmx")])
19519
19520(define_insn "subv2sf3"
19521 [(set (match_operand:V2SF 0 "register_operand" "=y")
19522 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19523 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19524 "TARGET_3DNOW"
19525 "pfsub\\t{%2, %0|%0, %2}"
19526 [(set_attr "type" "mmx")])
19527
19528(define_insn "subrv2sf3"
19529 [(set (match_operand:V2SF 0 "register_operand" "=y")
19530 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
19531 (match_operand:V2SF 1 "register_operand" "0")))]
19532 "TARGET_3DNOW"
19533 "pfsubr\\t{%2, %0|%0, %2}"
19534 [(set_attr "type" "mmx")])
19535
19536(define_insn "gtv2sf3"
19537 [(set (match_operand:V2SI 0 "register_operand" "=y")
19538 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
19539 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19540 "TARGET_3DNOW"
19541 "pfcmpgt\\t{%2, %0|%0, %2}"
19542 [(set_attr "type" "mmx")])
19543
19544(define_insn "gev2sf3"
19545 [(set (match_operand:V2SI 0 "register_operand" "=y")
19546 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
19547 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19548 "TARGET_3DNOW"
19549 "pfcmpge\\t{%2, %0|%0, %2}"
19550 [(set_attr "type" "mmx")])
19551
19552(define_insn "eqv2sf3"
19553 [(set (match_operand:V2SI 0 "register_operand" "=y")
19554 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
19555 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19556 "TARGET_3DNOW"
19557 "pfcmpeq\\t{%2, %0|%0, %2}"
19558 [(set_attr "type" "mmx")])
19559
19560(define_insn "pfmaxv2sf3"
19561 [(set (match_operand:V2SF 0 "register_operand" "=y")
19562 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
19563 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19564 "TARGET_3DNOW"
19565 "pfmax\\t{%2, %0|%0, %2}"
19566 [(set_attr "type" "mmx")])
19567
19568(define_insn "pfminv2sf3"
19569 [(set (match_operand:V2SF 0 "register_operand" "=y")
19570 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
19571 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19572 "TARGET_3DNOW"
19573 "pfmin\\t{%2, %0|%0, %2}"
19574 [(set_attr "type" "mmx")])
19575
19576(define_insn "mulv2sf3"
19577 [(set (match_operand:V2SF 0 "register_operand" "=y")
19578 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
19579 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19580 "TARGET_3DNOW"
19581 "pfmul\\t{%2, %0|%0, %2}"
19582 [(set_attr "type" "mmx")])
19583
19584(define_insn "femms"
19585 [(unspec_volatile [(const_int 0)] 46)
19586 (clobber (reg:XF 8))
19587 (clobber (reg:XF 9))
19588 (clobber (reg:XF 10))
19589 (clobber (reg:XF 11))
19590 (clobber (reg:XF 12))
19591 (clobber (reg:XF 13))
19592 (clobber (reg:XF 14))
19593 (clobber (reg:XF 15))
19594 (clobber (reg:DI 29))
19595 (clobber (reg:DI 30))
19596 (clobber (reg:DI 31))
19597 (clobber (reg:DI 32))
19598 (clobber (reg:DI 33))
19599 (clobber (reg:DI 34))
19600 (clobber (reg:DI 35))
19601 (clobber (reg:DI 36))]
19602 "TARGET_3DNOW"
19603 "femms"
19604 [(set_attr "type" "mmx")])
19605
19606(define_insn "pf2id"
19607 [(set (match_operand:V2SI 0 "register_operand" "=y")
19608 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
19609 "TARGET_3DNOW"
19610 "pf2id\\t{%1, %0|%0, %1}"
19611 [(set_attr "type" "mmx")])
19612
19613(define_insn "pf2iw"
19614 [(set (match_operand:V2SI 0 "register_operand" "=y")
19615 (sign_extend:V2SI
19616 (ss_truncate:V2HI
19617 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
19618 "TARGET_3DNOW_A"
19619 "pf2iw\\t{%1, %0|%0, %1}"
19620 [(set_attr "type" "mmx")])
19621
19622(define_insn "pfacc"
19623 [(set (match_operand:V2SF 0 "register_operand" "=y")
19624 (vec_concat:V2SF
19625 (plus:SF
19626 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19627 (parallel [(const_int 0)]))
19628 (vec_select:SF (match_dup 1)
19629 (parallel [(const_int 1)])))
19630 (plus:SF
19631 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19632 (parallel [(const_int 0)]))
19633 (vec_select:SF (match_dup 2)
19634 (parallel [(const_int 1)])))))]
19635 "TARGET_3DNOW"
19636 "pfacc\\t{%2, %0|%0, %2}"
19637 [(set_attr "type" "mmx")])
19638
19639(define_insn "pfnacc"
19640 [(set (match_operand:V2SF 0 "register_operand" "=y")
19641 (vec_concat:V2SF
19642 (minus:SF
19643 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19644 (parallel [(const_int 0)]))
19645 (vec_select:SF (match_dup 1)
19646 (parallel [(const_int 1)])))
19647 (minus:SF
19648 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19649 (parallel [(const_int 0)]))
19650 (vec_select:SF (match_dup 2)
19651 (parallel [(const_int 1)])))))]
19652 "TARGET_3DNOW_A"
19653 "pfnacc\\t{%2, %0|%0, %2}"
19654 [(set_attr "type" "mmx")])
19655
19656(define_insn "pfpnacc"
19657 [(set (match_operand:V2SF 0 "register_operand" "=y")
19658 (vec_concat:V2SF
19659 (minus:SF
19660 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19661 (parallel [(const_int 0)]))
19662 (vec_select:SF (match_dup 1)
19663 (parallel [(const_int 1)])))
19664 (plus:SF
19665 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19666 (parallel [(const_int 0)]))
19667 (vec_select:SF (match_dup 2)
19668 (parallel [(const_int 1)])))))]
19669 "TARGET_3DNOW_A"
19670 "pfpnacc\\t{%2, %0|%0, %2}"
19671 [(set_attr "type" "mmx")])
19672
19673(define_insn "pi2fw"
19674 [(set (match_operand:V2SF 0 "register_operand" "=y")
19675 (float:V2SF
19676 (vec_concat:V2SI
19677 (sign_extend:SI
19678 (truncate:HI
19679 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19680 (parallel [(const_int 0)]))))
19681 (sign_extend:SI
19682 (truncate:HI
19683 (vec_select:SI (match_dup 1)
19684 (parallel [(const_int 1)])))))))]
19685 "TARGET_3DNOW_A"
19686 "pi2fw\\t{%1, %0|%0, %1}"
19687 [(set_attr "type" "mmx")])
19688
19689(define_insn "floatv2si2"
19690 [(set (match_operand:V2SF 0 "register_operand" "=y")
19691 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
19692 "TARGET_3DNOW"
19693 "pi2fd\\t{%1, %0|%0, %1}"
19694 [(set_attr "type" "mmx")])
19695
19696;; This insn is identical to pavgb in operation, but the opcode is
19697;; different. To avoid accidentally matching pavgb, use an unspec.
19698
19699(define_insn "pavgusb"
19700 [(set (match_operand:V8QI 0 "register_operand" "=y")
19701 (unspec:V8QI
19702 [(match_operand:V8QI 1 "register_operand" "0")
19703 (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
19704 "TARGET_3DNOW"
19705 "pavgusb\\t{%2, %0|%0, %2}"
19706 [(set_attr "type" "mmx")])
19707
19708;; 3DNow reciprical and sqrt
19709
19710(define_insn "pfrcpv2sf2"
19711 [(set (match_operand:V2SF 0 "register_operand" "=y")
19712 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
19713 "TARGET_3DNOW"
19714 "pfrcp\\t{%1, %0|%0, %1}"
19715 [(set_attr "type" "mmx")])
19716
19717(define_insn "pfrcpit1v2sf3"
19718 [(set (match_operand:V2SF 0 "register_operand" "=y")
19719 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19720 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
19721 "TARGET_3DNOW"
19722 "pfrcpit1\\t{%2, %0|%0, %2}"
19723 [(set_attr "type" "mmx")])
19724
19725(define_insn "pfrcpit2v2sf3"
19726 [(set (match_operand:V2SF 0 "register_operand" "=y")
19727 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19728 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
19729 "TARGET_3DNOW"
19730 "pfrcpit2\\t{%2, %0|%0, %2}"
19731 [(set_attr "type" "mmx")])
19732
19733(define_insn "pfrsqrtv2sf2"
19734 [(set (match_operand:V2SF 0 "register_operand" "=y")
19735 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
19736 "TARGET_3DNOW"
19737 "pfrsqrt\\t{%1, %0|%0, %1}"
19738 [(set_attr "type" "mmx")])
19739
19740(define_insn "pfrsqit1v2sf3"
19741 [(set (match_operand:V2SF 0 "register_operand" "=y")
19742 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19743 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
19744 "TARGET_3DNOW"
19745 "pfrsqit1\\t{%2, %0|%0, %2}"
19746 [(set_attr "type" "mmx")])
19747
19748(define_insn "pmulhrwv4hi3"
19749 [(set (match_operand:V4HI 0 "register_operand" "=y")
19750 (truncate:V4HI
19751 (lshiftrt:V4SI
19752 (plus:V4SI
19753 (mult:V4SI
19754 (sign_extend:V4SI
19755 (match_operand:V4HI 1 "register_operand" "0"))
19756 (sign_extend:V4SI
19757 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19578 (vec_const:V4SI
19579 (parallel [(const_int 32768)
19580 (const_int 32768)
19581 (const_int 32768)
19582 (const_int 32768)])))
19583 (const_int 16))))]
19758 (const_vector:V4SI [(const_int 32768)
19759 (const_int 32768)
19760 (const_int 32768)
19761 (const_int 32768)]))
19762 (const_int 16))))]
19584 "TARGET_3DNOW"
19585 "pmulhrw\\t{%2, %0|%0, %2}"
19586 [(set_attr "type" "mmx")])
19587
19588(define_insn "pswapdv2si2"
19589 [(set (match_operand:V2SI 0 "register_operand" "=y")
19590 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19591 (parallel [(const_int 1) (const_int 0)])))]
19592 "TARGET_3DNOW_A"
19593 "pswapd\\t{%1, %0|%0, %1}"
19594 [(set_attr "type" "mmx")])
19595
19596(define_insn "pswapdv2sf2"
19597 [(set (match_operand:V2SF 0 "register_operand" "=y")
19598 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
19599 (parallel [(const_int 1) (const_int 0)])))]
19600 "TARGET_3DNOW_A"
19601 "pswapd\\t{%1, %0|%0, %1}"
19602 [(set_attr "type" "mmx")])
19603
19604(define_expand "prefetch"
19605 [(prefetch (match_operand:SI 0 "address_operand" "")
19606 (match_operand:SI 1 "const_int_operand" "")
19607 (match_operand:SI 2 "const_int_operand" ""))]
19608 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19609{
19610 int rw = INTVAL (operands[1]);
19611 int locality = INTVAL (operands[2]);
19612
19613 if (rw != 0 && rw != 1)
19614 abort ();
19615 if (locality < 0 || locality > 3)
19616 abort ();
19617
19618 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19619 suported by SSE counterpart or the SSE prefetch is not available
19620 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19621 of locality. */
19622 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19623 operands[2] = GEN_INT (3);
19624 else
19625 operands[1] = const0_rtx;
19626})
19627
19628(define_insn "*prefetch_sse"
19629 [(prefetch (match_operand:SI 0 "address_operand" "p")
19630 (const_int 0)
19631 (match_operand:SI 1 "const_int_operand" ""))]
19632 "TARGET_PREFETCH_SSE"
19633{
19634 static const char * const patterns[4] = {
19635 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19636 };
19637
19638 int locality = INTVAL (operands[1]);
19639 if (locality < 0 || locality > 3)
19640 abort ();
19641
19642 return patterns[locality];
19643}
19644 [(set_attr "type" "sse")])
19645
19646(define_insn "*prefetch_3dnow"
19647 [(prefetch (match_operand:SI 0 "address_operand" "p")
19648 (match_operand:SI 1 "const_int_operand" "n")
19649 (const_int 3))]
19650 "TARGET_3DNOW"
19651{
19652 if (INTVAL (operands[1]) == 0)
19653 return "prefetch\t%a0";
19654 else
19655 return "prefetchw\t%a0";
19656}
19657 [(set_attr "type" "mmx")])
19763 "TARGET_3DNOW"
19764 "pmulhrw\\t{%2, %0|%0, %2}"
19765 [(set_attr "type" "mmx")])
19766
19767(define_insn "pswapdv2si2"
19768 [(set (match_operand:V2SI 0 "register_operand" "=y")
19769 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19770 (parallel [(const_int 1) (const_int 0)])))]
19771 "TARGET_3DNOW_A"
19772 "pswapd\\t{%1, %0|%0, %1}"
19773 [(set_attr "type" "mmx")])
19774
19775(define_insn "pswapdv2sf2"
19776 [(set (match_operand:V2SF 0 "register_operand" "=y")
19777 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
19778 (parallel [(const_int 1) (const_int 0)])))]
19779 "TARGET_3DNOW_A"
19780 "pswapd\\t{%1, %0|%0, %1}"
19781 [(set_attr "type" "mmx")])
19782
19783(define_expand "prefetch"
19784 [(prefetch (match_operand:SI 0 "address_operand" "")
19785 (match_operand:SI 1 "const_int_operand" "")
19786 (match_operand:SI 2 "const_int_operand" ""))]
19787 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19788{
19789 int rw = INTVAL (operands[1]);
19790 int locality = INTVAL (operands[2]);
19791
19792 if (rw != 0 && rw != 1)
19793 abort ();
19794 if (locality < 0 || locality > 3)
19795 abort ();
19796
19797 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19798 suported by SSE counterpart or the SSE prefetch is not available
19799 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19800 of locality. */
19801 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19802 operands[2] = GEN_INT (3);
19803 else
19804 operands[1] = const0_rtx;
19805})
19806
19807(define_insn "*prefetch_sse"
19808 [(prefetch (match_operand:SI 0 "address_operand" "p")
19809 (const_int 0)
19810 (match_operand:SI 1 "const_int_operand" ""))]
19811 "TARGET_PREFETCH_SSE"
19812{
19813 static const char * const patterns[4] = {
19814 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19815 };
19816
19817 int locality = INTVAL (operands[1]);
19818 if (locality < 0 || locality > 3)
19819 abort ();
19820
19821 return patterns[locality];
19822}
19823 [(set_attr "type" "sse")])
19824
19825(define_insn "*prefetch_3dnow"
19826 [(prefetch (match_operand:SI 0 "address_operand" "p")
19827 (match_operand:SI 1 "const_int_operand" "n")
19828 (const_int 3))]
19829 "TARGET_3DNOW"
19830{
19831 if (INTVAL (operands[1]) == 0)
19832 return "prefetch\t%a0";
19833 else
19834 return "prefetchw\t%a0";
19835}
19836 [(set_attr "type" "mmx")])