* config/i386/i386.md (align): Use ASM_OUTPUT_*ALIGN macros.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GNU CC.
9 ;;
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
31 ;; updates for most instructions.
32 ;;
33 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
34 ;; constraint letters.
35 ;;
36 ;; The special asm out single letter directives following a '%' are:
37 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
38 ;; operands[1].
39 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
40 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
41 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
42 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
43 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
44 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
45 ;; 'J' Print the appropriate jump operand.
46 ;;
47 ;; 'b' Print the QImode name of the register for the indicated operand.
48 ;; %b0 would print %al if operands[0] is reg 0.
49 ;; 'w' Likewise, print the HImode name of the register.
50 ;; 'k' Likewise, print the SImode name of the register.
51 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; 'y' Print "st(0)" instead of "st" as a register.
53
54 ;; UNSPEC usage:
55
56 (define_constants
57 [; Relocation specifiers
58 (UNSPEC_GOT 0)
59 (UNSPEC_GOTOFF 1)
60 (UNSPEC_GOTPCREL 2)
61 (UNSPEC_GOTTPOFF 3)
62 (UNSPEC_TPOFF 4)
63 (UNSPEC_NTPOFF 5)
64 (UNSPEC_DTPOFF 6)
65 (UNSPEC_GOTNTPOFF 7)
66 (UNSPEC_INDNTPOFF 8)
67
68 ; Prologue support
69 (UNSPEC_STACK_PROBE 10)
70 (UNSPEC_STACK_ALLOC 11)
71 (UNSPEC_SET_GOT 12)
72 (UNSPEC_SSE_PROLOGUE_SAVE 13)
73
74 ; TLS support
75 (UNSPEC_TP 15)
76 (UNSPEC_TLS_GD 16)
77 (UNSPEC_TLS_LD_BASE 17)
78
79 ; Other random patterns
80 (UNSPEC_SCAS 20)
81 (UNSPEC_SIN 21)
82 (UNSPEC_COS 22)
83 (UNSPEC_FNSTSW 24)
84 (UNSPEC_SAHF 25)
85 (UNSPEC_FSTCW 26)
86 (UNSPEC_ADD_CARRY 27)
87 (UNSPEC_FLDCW 28)
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX 30)
91 (UNSPEC_MASKMOV 32)
92 (UNSPEC_MOVMSK 33)
93 (UNSPEC_MOVNT 34)
94 (UNSPEC_MOVA 38)
95 (UNSPEC_MOVU 39)
96 (UNSPEC_SHUFFLE 41)
97 (UNSPEC_RCP 42)
98 (UNSPEC_RSQRT 43)
99 (UNSPEC_SFENCE 44)
100 (UNSPEC_NOP 45) ; prevents combiner cleverness
101 (UNSPEC_PAVGUSB 49)
102 (UNSPEC_PFRCP 50)
103 (UNSPEC_PFRCPIT1 51)
104 (UNSPEC_PFRCPIT2 52)
105 (UNSPEC_PFRSQRT 53)
106 (UNSPEC_PFRSQIT1 54)
107 (UNSPEC_PSHUFLW 55)
108 (UNSPEC_PSHUFHW 56)
109 (UNSPEC_MFENCE 59)
110 (UNSPEC_LFENCE 60)
111 (UNSPEC_PSADBW 61)
112
113 ; x87 Floating point
114 (UNSPEC_FPATAN 65)
115 (UNSPEC_FYL2X 66)
116
117 ; REP instruction
118 (UNSPEC_REP 67)
119 ])
120
121 (define_constants
122 [(UNSPECV_BLOCKAGE 0)
123 (UNSPECV_EH_RETURN 13)
124 (UNSPECV_EMMS 31)
125 (UNSPECV_LDMXCSR 37)
126 (UNSPECV_STMXCSR 40)
127 (UNSPECV_FEMMS 46)
128 (UNSPECV_CLFLUSH 57)
129 (UNSPECV_ALIGN 68)
130 ])
131
132 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
133 ;; from i386.c.
134
135 ;; In C guard expressions, put expressions which may be compile-time
136 ;; constants first. This allows for better optimization. For
137 ;; example, write "TARGET_64BIT && reload_completed", not
138 ;; "reload_completed && TARGET_64BIT".
139
140 \f
141 ;; Processor type. This attribute must exactly match the processor_type
142 ;; enumeration in i386.h.
143 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
144 (const (symbol_ref "ix86_tune")))
145
146 ;; A basic instruction type. Refinements due to arguments to be
147 ;; provided in other attributes.
148 (define_attr "type"
149 "other,multi,
150 alu,alu1,negnot,imov,imovx,lea,
151 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
152 icmp,test,ibr,setcc,icmov,
153 push,pop,call,callv,leave,
154 str,cld,
155 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
156 sselog,sseiadd,sseishft,sseimul,
157 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
158 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
159 (const_string "other"))
160
161 ;; Main data type used by the insn
162 (define_attr "mode"
163 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
164 (const_string "unknown"))
165
166 ;; The CPU unit operations uses.
167 (define_attr "unit" "integer,i387,sse,mmx,unknown"
168 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
169 (const_string "i387")
170 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
171 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
172 (const_string "sse")
173 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
174 (const_string "mmx")
175 (eq_attr "type" "other")
176 (const_string "unknown")]
177 (const_string "integer")))
178
179 ;; The (bounding maximum) length of an instruction immediate.
180 (define_attr "length_immediate" ""
181 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
182 (const_int 0)
183 (eq_attr "unit" "i387,sse,mmx")
184 (const_int 0)
185 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
186 imul,icmp,push,pop")
187 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
188 (eq_attr "type" "imov,test")
189 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
190 (eq_attr "type" "call")
191 (if_then_else (match_operand 0 "constant_call_address_operand" "")
192 (const_int 4)
193 (const_int 0))
194 (eq_attr "type" "callv")
195 (if_then_else (match_operand 1 "constant_call_address_operand" "")
196 (const_int 4)
197 (const_int 0))
198 ;; We don't know the size before shorten_branches. Expect
199 ;; the instruction to fit for better scheduling.
200 (eq_attr "type" "ibr")
201 (const_int 1)
202 ]
203 (symbol_ref "/* Update immediate_length and other attributes! */
204 abort(),1")))
205
206 ;; The (bounding maximum) length of an instruction address.
207 (define_attr "length_address" ""
208 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
209 (const_int 0)
210 (and (eq_attr "type" "call")
211 (match_operand 0 "constant_call_address_operand" ""))
212 (const_int 0)
213 (and (eq_attr "type" "callv")
214 (match_operand 1 "constant_call_address_operand" ""))
215 (const_int 0)
216 ]
217 (symbol_ref "ix86_attr_length_address_default (insn)")))
218
219 ;; Set when length prefix is used.
220 (define_attr "prefix_data16" ""
221 (if_then_else (ior (eq_attr "mode" "HI")
222 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
223 (const_int 1)
224 (const_int 0)))
225
226 ;; Set when string REP prefix is used.
227 (define_attr "prefix_rep" ""
228 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
229 (const_int 1)
230 (const_int 0)))
231
232 ;; Set when 0f opcode prefix is used.
233 (define_attr "prefix_0f" ""
234 (if_then_else
235 (ior (eq_attr "type" "imovx,setcc,icmov")
236 (eq_attr "unit" "sse,mmx"))
237 (const_int 1)
238 (const_int 0)))
239
240 ;; Set when 0f opcode prefix is used.
241 (define_attr "prefix_rex" ""
242 (cond [(and (eq_attr "mode" "DI")
243 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
244 (const_int 1)
245 (and (eq_attr "mode" "QI")
246 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
247 (const_int 0)))
248 (const_int 1)
249 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
250 (const_int 0))
251 (const_int 1)
252 ]
253 (const_int 0)))
254
255 ;; Set when modrm byte is used.
256 (define_attr "modrm" ""
257 (cond [(eq_attr "type" "str,cld,leave")
258 (const_int 0)
259 (eq_attr "unit" "i387")
260 (const_int 0)
261 (and (eq_attr "type" "incdec")
262 (ior (match_operand:SI 1 "register_operand" "")
263 (match_operand:HI 1 "register_operand" "")))
264 (const_int 0)
265 (and (eq_attr "type" "push")
266 (not (match_operand 1 "memory_operand" "")))
267 (const_int 0)
268 (and (eq_attr "type" "pop")
269 (not (match_operand 0 "memory_operand" "")))
270 (const_int 0)
271 (and (eq_attr "type" "imov")
272 (and (match_operand 0 "register_operand" "")
273 (match_operand 1 "immediate_operand" "")))
274 (const_int 0)
275 (and (eq_attr "type" "call")
276 (match_operand 0 "constant_call_address_operand" ""))
277 (const_int 0)
278 (and (eq_attr "type" "callv")
279 (match_operand 1 "constant_call_address_operand" ""))
280 (const_int 0)
281 ]
282 (const_int 1)))
283
284 ;; The (bounding maximum) length of an instruction in bytes.
285 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
286 ;; to split it and compute proper length as for other insns.
287 (define_attr "length" ""
288 (cond [(eq_attr "type" "other,multi,fistp")
289 (const_int 16)
290 (eq_attr "type" "fcmp")
291 (const_int 4)
292 (eq_attr "unit" "i387")
293 (plus (const_int 2)
294 (plus (attr "prefix_data16")
295 (attr "length_address")))]
296 (plus (plus (attr "modrm")
297 (plus (attr "prefix_0f")
298 (plus (attr "prefix_rex")
299 (const_int 1))))
300 (plus (attr "prefix_rep")
301 (plus (attr "prefix_data16")
302 (plus (attr "length_immediate")
303 (attr "length_address")))))))
304
305 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
306 ;; `store' if there is a simple memory reference therein, or `unknown'
307 ;; if the instruction is complex.
308
309 (define_attr "memory" "none,load,store,both,unknown"
310 (cond [(eq_attr "type" "other,multi,str")
311 (const_string "unknown")
312 (eq_attr "type" "lea,fcmov,fpspc,cld")
313 (const_string "none")
314 (eq_attr "type" "fistp,leave")
315 (const_string "both")
316 (eq_attr "type" "push")
317 (if_then_else (match_operand 1 "memory_operand" "")
318 (const_string "both")
319 (const_string "store"))
320 (eq_attr "type" "pop")
321 (if_then_else (match_operand 0 "memory_operand" "")
322 (const_string "both")
323 (const_string "load"))
324 (eq_attr "type" "setcc")
325 (if_then_else (match_operand 0 "memory_operand" "")
326 (const_string "store")
327 (const_string "none"))
328 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
329 (if_then_else (ior (match_operand 0 "memory_operand" "")
330 (match_operand 1 "memory_operand" ""))
331 (const_string "load")
332 (const_string "none"))
333 (eq_attr "type" "ibr")
334 (if_then_else (match_operand 0 "memory_operand" "")
335 (const_string "load")
336 (const_string "none"))
337 (eq_attr "type" "call")
338 (if_then_else (match_operand 0 "constant_call_address_operand" "")
339 (const_string "none")
340 (const_string "load"))
341 (eq_attr "type" "callv")
342 (if_then_else (match_operand 1 "constant_call_address_operand" "")
343 (const_string "none")
344 (const_string "load"))
345 (and (eq_attr "type" "alu1,negnot")
346 (match_operand 1 "memory_operand" ""))
347 (const_string "both")
348 (and (match_operand 0 "memory_operand" "")
349 (match_operand 1 "memory_operand" ""))
350 (const_string "both")
351 (match_operand 0 "memory_operand" "")
352 (const_string "store")
353 (match_operand 1 "memory_operand" "")
354 (const_string "load")
355 (and (eq_attr "type"
356 "!alu1,negnot,
357 imov,imovx,icmp,test,
358 fmov,fcmp,fsgn,
359 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
360 mmx,mmxmov,mmxcmp,mmxcvt")
361 (match_operand 2 "memory_operand" ""))
362 (const_string "load")
363 (and (eq_attr "type" "icmov")
364 (match_operand 3 "memory_operand" ""))
365 (const_string "load")
366 ]
367 (const_string "none")))
368
369 ;; Indicates if an instruction has both an immediate and a displacement.
370
371 (define_attr "imm_disp" "false,true,unknown"
372 (cond [(eq_attr "type" "other,multi")
373 (const_string "unknown")
374 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
375 (and (match_operand 0 "memory_displacement_operand" "")
376 (match_operand 1 "immediate_operand" "")))
377 (const_string "true")
378 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
379 (and (match_operand 0 "memory_displacement_operand" "")
380 (match_operand 2 "immediate_operand" "")))
381 (const_string "true")
382 ]
383 (const_string "false")))
384
385 ;; Indicates if an FP operation has an integer source.
386
387 (define_attr "fp_int_src" "false,true"
388 (const_string "false"))
389
390 ;; Describe a user's asm statement.
391 (define_asm_attributes
392 [(set_attr "length" "128")
393 (set_attr "type" "multi")])
394 \f
395 (include "pentium.md")
396 (include "ppro.md")
397 (include "k6.md")
398 (include "athlon.md")
399 \f
400 ;; Compare instructions.
401
402 ;; All compare insns have expanders that save the operands away without
403 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
404 ;; after the cmp) will actually emit the cmpM.
405
406 (define_expand "cmpdi"
407 [(set (reg:CC 17)
408 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
409 (match_operand:DI 1 "x86_64_general_operand" "")))]
410 ""
411 {
412 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
413 operands[0] = force_reg (DImode, operands[0]);
414 ix86_compare_op0 = operands[0];
415 ix86_compare_op1 = operands[1];
416 DONE;
417 })
418
419 (define_expand "cmpsi"
420 [(set (reg:CC 17)
421 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
422 (match_operand:SI 1 "general_operand" "")))]
423 ""
424 {
425 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
426 operands[0] = force_reg (SImode, operands[0]);
427 ix86_compare_op0 = operands[0];
428 ix86_compare_op1 = operands[1];
429 DONE;
430 })
431
432 (define_expand "cmphi"
433 [(set (reg:CC 17)
434 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
435 (match_operand:HI 1 "general_operand" "")))]
436 ""
437 {
438 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
439 operands[0] = force_reg (HImode, operands[0]);
440 ix86_compare_op0 = operands[0];
441 ix86_compare_op1 = operands[1];
442 DONE;
443 })
444
445 (define_expand "cmpqi"
446 [(set (reg:CC 17)
447 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
448 (match_operand:QI 1 "general_operand" "")))]
449 "TARGET_QIMODE_MATH"
450 {
451 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
452 operands[0] = force_reg (QImode, operands[0]);
453 ix86_compare_op0 = operands[0];
454 ix86_compare_op1 = operands[1];
455 DONE;
456 })
457
458 (define_insn "cmpdi_ccno_1_rex64"
459 [(set (reg 17)
460 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
461 (match_operand:DI 1 "const0_operand" "n,n")))]
462 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
463 "@
464 test{q}\t{%0, %0|%0, %0}
465 cmp{q}\t{%1, %0|%0, %1}"
466 [(set_attr "type" "test,icmp")
467 (set_attr "length_immediate" "0,1")
468 (set_attr "mode" "DI")])
469
470 (define_insn "*cmpdi_minus_1_rex64"
471 [(set (reg 17)
472 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
473 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
474 (const_int 0)))]
475 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
476 "cmp{q}\t{%1, %0|%0, %1}"
477 [(set_attr "type" "icmp")
478 (set_attr "mode" "DI")])
479
480 (define_expand "cmpdi_1_rex64"
481 [(set (reg:CC 17)
482 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
483 (match_operand:DI 1 "general_operand" "")))]
484 "TARGET_64BIT"
485 "")
486
487 (define_insn "cmpdi_1_insn_rex64"
488 [(set (reg 17)
489 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
490 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
491 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
492 "cmp{q}\t{%1, %0|%0, %1}"
493 [(set_attr "type" "icmp")
494 (set_attr "mode" "DI")])
495
496
497 (define_insn "*cmpsi_ccno_1"
498 [(set (reg 17)
499 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
500 (match_operand:SI 1 "const0_operand" "n,n")))]
501 "ix86_match_ccmode (insn, CCNOmode)"
502 "@
503 test{l}\t{%0, %0|%0, %0}
504 cmp{l}\t{%1, %0|%0, %1}"
505 [(set_attr "type" "test,icmp")
506 (set_attr "length_immediate" "0,1")
507 (set_attr "mode" "SI")])
508
509 (define_insn "*cmpsi_minus_1"
510 [(set (reg 17)
511 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
512 (match_operand:SI 1 "general_operand" "ri,mr"))
513 (const_int 0)))]
514 "ix86_match_ccmode (insn, CCGOCmode)"
515 "cmp{l}\t{%1, %0|%0, %1}"
516 [(set_attr "type" "icmp")
517 (set_attr "mode" "SI")])
518
519 (define_expand "cmpsi_1"
520 [(set (reg:CC 17)
521 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
522 (match_operand:SI 1 "general_operand" "ri,mr")))]
523 ""
524 "")
525
526 (define_insn "*cmpsi_1_insn"
527 [(set (reg 17)
528 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
529 (match_operand:SI 1 "general_operand" "ri,mr")))]
530 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
531 && ix86_match_ccmode (insn, CCmode)"
532 "cmp{l}\t{%1, %0|%0, %1}"
533 [(set_attr "type" "icmp")
534 (set_attr "mode" "SI")])
535
536 (define_insn "*cmphi_ccno_1"
537 [(set (reg 17)
538 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
539 (match_operand:HI 1 "const0_operand" "n,n")))]
540 "ix86_match_ccmode (insn, CCNOmode)"
541 "@
542 test{w}\t{%0, %0|%0, %0}
543 cmp{w}\t{%1, %0|%0, %1}"
544 [(set_attr "type" "test,icmp")
545 (set_attr "length_immediate" "0,1")
546 (set_attr "mode" "HI")])
547
548 (define_insn "*cmphi_minus_1"
549 [(set (reg 17)
550 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
551 (match_operand:HI 1 "general_operand" "ri,mr"))
552 (const_int 0)))]
553 "ix86_match_ccmode (insn, CCGOCmode)"
554 "cmp{w}\t{%1, %0|%0, %1}"
555 [(set_attr "type" "icmp")
556 (set_attr "mode" "HI")])
557
558 (define_insn "*cmphi_1"
559 [(set (reg 17)
560 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
561 (match_operand:HI 1 "general_operand" "ri,mr")))]
562 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
563 && ix86_match_ccmode (insn, CCmode)"
564 "cmp{w}\t{%1, %0|%0, %1}"
565 [(set_attr "type" "icmp")
566 (set_attr "mode" "HI")])
567
568 (define_insn "*cmpqi_ccno_1"
569 [(set (reg 17)
570 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
571 (match_operand:QI 1 "const0_operand" "n,n")))]
572 "ix86_match_ccmode (insn, CCNOmode)"
573 "@
574 test{b}\t{%0, %0|%0, %0}
575 cmp{b}\t{$0, %0|%0, 0}"
576 [(set_attr "type" "test,icmp")
577 (set_attr "length_immediate" "0,1")
578 (set_attr "mode" "QI")])
579
580 (define_insn "*cmpqi_1"
581 [(set (reg 17)
582 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
583 (match_operand:QI 1 "general_operand" "qi,mq")))]
584 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
585 && ix86_match_ccmode (insn, CCmode)"
586 "cmp{b}\t{%1, %0|%0, %1}"
587 [(set_attr "type" "icmp")
588 (set_attr "mode" "QI")])
589
590 (define_insn "*cmpqi_minus_1"
591 [(set (reg 17)
592 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
593 (match_operand:QI 1 "general_operand" "qi,mq"))
594 (const_int 0)))]
595 "ix86_match_ccmode (insn, CCGOCmode)"
596 "cmp{b}\t{%1, %0|%0, %1}"
597 [(set_attr "type" "icmp")
598 (set_attr "mode" "QI")])
599
600 (define_insn "*cmpqi_ext_1"
601 [(set (reg 17)
602 (compare
603 (match_operand:QI 0 "general_operand" "Qm")
604 (subreg:QI
605 (zero_extract:SI
606 (match_operand 1 "ext_register_operand" "Q")
607 (const_int 8)
608 (const_int 8)) 0)))]
609 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
610 "cmp{b}\t{%h1, %0|%0, %h1}"
611 [(set_attr "type" "icmp")
612 (set_attr "mode" "QI")])
613
614 (define_insn "*cmpqi_ext_1_rex64"
615 [(set (reg 17)
616 (compare
617 (match_operand:QI 0 "register_operand" "Q")
618 (subreg:QI
619 (zero_extract:SI
620 (match_operand 1 "ext_register_operand" "Q")
621 (const_int 8)
622 (const_int 8)) 0)))]
623 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
624 "cmp{b}\t{%h1, %0|%0, %h1}"
625 [(set_attr "type" "icmp")
626 (set_attr "mode" "QI")])
627
628 (define_insn "*cmpqi_ext_2"
629 [(set (reg 17)
630 (compare
631 (subreg:QI
632 (zero_extract:SI
633 (match_operand 0 "ext_register_operand" "Q")
634 (const_int 8)
635 (const_int 8)) 0)
636 (match_operand:QI 1 "const0_operand" "n")))]
637 "ix86_match_ccmode (insn, CCNOmode)"
638 "test{b}\t%h0, %h0"
639 [(set_attr "type" "test")
640 (set_attr "length_immediate" "0")
641 (set_attr "mode" "QI")])
642
643 (define_expand "cmpqi_ext_3"
644 [(set (reg:CC 17)
645 (compare:CC
646 (subreg:QI
647 (zero_extract:SI
648 (match_operand 0 "ext_register_operand" "")
649 (const_int 8)
650 (const_int 8)) 0)
651 (match_operand:QI 1 "general_operand" "")))]
652 ""
653 "")
654
655 (define_insn "cmpqi_ext_3_insn"
656 [(set (reg 17)
657 (compare
658 (subreg:QI
659 (zero_extract:SI
660 (match_operand 0 "ext_register_operand" "Q")
661 (const_int 8)
662 (const_int 8)) 0)
663 (match_operand:QI 1 "general_operand" "Qmn")))]
664 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665 "cmp{b}\t{%1, %h0|%h0, %1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "QI")])
668
669 (define_insn "cmpqi_ext_3_insn_rex64"
670 [(set (reg 17)
671 (compare
672 (subreg:QI
673 (zero_extract:SI
674 (match_operand 0 "ext_register_operand" "Q")
675 (const_int 8)
676 (const_int 8)) 0)
677 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
678 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679 "cmp{b}\t{%1, %h0|%h0, %1}"
680 [(set_attr "type" "icmp")
681 (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_4"
684 [(set (reg 17)
685 (compare
686 (subreg:QI
687 (zero_extract:SI
688 (match_operand 0 "ext_register_operand" "Q")
689 (const_int 8)
690 (const_int 8)) 0)
691 (subreg:QI
692 (zero_extract:SI
693 (match_operand 1 "ext_register_operand" "Q")
694 (const_int 8)
695 (const_int 8)) 0)))]
696 "ix86_match_ccmode (insn, CCmode)"
697 "cmp{b}\t{%h1, %h0|%h0, %h1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "QI")])
700
701 ;; These implement float point compares.
702 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
703 ;; which would allow mix and match FP modes on the compares. Which is what
704 ;; the old patterns did, but with many more of them.
705
706 (define_expand "cmpxf"
707 [(set (reg:CC 17)
708 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
709 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
710 "!TARGET_64BIT && TARGET_80387"
711 {
712 ix86_compare_op0 = operands[0];
713 ix86_compare_op1 = operands[1];
714 DONE;
715 })
716
717 (define_expand "cmptf"
718 [(set (reg:CC 17)
719 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
720 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
721 "TARGET_80387"
722 {
723 ix86_compare_op0 = operands[0];
724 ix86_compare_op1 = operands[1];
725 DONE;
726 })
727
728 (define_expand "cmpdf"
729 [(set (reg:CC 17)
730 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
731 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
732 "TARGET_80387 || TARGET_SSE2"
733 {
734 ix86_compare_op0 = operands[0];
735 ix86_compare_op1 = operands[1];
736 DONE;
737 })
738
739 (define_expand "cmpsf"
740 [(set (reg:CC 17)
741 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
742 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
743 "TARGET_80387 || TARGET_SSE"
744 {
745 ix86_compare_op0 = operands[0];
746 ix86_compare_op1 = operands[1];
747 DONE;
748 })
749
750 ;; FP compares, step 1:
751 ;; Set the FP condition codes.
752 ;;
753 ;; CCFPmode compare with exceptions
754 ;; CCFPUmode compare with no exceptions
755
756 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
757 ;; and that fp moves clobber the condition codes, and that there is
758 ;; currently no way to describe this fact to reg-stack. So there are
759 ;; no splitters yet for this.
760
761 ;; %%% YIKES! This scheme does not retain a strong connection between
762 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
763 ;; work! Only allow tos/mem with tos in op 0.
764 ;;
765 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
766 ;; things aren't as bad as they sound...
767
768 (define_insn "*cmpfp_0"
769 [(set (match_operand:HI 0 "register_operand" "=a")
770 (unspec:HI
771 [(compare:CCFP (match_operand 1 "register_operand" "f")
772 (match_operand 2 "const0_operand" "X"))]
773 UNSPEC_FNSTSW))]
774 "TARGET_80387
775 && FLOAT_MODE_P (GET_MODE (operands[1]))
776 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
777 {
778 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
779 return "ftst\;fnstsw\t%0\;fstp\t%y0";
780 else
781 return "ftst\;fnstsw\t%0";
782 }
783 [(set_attr "type" "multi")
784 (set (attr "mode")
785 (cond [(match_operand:SF 1 "" "")
786 (const_string "SF")
787 (match_operand:DF 1 "" "")
788 (const_string "DF")
789 ]
790 (const_string "XF")))])
791
792 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
793 ;; used to manage the reg stack popping would not be preserved.
794
795 (define_insn "*cmpfp_2_sf"
796 [(set (reg:CCFP 18)
797 (compare:CCFP
798 (match_operand:SF 0 "register_operand" "f")
799 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
800 "TARGET_80387"
801 "* return output_fp_compare (insn, operands, 0, 0);"
802 [(set_attr "type" "fcmp")
803 (set_attr "mode" "SF")])
804
805 (define_insn "*cmpfp_2_sf_1"
806 [(set (match_operand:HI 0 "register_operand" "=a")
807 (unspec:HI
808 [(compare:CCFP
809 (match_operand:SF 1 "register_operand" "f")
810 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
811 UNSPEC_FNSTSW))]
812 "TARGET_80387"
813 "* return output_fp_compare (insn, operands, 2, 0);"
814 [(set_attr "type" "fcmp")
815 (set_attr "mode" "SF")])
816
817 (define_insn "*cmpfp_2_df"
818 [(set (reg:CCFP 18)
819 (compare:CCFP
820 (match_operand:DF 0 "register_operand" "f")
821 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
822 "TARGET_80387"
823 "* return output_fp_compare (insn, operands, 0, 0);"
824 [(set_attr "type" "fcmp")
825 (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_2_df_1"
828 [(set (match_operand:HI 0 "register_operand" "=a")
829 (unspec:HI
830 [(compare:CCFP
831 (match_operand:DF 1 "register_operand" "f")
832 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
833 UNSPEC_FNSTSW))]
834 "TARGET_80387"
835 "* return output_fp_compare (insn, operands, 2, 0);"
836 [(set_attr "type" "multi")
837 (set_attr "mode" "DF")])
838
839 (define_insn "*cmpfp_2_xf"
840 [(set (reg:CCFP 18)
841 (compare:CCFP
842 (match_operand:XF 0 "register_operand" "f")
843 (match_operand:XF 1 "register_operand" "f")))]
844 "!TARGET_64BIT && TARGET_80387"
845 "* return output_fp_compare (insn, operands, 0, 0);"
846 [(set_attr "type" "fcmp")
847 (set_attr "mode" "XF")])
848
849 (define_insn "*cmpfp_2_tf"
850 [(set (reg:CCFP 18)
851 (compare:CCFP
852 (match_operand:TF 0 "register_operand" "f")
853 (match_operand:TF 1 "register_operand" "f")))]
854 "TARGET_80387"
855 "* return output_fp_compare (insn, operands, 0, 0);"
856 [(set_attr "type" "fcmp")
857 (set_attr "mode" "XF")])
858
859 (define_insn "*cmpfp_2_xf_1"
860 [(set (match_operand:HI 0 "register_operand" "=a")
861 (unspec:HI
862 [(compare:CCFP
863 (match_operand:XF 1 "register_operand" "f")
864 (match_operand:XF 2 "register_operand" "f"))]
865 UNSPEC_FNSTSW))]
866 "!TARGET_64BIT && TARGET_80387"
867 "* return output_fp_compare (insn, operands, 2, 0);"
868 [(set_attr "type" "multi")
869 (set_attr "mode" "XF")])
870
871 (define_insn "*cmpfp_2_tf_1"
872 [(set (match_operand:HI 0 "register_operand" "=a")
873 (unspec:HI
874 [(compare:CCFP
875 (match_operand:TF 1 "register_operand" "f")
876 (match_operand:TF 2 "register_operand" "f"))]
877 UNSPEC_FNSTSW))]
878 "TARGET_80387"
879 "* return output_fp_compare (insn, operands, 2, 0);"
880 [(set_attr "type" "multi")
881 (set_attr "mode" "XF")])
882
883 (define_insn "*cmpfp_2u"
884 [(set (reg:CCFPU 18)
885 (compare:CCFPU
886 (match_operand 0 "register_operand" "f")
887 (match_operand 1 "register_operand" "f")))]
888 "TARGET_80387
889 && FLOAT_MODE_P (GET_MODE (operands[0]))
890 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
891 "* return output_fp_compare (insn, operands, 0, 1);"
892 [(set_attr "type" "fcmp")
893 (set (attr "mode")
894 (cond [(match_operand:SF 1 "" "")
895 (const_string "SF")
896 (match_operand:DF 1 "" "")
897 (const_string "DF")
898 ]
899 (const_string "XF")))])
900
901 (define_insn "*cmpfp_2u_1"
902 [(set (match_operand:HI 0 "register_operand" "=a")
903 (unspec:HI
904 [(compare:CCFPU
905 (match_operand 1 "register_operand" "f")
906 (match_operand 2 "register_operand" "f"))]
907 UNSPEC_FNSTSW))]
908 "TARGET_80387
909 && FLOAT_MODE_P (GET_MODE (operands[1]))
910 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
911 "* return output_fp_compare (insn, operands, 2, 1);"
912 [(set_attr "type" "multi")
913 (set (attr "mode")
914 (cond [(match_operand:SF 1 "" "")
915 (const_string "SF")
916 (match_operand:DF 1 "" "")
917 (const_string "DF")
918 ]
919 (const_string "XF")))])
920
921 ;; Patterns to match the SImode-in-memory ficom instructions.
922 ;;
923 ;; %%% Play games with accepting gp registers, as otherwise we have to
924 ;; force them to memory during rtl generation, which is no good. We
925 ;; can get rid of this once we teach reload to do memory input reloads
926 ;; via pushes.
927
928 (define_insn "*ficom_1"
929 [(set (reg:CCFP 18)
930 (compare:CCFP
931 (match_operand 0 "register_operand" "f,f")
932 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
933 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
934 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
935 "#")
936
937 ;; Split the not-really-implemented gp register case into a
938 ;; push-op-pop sequence.
939 ;;
940 ;; %%% This is most efficient, but am I gonna get in trouble
941 ;; for separating cc0_setter and cc0_user?
942
943 (define_split
944 [(set (reg:CCFP 18)
945 (compare:CCFP
946 (match_operand:SF 0 "register_operand" "")
947 (float (match_operand:SI 1 "register_operand" ""))))]
948 "0 && TARGET_80387 && reload_completed"
949 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
950 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
951 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
952 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
953 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
954 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
955
956 ;; FP compares, step 2
957 ;; Move the fpsw to ax.
958
959 (define_insn "*x86_fnstsw_1"
960 [(set (match_operand:HI 0 "register_operand" "=a")
961 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
962 "TARGET_80387"
963 "fnstsw\t%0"
964 [(set_attr "length" "2")
965 (set_attr "mode" "SI")
966 (set_attr "unit" "i387")
967 (set_attr "ppro_uops" "few")])
968
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
971
972 (define_insn "x86_sahf_1"
973 [(set (reg:CC 17)
974 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975 "!TARGET_64BIT"
976 "sahf"
977 [(set_attr "length" "1")
978 (set_attr "athlon_decode" "vector")
979 (set_attr "mode" "SI")
980 (set_attr "ppro_uops" "one")])
981
982 ;; Pentium Pro can do steps 1 through 3 in one go.
983
984 (define_insn "*cmpfp_i"
985 [(set (reg:CCFP 17)
986 (compare:CCFP (match_operand 0 "register_operand" "f")
987 (match_operand 1 "register_operand" "f")))]
988 "TARGET_80387 && TARGET_CMOVE
989 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && FLOAT_MODE_P (GET_MODE (operands[0]))
991 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
992 "* return output_fp_compare (insn, operands, 1, 0);"
993 [(set_attr "type" "fcmp")
994 (set (attr "mode")
995 (cond [(match_operand:SF 1 "" "")
996 (const_string "SF")
997 (match_operand:DF 1 "" "")
998 (const_string "DF")
999 ]
1000 (const_string "XF")))
1001 (set_attr "athlon_decode" "vector")])
1002
1003 (define_insn "*cmpfp_i_sse"
1004 [(set (reg:CCFP 17)
1005 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1006 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1007 "TARGET_80387
1008 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1009 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1010 "* return output_fp_compare (insn, operands, 1, 0);"
1011 [(set_attr "type" "fcmp,ssecomi")
1012 (set (attr "mode")
1013 (if_then_else (match_operand:SF 1 "" "")
1014 (const_string "SF")
1015 (const_string "DF")))
1016 (set_attr "athlon_decode" "vector")])
1017
1018 (define_insn "*cmpfp_i_sse_only"
1019 [(set (reg:CCFP 17)
1020 (compare:CCFP (match_operand 0 "register_operand" "x")
1021 (match_operand 1 "nonimmediate_operand" "xm")))]
1022 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1024 "* return output_fp_compare (insn, operands, 1, 0);"
1025 [(set_attr "type" "ssecomi")
1026 (set (attr "mode")
1027 (if_then_else (match_operand:SF 1 "" "")
1028 (const_string "SF")
1029 (const_string "DF")))
1030 (set_attr "athlon_decode" "vector")])
1031
1032 (define_insn "*cmpfp_iu"
1033 [(set (reg:CCFPU 17)
1034 (compare:CCFPU (match_operand 0 "register_operand" "f")
1035 (match_operand 1 "register_operand" "f")))]
1036 "TARGET_80387 && TARGET_CMOVE
1037 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038 && FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "fcmp")
1042 (set (attr "mode")
1043 (cond [(match_operand:SF 1 "" "")
1044 (const_string "SF")
1045 (match_operand:DF 1 "" "")
1046 (const_string "DF")
1047 ]
1048 (const_string "XF")))
1049 (set_attr "athlon_decode" "vector")])
1050
1051 (define_insn "*cmpfp_iu_sse"
1052 [(set (reg:CCFPU 17)
1053 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1054 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1055 "TARGET_80387
1056 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1057 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1058 "* return output_fp_compare (insn, operands, 1, 1);"
1059 [(set_attr "type" "fcmp,ssecomi")
1060 (set (attr "mode")
1061 (if_then_else (match_operand:SF 1 "" "")
1062 (const_string "SF")
1063 (const_string "DF")))
1064 (set_attr "athlon_decode" "vector")])
1065
1066 (define_insn "*cmpfp_iu_sse_only"
1067 [(set (reg:CCFPU 17)
1068 (compare:CCFPU (match_operand 0 "register_operand" "x")
1069 (match_operand 1 "nonimmediate_operand" "xm")))]
1070 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1071 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1072 "* return output_fp_compare (insn, operands, 1, 1);"
1073 [(set_attr "type" "ssecomi")
1074 (set (attr "mode")
1075 (if_then_else (match_operand:SF 1 "" "")
1076 (const_string "SF")
1077 (const_string "DF")))
1078 (set_attr "athlon_decode" "vector")])
1079 \f
1080 ;; Move instructions.
1081
1082 ;; General case of fullword move.
1083
1084 (define_expand "movsi"
1085 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1086 (match_operand:SI 1 "general_operand" ""))]
1087 ""
1088 "ix86_expand_move (SImode, operands); DONE;")
1089
1090 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1091 ;; general_operand.
1092 ;;
1093 ;; %%% We don't use a post-inc memory reference because x86 is not a
1094 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1095 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1096 ;; targets without our curiosities, and it is just as easy to represent
1097 ;; this differently.
1098
1099 (define_insn "*pushsi2"
1100 [(set (match_operand:SI 0 "push_operand" "=<")
1101 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1102 "!TARGET_64BIT"
1103 "push{l}\t%1"
1104 [(set_attr "type" "push")
1105 (set_attr "mode" "SI")])
1106
1107 ;; For 64BIT abi we always round up to 8 bytes.
1108 (define_insn "*pushsi2_rex64"
1109 [(set (match_operand:SI 0 "push_operand" "=X")
1110 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1111 "TARGET_64BIT"
1112 "push{q}\t%q1"
1113 [(set_attr "type" "push")
1114 (set_attr "mode" "SI")])
1115
1116 (define_insn "*pushsi2_prologue"
1117 [(set (match_operand:SI 0 "push_operand" "=<")
1118 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1119 (clobber (mem:BLK (scratch)))]
1120 "!TARGET_64BIT"
1121 "push{l}\t%1"
1122 [(set_attr "type" "push")
1123 (set_attr "mode" "SI")])
1124
1125 (define_insn "*popsi1_epilogue"
1126 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1127 (mem:SI (reg:SI 7)))
1128 (set (reg:SI 7)
1129 (plus:SI (reg:SI 7) (const_int 4)))
1130 (clobber (mem:BLK (scratch)))]
1131 "!TARGET_64BIT"
1132 "pop{l}\t%0"
1133 [(set_attr "type" "pop")
1134 (set_attr "mode" "SI")])
1135
1136 (define_insn "popsi1"
1137 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1138 (mem:SI (reg:SI 7)))
1139 (set (reg:SI 7)
1140 (plus:SI (reg:SI 7) (const_int 4)))]
1141 "!TARGET_64BIT"
1142 "pop{l}\t%0"
1143 [(set_attr "type" "pop")
1144 (set_attr "mode" "SI")])
1145
1146 (define_insn "*movsi_xor"
1147 [(set (match_operand:SI 0 "register_operand" "=r")
1148 (match_operand:SI 1 "const0_operand" "i"))
1149 (clobber (reg:CC 17))]
1150 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1151 "xor{l}\t{%0, %0|%0, %0}"
1152 [(set_attr "type" "alu1")
1153 (set_attr "mode" "SI")
1154 (set_attr "length_immediate" "0")])
1155
1156 (define_insn "*movsi_or"
1157 [(set (match_operand:SI 0 "register_operand" "=r")
1158 (match_operand:SI 1 "immediate_operand" "i"))
1159 (clobber (reg:CC 17))]
1160 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1161 && INTVAL (operands[1]) == -1
1162 && (TARGET_PENTIUM || optimize_size)"
1163 {
1164 operands[1] = constm1_rtx;
1165 return "or{l}\t{%1, %0|%0, %1}";
1166 }
1167 [(set_attr "type" "alu1")
1168 (set_attr "mode" "SI")
1169 (set_attr "length_immediate" "1")])
1170
1171 (define_insn "*movsi_1"
1172 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1173 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1174 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1176 {
1177 switch (get_attr_type (insn))
1178 {
1179 case TYPE_SSEMOV:
1180 if (get_attr_mode (insn) == MODE_TI)
1181 return "movdqa\t{%1, %0|%0, %1}";
1182 return "movd\t{%1, %0|%0, %1}";
1183
1184 case TYPE_MMXMOV:
1185 if (get_attr_mode (insn) == MODE_DI)
1186 return "movq\t{%1, %0|%0, %1}";
1187 return "movd\t{%1, %0|%0, %1}";
1188
1189 case TYPE_LEA:
1190 return "lea{l}\t{%1, %0|%0, %1}";
1191
1192 default:
1193 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1194 abort();
1195 return "mov{l}\t{%1, %0|%0, %1}";
1196 }
1197 }
1198 [(set (attr "type")
1199 (cond [(eq_attr "alternative" "2,3,4")
1200 (const_string "mmxmov")
1201 (eq_attr "alternative" "5,6,7")
1202 (const_string "ssemov")
1203 (and (ne (symbol_ref "flag_pic") (const_int 0))
1204 (match_operand:SI 1 "symbolic_operand" ""))
1205 (const_string "lea")
1206 ]
1207 (const_string "imov")))
1208 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1209
1210 (define_insn "*movsi_1_nointernunit"
1211 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1212 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1213 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1214 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1215 {
1216 switch (get_attr_type (insn))
1217 {
1218 case TYPE_SSEMOV:
1219 if (get_attr_mode (insn) == MODE_TI)
1220 return "movdqa\t{%1, %0|%0, %1}";
1221 return "movd\t{%1, %0|%0, %1}";
1222
1223 case TYPE_MMXMOV:
1224 if (get_attr_mode (insn) == MODE_DI)
1225 return "movq\t{%1, %0|%0, %1}";
1226 return "movd\t{%1, %0|%0, %1}";
1227
1228 case TYPE_LEA:
1229 return "lea{l}\t{%1, %0|%0, %1}";
1230
1231 default:
1232 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1233 abort();
1234 return "mov{l}\t{%1, %0|%0, %1}";
1235 }
1236 }
1237 [(set (attr "type")
1238 (cond [(eq_attr "alternative" "2,3,4")
1239 (const_string "mmxmov")
1240 (eq_attr "alternative" "5,6,7")
1241 (const_string "ssemov")
1242 (and (ne (symbol_ref "flag_pic") (const_int 0))
1243 (match_operand:SI 1 "symbolic_operand" ""))
1244 (const_string "lea")
1245 ]
1246 (const_string "imov")))
1247 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1248
1249 ;; Stores and loads of ax to arbitrary constant address.
1250 ;; We fake an second form of instruction to force reload to load address
1251 ;; into register when rax is not available
1252 (define_insn "*movabssi_1_rex64"
1253 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1254 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1255 "TARGET_64BIT"
1256 "@
1257 movabs{l}\t{%1, %P0|%P0, %1}
1258 mov{l}\t{%1, %a0|%a0, %1}
1259 movabs{l}\t{%1, %a0|%a0, %1}"
1260 [(set_attr "type" "imov")
1261 (set_attr "modrm" "0,*,*")
1262 (set_attr "length_address" "8,0,0")
1263 (set_attr "length_immediate" "0,*,*")
1264 (set_attr "memory" "store")
1265 (set_attr "mode" "SI")])
1266
1267 (define_insn "*movabssi_2_rex64"
1268 [(set (match_operand:SI 0 "register_operand" "=a,r")
1269 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1270 "TARGET_64BIT"
1271 "@
1272 movabs{l}\t{%P1, %0|%0, %P1}
1273 mov{l}\t{%a1, %0|%0, %a1}"
1274 [(set_attr "type" "imov")
1275 (set_attr "modrm" "0,*")
1276 (set_attr "length_address" "8,0")
1277 (set_attr "length_immediate" "0")
1278 (set_attr "memory" "load")
1279 (set_attr "mode" "SI")])
1280
1281 (define_insn "*swapsi"
1282 [(set (match_operand:SI 0 "register_operand" "+r")
1283 (match_operand:SI 1 "register_operand" "+r"))
1284 (set (match_dup 1)
1285 (match_dup 0))]
1286 ""
1287 "xchg{l}\t%1, %0"
1288 [(set_attr "type" "imov")
1289 (set_attr "pent_pair" "np")
1290 (set_attr "athlon_decode" "vector")
1291 (set_attr "mode" "SI")
1292 (set_attr "modrm" "0")
1293 (set_attr "ppro_uops" "few")])
1294
1295 (define_expand "movhi"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297 (match_operand:HI 1 "general_operand" ""))]
1298 ""
1299 "ix86_expand_move (HImode, operands); DONE;")
1300
1301 (define_insn "*pushhi2"
1302 [(set (match_operand:HI 0 "push_operand" "=<,<")
1303 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1304 "!TARGET_64BIT"
1305 "@
1306 push{w}\t{|WORD PTR }%1
1307 push{w}\t%1"
1308 [(set_attr "type" "push")
1309 (set_attr "mode" "HI")])
1310
1311 ;; For 64BIT abi we always round up to 8 bytes.
1312 (define_insn "*pushhi2_rex64"
1313 [(set (match_operand:HI 0 "push_operand" "=X")
1314 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1315 "TARGET_64BIT"
1316 "push{q}\t%q1"
1317 [(set_attr "type" "push")
1318 (set_attr "mode" "QI")])
1319
1320 (define_insn "*movhi_1"
1321 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1322 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1323 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1324 {
1325 switch (get_attr_type (insn))
1326 {
1327 case TYPE_IMOVX:
1328 /* movzwl is faster than movw on p2 due to partial word stalls,
1329 though not as fast as an aligned movl. */
1330 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1331 default:
1332 if (get_attr_mode (insn) == MODE_SI)
1333 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1334 else
1335 return "mov{w}\t{%1, %0|%0, %1}";
1336 }
1337 }
1338 [(set (attr "type")
1339 (cond [(and (eq_attr "alternative" "0")
1340 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341 (const_int 0))
1342 (eq (symbol_ref "TARGET_HIMODE_MATH")
1343 (const_int 0))))
1344 (const_string "imov")
1345 (and (eq_attr "alternative" "1,2")
1346 (match_operand:HI 1 "aligned_operand" ""))
1347 (const_string "imov")
1348 (and (ne (symbol_ref "TARGET_MOVX")
1349 (const_int 0))
1350 (eq_attr "alternative" "0,2"))
1351 (const_string "imovx")
1352 ]
1353 (const_string "imov")))
1354 (set (attr "mode")
1355 (cond [(eq_attr "type" "imovx")
1356 (const_string "SI")
1357 (and (eq_attr "alternative" "1,2")
1358 (match_operand:HI 1 "aligned_operand" ""))
1359 (const_string "SI")
1360 (and (eq_attr "alternative" "0")
1361 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1362 (const_int 0))
1363 (eq (symbol_ref "TARGET_HIMODE_MATH")
1364 (const_int 0))))
1365 (const_string "SI")
1366 ]
1367 (const_string "HI")))])
1368
1369 ;; Stores and loads of ax to arbitrary constant address.
1370 ;; We fake an second form of instruction to force reload to load address
1371 ;; into register when rax is not available
1372 (define_insn "*movabshi_1_rex64"
1373 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1374 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1375 "TARGET_64BIT"
1376 "@
1377 movabs{w}\t{%1, %P0|%P0, %1}
1378 mov{w}\t{%1, %a0|%a0, %1}
1379 movabs{w}\t{%1, %a0|%a0, %1}"
1380 [(set_attr "type" "imov")
1381 (set_attr "modrm" "0,*,*")
1382 (set_attr "length_address" "8,0,0")
1383 (set_attr "length_immediate" "0,*,*")
1384 (set_attr "memory" "store")
1385 (set_attr "mode" "HI")])
1386
1387 (define_insn "*movabshi_2_rex64"
1388 [(set (match_operand:HI 0 "register_operand" "=a,r")
1389 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1390 "TARGET_64BIT"
1391 "@
1392 movabs{w}\t{%P1, %0|%0, %P1}
1393 mov{w}\t{%a1, %0|%0, %a1}"
1394 [(set_attr "type" "imov")
1395 (set_attr "modrm" "0,*")
1396 (set_attr "length_address" "8,0")
1397 (set_attr "length_immediate" "0")
1398 (set_attr "memory" "load")
1399 (set_attr "mode" "HI")])
1400
1401 (define_insn "*swaphi_1"
1402 [(set (match_operand:HI 0 "register_operand" "+r")
1403 (match_operand:HI 1 "register_operand" "+r"))
1404 (set (match_dup 1)
1405 (match_dup 0))]
1406 "TARGET_PARTIAL_REG_STALL"
1407 "xchg{w}\t%1, %0"
1408 [(set_attr "type" "imov")
1409 (set_attr "pent_pair" "np")
1410 (set_attr "mode" "HI")
1411 (set_attr "modrm" "0")
1412 (set_attr "ppro_uops" "few")])
1413
1414 (define_insn "*swaphi_2"
1415 [(set (match_operand:HI 0 "register_operand" "+r")
1416 (match_operand:HI 1 "register_operand" "+r"))
1417 (set (match_dup 1)
1418 (match_dup 0))]
1419 "! TARGET_PARTIAL_REG_STALL"
1420 "xchg{l}\t%k1, %k0"
1421 [(set_attr "type" "imov")
1422 (set_attr "pent_pair" "np")
1423 (set_attr "mode" "SI")
1424 (set_attr "modrm" "0")
1425 (set_attr "ppro_uops" "few")])
1426
1427 (define_expand "movstricthi"
1428 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1429 (match_operand:HI 1 "general_operand" ""))]
1430 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1431 {
1432 /* Don't generate memory->memory moves, go through a register */
1433 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1434 operands[1] = force_reg (HImode, operands[1]);
1435 })
1436
1437 (define_insn "*movstricthi_1"
1438 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1439 (match_operand:HI 1 "general_operand" "rn,m"))]
1440 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1441 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1442 "mov{w}\t{%1, %0|%0, %1}"
1443 [(set_attr "type" "imov")
1444 (set_attr "mode" "HI")])
1445
1446 (define_insn "*movstricthi_xor"
1447 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1448 (match_operand:HI 1 "const0_operand" "i"))
1449 (clobber (reg:CC 17))]
1450 "reload_completed
1451 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1452 "xor{w}\t{%0, %0|%0, %0}"
1453 [(set_attr "type" "alu1")
1454 (set_attr "mode" "HI")
1455 (set_attr "length_immediate" "0")])
1456
1457 (define_expand "movqi"
1458 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1459 (match_operand:QI 1 "general_operand" ""))]
1460 ""
1461 "ix86_expand_move (QImode, operands); DONE;")
1462
1463 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1464 ;; "push a byte". But actually we use pushw, which has the effect
1465 ;; of rounding the amount pushed up to a halfword.
1466
1467 (define_insn "*pushqi2"
1468 [(set (match_operand:QI 0 "push_operand" "=X,X")
1469 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1470 "!TARGET_64BIT"
1471 "@
1472 push{w}\t{|word ptr }%1
1473 push{w}\t%w1"
1474 [(set_attr "type" "push")
1475 (set_attr "mode" "HI")])
1476
1477 ;; For 64BIT abi we always round up to 8 bytes.
1478 (define_insn "*pushqi2_rex64"
1479 [(set (match_operand:QI 0 "push_operand" "=X")
1480 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1481 "TARGET_64BIT"
1482 "push{q}\t%q1"
1483 [(set_attr "type" "push")
1484 (set_attr "mode" "QI")])
1485
1486 ;; Situation is quite tricky about when to choose full sized (SImode) move
1487 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1488 ;; partial register dependency machines (such as AMD Athlon), where QImode
1489 ;; moves issue extra dependency and for partial register stalls machines
1490 ;; that don't use QImode patterns (and QImode move cause stall on the next
1491 ;; instruction).
1492 ;;
1493 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1494 ;; register stall machines with, where we use QImode instructions, since
1495 ;; partial register stall can be caused there. Then we use movzx.
1496 (define_insn "*movqi_1"
1497 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1498 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1499 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1500 {
1501 switch (get_attr_type (insn))
1502 {
1503 case TYPE_IMOVX:
1504 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1505 abort ();
1506 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1507 default:
1508 if (get_attr_mode (insn) == MODE_SI)
1509 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1510 else
1511 return "mov{b}\t{%1, %0|%0, %1}";
1512 }
1513 }
1514 [(set (attr "type")
1515 (cond [(and (eq_attr "alternative" "3")
1516 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1517 (const_int 0))
1518 (eq (symbol_ref "TARGET_QIMODE_MATH")
1519 (const_int 0))))
1520 (const_string "imov")
1521 (eq_attr "alternative" "3,5")
1522 (const_string "imovx")
1523 (and (ne (symbol_ref "TARGET_MOVX")
1524 (const_int 0))
1525 (eq_attr "alternative" "2"))
1526 (const_string "imovx")
1527 ]
1528 (const_string "imov")))
1529 (set (attr "mode")
1530 (cond [(eq_attr "alternative" "3,4,5")
1531 (const_string "SI")
1532 (eq_attr "alternative" "6")
1533 (const_string "QI")
1534 (eq_attr "type" "imovx")
1535 (const_string "SI")
1536 (and (eq_attr "type" "imov")
1537 (and (eq_attr "alternative" "0,1,2")
1538 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1539 (const_int 0))))
1540 (const_string "SI")
1541 ;; Avoid partial register stalls when not using QImode arithmetic
1542 (and (eq_attr "type" "imov")
1543 (and (eq_attr "alternative" "0,1,2")
1544 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1545 (const_int 0))
1546 (eq (symbol_ref "TARGET_QIMODE_MATH")
1547 (const_int 0)))))
1548 (const_string "SI")
1549 ]
1550 (const_string "QI")))])
1551
1552 (define_expand "reload_outqi"
1553 [(parallel [(match_operand:QI 0 "" "=m")
1554 (match_operand:QI 1 "register_operand" "r")
1555 (match_operand:QI 2 "register_operand" "=&q")])]
1556 ""
1557 {
1558 rtx op0, op1, op2;
1559 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1560
1561 if (reg_overlap_mentioned_p (op2, op0))
1562 abort ();
1563 if (! q_regs_operand (op1, QImode))
1564 {
1565 emit_insn (gen_movqi (op2, op1));
1566 op1 = op2;
1567 }
1568 emit_insn (gen_movqi (op0, op1));
1569 DONE;
1570 })
1571
1572 (define_insn "*swapqi"
1573 [(set (match_operand:QI 0 "register_operand" "+r")
1574 (match_operand:QI 1 "register_operand" "+r"))
1575 (set (match_dup 1)
1576 (match_dup 0))]
1577 ""
1578 "xchg{b}\t%1, %0"
1579 [(set_attr "type" "imov")
1580 (set_attr "pent_pair" "np")
1581 (set_attr "mode" "QI")
1582 (set_attr "modrm" "0")
1583 (set_attr "ppro_uops" "few")])
1584
1585 (define_expand "movstrictqi"
1586 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1587 (match_operand:QI 1 "general_operand" ""))]
1588 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1589 {
1590 /* Don't generate memory->memory moves, go through a register. */
1591 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1592 operands[1] = force_reg (QImode, operands[1]);
1593 })
1594
1595 (define_insn "*movstrictqi_1"
1596 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1597 (match_operand:QI 1 "general_operand" "*qn,m"))]
1598 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1599 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1600 "mov{b}\t{%1, %0|%0, %1}"
1601 [(set_attr "type" "imov")
1602 (set_attr "mode" "QI")])
1603
1604 (define_insn "*movstrictqi_xor"
1605 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1606 (match_operand:QI 1 "const0_operand" "i"))
1607 (clobber (reg:CC 17))]
1608 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1609 "xor{b}\t{%0, %0|%0, %0}"
1610 [(set_attr "type" "alu1")
1611 (set_attr "mode" "QI")
1612 (set_attr "length_immediate" "0")])
1613
1614 (define_insn "*movsi_extv_1"
1615 [(set (match_operand:SI 0 "register_operand" "=R")
1616 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1617 (const_int 8)
1618 (const_int 8)))]
1619 ""
1620 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1621 [(set_attr "type" "imovx")
1622 (set_attr "mode" "SI")])
1623
1624 (define_insn "*movhi_extv_1"
1625 [(set (match_operand:HI 0 "register_operand" "=R")
1626 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1627 (const_int 8)
1628 (const_int 8)))]
1629 ""
1630 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1631 [(set_attr "type" "imovx")
1632 (set_attr "mode" "SI")])
1633
1634 (define_insn "*movqi_extv_1"
1635 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1636 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1637 (const_int 8)
1638 (const_int 8)))]
1639 "!TARGET_64BIT"
1640 {
1641 switch (get_attr_type (insn))
1642 {
1643 case TYPE_IMOVX:
1644 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1645 default:
1646 return "mov{b}\t{%h1, %0|%0, %h1}";
1647 }
1648 }
1649 [(set (attr "type")
1650 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1651 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1652 (ne (symbol_ref "TARGET_MOVX")
1653 (const_int 0))))
1654 (const_string "imovx")
1655 (const_string "imov")))
1656 (set (attr "mode")
1657 (if_then_else (eq_attr "type" "imovx")
1658 (const_string "SI")
1659 (const_string "QI")))])
1660
1661 (define_insn "*movqi_extv_1_rex64"
1662 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1663 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1664 (const_int 8)
1665 (const_int 8)))]
1666 "TARGET_64BIT"
1667 {
1668 switch (get_attr_type (insn))
1669 {
1670 case TYPE_IMOVX:
1671 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1672 default:
1673 return "mov{b}\t{%h1, %0|%0, %h1}";
1674 }
1675 }
1676 [(set (attr "type")
1677 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1678 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1679 (ne (symbol_ref "TARGET_MOVX")
1680 (const_int 0))))
1681 (const_string "imovx")
1682 (const_string "imov")))
1683 (set (attr "mode")
1684 (if_then_else (eq_attr "type" "imovx")
1685 (const_string "SI")
1686 (const_string "QI")))])
1687
1688 ;; Stores and loads of ax to arbitrary constant address.
1689 ;; We fake an second form of instruction to force reload to load address
1690 ;; into register when rax is not available
1691 (define_insn "*movabsqi_1_rex64"
1692 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1693 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1694 "TARGET_64BIT"
1695 "@
1696 movabs{b}\t{%1, %P0|%P0, %1}
1697 mov{b}\t{%1, %a0|%a0, %1}
1698 movabs{b}\t{%1, %a0|%a0, %1}"
1699 [(set_attr "type" "imov")
1700 (set_attr "modrm" "0,*,*")
1701 (set_attr "length_address" "8,0,0")
1702 (set_attr "length_immediate" "0,*,*")
1703 (set_attr "memory" "store")
1704 (set_attr "mode" "QI")])
1705
1706 (define_insn "*movabsqi_2_rex64"
1707 [(set (match_operand:QI 0 "register_operand" "=a,r")
1708 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1709 "TARGET_64BIT"
1710 "@
1711 movabs{b}\t{%P1, %0|%0, %P1}
1712 mov{b}\t{%a1, %0|%0, %a1}"
1713 [(set_attr "type" "imov")
1714 (set_attr "modrm" "0,*")
1715 (set_attr "length_address" "8,0")
1716 (set_attr "length_immediate" "0")
1717 (set_attr "memory" "load")
1718 (set_attr "mode" "QI")])
1719
1720 (define_insn "*movsi_extzv_1"
1721 [(set (match_operand:SI 0 "register_operand" "=R")
1722 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723 (const_int 8)
1724 (const_int 8)))]
1725 ""
1726 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727 [(set_attr "type" "imovx")
1728 (set_attr "mode" "SI")])
1729
1730 (define_insn "*movqi_extzv_2"
1731 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733 (const_int 8)
1734 (const_int 8)) 0))]
1735 "!TARGET_64BIT"
1736 {
1737 switch (get_attr_type (insn))
1738 {
1739 case TYPE_IMOVX:
1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741 default:
1742 return "mov{b}\t{%h1, %0|%0, %h1}";
1743 }
1744 }
1745 [(set (attr "type")
1746 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748 (ne (symbol_ref "TARGET_MOVX")
1749 (const_int 0))))
1750 (const_string "imovx")
1751 (const_string "imov")))
1752 (set (attr "mode")
1753 (if_then_else (eq_attr "type" "imovx")
1754 (const_string "SI")
1755 (const_string "QI")))])
1756
1757 (define_insn "*movqi_extzv_2_rex64"
1758 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760 (const_int 8)
1761 (const_int 8)) 0))]
1762 "TARGET_64BIT"
1763 {
1764 switch (get_attr_type (insn))
1765 {
1766 case TYPE_IMOVX:
1767 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768 default:
1769 return "mov{b}\t{%h1, %0|%0, %h1}";
1770 }
1771 }
1772 [(set (attr "type")
1773 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774 (ne (symbol_ref "TARGET_MOVX")
1775 (const_int 0)))
1776 (const_string "imovx")
1777 (const_string "imov")))
1778 (set (attr "mode")
1779 (if_then_else (eq_attr "type" "imovx")
1780 (const_string "SI")
1781 (const_string "QI")))])
1782
1783 (define_insn "movsi_insv_1"
1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785 (const_int 8)
1786 (const_int 8))
1787 (match_operand:SI 1 "general_operand" "Qmn"))]
1788 "!TARGET_64BIT"
1789 "mov{b}\t{%b1, %h0|%h0, %b1}"
1790 [(set_attr "type" "imov")
1791 (set_attr "mode" "QI")])
1792
1793 (define_insn "*movsi_insv_1_rex64"
1794 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1795 (const_int 8)
1796 (const_int 8))
1797 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1798 "TARGET_64BIT"
1799 "mov{b}\t{%b1, %h0|%h0, %b1}"
1800 [(set_attr "type" "imov")
1801 (set_attr "mode" "QI")])
1802
1803 (define_insn "*movqi_insv_2"
1804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1805 (const_int 8)
1806 (const_int 8))
1807 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1808 (const_int 8))
1809 (const_int 255)))]
1810 ""
1811 "mov{b}\t{%h1, %h0|%h0, %h1}"
1812 [(set_attr "type" "imov")
1813 (set_attr "mode" "QI")])
1814
1815 (define_expand "movdi"
1816 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1817 (match_operand:DI 1 "general_operand" ""))]
1818 ""
1819 "ix86_expand_move (DImode, operands); DONE;")
1820
1821 (define_insn "*pushdi"
1822 [(set (match_operand:DI 0 "push_operand" "=<")
1823 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1824 "!TARGET_64BIT"
1825 "#")
1826
1827 (define_insn "pushdi2_rex64"
1828 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1829 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1830 "TARGET_64BIT"
1831 "@
1832 push{q}\t%1
1833 #"
1834 [(set_attr "type" "push,multi")
1835 (set_attr "mode" "DI")])
1836
1837 ;; Convert impossible pushes of immediate to existing instructions.
1838 ;; First try to get scratch register and go through it. In case this
1839 ;; fails, push sign extended lower part first and then overwrite
1840 ;; upper part by 32bit move.
1841 (define_peephole2
1842 [(match_scratch:DI 2 "r")
1843 (set (match_operand:DI 0 "push_operand" "")
1844 (match_operand:DI 1 "immediate_operand" ""))]
1845 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1846 && !x86_64_immediate_operand (operands[1], DImode)"
1847 [(set (match_dup 2) (match_dup 1))
1848 (set (match_dup 0) (match_dup 2))]
1849 "")
1850
1851 ;; We need to define this as both peepholer and splitter for case
1852 ;; peephole2 pass is not run.
1853 (define_peephole2
1854 [(set (match_operand:DI 0 "push_operand" "")
1855 (match_operand:DI 1 "immediate_operand" ""))]
1856 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858 [(set (match_dup 0) (match_dup 1))
1859 (set (match_dup 2) (match_dup 3))]
1860 "split_di (operands + 1, 1, operands + 2, operands + 3);
1861 operands[1] = gen_lowpart (DImode, operands[2]);
1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863 GEN_INT (4)));
1864 ")
1865
1866 (define_split
1867 [(set (match_operand:DI 0 "push_operand" "")
1868 (match_operand:DI 1 "immediate_operand" ""))]
1869 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1870 && !symbolic_operand (operands[1], DImode)
1871 && !x86_64_immediate_operand (operands[1], DImode)"
1872 [(set (match_dup 0) (match_dup 1))
1873 (set (match_dup 2) (match_dup 3))]
1874 "split_di (operands + 1, 1, operands + 2, operands + 3);
1875 operands[1] = gen_lowpart (DImode, operands[2]);
1876 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1877 GEN_INT (4)));
1878 ")
1879
1880 (define_insn "*pushdi2_prologue_rex64"
1881 [(set (match_operand:DI 0 "push_operand" "=<")
1882 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883 (clobber (mem:BLK (scratch)))]
1884 "TARGET_64BIT"
1885 "push{q}\t%1"
1886 [(set_attr "type" "push")
1887 (set_attr "mode" "DI")])
1888
1889 (define_insn "*popdi1_epilogue_rex64"
1890 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891 (mem:DI (reg:DI 7)))
1892 (set (reg:DI 7)
1893 (plus:DI (reg:DI 7) (const_int 8)))
1894 (clobber (mem:BLK (scratch)))]
1895 "TARGET_64BIT"
1896 "pop{q}\t%0"
1897 [(set_attr "type" "pop")
1898 (set_attr "mode" "DI")])
1899
1900 (define_insn "popdi1"
1901 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902 (mem:DI (reg:DI 7)))
1903 (set (reg:DI 7)
1904 (plus:DI (reg:DI 7) (const_int 8)))]
1905 "TARGET_64BIT"
1906 "pop{q}\t%0"
1907 [(set_attr "type" "pop")
1908 (set_attr "mode" "DI")])
1909
1910 (define_insn "*movdi_xor_rex64"
1911 [(set (match_operand:DI 0 "register_operand" "=r")
1912 (match_operand:DI 1 "const0_operand" "i"))
1913 (clobber (reg:CC 17))]
1914 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915 && reload_completed"
1916 "xor{l}\t{%k0, %k0|%k0, %k0}"
1917 [(set_attr "type" "alu1")
1918 (set_attr "mode" "SI")
1919 (set_attr "length_immediate" "0")])
1920
1921 (define_insn "*movdi_or_rex64"
1922 [(set (match_operand:DI 0 "register_operand" "=r")
1923 (match_operand:DI 1 "const_int_operand" "i"))
1924 (clobber (reg:CC 17))]
1925 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1926 && reload_completed
1927 && GET_CODE (operands[1]) == CONST_INT
1928 && INTVAL (operands[1]) == -1"
1929 {
1930 operands[1] = constm1_rtx;
1931 return "or{q}\t{%1, %0|%0, %1}";
1932 }
1933 [(set_attr "type" "alu1")
1934 (set_attr "mode" "DI")
1935 (set_attr "length_immediate" "1")])
1936
1937 (define_insn "*movdi_2"
1938 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1939 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1940 "!TARGET_64BIT
1941 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1942 "@
1943 #
1944 #
1945 movq\t{%1, %0|%0, %1}
1946 movq\t{%1, %0|%0, %1}
1947 movq\t{%1, %0|%0, %1}
1948 movdqa\t{%1, %0|%0, %1}
1949 movq\t{%1, %0|%0, %1}"
1950 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1951 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1952
1953 (define_split
1954 [(set (match_operand:DI 0 "push_operand" "")
1955 (match_operand:DI 1 "general_operand" ""))]
1956 "!TARGET_64BIT && reload_completed
1957 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1958 [(const_int 0)]
1959 "ix86_split_long_move (operands); DONE;")
1960
1961 ;; %%% This multiword shite has got to go.
1962 (define_split
1963 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1964 (match_operand:DI 1 "general_operand" ""))]
1965 "!TARGET_64BIT && reload_completed
1966 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1967 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1968 [(const_int 0)]
1969 "ix86_split_long_move (operands); DONE;")
1970
1971 (define_insn "*movdi_1_rex64"
1972 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1973 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1974 "TARGET_64BIT
1975 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1976 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1977 {
1978 switch (get_attr_type (insn))
1979 {
1980 case TYPE_SSEMOV:
1981 if (get_attr_mode (insn) == MODE_TI)
1982 return "movdqa\t{%1, %0|%0, %1}";
1983 /* FALLTHRU */
1984 case TYPE_MMXMOV:
1985 /* Moves from and into integer register is done using movd opcode with
1986 REX prefix. */
1987 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1988 return "movd\t{%1, %0|%0, %1}";
1989 return "movq\t{%1, %0|%0, %1}";
1990 case TYPE_MULTI:
1991 return "#";
1992 case TYPE_LEA:
1993 return "lea{q}\t{%a1, %0|%0, %a1}";
1994 default:
1995 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1996 abort ();
1997 if (get_attr_mode (insn) == MODE_SI)
1998 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1999 else if (which_alternative == 2)
2000 return "movabs{q}\t{%1, %0|%0, %1}";
2001 else
2002 return "mov{q}\t{%1, %0|%0, %1}";
2003 }
2004 }
2005 [(set (attr "type")
2006 (cond [(eq_attr "alternative" "5,6,7")
2007 (const_string "mmxmov")
2008 (eq_attr "alternative" "8,9,10")
2009 (const_string "ssemov")
2010 (eq_attr "alternative" "4")
2011 (const_string "multi")
2012 (and (ne (symbol_ref "flag_pic") (const_int 0))
2013 (match_operand:DI 1 "symbolic_operand" ""))
2014 (const_string "lea")
2015 ]
2016 (const_string "imov")))
2017 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2018 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2019 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2020
2021 (define_insn "*movdi_1_rex64_nointerunit"
2022 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2023 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2024 "TARGET_64BIT
2025 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2026 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2027 {
2028 switch (get_attr_type (insn))
2029 {
2030 case TYPE_SSEMOV:
2031 if (get_attr_mode (insn) == MODE_TI)
2032 return "movdqa\t{%1, %0|%0, %1}";
2033 /* FALLTHRU */
2034 case TYPE_MMXMOV:
2035 return "movq\t{%1, %0|%0, %1}";
2036 case TYPE_MULTI:
2037 return "#";
2038 case TYPE_LEA:
2039 return "lea{q}\t{%a1, %0|%0, %a1}";
2040 default:
2041 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2042 abort ();
2043 if (get_attr_mode (insn) == MODE_SI)
2044 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2045 else if (which_alternative == 2)
2046 return "movabs{q}\t{%1, %0|%0, %1}";
2047 else
2048 return "mov{q}\t{%1, %0|%0, %1}";
2049 }
2050 }
2051 [(set (attr "type")
2052 (cond [(eq_attr "alternative" "5,6,7")
2053 (const_string "mmxmov")
2054 (eq_attr "alternative" "8,9,10")
2055 (const_string "ssemov")
2056 (eq_attr "alternative" "4")
2057 (const_string "multi")
2058 (and (ne (symbol_ref "flag_pic") (const_int 0))
2059 (match_operand:DI 1 "symbolic_operand" ""))
2060 (const_string "lea")
2061 ]
2062 (const_string "imov")))
2063 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2064 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2065 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2066
2067 ;; Stores and loads of ax to arbitrary constant address.
2068 ;; We fake an second form of instruction to force reload to load address
2069 ;; into register when rax is not available
2070 (define_insn "*movabsdi_1_rex64"
2071 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2072 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2073 "TARGET_64BIT"
2074 "@
2075 movabs{q}\t{%1, %P0|%P0, %1}
2076 mov{q}\t{%1, %a0|%a0, %1}
2077 movabs{q}\t{%1, %a0|%a0, %1}"
2078 [(set_attr "type" "imov")
2079 (set_attr "modrm" "0,*,*")
2080 (set_attr "length_address" "8,0,0")
2081 (set_attr "length_immediate" "0,*,*")
2082 (set_attr "memory" "store")
2083 (set_attr "mode" "DI")])
2084
2085 (define_insn "*movabsdi_2_rex64"
2086 [(set (match_operand:DI 0 "register_operand" "=a,r")
2087 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2088 "TARGET_64BIT"
2089 "@
2090 movabs{q}\t{%P1, %0|%0, %P1}
2091 mov{q}\t{%a1, %0|%0, %a1}"
2092 [(set_attr "type" "imov")
2093 (set_attr "modrm" "0,*")
2094 (set_attr "length_address" "8,0")
2095 (set_attr "length_immediate" "0")
2096 (set_attr "memory" "load")
2097 (set_attr "mode" "DI")])
2098
2099 ;; Convert impossible stores of immediate to existing instructions.
2100 ;; First try to get scratch register and go through it. In case this
2101 ;; fails, move by 32bit parts.
2102 (define_peephole2
2103 [(match_scratch:DI 2 "r")
2104 (set (match_operand:DI 0 "memory_operand" "")
2105 (match_operand:DI 1 "immediate_operand" ""))]
2106 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2107 && !x86_64_immediate_operand (operands[1], DImode)"
2108 [(set (match_dup 2) (match_dup 1))
2109 (set (match_dup 0) (match_dup 2))]
2110 "")
2111
2112 ;; We need to define this as both peepholer and splitter for case
2113 ;; peephole2 pass is not run.
2114 (define_peephole2
2115 [(set (match_operand:DI 0 "memory_operand" "")
2116 (match_operand:DI 1 "immediate_operand" ""))]
2117 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2119 [(set (match_dup 2) (match_dup 3))
2120 (set (match_dup 4) (match_dup 5))]
2121 "split_di (operands, 2, operands + 2, operands + 4);")
2122
2123 (define_split
2124 [(set (match_operand:DI 0 "memory_operand" "")
2125 (match_operand:DI 1 "immediate_operand" ""))]
2126 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2127 && !symbolic_operand (operands[1], DImode)
2128 && !x86_64_immediate_operand (operands[1], DImode)"
2129 [(set (match_dup 2) (match_dup 3))
2130 (set (match_dup 4) (match_dup 5))]
2131 "split_di (operands, 2, operands + 2, operands + 4);")
2132
2133 (define_insn "*swapdi_rex64"
2134 [(set (match_operand:DI 0 "register_operand" "+r")
2135 (match_operand:DI 1 "register_operand" "+r"))
2136 (set (match_dup 1)
2137 (match_dup 0))]
2138 "TARGET_64BIT"
2139 "xchg{q}\t%1, %0"
2140 [(set_attr "type" "imov")
2141 (set_attr "pent_pair" "np")
2142 (set_attr "athlon_decode" "vector")
2143 (set_attr "mode" "DI")
2144 (set_attr "modrm" "0")
2145 (set_attr "ppro_uops" "few")])
2146
2147
2148 (define_expand "movsf"
2149 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2150 (match_operand:SF 1 "general_operand" ""))]
2151 ""
2152 "ix86_expand_move (SFmode, operands); DONE;")
2153
2154 (define_insn "*pushsf"
2155 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2156 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2157 "!TARGET_64BIT"
2158 {
2159 switch (which_alternative)
2160 {
2161 case 1:
2162 return "push{l}\t%1";
2163
2164 default:
2165 /* This insn should be already splitted before reg-stack. */
2166 abort ();
2167 }
2168 }
2169 [(set_attr "type" "multi,push,multi")
2170 (set_attr "mode" "SF,SI,SF")])
2171
2172 (define_insn "*pushsf_rex64"
2173 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2174 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2175 "TARGET_64BIT"
2176 {
2177 switch (which_alternative)
2178 {
2179 case 1:
2180 return "push{q}\t%q1";
2181
2182 default:
2183 /* This insn should be already splitted before reg-stack. */
2184 abort ();
2185 }
2186 }
2187 [(set_attr "type" "multi,push,multi")
2188 (set_attr "mode" "SF,DI,SF")])
2189
2190 (define_split
2191 [(set (match_operand:SF 0 "push_operand" "")
2192 (match_operand:SF 1 "memory_operand" ""))]
2193 "reload_completed
2194 && GET_CODE (operands[1]) == MEM
2195 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2196 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2197 [(set (match_dup 0)
2198 (match_dup 1))]
2199 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2200
2201
2202 ;; %%% Kill this when call knows how to work this out.
2203 (define_split
2204 [(set (match_operand:SF 0 "push_operand" "")
2205 (match_operand:SF 1 "any_fp_register_operand" ""))]
2206 "!TARGET_64BIT"
2207 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2208 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2209
2210 (define_split
2211 [(set (match_operand:SF 0 "push_operand" "")
2212 (match_operand:SF 1 "any_fp_register_operand" ""))]
2213 "TARGET_64BIT"
2214 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2215 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2216
2217 (define_insn "*movsf_1"
2218 [(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")
2219 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2220 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2221 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2222 && (reload_in_progress || reload_completed
2223 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2224 || GET_CODE (operands[1]) != CONST_DOUBLE
2225 || memory_operand (operands[0], SFmode))"
2226 {
2227 switch (which_alternative)
2228 {
2229 case 0:
2230 if (REG_P (operands[1])
2231 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2232 return "fstp\t%y0";
2233 else if (STACK_TOP_P (operands[0]))
2234 return "fld%z1\t%y1";
2235 else
2236 return "fst\t%y0";
2237
2238 case 1:
2239 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2240 return "fstp%z0\t%y0";
2241 else
2242 return "fst%z0\t%y0";
2243
2244 case 2:
2245 return standard_80387_constant_opcode (operands[1]);
2246
2247 case 3:
2248 case 4:
2249 return "mov{l}\t{%1, %0|%0, %1}";
2250 case 5:
2251 if (get_attr_mode (insn) == MODE_TI)
2252 return "pxor\t%0, %0";
2253 else
2254 return "xorps\t%0, %0";
2255 case 6:
2256 if (get_attr_mode (insn) == MODE_V4SF)
2257 return "movaps\t{%1, %0|%0, %1}";
2258 else
2259 return "movss\t{%1, %0|%0, %1}";
2260 case 7:
2261 case 8:
2262 return "movss\t{%1, %0|%0, %1}";
2263
2264 case 9:
2265 case 10:
2266 return "movd\t{%1, %0|%0, %1}";
2267
2268 case 11:
2269 return "movq\t{%1, %0|%0, %1}";
2270
2271 default:
2272 abort();
2273 }
2274 }
2275 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2276 (set (attr "mode")
2277 (cond [(eq_attr "alternative" "3,4,9,10")
2278 (const_string "SI")
2279 (eq_attr "alternative" "5")
2280 (if_then_else
2281 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2282 (const_int 0))
2283 (ne (symbol_ref "TARGET_SSE2")
2284 (const_int 0)))
2285 (eq (symbol_ref "optimize_size")
2286 (const_int 0)))
2287 (const_string "TI")
2288 (const_string "V4SF"))
2289 /* For architectures resolving dependencies on
2290 whole SSE registers use APS move to break dependency
2291 chains, otherwise use short move to avoid extra work.
2292
2293 Do the same for architectures resolving dependencies on
2294 the parts. While in DF mode it is better to always handle
2295 just register parts, the SF mode is different due to lack
2296 of instructions to load just part of the register. It is
2297 better to maintain the whole registers in single format
2298 to avoid problems on using packed logical operations. */
2299 (eq_attr "alternative" "6")
2300 (if_then_else
2301 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2302 (const_int 0))
2303 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2304 (const_int 0)))
2305 (const_string "V4SF")
2306 (const_string "SF"))
2307 (eq_attr "alternative" "11")
2308 (const_string "DI")]
2309 (const_string "SF")))])
2310
2311 (define_insn "*movsf_1_nointerunit"
2312 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2313 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2314 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2315 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2316 && (reload_in_progress || reload_completed
2317 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2318 || GET_CODE (operands[1]) != CONST_DOUBLE
2319 || memory_operand (operands[0], SFmode))"
2320 {
2321 switch (which_alternative)
2322 {
2323 case 0:
2324 if (REG_P (operands[1])
2325 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2326 {
2327 if (REGNO (operands[0]) == FIRST_STACK_REG
2328 && TARGET_USE_FFREEP)
2329 return "ffreep\t%y0";
2330 return "fstp\t%y0";
2331 }
2332 else if (STACK_TOP_P (operands[0]))
2333 return "fld%z1\t%y1";
2334 else
2335 return "fst\t%y0";
2336
2337 case 1:
2338 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2339 return "fstp%z0\t%y0";
2340 else
2341 return "fst%z0\t%y0";
2342
2343 case 2:
2344 return standard_80387_constant_opcode (operands[1]);
2345
2346 case 3:
2347 case 4:
2348 return "mov{l}\t{%1, %0|%0, %1}";
2349 case 5:
2350 if (get_attr_mode (insn) == MODE_TI)
2351 return "pxor\t%0, %0";
2352 else
2353 return "xorps\t%0, %0";
2354 case 6:
2355 if (get_attr_mode (insn) == MODE_V4SF)
2356 return "movaps\t{%1, %0|%0, %1}";
2357 else
2358 return "movss\t{%1, %0|%0, %1}";
2359 case 7:
2360 case 8:
2361 return "movss\t{%1, %0|%0, %1}";
2362
2363 case 9:
2364 case 10:
2365 return "movd\t{%1, %0|%0, %1}";
2366
2367 case 11:
2368 return "movq\t{%1, %0|%0, %1}";
2369
2370 default:
2371 abort();
2372 }
2373 }
2374 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2375 (set (attr "mode")
2376 (cond [(eq_attr "alternative" "3,4,9,10")
2377 (const_string "SI")
2378 (eq_attr "alternative" "5")
2379 (if_then_else
2380 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2381 (const_int 0))
2382 (ne (symbol_ref "TARGET_SSE2")
2383 (const_int 0)))
2384 (eq (symbol_ref "optimize_size")
2385 (const_int 0)))
2386 (const_string "TI")
2387 (const_string "V4SF"))
2388 /* For architectures resolving dependencies on
2389 whole SSE registers use APS move to break dependency
2390 chains, otherwise use short move to avoid extra work.
2391
2392 Do the same for architectures resolving dependencies on
2393 the parts. While in DF mode it is better to always handle
2394 just register parts, the SF mode is different due to lack
2395 of instructions to load just part of the register. It is
2396 better to maintain the whole registers in single format
2397 to avoid problems on using packed logical operations. */
2398 (eq_attr "alternative" "6")
2399 (if_then_else
2400 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2401 (const_int 0))
2402 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2403 (const_int 0)))
2404 (const_string "V4SF")
2405 (const_string "SF"))
2406 (eq_attr "alternative" "11")
2407 (const_string "DI")]
2408 (const_string "SF")))])
2409
2410 (define_insn "*swapsf"
2411 [(set (match_operand:SF 0 "register_operand" "+f")
2412 (match_operand:SF 1 "register_operand" "+f"))
2413 (set (match_dup 1)
2414 (match_dup 0))]
2415 "reload_completed || !TARGET_SSE"
2416 {
2417 if (STACK_TOP_P (operands[0]))
2418 return "fxch\t%1";
2419 else
2420 return "fxch\t%0";
2421 }
2422 [(set_attr "type" "fxch")
2423 (set_attr "mode" "SF")])
2424
2425 (define_expand "movdf"
2426 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2427 (match_operand:DF 1 "general_operand" ""))]
2428 ""
2429 "ix86_expand_move (DFmode, operands); DONE;")
2430
2431 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2432 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2433 ;; On the average, pushdf using integers can be still shorter. Allow this
2434 ;; pattern for optimize_size too.
2435
2436 (define_insn "*pushdf_nointeger"
2437 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2438 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2439 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2440 {
2441 /* This insn should be already splitted before reg-stack. */
2442 abort ();
2443 }
2444 [(set_attr "type" "multi")
2445 (set_attr "mode" "DF,SI,SI,DF")])
2446
2447 (define_insn "*pushdf_integer"
2448 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2449 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2450 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2451 {
2452 /* This insn should be already splitted before reg-stack. */
2453 abort ();
2454 }
2455 [(set_attr "type" "multi")
2456 (set_attr "mode" "DF,SI,DF")])
2457
2458 ;; %%% Kill this when call knows how to work this out.
2459 (define_split
2460 [(set (match_operand:DF 0 "push_operand" "")
2461 (match_operand:DF 1 "any_fp_register_operand" ""))]
2462 "!TARGET_64BIT && reload_completed"
2463 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2464 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2465 "")
2466
2467 (define_split
2468 [(set (match_operand:DF 0 "push_operand" "")
2469 (match_operand:DF 1 "any_fp_register_operand" ""))]
2470 "TARGET_64BIT && reload_completed"
2471 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2472 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2473 "")
2474
2475 (define_split
2476 [(set (match_operand:DF 0 "push_operand" "")
2477 (match_operand:DF 1 "general_operand" ""))]
2478 "reload_completed"
2479 [(const_int 0)]
2480 "ix86_split_long_move (operands); DONE;")
2481
2482 ;; Moving is usually shorter when only FP registers are used. This separate
2483 ;; movdf pattern avoids the use of integer registers for FP operations
2484 ;; when optimizing for size.
2485
2486 (define_insn "*movdf_nointeger"
2487 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2488 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2489 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2490 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2491 && (reload_in_progress || reload_completed
2492 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2493 || GET_CODE (operands[1]) != CONST_DOUBLE
2494 || memory_operand (operands[0], DFmode))"
2495 {
2496 switch (which_alternative)
2497 {
2498 case 0:
2499 if (REG_P (operands[1])
2500 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2501 {
2502 if (REGNO (operands[0]) == FIRST_STACK_REG
2503 && TARGET_USE_FFREEP)
2504 return "ffreep\t%y0";
2505 return "fstp\t%y0";
2506 }
2507 else if (STACK_TOP_P (operands[0]))
2508 return "fld%z1\t%y1";
2509 else
2510 return "fst\t%y0";
2511
2512 case 1:
2513 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2514 return "fstp%z0\t%y0";
2515 else
2516 return "fst%z0\t%y0";
2517
2518 case 2:
2519 return standard_80387_constant_opcode (operands[1]);
2520
2521 case 3:
2522 case 4:
2523 return "#";
2524 case 5:
2525 switch (get_attr_mode (insn))
2526 {
2527 case MODE_V4SF:
2528 return "xorps\t%0, %0";
2529 case MODE_V2DF:
2530 return "xorpd\t%0, %0";
2531 case MODE_TI:
2532 return "pxor\t%0, %0";
2533 default:
2534 abort ();
2535 }
2536 case 6:
2537 switch (get_attr_mode (insn))
2538 {
2539 case MODE_V4SF:
2540 return "movaps\t{%1, %0|%0, %1}";
2541 case MODE_V2DF:
2542 return "movapd\t{%1, %0|%0, %1}";
2543 case MODE_DF:
2544 return "movsd\t{%1, %0|%0, %1}";
2545 default:
2546 abort ();
2547 }
2548 case 7:
2549 if (get_attr_mode (insn) == MODE_V2DF)
2550 return "movlpd\t{%1, %0|%0, %1}";
2551 else
2552 return "movsd\t{%1, %0|%0, %1}";
2553 case 8:
2554 return "movsd\t{%1, %0|%0, %1}";
2555
2556 default:
2557 abort();
2558 }
2559 }
2560 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2561 (set (attr "mode")
2562 (cond [(eq_attr "alternative" "3,4")
2563 (const_string "SI")
2564 /* xorps is one byte shorter. */
2565 (eq_attr "alternative" "5")
2566 (cond [(ne (symbol_ref "optimize_size")
2567 (const_int 0))
2568 (const_string "V4SF")
2569 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2570 (const_int 0))
2571 (const_string "TI")]
2572 (const_string "V2DF"))
2573 /* For architectures resolving dependencies on
2574 whole SSE registers use APD move to break dependency
2575 chains, otherwise use short move to avoid extra work.
2576
2577 movaps encodes one byte shorter. */
2578 (eq_attr "alternative" "6")
2579 (cond
2580 [(ne (symbol_ref "optimize_size")
2581 (const_int 0))
2582 (const_string "V4SF")
2583 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2584 (const_int 0))
2585 (const_string "V2DF")]
2586 (const_string "DF"))
2587 /* For architectures resolving dependencies on register
2588 parts we may avoid extra work to zero out upper part
2589 of register. */
2590 (eq_attr "alternative" "7")
2591 (if_then_else
2592 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2593 (const_int 0))
2594 (const_string "V2DF")
2595 (const_string "DF"))]
2596 (const_string "DF")))])
2597
2598 (define_insn "*movdf_integer"
2599 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2600 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2601 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2602 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2603 && (reload_in_progress || reload_completed
2604 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2605 || GET_CODE (operands[1]) != CONST_DOUBLE
2606 || memory_operand (operands[0], DFmode))"
2607 {
2608 switch (which_alternative)
2609 {
2610 case 0:
2611 if (REG_P (operands[1])
2612 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2613 {
2614 if (REGNO (operands[0]) == FIRST_STACK_REG
2615 && TARGET_USE_FFREEP)
2616 return "ffreep\t%y0";
2617 return "fstp\t%y0";
2618 }
2619 else if (STACK_TOP_P (operands[0]))
2620 return "fld%z1\t%y1";
2621 else
2622 return "fst\t%y0";
2623
2624 case 1:
2625 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2626 return "fstp%z0\t%y0";
2627 else
2628 return "fst%z0\t%y0";
2629
2630 case 2:
2631 return standard_80387_constant_opcode (operands[1]);
2632
2633 case 3:
2634 case 4:
2635 return "#";
2636
2637 case 5:
2638 switch (get_attr_mode (insn))
2639 {
2640 case MODE_V4SF:
2641 return "xorps\t%0, %0";
2642 case MODE_V2DF:
2643 return "xorpd\t%0, %0";
2644 case MODE_TI:
2645 return "pxor\t%0, %0";
2646 default:
2647 abort ();
2648 }
2649 case 6:
2650 switch (get_attr_mode (insn))
2651 {
2652 case MODE_V4SF:
2653 return "movaps\t{%1, %0|%0, %1}";
2654 case MODE_V2DF:
2655 return "movapd\t{%1, %0|%0, %1}";
2656 case MODE_DF:
2657 return "movsd\t{%1, %0|%0, %1}";
2658 default:
2659 abort ();
2660 }
2661 case 7:
2662 if (get_attr_mode (insn) == MODE_V2DF)
2663 return "movlpd\t{%1, %0|%0, %1}";
2664 else
2665 return "movsd\t{%1, %0|%0, %1}";
2666 case 8:
2667 return "movsd\t{%1, %0|%0, %1}";
2668
2669 default:
2670 abort();
2671 }
2672 }
2673 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2674 (set (attr "mode")
2675 (cond [(eq_attr "alternative" "3,4")
2676 (const_string "SI")
2677 /* xorps is one byte shorter. */
2678 (eq_attr "alternative" "5")
2679 (cond [(ne (symbol_ref "optimize_size")
2680 (const_int 0))
2681 (const_string "V4SF")
2682 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2683 (const_int 0))
2684 (const_string "TI")]
2685 (const_string "V2DF"))
2686 /* For architectures resolving dependencies on
2687 whole SSE registers use APD move to break dependency
2688 chains, otherwise use short move to avoid extra work.
2689
2690 movaps encodes one byte shorter. */
2691 (eq_attr "alternative" "6")
2692 (cond
2693 [(ne (symbol_ref "optimize_size")
2694 (const_int 0))
2695 (const_string "V4SF")
2696 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2697 (const_int 0))
2698 (const_string "V2DF")]
2699 (const_string "DF"))
2700 /* For architectures resolving dependencies on register
2701 parts we may avoid extra work to zero out upper part
2702 of register. */
2703 (eq_attr "alternative" "7")
2704 (if_then_else
2705 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2706 (const_int 0))
2707 (const_string "V2DF")
2708 (const_string "DF"))]
2709 (const_string "DF")))])
2710
2711 (define_split
2712 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2713 (match_operand:DF 1 "general_operand" ""))]
2714 "reload_completed
2715 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2716 && ! (ANY_FP_REG_P (operands[0]) ||
2717 (GET_CODE (operands[0]) == SUBREG
2718 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2719 && ! (ANY_FP_REG_P (operands[1]) ||
2720 (GET_CODE (operands[1]) == SUBREG
2721 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2722 [(const_int 0)]
2723 "ix86_split_long_move (operands); DONE;")
2724
2725 (define_insn "*swapdf"
2726 [(set (match_operand:DF 0 "register_operand" "+f")
2727 (match_operand:DF 1 "register_operand" "+f"))
2728 (set (match_dup 1)
2729 (match_dup 0))]
2730 "reload_completed || !TARGET_SSE2"
2731 {
2732 if (STACK_TOP_P (operands[0]))
2733 return "fxch\t%1";
2734 else
2735 return "fxch\t%0";
2736 }
2737 [(set_attr "type" "fxch")
2738 (set_attr "mode" "DF")])
2739
2740 (define_expand "movxf"
2741 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2742 (match_operand:XF 1 "general_operand" ""))]
2743 "!TARGET_64BIT"
2744 "ix86_expand_move (XFmode, operands); DONE;")
2745
2746 (define_expand "movtf"
2747 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2748 (match_operand:TF 1 "general_operand" ""))]
2749 ""
2750 "ix86_expand_move (TFmode, operands); DONE;")
2751
2752 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2753 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2754 ;; Pushing using integer instructions is longer except for constants
2755 ;; and direct memory references.
2756 ;; (assuming that any given constant is pushed only once, but this ought to be
2757 ;; handled elsewhere).
2758
2759 (define_insn "*pushxf_nointeger"
2760 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2761 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2762 "!TARGET_64BIT && optimize_size"
2763 {
2764 /* This insn should be already splitted before reg-stack. */
2765 abort ();
2766 }
2767 [(set_attr "type" "multi")
2768 (set_attr "mode" "XF,SI,SI")])
2769
2770 (define_insn "*pushtf_nointeger"
2771 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2772 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2773 "optimize_size"
2774 {
2775 /* This insn should be already splitted before reg-stack. */
2776 abort ();
2777 }
2778 [(set_attr "type" "multi")
2779 (set_attr "mode" "XF,SI,SI")])
2780
2781 (define_insn "*pushxf_integer"
2782 [(set (match_operand:XF 0 "push_operand" "=<,<")
2783 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2784 "!TARGET_64BIT && !optimize_size"
2785 {
2786 /* This insn should be already splitted before reg-stack. */
2787 abort ();
2788 }
2789 [(set_attr "type" "multi")
2790 (set_attr "mode" "XF,SI")])
2791
2792 (define_insn "*pushtf_integer"
2793 [(set (match_operand:TF 0 "push_operand" "=<,<")
2794 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2795 "!optimize_size"
2796 {
2797 /* This insn should be already splitted before reg-stack. */
2798 abort ();
2799 }
2800 [(set_attr "type" "multi")
2801 (set_attr "mode" "XF,SI")])
2802
2803 (define_split
2804 [(set (match_operand 0 "push_operand" "")
2805 (match_operand 1 "general_operand" ""))]
2806 "reload_completed
2807 && (GET_MODE (operands[0]) == XFmode
2808 || GET_MODE (operands[0]) == TFmode
2809 || GET_MODE (operands[0]) == DFmode)
2810 && !ANY_FP_REG_P (operands[1])"
2811 [(const_int 0)]
2812 "ix86_split_long_move (operands); DONE;")
2813
2814 (define_split
2815 [(set (match_operand:XF 0 "push_operand" "")
2816 (match_operand:XF 1 "any_fp_register_operand" ""))]
2817 "!TARGET_64BIT"
2818 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2819 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2820
2821 (define_split
2822 [(set (match_operand:TF 0 "push_operand" "")
2823 (match_operand:TF 1 "any_fp_register_operand" ""))]
2824 "!TARGET_64BIT"
2825 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2826 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2827
2828 (define_split
2829 [(set (match_operand:TF 0 "push_operand" "")
2830 (match_operand:TF 1 "any_fp_register_operand" ""))]
2831 "TARGET_64BIT"
2832 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2833 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2834
2835 ;; Do not use integer registers when optimizing for size
2836 (define_insn "*movxf_nointeger"
2837 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2838 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2839 "!TARGET_64BIT
2840 && optimize_size
2841 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2842 && (reload_in_progress || reload_completed
2843 || GET_CODE (operands[1]) != CONST_DOUBLE
2844 || memory_operand (operands[0], XFmode))"
2845 {
2846 switch (which_alternative)
2847 {
2848 case 0:
2849 if (REG_P (operands[1])
2850 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2851 {
2852 if (REGNO (operands[0]) == FIRST_STACK_REG
2853 && TARGET_USE_FFREEP)
2854 return "ffreep\t%y0";
2855 return "fstp\t%y0";
2856 }
2857 else if (STACK_TOP_P (operands[0]))
2858 return "fld%z1\t%y1";
2859 else
2860 return "fst\t%y0";
2861
2862 case 1:
2863 /* There is no non-popping store to memory for XFmode. So if
2864 we need one, follow the store with a load. */
2865 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2866 return "fstp%z0\t%y0\;fld%z0\t%y0";
2867 else
2868 return "fstp%z0\t%y0";
2869
2870 case 2:
2871 return standard_80387_constant_opcode (operands[1]);
2872
2873 case 3: case 4:
2874 return "#";
2875 }
2876 abort();
2877 }
2878 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2879 (set_attr "mode" "XF,XF,XF,SI,SI")])
2880
2881 (define_insn "*movtf_nointeger"
2882 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2883 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2884 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2885 && optimize_size
2886 && (reload_in_progress || reload_completed
2887 || GET_CODE (operands[1]) != CONST_DOUBLE
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || memory_operand (operands[0], TFmode))"
2890 {
2891 switch (which_alternative)
2892 {
2893 case 0:
2894 if (REG_P (operands[1])
2895 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2896 {
2897 if (REGNO (operands[0]) == FIRST_STACK_REG
2898 && TARGET_USE_FFREEP)
2899 return "ffreep\t%y0";
2900 return "fstp\t%y0";
2901 }
2902 else if (STACK_TOP_P (operands[0]))
2903 return "fld%z1\t%y1";
2904 else
2905 return "fst\t%y0";
2906
2907 case 1:
2908 /* There is no non-popping store to memory for XFmode. So if
2909 we need one, follow the store with a load. */
2910 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2911 return "fstp%z0\t%y0\;fld%z0\t%y0";
2912 else
2913 return "fstp%z0\t%y0";
2914
2915 case 2:
2916 return standard_80387_constant_opcode (operands[1]);
2917
2918 case 3: case 4:
2919 return "#";
2920 }
2921 abort();
2922 }
2923 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2924 (set_attr "mode" "XF,XF,XF,SI,SI")])
2925
2926 (define_insn "*movxf_integer"
2927 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2928 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2929 "!TARGET_64BIT
2930 && !optimize_size
2931 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2932 && (reload_in_progress || reload_completed
2933 || GET_CODE (operands[1]) != CONST_DOUBLE
2934 || memory_operand (operands[0], XFmode))"
2935 {
2936 switch (which_alternative)
2937 {
2938 case 0:
2939 if (REG_P (operands[1])
2940 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2941 {
2942 if (REGNO (operands[0]) == FIRST_STACK_REG
2943 && TARGET_USE_FFREEP)
2944 return "ffreep\t%y0";
2945 return "fstp\t%y0";
2946 }
2947 else if (STACK_TOP_P (operands[0]))
2948 return "fld%z1\t%y1";
2949 else
2950 return "fst\t%y0";
2951
2952 case 1:
2953 /* There is no non-popping store to memory for XFmode. So if
2954 we need one, follow the store with a load. */
2955 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2956 return "fstp%z0\t%y0\;fld%z0\t%y0";
2957 else
2958 return "fstp%z0\t%y0";
2959
2960 case 2:
2961 return standard_80387_constant_opcode (operands[1]);
2962
2963 case 3: case 4:
2964 return "#";
2965 }
2966 abort();
2967 }
2968 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2969 (set_attr "mode" "XF,XF,XF,SI,SI")])
2970
2971 (define_insn "*movtf_integer"
2972 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2973 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2974 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2975 && !optimize_size
2976 && (reload_in_progress || reload_completed
2977 || GET_CODE (operands[1]) != CONST_DOUBLE
2978 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2979 || memory_operand (operands[0], TFmode))"
2980 {
2981 switch (which_alternative)
2982 {
2983 case 0:
2984 if (REG_P (operands[1])
2985 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2986 {
2987 if (REGNO (operands[0]) == FIRST_STACK_REG
2988 && TARGET_USE_FFREEP)
2989 return "ffreep\t%y0";
2990 return "fstp\t%y0";
2991 }
2992 else if (STACK_TOP_P (operands[0]))
2993 return "fld%z1\t%y1";
2994 else
2995 return "fst\t%y0";
2996
2997 case 1:
2998 /* There is no non-popping store to memory for XFmode. So if
2999 we need one, follow the store with a load. */
3000 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3001 return "fstp%z0\t%y0\;fld%z0\t%y0";
3002 else
3003 return "fstp%z0\t%y0";
3004
3005 case 2:
3006 return standard_80387_constant_opcode (operands[1]);
3007
3008 case 3: case 4:
3009 return "#";
3010 }
3011 abort();
3012 }
3013 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3014 (set_attr "mode" "XF,XF,XF,SI,SI")])
3015
3016 (define_split
3017 [(set (match_operand 0 "nonimmediate_operand" "")
3018 (match_operand 1 "general_operand" ""))]
3019 "reload_completed
3020 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3021 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3022 && ! (ANY_FP_REG_P (operands[0]) ||
3023 (GET_CODE (operands[0]) == SUBREG
3024 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3025 && ! (ANY_FP_REG_P (operands[1]) ||
3026 (GET_CODE (operands[1]) == SUBREG
3027 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3028 [(const_int 0)]
3029 "ix86_split_long_move (operands); DONE;")
3030
3031 (define_split
3032 [(set (match_operand 0 "register_operand" "")
3033 (match_operand 1 "memory_operand" ""))]
3034 "reload_completed
3035 && GET_CODE (operands[1]) == MEM
3036 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3037 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3038 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3039 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3040 && (!(SSE_REG_P (operands[0]) ||
3041 (GET_CODE (operands[0]) == SUBREG
3042 && SSE_REG_P (SUBREG_REG (operands[0]))))
3043 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3044 && (!(FP_REG_P (operands[0]) ||
3045 (GET_CODE (operands[0]) == SUBREG
3046 && FP_REG_P (SUBREG_REG (operands[0]))))
3047 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3048 [(set (match_dup 0)
3049 (match_dup 1))]
3050 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3051
3052 (define_insn "swapxf"
3053 [(set (match_operand:XF 0 "register_operand" "+f")
3054 (match_operand:XF 1 "register_operand" "+f"))
3055 (set (match_dup 1)
3056 (match_dup 0))]
3057 ""
3058 {
3059 if (STACK_TOP_P (operands[0]))
3060 return "fxch\t%1";
3061 else
3062 return "fxch\t%0";
3063 }
3064 [(set_attr "type" "fxch")
3065 (set_attr "mode" "XF")])
3066
3067 (define_insn "swaptf"
3068 [(set (match_operand:TF 0 "register_operand" "+f")
3069 (match_operand:TF 1 "register_operand" "+f"))
3070 (set (match_dup 1)
3071 (match_dup 0))]
3072 ""
3073 {
3074 if (STACK_TOP_P (operands[0]))
3075 return "fxch\t%1";
3076 else
3077 return "fxch\t%0";
3078 }
3079 [(set_attr "type" "fxch")
3080 (set_attr "mode" "XF")])
3081 \f
3082 ;; Zero extension instructions
3083
3084 (define_expand "zero_extendhisi2"
3085 [(set (match_operand:SI 0 "register_operand" "")
3086 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3087 ""
3088 {
3089 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3090 {
3091 operands[1] = force_reg (HImode, operands[1]);
3092 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3093 DONE;
3094 }
3095 })
3096
3097 (define_insn "zero_extendhisi2_and"
3098 [(set (match_operand:SI 0 "register_operand" "=r")
3099 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3100 (clobber (reg:CC 17))]
3101 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3102 "#"
3103 [(set_attr "type" "alu1")
3104 (set_attr "mode" "SI")])
3105
3106 (define_split
3107 [(set (match_operand:SI 0 "register_operand" "")
3108 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3109 (clobber (reg:CC 17))]
3110 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3111 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3112 (clobber (reg:CC 17))])]
3113 "")
3114
3115 (define_insn "*zero_extendhisi2_movzwl"
3116 [(set (match_operand:SI 0 "register_operand" "=r")
3117 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3118 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3119 "movz{wl|x}\t{%1, %0|%0, %1}"
3120 [(set_attr "type" "imovx")
3121 (set_attr "mode" "SI")])
3122
3123 (define_expand "zero_extendqihi2"
3124 [(parallel
3125 [(set (match_operand:HI 0 "register_operand" "")
3126 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3127 (clobber (reg:CC 17))])]
3128 ""
3129 "")
3130
3131 (define_insn "*zero_extendqihi2_and"
3132 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3133 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3134 (clobber (reg:CC 17))]
3135 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3136 "#"
3137 [(set_attr "type" "alu1")
3138 (set_attr "mode" "HI")])
3139
3140 (define_insn "*zero_extendqihi2_movzbw_and"
3141 [(set (match_operand:HI 0 "register_operand" "=r,r")
3142 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3143 (clobber (reg:CC 17))]
3144 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3145 "#"
3146 [(set_attr "type" "imovx,alu1")
3147 (set_attr "mode" "HI")])
3148
3149 (define_insn "*zero_extendqihi2_movzbw"
3150 [(set (match_operand:HI 0 "register_operand" "=r")
3151 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3152 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3153 "movz{bw|x}\t{%1, %0|%0, %1}"
3154 [(set_attr "type" "imovx")
3155 (set_attr "mode" "HI")])
3156
3157 ;; For the movzbw case strip only the clobber
3158 (define_split
3159 [(set (match_operand:HI 0 "register_operand" "")
3160 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3161 (clobber (reg:CC 17))]
3162 "reload_completed
3163 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3164 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3165 [(set (match_operand:HI 0 "register_operand" "")
3166 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3167
3168 ;; When source and destination does not overlap, clear destination
3169 ;; first and then do the movb
3170 (define_split
3171 [(set (match_operand:HI 0 "register_operand" "")
3172 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3173 (clobber (reg:CC 17))]
3174 "reload_completed
3175 && ANY_QI_REG_P (operands[0])
3176 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3177 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3178 [(set (match_dup 0) (const_int 0))
3179 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3180 "operands[2] = gen_lowpart (QImode, operands[0]);")
3181
3182 ;; Rest is handled by single and.
3183 (define_split
3184 [(set (match_operand:HI 0 "register_operand" "")
3185 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3186 (clobber (reg:CC 17))]
3187 "reload_completed
3188 && true_regnum (operands[0]) == true_regnum (operands[1])"
3189 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3190 (clobber (reg:CC 17))])]
3191 "")
3192
3193 (define_expand "zero_extendqisi2"
3194 [(parallel
3195 [(set (match_operand:SI 0 "register_operand" "")
3196 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3197 (clobber (reg:CC 17))])]
3198 ""
3199 "")
3200
3201 (define_insn "*zero_extendqisi2_and"
3202 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3203 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3204 (clobber (reg:CC 17))]
3205 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3206 "#"
3207 [(set_attr "type" "alu1")
3208 (set_attr "mode" "SI")])
3209
3210 (define_insn "*zero_extendqisi2_movzbw_and"
3211 [(set (match_operand:SI 0 "register_operand" "=r,r")
3212 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3213 (clobber (reg:CC 17))]
3214 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3215 "#"
3216 [(set_attr "type" "imovx,alu1")
3217 (set_attr "mode" "SI")])
3218
3219 (define_insn "*zero_extendqisi2_movzbw"
3220 [(set (match_operand:SI 0 "register_operand" "=r")
3221 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3222 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3223 "movz{bl|x}\t{%1, %0|%0, %1}"
3224 [(set_attr "type" "imovx")
3225 (set_attr "mode" "SI")])
3226
3227 ;; For the movzbl case strip only the clobber
3228 (define_split
3229 [(set (match_operand:SI 0 "register_operand" "")
3230 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3231 (clobber (reg:CC 17))]
3232 "reload_completed
3233 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3234 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3235 [(set (match_dup 0)
3236 (zero_extend:SI (match_dup 1)))])
3237
3238 ;; When source and destination does not overlap, clear destination
3239 ;; first and then do the movb
3240 (define_split
3241 [(set (match_operand:SI 0 "register_operand" "")
3242 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3243 (clobber (reg:CC 17))]
3244 "reload_completed
3245 && ANY_QI_REG_P (operands[0])
3246 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3247 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3248 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3249 [(set (match_dup 0) (const_int 0))
3250 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3251 "operands[2] = gen_lowpart (QImode, operands[0]);")
3252
3253 ;; Rest is handled by single and.
3254 (define_split
3255 [(set (match_operand:SI 0 "register_operand" "")
3256 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3257 (clobber (reg:CC 17))]
3258 "reload_completed
3259 && true_regnum (operands[0]) == true_regnum (operands[1])"
3260 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3261 (clobber (reg:CC 17))])]
3262 "")
3263
3264 ;; %%% Kill me once multi-word ops are sane.
3265 (define_expand "zero_extendsidi2"
3266 [(set (match_operand:DI 0 "register_operand" "=r")
3267 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3268 ""
3269 "if (!TARGET_64BIT)
3270 {
3271 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3272 DONE;
3273 }
3274 ")
3275
3276 (define_insn "zero_extendsidi2_32"
3277 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3278 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3279 (clobber (reg:CC 17))]
3280 "!TARGET_64BIT"
3281 "#"
3282 [(set_attr "mode" "SI")])
3283
3284 (define_insn "zero_extendsidi2_rex64"
3285 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3286 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3287 "TARGET_64BIT"
3288 "@
3289 mov\t{%k1, %k0|%k0, %k1}
3290 #"
3291 [(set_attr "type" "imovx,imov")
3292 (set_attr "mode" "SI,DI")])
3293
3294 (define_split
3295 [(set (match_operand:DI 0 "memory_operand" "")
3296 (zero_extend:DI (match_dup 0)))]
3297 "TARGET_64BIT"
3298 [(set (match_dup 4) (const_int 0))]
3299 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3300
3301 (define_split
3302 [(set (match_operand:DI 0 "register_operand" "")
3303 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3304 (clobber (reg:CC 17))]
3305 "!TARGET_64BIT && reload_completed
3306 && true_regnum (operands[0]) == true_regnum (operands[1])"
3307 [(set (match_dup 4) (const_int 0))]
3308 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3309
3310 (define_split
3311 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3312 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3313 (clobber (reg:CC 17))]
3314 "!TARGET_64BIT && reload_completed"
3315 [(set (match_dup 3) (match_dup 1))
3316 (set (match_dup 4) (const_int 0))]
3317 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3318
3319 (define_insn "zero_extendhidi2"
3320 [(set (match_operand:DI 0 "register_operand" "=r,r")
3321 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3322 "TARGET_64BIT"
3323 "@
3324 movz{wl|x}\t{%1, %k0|%k0, %1}
3325 movz{wq|x}\t{%1, %0|%0, %1}"
3326 [(set_attr "type" "imovx")
3327 (set_attr "mode" "SI,DI")])
3328
3329 (define_insn "zero_extendqidi2"
3330 [(set (match_operand:DI 0 "register_operand" "=r,r")
3331 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3332 "TARGET_64BIT"
3333 "@
3334 movz{bl|x}\t{%1, %k0|%k0, %1}
3335 movz{bq|x}\t{%1, %0|%0, %1}"
3336 [(set_attr "type" "imovx")
3337 (set_attr "mode" "SI,DI")])
3338 \f
3339 ;; Sign extension instructions
3340
3341 (define_expand "extendsidi2"
3342 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3343 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3344 (clobber (reg:CC 17))
3345 (clobber (match_scratch:SI 2 ""))])]
3346 ""
3347 {
3348 if (TARGET_64BIT)
3349 {
3350 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3351 DONE;
3352 }
3353 })
3354
3355 (define_insn "*extendsidi2_1"
3356 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3357 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3358 (clobber (reg:CC 17))
3359 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3360 "!TARGET_64BIT"
3361 "#")
3362
3363 (define_insn "extendsidi2_rex64"
3364 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3365 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3366 "TARGET_64BIT"
3367 "@
3368 {cltq|cdqe}
3369 movs{lq|x}\t{%1,%0|%0, %1}"
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "DI")
3372 (set_attr "prefix_0f" "0")
3373 (set_attr "modrm" "0,1")])
3374
3375 (define_insn "extendhidi2"
3376 [(set (match_operand:DI 0 "register_operand" "=r")
3377 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3378 "TARGET_64BIT"
3379 "movs{wq|x}\t{%1,%0|%0, %1}"
3380 [(set_attr "type" "imovx")
3381 (set_attr "mode" "DI")])
3382
3383 (define_insn "extendqidi2"
3384 [(set (match_operand:DI 0 "register_operand" "=r")
3385 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3386 "TARGET_64BIT"
3387 "movs{bq|x}\t{%1,%0|%0, %1}"
3388 [(set_attr "type" "imovx")
3389 (set_attr "mode" "DI")])
3390
3391 ;; Extend to memory case when source register does die.
3392 (define_split
3393 [(set (match_operand:DI 0 "memory_operand" "")
3394 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3395 (clobber (reg:CC 17))
3396 (clobber (match_operand:SI 2 "register_operand" ""))]
3397 "(reload_completed
3398 && dead_or_set_p (insn, operands[1])
3399 && !reg_mentioned_p (operands[1], operands[0]))"
3400 [(set (match_dup 3) (match_dup 1))
3401 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3402 (clobber (reg:CC 17))])
3403 (set (match_dup 4) (match_dup 1))]
3404 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3405
3406 ;; Extend to memory case when source register does not die.
3407 (define_split
3408 [(set (match_operand:DI 0 "memory_operand" "")
3409 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3410 (clobber (reg:CC 17))
3411 (clobber (match_operand:SI 2 "register_operand" ""))]
3412 "reload_completed"
3413 [(const_int 0)]
3414 {
3415 split_di (&operands[0], 1, &operands[3], &operands[4]);
3416
3417 emit_move_insn (operands[3], operands[1]);
3418
3419 /* Generate a cltd if possible and doing so it profitable. */
3420 if (true_regnum (operands[1]) == 0
3421 && true_regnum (operands[2]) == 1
3422 && (optimize_size || TARGET_USE_CLTD))
3423 {
3424 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3425 }
3426 else
3427 {
3428 emit_move_insn (operands[2], operands[1]);
3429 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3430 }
3431 emit_move_insn (operands[4], operands[2]);
3432 DONE;
3433 })
3434
3435 ;; Extend to register case. Optimize case where source and destination
3436 ;; registers match and cases where we can use cltd.
3437 (define_split
3438 [(set (match_operand:DI 0 "register_operand" "")
3439 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3440 (clobber (reg:CC 17))
3441 (clobber (match_scratch:SI 2 ""))]
3442 "reload_completed"
3443 [(const_int 0)]
3444 {
3445 split_di (&operands[0], 1, &operands[3], &operands[4]);
3446
3447 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3448 emit_move_insn (operands[3], operands[1]);
3449
3450 /* Generate a cltd if possible and doing so it profitable. */
3451 if (true_regnum (operands[3]) == 0
3452 && (optimize_size || TARGET_USE_CLTD))
3453 {
3454 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3455 DONE;
3456 }
3457
3458 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3459 emit_move_insn (operands[4], operands[1]);
3460
3461 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3462 DONE;
3463 })
3464
3465 (define_insn "extendhisi2"
3466 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3467 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3468 ""
3469 {
3470 switch (get_attr_prefix_0f (insn))
3471 {
3472 case 0:
3473 return "{cwtl|cwde}";
3474 default:
3475 return "movs{wl|x}\t{%1,%0|%0, %1}";
3476 }
3477 }
3478 [(set_attr "type" "imovx")
3479 (set_attr "mode" "SI")
3480 (set (attr "prefix_0f")
3481 ;; movsx is short decodable while cwtl is vector decoded.
3482 (if_then_else (and (eq_attr "cpu" "!k6")
3483 (eq_attr "alternative" "0"))
3484 (const_string "0")
3485 (const_string "1")))
3486 (set (attr "modrm")
3487 (if_then_else (eq_attr "prefix_0f" "0")
3488 (const_string "0")
3489 (const_string "1")))])
3490
3491 (define_insn "*extendhisi2_zext"
3492 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3493 (zero_extend:DI
3494 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3495 "TARGET_64BIT"
3496 {
3497 switch (get_attr_prefix_0f (insn))
3498 {
3499 case 0:
3500 return "{cwtl|cwde}";
3501 default:
3502 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3503 }
3504 }
3505 [(set_attr "type" "imovx")
3506 (set_attr "mode" "SI")
3507 (set (attr "prefix_0f")
3508 ;; movsx is short decodable while cwtl is vector decoded.
3509 (if_then_else (and (eq_attr "cpu" "!k6")
3510 (eq_attr "alternative" "0"))
3511 (const_string "0")
3512 (const_string "1")))
3513 (set (attr "modrm")
3514 (if_then_else (eq_attr "prefix_0f" "0")
3515 (const_string "0")
3516 (const_string "1")))])
3517
3518 (define_insn "extendqihi2"
3519 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3520 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3521 ""
3522 {
3523 switch (get_attr_prefix_0f (insn))
3524 {
3525 case 0:
3526 return "{cbtw|cbw}";
3527 default:
3528 return "movs{bw|x}\t{%1,%0|%0, %1}";
3529 }
3530 }
3531 [(set_attr "type" "imovx")
3532 (set_attr "mode" "HI")
3533 (set (attr "prefix_0f")
3534 ;; movsx is short decodable while cwtl is vector decoded.
3535 (if_then_else (and (eq_attr "cpu" "!k6")
3536 (eq_attr "alternative" "0"))
3537 (const_string "0")
3538 (const_string "1")))
3539 (set (attr "modrm")
3540 (if_then_else (eq_attr "prefix_0f" "0")
3541 (const_string "0")
3542 (const_string "1")))])
3543
3544 (define_insn "extendqisi2"
3545 [(set (match_operand:SI 0 "register_operand" "=r")
3546 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547 ""
3548 "movs{bl|x}\t{%1,%0|%0, %1}"
3549 [(set_attr "type" "imovx")
3550 (set_attr "mode" "SI")])
3551
3552 (define_insn "*extendqisi2_zext"
3553 [(set (match_operand:DI 0 "register_operand" "=r")
3554 (zero_extend:DI
3555 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3556 "TARGET_64BIT"
3557 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3558 [(set_attr "type" "imovx")
3559 (set_attr "mode" "SI")])
3560 \f
3561 ;; Conversions between float and double.
3562
3563 ;; These are all no-ops in the model used for the 80387. So just
3564 ;; emit moves.
3565
3566 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3567 (define_insn "*dummy_extendsfdf2"
3568 [(set (match_operand:DF 0 "push_operand" "=<")
3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3570 "0"
3571 "#")
3572
3573 (define_split
3574 [(set (match_operand:DF 0 "push_operand" "")
3575 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3576 "!TARGET_64BIT"
3577 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3578 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3579
3580 (define_split
3581 [(set (match_operand:DF 0 "push_operand" "")
3582 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3583 "TARGET_64BIT"
3584 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3585 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3586
3587 (define_insn "*dummy_extendsfxf2"
3588 [(set (match_operand:XF 0 "push_operand" "=<")
3589 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3590 "0"
3591 "#")
3592
3593 (define_split
3594 [(set (match_operand:XF 0 "push_operand" "")
3595 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3596 "!TARGET_64BIT"
3597 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3598 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3599
3600 (define_insn "*dummy_extendsftf2"
3601 [(set (match_operand:TF 0 "push_operand" "=<")
3602 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3603 "0"
3604 "#")
3605
3606 (define_split
3607 [(set (match_operand:TF 0 "push_operand" "")
3608 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3609 "!TARGET_64BIT"
3610 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3611 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3612
3613 (define_split
3614 [(set (match_operand:TF 0 "push_operand" "")
3615 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3616 "TARGET_64BIT"
3617 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3618 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3619
3620 (define_insn "*dummy_extenddfxf2"
3621 [(set (match_operand:XF 0 "push_operand" "=<")
3622 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3623 "0"
3624 "#")
3625
3626 (define_split
3627 [(set (match_operand:XF 0 "push_operand" "")
3628 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3629 "!TARGET_64BIT"
3630 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3631 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3632
3633 (define_insn "*dummy_extenddftf2"
3634 [(set (match_operand:TF 0 "push_operand" "=<")
3635 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3636 "0"
3637 "#")
3638
3639 (define_split
3640 [(set (match_operand:TF 0 "push_operand" "")
3641 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3642 "!TARGET_64BIT"
3643 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3644 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3645
3646 (define_split
3647 [(set (match_operand:TF 0 "push_operand" "")
3648 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3649 "TARGET_64BIT"
3650 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3651 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3652
3653 (define_expand "extendsfdf2"
3654 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3655 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3656 "TARGET_80387 || TARGET_SSE2"
3657 {
3658 /* ??? Needed for compress_float_constant since all fp constants
3659 are LEGITIMATE_CONSTANT_P. */
3660 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3661 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3662 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3663 operands[1] = force_reg (SFmode, operands[1]);
3664 })
3665
3666 (define_insn "*extendsfdf2_1"
3667 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3668 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3669 "(TARGET_80387 || TARGET_SSE2)
3670 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3671 {
3672 switch (which_alternative)
3673 {
3674 case 0:
3675 if (REG_P (operands[1])
3676 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3677 return "fstp\t%y0";
3678 else if (STACK_TOP_P (operands[0]))
3679 return "fld%z1\t%y1";
3680 else
3681 return "fst\t%y0";
3682
3683 case 1:
3684 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685 return "fstp%z0\t%y0";
3686
3687 else
3688 return "fst%z0\t%y0";
3689 case 2:
3690 return "cvtss2sd\t{%1, %0|%0, %1}";
3691
3692 default:
3693 abort ();
3694 }
3695 }
3696 [(set_attr "type" "fmov,fmov,ssecvt")
3697 (set_attr "mode" "SF,XF,DF")])
3698
3699 (define_insn "*extendsfdf2_1_sse_only"
3700 [(set (match_operand:DF 0 "register_operand" "=Y")
3701 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3702 "!TARGET_80387 && TARGET_SSE2
3703 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3704 "cvtss2sd\t{%1, %0|%0, %1}"
3705 [(set_attr "type" "ssecvt")
3706 (set_attr "mode" "DF")])
3707
3708 (define_expand "extendsfxf2"
3709 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3710 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3711 "!TARGET_64BIT && TARGET_80387"
3712 {
3713 /* ??? Needed for compress_float_constant since all fp constants
3714 are LEGITIMATE_CONSTANT_P. */
3715 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3716 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3717 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3718 operands[1] = force_reg (SFmode, operands[1]);
3719 })
3720
3721 (define_insn "*extendsfxf2_1"
3722 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3723 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3724 "!TARGET_64BIT && TARGET_80387
3725 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3726 {
3727 switch (which_alternative)
3728 {
3729 case 0:
3730 if (REG_P (operands[1])
3731 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3732 return "fstp\t%y0";
3733 else if (STACK_TOP_P (operands[0]))
3734 return "fld%z1\t%y1";
3735 else
3736 return "fst\t%y0";
3737
3738 case 1:
3739 /* There is no non-popping store to memory for XFmode. So if
3740 we need one, follow the store with a load. */
3741 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3742 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3743 else
3744 return "fstp%z0\t%y0";
3745
3746 default:
3747 abort ();
3748 }
3749 }
3750 [(set_attr "type" "fmov")
3751 (set_attr "mode" "SF,XF")])
3752
3753 (define_expand "extendsftf2"
3754 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3755 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3756 "TARGET_80387"
3757 {
3758 /* ??? Needed for compress_float_constant since all fp constants
3759 are LEGITIMATE_CONSTANT_P. */
3760 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3761 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3762 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3763 operands[1] = force_reg (SFmode, operands[1]);
3764 })
3765
3766 (define_insn "*extendsftf2_1"
3767 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3768 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3769 "TARGET_80387
3770 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3771 {
3772 switch (which_alternative)
3773 {
3774 case 0:
3775 if (REG_P (operands[1])
3776 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777 return "fstp\t%y0";
3778 else if (STACK_TOP_P (operands[0]))
3779 return "fld%z1\t%y1";
3780 else
3781 return "fst\t%y0";
3782
3783 case 1:
3784 /* There is no non-popping store to memory for XFmode. So if
3785 we need one, follow the store with a load. */
3786 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3787 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3788 else
3789 return "fstp%z0\t%y0";
3790
3791 default:
3792 abort ();
3793 }
3794 }
3795 [(set_attr "type" "fmov")
3796 (set_attr "mode" "SF,XF")])
3797
3798 (define_expand "extenddfxf2"
3799 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3800 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3801 "!TARGET_64BIT && TARGET_80387"
3802 {
3803 /* ??? Needed for compress_float_constant since all fp constants
3804 are LEGITIMATE_CONSTANT_P. */
3805 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3806 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3807 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3808 operands[1] = force_reg (DFmode, operands[1]);
3809 })
3810
3811 (define_insn "*extenddfxf2_1"
3812 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3813 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3814 "!TARGET_64BIT && TARGET_80387
3815 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3816 {
3817 switch (which_alternative)
3818 {
3819 case 0:
3820 if (REG_P (operands[1])
3821 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3822 return "fstp\t%y0";
3823 else if (STACK_TOP_P (operands[0]))
3824 return "fld%z1\t%y1";
3825 else
3826 return "fst\t%y0";
3827
3828 case 1:
3829 /* There is no non-popping store to memory for XFmode. So if
3830 we need one, follow the store with a load. */
3831 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3832 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3833 else
3834 return "fstp%z0\t%y0";
3835
3836 default:
3837 abort ();
3838 }
3839 }
3840 [(set_attr "type" "fmov")
3841 (set_attr "mode" "DF,XF")])
3842
3843 (define_expand "extenddftf2"
3844 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3845 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3846 "TARGET_80387"
3847 {
3848 /* ??? Needed for compress_float_constant since all fp constants
3849 are LEGITIMATE_CONSTANT_P. */
3850 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3851 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3852 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3853 operands[1] = force_reg (DFmode, operands[1]);
3854 })
3855
3856 (define_insn "*extenddftf2_1"
3857 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3858 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3859 "TARGET_80387
3860 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3861 {
3862 switch (which_alternative)
3863 {
3864 case 0:
3865 if (REG_P (operands[1])
3866 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867 return "fstp\t%y0";
3868 else if (STACK_TOP_P (operands[0]))
3869 return "fld%z1\t%y1";
3870 else
3871 return "fst\t%y0";
3872
3873 case 1:
3874 /* There is no non-popping store to memory for XFmode. So if
3875 we need one, follow the store with a load. */
3876 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3878 else
3879 return "fstp%z0\t%y0";
3880
3881 default:
3882 abort ();
3883 }
3884 }
3885 [(set_attr "type" "fmov")
3886 (set_attr "mode" "DF,XF")])
3887
3888 ;; %%% This seems bad bad news.
3889 ;; This cannot output into an f-reg because there is no way to be sure
3890 ;; of truncating in that case. Otherwise this is just like a simple move
3891 ;; insn. So we pretend we can output to a reg in order to get better
3892 ;; register preferencing, but we really use a stack slot.
3893
3894 (define_expand "truncdfsf2"
3895 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3896 (float_truncate:SF
3897 (match_operand:DF 1 "register_operand" "")))
3898 (clobber (match_dup 2))])]
3899 "TARGET_80387 || TARGET_SSE2"
3900 "
3901 if (TARGET_80387)
3902 operands[2] = assign_386_stack_local (SFmode, 0);
3903 else
3904 {
3905 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3906 DONE;
3907 }
3908 ")
3909
3910 (define_insn "*truncdfsf2_1"
3911 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3912 (float_truncate:SF
3913 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3914 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3915 "TARGET_80387 && !TARGET_SSE2"
3916 {
3917 switch (which_alternative)
3918 {
3919 case 0:
3920 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921 return "fstp%z0\t%y0";
3922 else
3923 return "fst%z0\t%y0";
3924 default:
3925 abort ();
3926 }
3927 }
3928 [(set_attr "type" "fmov,multi,multi,multi")
3929 (set_attr "mode" "SF,SF,SF,SF")])
3930
3931 (define_insn "*truncdfsf2_1_sse"
3932 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3933 (float_truncate:SF
3934 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3935 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3936 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3937 {
3938 switch (which_alternative)
3939 {
3940 case 0:
3941 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3942 return "fstp%z0\t%y0";
3943 else
3944 return "fst%z0\t%y0";
3945 case 4:
3946 return "#";
3947 default:
3948 abort ();
3949 }
3950 }
3951 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3952 (set_attr "mode" "SF,SF,SF,SF,DF")])
3953
3954 (define_insn "*truncdfsf2_1_sse_nooverlap"
3955 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3956 (float_truncate:SF
3957 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3958 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3959 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3960 {
3961 switch (which_alternative)
3962 {
3963 case 0:
3964 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3965 return "fstp%z0\t%y0";
3966 else
3967 return "fst%z0\t%y0";
3968 case 4:
3969 return "#";
3970 default:
3971 abort ();
3972 }
3973 }
3974 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3975 (set_attr "mode" "SF,SF,SF,SF,DF")])
3976
3977 (define_insn "*truncdfsf2_2"
3978 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3979 (float_truncate:SF
3980 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3981 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3982 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3983 {
3984 switch (which_alternative)
3985 {
3986 case 0:
3987 case 1:
3988 return "cvtsd2ss\t{%1, %0|%0, %1}";
3989 case 2:
3990 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3991 return "fstp%z0\t%y0";
3992 else
3993 return "fst%z0\t%y0";
3994 default:
3995 abort ();
3996 }
3997 }
3998 [(set_attr "type" "ssecvt,ssecvt,fmov")
3999 (set_attr "athlon_decode" "vector,double,*")
4000 (set_attr "mode" "SF,SF,SF")])
4001
4002 (define_insn "*truncdfsf2_2_nooverlap"
4003 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
4004 (float_truncate:SF
4005 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4006 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4007 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4008 {
4009 switch (which_alternative)
4010 {
4011 case 0:
4012 return "#";
4013 case 1:
4014 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4015 return "fstp%z0\t%y0";
4016 else
4017 return "fst%z0\t%y0";
4018 default:
4019 abort ();
4020 }
4021 }
4022 [(set_attr "type" "ssecvt,fmov")
4023 (set_attr "mode" "DF,SF")])
4024
4025 (define_insn "*truncdfsf2_3"
4026 [(set (match_operand:SF 0 "memory_operand" "=m")
4027 (float_truncate:SF
4028 (match_operand:DF 1 "register_operand" "f")))]
4029 "TARGET_80387"
4030 {
4031 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4032 return "fstp%z0\t%y0";
4033 else
4034 return "fst%z0\t%y0";
4035 }
4036 [(set_attr "type" "fmov")
4037 (set_attr "mode" "SF")])
4038
4039 (define_insn "truncdfsf2_sse_only"
4040 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4041 (float_truncate:SF
4042 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4043 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4044 "cvtsd2ss\t{%1, %0|%0, %1}"
4045 [(set_attr "type" "ssecvt")
4046 (set_attr "athlon_decode" "vector,double")
4047 (set_attr "mode" "SF")])
4048
4049 (define_insn "*truncdfsf2_sse_only_nooverlap"
4050 [(set (match_operand:SF 0 "register_operand" "=&Y")
4051 (float_truncate:SF
4052 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4053 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4054 "#"
4055 [(set_attr "type" "ssecvt")
4056 (set_attr "mode" "DF")])
4057
4058 (define_split
4059 [(set (match_operand:SF 0 "memory_operand" "")
4060 (float_truncate:SF
4061 (match_operand:DF 1 "register_operand" "")))
4062 (clobber (match_operand:SF 2 "memory_operand" ""))]
4063 "TARGET_80387"
4064 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4065 "")
4066
4067 ; Avoid possible reformatting penalty on the destination by first
4068 ; zeroing it out
4069 (define_split
4070 [(set (match_operand:SF 0 "register_operand" "")
4071 (float_truncate:SF
4072 (match_operand:DF 1 "nonimmediate_operand" "")))
4073 (clobber (match_operand 2 "" ""))]
4074 "TARGET_80387 && reload_completed
4075 && SSE_REG_P (operands[0])
4076 && !STACK_REG_P (operands[1])"
4077 [(const_int 0)]
4078 {
4079 rtx src, dest;
4080 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4081 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4082 else
4083 {
4084 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4085 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4086 /* simplify_gen_subreg refuses to widen memory references. */
4087 if (GET_CODE (src) == SUBREG)
4088 alter_subreg (&src);
4089 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4090 abort ();
4091 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4092 emit_insn (gen_cvtsd2ss (dest, dest, src));
4093 }
4094 DONE;
4095 })
4096
4097 (define_split
4098 [(set (match_operand:SF 0 "register_operand" "")
4099 (float_truncate:SF
4100 (match_operand:DF 1 "nonimmediate_operand" "")))]
4101 "TARGET_80387 && reload_completed
4102 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4103 [(const_int 0)]
4104 {
4105 rtx src, dest;
4106 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4107 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4108 /* simplify_gen_subreg refuses to widen memory references. */
4109 if (GET_CODE (src) == SUBREG)
4110 alter_subreg (&src);
4111 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4112 abort ();
4113 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4114 emit_insn (gen_cvtsd2ss (dest, dest, src));
4115 DONE;
4116 })
4117
4118 (define_split
4119 [(set (match_operand:SF 0 "register_operand" "")
4120 (float_truncate:SF
4121 (match_operand:DF 1 "fp_register_operand" "")))
4122 (clobber (match_operand:SF 2 "memory_operand" ""))]
4123 "TARGET_80387 && reload_completed"
4124 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4125 (set (match_dup 0) (match_dup 2))]
4126 "")
4127
4128 (define_expand "truncxfsf2"
4129 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4130 (float_truncate:SF
4131 (match_operand:XF 1 "register_operand" "")))
4132 (clobber (match_dup 2))])]
4133 "!TARGET_64BIT && TARGET_80387"
4134 "operands[2] = assign_386_stack_local (SFmode, 0);")
4135
4136 (define_insn "*truncxfsf2_1"
4137 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4138 (float_truncate:SF
4139 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4140 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4141 "!TARGET_64BIT && TARGET_80387"
4142 {
4143 switch (which_alternative)
4144 {
4145 case 0:
4146 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4147 return "fstp%z0\t%y0";
4148 else
4149 return "fst%z0\t%y0";
4150 default:
4151 abort();
4152 }
4153 }
4154 [(set_attr "type" "fmov,multi,multi,multi")
4155 (set_attr "mode" "SF")])
4156
4157 (define_insn "*truncxfsf2_2"
4158 [(set (match_operand:SF 0 "memory_operand" "=m")
4159 (float_truncate:SF
4160 (match_operand:XF 1 "register_operand" "f")))]
4161 "!TARGET_64BIT && TARGET_80387"
4162 {
4163 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4164 return "fstp%z0\t%y0";
4165 else
4166 return "fst%z0\t%y0";
4167 }
4168 [(set_attr "type" "fmov")
4169 (set_attr "mode" "SF")])
4170
4171 (define_split
4172 [(set (match_operand:SF 0 "memory_operand" "")
4173 (float_truncate:SF
4174 (match_operand:XF 1 "register_operand" "")))
4175 (clobber (match_operand:SF 2 "memory_operand" ""))]
4176 "TARGET_80387"
4177 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4178 "")
4179
4180 (define_split
4181 [(set (match_operand:SF 0 "register_operand" "")
4182 (float_truncate:SF
4183 (match_operand:XF 1 "register_operand" "")))
4184 (clobber (match_operand:SF 2 "memory_operand" ""))]
4185 "TARGET_80387 && reload_completed"
4186 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4187 (set (match_dup 0) (match_dup 2))]
4188 "")
4189
4190 (define_expand "trunctfsf2"
4191 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4192 (float_truncate:SF
4193 (match_operand:TF 1 "register_operand" "")))
4194 (clobber (match_dup 2))])]
4195 "TARGET_80387"
4196 "operands[2] = assign_386_stack_local (SFmode, 0);")
4197
4198 (define_insn "*trunctfsf2_1"
4199 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4200 (float_truncate:SF
4201 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4202 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4203 "TARGET_80387"
4204 {
4205 switch (which_alternative)
4206 {
4207 case 0:
4208 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4209 return "fstp%z0\t%y0";
4210 else
4211 return "fst%z0\t%y0";
4212 default:
4213 abort();
4214 }
4215 }
4216 [(set_attr "type" "fmov,multi,multi,multi")
4217 (set_attr "mode" "SF")])
4218
4219 (define_insn "*trunctfsf2_2"
4220 [(set (match_operand:SF 0 "memory_operand" "=m")
4221 (float_truncate:SF
4222 (match_operand:TF 1 "register_operand" "f")))]
4223 "TARGET_80387"
4224 {
4225 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4226 return "fstp%z0\t%y0";
4227 else
4228 return "fst%z0\t%y0";
4229 }
4230 [(set_attr "type" "fmov")
4231 (set_attr "mode" "SF")])
4232
4233 (define_split
4234 [(set (match_operand:SF 0 "memory_operand" "")
4235 (float_truncate:SF
4236 (match_operand:TF 1 "register_operand" "")))
4237 (clobber (match_operand:SF 2 "memory_operand" ""))]
4238 "TARGET_80387"
4239 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4240 "")
4241
4242 (define_split
4243 [(set (match_operand:SF 0 "register_operand" "")
4244 (float_truncate:SF
4245 (match_operand:TF 1 "register_operand" "")))
4246 (clobber (match_operand:SF 2 "memory_operand" ""))]
4247 "TARGET_80387 && reload_completed"
4248 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4249 (set (match_dup 0) (match_dup 2))]
4250 "")
4251
4252
4253 (define_expand "truncxfdf2"
4254 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4255 (float_truncate:DF
4256 (match_operand:XF 1 "register_operand" "")))
4257 (clobber (match_dup 2))])]
4258 "!TARGET_64BIT && TARGET_80387"
4259 "operands[2] = assign_386_stack_local (DFmode, 0);")
4260
4261 (define_insn "*truncxfdf2_1"
4262 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4263 (float_truncate:DF
4264 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4265 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4266 "!TARGET_64BIT && TARGET_80387"
4267 {
4268 switch (which_alternative)
4269 {
4270 case 0:
4271 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4272 return "fstp%z0\t%y0";
4273 else
4274 return "fst%z0\t%y0";
4275 default:
4276 abort();
4277 }
4278 abort ();
4279 }
4280 [(set_attr "type" "fmov,multi,multi,multi")
4281 (set_attr "mode" "DF")])
4282
4283 (define_insn "*truncxfdf2_2"
4284 [(set (match_operand:DF 0 "memory_operand" "=m")
4285 (float_truncate:DF
4286 (match_operand:XF 1 "register_operand" "f")))]
4287 "!TARGET_64BIT && TARGET_80387"
4288 {
4289 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4290 return "fstp%z0\t%y0";
4291 else
4292 return "fst%z0\t%y0";
4293 }
4294 [(set_attr "type" "fmov")
4295 (set_attr "mode" "DF")])
4296
4297 (define_split
4298 [(set (match_operand:DF 0 "memory_operand" "")
4299 (float_truncate:DF
4300 (match_operand:XF 1 "register_operand" "")))
4301 (clobber (match_operand:DF 2 "memory_operand" ""))]
4302 "TARGET_80387"
4303 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4304 "")
4305
4306 (define_split
4307 [(set (match_operand:DF 0 "register_operand" "")
4308 (float_truncate:DF
4309 (match_operand:XF 1 "register_operand" "")))
4310 (clobber (match_operand:DF 2 "memory_operand" ""))]
4311 "TARGET_80387 && reload_completed"
4312 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4313 (set (match_dup 0) (match_dup 2))]
4314 "")
4315
4316 (define_expand "trunctfdf2"
4317 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4318 (float_truncate:DF
4319 (match_operand:TF 1 "register_operand" "")))
4320 (clobber (match_dup 2))])]
4321 "TARGET_80387"
4322 "operands[2] = assign_386_stack_local (DFmode, 0);")
4323
4324 (define_insn "*trunctfdf2_1"
4325 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4326 (float_truncate:DF
4327 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4328 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4329 "TARGET_80387"
4330 {
4331 switch (which_alternative)
4332 {
4333 case 0:
4334 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4335 return "fstp%z0\t%y0";
4336 else
4337 return "fst%z0\t%y0";
4338 default:
4339 abort();
4340 }
4341 abort ();
4342 }
4343 [(set_attr "type" "fmov,multi,multi,multi")
4344 (set_attr "mode" "DF")])
4345
4346 (define_insn "*trunctfdf2_2"
4347 [(set (match_operand:DF 0 "memory_operand" "=m")
4348 (float_truncate:DF
4349 (match_operand:TF 1 "register_operand" "f")))]
4350 "TARGET_80387"
4351 {
4352 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4353 return "fstp%z0\t%y0";
4354 else
4355 return "fst%z0\t%y0";
4356 }
4357 [(set_attr "type" "fmov")
4358 (set_attr "mode" "DF")])
4359
4360 (define_split
4361 [(set (match_operand:DF 0 "memory_operand" "")
4362 (float_truncate:DF
4363 (match_operand:TF 1 "register_operand" "")))
4364 (clobber (match_operand:DF 2 "memory_operand" ""))]
4365 "TARGET_80387"
4366 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4367 "")
4368
4369 (define_split
4370 [(set (match_operand:DF 0 "register_operand" "")
4371 (float_truncate:DF
4372 (match_operand:TF 1 "register_operand" "")))
4373 (clobber (match_operand:DF 2 "memory_operand" ""))]
4374 "TARGET_80387 && reload_completed"
4375 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4376 (set (match_dup 0) (match_dup 2))]
4377 "")
4378
4379 \f
4380 ;; %%% Break up all these bad boys.
4381
4382 ;; Signed conversion to DImode.
4383
4384 (define_expand "fix_truncxfdi2"
4385 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4386 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4387 "!TARGET_64BIT && TARGET_80387"
4388 "")
4389
4390 (define_expand "fix_trunctfdi2"
4391 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4392 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4393 "TARGET_80387"
4394 "")
4395
4396 (define_expand "fix_truncdfdi2"
4397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4398 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4399 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4400 {
4401 if (TARGET_64BIT && TARGET_SSE2)
4402 {
4403 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4404 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4405 if (out != operands[0])
4406 emit_move_insn (operands[0], out);
4407 DONE;
4408 }
4409 })
4410
4411 (define_expand "fix_truncsfdi2"
4412 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4413 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4414 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4415 {
4416 if (TARGET_SSE && TARGET_64BIT)
4417 {
4418 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4419 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4420 if (out != operands[0])
4421 emit_move_insn (operands[0], out);
4422 DONE;
4423 }
4424 })
4425
4426 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4427 ;; of the machinery.
4428 (define_insn_and_split "*fix_truncdi_1"
4429 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4430 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4431 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4432 && !reload_completed && !reload_in_progress
4433 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4434 "#"
4435 "&& 1"
4436 [(const_int 0)]
4437 {
4438 ix86_optimize_mode_switching = 1;
4439 operands[2] = assign_386_stack_local (HImode, 1);
4440 operands[3] = assign_386_stack_local (HImode, 2);
4441 if (memory_operand (operands[0], VOIDmode))
4442 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4443 operands[2], operands[3]));
4444 else
4445 {
4446 operands[4] = assign_386_stack_local (DImode, 0);
4447 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4448 operands[2], operands[3],
4449 operands[4]));
4450 }
4451 DONE;
4452 }
4453 [(set_attr "type" "fistp")
4454 (set_attr "mode" "DI")])
4455
4456 (define_insn "fix_truncdi_nomemory"
4457 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4458 (fix:DI (match_operand 1 "register_operand" "f,f")))
4459 (use (match_operand:HI 2 "memory_operand" "m,m"))
4460 (use (match_operand:HI 3 "memory_operand" "m,m"))
4461 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4462 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4463 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4464 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4465 "#"
4466 [(set_attr "type" "fistp")
4467 (set_attr "mode" "DI")])
4468
4469 (define_insn "fix_truncdi_memory"
4470 [(set (match_operand:DI 0 "memory_operand" "=m")
4471 (fix:DI (match_operand 1 "register_operand" "f")))
4472 (use (match_operand:HI 2 "memory_operand" "m"))
4473 (use (match_operand:HI 3 "memory_operand" "m"))
4474 (clobber (match_scratch:DF 4 "=&1f"))]
4475 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4476 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4477 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4478 [(set_attr "type" "fistp")
4479 (set_attr "mode" "DI")])
4480
4481 (define_split
4482 [(set (match_operand:DI 0 "register_operand" "")
4483 (fix:DI (match_operand 1 "register_operand" "")))
4484 (use (match_operand:HI 2 "memory_operand" ""))
4485 (use (match_operand:HI 3 "memory_operand" ""))
4486 (clobber (match_operand:DI 4 "memory_operand" ""))
4487 (clobber (match_scratch 5 ""))]
4488 "reload_completed"
4489 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4490 (use (match_dup 2))
4491 (use (match_dup 3))
4492 (clobber (match_dup 5))])
4493 (set (match_dup 0) (match_dup 4))]
4494 "")
4495
4496 (define_split
4497 [(set (match_operand:DI 0 "memory_operand" "")
4498 (fix:DI (match_operand 1 "register_operand" "")))
4499 (use (match_operand:HI 2 "memory_operand" ""))
4500 (use (match_operand:HI 3 "memory_operand" ""))
4501 (clobber (match_operand:DI 4 "memory_operand" ""))
4502 (clobber (match_scratch 5 ""))]
4503 "reload_completed"
4504 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4505 (use (match_dup 2))
4506 (use (match_dup 3))
4507 (clobber (match_dup 5))])]
4508 "")
4509
4510 ;; When SSE available, it is always faster to use it!
4511 (define_insn "fix_truncsfdi_sse"
4512 [(set (match_operand:DI 0 "register_operand" "=r,r")
4513 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4514 "TARGET_64BIT && TARGET_SSE"
4515 "cvttss2si{q}\t{%1, %0|%0, %1}"
4516 [(set_attr "type" "sseicvt")
4517 (set_attr "mode" "SF")
4518 (set_attr "athlon_decode" "double,vector")])
4519
4520 ;; Avoid vector decoded form of the instruction.
4521 (define_peephole2
4522 [(match_scratch:SF 2 "x")
4523 (set (match_operand:DI 0 "register_operand" "")
4524 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4525 "TARGET_K8 && !optimize_size"
4526 [(set (match_dup 2) (match_dup 1))
4527 (set (match_dup 0) (fix:DI (match_dup 2)))]
4528 "")
4529
4530 (define_insn "fix_truncdfdi_sse"
4531 [(set (match_operand:DI 0 "register_operand" "=r,r")
4532 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4533 "TARGET_64BIT && TARGET_SSE2"
4534 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4535 [(set_attr "type" "sseicvt,sseicvt")
4536 (set_attr "mode" "DF")
4537 (set_attr "athlon_decode" "double,vector")])
4538
4539 ;; Avoid vector decoded form of the instruction.
4540 (define_peephole2
4541 [(match_scratch:DF 2 "Y")
4542 (set (match_operand:DI 0 "register_operand" "")
4543 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4544 "TARGET_K8 && !optimize_size"
4545 [(set (match_dup 2) (match_dup 1))
4546 (set (match_dup 0) (fix:DI (match_dup 2)))]
4547 "")
4548
4549 ;; Signed conversion to SImode.
4550
4551 (define_expand "fix_truncxfsi2"
4552 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4553 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4554 "!TARGET_64BIT && TARGET_80387"
4555 "")
4556
4557 (define_expand "fix_trunctfsi2"
4558 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4559 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4560 "TARGET_80387"
4561 "")
4562
4563 (define_expand "fix_truncdfsi2"
4564 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4565 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4566 "TARGET_80387 || TARGET_SSE2"
4567 {
4568 if (TARGET_SSE2)
4569 {
4570 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4571 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4572 if (out != operands[0])
4573 emit_move_insn (operands[0], out);
4574 DONE;
4575 }
4576 })
4577
4578 (define_expand "fix_truncsfsi2"
4579 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4580 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4581 "TARGET_80387 || TARGET_SSE"
4582 {
4583 if (TARGET_SSE)
4584 {
4585 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4586 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4587 if (out != operands[0])
4588 emit_move_insn (operands[0], out);
4589 DONE;
4590 }
4591 })
4592
4593 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4594 ;; of the machinery.
4595 (define_insn_and_split "*fix_truncsi_1"
4596 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4597 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4598 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4599 && !reload_completed && !reload_in_progress
4600 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4601 "#"
4602 "&& 1"
4603 [(const_int 0)]
4604 {
4605 ix86_optimize_mode_switching = 1;
4606 operands[2] = assign_386_stack_local (HImode, 1);
4607 operands[3] = assign_386_stack_local (HImode, 2);
4608 if (memory_operand (operands[0], VOIDmode))
4609 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4610 operands[2], operands[3]));
4611 else
4612 {
4613 operands[4] = assign_386_stack_local (SImode, 0);
4614 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4615 operands[2], operands[3],
4616 operands[4]));
4617 }
4618 DONE;
4619 }
4620 [(set_attr "type" "fistp")
4621 (set_attr "mode" "SI")])
4622
4623 (define_insn "fix_truncsi_nomemory"
4624 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4625 (fix:SI (match_operand 1 "register_operand" "f,f")))
4626 (use (match_operand:HI 2 "memory_operand" "m,m"))
4627 (use (match_operand:HI 3 "memory_operand" "m,m"))
4628 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4629 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4630 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4631 "#"
4632 [(set_attr "type" "fistp")
4633 (set_attr "mode" "SI")])
4634
4635 (define_insn "fix_truncsi_memory"
4636 [(set (match_operand:SI 0 "memory_operand" "=m")
4637 (fix:SI (match_operand 1 "register_operand" "f")))
4638 (use (match_operand:HI 2 "memory_operand" "m"))
4639 (use (match_operand:HI 3 "memory_operand" "m"))]
4640 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4641 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4642 "* return output_fix_trunc (insn, operands);"
4643 [(set_attr "type" "fistp")
4644 (set_attr "mode" "SI")])
4645
4646 ;; When SSE available, it is always faster to use it!
4647 (define_insn "fix_truncsfsi_sse"
4648 [(set (match_operand:SI 0 "register_operand" "=r,r")
4649 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4650 "TARGET_SSE"
4651 "cvttss2si\t{%1, %0|%0, %1}"
4652 [(set_attr "type" "sseicvt")
4653 (set_attr "mode" "DF")
4654 (set_attr "athlon_decode" "double,vector")])
4655
4656 ;; Avoid vector decoded form of the instruction.
4657 (define_peephole2
4658 [(match_scratch:SF 2 "x")
4659 (set (match_operand:SI 0 "register_operand" "")
4660 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4661 "TARGET_K8 && !optimize_size"
4662 [(set (match_dup 2) (match_dup 1))
4663 (set (match_dup 0) (fix:SI (match_dup 2)))]
4664 "")
4665
4666 (define_insn "fix_truncdfsi_sse"
4667 [(set (match_operand:SI 0 "register_operand" "=r,r")
4668 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4669 "TARGET_SSE2"
4670 "cvttsd2si\t{%1, %0|%0, %1}"
4671 [(set_attr "type" "sseicvt")
4672 (set_attr "mode" "DF")
4673 (set_attr "athlon_decode" "double,vector")])
4674
4675 ;; Avoid vector decoded form of the instruction.
4676 (define_peephole2
4677 [(match_scratch:DF 2 "Y")
4678 (set (match_operand:SI 0 "register_operand" "")
4679 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4680 "TARGET_K8 && !optimize_size"
4681 [(set (match_dup 2) (match_dup 1))
4682 (set (match_dup 0) (fix:SI (match_dup 2)))]
4683 "")
4684
4685 (define_split
4686 [(set (match_operand:SI 0 "register_operand" "")
4687 (fix:SI (match_operand 1 "register_operand" "")))
4688 (use (match_operand:HI 2 "memory_operand" ""))
4689 (use (match_operand:HI 3 "memory_operand" ""))
4690 (clobber (match_operand:SI 4 "memory_operand" ""))]
4691 "reload_completed"
4692 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4693 (use (match_dup 2))
4694 (use (match_dup 3))])
4695 (set (match_dup 0) (match_dup 4))]
4696 "")
4697
4698 (define_split
4699 [(set (match_operand:SI 0 "memory_operand" "")
4700 (fix:SI (match_operand 1 "register_operand" "")))
4701 (use (match_operand:HI 2 "memory_operand" ""))
4702 (use (match_operand:HI 3 "memory_operand" ""))
4703 (clobber (match_operand:SI 4 "memory_operand" ""))]
4704 "reload_completed"
4705 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4706 (use (match_dup 2))
4707 (use (match_dup 3))])]
4708 "")
4709
4710 ;; Signed conversion to HImode.
4711
4712 (define_expand "fix_truncxfhi2"
4713 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4714 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4715 "!TARGET_64BIT && TARGET_80387"
4716 "")
4717
4718 (define_expand "fix_trunctfhi2"
4719 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4720 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4721 "TARGET_80387"
4722 "")
4723
4724 (define_expand "fix_truncdfhi2"
4725 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4726 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4727 "TARGET_80387 && !TARGET_SSE2"
4728 "")
4729
4730 (define_expand "fix_truncsfhi2"
4731 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4732 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4733 "TARGET_80387 && !TARGET_SSE"
4734 "")
4735
4736 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4737 ;; of the machinery.
4738 (define_insn_and_split "*fix_trunchi_1"
4739 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4740 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4741 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4742 && !reload_completed && !reload_in_progress
4743 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4744 "#"
4745 ""
4746 [(const_int 0)]
4747 {
4748 ix86_optimize_mode_switching = 1;
4749 operands[2] = assign_386_stack_local (HImode, 1);
4750 operands[3] = assign_386_stack_local (HImode, 2);
4751 if (memory_operand (operands[0], VOIDmode))
4752 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4753 operands[2], operands[3]));
4754 else
4755 {
4756 operands[4] = assign_386_stack_local (HImode, 0);
4757 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4758 operands[2], operands[3],
4759 operands[4]));
4760 }
4761 DONE;
4762 }
4763 [(set_attr "type" "fistp")
4764 (set_attr "mode" "HI")])
4765
4766 (define_insn "fix_trunchi_nomemory"
4767 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4768 (fix:HI (match_operand 1 "register_operand" "f,f")))
4769 (use (match_operand:HI 2 "memory_operand" "m,m"))
4770 (use (match_operand:HI 3 "memory_operand" "m,m"))
4771 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4772 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4773 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4774 "#"
4775 [(set_attr "type" "fistp")
4776 (set_attr "mode" "HI")])
4777
4778 (define_insn "fix_trunchi_memory"
4779 [(set (match_operand:HI 0 "memory_operand" "=m")
4780 (fix:HI (match_operand 1 "register_operand" "f")))
4781 (use (match_operand:HI 2 "memory_operand" "m"))
4782 (use (match_operand:HI 3 "memory_operand" "m"))]
4783 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4784 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4785 "* return output_fix_trunc (insn, operands);"
4786 [(set_attr "type" "fistp")
4787 (set_attr "mode" "HI")])
4788
4789 (define_split
4790 [(set (match_operand:HI 0 "memory_operand" "")
4791 (fix:HI (match_operand 1 "register_operand" "")))
4792 (use (match_operand:HI 2 "memory_operand" ""))
4793 (use (match_operand:HI 3 "memory_operand" ""))
4794 (clobber (match_operand:HI 4 "memory_operand" ""))]
4795 "reload_completed"
4796 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4797 (use (match_dup 2))
4798 (use (match_dup 3))])]
4799 "")
4800
4801 (define_split
4802 [(set (match_operand:HI 0 "register_operand" "")
4803 (fix:HI (match_operand 1 "register_operand" "")))
4804 (use (match_operand:HI 2 "memory_operand" ""))
4805 (use (match_operand:HI 3 "memory_operand" ""))
4806 (clobber (match_operand:HI 4 "memory_operand" ""))]
4807 "reload_completed"
4808 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4809 (use (match_dup 2))
4810 (use (match_dup 3))
4811 (clobber (match_dup 4))])
4812 (set (match_dup 0) (match_dup 4))]
4813 "")
4814
4815 ;; %% Not used yet.
4816 (define_insn "x86_fnstcw_1"
4817 [(set (match_operand:HI 0 "memory_operand" "=m")
4818 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4819 "TARGET_80387"
4820 "fnstcw\t%0"
4821 [(set_attr "length" "2")
4822 (set_attr "mode" "HI")
4823 (set_attr "unit" "i387")
4824 (set_attr "ppro_uops" "few")])
4825
4826 (define_insn "x86_fldcw_1"
4827 [(set (reg:HI 18)
4828 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4829 "TARGET_80387"
4830 "fldcw\t%0"
4831 [(set_attr "length" "2")
4832 (set_attr "mode" "HI")
4833 (set_attr "unit" "i387")
4834 (set_attr "athlon_decode" "vector")
4835 (set_attr "ppro_uops" "few")])
4836 \f
4837 ;; Conversion between fixed point and floating point.
4838
4839 ;; Even though we only accept memory inputs, the backend _really_
4840 ;; wants to be able to do this between registers.
4841
4842 (define_expand "floathisf2"
4843 [(set (match_operand:SF 0 "register_operand" "")
4844 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4845 "TARGET_SSE || TARGET_80387"
4846 {
4847 if (TARGET_SSE && TARGET_SSE_MATH)
4848 {
4849 emit_insn (gen_floatsisf2 (operands[0],
4850 convert_to_mode (SImode, operands[1], 0)));
4851 DONE;
4852 }
4853 })
4854
4855 (define_insn "*floathisf2_1"
4856 [(set (match_operand:SF 0 "register_operand" "=f,f")
4857 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4858 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4859 "@
4860 fild%z1\t%1
4861 #"
4862 [(set_attr "type" "fmov,multi")
4863 (set_attr "mode" "SF")
4864 (set_attr "fp_int_src" "true")])
4865
4866 (define_expand "floatsisf2"
4867 [(set (match_operand:SF 0 "register_operand" "")
4868 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4869 "TARGET_SSE || TARGET_80387"
4870 "")
4871
4872 (define_insn "*floatsisf2_i387"
4873 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4874 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4875 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4876 "@
4877 fild%z1\t%1
4878 #
4879 cvtsi2ss\t{%1, %0|%0, %1}
4880 cvtsi2ss\t{%1, %0|%0, %1}"
4881 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4882 (set_attr "mode" "SF")
4883 (set_attr "athlon_decode" "*,*,vector,double")
4884 (set_attr "fp_int_src" "true")])
4885
4886 (define_insn "*floatsisf2_sse"
4887 [(set (match_operand:SF 0 "register_operand" "=x,x")
4888 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4889 "TARGET_SSE"
4890 "cvtsi2ss\t{%1, %0|%0, %1}"
4891 [(set_attr "type" "sseicvt")
4892 (set_attr "mode" "SF")
4893 (set_attr "athlon_decode" "vector,double")
4894 (set_attr "fp_int_src" "true")])
4895
4896 ; Avoid possible reformatting penalty on the destination by first
4897 ; zeroing it out
4898 (define_split
4899 [(set (match_operand:SF 0 "register_operand" "")
4900 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4901 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4902 && SSE_REG_P (operands[0])"
4903 [(const_int 0)]
4904 {
4905 rtx dest;
4906 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4907 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4908 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4909 DONE;
4910 })
4911
4912 (define_expand "floatdisf2"
4913 [(set (match_operand:SF 0 "register_operand" "")
4914 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4915 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4916 "")
4917
4918 (define_insn "*floatdisf2_i387_only"
4919 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4920 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4921 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4922 "@
4923 fild%z1\t%1
4924 #"
4925 [(set_attr "type" "fmov,multi")
4926 (set_attr "mode" "SF")
4927 (set_attr "fp_int_src" "true")])
4928
4929 (define_insn "*floatdisf2_i387"
4930 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4931 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4932 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4933 "@
4934 fild%z1\t%1
4935 #
4936 cvtsi2ss{q}\t{%1, %0|%0, %1}
4937 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4938 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4939 (set_attr "mode" "SF")
4940 (set_attr "athlon_decode" "*,*,vector,double")
4941 (set_attr "fp_int_src" "true")])
4942
4943 (define_insn "*floatdisf2_sse"
4944 [(set (match_operand:SF 0 "register_operand" "=x,x")
4945 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4946 "TARGET_64BIT && TARGET_SSE"
4947 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4948 [(set_attr "type" "sseicvt")
4949 (set_attr "mode" "SF")
4950 (set_attr "athlon_decode" "vector,double")
4951 (set_attr "fp_int_src" "true")])
4952
4953 ; Avoid possible reformatting penalty on the destination by first
4954 ; zeroing it out
4955 (define_split
4956 [(set (match_operand:SF 0 "register_operand" "")
4957 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4958 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4959 && SSE_REG_P (operands[0])"
4960 [(const_int 0)]
4961 {
4962 rtx dest;
4963 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4964 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4965 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4966 DONE;
4967 })
4968
4969 (define_expand "floathidf2"
4970 [(set (match_operand:DF 0 "register_operand" "")
4971 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4972 "TARGET_SSE2 || TARGET_80387"
4973 {
4974 if (TARGET_SSE && TARGET_SSE_MATH)
4975 {
4976 emit_insn (gen_floatsidf2 (operands[0],
4977 convert_to_mode (SImode, operands[1], 0)));
4978 DONE;
4979 }
4980 })
4981
4982 (define_insn "*floathidf2_1"
4983 [(set (match_operand:DF 0 "register_operand" "=f,f")
4984 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4985 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4986 "@
4987 fild%z1\t%1
4988 #"
4989 [(set_attr "type" "fmov,multi")
4990 (set_attr "mode" "DF")
4991 (set_attr "fp_int_src" "true")])
4992
4993 (define_expand "floatsidf2"
4994 [(set (match_operand:DF 0 "register_operand" "")
4995 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4996 "TARGET_80387 || TARGET_SSE2"
4997 "")
4998
4999 (define_insn "*floatsidf2_i387"
5000 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5001 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
5002 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5003 "@
5004 fild%z1\t%1
5005 #
5006 cvtsi2sd\t{%1, %0|%0, %1}
5007 cvtsi2sd\t{%1, %0|%0, %1}"
5008 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5009 (set_attr "mode" "DF")
5010 (set_attr "athlon_decode" "*,*,double,direct")
5011 (set_attr "fp_int_src" "true")])
5012
5013 (define_insn "*floatsidf2_sse"
5014 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5015 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
5016 "TARGET_SSE2"
5017 "cvtsi2sd\t{%1, %0|%0, %1}"
5018 [(set_attr "type" "sseicvt")
5019 (set_attr "mode" "DF")
5020 (set_attr "athlon_decode" "double,direct")
5021 (set_attr "fp_int_src" "true")])
5022
5023 (define_expand "floatdidf2"
5024 [(set (match_operand:DF 0 "register_operand" "")
5025 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5026 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5027 "")
5028
5029 (define_insn "*floatdidf2_i387_only"
5030 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5031 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5032 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5033 "@
5034 fild%z1\t%1
5035 #"
5036 [(set_attr "type" "fmov,multi")
5037 (set_attr "mode" "DF")
5038 (set_attr "fp_int_src" "true")])
5039
5040 (define_insn "*floatdidf2_i387"
5041 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5042 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5043 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5044 "@
5045 fild%z1\t%1
5046 #
5047 cvtsi2sd{q}\t{%1, %0|%0, %1}
5048 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5049 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5050 (set_attr "mode" "DF")
5051 (set_attr "athlon_decode" "*,*,double,direct")
5052 (set_attr "fp_int_src" "true")])
5053
5054 (define_insn "*floatdidf2_sse"
5055 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5056 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5057 "TARGET_SSE2"
5058 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5059 [(set_attr "type" "sseicvt")
5060 (set_attr "mode" "DF")
5061 (set_attr "athlon_decode" "double,direct")
5062 (set_attr "fp_int_src" "true")])
5063
5064 (define_insn "floathixf2"
5065 [(set (match_operand:XF 0 "register_operand" "=f,f")
5066 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5067 "!TARGET_64BIT && TARGET_80387"
5068 "@
5069 fild%z1\t%1
5070 #"
5071 [(set_attr "type" "fmov,multi")
5072 (set_attr "mode" "XF")
5073 (set_attr "fp_int_src" "true")])
5074
5075 (define_insn "floathitf2"
5076 [(set (match_operand:TF 0 "register_operand" "=f,f")
5077 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5078 "TARGET_80387"
5079 "@
5080 fild%z1\t%1
5081 #"
5082 [(set_attr "type" "fmov,multi")
5083 (set_attr "mode" "XF")
5084 (set_attr "fp_int_src" "true")])
5085
5086 (define_insn "floatsixf2"
5087 [(set (match_operand:XF 0 "register_operand" "=f,f")
5088 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5089 "!TARGET_64BIT && TARGET_80387"
5090 "@
5091 fild%z1\t%1
5092 #"
5093 [(set_attr "type" "fmov,multi")
5094 (set_attr "mode" "XF")
5095 (set_attr "fp_int_src" "true")])
5096
5097 (define_insn "floatsitf2"
5098 [(set (match_operand:TF 0 "register_operand" "=f,f")
5099 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5100 "TARGET_80387"
5101 "@
5102 fild%z1\t%1
5103 #"
5104 [(set_attr "type" "fmov,multi")
5105 (set_attr "mode" "XF")
5106 (set_attr "fp_int_src" "true")])
5107
5108 (define_insn "floatdixf2"
5109 [(set (match_operand:XF 0 "register_operand" "=f,f")
5110 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5111 "!TARGET_64BIT && TARGET_80387"
5112 "@
5113 fild%z1\t%1
5114 #"
5115 [(set_attr "type" "fmov,multi")
5116 (set_attr "mode" "XF")
5117 (set_attr "fp_int_src" "true")])
5118
5119 (define_insn "floatditf2"
5120 [(set (match_operand:TF 0 "register_operand" "=f,f")
5121 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5122 "TARGET_80387"
5123 "@
5124 fild%z1\t%1
5125 #"
5126 [(set_attr "type" "fmov,multi")
5127 (set_attr "mode" "XF")
5128 (set_attr "fp_int_src" "true")])
5129
5130 ;; %%% Kill these when reload knows how to do it.
5131 (define_split
5132 [(set (match_operand 0 "fp_register_operand" "")
5133 (float (match_operand 1 "register_operand" "")))]
5134 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5135 [(const_int 0)]
5136 {
5137 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5138 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5139 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5140 ix86_free_from_memory (GET_MODE (operands[1]));
5141 DONE;
5142 })
5143
5144 (define_expand "floatunssisf2"
5145 [(use (match_operand:SF 0 "register_operand" ""))
5146 (use (match_operand:SI 1 "register_operand" ""))]
5147 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5148 "x86_emit_floatuns (operands); DONE;")
5149
5150 (define_expand "floatunsdisf2"
5151 [(use (match_operand:SF 0 "register_operand" ""))
5152 (use (match_operand:DI 1 "register_operand" ""))]
5153 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5154 "x86_emit_floatuns (operands); DONE;")
5155
5156 (define_expand "floatunsdidf2"
5157 [(use (match_operand:DF 0 "register_operand" ""))
5158 (use (match_operand:DI 1 "register_operand" ""))]
5159 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5160 "x86_emit_floatuns (operands); DONE;")
5161 \f
5162 ;; Add instructions
5163
5164 ;; %%% splits for addsidi3
5165 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5166 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5167 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5168
5169 (define_expand "adddi3"
5170 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5171 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5172 (match_operand:DI 2 "x86_64_general_operand" "")))
5173 (clobber (reg:CC 17))]
5174 ""
5175 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5176
5177 (define_insn "*adddi3_1"
5178 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5179 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5180 (match_operand:DI 2 "general_operand" "roiF,riF")))
5181 (clobber (reg:CC 17))]
5182 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5183 "#")
5184
5185 (define_split
5186 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5187 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5188 (match_operand:DI 2 "general_operand" "")))
5189 (clobber (reg:CC 17))]
5190 "!TARGET_64BIT && reload_completed"
5191 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5192 UNSPEC_ADD_CARRY))
5193 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5194 (parallel [(set (match_dup 3)
5195 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5196 (match_dup 4))
5197 (match_dup 5)))
5198 (clobber (reg:CC 17))])]
5199 "split_di (operands+0, 1, operands+0, operands+3);
5200 split_di (operands+1, 1, operands+1, operands+4);
5201 split_di (operands+2, 1, operands+2, operands+5);")
5202
5203 (define_insn "adddi3_carry_rex64"
5204 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5205 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5206 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5207 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5208 (clobber (reg:CC 17))]
5209 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5210 "adc{q}\t{%2, %0|%0, %2}"
5211 [(set_attr "type" "alu")
5212 (set_attr "pent_pair" "pu")
5213 (set_attr "mode" "DI")
5214 (set_attr "ppro_uops" "few")])
5215
5216 (define_insn "*adddi3_cc_rex64"
5217 [(set (reg:CC 17)
5218 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5219 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5220 UNSPEC_ADD_CARRY))
5221 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5222 (plus:DI (match_dup 1) (match_dup 2)))]
5223 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5224 "add{q}\t{%2, %0|%0, %2}"
5225 [(set_attr "type" "alu")
5226 (set_attr "mode" "DI")])
5227
5228 (define_insn "addqi3_carry"
5229 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5230 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5231 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5232 (match_operand:QI 2 "general_operand" "ri,rm")))
5233 (clobber (reg:CC 17))]
5234 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5235 "adc{b}\t{%2, %0|%0, %2}"
5236 [(set_attr "type" "alu")
5237 (set_attr "pent_pair" "pu")
5238 (set_attr "mode" "QI")
5239 (set_attr "ppro_uops" "few")])
5240
5241 (define_insn "addhi3_carry"
5242 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5243 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5244 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5245 (match_operand:HI 2 "general_operand" "ri,rm")))
5246 (clobber (reg:CC 17))]
5247 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5248 "adc{w}\t{%2, %0|%0, %2}"
5249 [(set_attr "type" "alu")
5250 (set_attr "pent_pair" "pu")
5251 (set_attr "mode" "HI")
5252 (set_attr "ppro_uops" "few")])
5253
5254 (define_insn "addsi3_carry"
5255 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5256 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5257 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5258 (match_operand:SI 2 "general_operand" "ri,rm")))
5259 (clobber (reg:CC 17))]
5260 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5261 "adc{l}\t{%2, %0|%0, %2}"
5262 [(set_attr "type" "alu")
5263 (set_attr "pent_pair" "pu")
5264 (set_attr "mode" "SI")
5265 (set_attr "ppro_uops" "few")])
5266
5267 (define_insn "*addsi3_carry_zext"
5268 [(set (match_operand:DI 0 "register_operand" "=r")
5269 (zero_extend:DI
5270 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5271 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5272 (match_operand:SI 2 "general_operand" "rim"))))
5273 (clobber (reg:CC 17))]
5274 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5275 "adc{l}\t{%2, %k0|%k0, %2}"
5276 [(set_attr "type" "alu")
5277 (set_attr "pent_pair" "pu")
5278 (set_attr "mode" "SI")
5279 (set_attr "ppro_uops" "few")])
5280
5281 (define_insn "*addsi3_cc"
5282 [(set (reg:CC 17)
5283 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5284 (match_operand:SI 2 "general_operand" "ri,rm")]
5285 UNSPEC_ADD_CARRY))
5286 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5287 (plus:SI (match_dup 1) (match_dup 2)))]
5288 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5289 "add{l}\t{%2, %0|%0, %2}"
5290 [(set_attr "type" "alu")
5291 (set_attr "mode" "SI")])
5292
5293 (define_insn "addqi3_cc"
5294 [(set (reg:CC 17)
5295 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5296 (match_operand:QI 2 "general_operand" "qi,qm")]
5297 UNSPEC_ADD_CARRY))
5298 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5299 (plus:QI (match_dup 1) (match_dup 2)))]
5300 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5301 "add{b}\t{%2, %0|%0, %2}"
5302 [(set_attr "type" "alu")
5303 (set_attr "mode" "QI")])
5304
5305 (define_expand "addsi3"
5306 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5307 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5308 (match_operand:SI 2 "general_operand" "")))
5309 (clobber (reg:CC 17))])]
5310 ""
5311 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5312
5313 (define_insn "*lea_1"
5314 [(set (match_operand:SI 0 "register_operand" "=r")
5315 (match_operand:SI 1 "address_operand" "p"))]
5316 "!TARGET_64BIT"
5317 "lea{l}\t{%a1, %0|%0, %a1}"
5318 [(set_attr "type" "lea")
5319 (set_attr "mode" "SI")])
5320
5321 (define_insn "*lea_1_rex64"
5322 [(set (match_operand:SI 0 "register_operand" "=r")
5323 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5324 "TARGET_64BIT"
5325 "lea{l}\t{%a1, %0|%0, %a1}"
5326 [(set_attr "type" "lea")
5327 (set_attr "mode" "SI")])
5328
5329 (define_insn "*lea_1_zext"
5330 [(set (match_operand:DI 0 "register_operand" "=r")
5331 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5332 "TARGET_64BIT"
5333 "lea{l}\t{%a1, %k0|%k0, %a1}"
5334 [(set_attr "type" "lea")
5335 (set_attr "mode" "SI")])
5336
5337 (define_insn "*lea_2_rex64"
5338 [(set (match_operand:DI 0 "register_operand" "=r")
5339 (match_operand:DI 1 "address_operand" "p"))]
5340 "TARGET_64BIT"
5341 "lea{q}\t{%a1, %0|%0, %a1}"
5342 [(set_attr "type" "lea")
5343 (set_attr "mode" "DI")])
5344
5345 ;; The lea patterns for non-Pmodes needs to be matched by several
5346 ;; insns converted to real lea by splitters.
5347
5348 (define_insn_and_split "*lea_general_1"
5349 [(set (match_operand 0 "register_operand" "=r")
5350 (plus (plus (match_operand 1 "index_register_operand" "r")
5351 (match_operand 2 "register_operand" "r"))
5352 (match_operand 3 "immediate_operand" "i")))]
5353 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5354 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5355 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5356 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5357 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5358 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5359 || GET_MODE (operands[3]) == VOIDmode)"
5360 "#"
5361 "&& reload_completed"
5362 [(const_int 0)]
5363 {
5364 rtx pat;
5365 operands[0] = gen_lowpart (SImode, operands[0]);
5366 operands[1] = gen_lowpart (Pmode, operands[1]);
5367 operands[2] = gen_lowpart (Pmode, operands[2]);
5368 operands[3] = gen_lowpart (Pmode, operands[3]);
5369 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5370 operands[3]);
5371 if (Pmode != SImode)
5372 pat = gen_rtx_SUBREG (SImode, pat, 0);
5373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5374 DONE;
5375 }
5376 [(set_attr "type" "lea")
5377 (set_attr "mode" "SI")])
5378
5379 (define_insn_and_split "*lea_general_1_zext"
5380 [(set (match_operand:DI 0 "register_operand" "=r")
5381 (zero_extend:DI
5382 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5383 (match_operand:SI 2 "register_operand" "r"))
5384 (match_operand:SI 3 "immediate_operand" "i"))))]
5385 "TARGET_64BIT"
5386 "#"
5387 "&& reload_completed"
5388 [(set (match_dup 0)
5389 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5390 (match_dup 2))
5391 (match_dup 3)) 0)))]
5392 {
5393 operands[1] = gen_lowpart (Pmode, operands[1]);
5394 operands[2] = gen_lowpart (Pmode, operands[2]);
5395 operands[3] = gen_lowpart (Pmode, operands[3]);
5396 }
5397 [(set_attr "type" "lea")
5398 (set_attr "mode" "SI")])
5399
5400 (define_insn_and_split "*lea_general_2"
5401 [(set (match_operand 0 "register_operand" "=r")
5402 (plus (mult (match_operand 1 "index_register_operand" "r")
5403 (match_operand 2 "const248_operand" "i"))
5404 (match_operand 3 "nonmemory_operand" "ri")))]
5405 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5406 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5407 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5408 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5409 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5410 || GET_MODE (operands[3]) == VOIDmode)"
5411 "#"
5412 "&& reload_completed"
5413 [(const_int 0)]
5414 {
5415 rtx pat;
5416 operands[0] = gen_lowpart (SImode, operands[0]);
5417 operands[1] = gen_lowpart (Pmode, operands[1]);
5418 operands[3] = gen_lowpart (Pmode, operands[3]);
5419 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5420 operands[3]);
5421 if (Pmode != SImode)
5422 pat = gen_rtx_SUBREG (SImode, pat, 0);
5423 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5424 DONE;
5425 }
5426 [(set_attr "type" "lea")
5427 (set_attr "mode" "SI")])
5428
5429 (define_insn_and_split "*lea_general_2_zext"
5430 [(set (match_operand:DI 0 "register_operand" "=r")
5431 (zero_extend:DI
5432 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5433 (match_operand:SI 2 "const248_operand" "n"))
5434 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5435 "TARGET_64BIT"
5436 "#"
5437 "&& reload_completed"
5438 [(set (match_dup 0)
5439 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5440 (match_dup 2))
5441 (match_dup 3)) 0)))]
5442 {
5443 operands[1] = gen_lowpart (Pmode, operands[1]);
5444 operands[3] = gen_lowpart (Pmode, operands[3]);
5445 }
5446 [(set_attr "type" "lea")
5447 (set_attr "mode" "SI")])
5448
5449 (define_insn_and_split "*lea_general_3"
5450 [(set (match_operand 0 "register_operand" "=r")
5451 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5452 (match_operand 2 "const248_operand" "i"))
5453 (match_operand 3 "register_operand" "r"))
5454 (match_operand 4 "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[3])"
5460 "#"
5461 "&& reload_completed"
5462 [(const_int 0)]
5463 {
5464 rtx pat;
5465 operands[0] = gen_lowpart (SImode, operands[0]);
5466 operands[1] = gen_lowpart (Pmode, operands[1]);
5467 operands[3] = gen_lowpart (Pmode, operands[3]);
5468 operands[4] = gen_lowpart (Pmode, operands[4]);
5469 pat = gen_rtx_PLUS (Pmode,
5470 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5471 operands[2]),
5472 operands[3]),
5473 operands[4]);
5474 if (Pmode != SImode)
5475 pat = gen_rtx_SUBREG (SImode, pat, 0);
5476 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5477 DONE;
5478 }
5479 [(set_attr "type" "lea")
5480 (set_attr "mode" "SI")])
5481
5482 (define_insn_and_split "*lea_general_3_zext"
5483 [(set (match_operand:DI 0 "register_operand" "=r")
5484 (zero_extend:DI
5485 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5486 (match_operand:SI 2 "const248_operand" "n"))
5487 (match_operand:SI 3 "register_operand" "r"))
5488 (match_operand:SI 4 "immediate_operand" "i"))))]
5489 "TARGET_64BIT"
5490 "#"
5491 "&& reload_completed"
5492 [(set (match_dup 0)
5493 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5494 (match_dup 2))
5495 (match_dup 3))
5496 (match_dup 4)) 0)))]
5497 {
5498 operands[1] = gen_lowpart (Pmode, operands[1]);
5499 operands[3] = gen_lowpart (Pmode, operands[3]);
5500 operands[4] = gen_lowpart (Pmode, operands[4]);
5501 }
5502 [(set_attr "type" "lea")
5503 (set_attr "mode" "SI")])
5504
5505 (define_insn "*adddi_1_rex64"
5506 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5507 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5508 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5509 (clobber (reg:CC 17))]
5510 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5511 {
5512 switch (get_attr_type (insn))
5513 {
5514 case TYPE_LEA:
5515 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5516 return "lea{q}\t{%a2, %0|%0, %a2}";
5517
5518 case TYPE_INCDEC:
5519 if (! rtx_equal_p (operands[0], operands[1]))
5520 abort ();
5521 if (operands[2] == const1_rtx)
5522 return "inc{q}\t%0";
5523 else if (operands[2] == constm1_rtx)
5524 return "dec{q}\t%0";
5525 else
5526 abort ();
5527
5528 default:
5529 if (! rtx_equal_p (operands[0], operands[1]))
5530 abort ();
5531
5532 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5533 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5534 if (GET_CODE (operands[2]) == CONST_INT
5535 /* Avoid overflows. */
5536 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5537 && (INTVAL (operands[2]) == 128
5538 || (INTVAL (operands[2]) < 0
5539 && INTVAL (operands[2]) != -128)))
5540 {
5541 operands[2] = GEN_INT (-INTVAL (operands[2]));
5542 return "sub{q}\t{%2, %0|%0, %2}";
5543 }
5544 return "add{q}\t{%2, %0|%0, %2}";
5545 }
5546 }
5547 [(set (attr "type")
5548 (cond [(eq_attr "alternative" "2")
5549 (const_string "lea")
5550 ; Current assemblers are broken and do not allow @GOTOFF in
5551 ; ought but a memory context.
5552 (match_operand:DI 2 "pic_symbolic_operand" "")
5553 (const_string "lea")
5554 (match_operand:DI 2 "incdec_operand" "")
5555 (const_string "incdec")
5556 ]
5557 (const_string "alu")))
5558 (set_attr "mode" "DI")])
5559
5560 ;; Convert lea to the lea pattern to avoid flags dependency.
5561 (define_split
5562 [(set (match_operand:DI 0 "register_operand" "")
5563 (plus:DI (match_operand:DI 1 "register_operand" "")
5564 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5565 (clobber (reg:CC 17))]
5566 "TARGET_64BIT && reload_completed
5567 && true_regnum (operands[0]) != true_regnum (operands[1])"
5568 [(set (match_dup 0)
5569 (plus:DI (match_dup 1)
5570 (match_dup 2)))]
5571 "")
5572
5573 (define_insn "*adddi_2_rex64"
5574 [(set (reg 17)
5575 (compare
5576 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5577 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5578 (const_int 0)))
5579 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5580 (plus:DI (match_dup 1) (match_dup 2)))]
5581 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5582 && ix86_binary_operator_ok (PLUS, DImode, operands)
5583 /* Current assemblers are broken and do not allow @GOTOFF in
5584 ought but a memory context. */
5585 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5586 {
5587 switch (get_attr_type (insn))
5588 {
5589 case TYPE_INCDEC:
5590 if (! rtx_equal_p (operands[0], operands[1]))
5591 abort ();
5592 if (operands[2] == const1_rtx)
5593 return "inc{q}\t%0";
5594 else if (operands[2] == constm1_rtx)
5595 return "dec{q}\t%0";
5596 else
5597 abort ();
5598
5599 default:
5600 if (! rtx_equal_p (operands[0], operands[1]))
5601 abort ();
5602 /* ???? We ought to handle there the 32bit case too
5603 - do we need new constraint? */
5604 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5605 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5606 if (GET_CODE (operands[2]) == CONST_INT
5607 /* Avoid overflows. */
5608 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5609 && (INTVAL (operands[2]) == 128
5610 || (INTVAL (operands[2]) < 0
5611 && INTVAL (operands[2]) != -128)))
5612 {
5613 operands[2] = GEN_INT (-INTVAL (operands[2]));
5614 return "sub{q}\t{%2, %0|%0, %2}";
5615 }
5616 return "add{q}\t{%2, %0|%0, %2}";
5617 }
5618 }
5619 [(set (attr "type")
5620 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5621 (const_string "incdec")
5622 (const_string "alu")))
5623 (set_attr "mode" "DI")])
5624
5625 (define_insn "*adddi_3_rex64"
5626 [(set (reg 17)
5627 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5628 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5629 (clobber (match_scratch:DI 0 "=r"))]
5630 "TARGET_64BIT
5631 && ix86_match_ccmode (insn, CCZmode)
5632 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5633 /* Current assemblers are broken and do not allow @GOTOFF in
5634 ought but a memory context. */
5635 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5636 {
5637 switch (get_attr_type (insn))
5638 {
5639 case TYPE_INCDEC:
5640 if (! rtx_equal_p (operands[0], operands[1]))
5641 abort ();
5642 if (operands[2] == const1_rtx)
5643 return "inc{q}\t%0";
5644 else if (operands[2] == constm1_rtx)
5645 return "dec{q}\t%0";
5646 else
5647 abort ();
5648
5649 default:
5650 if (! rtx_equal_p (operands[0], operands[1]))
5651 abort ();
5652 /* ???? We ought to handle there the 32bit case too
5653 - do we need new constraint? */
5654 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5655 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5656 if (GET_CODE (operands[2]) == CONST_INT
5657 /* Avoid overflows. */
5658 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5659 && (INTVAL (operands[2]) == 128
5660 || (INTVAL (operands[2]) < 0
5661 && INTVAL (operands[2]) != -128)))
5662 {
5663 operands[2] = GEN_INT (-INTVAL (operands[2]));
5664 return "sub{q}\t{%2, %0|%0, %2}";
5665 }
5666 return "add{q}\t{%2, %0|%0, %2}";
5667 }
5668 }
5669 [(set (attr "type")
5670 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5671 (const_string "incdec")
5672 (const_string "alu")))
5673 (set_attr "mode" "DI")])
5674
5675 ; For comparisons against 1, -1 and 128, we may generate better code
5676 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5677 ; is matched then. We can't accept general immediate, because for
5678 ; case of overflows, the result is messed up.
5679 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5680 ; when negated.
5681 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5682 ; only for comparisons not depending on it.
5683 (define_insn "*adddi_4_rex64"
5684 [(set (reg 17)
5685 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5686 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5687 (clobber (match_scratch:DI 0 "=rm"))]
5688 "TARGET_64BIT
5689 && ix86_match_ccmode (insn, CCGCmode)"
5690 {
5691 switch (get_attr_type (insn))
5692 {
5693 case TYPE_INCDEC:
5694 if (operands[2] == constm1_rtx)
5695 return "inc{q}\t%0";
5696 else if (operands[2] == const1_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 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5705 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5706 if ((INTVAL (operands[2]) == -128
5707 || (INTVAL (operands[2]) > 0
5708 && INTVAL (operands[2]) != 128))
5709 /* Avoid overflows. */
5710 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5711 return "sub{q}\t{%2, %0|%0, %2}";
5712 operands[2] = GEN_INT (-INTVAL (operands[2]));
5713 return "add{q}\t{%2, %0|%0, %2}";
5714 }
5715 }
5716 [(set (attr "type")
5717 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5718 (const_string "incdec")
5719 (const_string "alu")))
5720 (set_attr "mode" "DI")])
5721
5722 (define_insn "*adddi_5_rex64"
5723 [(set (reg 17)
5724 (compare
5725 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5726 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5727 (const_int 0)))
5728 (clobber (match_scratch:DI 0 "=r"))]
5729 "TARGET_64BIT
5730 && ix86_match_ccmode (insn, CCGOCmode)
5731 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732 /* Current assemblers are broken and do not allow @GOTOFF in
5733 ought but a memory context. */
5734 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5735 {
5736 switch (get_attr_type (insn))
5737 {
5738 case TYPE_INCDEC:
5739 if (! rtx_equal_p (operands[0], operands[1]))
5740 abort ();
5741 if (operands[2] == const1_rtx)
5742 return "inc{q}\t%0";
5743 else if (operands[2] == constm1_rtx)
5744 return "dec{q}\t%0";
5745 else
5746 abort();
5747
5748 default:
5749 if (! rtx_equal_p (operands[0], operands[1]))
5750 abort ();
5751 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5752 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5753 if (GET_CODE (operands[2]) == CONST_INT
5754 /* Avoid overflows. */
5755 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5756 && (INTVAL (operands[2]) == 128
5757 || (INTVAL (operands[2]) < 0
5758 && INTVAL (operands[2]) != -128)))
5759 {
5760 operands[2] = GEN_INT (-INTVAL (operands[2]));
5761 return "sub{q}\t{%2, %0|%0, %2}";
5762 }
5763 return "add{q}\t{%2, %0|%0, %2}";
5764 }
5765 }
5766 [(set (attr "type")
5767 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5768 (const_string "incdec")
5769 (const_string "alu")))
5770 (set_attr "mode" "DI")])
5771
5772
5773 (define_insn "*addsi_1"
5774 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5775 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5776 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5777 (clobber (reg:CC 17))]
5778 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5779 {
5780 switch (get_attr_type (insn))
5781 {
5782 case TYPE_LEA:
5783 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5784 return "lea{l}\t{%a2, %0|%0, %a2}";
5785
5786 case TYPE_INCDEC:
5787 if (! rtx_equal_p (operands[0], operands[1]))
5788 abort ();
5789 if (operands[2] == const1_rtx)
5790 return "inc{l}\t%0";
5791 else if (operands[2] == constm1_rtx)
5792 return "dec{l}\t%0";
5793 else
5794 abort();
5795
5796 default:
5797 if (! rtx_equal_p (operands[0], operands[1]))
5798 abort ();
5799
5800 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5801 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5802 if (GET_CODE (operands[2]) == CONST_INT
5803 && (INTVAL (operands[2]) == 128
5804 || (INTVAL (operands[2]) < 0
5805 && INTVAL (operands[2]) != -128)))
5806 {
5807 operands[2] = GEN_INT (-INTVAL (operands[2]));
5808 return "sub{l}\t{%2, %0|%0, %2}";
5809 }
5810 return "add{l}\t{%2, %0|%0, %2}";
5811 }
5812 }
5813 [(set (attr "type")
5814 (cond [(eq_attr "alternative" "2")
5815 (const_string "lea")
5816 ; Current assemblers are broken and do not allow @GOTOFF in
5817 ; ought but a memory context.
5818 (match_operand:SI 2 "pic_symbolic_operand" "")
5819 (const_string "lea")
5820 (match_operand:SI 2 "incdec_operand" "")
5821 (const_string "incdec")
5822 ]
5823 (const_string "alu")))
5824 (set_attr "mode" "SI")])
5825
5826 ;; Convert lea to the lea pattern to avoid flags dependency.
5827 (define_split
5828 [(set (match_operand 0 "register_operand" "")
5829 (plus (match_operand 1 "register_operand" "")
5830 (match_operand 2 "nonmemory_operand" "")))
5831 (clobber (reg:CC 17))]
5832 "reload_completed
5833 && true_regnum (operands[0]) != true_regnum (operands[1])"
5834 [(const_int 0)]
5835 {
5836 rtx pat;
5837 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5838 may confuse gen_lowpart. */
5839 if (GET_MODE (operands[0]) != Pmode)
5840 {
5841 operands[1] = gen_lowpart (Pmode, operands[1]);
5842 operands[2] = gen_lowpart (Pmode, operands[2]);
5843 }
5844 operands[0] = gen_lowpart (SImode, operands[0]);
5845 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5846 if (Pmode != SImode)
5847 pat = gen_rtx_SUBREG (SImode, pat, 0);
5848 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5849 DONE;
5850 })
5851
5852 ;; It may seem that nonimmediate operand is proper one for operand 1.
5853 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5854 ;; we take care in ix86_binary_operator_ok to not allow two memory
5855 ;; operands so proper swapping will be done in reload. This allow
5856 ;; patterns constructed from addsi_1 to match.
5857 (define_insn "addsi_1_zext"
5858 [(set (match_operand:DI 0 "register_operand" "=r,r")
5859 (zero_extend:DI
5860 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5861 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5862 (clobber (reg:CC 17))]
5863 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5864 {
5865 switch (get_attr_type (insn))
5866 {
5867 case TYPE_LEA:
5868 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5869 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5870
5871 case TYPE_INCDEC:
5872 if (operands[2] == const1_rtx)
5873 return "inc{l}\t%k0";
5874 else if (operands[2] == constm1_rtx)
5875 return "dec{l}\t%k0";
5876 else
5877 abort();
5878
5879 default:
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, %k0|%k0, %2}";
5889 }
5890 return "add{l}\t{%2, %k0|%k0, %2}";
5891 }
5892 }
5893 [(set (attr "type")
5894 (cond [(eq_attr "alternative" "1")
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:DI 0 "register_operand" "")
5909 (zero_extend:DI
5910 (plus:SI (match_operand:SI 1 "register_operand" "")
5911 (match_operand:SI 2 "nonmemory_operand" ""))))
5912 (clobber (reg:CC 17))]
5913 "TARGET_64BIT && reload_completed
5914 && true_regnum (operands[0]) != true_regnum (operands[1])"
5915 [(set (match_dup 0)
5916 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5917 {
5918 operands[1] = gen_lowpart (Pmode, operands[1]);
5919 operands[2] = gen_lowpart (Pmode, operands[2]);
5920 })
5921
5922 (define_insn "*addsi_2"
5923 [(set (reg 17)
5924 (compare
5925 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5926 (match_operand:SI 2 "general_operand" "rmni,rni"))
5927 (const_int 0)))
5928 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5929 (plus:SI (match_dup 1) (match_dup 2)))]
5930 "ix86_match_ccmode (insn, CCGOCmode)
5931 && ix86_binary_operator_ok (PLUS, SImode, operands)
5932 /* Current assemblers are broken and do not allow @GOTOFF in
5933 ought but a memory context. */
5934 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5935 {
5936 switch (get_attr_type (insn))
5937 {
5938 case TYPE_INCDEC:
5939 if (! rtx_equal_p (operands[0], operands[1]))
5940 abort ();
5941 if (operands[2] == const1_rtx)
5942 return "inc{l}\t%0";
5943 else if (operands[2] == constm1_rtx)
5944 return "dec{l}\t%0";
5945 else
5946 abort();
5947
5948 default:
5949 if (! rtx_equal_p (operands[0], operands[1]))
5950 abort ();
5951 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5953 if (GET_CODE (operands[2]) == CONST_INT
5954 && (INTVAL (operands[2]) == 128
5955 || (INTVAL (operands[2]) < 0
5956 && INTVAL (operands[2]) != -128)))
5957 {
5958 operands[2] = GEN_INT (-INTVAL (operands[2]));
5959 return "sub{l}\t{%2, %0|%0, %2}";
5960 }
5961 return "add{l}\t{%2, %0|%0, %2}";
5962 }
5963 }
5964 [(set (attr "type")
5965 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5966 (const_string "incdec")
5967 (const_string "alu")))
5968 (set_attr "mode" "SI")])
5969
5970 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5971 (define_insn "*addsi_2_zext"
5972 [(set (reg 17)
5973 (compare
5974 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5975 (match_operand:SI 2 "general_operand" "rmni"))
5976 (const_int 0)))
5977 (set (match_operand:DI 0 "register_operand" "=r")
5978 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5980 && ix86_binary_operator_ok (PLUS, SImode, operands)
5981 /* Current assemblers are broken and do not allow @GOTOFF in
5982 ought but a memory context. */
5983 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5984 {
5985 switch (get_attr_type (insn))
5986 {
5987 case TYPE_INCDEC:
5988 if (operands[2] == const1_rtx)
5989 return "inc{l}\t%k0";
5990 else if (operands[2] == constm1_rtx)
5991 return "dec{l}\t%k0";
5992 else
5993 abort();
5994
5995 default:
5996 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5997 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5998 if (GET_CODE (operands[2]) == CONST_INT
5999 && (INTVAL (operands[2]) == 128
6000 || (INTVAL (operands[2]) < 0
6001 && INTVAL (operands[2]) != -128)))
6002 {
6003 operands[2] = GEN_INT (-INTVAL (operands[2]));
6004 return "sub{l}\t{%2, %k0|%k0, %2}";
6005 }
6006 return "add{l}\t{%2, %k0|%k0, %2}";
6007 }
6008 }
6009 [(set (attr "type")
6010 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6011 (const_string "incdec")
6012 (const_string "alu")))
6013 (set_attr "mode" "SI")])
6014
6015 (define_insn "*addsi_3"
6016 [(set (reg 17)
6017 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6018 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6019 (clobber (match_scratch:SI 0 "=r"))]
6020 "ix86_match_ccmode (insn, CCZmode)
6021 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6022 /* Current assemblers are broken and do not allow @GOTOFF in
6023 ought but a memory context. */
6024 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6025 {
6026 switch (get_attr_type (insn))
6027 {
6028 case TYPE_INCDEC:
6029 if (! rtx_equal_p (operands[0], operands[1]))
6030 abort ();
6031 if (operands[2] == const1_rtx)
6032 return "inc{l}\t%0";
6033 else if (operands[2] == constm1_rtx)
6034 return "dec{l}\t%0";
6035 else
6036 abort();
6037
6038 default:
6039 if (! rtx_equal_p (operands[0], operands[1]))
6040 abort ();
6041 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6042 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6043 if (GET_CODE (operands[2]) == CONST_INT
6044 && (INTVAL (operands[2]) == 128
6045 || (INTVAL (operands[2]) < 0
6046 && INTVAL (operands[2]) != -128)))
6047 {
6048 operands[2] = GEN_INT (-INTVAL (operands[2]));
6049 return "sub{l}\t{%2, %0|%0, %2}";
6050 }
6051 return "add{l}\t{%2, %0|%0, %2}";
6052 }
6053 }
6054 [(set (attr "type")
6055 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6056 (const_string "incdec")
6057 (const_string "alu")))
6058 (set_attr "mode" "SI")])
6059
6060 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6061 (define_insn "*addsi_3_zext"
6062 [(set (reg 17)
6063 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6064 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6065 (set (match_operand:DI 0 "register_operand" "=r")
6066 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6067 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6068 && ix86_binary_operator_ok (PLUS, SImode, operands)
6069 /* Current assemblers are broken and do not allow @GOTOFF in
6070 ought but a memory context. */
6071 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6072 {
6073 switch (get_attr_type (insn))
6074 {
6075 case TYPE_INCDEC:
6076 if (operands[2] == const1_rtx)
6077 return "inc{l}\t%k0";
6078 else if (operands[2] == constm1_rtx)
6079 return "dec{l}\t%k0";
6080 else
6081 abort();
6082
6083 default:
6084 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6085 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6086 if (GET_CODE (operands[2]) == CONST_INT
6087 && (INTVAL (operands[2]) == 128
6088 || (INTVAL (operands[2]) < 0
6089 && INTVAL (operands[2]) != -128)))
6090 {
6091 operands[2] = GEN_INT (-INTVAL (operands[2]));
6092 return "sub{l}\t{%2, %k0|%k0, %2}";
6093 }
6094 return "add{l}\t{%2, %k0|%k0, %2}";
6095 }
6096 }
6097 [(set (attr "type")
6098 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6099 (const_string "incdec")
6100 (const_string "alu")))
6101 (set_attr "mode" "SI")])
6102
6103 ; For comparisons against 1, -1 and 128, we may generate better code
6104 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6105 ; is matched then. We can't accept general immediate, because for
6106 ; case of overflows, the result is messed up.
6107 ; This pattern also don't hold of 0x80000000, since the value overflows
6108 ; when negated.
6109 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6110 ; only for comparisons not depending on it.
6111 (define_insn "*addsi_4"
6112 [(set (reg 17)
6113 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6114 (match_operand:SI 2 "const_int_operand" "n")))
6115 (clobber (match_scratch:SI 0 "=rm"))]
6116 "ix86_match_ccmode (insn, CCGCmode)
6117 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6118 {
6119 switch (get_attr_type (insn))
6120 {
6121 case TYPE_INCDEC:
6122 if (operands[2] == constm1_rtx)
6123 return "inc{l}\t%0";
6124 else if (operands[2] == const1_rtx)
6125 return "dec{l}\t%0";
6126 else
6127 abort();
6128
6129 default:
6130 if (! rtx_equal_p (operands[0], operands[1]))
6131 abort ();
6132 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6133 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6134 if ((INTVAL (operands[2]) == -128
6135 || (INTVAL (operands[2]) > 0
6136 && INTVAL (operands[2]) != 128)))
6137 return "sub{l}\t{%2, %0|%0, %2}";
6138 operands[2] = GEN_INT (-INTVAL (operands[2]));
6139 return "add{l}\t{%2, %0|%0, %2}";
6140 }
6141 }
6142 [(set (attr "type")
6143 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6144 (const_string "incdec")
6145 (const_string "alu")))
6146 (set_attr "mode" "SI")])
6147
6148 (define_insn "*addsi_5"
6149 [(set (reg 17)
6150 (compare
6151 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6152 (match_operand:SI 2 "general_operand" "rmni"))
6153 (const_int 0)))
6154 (clobber (match_scratch:SI 0 "=r"))]
6155 "ix86_match_ccmode (insn, CCGOCmode)
6156 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6157 /* Current assemblers are broken and do not allow @GOTOFF in
6158 ought but a memory context. */
6159 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6160 {
6161 switch (get_attr_type (insn))
6162 {
6163 case TYPE_INCDEC:
6164 if (! rtx_equal_p (operands[0], operands[1]))
6165 abort ();
6166 if (operands[2] == const1_rtx)
6167 return "inc{l}\t%0";
6168 else if (operands[2] == constm1_rtx)
6169 return "dec{l}\t%0";
6170 else
6171 abort();
6172
6173 default:
6174 if (! rtx_equal_p (operands[0], operands[1]))
6175 abort ();
6176 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6177 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6178 if (GET_CODE (operands[2]) == CONST_INT
6179 && (INTVAL (operands[2]) == 128
6180 || (INTVAL (operands[2]) < 0
6181 && INTVAL (operands[2]) != -128)))
6182 {
6183 operands[2] = GEN_INT (-INTVAL (operands[2]));
6184 return "sub{l}\t{%2, %0|%0, %2}";
6185 }
6186 return "add{l}\t{%2, %0|%0, %2}";
6187 }
6188 }
6189 [(set (attr "type")
6190 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6191 (const_string "incdec")
6192 (const_string "alu")))
6193 (set_attr "mode" "SI")])
6194
6195 (define_expand "addhi3"
6196 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6197 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6198 (match_operand:HI 2 "general_operand" "")))
6199 (clobber (reg:CC 17))])]
6200 "TARGET_HIMODE_MATH"
6201 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6202
6203 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6204 ;; type optimizations enabled by define-splits. This is not important
6205 ;; for PII, and in fact harmful because of partial register stalls.
6206
6207 (define_insn "*addhi_1_lea"
6208 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6209 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6210 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6211 (clobber (reg:CC 17))]
6212 "!TARGET_PARTIAL_REG_STALL
6213 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6214 {
6215 switch (get_attr_type (insn))
6216 {
6217 case TYPE_LEA:
6218 return "#";
6219 case TYPE_INCDEC:
6220 if (operands[2] == const1_rtx)
6221 return "inc{w}\t%0";
6222 else if (operands[2] == constm1_rtx)
6223 return "dec{w}\t%0";
6224 abort();
6225
6226 default:
6227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6229 if (GET_CODE (operands[2]) == CONST_INT
6230 && (INTVAL (operands[2]) == 128
6231 || (INTVAL (operands[2]) < 0
6232 && INTVAL (operands[2]) != -128)))
6233 {
6234 operands[2] = GEN_INT (-INTVAL (operands[2]));
6235 return "sub{w}\t{%2, %0|%0, %2}";
6236 }
6237 return "add{w}\t{%2, %0|%0, %2}";
6238 }
6239 }
6240 [(set (attr "type")
6241 (if_then_else (eq_attr "alternative" "2")
6242 (const_string "lea")
6243 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu"))))
6246 (set_attr "mode" "HI,HI,SI")])
6247
6248 (define_insn "*addhi_1"
6249 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6250 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6251 (match_operand:HI 2 "general_operand" "ri,rm")))
6252 (clobber (reg:CC 17))]
6253 "TARGET_PARTIAL_REG_STALL
6254 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6255 {
6256 switch (get_attr_type (insn))
6257 {
6258 case TYPE_INCDEC:
6259 if (operands[2] == const1_rtx)
6260 return "inc{w}\t%0";
6261 else if (operands[2] == constm1_rtx)
6262 return "dec{w}\t%0";
6263 abort();
6264
6265 default:
6266 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6267 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6268 if (GET_CODE (operands[2]) == CONST_INT
6269 && (INTVAL (operands[2]) == 128
6270 || (INTVAL (operands[2]) < 0
6271 && INTVAL (operands[2]) != -128)))
6272 {
6273 operands[2] = GEN_INT (-INTVAL (operands[2]));
6274 return "sub{w}\t{%2, %0|%0, %2}";
6275 }
6276 return "add{w}\t{%2, %0|%0, %2}";
6277 }
6278 }
6279 [(set (attr "type")
6280 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6281 (const_string "incdec")
6282 (const_string "alu")))
6283 (set_attr "mode" "HI")])
6284
6285 (define_insn "*addhi_2"
6286 [(set (reg 17)
6287 (compare
6288 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6289 (match_operand:HI 2 "general_operand" "rmni,rni"))
6290 (const_int 0)))
6291 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6292 (plus:HI (match_dup 1) (match_dup 2)))]
6293 "ix86_match_ccmode (insn, CCGOCmode)
6294 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6295 {
6296 switch (get_attr_type (insn))
6297 {
6298 case TYPE_INCDEC:
6299 if (operands[2] == const1_rtx)
6300 return "inc{w}\t%0";
6301 else if (operands[2] == constm1_rtx)
6302 return "dec{w}\t%0";
6303 abort();
6304
6305 default:
6306 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6307 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6308 if (GET_CODE (operands[2]) == CONST_INT
6309 && (INTVAL (operands[2]) == 128
6310 || (INTVAL (operands[2]) < 0
6311 && INTVAL (operands[2]) != -128)))
6312 {
6313 operands[2] = GEN_INT (-INTVAL (operands[2]));
6314 return "sub{w}\t{%2, %0|%0, %2}";
6315 }
6316 return "add{w}\t{%2, %0|%0, %2}";
6317 }
6318 }
6319 [(set (attr "type")
6320 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6321 (const_string "incdec")
6322 (const_string "alu")))
6323 (set_attr "mode" "HI")])
6324
6325 (define_insn "*addhi_3"
6326 [(set (reg 17)
6327 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6328 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6329 (clobber (match_scratch:HI 0 "=r"))]
6330 "ix86_match_ccmode (insn, CCZmode)
6331 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6332 {
6333 switch (get_attr_type (insn))
6334 {
6335 case TYPE_INCDEC:
6336 if (operands[2] == const1_rtx)
6337 return "inc{w}\t%0";
6338 else if (operands[2] == constm1_rtx)
6339 return "dec{w}\t%0";
6340 abort();
6341
6342 default:
6343 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6344 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6345 if (GET_CODE (operands[2]) == CONST_INT
6346 && (INTVAL (operands[2]) == 128
6347 || (INTVAL (operands[2]) < 0
6348 && INTVAL (operands[2]) != -128)))
6349 {
6350 operands[2] = GEN_INT (-INTVAL (operands[2]));
6351 return "sub{w}\t{%2, %0|%0, %2}";
6352 }
6353 return "add{w}\t{%2, %0|%0, %2}";
6354 }
6355 }
6356 [(set (attr "type")
6357 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6358 (const_string "incdec")
6359 (const_string "alu")))
6360 (set_attr "mode" "HI")])
6361
6362 ; See comments above addsi_3_imm for details.
6363 (define_insn "*addhi_4"
6364 [(set (reg 17)
6365 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6366 (match_operand:HI 2 "const_int_operand" "n")))
6367 (clobber (match_scratch:HI 0 "=rm"))]
6368 "ix86_match_ccmode (insn, CCGCmode)
6369 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6370 {
6371 switch (get_attr_type (insn))
6372 {
6373 case TYPE_INCDEC:
6374 if (operands[2] == constm1_rtx)
6375 return "inc{w}\t%0";
6376 else if (operands[2] == const1_rtx)
6377 return "dec{w}\t%0";
6378 else
6379 abort();
6380
6381 default:
6382 if (! rtx_equal_p (operands[0], operands[1]))
6383 abort ();
6384 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6385 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6386 if ((INTVAL (operands[2]) == -128
6387 || (INTVAL (operands[2]) > 0
6388 && INTVAL (operands[2]) != 128)))
6389 return "sub{w}\t{%2, %0|%0, %2}";
6390 operands[2] = GEN_INT (-INTVAL (operands[2]));
6391 return "add{w}\t{%2, %0|%0, %2}";
6392 }
6393 }
6394 [(set (attr "type")
6395 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6396 (const_string "incdec")
6397 (const_string "alu")))
6398 (set_attr "mode" "SI")])
6399
6400
6401 (define_insn "*addhi_5"
6402 [(set (reg 17)
6403 (compare
6404 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6405 (match_operand:HI 2 "general_operand" "rmni"))
6406 (const_int 0)))
6407 (clobber (match_scratch:HI 0 "=r"))]
6408 "ix86_match_ccmode (insn, CCGOCmode)
6409 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6410 {
6411 switch (get_attr_type (insn))
6412 {
6413 case TYPE_INCDEC:
6414 if (operands[2] == const1_rtx)
6415 return "inc{w}\t%0";
6416 else if (operands[2] == constm1_rtx)
6417 return "dec{w}\t%0";
6418 abort();
6419
6420 default:
6421 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6422 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6423 if (GET_CODE (operands[2]) == CONST_INT
6424 && (INTVAL (operands[2]) == 128
6425 || (INTVAL (operands[2]) < 0
6426 && INTVAL (operands[2]) != -128)))
6427 {
6428 operands[2] = GEN_INT (-INTVAL (operands[2]));
6429 return "sub{w}\t{%2, %0|%0, %2}";
6430 }
6431 return "add{w}\t{%2, %0|%0, %2}";
6432 }
6433 }
6434 [(set (attr "type")
6435 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6436 (const_string "incdec")
6437 (const_string "alu")))
6438 (set_attr "mode" "HI")])
6439
6440 (define_expand "addqi3"
6441 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6442 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6443 (match_operand:QI 2 "general_operand" "")))
6444 (clobber (reg:CC 17))])]
6445 "TARGET_QIMODE_MATH"
6446 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6447
6448 ;; %%% Potential partial reg stall on alternative 2. What to do?
6449 (define_insn "*addqi_1_lea"
6450 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6451 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6452 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6453 (clobber (reg:CC 17))]
6454 "!TARGET_PARTIAL_REG_STALL
6455 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6456 {
6457 int widen = (which_alternative == 2);
6458 switch (get_attr_type (insn))
6459 {
6460 case TYPE_LEA:
6461 return "#";
6462 case TYPE_INCDEC:
6463 if (operands[2] == const1_rtx)
6464 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6465 else if (operands[2] == constm1_rtx)
6466 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6467 abort();
6468
6469 default:
6470 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6471 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6472 if (GET_CODE (operands[2]) == CONST_INT
6473 && (INTVAL (operands[2]) == 128
6474 || (INTVAL (operands[2]) < 0
6475 && INTVAL (operands[2]) != -128)))
6476 {
6477 operands[2] = GEN_INT (-INTVAL (operands[2]));
6478 if (widen)
6479 return "sub{l}\t{%2, %k0|%k0, %2}";
6480 else
6481 return "sub{b}\t{%2, %0|%0, %2}";
6482 }
6483 if (widen)
6484 return "add{l}\t{%k2, %k0|%k0, %k2}";
6485 else
6486 return "add{b}\t{%2, %0|%0, %2}";
6487 }
6488 }
6489 [(set (attr "type")
6490 (if_then_else (eq_attr "alternative" "3")
6491 (const_string "lea")
6492 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6493 (const_string "incdec")
6494 (const_string "alu"))))
6495 (set_attr "mode" "QI,QI,SI,SI")])
6496
6497 (define_insn "*addqi_1"
6498 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6499 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6500 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6501 (clobber (reg:CC 17))]
6502 "TARGET_PARTIAL_REG_STALL
6503 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6504 {
6505 int widen = (which_alternative == 2);
6506 switch (get_attr_type (insn))
6507 {
6508 case TYPE_INCDEC:
6509 if (operands[2] == const1_rtx)
6510 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6511 else if (operands[2] == constm1_rtx)
6512 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6513 abort();
6514
6515 default:
6516 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6517 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6518 if (GET_CODE (operands[2]) == CONST_INT
6519 && (INTVAL (operands[2]) == 128
6520 || (INTVAL (operands[2]) < 0
6521 && INTVAL (operands[2]) != -128)))
6522 {
6523 operands[2] = GEN_INT (-INTVAL (operands[2]));
6524 if (widen)
6525 return "sub{l}\t{%2, %k0|%k0, %2}";
6526 else
6527 return "sub{b}\t{%2, %0|%0, %2}";
6528 }
6529 if (widen)
6530 return "add{l}\t{%k2, %k0|%k0, %k2}";
6531 else
6532 return "add{b}\t{%2, %0|%0, %2}";
6533 }
6534 }
6535 [(set (attr "type")
6536 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6537 (const_string "incdec")
6538 (const_string "alu")))
6539 (set_attr "mode" "QI,QI,SI")])
6540
6541 (define_insn "*addqi_1_slp"
6542 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6543 (plus:QI (match_dup 0)
6544 (match_operand:QI 1 "general_operand" "qn,qnm")))
6545 (clobber (reg:CC 17))]
6546 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6547 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6548 {
6549 switch (get_attr_type (insn))
6550 {
6551 case TYPE_INCDEC:
6552 if (operands[1] == const1_rtx)
6553 return "inc{b}\t%0";
6554 else if (operands[1] == constm1_rtx)
6555 return "dec{b}\t%0";
6556 abort();
6557
6558 default:
6559 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6560 if (GET_CODE (operands[1]) == CONST_INT
6561 && INTVAL (operands[1]) < 0)
6562 {
6563 operands[2] = GEN_INT (-INTVAL (operands[2]));
6564 return "sub{b}\t{%1, %0|%0, %1}";
6565 }
6566 return "add{b}\t{%1, %0|%0, %1}";
6567 }
6568 }
6569 [(set (attr "type")
6570 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6571 (const_string "incdec")
6572 (const_string "alu1")))
6573 (set_attr "mode" "QI")])
6574
6575 (define_insn "*addqi_2"
6576 [(set (reg 17)
6577 (compare
6578 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6579 (match_operand:QI 2 "general_operand" "qmni,qni"))
6580 (const_int 0)))
6581 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6582 (plus:QI (match_dup 1) (match_dup 2)))]
6583 "ix86_match_ccmode (insn, CCGOCmode)
6584 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6585 {
6586 switch (get_attr_type (insn))
6587 {
6588 case TYPE_INCDEC:
6589 if (operands[2] == const1_rtx)
6590 return "inc{b}\t%0";
6591 else if (operands[2] == constm1_rtx
6592 || (GET_CODE (operands[2]) == CONST_INT
6593 && INTVAL (operands[2]) == 255))
6594 return "dec{b}\t%0";
6595 abort();
6596
6597 default:
6598 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6599 if (GET_CODE (operands[2]) == CONST_INT
6600 && INTVAL (operands[2]) < 0)
6601 {
6602 operands[2] = GEN_INT (-INTVAL (operands[2]));
6603 return "sub{b}\t{%2, %0|%0, %2}";
6604 }
6605 return "add{b}\t{%2, %0|%0, %2}";
6606 }
6607 }
6608 [(set (attr "type")
6609 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6610 (const_string "incdec")
6611 (const_string "alu")))
6612 (set_attr "mode" "QI")])
6613
6614 (define_insn "*addqi_3"
6615 [(set (reg 17)
6616 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6617 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6618 (clobber (match_scratch:QI 0 "=q"))]
6619 "ix86_match_ccmode (insn, CCZmode)
6620 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6621 {
6622 switch (get_attr_type (insn))
6623 {
6624 case TYPE_INCDEC:
6625 if (operands[2] == const1_rtx)
6626 return "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 "dec{b}\t%0";
6631 abort();
6632
6633 default:
6634 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6635 if (GET_CODE (operands[2]) == CONST_INT
6636 && INTVAL (operands[2]) < 0)
6637 {
6638 operands[2] = GEN_INT (-INTVAL (operands[2]));
6639 return "sub{b}\t{%2, %0|%0, %2}";
6640 }
6641 return "add{b}\t{%2, %0|%0, %2}";
6642 }
6643 }
6644 [(set (attr "type")
6645 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6646 (const_string "incdec")
6647 (const_string "alu")))
6648 (set_attr "mode" "QI")])
6649
6650 ; See comments above addsi_3_imm for details.
6651 (define_insn "*addqi_4"
6652 [(set (reg 17)
6653 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6654 (match_operand:QI 2 "const_int_operand" "n")))
6655 (clobber (match_scratch:QI 0 "=qm"))]
6656 "ix86_match_ccmode (insn, CCGCmode)
6657 && (INTVAL (operands[2]) & 0xff) != 0x80"
6658 {
6659 switch (get_attr_type (insn))
6660 {
6661 case TYPE_INCDEC:
6662 if (operands[2] == constm1_rtx
6663 || (GET_CODE (operands[2]) == CONST_INT
6664 && INTVAL (operands[2]) == 255))
6665 return "inc{b}\t%0";
6666 else if (operands[2] == const1_rtx)
6667 return "dec{b}\t%0";
6668 else
6669 abort();
6670
6671 default:
6672 if (! rtx_equal_p (operands[0], operands[1]))
6673 abort ();
6674 if (INTVAL (operands[2]) < 0)
6675 {
6676 operands[2] = GEN_INT (-INTVAL (operands[2]));
6677 return "add{b}\t{%2, %0|%0, %2}";
6678 }
6679 return "sub{b}\t{%2, %0|%0, %2}";
6680 }
6681 }
6682 [(set (attr "type")
6683 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6684 (const_string "incdec")
6685 (const_string "alu")))
6686 (set_attr "mode" "QI")])
6687
6688
6689 (define_insn "*addqi_5"
6690 [(set (reg 17)
6691 (compare
6692 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6693 (match_operand:QI 2 "general_operand" "qmni"))
6694 (const_int 0)))
6695 (clobber (match_scratch:QI 0 "=q"))]
6696 "ix86_match_ccmode (insn, CCGOCmode)
6697 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6698 {
6699 switch (get_attr_type (insn))
6700 {
6701 case TYPE_INCDEC:
6702 if (operands[2] == const1_rtx)
6703 return "inc{b}\t%0";
6704 else if (operands[2] == constm1_rtx
6705 || (GET_CODE (operands[2]) == CONST_INT
6706 && INTVAL (operands[2]) == 255))
6707 return "dec{b}\t%0";
6708 abort();
6709
6710 default:
6711 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6712 if (GET_CODE (operands[2]) == CONST_INT
6713 && INTVAL (operands[2]) < 0)
6714 {
6715 operands[2] = GEN_INT (-INTVAL (operands[2]));
6716 return "sub{b}\t{%2, %0|%0, %2}";
6717 }
6718 return "add{b}\t{%2, %0|%0, %2}";
6719 }
6720 }
6721 [(set (attr "type")
6722 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6723 (const_string "incdec")
6724 (const_string "alu")))
6725 (set_attr "mode" "QI")])
6726
6727
6728 (define_insn "addqi_ext_1"
6729 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6730 (const_int 8)
6731 (const_int 8))
6732 (plus:SI
6733 (zero_extract:SI
6734 (match_operand 1 "ext_register_operand" "0")
6735 (const_int 8)
6736 (const_int 8))
6737 (match_operand:QI 2 "general_operand" "Qmn")))
6738 (clobber (reg:CC 17))]
6739 "!TARGET_64BIT"
6740 {
6741 switch (get_attr_type (insn))
6742 {
6743 case TYPE_INCDEC:
6744 if (operands[2] == const1_rtx)
6745 return "inc{b}\t%h0";
6746 else if (operands[2] == constm1_rtx
6747 || (GET_CODE (operands[2]) == CONST_INT
6748 && INTVAL (operands[2]) == 255))
6749 return "dec{b}\t%h0";
6750 abort();
6751
6752 default:
6753 return "add{b}\t{%2, %h0|%h0, %2}";
6754 }
6755 }
6756 [(set (attr "type")
6757 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6758 (const_string "incdec")
6759 (const_string "alu")))
6760 (set_attr "mode" "QI")])
6761
6762 (define_insn "*addqi_ext_1_rex64"
6763 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6764 (const_int 8)
6765 (const_int 8))
6766 (plus:SI
6767 (zero_extract:SI
6768 (match_operand 1 "ext_register_operand" "0")
6769 (const_int 8)
6770 (const_int 8))
6771 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6772 (clobber (reg:CC 17))]
6773 "TARGET_64BIT"
6774 {
6775 switch (get_attr_type (insn))
6776 {
6777 case TYPE_INCDEC:
6778 if (operands[2] == const1_rtx)
6779 return "inc{b}\t%h0";
6780 else if (operands[2] == constm1_rtx
6781 || (GET_CODE (operands[2]) == CONST_INT
6782 && INTVAL (operands[2]) == 255))
6783 return "dec{b}\t%h0";
6784 abort();
6785
6786 default:
6787 return "add{b}\t{%2, %h0|%h0, %2}";
6788 }
6789 }
6790 [(set (attr "type")
6791 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6792 (const_string "incdec")
6793 (const_string "alu")))
6794 (set_attr "mode" "QI")])
6795
6796 (define_insn "*addqi_ext_2"
6797 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6798 (const_int 8)
6799 (const_int 8))
6800 (plus:SI
6801 (zero_extract:SI
6802 (match_operand 1 "ext_register_operand" "%0")
6803 (const_int 8)
6804 (const_int 8))
6805 (zero_extract:SI
6806 (match_operand 2 "ext_register_operand" "Q")
6807 (const_int 8)
6808 (const_int 8))))
6809 (clobber (reg:CC 17))]
6810 ""
6811 "add{b}\t{%h2, %h0|%h0, %h2}"
6812 [(set_attr "type" "alu")
6813 (set_attr "mode" "QI")])
6814
6815 ;; The patterns that match these are at the end of this file.
6816
6817 (define_expand "addxf3"
6818 [(set (match_operand:XF 0 "register_operand" "")
6819 (plus:XF (match_operand:XF 1 "register_operand" "")
6820 (match_operand:XF 2 "register_operand" "")))]
6821 "!TARGET_64BIT && TARGET_80387"
6822 "")
6823
6824 (define_expand "addtf3"
6825 [(set (match_operand:TF 0 "register_operand" "")
6826 (plus:TF (match_operand:TF 1 "register_operand" "")
6827 (match_operand:TF 2 "register_operand" "")))]
6828 "TARGET_80387"
6829 "")
6830
6831 (define_expand "adddf3"
6832 [(set (match_operand:DF 0 "register_operand" "")
6833 (plus:DF (match_operand:DF 1 "register_operand" "")
6834 (match_operand:DF 2 "nonimmediate_operand" "")))]
6835 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6836 "")
6837
6838 (define_expand "addsf3"
6839 [(set (match_operand:SF 0 "register_operand" "")
6840 (plus:SF (match_operand:SF 1 "register_operand" "")
6841 (match_operand:SF 2 "nonimmediate_operand" "")))]
6842 "TARGET_80387 || TARGET_SSE_MATH"
6843 "")
6844 \f
6845 ;; Subtract instructions
6846
6847 ;; %%% splits for subsidi3
6848
6849 (define_expand "subdi3"
6850 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6851 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6852 (match_operand:DI 2 "x86_64_general_operand" "")))
6853 (clobber (reg:CC 17))])]
6854 ""
6855 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6856
6857 (define_insn "*subdi3_1"
6858 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6859 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6860 (match_operand:DI 2 "general_operand" "roiF,riF")))
6861 (clobber (reg:CC 17))]
6862 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6863 "#")
6864
6865 (define_split
6866 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6867 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6868 (match_operand:DI 2 "general_operand" "")))
6869 (clobber (reg:CC 17))]
6870 "!TARGET_64BIT && reload_completed"
6871 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6872 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6873 (parallel [(set (match_dup 3)
6874 (minus:SI (match_dup 4)
6875 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6876 (match_dup 5))))
6877 (clobber (reg:CC 17))])]
6878 "split_di (operands+0, 1, operands+0, operands+3);
6879 split_di (operands+1, 1, operands+1, operands+4);
6880 split_di (operands+2, 1, operands+2, operands+5);")
6881
6882 (define_insn "subdi3_carry_rex64"
6883 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6884 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6885 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6886 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6887 (clobber (reg:CC 17))]
6888 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6889 "sbb{q}\t{%2, %0|%0, %2}"
6890 [(set_attr "type" "alu")
6891 (set_attr "pent_pair" "pu")
6892 (set_attr "ppro_uops" "few")
6893 (set_attr "mode" "DI")])
6894
6895 (define_insn "*subdi_1_rex64"
6896 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6897 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6898 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6899 (clobber (reg:CC 17))]
6900 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6901 "sub{q}\t{%2, %0|%0, %2}"
6902 [(set_attr "type" "alu")
6903 (set_attr "mode" "DI")])
6904
6905 (define_insn "*subdi_2_rex64"
6906 [(set (reg 17)
6907 (compare
6908 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6909 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6910 (const_int 0)))
6911 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6912 (minus:DI (match_dup 1) (match_dup 2)))]
6913 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6914 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6915 "sub{q}\t{%2, %0|%0, %2}"
6916 [(set_attr "type" "alu")
6917 (set_attr "mode" "DI")])
6918
6919 (define_insn "*subdi_3_rex63"
6920 [(set (reg 17)
6921 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6922 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6923 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6924 (minus:DI (match_dup 1) (match_dup 2)))]
6925 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6926 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6927 "sub{q}\t{%2, %0|%0, %2}"
6928 [(set_attr "type" "alu")
6929 (set_attr "mode" "DI")])
6930
6931 (define_insn "subqi3_carry"
6932 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6933 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6934 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6935 (match_operand:QI 2 "general_operand" "ri,rm"))))
6936 (clobber (reg:CC 17))]
6937 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6938 "sbb{b}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "alu")
6940 (set_attr "pent_pair" "pu")
6941 (set_attr "ppro_uops" "few")
6942 (set_attr "mode" "QI")])
6943
6944 (define_insn "subhi3_carry"
6945 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6946 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6947 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6948 (match_operand:HI 2 "general_operand" "ri,rm"))))
6949 (clobber (reg:CC 17))]
6950 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6951 "sbb{w}\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" "HI")])
6956
6957 (define_insn "subsi3_carry"
6958 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6959 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6960 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6961 (match_operand:SI 2 "general_operand" "ri,rm"))))
6962 (clobber (reg:CC 17))]
6963 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6964 "sbb{l}\t{%2, %0|%0, %2}"
6965 [(set_attr "type" "alu")
6966 (set_attr "pent_pair" "pu")
6967 (set_attr "ppro_uops" "few")
6968 (set_attr "mode" "SI")])
6969
6970 (define_insn "subsi3_carry_zext"
6971 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6972 (zero_extend:DI
6973 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6974 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6975 (match_operand:SI 2 "general_operand" "ri,rm")))))
6976 (clobber (reg:CC 17))]
6977 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6978 "sbb{l}\t{%2, %k0|%k0, %2}"
6979 [(set_attr "type" "alu")
6980 (set_attr "pent_pair" "pu")
6981 (set_attr "ppro_uops" "few")
6982 (set_attr "mode" "SI")])
6983
6984 (define_expand "subsi3"
6985 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6986 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6987 (match_operand:SI 2 "general_operand" "")))
6988 (clobber (reg:CC 17))])]
6989 ""
6990 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6991
6992 (define_insn "*subsi_1"
6993 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6994 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6995 (match_operand:SI 2 "general_operand" "ri,rm")))
6996 (clobber (reg:CC 17))]
6997 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6998 "sub{l}\t{%2, %0|%0, %2}"
6999 [(set_attr "type" "alu")
7000 (set_attr "mode" "SI")])
7001
7002 (define_insn "*subsi_1_zext"
7003 [(set (match_operand:DI 0 "register_operand" "=r")
7004 (zero_extend:DI
7005 (minus:SI (match_operand:SI 1 "register_operand" "0")
7006 (match_operand:SI 2 "general_operand" "rim"))))
7007 (clobber (reg:CC 17))]
7008 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7009 "sub{l}\t{%2, %k0|%k0, %2}"
7010 [(set_attr "type" "alu")
7011 (set_attr "mode" "SI")])
7012
7013 (define_insn "*subsi_2"
7014 [(set (reg 17)
7015 (compare
7016 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7017 (match_operand:SI 2 "general_operand" "ri,rm"))
7018 (const_int 0)))
7019 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7020 (minus:SI (match_dup 1) (match_dup 2)))]
7021 "ix86_match_ccmode (insn, CCGOCmode)
7022 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7023 "sub{l}\t{%2, %0|%0, %2}"
7024 [(set_attr "type" "alu")
7025 (set_attr "mode" "SI")])
7026
7027 (define_insn "*subsi_2_zext"
7028 [(set (reg 17)
7029 (compare
7030 (minus:SI (match_operand:SI 1 "register_operand" "0")
7031 (match_operand:SI 2 "general_operand" "rim"))
7032 (const_int 0)))
7033 (set (match_operand:DI 0 "register_operand" "=r")
7034 (zero_extend:DI
7035 (minus:SI (match_dup 1)
7036 (match_dup 2))))]
7037 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7038 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7039 "sub{l}\t{%2, %k0|%k0, %2}"
7040 [(set_attr "type" "alu")
7041 (set_attr "mode" "SI")])
7042
7043 (define_insn "*subsi_3"
7044 [(set (reg 17)
7045 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7046 (match_operand:SI 2 "general_operand" "ri,rm")))
7047 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7048 (minus:SI (match_dup 1) (match_dup 2)))]
7049 "ix86_match_ccmode (insn, CCmode)
7050 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7051 "sub{l}\t{%2, %0|%0, %2}"
7052 [(set_attr "type" "alu")
7053 (set_attr "mode" "SI")])
7054
7055 (define_insn "*subsi_3_zext"
7056 [(set (reg 17)
7057 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7058 (match_operand:SI 2 "general_operand" "rim")))
7059 (set (match_operand:DI 0 "register_operand" "=r")
7060 (zero_extend:DI
7061 (minus:SI (match_dup 1)
7062 (match_dup 2))))]
7063 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7064 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7065 "sub{q}\t{%2, %0|%0, %2}"
7066 [(set_attr "type" "alu")
7067 (set_attr "mode" "DI")])
7068
7069 (define_expand "subhi3"
7070 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7071 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7072 (match_operand:HI 2 "general_operand" "")))
7073 (clobber (reg:CC 17))])]
7074 "TARGET_HIMODE_MATH"
7075 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7076
7077 (define_insn "*subhi_1"
7078 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7079 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7080 (match_operand:HI 2 "general_operand" "ri,rm")))
7081 (clobber (reg:CC 17))]
7082 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7083 "sub{w}\t{%2, %0|%0, %2}"
7084 [(set_attr "type" "alu")
7085 (set_attr "mode" "HI")])
7086
7087 (define_insn "*subhi_2"
7088 [(set (reg 17)
7089 (compare
7090 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7091 (match_operand:HI 2 "general_operand" "ri,rm"))
7092 (const_int 0)))
7093 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7094 (minus:HI (match_dup 1) (match_dup 2)))]
7095 "ix86_match_ccmode (insn, CCGOCmode)
7096 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7097 "sub{w}\t{%2, %0|%0, %2}"
7098 [(set_attr "type" "alu")
7099 (set_attr "mode" "HI")])
7100
7101 (define_insn "*subhi_3"
7102 [(set (reg 17)
7103 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7104 (match_operand:HI 2 "general_operand" "ri,rm")))
7105 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7106 (minus:HI (match_dup 1) (match_dup 2)))]
7107 "ix86_match_ccmode (insn, CCmode)
7108 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7109 "sub{w}\t{%2, %0|%0, %2}"
7110 [(set_attr "type" "alu")
7111 (set_attr "mode" "HI")])
7112
7113 (define_expand "subqi3"
7114 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7115 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7116 (match_operand:QI 2 "general_operand" "")))
7117 (clobber (reg:CC 17))])]
7118 "TARGET_QIMODE_MATH"
7119 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7120
7121 (define_insn "*subqi_1"
7122 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7123 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7124 (match_operand:QI 2 "general_operand" "qn,qmn")))
7125 (clobber (reg:CC 17))]
7126 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7127 "sub{b}\t{%2, %0|%0, %2}"
7128 [(set_attr "type" "alu")
7129 (set_attr "mode" "QI")])
7130
7131 (define_insn "*subqi_1_slp"
7132 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7133 (minus:QI (match_dup 0)
7134 (match_operand:QI 1 "general_operand" "qn,qmn")))
7135 (clobber (reg:CC 17))]
7136 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7137 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7138 "sub{b}\t{%1, %0|%0, %1}"
7139 [(set_attr "type" "alu1")
7140 (set_attr "mode" "QI")])
7141
7142 (define_insn "*subqi_2"
7143 [(set (reg 17)
7144 (compare
7145 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7146 (match_operand:QI 2 "general_operand" "qi,qm"))
7147 (const_int 0)))
7148 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7149 (minus:HI (match_dup 1) (match_dup 2)))]
7150 "ix86_match_ccmode (insn, CCGOCmode)
7151 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7152 "sub{b}\t{%2, %0|%0, %2}"
7153 [(set_attr "type" "alu")
7154 (set_attr "mode" "QI")])
7155
7156 (define_insn "*subqi_3"
7157 [(set (reg 17)
7158 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7159 (match_operand:QI 2 "general_operand" "qi,qm")))
7160 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7161 (minus:HI (match_dup 1) (match_dup 2)))]
7162 "ix86_match_ccmode (insn, CCmode)
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 ;; The patterns that match these are at the end of this file.
7169
7170 (define_expand "subxf3"
7171 [(set (match_operand:XF 0 "register_operand" "")
7172 (minus:XF (match_operand:XF 1 "register_operand" "")
7173 (match_operand:XF 2 "register_operand" "")))]
7174 "!TARGET_64BIT && TARGET_80387"
7175 "")
7176
7177 (define_expand "subtf3"
7178 [(set (match_operand:TF 0 "register_operand" "")
7179 (minus:TF (match_operand:TF 1 "register_operand" "")
7180 (match_operand:TF 2 "register_operand" "")))]
7181 "TARGET_80387"
7182 "")
7183
7184 (define_expand "subdf3"
7185 [(set (match_operand:DF 0 "register_operand" "")
7186 (minus:DF (match_operand:DF 1 "register_operand" "")
7187 (match_operand:DF 2 "nonimmediate_operand" "")))]
7188 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7189 "")
7190
7191 (define_expand "subsf3"
7192 [(set (match_operand:SF 0 "register_operand" "")
7193 (minus:SF (match_operand:SF 1 "register_operand" "")
7194 (match_operand:SF 2 "nonimmediate_operand" "")))]
7195 "TARGET_80387 || TARGET_SSE_MATH"
7196 "")
7197 \f
7198 ;; Multiply instructions
7199
7200 (define_expand "muldi3"
7201 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7202 (mult:DI (match_operand:DI 1 "register_operand" "")
7203 (match_operand:DI 2 "x86_64_general_operand" "")))
7204 (clobber (reg:CC 17))])]
7205 "TARGET_64BIT"
7206 "")
7207
7208 (define_insn "*muldi3_1_rex64"
7209 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7210 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7211 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7212 (clobber (reg:CC 17))]
7213 "TARGET_64BIT
7214 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7215 "@
7216 imul{q}\t{%2, %1, %0|%0, %1, %2}
7217 imul{q}\t{%2, %1, %0|%0, %1, %2}
7218 imul{q}\t{%2, %0|%0, %2}"
7219 [(set_attr "type" "imul")
7220 (set_attr "prefix_0f" "0,0,1")
7221 (set (attr "athlon_decode")
7222 (cond [(eq_attr "cpu" "athlon")
7223 (const_string "vector")
7224 (eq_attr "alternative" "1")
7225 (const_string "vector")
7226 (and (eq_attr "alternative" "2")
7227 (match_operand 1 "memory_operand" ""))
7228 (const_string "vector")]
7229 (const_string "direct")))
7230 (set_attr "mode" "DI")])
7231
7232 (define_expand "mulsi3"
7233 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7234 (mult:SI (match_operand:SI 1 "register_operand" "")
7235 (match_operand:SI 2 "general_operand" "")))
7236 (clobber (reg:CC 17))])]
7237 ""
7238 "")
7239
7240 (define_insn "*mulsi3_1"
7241 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7242 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7243 (match_operand:SI 2 "general_operand" "K,i,mr")))
7244 (clobber (reg:CC 17))]
7245 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7246 "@
7247 imul{l}\t{%2, %1, %0|%0, %1, %2}
7248 imul{l}\t{%2, %1, %0|%0, %1, %2}
7249 imul{l}\t{%2, %0|%0, %2}"
7250 [(set_attr "type" "imul")
7251 (set_attr "prefix_0f" "0,0,1")
7252 (set (attr "athlon_decode")
7253 (cond [(eq_attr "cpu" "athlon")
7254 (const_string "vector")
7255 (eq_attr "alternative" "1")
7256 (const_string "vector")
7257 (and (eq_attr "alternative" "2")
7258 (match_operand 1 "memory_operand" ""))
7259 (const_string "vector")]
7260 (const_string "direct")))
7261 (set_attr "mode" "SI")])
7262
7263 (define_insn "*mulsi3_1_zext"
7264 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7265 (zero_extend:DI
7266 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7267 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7268 (clobber (reg:CC 17))]
7269 "TARGET_64BIT
7270 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7271 "@
7272 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7273 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7274 imul{l}\t{%2, %k0|%k0, %2}"
7275 [(set_attr "type" "imul")
7276 (set_attr "prefix_0f" "0,0,1")
7277 (set (attr "athlon_decode")
7278 (cond [(eq_attr "cpu" "athlon")
7279 (const_string "vector")
7280 (eq_attr "alternative" "1")
7281 (const_string "vector")
7282 (and (eq_attr "alternative" "2")
7283 (match_operand 1 "memory_operand" ""))
7284 (const_string "vector")]
7285 (const_string "direct")))
7286 (set_attr "mode" "SI")])
7287
7288 (define_expand "mulhi3"
7289 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7290 (mult:HI (match_operand:HI 1 "register_operand" "")
7291 (match_operand:HI 2 "general_operand" "")))
7292 (clobber (reg:CC 17))])]
7293 "TARGET_HIMODE_MATH"
7294 "")
7295
7296 (define_insn "*mulhi3_1"
7297 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7298 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7299 (match_operand:HI 2 "general_operand" "K,i,mr")))
7300 (clobber (reg:CC 17))]
7301 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7302 "@
7303 imul{w}\t{%2, %1, %0|%0, %1, %2}
7304 imul{w}\t{%2, %1, %0|%0, %1, %2}
7305 imul{w}\t{%2, %0|%0, %2}"
7306 [(set_attr "type" "imul")
7307 (set_attr "prefix_0f" "0,0,1")
7308 (set (attr "athlon_decode")
7309 (cond [(eq_attr "cpu" "athlon")
7310 (const_string "vector")
7311 (eq_attr "alternative" "1,2")
7312 (const_string "vector")]
7313 (const_string "direct")))
7314 (set_attr "mode" "HI")])
7315
7316 (define_expand "mulqi3"
7317 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7318 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7319 (match_operand:QI 2 "register_operand" "")))
7320 (clobber (reg:CC 17))])]
7321 "TARGET_QIMODE_MATH"
7322 "")
7323
7324 (define_insn "*mulqi3_1"
7325 [(set (match_operand:QI 0 "register_operand" "=a")
7326 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7327 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7328 (clobber (reg:CC 17))]
7329 "TARGET_QIMODE_MATH
7330 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7331 "mul{b}\t%2"
7332 [(set_attr "type" "imul")
7333 (set_attr "length_immediate" "0")
7334 (set (attr "athlon_decode")
7335 (if_then_else (eq_attr "cpu" "athlon")
7336 (const_string "vector")
7337 (const_string "direct")))
7338 (set_attr "mode" "QI")])
7339
7340 (define_expand "umulqihi3"
7341 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7342 (mult:HI (zero_extend:HI
7343 (match_operand:QI 1 "nonimmediate_operand" ""))
7344 (zero_extend:HI
7345 (match_operand:QI 2 "register_operand" ""))))
7346 (clobber (reg:CC 17))])]
7347 "TARGET_QIMODE_MATH"
7348 "")
7349
7350 (define_insn "*umulqihi3_1"
7351 [(set (match_operand:HI 0 "register_operand" "=a")
7352 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7353 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7354 (clobber (reg:CC 17))]
7355 "TARGET_QIMODE_MATH
7356 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7357 "mul{b}\t%2"
7358 [(set_attr "type" "imul")
7359 (set_attr "length_immediate" "0")
7360 (set (attr "athlon_decode")
7361 (if_then_else (eq_attr "cpu" "athlon")
7362 (const_string "vector")
7363 (const_string "direct")))
7364 (set_attr "mode" "QI")])
7365
7366 (define_expand "mulqihi3"
7367 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7368 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7369 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7370 (clobber (reg:CC 17))])]
7371 "TARGET_QIMODE_MATH"
7372 "")
7373
7374 (define_insn "*mulqihi3_insn"
7375 [(set (match_operand:HI 0 "register_operand" "=a")
7376 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7377 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7378 (clobber (reg:CC 17))]
7379 "TARGET_QIMODE_MATH
7380 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7381 "imul{b}\t%2"
7382 [(set_attr "type" "imul")
7383 (set_attr "length_immediate" "0")
7384 (set (attr "athlon_decode")
7385 (if_then_else (eq_attr "cpu" "athlon")
7386 (const_string "vector")
7387 (const_string "direct")))
7388 (set_attr "mode" "QI")])
7389
7390 (define_expand "umulditi3"
7391 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7392 (mult:TI (zero_extend:TI
7393 (match_operand:DI 1 "nonimmediate_operand" ""))
7394 (zero_extend:TI
7395 (match_operand:DI 2 "register_operand" ""))))
7396 (clobber (reg:CC 17))])]
7397 "TARGET_64BIT"
7398 "")
7399
7400 (define_insn "*umulditi3_insn"
7401 [(set (match_operand:TI 0 "register_operand" "=A")
7402 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7403 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7404 (clobber (reg:CC 17))]
7405 "TARGET_64BIT
7406 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7407 "mul{q}\t%2"
7408 [(set_attr "type" "imul")
7409 (set_attr "ppro_uops" "few")
7410 (set_attr "length_immediate" "0")
7411 (set (attr "athlon_decode")
7412 (if_then_else (eq_attr "cpu" "athlon")
7413 (const_string "vector")
7414 (const_string "double")))
7415 (set_attr "mode" "DI")])
7416
7417 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7418 (define_expand "umulsidi3"
7419 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7420 (mult:DI (zero_extend:DI
7421 (match_operand:SI 1 "nonimmediate_operand" ""))
7422 (zero_extend:DI
7423 (match_operand:SI 2 "register_operand" ""))))
7424 (clobber (reg:CC 17))])]
7425 "!TARGET_64BIT"
7426 "")
7427
7428 (define_insn "*umulsidi3_insn"
7429 [(set (match_operand:DI 0 "register_operand" "=A")
7430 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7431 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7432 (clobber (reg:CC 17))]
7433 "!TARGET_64BIT
7434 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7435 "mul{l}\t%2"
7436 [(set_attr "type" "imul")
7437 (set_attr "ppro_uops" "few")
7438 (set_attr "length_immediate" "0")
7439 (set (attr "athlon_decode")
7440 (if_then_else (eq_attr "cpu" "athlon")
7441 (const_string "vector")
7442 (const_string "double")))
7443 (set_attr "mode" "SI")])
7444
7445 (define_expand "mulditi3"
7446 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7447 (mult:TI (sign_extend:TI
7448 (match_operand:DI 1 "nonimmediate_operand" ""))
7449 (sign_extend:TI
7450 (match_operand:DI 2 "register_operand" ""))))
7451 (clobber (reg:CC 17))])]
7452 "TARGET_64BIT"
7453 "")
7454
7455 (define_insn "*mulditi3_insn"
7456 [(set (match_operand:TI 0 "register_operand" "=A")
7457 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7458 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7459 (clobber (reg:CC 17))]
7460 "TARGET_64BIT
7461 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7462 "imul{q}\t%2"
7463 [(set_attr "type" "imul")
7464 (set_attr "length_immediate" "0")
7465 (set (attr "athlon_decode")
7466 (if_then_else (eq_attr "cpu" "athlon")
7467 (const_string "vector")
7468 (const_string "double")))
7469 (set_attr "mode" "DI")])
7470
7471 (define_expand "mulsidi3"
7472 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7473 (mult:DI (sign_extend:DI
7474 (match_operand:SI 1 "nonimmediate_operand" ""))
7475 (sign_extend:DI
7476 (match_operand:SI 2 "register_operand" ""))))
7477 (clobber (reg:CC 17))])]
7478 "!TARGET_64BIT"
7479 "")
7480
7481 (define_insn "*mulsidi3_insn"
7482 [(set (match_operand:DI 0 "register_operand" "=A")
7483 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7484 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7485 (clobber (reg:CC 17))]
7486 "!TARGET_64BIT
7487 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7488 "imul{l}\t%2"
7489 [(set_attr "type" "imul")
7490 (set_attr "length_immediate" "0")
7491 (set (attr "athlon_decode")
7492 (if_then_else (eq_attr "cpu" "athlon")
7493 (const_string "vector")
7494 (const_string "double")))
7495 (set_attr "mode" "SI")])
7496
7497 (define_expand "umuldi3_highpart"
7498 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7499 (truncate:DI
7500 (lshiftrt:TI
7501 (mult:TI (zero_extend:TI
7502 (match_operand:DI 1 "nonimmediate_operand" ""))
7503 (zero_extend:TI
7504 (match_operand:DI 2 "register_operand" "")))
7505 (const_int 64))))
7506 (clobber (match_scratch:DI 3 ""))
7507 (clobber (reg:CC 17))])]
7508 "TARGET_64BIT"
7509 "")
7510
7511 (define_insn "*umuldi3_highpart_rex64"
7512 [(set (match_operand:DI 0 "register_operand" "=d")
7513 (truncate:DI
7514 (lshiftrt:TI
7515 (mult:TI (zero_extend:TI
7516 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7517 (zero_extend:TI
7518 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7519 (const_int 64))))
7520 (clobber (match_scratch:DI 3 "=1"))
7521 (clobber (reg:CC 17))]
7522 "TARGET_64BIT
7523 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7524 "mul{q}\t%2"
7525 [(set_attr "type" "imul")
7526 (set_attr "ppro_uops" "few")
7527 (set_attr "length_immediate" "0")
7528 (set (attr "athlon_decode")
7529 (if_then_else (eq_attr "cpu" "athlon")
7530 (const_string "vector")
7531 (const_string "double")))
7532 (set_attr "mode" "DI")])
7533
7534 (define_expand "umulsi3_highpart"
7535 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7536 (truncate:SI
7537 (lshiftrt:DI
7538 (mult:DI (zero_extend:DI
7539 (match_operand:SI 1 "nonimmediate_operand" ""))
7540 (zero_extend:DI
7541 (match_operand:SI 2 "register_operand" "")))
7542 (const_int 32))))
7543 (clobber (match_scratch:SI 3 ""))
7544 (clobber (reg:CC 17))])]
7545 ""
7546 "")
7547
7548 (define_insn "*umulsi3_highpart_insn"
7549 [(set (match_operand:SI 0 "register_operand" "=d")
7550 (truncate:SI
7551 (lshiftrt:DI
7552 (mult:DI (zero_extend:DI
7553 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7554 (zero_extend:DI
7555 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7556 (const_int 32))))
7557 (clobber (match_scratch:SI 3 "=1"))
7558 (clobber (reg:CC 17))]
7559 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7560 "mul{l}\t%2"
7561 [(set_attr "type" "imul")
7562 (set_attr "ppro_uops" "few")
7563 (set_attr "length_immediate" "0")
7564 (set (attr "athlon_decode")
7565 (if_then_else (eq_attr "cpu" "athlon")
7566 (const_string "vector")
7567 (const_string "double")))
7568 (set_attr "mode" "SI")])
7569
7570 (define_insn "*umulsi3_highpart_zext"
7571 [(set (match_operand:DI 0 "register_operand" "=d")
7572 (zero_extend:DI (truncate:SI
7573 (lshiftrt:DI
7574 (mult:DI (zero_extend:DI
7575 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7576 (zero_extend:DI
7577 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7578 (const_int 32)))))
7579 (clobber (match_scratch:SI 3 "=1"))
7580 (clobber (reg:CC 17))]
7581 "TARGET_64BIT
7582 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7583 "mul{l}\t%2"
7584 [(set_attr "type" "imul")
7585 (set_attr "ppro_uops" "few")
7586 (set_attr "length_immediate" "0")
7587 (set (attr "athlon_decode")
7588 (if_then_else (eq_attr "cpu" "athlon")
7589 (const_string "vector")
7590 (const_string "double")))
7591 (set_attr "mode" "SI")])
7592
7593 (define_expand "smuldi3_highpart"
7594 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7595 (truncate:DI
7596 (lshiftrt:TI
7597 (mult:TI (sign_extend:TI
7598 (match_operand:DI 1 "nonimmediate_operand" ""))
7599 (sign_extend:TI
7600 (match_operand:DI 2 "register_operand" "")))
7601 (const_int 64))))
7602 (clobber (match_scratch:DI 3 ""))
7603 (clobber (reg:CC 17))])]
7604 "TARGET_64BIT"
7605 "")
7606
7607 (define_insn "*smuldi3_highpart_rex64"
7608 [(set (match_operand:DI 0 "register_operand" "=d")
7609 (truncate:DI
7610 (lshiftrt:TI
7611 (mult:TI (sign_extend:TI
7612 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7613 (sign_extend:TI
7614 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7615 (const_int 64))))
7616 (clobber (match_scratch:DI 3 "=1"))
7617 (clobber (reg:CC 17))]
7618 "TARGET_64BIT
7619 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7620 "imul{q}\t%2"
7621 [(set_attr "type" "imul")
7622 (set_attr "ppro_uops" "few")
7623 (set (attr "athlon_decode")
7624 (if_then_else (eq_attr "cpu" "athlon")
7625 (const_string "vector")
7626 (const_string "double")))
7627 (set_attr "mode" "DI")])
7628
7629 (define_expand "smulsi3_highpart"
7630 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7631 (truncate:SI
7632 (lshiftrt:DI
7633 (mult:DI (sign_extend:DI
7634 (match_operand:SI 1 "nonimmediate_operand" ""))
7635 (sign_extend:DI
7636 (match_operand:SI 2 "register_operand" "")))
7637 (const_int 32))))
7638 (clobber (match_scratch:SI 3 ""))
7639 (clobber (reg:CC 17))])]
7640 ""
7641 "")
7642
7643 (define_insn "*smulsi3_highpart_insn"
7644 [(set (match_operand:SI 0 "register_operand" "=d")
7645 (truncate:SI
7646 (lshiftrt:DI
7647 (mult:DI (sign_extend:DI
7648 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7649 (sign_extend:DI
7650 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7651 (const_int 32))))
7652 (clobber (match_scratch:SI 3 "=1"))
7653 (clobber (reg:CC 17))]
7654 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7655 "imul{l}\t%2"
7656 [(set_attr "type" "imul")
7657 (set_attr "ppro_uops" "few")
7658 (set (attr "athlon_decode")
7659 (if_then_else (eq_attr "cpu" "athlon")
7660 (const_string "vector")
7661 (const_string "double")))
7662 (set_attr "mode" "SI")])
7663
7664 (define_insn "*smulsi3_highpart_zext"
7665 [(set (match_operand:DI 0 "register_operand" "=d")
7666 (zero_extend:DI (truncate:SI
7667 (lshiftrt:DI
7668 (mult:DI (sign_extend:DI
7669 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7670 (sign_extend:DI
7671 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7672 (const_int 32)))))
7673 (clobber (match_scratch:SI 3 "=1"))
7674 (clobber (reg:CC 17))]
7675 "TARGET_64BIT
7676 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7677 "imul{l}\t%2"
7678 [(set_attr "type" "imul")
7679 (set_attr "ppro_uops" "few")
7680 (set (attr "athlon_decode")
7681 (if_then_else (eq_attr "cpu" "athlon")
7682 (const_string "vector")
7683 (const_string "double")))
7684 (set_attr "mode" "SI")])
7685
7686 ;; The patterns that match these are at the end of this file.
7687
7688 (define_expand "mulxf3"
7689 [(set (match_operand:XF 0 "register_operand" "")
7690 (mult:XF (match_operand:XF 1 "register_operand" "")
7691 (match_operand:XF 2 "register_operand" "")))]
7692 "!TARGET_64BIT && TARGET_80387"
7693 "")
7694
7695 (define_expand "multf3"
7696 [(set (match_operand:TF 0 "register_operand" "")
7697 (mult:TF (match_operand:TF 1 "register_operand" "")
7698 (match_operand:TF 2 "register_operand" "")))]
7699 "TARGET_80387"
7700 "")
7701
7702 (define_expand "muldf3"
7703 [(set (match_operand:DF 0 "register_operand" "")
7704 (mult:DF (match_operand:DF 1 "register_operand" "")
7705 (match_operand:DF 2 "nonimmediate_operand" "")))]
7706 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7707 "")
7708
7709 (define_expand "mulsf3"
7710 [(set (match_operand:SF 0 "register_operand" "")
7711 (mult:SF (match_operand:SF 1 "register_operand" "")
7712 (match_operand:SF 2 "nonimmediate_operand" "")))]
7713 "TARGET_80387 || TARGET_SSE_MATH"
7714 "")
7715 \f
7716 ;; Divide instructions
7717
7718 (define_insn "divqi3"
7719 [(set (match_operand:QI 0 "register_operand" "=a")
7720 (div: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 "idiv{b}\t%2"
7725 [(set_attr "type" "idiv")
7726 (set_attr "mode" "QI")
7727 (set_attr "ppro_uops" "few")])
7728
7729 (define_insn "udivqi3"
7730 [(set (match_operand:QI 0 "register_operand" "=a")
7731 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7732 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7733 (clobber (reg:CC 17))]
7734 "TARGET_QIMODE_MATH"
7735 "div{b}\t%2"
7736 [(set_attr "type" "idiv")
7737 (set_attr "mode" "QI")
7738 (set_attr "ppro_uops" "few")])
7739
7740 ;; The patterns that match these are at the end of this file.
7741
7742 (define_expand "divxf3"
7743 [(set (match_operand:XF 0 "register_operand" "")
7744 (div:XF (match_operand:XF 1 "register_operand" "")
7745 (match_operand:XF 2 "register_operand" "")))]
7746 "!TARGET_64BIT && TARGET_80387"
7747 "")
7748
7749 (define_expand "divtf3"
7750 [(set (match_operand:TF 0 "register_operand" "")
7751 (div:TF (match_operand:TF 1 "register_operand" "")
7752 (match_operand:TF 2 "register_operand" "")))]
7753 "TARGET_80387"
7754 "")
7755
7756 (define_expand "divdf3"
7757 [(set (match_operand:DF 0 "register_operand" "")
7758 (div:DF (match_operand:DF 1 "register_operand" "")
7759 (match_operand:DF 2 "nonimmediate_operand" "")))]
7760 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7761 "")
7762
7763 (define_expand "divsf3"
7764 [(set (match_operand:SF 0 "register_operand" "")
7765 (div:SF (match_operand:SF 1 "register_operand" "")
7766 (match_operand:SF 2 "nonimmediate_operand" "")))]
7767 "TARGET_80387 || TARGET_SSE_MATH"
7768 "")
7769 \f
7770 ;; Remainder instructions.
7771
7772 (define_expand "divmoddi4"
7773 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7774 (div:DI (match_operand:DI 1 "register_operand" "")
7775 (match_operand:DI 2 "nonimmediate_operand" "")))
7776 (set (match_operand:DI 3 "register_operand" "")
7777 (mod:DI (match_dup 1) (match_dup 2)))
7778 (clobber (reg:CC 17))])]
7779 "TARGET_64BIT"
7780 "")
7781
7782 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7783 ;; Penalize eax case slightly because it results in worse scheduling
7784 ;; of code.
7785 (define_insn "*divmoddi4_nocltd_rex64"
7786 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7787 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7788 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7789 (set (match_operand:DI 1 "register_operand" "=&d,&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 "*divmoddi4_cltd_rex64"
7797 [(set (match_operand:DI 0 "register_operand" "=a")
7798 (div:DI (match_operand:DI 2 "register_operand" "a")
7799 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7800 (set (match_operand:DI 1 "register_operand" "=&d")
7801 (mod:DI (match_dup 2) (match_dup 3)))
7802 (clobber (reg:CC 17))]
7803 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7804 "#"
7805 [(set_attr "type" "multi")])
7806
7807 (define_insn "*divmoddi_noext_rex64"
7808 [(set (match_operand:DI 0 "register_operand" "=a")
7809 (div:DI (match_operand:DI 1 "register_operand" "0")
7810 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7811 (set (match_operand:DI 3 "register_operand" "=d")
7812 (mod:DI (match_dup 1) (match_dup 2)))
7813 (use (match_operand:DI 4 "register_operand" "3"))
7814 (clobber (reg:CC 17))]
7815 "TARGET_64BIT"
7816 "idiv{q}\t%2"
7817 [(set_attr "type" "idiv")
7818 (set_attr "mode" "DI")
7819 (set_attr "ppro_uops" "few")])
7820
7821 (define_split
7822 [(set (match_operand:DI 0 "register_operand" "")
7823 (div:DI (match_operand:DI 1 "register_operand" "")
7824 (match_operand:DI 2 "nonimmediate_operand" "")))
7825 (set (match_operand:DI 3 "register_operand" "")
7826 (mod:DI (match_dup 1) (match_dup 2)))
7827 (clobber (reg:CC 17))]
7828 "TARGET_64BIT && reload_completed"
7829 [(parallel [(set (match_dup 3)
7830 (ashiftrt:DI (match_dup 4) (const_int 63)))
7831 (clobber (reg:CC 17))])
7832 (parallel [(set (match_dup 0)
7833 (div:DI (reg:DI 0) (match_dup 2)))
7834 (set (match_dup 3)
7835 (mod:DI (reg:DI 0) (match_dup 2)))
7836 (use (match_dup 3))
7837 (clobber (reg:CC 17))])]
7838 {
7839 /* Avoid use of cltd in favor of a mov+shift. */
7840 if (!TARGET_USE_CLTD && !optimize_size)
7841 {
7842 if (true_regnum (operands[1]))
7843 emit_move_insn (operands[0], operands[1]);
7844 else
7845 emit_move_insn (operands[3], operands[1]);
7846 operands[4] = operands[3];
7847 }
7848 else
7849 {
7850 if (true_regnum (operands[1]))
7851 abort();
7852 operands[4] = operands[1];
7853 }
7854 })
7855
7856
7857 (define_expand "divmodsi4"
7858 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7859 (div:SI (match_operand:SI 1 "register_operand" "")
7860 (match_operand:SI 2 "nonimmediate_operand" "")))
7861 (set (match_operand:SI 3 "register_operand" "")
7862 (mod:SI (match_dup 1) (match_dup 2)))
7863 (clobber (reg:CC 17))])]
7864 ""
7865 "")
7866
7867 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7868 ;; Penalize eax case slightly because it results in worse scheduling
7869 ;; of code.
7870 (define_insn "*divmodsi4_nocltd"
7871 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7872 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7873 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7874 (set (match_operand:SI 1 "register_operand" "=&d,&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 "*divmodsi4_cltd"
7882 [(set (match_operand:SI 0 "register_operand" "=a")
7883 (div:SI (match_operand:SI 2 "register_operand" "a")
7884 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7885 (set (match_operand:SI 1 "register_operand" "=&d")
7886 (mod:SI (match_dup 2) (match_dup 3)))
7887 (clobber (reg:CC 17))]
7888 "optimize_size || TARGET_USE_CLTD"
7889 "#"
7890 [(set_attr "type" "multi")])
7891
7892 (define_insn "*divmodsi_noext"
7893 [(set (match_operand:SI 0 "register_operand" "=a")
7894 (div:SI (match_operand:SI 1 "register_operand" "0")
7895 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7896 (set (match_operand:SI 3 "register_operand" "=d")
7897 (mod:SI (match_dup 1) (match_dup 2)))
7898 (use (match_operand:SI 4 "register_operand" "3"))
7899 (clobber (reg:CC 17))]
7900 ""
7901 "idiv{l}\t%2"
7902 [(set_attr "type" "idiv")
7903 (set_attr "mode" "SI")
7904 (set_attr "ppro_uops" "few")])
7905
7906 (define_split
7907 [(set (match_operand:SI 0 "register_operand" "")
7908 (div:SI (match_operand:SI 1 "register_operand" "")
7909 (match_operand:SI 2 "nonimmediate_operand" "")))
7910 (set (match_operand:SI 3 "register_operand" "")
7911 (mod:SI (match_dup 1) (match_dup 2)))
7912 (clobber (reg:CC 17))]
7913 "reload_completed"
7914 [(parallel [(set (match_dup 3)
7915 (ashiftrt:SI (match_dup 4) (const_int 31)))
7916 (clobber (reg:CC 17))])
7917 (parallel [(set (match_dup 0)
7918 (div:SI (reg:SI 0) (match_dup 2)))
7919 (set (match_dup 3)
7920 (mod:SI (reg:SI 0) (match_dup 2)))
7921 (use (match_dup 3))
7922 (clobber (reg:CC 17))])]
7923 {
7924 /* Avoid use of cltd in favor of a mov+shift. */
7925 if (!TARGET_USE_CLTD && !optimize_size)
7926 {
7927 if (true_regnum (operands[1]))
7928 emit_move_insn (operands[0], operands[1]);
7929 else
7930 emit_move_insn (operands[3], operands[1]);
7931 operands[4] = operands[3];
7932 }
7933 else
7934 {
7935 if (true_regnum (operands[1]))
7936 abort();
7937 operands[4] = operands[1];
7938 }
7939 })
7940 ;; %%% Split me.
7941 (define_insn "divmodhi4"
7942 [(set (match_operand:HI 0 "register_operand" "=a")
7943 (div:HI (match_operand:HI 1 "register_operand" "0")
7944 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7945 (set (match_operand:HI 3 "register_operand" "=&d")
7946 (mod:HI (match_dup 1) (match_dup 2)))
7947 (clobber (reg:CC 17))]
7948 "TARGET_HIMODE_MATH"
7949 "cwtd\;idiv{w}\t%2"
7950 [(set_attr "type" "multi")
7951 (set_attr "length_immediate" "0")
7952 (set_attr "mode" "SI")])
7953
7954 (define_insn "udivmoddi4"
7955 [(set (match_operand:DI 0 "register_operand" "=a")
7956 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7957 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7958 (set (match_operand:DI 3 "register_operand" "=&d")
7959 (umod:DI (match_dup 1) (match_dup 2)))
7960 (clobber (reg:CC 17))]
7961 "TARGET_64BIT"
7962 "xor{q}\t%3, %3\;div{q}\t%2"
7963 [(set_attr "type" "multi")
7964 (set_attr "length_immediate" "0")
7965 (set_attr "mode" "DI")])
7966
7967 (define_insn "*udivmoddi4_noext"
7968 [(set (match_operand:DI 0 "register_operand" "=a")
7969 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7970 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7971 (set (match_operand:DI 3 "register_operand" "=d")
7972 (umod:DI (match_dup 1) (match_dup 2)))
7973 (use (match_dup 3))
7974 (clobber (reg:CC 17))]
7975 "TARGET_64BIT"
7976 "div{q}\t%2"
7977 [(set_attr "type" "idiv")
7978 (set_attr "ppro_uops" "few")
7979 (set_attr "mode" "DI")])
7980
7981 (define_split
7982 [(set (match_operand:DI 0 "register_operand" "")
7983 (udiv:DI (match_operand:DI 1 "register_operand" "")
7984 (match_operand:DI 2 "nonimmediate_operand" "")))
7985 (set (match_operand:DI 3 "register_operand" "")
7986 (umod:DI (match_dup 1) (match_dup 2)))
7987 (clobber (reg:CC 17))]
7988 "TARGET_64BIT && reload_completed"
7989 [(set (match_dup 3) (const_int 0))
7990 (parallel [(set (match_dup 0)
7991 (udiv:DI (match_dup 1) (match_dup 2)))
7992 (set (match_dup 3)
7993 (umod:DI (match_dup 1) (match_dup 2)))
7994 (use (match_dup 3))
7995 (clobber (reg:CC 17))])]
7996 "")
7997
7998 (define_insn "udivmodsi4"
7999 [(set (match_operand:SI 0 "register_operand" "=a")
8000 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8001 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8002 (set (match_operand:SI 3 "register_operand" "=&d")
8003 (umod:SI (match_dup 1) (match_dup 2)))
8004 (clobber (reg:CC 17))]
8005 ""
8006 "xor{l}\t%3, %3\;div{l}\t%2"
8007 [(set_attr "type" "multi")
8008 (set_attr "length_immediate" "0")
8009 (set_attr "mode" "SI")])
8010
8011 (define_insn "*udivmodsi4_noext"
8012 [(set (match_operand:SI 0 "register_operand" "=a")
8013 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8014 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8015 (set (match_operand:SI 3 "register_operand" "=d")
8016 (umod:SI (match_dup 1) (match_dup 2)))
8017 (use (match_dup 3))
8018 (clobber (reg:CC 17))]
8019 ""
8020 "div{l}\t%2"
8021 [(set_attr "type" "idiv")
8022 (set_attr "ppro_uops" "few")
8023 (set_attr "mode" "SI")])
8024
8025 (define_split
8026 [(set (match_operand:SI 0 "register_operand" "")
8027 (udiv:SI (match_operand:SI 1 "register_operand" "")
8028 (match_operand:SI 2 "nonimmediate_operand" "")))
8029 (set (match_operand:SI 3 "register_operand" "")
8030 (umod:SI (match_dup 1) (match_dup 2)))
8031 (clobber (reg:CC 17))]
8032 "reload_completed"
8033 [(set (match_dup 3) (const_int 0))
8034 (parallel [(set (match_dup 0)
8035 (udiv:SI (match_dup 1) (match_dup 2)))
8036 (set (match_dup 3)
8037 (umod:SI (match_dup 1) (match_dup 2)))
8038 (use (match_dup 3))
8039 (clobber (reg:CC 17))])]
8040 "")
8041
8042 (define_expand "udivmodhi4"
8043 [(set (match_dup 4) (const_int 0))
8044 (parallel [(set (match_operand:HI 0 "register_operand" "")
8045 (udiv:HI (match_operand:HI 1 "register_operand" "")
8046 (match_operand:HI 2 "nonimmediate_operand" "")))
8047 (set (match_operand:HI 3 "register_operand" "")
8048 (umod:HI (match_dup 1) (match_dup 2)))
8049 (use (match_dup 4))
8050 (clobber (reg:CC 17))])]
8051 "TARGET_HIMODE_MATH"
8052 "operands[4] = gen_reg_rtx (HImode);")
8053
8054 (define_insn "*udivmodhi_noext"
8055 [(set (match_operand:HI 0 "register_operand" "=a")
8056 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8057 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8058 (set (match_operand:HI 3 "register_operand" "=d")
8059 (umod:HI (match_dup 1) (match_dup 2)))
8060 (use (match_operand:HI 4 "register_operand" "3"))
8061 (clobber (reg:CC 17))]
8062 ""
8063 "div{w}\t%2"
8064 [(set_attr "type" "idiv")
8065 (set_attr "mode" "HI")
8066 (set_attr "ppro_uops" "few")])
8067
8068 ;; We can not use div/idiv for double division, because it causes
8069 ;; "division by zero" on the overflow and that's not what we expect
8070 ;; from truncate. Because true (non truncating) double division is
8071 ;; never generated, we can't create this insn anyway.
8072 ;
8073 ;(define_insn ""
8074 ; [(set (match_operand:SI 0 "register_operand" "=a")
8075 ; (truncate:SI
8076 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8077 ; (zero_extend:DI
8078 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8079 ; (set (match_operand:SI 3 "register_operand" "=d")
8080 ; (truncate:SI
8081 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8082 ; (clobber (reg:CC 17))]
8083 ; ""
8084 ; "div{l}\t{%2, %0|%0, %2}"
8085 ; [(set_attr "type" "idiv")
8086 ; (set_attr "ppro_uops" "few")])
8087 \f
8088 ;;- Logical AND instructions
8089
8090 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8091 ;; Note that this excludes ah.
8092
8093 (define_insn "*testdi_1_rex64"
8094 [(set (reg 17)
8095 (compare
8096 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8097 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8098 (const_int 0)))]
8099 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8100 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8101 "@
8102 test{l}\t{%k1, %k0|%k0, %k1}
8103 test{l}\t{%k1, %k0|%k0, %k1}
8104 test{q}\t{%1, %0|%0, %1}
8105 test{q}\t{%1, %0|%0, %1}
8106 test{q}\t{%1, %0|%0, %1}"
8107 [(set_attr "type" "test")
8108 (set_attr "modrm" "0,1,0,1,1")
8109 (set_attr "mode" "SI,SI,DI,DI,DI")
8110 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8111
8112 (define_insn "testsi_1"
8113 [(set (reg 17)
8114 (compare
8115 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8116 (match_operand:SI 1 "general_operand" "in,in,rin"))
8117 (const_int 0)))]
8118 "ix86_match_ccmode (insn, CCNOmode)
8119 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8120 "test{l}\t{%1, %0|%0, %1}"
8121 [(set_attr "type" "test")
8122 (set_attr "modrm" "0,1,1")
8123 (set_attr "mode" "SI")
8124 (set_attr "pent_pair" "uv,np,uv")])
8125
8126 (define_expand "testsi_ccno_1"
8127 [(set (reg:CCNO 17)
8128 (compare:CCNO
8129 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8130 (match_operand:SI 1 "nonmemory_operand" ""))
8131 (const_int 0)))]
8132 ""
8133 "")
8134
8135 (define_insn "*testhi_1"
8136 [(set (reg 17)
8137 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8138 (match_operand:HI 1 "general_operand" "n,n,rn"))
8139 (const_int 0)))]
8140 "ix86_match_ccmode (insn, CCNOmode)
8141 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8142 "test{w}\t{%1, %0|%0, %1}"
8143 [(set_attr "type" "test")
8144 (set_attr "modrm" "0,1,1")
8145 (set_attr "mode" "HI")
8146 (set_attr "pent_pair" "uv,np,uv")])
8147
8148 (define_expand "testqi_ccz_1"
8149 [(set (reg:CCZ 17)
8150 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8151 (match_operand:QI 1 "nonmemory_operand" ""))
8152 (const_int 0)))]
8153 ""
8154 "")
8155
8156 (define_insn "*testqi_1"
8157 [(set (reg 17)
8158 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8159 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8160 (const_int 0)))]
8161 "ix86_match_ccmode (insn, CCNOmode)
8162 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8163 {
8164 if (which_alternative == 3)
8165 {
8166 if (GET_CODE (operands[1]) == CONST_INT
8167 && (INTVAL (operands[1]) & 0xffffff00))
8168 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8169 return "test{l}\t{%1, %k0|%k0, %1}";
8170 }
8171 return "test{b}\t{%1, %0|%0, %1}";
8172 }
8173 [(set_attr "type" "test")
8174 (set_attr "modrm" "0,1,1,1")
8175 (set_attr "mode" "QI,QI,QI,SI")
8176 (set_attr "pent_pair" "uv,np,uv,np")])
8177
8178 (define_expand "testqi_ext_ccno_0"
8179 [(set (reg:CCNO 17)
8180 (compare:CCNO
8181 (and:SI
8182 (zero_extract:SI
8183 (match_operand 0 "ext_register_operand" "")
8184 (const_int 8)
8185 (const_int 8))
8186 (match_operand 1 "const_int_operand" ""))
8187 (const_int 0)))]
8188 ""
8189 "")
8190
8191 (define_insn "*testqi_ext_0"
8192 [(set (reg 17)
8193 (compare
8194 (and:SI
8195 (zero_extract:SI
8196 (match_operand 0 "ext_register_operand" "Q")
8197 (const_int 8)
8198 (const_int 8))
8199 (match_operand 1 "const_int_operand" "n"))
8200 (const_int 0)))]
8201 "ix86_match_ccmode (insn, CCNOmode)"
8202 "test{b}\t{%1, %h0|%h0, %1}"
8203 [(set_attr "type" "test")
8204 (set_attr "mode" "QI")
8205 (set_attr "length_immediate" "1")
8206 (set_attr "pent_pair" "np")])
8207
8208 (define_insn "*testqi_ext_1"
8209 [(set (reg 17)
8210 (compare
8211 (and:SI
8212 (zero_extract:SI
8213 (match_operand 0 "ext_register_operand" "Q")
8214 (const_int 8)
8215 (const_int 8))
8216 (zero_extend:SI
8217 (match_operand:QI 1 "general_operand" "Qm")))
8218 (const_int 0)))]
8219 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8220 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8221 "test{b}\t{%1, %h0|%h0, %1}"
8222 [(set_attr "type" "test")
8223 (set_attr "mode" "QI")])
8224
8225 (define_insn "*testqi_ext_1_rex64"
8226 [(set (reg 17)
8227 (compare
8228 (and:SI
8229 (zero_extract:SI
8230 (match_operand 0 "ext_register_operand" "Q")
8231 (const_int 8)
8232 (const_int 8))
8233 (zero_extend:SI
8234 (match_operand:QI 1 "register_operand" "Q")))
8235 (const_int 0)))]
8236 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8237 "test{b}\t{%1, %h0|%h0, %1}"
8238 [(set_attr "type" "test")
8239 (set_attr "mode" "QI")])
8240
8241 (define_insn "*testqi_ext_2"
8242 [(set (reg 17)
8243 (compare
8244 (and:SI
8245 (zero_extract:SI
8246 (match_operand 0 "ext_register_operand" "Q")
8247 (const_int 8)
8248 (const_int 8))
8249 (zero_extract:SI
8250 (match_operand 1 "ext_register_operand" "Q")
8251 (const_int 8)
8252 (const_int 8)))
8253 (const_int 0)))]
8254 "ix86_match_ccmode (insn, CCNOmode)"
8255 "test{b}\t{%h1, %h0|%h0, %h1}"
8256 [(set_attr "type" "test")
8257 (set_attr "mode" "QI")])
8258
8259 ;; Combine likes to form bit extractions for some tests. Humor it.
8260 (define_insn "*testqi_ext_3"
8261 [(set (reg 17)
8262 (compare (zero_extract:SI
8263 (match_operand 0 "nonimmediate_operand" "rm")
8264 (match_operand:SI 1 "const_int_operand" "")
8265 (match_operand:SI 2 "const_int_operand" ""))
8266 (const_int 0)))]
8267 "ix86_match_ccmode (insn, CCNOmode)
8268 && (GET_MODE (operands[0]) == SImode
8269 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8270 || GET_MODE (operands[0]) == HImode
8271 || GET_MODE (operands[0]) == QImode)"
8272 "#")
8273
8274 (define_insn "*testqi_ext_3_rex64"
8275 [(set (reg 17)
8276 (compare (zero_extract:DI
8277 (match_operand 0 "nonimmediate_operand" "rm")
8278 (match_operand:DI 1 "const_int_operand" "")
8279 (match_operand:DI 2 "const_int_operand" ""))
8280 (const_int 0)))]
8281 "TARGET_64BIT
8282 && ix86_match_ccmode (insn, CCNOmode)
8283 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8284 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8285 /* Ensure that resulting mask is zero or sign extended operand. */
8286 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8287 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8288 && INTVAL (operands[1]) > 32))
8289 && (GET_MODE (operands[0]) == SImode
8290 || GET_MODE (operands[0]) == DImode
8291 || GET_MODE (operands[0]) == HImode
8292 || GET_MODE (operands[0]) == QImode)"
8293 "#")
8294
8295 (define_split
8296 [(set (reg 17)
8297 (compare (zero_extract
8298 (match_operand 0 "nonimmediate_operand" "")
8299 (match_operand 1 "const_int_operand" "")
8300 (match_operand 2 "const_int_operand" ""))
8301 (const_int 0)))]
8302 "ix86_match_ccmode (insn, CCNOmode)"
8303 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8304 {
8305 HOST_WIDE_INT len = INTVAL (operands[1]);
8306 HOST_WIDE_INT pos = INTVAL (operands[2]);
8307 HOST_WIDE_INT mask;
8308 enum machine_mode mode, submode;
8309
8310 mode = GET_MODE (operands[0]);
8311 if (GET_CODE (operands[0]) == MEM)
8312 {
8313 /* ??? Combine likes to put non-volatile mem extractions in QImode
8314 no matter the size of the test. So find a mode that works. */
8315 if (! MEM_VOLATILE_P (operands[0]))
8316 {
8317 mode = smallest_mode_for_size (pos + len, MODE_INT);
8318 operands[0] = adjust_address (operands[0], mode, 0);
8319 }
8320 }
8321 else if (GET_CODE (operands[0]) == SUBREG
8322 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8323 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8324 && pos + len <= GET_MODE_BITSIZE (submode))
8325 {
8326 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8327 mode = submode;
8328 operands[0] = SUBREG_REG (operands[0]);
8329 }
8330 else if (mode == HImode && pos + len <= 8)
8331 {
8332 /* Small HImode tests can be converted to QImode. */
8333 mode = QImode;
8334 operands[0] = gen_lowpart (QImode, operands[0]);
8335 }
8336
8337 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8338 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8339
8340 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8341 })
8342
8343 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8344 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8345 ;; this is relatively important trick.
8346 ;; Do the conversion only post-reload to avoid limiting of the register class
8347 ;; to QI regs.
8348 (define_split
8349 [(set (reg 17)
8350 (compare
8351 (and (match_operand 0 "register_operand" "")
8352 (match_operand 1 "const_int_operand" ""))
8353 (const_int 0)))]
8354 "reload_completed
8355 && QI_REG_P (operands[0])
8356 && ((ix86_match_ccmode (insn, CCZmode)
8357 && !(INTVAL (operands[1]) & ~(255 << 8)))
8358 || (ix86_match_ccmode (insn, CCNOmode)
8359 && !(INTVAL (operands[1]) & ~(127 << 8))))
8360 && GET_MODE (operands[0]) != QImode"
8361 [(set (reg:CCNO 17)
8362 (compare:CCNO
8363 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8364 (match_dup 1))
8365 (const_int 0)))]
8366 "operands[0] = gen_lowpart (SImode, operands[0]);
8367 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8368
8369 (define_split
8370 [(set (reg 17)
8371 (compare
8372 (and (match_operand 0 "nonimmediate_operand" "")
8373 (match_operand 1 "const_int_operand" ""))
8374 (const_int 0)))]
8375 "reload_completed
8376 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8377 && ((ix86_match_ccmode (insn, CCZmode)
8378 && !(INTVAL (operands[1]) & ~255))
8379 || (ix86_match_ccmode (insn, CCNOmode)
8380 && !(INTVAL (operands[1]) & ~127)))
8381 && GET_MODE (operands[0]) != QImode"
8382 [(set (reg:CCNO 17)
8383 (compare:CCNO
8384 (and:QI (match_dup 0)
8385 (match_dup 1))
8386 (const_int 0)))]
8387 "operands[0] = gen_lowpart (QImode, operands[0]);
8388 operands[1] = gen_lowpart (QImode, operands[1]);")
8389
8390
8391 ;; %%% This used to optimize known byte-wide and operations to memory,
8392 ;; and sometimes to QImode registers. If this is considered useful,
8393 ;; it should be done with splitters.
8394
8395 (define_expand "anddi3"
8396 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8397 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8398 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8399 (clobber (reg:CC 17))]
8400 "TARGET_64BIT"
8401 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8402
8403 (define_insn "*anddi_1_rex64"
8404 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8405 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8406 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8407 (clobber (reg:CC 17))]
8408 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8409 {
8410 switch (get_attr_type (insn))
8411 {
8412 case TYPE_IMOVX:
8413 {
8414 enum machine_mode mode;
8415
8416 if (GET_CODE (operands[2]) != CONST_INT)
8417 abort ();
8418 if (INTVAL (operands[2]) == 0xff)
8419 mode = QImode;
8420 else if (INTVAL (operands[2]) == 0xffff)
8421 mode = HImode;
8422 else
8423 abort ();
8424
8425 operands[1] = gen_lowpart (mode, operands[1]);
8426 if (mode == QImode)
8427 return "movz{bq|x}\t{%1,%0|%0, %1}";
8428 else
8429 return "movz{wq|x}\t{%1,%0|%0, %1}";
8430 }
8431
8432 default:
8433 if (! rtx_equal_p (operands[0], operands[1]))
8434 abort ();
8435 if (get_attr_mode (insn) == MODE_SI)
8436 return "and{l}\t{%k2, %k0|%k0, %k2}";
8437 else
8438 return "and{q}\t{%2, %0|%0, %2}";
8439 }
8440 }
8441 [(set_attr "type" "alu,alu,alu,imovx")
8442 (set_attr "length_immediate" "*,*,*,0")
8443 (set_attr "mode" "SI,DI,DI,DI")])
8444
8445 (define_insn "*anddi_2"
8446 [(set (reg 17)
8447 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8448 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8449 (const_int 0)))
8450 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8451 (and:DI (match_dup 1) (match_dup 2)))]
8452 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8453 && ix86_binary_operator_ok (AND, DImode, operands)"
8454 "@
8455 and{l}\t{%k2, %k0|%k0, %k2}
8456 and{q}\t{%2, %0|%0, %2}
8457 and{q}\t{%2, %0|%0, %2}"
8458 [(set_attr "type" "alu")
8459 (set_attr "mode" "SI,DI,DI")])
8460
8461 (define_expand "andsi3"
8462 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8463 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8464 (match_operand:SI 2 "general_operand" "")))
8465 (clobber (reg:CC 17))]
8466 ""
8467 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8468
8469 (define_insn "*andsi_1"
8470 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8471 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8472 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8473 (clobber (reg:CC 17))]
8474 "ix86_binary_operator_ok (AND, SImode, operands)"
8475 {
8476 switch (get_attr_type (insn))
8477 {
8478 case TYPE_IMOVX:
8479 {
8480 enum machine_mode mode;
8481
8482 if (GET_CODE (operands[2]) != CONST_INT)
8483 abort ();
8484 if (INTVAL (operands[2]) == 0xff)
8485 mode = QImode;
8486 else if (INTVAL (operands[2]) == 0xffff)
8487 mode = HImode;
8488 else
8489 abort ();
8490
8491 operands[1] = gen_lowpart (mode, operands[1]);
8492 if (mode == QImode)
8493 return "movz{bl|x}\t{%1,%0|%0, %1}";
8494 else
8495 return "movz{wl|x}\t{%1,%0|%0, %1}";
8496 }
8497
8498 default:
8499 if (! rtx_equal_p (operands[0], operands[1]))
8500 abort ();
8501 return "and{l}\t{%2, %0|%0, %2}";
8502 }
8503 }
8504 [(set_attr "type" "alu,alu,imovx")
8505 (set_attr "length_immediate" "*,*,0")
8506 (set_attr "mode" "SI")])
8507
8508 (define_split
8509 [(set (match_operand 0 "register_operand" "")
8510 (and (match_dup 0)
8511 (const_int -65536)))
8512 (clobber (reg:CC 17))]
8513 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8514 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8515 "operands[1] = gen_lowpart (HImode, operands[0]);")
8516
8517 (define_split
8518 [(set (match_operand 0 "ext_register_operand" "")
8519 (and (match_dup 0)
8520 (const_int -256)))
8521 (clobber (reg:CC 17))]
8522 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8523 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8524 "operands[1] = gen_lowpart (QImode, operands[0]);")
8525
8526 (define_split
8527 [(set (match_operand 0 "ext_register_operand" "")
8528 (and (match_dup 0)
8529 (const_int -65281)))
8530 (clobber (reg:CC 17))]
8531 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8532 [(parallel [(set (zero_extract:SI (match_dup 0)
8533 (const_int 8)
8534 (const_int 8))
8535 (xor:SI
8536 (zero_extract:SI (match_dup 0)
8537 (const_int 8)
8538 (const_int 8))
8539 (zero_extract:SI (match_dup 0)
8540 (const_int 8)
8541 (const_int 8))))
8542 (clobber (reg:CC 17))])]
8543 "operands[0] = gen_lowpart (SImode, operands[0]);")
8544
8545 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8546 (define_insn "*andsi_1_zext"
8547 [(set (match_operand:DI 0 "register_operand" "=r")
8548 (zero_extend:DI
8549 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8550 (match_operand:SI 2 "general_operand" "rim"))))
8551 (clobber (reg:CC 17))]
8552 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8553 "and{l}\t{%2, %k0|%k0, %2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "mode" "SI")])
8556
8557 (define_insn "*andsi_2"
8558 [(set (reg 17)
8559 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8560 (match_operand:SI 2 "general_operand" "rim,ri"))
8561 (const_int 0)))
8562 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8563 (and:SI (match_dup 1) (match_dup 2)))]
8564 "ix86_match_ccmode (insn, CCNOmode)
8565 && ix86_binary_operator_ok (AND, SImode, operands)"
8566 "and{l}\t{%2, %0|%0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "mode" "SI")])
8569
8570 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8571 (define_insn "*andsi_2_zext"
8572 [(set (reg 17)
8573 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8574 (match_operand:SI 2 "general_operand" "rim"))
8575 (const_int 0)))
8576 (set (match_operand:DI 0 "register_operand" "=r")
8577 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8578 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8579 && ix86_binary_operator_ok (AND, SImode, operands)"
8580 "and{l}\t{%2, %k0|%k0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "mode" "SI")])
8583
8584 (define_expand "andhi3"
8585 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8586 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8587 (match_operand:HI 2 "general_operand" "")))
8588 (clobber (reg:CC 17))]
8589 "TARGET_HIMODE_MATH"
8590 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8591
8592 (define_insn "*andhi_1"
8593 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8594 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8595 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8596 (clobber (reg:CC 17))]
8597 "ix86_binary_operator_ok (AND, HImode, operands)"
8598 {
8599 switch (get_attr_type (insn))
8600 {
8601 case TYPE_IMOVX:
8602 if (GET_CODE (operands[2]) != CONST_INT)
8603 abort ();
8604 if (INTVAL (operands[2]) == 0xff)
8605 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8606 abort ();
8607
8608 default:
8609 if (! rtx_equal_p (operands[0], operands[1]))
8610 abort ();
8611
8612 return "and{w}\t{%2, %0|%0, %2}";
8613 }
8614 }
8615 [(set_attr "type" "alu,alu,imovx")
8616 (set_attr "length_immediate" "*,*,0")
8617 (set_attr "mode" "HI,HI,SI")])
8618
8619 (define_insn "*andhi_2"
8620 [(set (reg 17)
8621 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8622 (match_operand:HI 2 "general_operand" "rim,ri"))
8623 (const_int 0)))
8624 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8625 (and:HI (match_dup 1) (match_dup 2)))]
8626 "ix86_match_ccmode (insn, CCNOmode)
8627 && ix86_binary_operator_ok (AND, HImode, operands)"
8628 "and{w}\t{%2, %0|%0, %2}"
8629 [(set_attr "type" "alu")
8630 (set_attr "mode" "HI")])
8631
8632 (define_expand "andqi3"
8633 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8634 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8635 (match_operand:QI 2 "general_operand" "")))
8636 (clobber (reg:CC 17))]
8637 "TARGET_QIMODE_MATH"
8638 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8639
8640 ;; %%% Potential partial reg stall on alternative 2. What to do?
8641 (define_insn "*andqi_1"
8642 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8643 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8644 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8645 (clobber (reg:CC 17))]
8646 "ix86_binary_operator_ok (AND, QImode, operands)"
8647 "@
8648 and{b}\t{%2, %0|%0, %2}
8649 and{b}\t{%2, %0|%0, %2}
8650 and{l}\t{%k2, %k0|%k0, %k2}"
8651 [(set_attr "type" "alu")
8652 (set_attr "mode" "QI,QI,SI")])
8653
8654 (define_insn "*andqi_1_slp"
8655 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8656 (and:QI (match_dup 0)
8657 (match_operand:QI 1 "general_operand" "qi,qmi")))
8658 (clobber (reg:CC 17))]
8659 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8660 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8661 "and{b}\t{%1, %0|%0, %1}"
8662 [(set_attr "type" "alu1")
8663 (set_attr "mode" "QI")])
8664
8665 (define_insn "*andqi_2"
8666 [(set (reg 17)
8667 (compare (and:QI
8668 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8669 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8670 (const_int 0)))
8671 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8672 (and:QI (match_dup 1) (match_dup 2)))]
8673 "ix86_match_ccmode (insn, CCNOmode)
8674 && ix86_binary_operator_ok (AND, QImode, operands)"
8675 {
8676 if (which_alternative == 2)
8677 {
8678 if (GET_CODE (operands[2]) == CONST_INT
8679 && (INTVAL (operands[2]) & 0xffffff00))
8680 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8681 return "and{l}\t{%2, %k0|%k0, %2}";
8682 }
8683 return "and{b}\t{%2, %0|%0, %2}";
8684 }
8685 [(set_attr "type" "alu")
8686 (set_attr "mode" "QI,QI,SI")])
8687
8688 (define_insn "*andqi_2_slp"
8689 [(set (reg 17)
8690 (compare (and:QI
8691 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8692 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8693 (const_int 0)))
8694 (set (strict_low_part (match_dup 0))
8695 (and:QI (match_dup 0) (match_dup 1)))]
8696 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8697 && ix86_match_ccmode (insn, CCNOmode)
8698 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8699 "and{b}\t{%1, %0|%0, %1}"
8700 [(set_attr "type" "alu1")
8701 (set_attr "mode" "QI")])
8702
8703 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8704 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8705 ;; for a QImode operand, which of course failed.
8706
8707 (define_insn "andqi_ext_0"
8708 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8709 (const_int 8)
8710 (const_int 8))
8711 (and:SI
8712 (zero_extract:SI
8713 (match_operand 1 "ext_register_operand" "0")
8714 (const_int 8)
8715 (const_int 8))
8716 (match_operand 2 "const_int_operand" "n")))
8717 (clobber (reg:CC 17))]
8718 ""
8719 "and{b}\t{%2, %h0|%h0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "length_immediate" "1")
8722 (set_attr "mode" "QI")])
8723
8724 ;; Generated by peephole translating test to and. This shows up
8725 ;; often in fp comparisons.
8726
8727 (define_insn "*andqi_ext_0_cc"
8728 [(set (reg 17)
8729 (compare
8730 (and:SI
8731 (zero_extract:SI
8732 (match_operand 1 "ext_register_operand" "0")
8733 (const_int 8)
8734 (const_int 8))
8735 (match_operand 2 "const_int_operand" "n"))
8736 (const_int 0)))
8737 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8738 (const_int 8)
8739 (const_int 8))
8740 (and:SI
8741 (zero_extract:SI
8742 (match_dup 1)
8743 (const_int 8)
8744 (const_int 8))
8745 (match_dup 2)))]
8746 "ix86_match_ccmode (insn, CCNOmode)"
8747 "and{b}\t{%2, %h0|%h0, %2}"
8748 [(set_attr "type" "alu")
8749 (set_attr "length_immediate" "1")
8750 (set_attr "mode" "QI")])
8751
8752 (define_insn "*andqi_ext_1"
8753 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8754 (const_int 8)
8755 (const_int 8))
8756 (and:SI
8757 (zero_extract:SI
8758 (match_operand 1 "ext_register_operand" "0")
8759 (const_int 8)
8760 (const_int 8))
8761 (zero_extend:SI
8762 (match_operand:QI 2 "general_operand" "Qm"))))
8763 (clobber (reg:CC 17))]
8764 "!TARGET_64BIT"
8765 "and{b}\t{%2, %h0|%h0, %2}"
8766 [(set_attr "type" "alu")
8767 (set_attr "length_immediate" "0")
8768 (set_attr "mode" "QI")])
8769
8770 (define_insn "*andqi_ext_1_rex64"
8771 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772 (const_int 8)
8773 (const_int 8))
8774 (and:SI
8775 (zero_extract:SI
8776 (match_operand 1 "ext_register_operand" "0")
8777 (const_int 8)
8778 (const_int 8))
8779 (zero_extend:SI
8780 (match_operand 2 "ext_register_operand" "Q"))))
8781 (clobber (reg:CC 17))]
8782 "TARGET_64BIT"
8783 "and{b}\t{%2, %h0|%h0, %2}"
8784 [(set_attr "type" "alu")
8785 (set_attr "length_immediate" "0")
8786 (set_attr "mode" "QI")])
8787
8788 (define_insn "*andqi_ext_2"
8789 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8790 (const_int 8)
8791 (const_int 8))
8792 (and:SI
8793 (zero_extract:SI
8794 (match_operand 1 "ext_register_operand" "%0")
8795 (const_int 8)
8796 (const_int 8))
8797 (zero_extract:SI
8798 (match_operand 2 "ext_register_operand" "Q")
8799 (const_int 8)
8800 (const_int 8))))
8801 (clobber (reg:CC 17))]
8802 ""
8803 "and{b}\t{%h2, %h0|%h0, %h2}"
8804 [(set_attr "type" "alu")
8805 (set_attr "length_immediate" "0")
8806 (set_attr "mode" "QI")])
8807
8808 ;; Convert wide AND instructions with immediate operand to shorter QImode
8809 ;; equivalents when possible.
8810 ;; Don't do the splitting with memory operands, since it introduces risk
8811 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8812 ;; for size, but that can (should?) be handled by generic code instead.
8813 (define_split
8814 [(set (match_operand 0 "register_operand" "")
8815 (and (match_operand 1 "register_operand" "")
8816 (match_operand 2 "const_int_operand" "")))
8817 (clobber (reg:CC 17))]
8818 "reload_completed
8819 && QI_REG_P (operands[0])
8820 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8821 && !(~INTVAL (operands[2]) & ~(255 << 8))
8822 && GET_MODE (operands[0]) != QImode"
8823 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8824 (and:SI (zero_extract:SI (match_dup 1)
8825 (const_int 8) (const_int 8))
8826 (match_dup 2)))
8827 (clobber (reg:CC 17))])]
8828 "operands[0] = gen_lowpart (SImode, operands[0]);
8829 operands[1] = gen_lowpart (SImode, operands[1]);
8830 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8831
8832 ;; Since AND can be encoded with sign extended immediate, this is only
8833 ;; profitable when 7th bit is not set.
8834 (define_split
8835 [(set (match_operand 0 "register_operand" "")
8836 (and (match_operand 1 "general_operand" "")
8837 (match_operand 2 "const_int_operand" "")))
8838 (clobber (reg:CC 17))]
8839 "reload_completed
8840 && ANY_QI_REG_P (operands[0])
8841 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8842 && !(~INTVAL (operands[2]) & ~255)
8843 && !(INTVAL (operands[2]) & 128)
8844 && GET_MODE (operands[0]) != QImode"
8845 [(parallel [(set (strict_low_part (match_dup 0))
8846 (and:QI (match_dup 1)
8847 (match_dup 2)))
8848 (clobber (reg:CC 17))])]
8849 "operands[0] = gen_lowpart (QImode, operands[0]);
8850 operands[1] = gen_lowpart (QImode, operands[1]);
8851 operands[2] = gen_lowpart (QImode, operands[2]);")
8852 \f
8853 ;; Logical inclusive OR instructions
8854
8855 ;; %%% This used to optimize known byte-wide and operations to memory.
8856 ;; If this is considered useful, it should be done with splitters.
8857
8858 (define_expand "iordi3"
8859 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8860 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8861 (match_operand:DI 2 "x86_64_general_operand" "")))
8862 (clobber (reg:CC 17))]
8863 "TARGET_64BIT"
8864 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8865
8866 (define_insn "*iordi_1_rex64"
8867 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8868 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8869 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8870 (clobber (reg:CC 17))]
8871 "TARGET_64BIT
8872 && ix86_binary_operator_ok (IOR, DImode, operands)"
8873 "or{q}\t{%2, %0|%0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "mode" "DI")])
8876
8877 (define_insn "*iordi_2_rex64"
8878 [(set (reg 17)
8879 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8880 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8881 (const_int 0)))
8882 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8883 (ior:DI (match_dup 1) (match_dup 2)))]
8884 "TARGET_64BIT
8885 && ix86_match_ccmode (insn, CCNOmode)
8886 && ix86_binary_operator_ok (IOR, DImode, operands)"
8887 "or{q}\t{%2, %0|%0, %2}"
8888 [(set_attr "type" "alu")
8889 (set_attr "mode" "DI")])
8890
8891 (define_insn "*iordi_3_rex64"
8892 [(set (reg 17)
8893 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8894 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8895 (const_int 0)))
8896 (clobber (match_scratch:DI 0 "=r"))]
8897 "TARGET_64BIT
8898 && ix86_match_ccmode (insn, CCNOmode)
8899 && ix86_binary_operator_ok (IOR, DImode, operands)"
8900 "or{q}\t{%2, %0|%0, %2}"
8901 [(set_attr "type" "alu")
8902 (set_attr "mode" "DI")])
8903
8904
8905 (define_expand "iorsi3"
8906 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8907 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8908 (match_operand:SI 2 "general_operand" "")))
8909 (clobber (reg:CC 17))]
8910 ""
8911 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8912
8913 (define_insn "*iorsi_1"
8914 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8915 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8916 (match_operand:SI 2 "general_operand" "ri,rmi")))
8917 (clobber (reg:CC 17))]
8918 "ix86_binary_operator_ok (IOR, SImode, operands)"
8919 "or{l}\t{%2, %0|%0, %2}"
8920 [(set_attr "type" "alu")
8921 (set_attr "mode" "SI")])
8922
8923 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8924 (define_insn "*iorsi_1_zext"
8925 [(set (match_operand:DI 0 "register_operand" "=rm")
8926 (zero_extend:DI
8927 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8928 (match_operand:SI 2 "general_operand" "rim"))))
8929 (clobber (reg:CC 17))]
8930 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8931 "or{l}\t{%2, %k0|%k0, %2}"
8932 [(set_attr "type" "alu")
8933 (set_attr "mode" "SI")])
8934
8935 (define_insn "*iorsi_1_zext_imm"
8936 [(set (match_operand:DI 0 "register_operand" "=rm")
8937 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8938 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8939 (clobber (reg:CC 17))]
8940 "TARGET_64BIT"
8941 "or{l}\t{%2, %k0|%k0, %2}"
8942 [(set_attr "type" "alu")
8943 (set_attr "mode" "SI")])
8944
8945 (define_insn "*iorsi_2"
8946 [(set (reg 17)
8947 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8948 (match_operand:SI 2 "general_operand" "rim,ri"))
8949 (const_int 0)))
8950 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8951 (ior:SI (match_dup 1) (match_dup 2)))]
8952 "ix86_match_ccmode (insn, CCNOmode)
8953 && ix86_binary_operator_ok (IOR, SImode, operands)"
8954 "or{l}\t{%2, %0|%0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "SI")])
8957
8958 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8959 ;; ??? Special case for immediate operand is missing - it is tricky.
8960 (define_insn "*iorsi_2_zext"
8961 [(set (reg 17)
8962 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8963 (match_operand:SI 2 "general_operand" "rim"))
8964 (const_int 0)))
8965 (set (match_operand:DI 0 "register_operand" "=r")
8966 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8967 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8968 && ix86_binary_operator_ok (IOR, SImode, operands)"
8969 "or{l}\t{%2, %k0|%k0, %2}"
8970 [(set_attr "type" "alu")
8971 (set_attr "mode" "SI")])
8972
8973 (define_insn "*iorsi_2_zext_imm"
8974 [(set (reg 17)
8975 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8976 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8977 (const_int 0)))
8978 (set (match_operand:DI 0 "register_operand" "=r")
8979 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8980 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8981 && ix86_binary_operator_ok (IOR, SImode, operands)"
8982 "or{l}\t{%2, %k0|%k0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "SI")])
8985
8986 (define_insn "*iorsi_3"
8987 [(set (reg 17)
8988 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989 (match_operand:SI 2 "general_operand" "rim"))
8990 (const_int 0)))
8991 (clobber (match_scratch:SI 0 "=r"))]
8992 "ix86_match_ccmode (insn, CCNOmode)
8993 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8994 "or{l}\t{%2, %0|%0, %2}"
8995 [(set_attr "type" "alu")
8996 (set_attr "mode" "SI")])
8997
8998 (define_expand "iorhi3"
8999 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9000 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9001 (match_operand:HI 2 "general_operand" "")))
9002 (clobber (reg:CC 17))]
9003 "TARGET_HIMODE_MATH"
9004 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9005
9006 (define_insn "*iorhi_1"
9007 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9008 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9009 (match_operand:HI 2 "general_operand" "rmi,ri")))
9010 (clobber (reg:CC 17))]
9011 "ix86_binary_operator_ok (IOR, HImode, operands)"
9012 "or{w}\t{%2, %0|%0, %2}"
9013 [(set_attr "type" "alu")
9014 (set_attr "mode" "HI")])
9015
9016 (define_insn "*iorhi_2"
9017 [(set (reg 17)
9018 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9019 (match_operand:HI 2 "general_operand" "rim,ri"))
9020 (const_int 0)))
9021 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9022 (ior:HI (match_dup 1) (match_dup 2)))]
9023 "ix86_match_ccmode (insn, CCNOmode)
9024 && ix86_binary_operator_ok (IOR, HImode, operands)"
9025 "or{w}\t{%2, %0|%0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "HI")])
9028
9029 (define_insn "*iorhi_3"
9030 [(set (reg 17)
9031 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9032 (match_operand:HI 2 "general_operand" "rim"))
9033 (const_int 0)))
9034 (clobber (match_scratch:HI 0 "=r"))]
9035 "ix86_match_ccmode (insn, CCNOmode)
9036 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9037 "or{w}\t{%2, %0|%0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "HI")])
9040
9041 (define_expand "iorqi3"
9042 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9043 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9044 (match_operand:QI 2 "general_operand" "")))
9045 (clobber (reg:CC 17))]
9046 "TARGET_QIMODE_MATH"
9047 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9048
9049 ;; %%% Potential partial reg stall on alternative 2. What to do?
9050 (define_insn "*iorqi_1"
9051 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9052 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9053 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9054 (clobber (reg:CC 17))]
9055 "ix86_binary_operator_ok (IOR, QImode, operands)"
9056 "@
9057 or{b}\t{%2, %0|%0, %2}
9058 or{b}\t{%2, %0|%0, %2}
9059 or{l}\t{%k2, %k0|%k0, %k2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "QI,QI,SI")])
9062
9063 (define_insn "*iorqi_1_slp"
9064 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9065 (ior:QI (match_dup 0)
9066 (match_operand:QI 1 "general_operand" "qmi,qi")))
9067 (clobber (reg:CC 17))]
9068 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9069 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9070 "or{b}\t{%1, %0|%0, %1}"
9071 [(set_attr "type" "alu1")
9072 (set_attr "mode" "QI")])
9073
9074 (define_insn "*iorqi_2"
9075 [(set (reg 17)
9076 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9077 (match_operand:QI 2 "general_operand" "qim,qi"))
9078 (const_int 0)))
9079 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9080 (ior:QI (match_dup 1) (match_dup 2)))]
9081 "ix86_match_ccmode (insn, CCNOmode)
9082 && ix86_binary_operator_ok (IOR, QImode, operands)"
9083 "or{b}\t{%2, %0|%0, %2}"
9084 [(set_attr "type" "alu")
9085 (set_attr "mode" "QI")])
9086
9087 (define_insn "*iorqi_2_slp"
9088 [(set (reg 17)
9089 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9090 (match_operand:QI 1 "general_operand" "qim,qi"))
9091 (const_int 0)))
9092 (set (strict_low_part (match_dup 0))
9093 (ior:QI (match_dup 0) (match_dup 1)))]
9094 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9095 && ix86_match_ccmode (insn, CCNOmode)
9096 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9097 "or{b}\t{%1, %0|%0, %1}"
9098 [(set_attr "type" "alu1")
9099 (set_attr "mode" "QI")])
9100
9101 (define_insn "*iorqi_3"
9102 [(set (reg 17)
9103 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9104 (match_operand:QI 2 "general_operand" "qim"))
9105 (const_int 0)))
9106 (clobber (match_scratch:QI 0 "=q"))]
9107 "ix86_match_ccmode (insn, CCNOmode)
9108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9109 "or{b}\t{%2, %0|%0, %2}"
9110 [(set_attr "type" "alu")
9111 (set_attr "mode" "QI")])
9112
9113 (define_insn "iorqi_ext_0"
9114 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115 (const_int 8)
9116 (const_int 8))
9117 (ior:SI
9118 (zero_extract:SI
9119 (match_operand 1 "ext_register_operand" "0")
9120 (const_int 8)
9121 (const_int 8))
9122 (match_operand 2 "const_int_operand" "n")))
9123 (clobber (reg:CC 17))]
9124 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9125 "or{b}\t{%2, %h0|%h0, %2}"
9126 [(set_attr "type" "alu")
9127 (set_attr "length_immediate" "1")
9128 (set_attr "mode" "QI")])
9129
9130 (define_insn "*iorqi_ext_1"
9131 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9132 (const_int 8)
9133 (const_int 8))
9134 (ior:SI
9135 (zero_extract:SI
9136 (match_operand 1 "ext_register_operand" "0")
9137 (const_int 8)
9138 (const_int 8))
9139 (zero_extend:SI
9140 (match_operand:QI 2 "general_operand" "Qm"))))
9141 (clobber (reg:CC 17))]
9142 "!TARGET_64BIT
9143 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9144 "or{b}\t{%2, %h0|%h0, %2}"
9145 [(set_attr "type" "alu")
9146 (set_attr "length_immediate" "0")
9147 (set_attr "mode" "QI")])
9148
9149 (define_insn "*iorqi_ext_1_rex64"
9150 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9151 (const_int 8)
9152 (const_int 8))
9153 (ior:SI
9154 (zero_extract:SI
9155 (match_operand 1 "ext_register_operand" "0")
9156 (const_int 8)
9157 (const_int 8))
9158 (zero_extend:SI
9159 (match_operand 2 "ext_register_operand" "Q"))))
9160 (clobber (reg:CC 17))]
9161 "TARGET_64BIT
9162 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9163 "or{b}\t{%2, %h0|%h0, %2}"
9164 [(set_attr "type" "alu")
9165 (set_attr "length_immediate" "0")
9166 (set_attr "mode" "QI")])
9167
9168 (define_insn "*iorqi_ext_2"
9169 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9170 (const_int 8)
9171 (const_int 8))
9172 (ior:SI
9173 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9174 (const_int 8)
9175 (const_int 8))
9176 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9177 (const_int 8)
9178 (const_int 8))))
9179 (clobber (reg:CC 17))]
9180 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9181 "ior{b}\t{%h2, %h0|%h0, %h2}"
9182 [(set_attr "type" "alu")
9183 (set_attr "length_immediate" "0")
9184 (set_attr "mode" "QI")])
9185
9186 (define_split
9187 [(set (match_operand 0 "register_operand" "")
9188 (ior (match_operand 1 "register_operand" "")
9189 (match_operand 2 "const_int_operand" "")))
9190 (clobber (reg:CC 17))]
9191 "reload_completed
9192 && QI_REG_P (operands[0])
9193 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9194 && !(INTVAL (operands[2]) & ~(255 << 8))
9195 && GET_MODE (operands[0]) != QImode"
9196 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9197 (ior:SI (zero_extract:SI (match_dup 1)
9198 (const_int 8) (const_int 8))
9199 (match_dup 2)))
9200 (clobber (reg:CC 17))])]
9201 "operands[0] = gen_lowpart (SImode, operands[0]);
9202 operands[1] = gen_lowpart (SImode, operands[1]);
9203 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9204
9205 ;; Since OR can be encoded with sign extended immediate, this is only
9206 ;; profitable when 7th bit is set.
9207 (define_split
9208 [(set (match_operand 0 "register_operand" "")
9209 (ior (match_operand 1 "general_operand" "")
9210 (match_operand 2 "const_int_operand" "")))
9211 (clobber (reg:CC 17))]
9212 "reload_completed
9213 && ANY_QI_REG_P (operands[0])
9214 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9215 && !(INTVAL (operands[2]) & ~255)
9216 && (INTVAL (operands[2]) & 128)
9217 && GET_MODE (operands[0]) != QImode"
9218 [(parallel [(set (strict_low_part (match_dup 0))
9219 (ior:QI (match_dup 1)
9220 (match_dup 2)))
9221 (clobber (reg:CC 17))])]
9222 "operands[0] = gen_lowpart (QImode, operands[0]);
9223 operands[1] = gen_lowpart (QImode, operands[1]);
9224 operands[2] = gen_lowpart (QImode, operands[2]);")
9225 \f
9226 ;; Logical XOR instructions
9227
9228 ;; %%% This used to optimize known byte-wide and operations to memory.
9229 ;; If this is considered useful, it should be done with splitters.
9230
9231 (define_expand "xordi3"
9232 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9233 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9234 (match_operand:DI 2 "x86_64_general_operand" "")))
9235 (clobber (reg:CC 17))]
9236 "TARGET_64BIT"
9237 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9238
9239 (define_insn "*xordi_1_rex64"
9240 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9241 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9242 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9243 (clobber (reg:CC 17))]
9244 "TARGET_64BIT
9245 && ix86_binary_operator_ok (XOR, DImode, operands)"
9246 "@
9247 xor{q}\t{%2, %0|%0, %2}
9248 xor{q}\t{%2, %0|%0, %2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "mode" "DI,DI")])
9251
9252 (define_insn "*xordi_2_rex64"
9253 [(set (reg 17)
9254 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9255 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9256 (const_int 0)))
9257 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9258 (xor:DI (match_dup 1) (match_dup 2)))]
9259 "TARGET_64BIT
9260 && ix86_match_ccmode (insn, CCNOmode)
9261 && ix86_binary_operator_ok (XOR, DImode, operands)"
9262 "@
9263 xor{q}\t{%2, %0|%0, %2}
9264 xor{q}\t{%2, %0|%0, %2}"
9265 [(set_attr "type" "alu")
9266 (set_attr "mode" "DI,DI")])
9267
9268 (define_insn "*xordi_3_rex64"
9269 [(set (reg 17)
9270 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9271 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9272 (const_int 0)))
9273 (clobber (match_scratch:DI 0 "=r"))]
9274 "TARGET_64BIT
9275 && ix86_match_ccmode (insn, CCNOmode)
9276 && ix86_binary_operator_ok (XOR, DImode, operands)"
9277 "xor{q}\t{%2, %0|%0, %2}"
9278 [(set_attr "type" "alu")
9279 (set_attr "mode" "DI")])
9280
9281 (define_expand "xorsi3"
9282 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9283 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9284 (match_operand:SI 2 "general_operand" "")))
9285 (clobber (reg:CC 17))]
9286 ""
9287 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9288
9289 (define_insn "*xorsi_1"
9290 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9291 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9292 (match_operand:SI 2 "general_operand" "ri,rm")))
9293 (clobber (reg:CC 17))]
9294 "ix86_binary_operator_ok (XOR, SImode, operands)"
9295 "xor{l}\t{%2, %0|%0, %2}"
9296 [(set_attr "type" "alu")
9297 (set_attr "mode" "SI")])
9298
9299 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9300 ;; Add speccase for immediates
9301 (define_insn "*xorsi_1_zext"
9302 [(set (match_operand:DI 0 "register_operand" "=r")
9303 (zero_extend:DI
9304 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9305 (match_operand:SI 2 "general_operand" "rim"))))
9306 (clobber (reg:CC 17))]
9307 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9308 "xor{l}\t{%2, %k0|%k0, %2}"
9309 [(set_attr "type" "alu")
9310 (set_attr "mode" "SI")])
9311
9312 (define_insn "*xorsi_1_zext_imm"
9313 [(set (match_operand:DI 0 "register_operand" "=r")
9314 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9315 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9316 (clobber (reg:CC 17))]
9317 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9318 "xor{l}\t{%2, %k0|%k0, %2}"
9319 [(set_attr "type" "alu")
9320 (set_attr "mode" "SI")])
9321
9322 (define_insn "*xorsi_2"
9323 [(set (reg 17)
9324 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9325 (match_operand:SI 2 "general_operand" "rim,ri"))
9326 (const_int 0)))
9327 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9328 (xor:SI (match_dup 1) (match_dup 2)))]
9329 "ix86_match_ccmode (insn, CCNOmode)
9330 && ix86_binary_operator_ok (XOR, SImode, operands)"
9331 "xor{l}\t{%2, %0|%0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "SI")])
9334
9335 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9336 ;; ??? Special case for immediate operand is missing - it is tricky.
9337 (define_insn "*xorsi_2_zext"
9338 [(set (reg 17)
9339 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9340 (match_operand:SI 2 "general_operand" "rim"))
9341 (const_int 0)))
9342 (set (match_operand:DI 0 "register_operand" "=r")
9343 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9344 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9345 && ix86_binary_operator_ok (XOR, SImode, operands)"
9346 "xor{l}\t{%2, %k0|%k0, %2}"
9347 [(set_attr "type" "alu")
9348 (set_attr "mode" "SI")])
9349
9350 (define_insn "*xorsi_2_zext_imm"
9351 [(set (reg 17)
9352 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9353 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9354 (const_int 0)))
9355 (set (match_operand:DI 0 "register_operand" "=r")
9356 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9357 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9358 && ix86_binary_operator_ok (XOR, SImode, operands)"
9359 "xor{l}\t{%2, %k0|%k0, %2}"
9360 [(set_attr "type" "alu")
9361 (set_attr "mode" "SI")])
9362
9363 (define_insn "*xorsi_3"
9364 [(set (reg 17)
9365 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9366 (match_operand:SI 2 "general_operand" "rim"))
9367 (const_int 0)))
9368 (clobber (match_scratch:SI 0 "=r"))]
9369 "ix86_match_ccmode (insn, CCNOmode)
9370 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9371 "xor{l}\t{%2, %0|%0, %2}"
9372 [(set_attr "type" "alu")
9373 (set_attr "mode" "SI")])
9374
9375 (define_expand "xorhi3"
9376 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9377 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9378 (match_operand:HI 2 "general_operand" "")))
9379 (clobber (reg:CC 17))]
9380 "TARGET_HIMODE_MATH"
9381 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9382
9383 (define_insn "*xorhi_1"
9384 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9385 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9386 (match_operand:HI 2 "general_operand" "rmi,ri")))
9387 (clobber (reg:CC 17))]
9388 "ix86_binary_operator_ok (XOR, HImode, operands)"
9389 "xor{w}\t{%2, %0|%0, %2}"
9390 [(set_attr "type" "alu")
9391 (set_attr "mode" "HI")])
9392
9393 (define_insn "*xorhi_2"
9394 [(set (reg 17)
9395 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9396 (match_operand:HI 2 "general_operand" "rim,ri"))
9397 (const_int 0)))
9398 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9399 (xor:HI (match_dup 1) (match_dup 2)))]
9400 "ix86_match_ccmode (insn, CCNOmode)
9401 && ix86_binary_operator_ok (XOR, HImode, operands)"
9402 "xor{w}\t{%2, %0|%0, %2}"
9403 [(set_attr "type" "alu")
9404 (set_attr "mode" "HI")])
9405
9406 (define_insn "*xorhi_3"
9407 [(set (reg 17)
9408 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9409 (match_operand:HI 2 "general_operand" "rim"))
9410 (const_int 0)))
9411 (clobber (match_scratch:HI 0 "=r"))]
9412 "ix86_match_ccmode (insn, CCNOmode)
9413 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9414 "xor{w}\t{%2, %0|%0, %2}"
9415 [(set_attr "type" "alu")
9416 (set_attr "mode" "HI")])
9417
9418 (define_expand "xorqi3"
9419 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9420 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9421 (match_operand:QI 2 "general_operand" "")))
9422 (clobber (reg:CC 17))]
9423 "TARGET_QIMODE_MATH"
9424 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9425
9426 ;; %%% Potential partial reg stall on alternative 2. What to do?
9427 (define_insn "*xorqi_1"
9428 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9429 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9430 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9431 (clobber (reg:CC 17))]
9432 "ix86_binary_operator_ok (XOR, QImode, operands)"
9433 "@
9434 xor{b}\t{%2, %0|%0, %2}
9435 xor{b}\t{%2, %0|%0, %2}
9436 xor{l}\t{%k2, %k0|%k0, %k2}"
9437 [(set_attr "type" "alu")
9438 (set_attr "mode" "QI,QI,SI")])
9439
9440 (define_insn "*xorqi_1_slp"
9441 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9442 (xor:QI (match_dup 0)
9443 (match_operand:QI 1 "general_operand" "qi,qmi")))
9444 (clobber (reg:CC 17))]
9445 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9446 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9447 "xor{b}\t{%1, %0|%0, %1}"
9448 [(set_attr "type" "alu1")
9449 (set_attr "mode" "QI")])
9450
9451 (define_insn "xorqi_ext_0"
9452 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9453 (const_int 8)
9454 (const_int 8))
9455 (xor:SI
9456 (zero_extract:SI
9457 (match_operand 1 "ext_register_operand" "0")
9458 (const_int 8)
9459 (const_int 8))
9460 (match_operand 2 "const_int_operand" "n")))
9461 (clobber (reg:CC 17))]
9462 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9463 "xor{b}\t{%2, %h0|%h0, %2}"
9464 [(set_attr "type" "alu")
9465 (set_attr "length_immediate" "1")
9466 (set_attr "mode" "QI")])
9467
9468 (define_insn "*xorqi_ext_1"
9469 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9470 (const_int 8)
9471 (const_int 8))
9472 (xor:SI
9473 (zero_extract:SI
9474 (match_operand 1 "ext_register_operand" "0")
9475 (const_int 8)
9476 (const_int 8))
9477 (zero_extend:SI
9478 (match_operand:QI 2 "general_operand" "Qm"))))
9479 (clobber (reg:CC 17))]
9480 "!TARGET_64BIT
9481 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9482 "xor{b}\t{%2, %h0|%h0, %2}"
9483 [(set_attr "type" "alu")
9484 (set_attr "length_immediate" "0")
9485 (set_attr "mode" "QI")])
9486
9487 (define_insn "*xorqi_ext_1_rex64"
9488 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9489 (const_int 8)
9490 (const_int 8))
9491 (xor:SI
9492 (zero_extract:SI
9493 (match_operand 1 "ext_register_operand" "0")
9494 (const_int 8)
9495 (const_int 8))
9496 (zero_extend:SI
9497 (match_operand 2 "ext_register_operand" "Q"))))
9498 (clobber (reg:CC 17))]
9499 "TARGET_64BIT
9500 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9501 "xor{b}\t{%2, %h0|%h0, %2}"
9502 [(set_attr "type" "alu")
9503 (set_attr "length_immediate" "0")
9504 (set_attr "mode" "QI")])
9505
9506 (define_insn "*xorqi_ext_2"
9507 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9508 (const_int 8)
9509 (const_int 8))
9510 (xor:SI
9511 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9512 (const_int 8)
9513 (const_int 8))
9514 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9515 (const_int 8)
9516 (const_int 8))))
9517 (clobber (reg:CC 17))]
9518 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9519 "xor{b}\t{%h2, %h0|%h0, %h2}"
9520 [(set_attr "type" "alu")
9521 (set_attr "length_immediate" "0")
9522 (set_attr "mode" "QI")])
9523
9524 (define_insn "*xorqi_cc_1"
9525 [(set (reg 17)
9526 (compare
9527 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9528 (match_operand:QI 2 "general_operand" "qim,qi"))
9529 (const_int 0)))
9530 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9531 (xor:QI (match_dup 1) (match_dup 2)))]
9532 "ix86_match_ccmode (insn, CCNOmode)
9533 && ix86_binary_operator_ok (XOR, QImode, operands)"
9534 "xor{b}\t{%2, %0|%0, %2}"
9535 [(set_attr "type" "alu")
9536 (set_attr "mode" "QI")])
9537
9538 (define_insn "*xorqi_2_slp"
9539 [(set (reg 17)
9540 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9541 (match_operand:QI 1 "general_operand" "qim,qi"))
9542 (const_int 0)))
9543 (set (strict_low_part (match_dup 0))
9544 (xor:QI (match_dup 0) (match_dup 1)))]
9545 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9546 && ix86_match_ccmode (insn, CCNOmode)
9547 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9548 "xor{b}\t{%1, %0|%0, %1}"
9549 [(set_attr "type" "alu1")
9550 (set_attr "mode" "QI")])
9551
9552 (define_insn "*xorqi_cc_2"
9553 [(set (reg 17)
9554 (compare
9555 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9556 (match_operand:QI 2 "general_operand" "qim"))
9557 (const_int 0)))
9558 (clobber (match_scratch:QI 0 "=q"))]
9559 "ix86_match_ccmode (insn, CCNOmode)
9560 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9561 "xor{b}\t{%2, %0|%0, %2}"
9562 [(set_attr "type" "alu")
9563 (set_attr "mode" "QI")])
9564
9565 (define_insn "*xorqi_cc_ext_1"
9566 [(set (reg 17)
9567 (compare
9568 (xor:SI
9569 (zero_extract:SI
9570 (match_operand 1 "ext_register_operand" "0")
9571 (const_int 8)
9572 (const_int 8))
9573 (match_operand:QI 2 "general_operand" "qmn"))
9574 (const_int 0)))
9575 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9576 (const_int 8)
9577 (const_int 8))
9578 (xor:SI
9579 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9580 (match_dup 2)))]
9581 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9582 "xor{b}\t{%2, %h0|%h0, %2}"
9583 [(set_attr "type" "alu")
9584 (set_attr "mode" "QI")])
9585
9586 (define_insn "*xorqi_cc_ext_1_rex64"
9587 [(set (reg 17)
9588 (compare
9589 (xor:SI
9590 (zero_extract:SI
9591 (match_operand 1 "ext_register_operand" "0")
9592 (const_int 8)
9593 (const_int 8))
9594 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9595 (const_int 0)))
9596 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9597 (const_int 8)
9598 (const_int 8))
9599 (xor:SI
9600 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9601 (match_dup 2)))]
9602 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9603 "xor{b}\t{%2, %h0|%h0, %2}"
9604 [(set_attr "type" "alu")
9605 (set_attr "mode" "QI")])
9606
9607 (define_expand "xorqi_cc_ext_1"
9608 [(parallel [
9609 (set (reg:CCNO 17)
9610 (compare:CCNO
9611 (xor:SI
9612 (zero_extract:SI
9613 (match_operand 1 "ext_register_operand" "")
9614 (const_int 8)
9615 (const_int 8))
9616 (match_operand:QI 2 "general_operand" ""))
9617 (const_int 0)))
9618 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9619 (const_int 8)
9620 (const_int 8))
9621 (xor:SI
9622 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9623 (match_dup 2)))])]
9624 ""
9625 "")
9626
9627 (define_split
9628 [(set (match_operand 0 "register_operand" "")
9629 (xor (match_operand 1 "register_operand" "")
9630 (match_operand 2 "const_int_operand" "")))
9631 (clobber (reg:CC 17))]
9632 "reload_completed
9633 && QI_REG_P (operands[0])
9634 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9635 && !(INTVAL (operands[2]) & ~(255 << 8))
9636 && GET_MODE (operands[0]) != QImode"
9637 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9638 (xor:SI (zero_extract:SI (match_dup 1)
9639 (const_int 8) (const_int 8))
9640 (match_dup 2)))
9641 (clobber (reg:CC 17))])]
9642 "operands[0] = gen_lowpart (SImode, operands[0]);
9643 operands[1] = gen_lowpart (SImode, operands[1]);
9644 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9645
9646 ;; Since XOR can be encoded with sign extended immediate, this is only
9647 ;; profitable when 7th bit is set.
9648 (define_split
9649 [(set (match_operand 0 "register_operand" "")
9650 (xor (match_operand 1 "general_operand" "")
9651 (match_operand 2 "const_int_operand" "")))
9652 (clobber (reg:CC 17))]
9653 "reload_completed
9654 && ANY_QI_REG_P (operands[0])
9655 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9656 && !(INTVAL (operands[2]) & ~255)
9657 && (INTVAL (operands[2]) & 128)
9658 && GET_MODE (operands[0]) != QImode"
9659 [(parallel [(set (strict_low_part (match_dup 0))
9660 (xor:QI (match_dup 1)
9661 (match_dup 2)))
9662 (clobber (reg:CC 17))])]
9663 "operands[0] = gen_lowpart (QImode, operands[0]);
9664 operands[1] = gen_lowpart (QImode, operands[1]);
9665 operands[2] = gen_lowpart (QImode, operands[2]);")
9666 \f
9667 ;; Negation instructions
9668
9669 (define_expand "negdi2"
9670 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9671 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9672 (clobber (reg:CC 17))])]
9673 ""
9674 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9675
9676 (define_insn "*negdi2_1"
9677 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9678 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9679 (clobber (reg:CC 17))]
9680 "!TARGET_64BIT
9681 && ix86_unary_operator_ok (NEG, DImode, operands)"
9682 "#")
9683
9684 (define_split
9685 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9686 (neg:DI (match_operand:DI 1 "general_operand" "")))
9687 (clobber (reg:CC 17))]
9688 "!TARGET_64BIT && reload_completed"
9689 [(parallel
9690 [(set (reg:CCZ 17)
9691 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9692 (set (match_dup 0) (neg:SI (match_dup 2)))])
9693 (parallel
9694 [(set (match_dup 1)
9695 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9696 (match_dup 3))
9697 (const_int 0)))
9698 (clobber (reg:CC 17))])
9699 (parallel
9700 [(set (match_dup 1)
9701 (neg:SI (match_dup 1)))
9702 (clobber (reg:CC 17))])]
9703 "split_di (operands+1, 1, operands+2, operands+3);
9704 split_di (operands+0, 1, operands+0, operands+1);")
9705
9706 (define_insn "*negdi2_1_rex64"
9707 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9708 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9709 (clobber (reg:CC 17))]
9710 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9711 "neg{q}\t%0"
9712 [(set_attr "type" "negnot")
9713 (set_attr "mode" "DI")])
9714
9715 ;; The problem with neg is that it does not perform (compare x 0),
9716 ;; it really performs (compare 0 x), which leaves us with the zero
9717 ;; flag being the only useful item.
9718
9719 (define_insn "*negdi2_cmpz_rex64"
9720 [(set (reg:CCZ 17)
9721 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9722 (const_int 0)))
9723 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9724 (neg:DI (match_dup 1)))]
9725 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9726 "neg{q}\t%0"
9727 [(set_attr "type" "negnot")
9728 (set_attr "mode" "DI")])
9729
9730
9731 (define_expand "negsi2"
9732 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9733 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9734 (clobber (reg:CC 17))])]
9735 ""
9736 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9737
9738 (define_insn "*negsi2_1"
9739 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9740 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9741 (clobber (reg:CC 17))]
9742 "ix86_unary_operator_ok (NEG, SImode, operands)"
9743 "neg{l}\t%0"
9744 [(set_attr "type" "negnot")
9745 (set_attr "mode" "SI")])
9746
9747 ;; Combine is quite creative about this pattern.
9748 (define_insn "*negsi2_1_zext"
9749 [(set (match_operand:DI 0 "register_operand" "=r")
9750 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9751 (const_int 32)))
9752 (const_int 32)))
9753 (clobber (reg:CC 17))]
9754 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9755 "neg{l}\t%k0"
9756 [(set_attr "type" "negnot")
9757 (set_attr "mode" "SI")])
9758
9759 ;; The problem with neg is that it does not perform (compare x 0),
9760 ;; it really performs (compare 0 x), which leaves us with the zero
9761 ;; flag being the only useful item.
9762
9763 (define_insn "*negsi2_cmpz"
9764 [(set (reg:CCZ 17)
9765 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9766 (const_int 0)))
9767 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9768 (neg:SI (match_dup 1)))]
9769 "ix86_unary_operator_ok (NEG, SImode, operands)"
9770 "neg{l}\t%0"
9771 [(set_attr "type" "negnot")
9772 (set_attr "mode" "SI")])
9773
9774 (define_insn "*negsi2_cmpz_zext"
9775 [(set (reg:CCZ 17)
9776 (compare:CCZ (lshiftrt:DI
9777 (neg:DI (ashift:DI
9778 (match_operand:DI 1 "register_operand" "0")
9779 (const_int 32)))
9780 (const_int 32))
9781 (const_int 0)))
9782 (set (match_operand:DI 0 "register_operand" "=r")
9783 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9784 (const_int 32)))
9785 (const_int 32)))]
9786 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9787 "neg{l}\t%k0"
9788 [(set_attr "type" "negnot")
9789 (set_attr "mode" "SI")])
9790
9791 (define_expand "neghi2"
9792 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9793 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9794 (clobber (reg:CC 17))])]
9795 "TARGET_HIMODE_MATH"
9796 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9797
9798 (define_insn "*neghi2_1"
9799 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9800 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9801 (clobber (reg:CC 17))]
9802 "ix86_unary_operator_ok (NEG, HImode, operands)"
9803 "neg{w}\t%0"
9804 [(set_attr "type" "negnot")
9805 (set_attr "mode" "HI")])
9806
9807 (define_insn "*neghi2_cmpz"
9808 [(set (reg:CCZ 17)
9809 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9810 (const_int 0)))
9811 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9812 (neg:HI (match_dup 1)))]
9813 "ix86_unary_operator_ok (NEG, HImode, operands)"
9814 "neg{w}\t%0"
9815 [(set_attr "type" "negnot")
9816 (set_attr "mode" "HI")])
9817
9818 (define_expand "negqi2"
9819 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9820 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9821 (clobber (reg:CC 17))])]
9822 "TARGET_QIMODE_MATH"
9823 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9824
9825 (define_insn "*negqi2_1"
9826 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9827 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9828 (clobber (reg:CC 17))]
9829 "ix86_unary_operator_ok (NEG, QImode, operands)"
9830 "neg{b}\t%0"
9831 [(set_attr "type" "negnot")
9832 (set_attr "mode" "QI")])
9833
9834 (define_insn "*negqi2_cmpz"
9835 [(set (reg:CCZ 17)
9836 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9837 (const_int 0)))
9838 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9839 (neg:QI (match_dup 1)))]
9840 "ix86_unary_operator_ok (NEG, QImode, operands)"
9841 "neg{b}\t%0"
9842 [(set_attr "type" "negnot")
9843 (set_attr "mode" "QI")])
9844
9845 ;; Changing of sign for FP values is doable using integer unit too.
9846
9847 (define_expand "negsf2"
9848 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9849 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9850 (clobber (reg:CC 17))])]
9851 "TARGET_80387"
9852 "if (TARGET_SSE)
9853 {
9854 /* In case operand is in memory, we will not use SSE. */
9855 if (memory_operand (operands[0], VOIDmode)
9856 && rtx_equal_p (operands[0], operands[1]))
9857 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9858 else
9859 {
9860 /* Using SSE is tricky, since we need bitwise negation of -0
9861 in register. */
9862 rtx reg = gen_reg_rtx (SFmode);
9863 rtx dest = operands[0];
9864 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9865
9866 operands[1] = force_reg (SFmode, operands[1]);
9867 operands[0] = force_reg (SFmode, operands[0]);
9868 reg = force_reg (V4SFmode,
9869 gen_rtx_CONST_VECTOR (V4SFmode,
9870 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9871 CONST0_RTX (SFmode),
9872 CONST0_RTX (SFmode))));
9873 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9874 if (dest != operands[0])
9875 emit_move_insn (dest, operands[0]);
9876 }
9877 DONE;
9878 }
9879 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9880
9881 (define_insn "negsf2_memory"
9882 [(set (match_operand:SF 0 "memory_operand" "=m")
9883 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9884 (clobber (reg:CC 17))]
9885 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9886 "#")
9887
9888 (define_insn "negsf2_ifs"
9889 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9890 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9891 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9892 (clobber (reg:CC 17))]
9893 "TARGET_SSE
9894 && (reload_in_progress || reload_completed
9895 || (register_operand (operands[0], VOIDmode)
9896 && register_operand (operands[1], VOIDmode)))"
9897 "#")
9898
9899 (define_split
9900 [(set (match_operand:SF 0 "memory_operand" "")
9901 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9902 (use (match_operand:SF 2 "" ""))
9903 (clobber (reg:CC 17))]
9904 ""
9905 [(parallel [(set (match_dup 0)
9906 (neg:SF (match_dup 1)))
9907 (clobber (reg:CC 17))])])
9908
9909 (define_split
9910 [(set (match_operand:SF 0 "register_operand" "")
9911 (neg:SF (match_operand:SF 1 "register_operand" "")))
9912 (use (match_operand:V4SF 2 "" ""))
9913 (clobber (reg:CC 17))]
9914 "reload_completed && !SSE_REG_P (operands[0])"
9915 [(parallel [(set (match_dup 0)
9916 (neg:SF (match_dup 1)))
9917 (clobber (reg:CC 17))])])
9918
9919 (define_split
9920 [(set (match_operand:SF 0 "register_operand" "")
9921 (neg:SF (match_operand:SF 1 "register_operand" "")))
9922 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9923 (clobber (reg:CC 17))]
9924 "reload_completed && SSE_REG_P (operands[0])"
9925 [(set (subreg:TI (match_dup 0) 0)
9926 (xor:TI (match_dup 1)
9927 (match_dup 2)))]
9928 {
9929 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9930 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9931 if (operands_match_p (operands[0], operands[2]))
9932 {
9933 rtx tmp;
9934 tmp = operands[1];
9935 operands[1] = operands[2];
9936 operands[2] = tmp;
9937 }
9938 })
9939
9940
9941 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9942 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9943 ;; to itself.
9944 (define_insn "*negsf2_if"
9945 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9946 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9947 (clobber (reg:CC 17))]
9948 "TARGET_80387 && !TARGET_SSE
9949 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9950 "#")
9951
9952 (define_split
9953 [(set (match_operand:SF 0 "fp_register_operand" "")
9954 (neg:SF (match_operand:SF 1 "register_operand" "")))
9955 (clobber (reg:CC 17))]
9956 "TARGET_80387 && reload_completed"
9957 [(set (match_dup 0)
9958 (neg:SF (match_dup 1)))]
9959 "")
9960
9961 (define_split
9962 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9963 (neg:SF (match_operand:SF 1 "register_operand" "")))
9964 (clobber (reg:CC 17))]
9965 "TARGET_80387 && reload_completed"
9966 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9967 (clobber (reg:CC 17))])]
9968 "operands[1] = gen_int_mode (0x80000000, SImode);
9969 operands[0] = gen_lowpart (SImode, operands[0]);")
9970
9971 (define_split
9972 [(set (match_operand 0 "memory_operand" "")
9973 (neg (match_operand 1 "memory_operand" "")))
9974 (clobber (reg:CC 17))]
9975 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9976 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9977 (clobber (reg:CC 17))])]
9978 {
9979 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9980
9981 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9982 if (size >= 12)
9983 size = 10;
9984 operands[0] = adjust_address (operands[0], QImode, size - 1);
9985 operands[1] = gen_int_mode (0x80, QImode);
9986 })
9987
9988 (define_expand "negdf2"
9989 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9990 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9991 (clobber (reg:CC 17))])]
9992 "TARGET_80387"
9993 "if (TARGET_SSE2)
9994 {
9995 /* In case operand is in memory, we will not use SSE. */
9996 if (memory_operand (operands[0], VOIDmode)
9997 && rtx_equal_p (operands[0], operands[1]))
9998 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9999 else
10000 {
10001 /* Using SSE is tricky, since we need bitwise negation of -0
10002 in register. */
10003 rtx reg;
10004 #if HOST_BITS_PER_WIDE_INT >= 64
10005 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
10006 #else
10007 rtx imm = immed_double_const (0, 0x80000000, DImode);
10008 #endif
10009 rtx dest = operands[0];
10010
10011 operands[1] = force_reg (DFmode, operands[1]);
10012 operands[0] = force_reg (DFmode, operands[0]);
10013 imm = gen_lowpart (DFmode, imm);
10014 reg = force_reg (V2DFmode,
10015 gen_rtx_CONST_VECTOR (V2DFmode,
10016 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10017 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
10018 if (dest != operands[0])
10019 emit_move_insn (dest, operands[0]);
10020 }
10021 DONE;
10022 }
10023 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
10024
10025 (define_insn "negdf2_memory"
10026 [(set (match_operand:DF 0 "memory_operand" "=m")
10027 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10028 (clobber (reg:CC 17))]
10029 "ix86_unary_operator_ok (NEG, DFmode, operands)"
10030 "#")
10031
10032 (define_insn "negdf2_ifs"
10033 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10034 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10035 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10036 (clobber (reg:CC 17))]
10037 "!TARGET_64BIT && TARGET_SSE2
10038 && (reload_in_progress || reload_completed
10039 || (register_operand (operands[0], VOIDmode)
10040 && register_operand (operands[1], VOIDmode)))"
10041 "#")
10042
10043 (define_insn "*negdf2_ifs_rex64"
10044 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10045 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10046 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10047 (clobber (reg:CC 17))]
10048 "TARGET_64BIT && TARGET_SSE2
10049 && (reload_in_progress || reload_completed
10050 || (register_operand (operands[0], VOIDmode)
10051 && register_operand (operands[1], VOIDmode)))"
10052 "#")
10053
10054 (define_split
10055 [(set (match_operand:DF 0 "memory_operand" "")
10056 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10057 (use (match_operand:V2DF 2 "" ""))
10058 (clobber (reg:CC 17))]
10059 ""
10060 [(parallel [(set (match_dup 0)
10061 (neg:DF (match_dup 1)))
10062 (clobber (reg:CC 17))])])
10063
10064 (define_split
10065 [(set (match_operand:DF 0 "register_operand" "")
10066 (neg:DF (match_operand:DF 1 "register_operand" "")))
10067 (use (match_operand:V2DF 2 "" ""))
10068 (clobber (reg:CC 17))]
10069 "reload_completed && !SSE_REG_P (operands[0])
10070 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10071 [(parallel [(set (match_dup 0)
10072 (neg:DF (match_dup 1)))
10073 (clobber (reg:CC 17))])])
10074
10075 (define_split
10076 [(set (match_operand:DF 0 "register_operand" "")
10077 (neg:DF (match_operand:DF 1 "register_operand" "")))
10078 (use (match_operand:V2DF 2 "" ""))
10079 (clobber (reg:CC 17))]
10080 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10081 [(parallel [(set (match_dup 0)
10082 (xor:DI (match_dup 1) (match_dup 2)))
10083 (clobber (reg:CC 17))])]
10084 "operands[0] = gen_lowpart (DImode, operands[0]);
10085 operands[1] = gen_lowpart (DImode, operands[1]);
10086 operands[2] = gen_lowpart (DImode, operands[2]);")
10087
10088 (define_split
10089 [(set (match_operand:DF 0 "register_operand" "")
10090 (neg:DF (match_operand:DF 1 "register_operand" "")))
10091 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10092 (clobber (reg:CC 17))]
10093 "reload_completed && SSE_REG_P (operands[0])"
10094 [(set (subreg:TI (match_dup 0) 0)
10095 (xor:TI (match_dup 1)
10096 (match_dup 2)))]
10097 {
10098 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10099 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10100 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10101 /* Avoid possible reformatting on the operands. */
10102 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10103 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10104 if (operands_match_p (operands[0], operands[2]))
10105 {
10106 rtx tmp;
10107 tmp = operands[1];
10108 operands[1] = operands[2];
10109 operands[2] = tmp;
10110 }
10111 })
10112
10113 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10114 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10115 ;; to itself.
10116 (define_insn "*negdf2_if"
10117 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10118 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10119 (clobber (reg:CC 17))]
10120 "!TARGET_64BIT && TARGET_80387
10121 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10122 "#")
10123
10124 ;; FIXME: We should to allow integer registers here. Problem is that
10125 ;; we need another scratch register to get constant from.
10126 ;; Forcing constant to mem if no register available in peep2 should be
10127 ;; safe even for PIC mode, because of RIP relative addressing.
10128 (define_insn "*negdf2_if_rex64"
10129 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10130 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10131 (clobber (reg:CC 17))]
10132 "TARGET_64BIT && TARGET_80387
10133 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10134 "#")
10135
10136 (define_split
10137 [(set (match_operand:DF 0 "fp_register_operand" "")
10138 (neg:DF (match_operand:DF 1 "register_operand" "")))
10139 (clobber (reg:CC 17))]
10140 "TARGET_80387 && reload_completed"
10141 [(set (match_dup 0)
10142 (neg:DF (match_dup 1)))]
10143 "")
10144
10145 (define_split
10146 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10147 (neg:DF (match_operand:DF 1 "register_operand" "")))
10148 (clobber (reg:CC 17))]
10149 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10150 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10151 (clobber (reg:CC 17))])]
10152 "operands[4] = gen_int_mode (0x80000000, SImode);
10153 split_di (operands+0, 1, operands+2, operands+3);")
10154
10155 (define_expand "negxf2"
10156 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10157 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10158 (clobber (reg:CC 17))])]
10159 "!TARGET_64BIT && TARGET_80387"
10160 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10161
10162 (define_expand "negtf2"
10163 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10164 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10165 (clobber (reg:CC 17))])]
10166 "TARGET_80387"
10167 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10168
10169 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10170 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10171 ;; to itself.
10172 (define_insn "*negxf2_if"
10173 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10174 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10175 (clobber (reg:CC 17))]
10176 "!TARGET_64BIT && TARGET_80387
10177 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10178 "#")
10179
10180 (define_split
10181 [(set (match_operand:XF 0 "fp_register_operand" "")
10182 (neg:XF (match_operand:XF 1 "register_operand" "")))
10183 (clobber (reg:CC 17))]
10184 "TARGET_80387 && reload_completed"
10185 [(set (match_dup 0)
10186 (neg:XF (match_dup 1)))]
10187 "")
10188
10189 (define_split
10190 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10191 (neg:XF (match_operand:XF 1 "register_operand" "")))
10192 (clobber (reg:CC 17))]
10193 "TARGET_80387 && reload_completed"
10194 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10195 (clobber (reg:CC 17))])]
10196 "operands[1] = GEN_INT (0x8000);
10197 operands[0] = gen_rtx_REG (SImode,
10198 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10199
10200 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10201 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10202 ;; to itself.
10203 (define_insn "*negtf2_if"
10204 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10205 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10206 (clobber (reg:CC 17))]
10207 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10208 "#")
10209
10210 (define_split
10211 [(set (match_operand:TF 0 "fp_register_operand" "")
10212 (neg:TF (match_operand:TF 1 "register_operand" "")))
10213 (clobber (reg:CC 17))]
10214 "TARGET_80387 && reload_completed"
10215 [(set (match_dup 0)
10216 (neg:TF (match_dup 1)))]
10217 "")
10218
10219 (define_split
10220 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10221 (neg:TF (match_operand:TF 1 "register_operand" "")))
10222 (clobber (reg:CC 17))]
10223 "TARGET_80387 && reload_completed"
10224 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10225 (clobber (reg:CC 17))])]
10226 "operands[1] = GEN_INT (0x8000);
10227 operands[0] = gen_rtx_REG (SImode,
10228 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10229
10230 ;; Conditionalize these after reload. If they matches before reload, we
10231 ;; lose the clobber and ability to use integer instructions.
10232
10233 (define_insn "*negsf2_1"
10234 [(set (match_operand:SF 0 "register_operand" "=f")
10235 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10236 "TARGET_80387 && reload_completed"
10237 "fchs"
10238 [(set_attr "type" "fsgn")
10239 (set_attr "mode" "SF")
10240 (set_attr "ppro_uops" "few")])
10241
10242 (define_insn "*negdf2_1"
10243 [(set (match_operand:DF 0 "register_operand" "=f")
10244 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10245 "TARGET_80387 && reload_completed"
10246 "fchs"
10247 [(set_attr "type" "fsgn")
10248 (set_attr "mode" "DF")
10249 (set_attr "ppro_uops" "few")])
10250
10251 (define_insn "*negextendsfdf2"
10252 [(set (match_operand:DF 0 "register_operand" "=f")
10253 (neg:DF (float_extend:DF
10254 (match_operand:SF 1 "register_operand" "0"))))]
10255 "TARGET_80387"
10256 "fchs"
10257 [(set_attr "type" "fsgn")
10258 (set_attr "mode" "DF")
10259 (set_attr "ppro_uops" "few")])
10260
10261 (define_insn "*negxf2_1"
10262 [(set (match_operand:XF 0 "register_operand" "=f")
10263 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10264 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10265 "fchs"
10266 [(set_attr "type" "fsgn")
10267 (set_attr "mode" "XF")
10268 (set_attr "ppro_uops" "few")])
10269
10270 (define_insn "*negextenddfxf2"
10271 [(set (match_operand:XF 0 "register_operand" "=f")
10272 (neg:XF (float_extend:XF
10273 (match_operand:DF 1 "register_operand" "0"))))]
10274 "!TARGET_64BIT && TARGET_80387"
10275 "fchs"
10276 [(set_attr "type" "fsgn")
10277 (set_attr "mode" "XF")
10278 (set_attr "ppro_uops" "few")])
10279
10280 (define_insn "*negextendsfxf2"
10281 [(set (match_operand:XF 0 "register_operand" "=f")
10282 (neg:XF (float_extend:XF
10283 (match_operand:SF 1 "register_operand" "0"))))]
10284 "!TARGET_64BIT && TARGET_80387"
10285 "fchs"
10286 [(set_attr "type" "fsgn")
10287 (set_attr "mode" "XF")
10288 (set_attr "ppro_uops" "few")])
10289
10290 (define_insn "*negtf2_1"
10291 [(set (match_operand:TF 0 "register_operand" "=f")
10292 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10293 "TARGET_80387 && reload_completed"
10294 "fchs"
10295 [(set_attr "type" "fsgn")
10296 (set_attr "mode" "XF")
10297 (set_attr "ppro_uops" "few")])
10298
10299 (define_insn "*negextenddftf2"
10300 [(set (match_operand:TF 0 "register_operand" "=f")
10301 (neg:TF (float_extend:TF
10302 (match_operand:DF 1 "register_operand" "0"))))]
10303 "TARGET_80387"
10304 "fchs"
10305 [(set_attr "type" "fsgn")
10306 (set_attr "mode" "XF")
10307 (set_attr "ppro_uops" "few")])
10308
10309 (define_insn "*negextendsftf2"
10310 [(set (match_operand:TF 0 "register_operand" "=f")
10311 (neg:TF (float_extend:TF
10312 (match_operand:SF 1 "register_operand" "0"))))]
10313 "TARGET_80387"
10314 "fchs"
10315 [(set_attr "type" "fsgn")
10316 (set_attr "mode" "XF")
10317 (set_attr "ppro_uops" "few")])
10318 \f
10319 ;; Absolute value instructions
10320
10321 (define_expand "abssf2"
10322 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10323 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10324 (clobber (reg:CC 17))])]
10325 "TARGET_80387"
10326 "if (TARGET_SSE)
10327 {
10328 /* In case operand is in memory, we will not use SSE. */
10329 if (memory_operand (operands[0], VOIDmode)
10330 && rtx_equal_p (operands[0], operands[1]))
10331 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10332 else
10333 {
10334 /* Using SSE is tricky, since we need bitwise negation of -0
10335 in register. */
10336 rtx reg = gen_reg_rtx (V4SFmode);
10337 rtx dest = operands[0];
10338 rtx imm;
10339
10340 operands[1] = force_reg (SFmode, operands[1]);
10341 operands[0] = force_reg (SFmode, operands[0]);
10342 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10343 reg = force_reg (V4SFmode,
10344 gen_rtx_CONST_VECTOR (V4SFmode,
10345 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10346 CONST0_RTX (SFmode),
10347 CONST0_RTX (SFmode))));
10348 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10349 if (dest != operands[0])
10350 emit_move_insn (dest, operands[0]);
10351 }
10352 DONE;
10353 }
10354 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10355
10356 (define_insn "abssf2_memory"
10357 [(set (match_operand:SF 0 "memory_operand" "=m")
10358 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10359 (clobber (reg:CC 17))]
10360 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10361 "#")
10362
10363 (define_insn "abssf2_ifs"
10364 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10365 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10366 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10367 (clobber (reg:CC 17))]
10368 "TARGET_SSE
10369 && (reload_in_progress || reload_completed
10370 || (register_operand (operands[0], VOIDmode)
10371 && register_operand (operands[1], VOIDmode)))"
10372 "#")
10373
10374 (define_split
10375 [(set (match_operand:SF 0 "memory_operand" "")
10376 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10377 (use (match_operand:V4SF 2 "" ""))
10378 (clobber (reg:CC 17))]
10379 ""
10380 [(parallel [(set (match_dup 0)
10381 (abs:SF (match_dup 1)))
10382 (clobber (reg:CC 17))])])
10383
10384 (define_split
10385 [(set (match_operand:SF 0 "register_operand" "")
10386 (abs:SF (match_operand:SF 1 "register_operand" "")))
10387 (use (match_operand:V4SF 2 "" ""))
10388 (clobber (reg:CC 17))]
10389 "reload_completed && !SSE_REG_P (operands[0])"
10390 [(parallel [(set (match_dup 0)
10391 (abs:SF (match_dup 1)))
10392 (clobber (reg:CC 17))])])
10393
10394 (define_split
10395 [(set (match_operand:SF 0 "register_operand" "")
10396 (abs:SF (match_operand:SF 1 "register_operand" "")))
10397 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10398 (clobber (reg:CC 17))]
10399 "reload_completed && SSE_REG_P (operands[0])"
10400 [(set (subreg:TI (match_dup 0) 0)
10401 (and:TI (match_dup 1)
10402 (match_dup 2)))]
10403 {
10404 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10405 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10406 if (operands_match_p (operands[0], operands[2]))
10407 {
10408 rtx tmp;
10409 tmp = operands[1];
10410 operands[1] = operands[2];
10411 operands[2] = tmp;
10412 }
10413 })
10414
10415 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10416 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10417 ;; to itself.
10418 (define_insn "*abssf2_if"
10419 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10420 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10421 (clobber (reg:CC 17))]
10422 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10423 "#")
10424
10425 (define_split
10426 [(set (match_operand:SF 0 "fp_register_operand" "")
10427 (abs:SF (match_operand:SF 1 "register_operand" "")))
10428 (clobber (reg:CC 17))]
10429 "TARGET_80387 && reload_completed"
10430 [(set (match_dup 0)
10431 (abs:SF (match_dup 1)))]
10432 "")
10433
10434 (define_split
10435 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10436 (abs:SF (match_operand:SF 1 "register_operand" "")))
10437 (clobber (reg:CC 17))]
10438 "TARGET_80387 && reload_completed"
10439 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10440 (clobber (reg:CC 17))])]
10441 "operands[1] = gen_int_mode (~0x80000000, SImode);
10442 operands[0] = gen_lowpart (SImode, operands[0]);")
10443
10444 (define_split
10445 [(set (match_operand 0 "memory_operand" "")
10446 (abs (match_operand 1 "memory_operand" "")))
10447 (clobber (reg:CC 17))]
10448 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10449 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10450 (clobber (reg:CC 17))])]
10451 {
10452 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10453
10454 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10455 if (size >= 12)
10456 size = 10;
10457 operands[0] = adjust_address (operands[0], QImode, size - 1);
10458 operands[1] = gen_int_mode (~0x80, QImode);
10459 })
10460
10461 (define_expand "absdf2"
10462 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10463 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10464 (clobber (reg:CC 17))])]
10465 "TARGET_80387"
10466 "if (TARGET_SSE2)
10467 {
10468 /* In case operand is in memory, we will not use SSE. */
10469 if (memory_operand (operands[0], VOIDmode)
10470 && rtx_equal_p (operands[0], operands[1]))
10471 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10472 else
10473 {
10474 /* Using SSE is tricky, since we need bitwise negation of -0
10475 in register. */
10476 rtx reg = gen_reg_rtx (V2DFmode);
10477 #if HOST_BITS_PER_WIDE_INT >= 64
10478 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10479 #else
10480 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10481 #endif
10482 rtx dest = operands[0];
10483
10484 operands[1] = force_reg (DFmode, operands[1]);
10485 operands[0] = force_reg (DFmode, operands[0]);
10486
10487 /* Produce LONG_DOUBLE with the proper immediate argument. */
10488 imm = gen_lowpart (DFmode, imm);
10489 reg = force_reg (V2DFmode,
10490 gen_rtx_CONST_VECTOR (V2DFmode,
10491 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10492 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10493 if (dest != operands[0])
10494 emit_move_insn (dest, operands[0]);
10495 }
10496 DONE;
10497 }
10498 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10499
10500 (define_insn "absdf2_memory"
10501 [(set (match_operand:DF 0 "memory_operand" "=m")
10502 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10503 (clobber (reg:CC 17))]
10504 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10505 "#")
10506
10507 (define_insn "absdf2_ifs"
10508 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10509 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10510 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10511 (clobber (reg:CC 17))]
10512 "!TARGET_64BIT && TARGET_SSE2
10513 && (reload_in_progress || reload_completed
10514 || (register_operand (operands[0], VOIDmode)
10515 && register_operand (operands[1], VOIDmode)))"
10516 "#")
10517
10518 (define_insn "*absdf2_ifs_rex64"
10519 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10520 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10521 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10522 (clobber (reg:CC 17))]
10523 "TARGET_64BIT && TARGET_SSE2
10524 && (reload_in_progress || reload_completed
10525 || (register_operand (operands[0], VOIDmode)
10526 && register_operand (operands[1], VOIDmode)))"
10527 "#")
10528
10529 (define_split
10530 [(set (match_operand:DF 0 "memory_operand" "")
10531 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10532 (use (match_operand:V2DF 2 "" ""))
10533 (clobber (reg:CC 17))]
10534 ""
10535 [(parallel [(set (match_dup 0)
10536 (abs:DF (match_dup 1)))
10537 (clobber (reg:CC 17))])])
10538
10539 (define_split
10540 [(set (match_operand:DF 0 "register_operand" "")
10541 (abs:DF (match_operand:DF 1 "register_operand" "")))
10542 (use (match_operand:V2DF 2 "" ""))
10543 (clobber (reg:CC 17))]
10544 "reload_completed && !SSE_REG_P (operands[0])"
10545 [(parallel [(set (match_dup 0)
10546 (abs:DF (match_dup 1)))
10547 (clobber (reg:CC 17))])])
10548
10549 (define_split
10550 [(set (match_operand:DF 0 "register_operand" "")
10551 (abs:DF (match_operand:DF 1 "register_operand" "")))
10552 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10553 (clobber (reg:CC 17))]
10554 "reload_completed && SSE_REG_P (operands[0])"
10555 [(set (subreg:TI (match_dup 0) 0)
10556 (and:TI (match_dup 1)
10557 (match_dup 2)))]
10558 {
10559 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10560 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10561 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10562 /* Avoid possible reformatting on the operands. */
10563 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10564 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10565 if (operands_match_p (operands[0], operands[2]))
10566 {
10567 rtx tmp;
10568 tmp = operands[1];
10569 operands[1] = operands[2];
10570 operands[2] = tmp;
10571 }
10572 })
10573
10574
10575 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10576 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10577 ;; to itself.
10578 (define_insn "*absdf2_if"
10579 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10580 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10581 (clobber (reg:CC 17))]
10582 "!TARGET_64BIT && TARGET_80387
10583 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10584 "#")
10585
10586 ;; FIXME: We should to allow integer registers here. Problem is that
10587 ;; we need another scratch register to get constant from.
10588 ;; Forcing constant to mem if no register available in peep2 should be
10589 ;; safe even for PIC mode, because of RIP relative addressing.
10590 (define_insn "*absdf2_if_rex64"
10591 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10592 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10593 (clobber (reg:CC 17))]
10594 "TARGET_64BIT && TARGET_80387
10595 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10596 "#")
10597
10598 (define_split
10599 [(set (match_operand:DF 0 "fp_register_operand" "")
10600 (abs:DF (match_operand:DF 1 "register_operand" "")))
10601 (clobber (reg:CC 17))]
10602 "TARGET_80387 && reload_completed"
10603 [(set (match_dup 0)
10604 (abs:DF (match_dup 1)))]
10605 "")
10606
10607 (define_split
10608 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10609 (abs:DF (match_operand:DF 1 "register_operand" "")))
10610 (clobber (reg:CC 17))]
10611 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10612 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10613 (clobber (reg:CC 17))])]
10614 "operands[4] = gen_int_mode (~0x80000000, SImode);
10615 split_di (operands+0, 1, operands+2, operands+3);")
10616
10617 (define_expand "absxf2"
10618 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10619 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10620 (clobber (reg:CC 17))])]
10621 "!TARGET_64BIT && TARGET_80387"
10622 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10623
10624 (define_expand "abstf2"
10625 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10626 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10627 (clobber (reg:CC 17))])]
10628 "TARGET_80387"
10629 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10630
10631 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10632 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10633 ;; to itself.
10634 (define_insn "*absxf2_if"
10635 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10636 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10637 (clobber (reg:CC 17))]
10638 "!TARGET_64BIT && TARGET_80387
10639 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10640 "#")
10641
10642 (define_split
10643 [(set (match_operand:XF 0 "fp_register_operand" "")
10644 (abs:XF (match_operand:XF 1 "register_operand" "")))
10645 (clobber (reg:CC 17))]
10646 "TARGET_80387 && reload_completed"
10647 [(set (match_dup 0)
10648 (abs:XF (match_dup 1)))]
10649 "")
10650
10651 (define_split
10652 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10653 (abs:XF (match_operand:XF 1 "register_operand" "")))
10654 (clobber (reg:CC 17))]
10655 "TARGET_80387 && reload_completed"
10656 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10657 (clobber (reg:CC 17))])]
10658 "operands[1] = GEN_INT (~0x8000);
10659 operands[0] = gen_rtx_REG (SImode,
10660 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10661
10662 (define_insn "*abstf2_if"
10663 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10664 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10665 (clobber (reg:CC 17))]
10666 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10667 "#")
10668
10669 (define_split
10670 [(set (match_operand:TF 0 "fp_register_operand" "")
10671 (abs:TF (match_operand:TF 1 "register_operand" "")))
10672 (clobber (reg:CC 17))]
10673 "TARGET_80387 && reload_completed"
10674 [(set (match_dup 0)
10675 (abs:TF (match_dup 1)))]
10676 "")
10677
10678 (define_split
10679 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10680 (abs:TF (match_operand:TF 1 "register_operand" "")))
10681 (clobber (reg:CC 17))]
10682 "TARGET_80387 && reload_completed"
10683 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10684 (clobber (reg:CC 17))])]
10685 "operands[1] = GEN_INT (~0x8000);
10686 operands[0] = gen_rtx_REG (SImode,
10687 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10688
10689 (define_insn "*abssf2_1"
10690 [(set (match_operand:SF 0 "register_operand" "=f")
10691 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10692 "TARGET_80387 && reload_completed"
10693 "fabs"
10694 [(set_attr "type" "fsgn")
10695 (set_attr "mode" "SF")])
10696
10697 (define_insn "*absdf2_1"
10698 [(set (match_operand:DF 0 "register_operand" "=f")
10699 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10700 "TARGET_80387 && reload_completed"
10701 "fabs"
10702 [(set_attr "type" "fsgn")
10703 (set_attr "mode" "DF")])
10704
10705 (define_insn "*absextendsfdf2"
10706 [(set (match_operand:DF 0 "register_operand" "=f")
10707 (abs:DF (float_extend:DF
10708 (match_operand:SF 1 "register_operand" "0"))))]
10709 "TARGET_80387"
10710 "fabs"
10711 [(set_attr "type" "fsgn")
10712 (set_attr "mode" "DF")])
10713
10714 (define_insn "*absxf2_1"
10715 [(set (match_operand:XF 0 "register_operand" "=f")
10716 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10717 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10718 "fabs"
10719 [(set_attr "type" "fsgn")
10720 (set_attr "mode" "DF")])
10721
10722 (define_insn "*absextenddfxf2"
10723 [(set (match_operand:XF 0 "register_operand" "=f")
10724 (abs:XF (float_extend:XF
10725 (match_operand:DF 1 "register_operand" "0"))))]
10726 "!TARGET_64BIT && TARGET_80387"
10727 "fabs"
10728 [(set_attr "type" "fsgn")
10729 (set_attr "mode" "XF")])
10730
10731 (define_insn "*absextendsfxf2"
10732 [(set (match_operand:XF 0 "register_operand" "=f")
10733 (abs:XF (float_extend:XF
10734 (match_operand:SF 1 "register_operand" "0"))))]
10735 "!TARGET_64BIT && TARGET_80387"
10736 "fabs"
10737 [(set_attr "type" "fsgn")
10738 (set_attr "mode" "XF")])
10739
10740 (define_insn "*abstf2_1"
10741 [(set (match_operand:TF 0 "register_operand" "=f")
10742 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10743 "TARGET_80387 && reload_completed"
10744 "fabs"
10745 [(set_attr "type" "fsgn")
10746 (set_attr "mode" "DF")])
10747
10748 (define_insn "*absextenddftf2"
10749 [(set (match_operand:TF 0 "register_operand" "=f")
10750 (abs:TF (float_extend:TF
10751 (match_operand:DF 1 "register_operand" "0"))))]
10752 "TARGET_80387"
10753 "fabs"
10754 [(set_attr "type" "fsgn")
10755 (set_attr "mode" "XF")])
10756
10757 (define_insn "*absextendsftf2"
10758 [(set (match_operand:TF 0 "register_operand" "=f")
10759 (abs:TF (float_extend:TF
10760 (match_operand:SF 1 "register_operand" "0"))))]
10761 "TARGET_80387"
10762 "fabs"
10763 [(set_attr "type" "fsgn")
10764 (set_attr "mode" "XF")])
10765 \f
10766 ;; One complement instructions
10767
10768 (define_expand "one_cmpldi2"
10769 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10770 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10771 "TARGET_64BIT"
10772 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10773
10774 (define_insn "*one_cmpldi2_1_rex64"
10775 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10776 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10777 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10778 "not{q}\t%0"
10779 [(set_attr "type" "negnot")
10780 (set_attr "mode" "DI")])
10781
10782 (define_insn "*one_cmpldi2_2_rex64"
10783 [(set (reg 17)
10784 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10785 (const_int 0)))
10786 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10787 (not:DI (match_dup 1)))]
10788 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10789 && ix86_unary_operator_ok (NOT, DImode, operands)"
10790 "#"
10791 [(set_attr "type" "alu1")
10792 (set_attr "mode" "DI")])
10793
10794 (define_split
10795 [(set (reg 17)
10796 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10797 (const_int 0)))
10798 (set (match_operand:DI 0 "nonimmediate_operand" "")
10799 (not:DI (match_dup 1)))]
10800 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10801 [(parallel [(set (reg:CCNO 17)
10802 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10803 (const_int 0)))
10804 (set (match_dup 0)
10805 (xor:DI (match_dup 1) (const_int -1)))])]
10806 "")
10807
10808 (define_expand "one_cmplsi2"
10809 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10810 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10811 ""
10812 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10813
10814 (define_insn "*one_cmplsi2_1"
10815 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10816 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10817 "ix86_unary_operator_ok (NOT, SImode, operands)"
10818 "not{l}\t%0"
10819 [(set_attr "type" "negnot")
10820 (set_attr "mode" "SI")])
10821
10822 ;; ??? Currently never generated - xor is used instead.
10823 (define_insn "*one_cmplsi2_1_zext"
10824 [(set (match_operand:DI 0 "register_operand" "=r")
10825 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10826 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10827 "not{l}\t%k0"
10828 [(set_attr "type" "negnot")
10829 (set_attr "mode" "SI")])
10830
10831 (define_insn "*one_cmplsi2_2"
10832 [(set (reg 17)
10833 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10834 (const_int 0)))
10835 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10836 (not:SI (match_dup 1)))]
10837 "ix86_match_ccmode (insn, CCNOmode)
10838 && ix86_unary_operator_ok (NOT, SImode, operands)"
10839 "#"
10840 [(set_attr "type" "alu1")
10841 (set_attr "mode" "SI")])
10842
10843 (define_split
10844 [(set (reg 17)
10845 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10846 (const_int 0)))
10847 (set (match_operand:SI 0 "nonimmediate_operand" "")
10848 (not:SI (match_dup 1)))]
10849 "ix86_match_ccmode (insn, CCNOmode)"
10850 [(parallel [(set (reg:CCNO 17)
10851 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10852 (const_int 0)))
10853 (set (match_dup 0)
10854 (xor:SI (match_dup 1) (const_int -1)))])]
10855 "")
10856
10857 ;; ??? Currently never generated - xor is used instead.
10858 (define_insn "*one_cmplsi2_2_zext"
10859 [(set (reg 17)
10860 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10861 (const_int 0)))
10862 (set (match_operand:DI 0 "register_operand" "=r")
10863 (zero_extend:DI (not:SI (match_dup 1))))]
10864 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10865 && ix86_unary_operator_ok (NOT, SImode, operands)"
10866 "#"
10867 [(set_attr "type" "alu1")
10868 (set_attr "mode" "SI")])
10869
10870 (define_split
10871 [(set (reg 17)
10872 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10873 (const_int 0)))
10874 (set (match_operand:DI 0 "register_operand" "")
10875 (zero_extend:DI (not:SI (match_dup 1))))]
10876 "ix86_match_ccmode (insn, CCNOmode)"
10877 [(parallel [(set (reg:CCNO 17)
10878 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10879 (const_int 0)))
10880 (set (match_dup 0)
10881 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10882 "")
10883
10884 (define_expand "one_cmplhi2"
10885 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10886 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10887 "TARGET_HIMODE_MATH"
10888 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10889
10890 (define_insn "*one_cmplhi2_1"
10891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10892 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10893 "ix86_unary_operator_ok (NOT, HImode, operands)"
10894 "not{w}\t%0"
10895 [(set_attr "type" "negnot")
10896 (set_attr "mode" "HI")])
10897
10898 (define_insn "*one_cmplhi2_2"
10899 [(set (reg 17)
10900 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10901 (const_int 0)))
10902 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10903 (not:HI (match_dup 1)))]
10904 "ix86_match_ccmode (insn, CCNOmode)
10905 && ix86_unary_operator_ok (NEG, HImode, operands)"
10906 "#"
10907 [(set_attr "type" "alu1")
10908 (set_attr "mode" "HI")])
10909
10910 (define_split
10911 [(set (reg 17)
10912 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10913 (const_int 0)))
10914 (set (match_operand:HI 0 "nonimmediate_operand" "")
10915 (not:HI (match_dup 1)))]
10916 "ix86_match_ccmode (insn, CCNOmode)"
10917 [(parallel [(set (reg:CCNO 17)
10918 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10919 (const_int 0)))
10920 (set (match_dup 0)
10921 (xor:HI (match_dup 1) (const_int -1)))])]
10922 "")
10923
10924 ;; %%% Potential partial reg stall on alternative 1. What to do?
10925 (define_expand "one_cmplqi2"
10926 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10927 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10928 "TARGET_QIMODE_MATH"
10929 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10930
10931 (define_insn "*one_cmplqi2_1"
10932 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10933 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10934 "ix86_unary_operator_ok (NOT, QImode, operands)"
10935 "@
10936 not{b}\t%0
10937 not{l}\t%k0"
10938 [(set_attr "type" "negnot")
10939 (set_attr "mode" "QI,SI")])
10940
10941 (define_insn "*one_cmplqi2_2"
10942 [(set (reg 17)
10943 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10944 (const_int 0)))
10945 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10946 (not:QI (match_dup 1)))]
10947 "ix86_match_ccmode (insn, CCNOmode)
10948 && ix86_unary_operator_ok (NOT, QImode, operands)"
10949 "#"
10950 [(set_attr "type" "alu1")
10951 (set_attr "mode" "QI")])
10952
10953 (define_split
10954 [(set (reg 17)
10955 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10956 (const_int 0)))
10957 (set (match_operand:QI 0 "nonimmediate_operand" "")
10958 (not:QI (match_dup 1)))]
10959 "ix86_match_ccmode (insn, CCNOmode)"
10960 [(parallel [(set (reg:CCNO 17)
10961 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10962 (const_int 0)))
10963 (set (match_dup 0)
10964 (xor:QI (match_dup 1) (const_int -1)))])]
10965 "")
10966 \f
10967 ;; Arithmetic shift instructions
10968
10969 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10970 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10971 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10972 ;; from the assembler input.
10973 ;;
10974 ;; This instruction shifts the target reg/mem as usual, but instead of
10975 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10976 ;; is a left shift double, bits are taken from the high order bits of
10977 ;; reg, else if the insn is a shift right double, bits are taken from the
10978 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10979 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10980 ;;
10981 ;; Since sh[lr]d does not change the `reg' operand, that is done
10982 ;; separately, making all shifts emit pairs of shift double and normal
10983 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10984 ;; support a 63 bit shift, each shift where the count is in a reg expands
10985 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10986 ;;
10987 ;; If the shift count is a constant, we need never emit more than one
10988 ;; shift pair, instead using moves and sign extension for counts greater
10989 ;; than 31.
10990
10991 (define_expand "ashldi3"
10992 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10993 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10994 (match_operand:QI 2 "nonmemory_operand" "")))
10995 (clobber (reg:CC 17))])]
10996 ""
10997 {
10998 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10999 {
11000 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
11001 DONE;
11002 }
11003 ix86_expand_binary_operator (ASHIFT, DImode, operands);
11004 DONE;
11005 })
11006
11007 (define_insn "*ashldi3_1_rex64"
11008 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11009 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
11010 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11011 (clobber (reg:CC 17))]
11012 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11013 {
11014 switch (get_attr_type (insn))
11015 {
11016 case TYPE_ALU:
11017 if (operands[2] != const1_rtx)
11018 abort ();
11019 if (!rtx_equal_p (operands[0], operands[1]))
11020 abort ();
11021 return "add{q}\t{%0, %0|%0, %0}";
11022
11023 case TYPE_LEA:
11024 if (GET_CODE (operands[2]) != CONST_INT
11025 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11026 abort ();
11027 operands[1] = gen_rtx_MULT (DImode, operands[1],
11028 GEN_INT (1 << INTVAL (operands[2])));
11029 return "lea{q}\t{%a1, %0|%0, %a1}";
11030
11031 default:
11032 if (REG_P (operands[2]))
11033 return "sal{q}\t{%b2, %0|%0, %b2}";
11034 else if (GET_CODE (operands[2]) == CONST_INT
11035 && INTVAL (operands[2]) == 1
11036 && (TARGET_SHIFT1 || optimize_size))
11037 return "sal{q}\t%0";
11038 else
11039 return "sal{q}\t{%2, %0|%0, %2}";
11040 }
11041 }
11042 [(set (attr "type")
11043 (cond [(eq_attr "alternative" "1")
11044 (const_string "lea")
11045 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11046 (const_int 0))
11047 (match_operand 0 "register_operand" ""))
11048 (match_operand 2 "const1_operand" ""))
11049 (const_string "alu")
11050 ]
11051 (const_string "ishift")))
11052 (set_attr "mode" "DI")])
11053
11054 ;; Convert lea to the lea pattern to avoid flags dependency.
11055 (define_split
11056 [(set (match_operand:DI 0 "register_operand" "")
11057 (ashift:DI (match_operand:DI 1 "register_operand" "")
11058 (match_operand:QI 2 "immediate_operand" "")))
11059 (clobber (reg:CC 17))]
11060 "TARGET_64BIT && reload_completed
11061 && true_regnum (operands[0]) != true_regnum (operands[1])"
11062 [(set (match_dup 0)
11063 (mult:DI (match_dup 1)
11064 (match_dup 2)))]
11065 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11066
11067 ;; This pattern can't accept a variable shift count, since shifts by
11068 ;; zero don't affect the flags. We assume that shifts by constant
11069 ;; zero are optimized away.
11070 (define_insn "*ashldi3_cmp_rex64"
11071 [(set (reg 17)
11072 (compare
11073 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11074 (match_operand:QI 2 "immediate_operand" "e"))
11075 (const_int 0)))
11076 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11077 (ashift:DI (match_dup 1) (match_dup 2)))]
11078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11079 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11080 {
11081 switch (get_attr_type (insn))
11082 {
11083 case TYPE_ALU:
11084 if (operands[2] != const1_rtx)
11085 abort ();
11086 return "add{q}\t{%0, %0|%0, %0}";
11087
11088 default:
11089 if (REG_P (operands[2]))
11090 return "sal{q}\t{%b2, %0|%0, %b2}";
11091 else if (GET_CODE (operands[2]) == CONST_INT
11092 && INTVAL (operands[2]) == 1
11093 && (TARGET_SHIFT1 || optimize_size))
11094 return "sal{q}\t%0";
11095 else
11096 return "sal{q}\t{%2, %0|%0, %2}";
11097 }
11098 }
11099 [(set (attr "type")
11100 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11101 (const_int 0))
11102 (match_operand 0 "register_operand" ""))
11103 (match_operand 2 "const1_operand" ""))
11104 (const_string "alu")
11105 ]
11106 (const_string "ishift")))
11107 (set_attr "mode" "DI")])
11108
11109 (define_insn "ashldi3_1"
11110 [(set (match_operand:DI 0 "register_operand" "=r")
11111 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11112 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11113 (clobber (match_scratch:SI 3 "=&r"))
11114 (clobber (reg:CC 17))]
11115 "!TARGET_64BIT && TARGET_CMOVE"
11116 "#"
11117 [(set_attr "type" "multi")])
11118
11119 (define_insn "*ashldi3_2"
11120 [(set (match_operand:DI 0 "register_operand" "=r")
11121 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11122 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11123 (clobber (reg:CC 17))]
11124 "!TARGET_64BIT"
11125 "#"
11126 [(set_attr "type" "multi")])
11127
11128 (define_split
11129 [(set (match_operand:DI 0 "register_operand" "")
11130 (ashift:DI (match_operand:DI 1 "register_operand" "")
11131 (match_operand:QI 2 "nonmemory_operand" "")))
11132 (clobber (match_scratch:SI 3 ""))
11133 (clobber (reg:CC 17))]
11134 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11135 [(const_int 0)]
11136 "ix86_split_ashldi (operands, operands[3]); DONE;")
11137
11138 (define_split
11139 [(set (match_operand:DI 0 "register_operand" "")
11140 (ashift:DI (match_operand:DI 1 "register_operand" "")
11141 (match_operand:QI 2 "nonmemory_operand" "")))
11142 (clobber (reg:CC 17))]
11143 "!TARGET_64BIT && reload_completed"
11144 [(const_int 0)]
11145 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11146
11147 (define_insn "x86_shld_1"
11148 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11149 (ior:SI (ashift:SI (match_dup 0)
11150 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11151 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11152 (minus:QI (const_int 32) (match_dup 2)))))
11153 (clobber (reg:CC 17))]
11154 ""
11155 "@
11156 shld{l}\t{%2, %1, %0|%0, %1, %2}
11157 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11158 [(set_attr "type" "ishift")
11159 (set_attr "prefix_0f" "1")
11160 (set_attr "mode" "SI")
11161 (set_attr "pent_pair" "np")
11162 (set_attr "athlon_decode" "vector")
11163 (set_attr "ppro_uops" "few")])
11164
11165 (define_expand "x86_shift_adj_1"
11166 [(set (reg:CCZ 17)
11167 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11168 (const_int 32))
11169 (const_int 0)))
11170 (set (match_operand:SI 0 "register_operand" "")
11171 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11172 (match_operand:SI 1 "register_operand" "")
11173 (match_dup 0)))
11174 (set (match_dup 1)
11175 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11176 (match_operand:SI 3 "register_operand" "r")
11177 (match_dup 1)))]
11178 "TARGET_CMOVE"
11179 "")
11180
11181 (define_expand "x86_shift_adj_2"
11182 [(use (match_operand:SI 0 "register_operand" ""))
11183 (use (match_operand:SI 1 "register_operand" ""))
11184 (use (match_operand:QI 2 "register_operand" ""))]
11185 ""
11186 {
11187 rtx label = gen_label_rtx ();
11188 rtx tmp;
11189
11190 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11191
11192 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11193 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11194 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11195 gen_rtx_LABEL_REF (VOIDmode, label),
11196 pc_rtx);
11197 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11198 JUMP_LABEL (tmp) = label;
11199
11200 emit_move_insn (operands[0], operands[1]);
11201 emit_move_insn (operands[1], const0_rtx);
11202
11203 emit_label (label);
11204 LABEL_NUSES (label) = 1;
11205
11206 DONE;
11207 })
11208
11209 (define_expand "ashlsi3"
11210 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11211 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11212 (match_operand:QI 2 "nonmemory_operand" "")))
11213 (clobber (reg:CC 17))]
11214 ""
11215 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11216
11217 (define_insn "*ashlsi3_1"
11218 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11219 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11220 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11221 (clobber (reg:CC 17))]
11222 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11223 {
11224 switch (get_attr_type (insn))
11225 {
11226 case TYPE_ALU:
11227 if (operands[2] != const1_rtx)
11228 abort ();
11229 if (!rtx_equal_p (operands[0], operands[1]))
11230 abort ();
11231 return "add{l}\t{%0, %0|%0, %0}";
11232
11233 case TYPE_LEA:
11234 return "#";
11235
11236 default:
11237 if (REG_P (operands[2]))
11238 return "sal{l}\t{%b2, %0|%0, %b2}";
11239 else if (GET_CODE (operands[2]) == CONST_INT
11240 && INTVAL (operands[2]) == 1
11241 && (TARGET_SHIFT1 || optimize_size))
11242 return "sal{l}\t%0";
11243 else
11244 return "sal{l}\t{%2, %0|%0, %2}";
11245 }
11246 }
11247 [(set (attr "type")
11248 (cond [(eq_attr "alternative" "1")
11249 (const_string "lea")
11250 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11251 (const_int 0))
11252 (match_operand 0 "register_operand" ""))
11253 (match_operand 2 "const1_operand" ""))
11254 (const_string "alu")
11255 ]
11256 (const_string "ishift")))
11257 (set_attr "mode" "SI")])
11258
11259 ;; Convert lea to the lea pattern to avoid flags dependency.
11260 (define_split
11261 [(set (match_operand 0 "register_operand" "")
11262 (ashift (match_operand 1 "index_register_operand" "")
11263 (match_operand:QI 2 "const_int_operand" "")))
11264 (clobber (reg:CC 17))]
11265 "reload_completed
11266 && true_regnum (operands[0]) != true_regnum (operands[1])"
11267 [(const_int 0)]
11268 {
11269 rtx pat;
11270 operands[0] = gen_lowpart (SImode, operands[0]);
11271 operands[1] = gen_lowpart (Pmode, operands[1]);
11272 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11273 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11274 if (Pmode != SImode)
11275 pat = gen_rtx_SUBREG (SImode, pat, 0);
11276 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11277 DONE;
11278 })
11279
11280 ;; Rare case of shifting RSP is handled by generating move and shift
11281 (define_split
11282 [(set (match_operand 0 "register_operand" "")
11283 (ashift (match_operand 1 "register_operand" "")
11284 (match_operand:QI 2 "const_int_operand" "")))
11285 (clobber (reg:CC 17))]
11286 "reload_completed
11287 && true_regnum (operands[0]) != true_regnum (operands[1])"
11288 [(const_int 0)]
11289 {
11290 rtx pat, clob;
11291 emit_move_insn (operands[1], operands[0]);
11292 pat = gen_rtx_SET (VOIDmode, operands[0],
11293 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11294 operands[0], operands[2]));
11295 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11296 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11297 DONE;
11298 })
11299
11300 (define_insn "*ashlsi3_1_zext"
11301 [(set (match_operand:DI 0 "register_operand" "=r,r")
11302 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11303 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11304 (clobber (reg:CC 17))]
11305 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11306 {
11307 switch (get_attr_type (insn))
11308 {
11309 case TYPE_ALU:
11310 if (operands[2] != const1_rtx)
11311 abort ();
11312 return "add{l}\t{%k0, %k0|%k0, %k0}";
11313
11314 case TYPE_LEA:
11315 return "#";
11316
11317 default:
11318 if (REG_P (operands[2]))
11319 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11320 else if (GET_CODE (operands[2]) == CONST_INT
11321 && INTVAL (operands[2]) == 1
11322 && (TARGET_SHIFT1 || optimize_size))
11323 return "sal{l}\t%k0";
11324 else
11325 return "sal{l}\t{%2, %k0|%k0, %2}";
11326 }
11327 }
11328 [(set (attr "type")
11329 (cond [(eq_attr "alternative" "1")
11330 (const_string "lea")
11331 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332 (const_int 0))
11333 (match_operand 2 "const1_operand" ""))
11334 (const_string "alu")
11335 ]
11336 (const_string "ishift")))
11337 (set_attr "mode" "SI")])
11338
11339 ;; Convert lea to the lea pattern to avoid flags dependency.
11340 (define_split
11341 [(set (match_operand:DI 0 "register_operand" "")
11342 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11343 (match_operand:QI 2 "const_int_operand" ""))))
11344 (clobber (reg:CC 17))]
11345 "TARGET_64BIT && reload_completed
11346 && true_regnum (operands[0]) != true_regnum (operands[1])"
11347 [(set (match_dup 0) (zero_extend:DI
11348 (subreg:SI (mult:SI (match_dup 1)
11349 (match_dup 2)) 0)))]
11350 {
11351 operands[1] = gen_lowpart (Pmode, operands[1]);
11352 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11353 })
11354
11355 ;; This pattern can't accept a variable shift count, since shifts by
11356 ;; zero don't affect the flags. We assume that shifts by constant
11357 ;; zero are optimized away.
11358 (define_insn "*ashlsi3_cmp"
11359 [(set (reg 17)
11360 (compare
11361 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11362 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11363 (const_int 0)))
11364 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11365 (ashift:SI (match_dup 1) (match_dup 2)))]
11366 "ix86_match_ccmode (insn, CCGOCmode)
11367 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11368 {
11369 switch (get_attr_type (insn))
11370 {
11371 case TYPE_ALU:
11372 if (operands[2] != const1_rtx)
11373 abort ();
11374 return "add{l}\t{%0, %0|%0, %0}";
11375
11376 default:
11377 if (REG_P (operands[2]))
11378 return "sal{l}\t{%b2, %0|%0, %b2}";
11379 else if (GET_CODE (operands[2]) == CONST_INT
11380 && INTVAL (operands[2]) == 1
11381 && (TARGET_SHIFT1 || optimize_size))
11382 return "sal{l}\t%0";
11383 else
11384 return "sal{l}\t{%2, %0|%0, %2}";
11385 }
11386 }
11387 [(set (attr "type")
11388 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11389 (const_int 0))
11390 (match_operand 0 "register_operand" ""))
11391 (match_operand 2 "const1_operand" ""))
11392 (const_string "alu")
11393 ]
11394 (const_string "ishift")))
11395 (set_attr "mode" "SI")])
11396
11397 (define_insn "*ashlsi3_cmp_zext"
11398 [(set (reg 17)
11399 (compare
11400 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11401 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11402 (const_int 0)))
11403 (set (match_operand:DI 0 "register_operand" "=r")
11404 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11405 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11406 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11407 {
11408 switch (get_attr_type (insn))
11409 {
11410 case TYPE_ALU:
11411 if (operands[2] != const1_rtx)
11412 abort ();
11413 return "add{l}\t{%k0, %k0|%k0, %k0}";
11414
11415 default:
11416 if (REG_P (operands[2]))
11417 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11418 else if (GET_CODE (operands[2]) == CONST_INT
11419 && INTVAL (operands[2]) == 1
11420 && (TARGET_SHIFT1 || optimize_size))
11421 return "sal{l}\t%k0";
11422 else
11423 return "sal{l}\t{%2, %k0|%k0, %2}";
11424 }
11425 }
11426 [(set (attr "type")
11427 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11428 (const_int 0))
11429 (match_operand 2 "const1_operand" ""))
11430 (const_string "alu")
11431 ]
11432 (const_string "ishift")))
11433 (set_attr "mode" "SI")])
11434
11435 (define_expand "ashlhi3"
11436 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11437 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11438 (match_operand:QI 2 "nonmemory_operand" "")))
11439 (clobber (reg:CC 17))]
11440 "TARGET_HIMODE_MATH"
11441 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11442
11443 (define_insn "*ashlhi3_1_lea"
11444 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11445 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11446 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11447 (clobber (reg:CC 17))]
11448 "!TARGET_PARTIAL_REG_STALL
11449 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11450 {
11451 switch (get_attr_type (insn))
11452 {
11453 case TYPE_LEA:
11454 return "#";
11455 case TYPE_ALU:
11456 if (operands[2] != const1_rtx)
11457 abort ();
11458 return "add{w}\t{%0, %0|%0, %0}";
11459
11460 default:
11461 if (REG_P (operands[2]))
11462 return "sal{w}\t{%b2, %0|%0, %b2}";
11463 else if (GET_CODE (operands[2]) == CONST_INT
11464 && INTVAL (operands[2]) == 1
11465 && (TARGET_SHIFT1 || optimize_size))
11466 return "sal{w}\t%0";
11467 else
11468 return "sal{w}\t{%2, %0|%0, %2}";
11469 }
11470 }
11471 [(set (attr "type")
11472 (cond [(eq_attr "alternative" "1")
11473 (const_string "lea")
11474 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11475 (const_int 0))
11476 (match_operand 0 "register_operand" ""))
11477 (match_operand 2 "const1_operand" ""))
11478 (const_string "alu")
11479 ]
11480 (const_string "ishift")))
11481 (set_attr "mode" "HI,SI")])
11482
11483 (define_insn "*ashlhi3_1"
11484 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11485 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11486 (match_operand:QI 2 "nonmemory_operand" "cI")))
11487 (clobber (reg:CC 17))]
11488 "TARGET_PARTIAL_REG_STALL
11489 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11490 {
11491 switch (get_attr_type (insn))
11492 {
11493 case TYPE_ALU:
11494 if (operands[2] != const1_rtx)
11495 abort ();
11496 return "add{w}\t{%0, %0|%0, %0}";
11497
11498 default:
11499 if (REG_P (operands[2]))
11500 return "sal{w}\t{%b2, %0|%0, %b2}";
11501 else if (GET_CODE (operands[2]) == CONST_INT
11502 && INTVAL (operands[2]) == 1
11503 && (TARGET_SHIFT1 || optimize_size))
11504 return "sal{w}\t%0";
11505 else
11506 return "sal{w}\t{%2, %0|%0, %2}";
11507 }
11508 }
11509 [(set (attr "type")
11510 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11511 (const_int 0))
11512 (match_operand 0 "register_operand" ""))
11513 (match_operand 2 "const1_operand" ""))
11514 (const_string "alu")
11515 ]
11516 (const_string "ishift")))
11517 (set_attr "mode" "HI")])
11518
11519 ;; This pattern can't accept a variable shift count, since shifts by
11520 ;; zero don't affect the flags. We assume that shifts by constant
11521 ;; zero are optimized away.
11522 (define_insn "*ashlhi3_cmp"
11523 [(set (reg 17)
11524 (compare
11525 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11526 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11527 (const_int 0)))
11528 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11529 (ashift:HI (match_dup 1) (match_dup 2)))]
11530 "ix86_match_ccmode (insn, CCGOCmode)
11531 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11532 {
11533 switch (get_attr_type (insn))
11534 {
11535 case TYPE_ALU:
11536 if (operands[2] != const1_rtx)
11537 abort ();
11538 return "add{w}\t{%0, %0|%0, %0}";
11539
11540 default:
11541 if (REG_P (operands[2]))
11542 return "sal{w}\t{%b2, %0|%0, %b2}";
11543 else if (GET_CODE (operands[2]) == CONST_INT
11544 && INTVAL (operands[2]) == 1
11545 && (TARGET_SHIFT1 || optimize_size))
11546 return "sal{w}\t%0";
11547 else
11548 return "sal{w}\t{%2, %0|%0, %2}";
11549 }
11550 }
11551 [(set (attr "type")
11552 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11553 (const_int 0))
11554 (match_operand 0 "register_operand" ""))
11555 (match_operand 2 "const1_operand" ""))
11556 (const_string "alu")
11557 ]
11558 (const_string "ishift")))
11559 (set_attr "mode" "HI")])
11560
11561 (define_expand "ashlqi3"
11562 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11563 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11564 (match_operand:QI 2 "nonmemory_operand" "")))
11565 (clobber (reg:CC 17))]
11566 "TARGET_QIMODE_MATH"
11567 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11568
11569 ;; %%% Potential partial reg stall on alternative 2. What to do?
11570
11571 (define_insn "*ashlqi3_1_lea"
11572 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11573 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11574 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11575 (clobber (reg:CC 17))]
11576 "!TARGET_PARTIAL_REG_STALL
11577 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11578 {
11579 switch (get_attr_type (insn))
11580 {
11581 case TYPE_LEA:
11582 return "#";
11583 case TYPE_ALU:
11584 if (operands[2] != const1_rtx)
11585 abort ();
11586 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11587 return "add{l}\t{%k0, %k0|%k0, %k0}";
11588 else
11589 return "add{b}\t{%0, %0|%0, %0}";
11590
11591 default:
11592 if (REG_P (operands[2]))
11593 {
11594 if (get_attr_mode (insn) == MODE_SI)
11595 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11596 else
11597 return "sal{b}\t{%b2, %0|%0, %b2}";
11598 }
11599 else if (GET_CODE (operands[2]) == CONST_INT
11600 && INTVAL (operands[2]) == 1
11601 && (TARGET_SHIFT1 || optimize_size))
11602 {
11603 if (get_attr_mode (insn) == MODE_SI)
11604 return "sal{l}\t%0";
11605 else
11606 return "sal{b}\t%0";
11607 }
11608 else
11609 {
11610 if (get_attr_mode (insn) == MODE_SI)
11611 return "sal{l}\t{%2, %k0|%k0, %2}";
11612 else
11613 return "sal{b}\t{%2, %0|%0, %2}";
11614 }
11615 }
11616 }
11617 [(set (attr "type")
11618 (cond [(eq_attr "alternative" "2")
11619 (const_string "lea")
11620 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11621 (const_int 0))
11622 (match_operand 0 "register_operand" ""))
11623 (match_operand 2 "const1_operand" ""))
11624 (const_string "alu")
11625 ]
11626 (const_string "ishift")))
11627 (set_attr "mode" "QI,SI,SI")])
11628
11629 (define_insn "*ashlqi3_1"
11630 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11631 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11632 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11633 (clobber (reg:CC 17))]
11634 "TARGET_PARTIAL_REG_STALL
11635 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11636 {
11637 switch (get_attr_type (insn))
11638 {
11639 case TYPE_ALU:
11640 if (operands[2] != const1_rtx)
11641 abort ();
11642 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11643 return "add{l}\t{%k0, %k0|%k0, %k0}";
11644 else
11645 return "add{b}\t{%0, %0|%0, %0}";
11646
11647 default:
11648 if (REG_P (operands[2]))
11649 {
11650 if (get_attr_mode (insn) == MODE_SI)
11651 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11652 else
11653 return "sal{b}\t{%b2, %0|%0, %b2}";
11654 }
11655 else if (GET_CODE (operands[2]) == CONST_INT
11656 && INTVAL (operands[2]) == 1
11657 && (TARGET_SHIFT1 || optimize_size))
11658 {
11659 if (get_attr_mode (insn) == MODE_SI)
11660 return "sal{l}\t%0";
11661 else
11662 return "sal{b}\t%0";
11663 }
11664 else
11665 {
11666 if (get_attr_mode (insn) == MODE_SI)
11667 return "sal{l}\t{%2, %k0|%k0, %2}";
11668 else
11669 return "sal{b}\t{%2, %0|%0, %2}";
11670 }
11671 }
11672 }
11673 [(set (attr "type")
11674 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11675 (const_int 0))
11676 (match_operand 0 "register_operand" ""))
11677 (match_operand 2 "const1_operand" ""))
11678 (const_string "alu")
11679 ]
11680 (const_string "ishift")))
11681 (set_attr "mode" "QI,SI")])
11682
11683 ;; This pattern can't accept a variable shift count, since shifts by
11684 ;; zero don't affect the flags. We assume that shifts by constant
11685 ;; zero are optimized away.
11686 (define_insn "*ashlqi3_cmp"
11687 [(set (reg 17)
11688 (compare
11689 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11690 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11691 (const_int 0)))
11692 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11693 (ashift:QI (match_dup 1) (match_dup 2)))]
11694 "ix86_match_ccmode (insn, CCGOCmode)
11695 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11696 {
11697 switch (get_attr_type (insn))
11698 {
11699 case TYPE_ALU:
11700 if (operands[2] != const1_rtx)
11701 abort ();
11702 return "add{b}\t{%0, %0|%0, %0}";
11703
11704 default:
11705 if (REG_P (operands[2]))
11706 return "sal{b}\t{%b2, %0|%0, %b2}";
11707 else if (GET_CODE (operands[2]) == CONST_INT
11708 && INTVAL (operands[2]) == 1
11709 && (TARGET_SHIFT1 || optimize_size))
11710 return "sal{b}\t%0";
11711 else
11712 return "sal{b}\t{%2, %0|%0, %2}";
11713 }
11714 }
11715 [(set (attr "type")
11716 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11717 (const_int 0))
11718 (match_operand 0 "register_operand" ""))
11719 (match_operand 2 "const1_operand" ""))
11720 (const_string "alu")
11721 ]
11722 (const_string "ishift")))
11723 (set_attr "mode" "QI")])
11724
11725 ;; See comment above `ashldi3' about how this works.
11726
11727 (define_expand "ashrdi3"
11728 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11729 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11730 (match_operand:QI 2 "nonmemory_operand" "")))
11731 (clobber (reg:CC 17))])]
11732 ""
11733 {
11734 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11735 {
11736 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11737 DONE;
11738 }
11739 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11740 DONE;
11741 })
11742
11743 (define_insn "ashrdi3_63_rex64"
11744 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11745 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11746 (match_operand:DI 2 "const_int_operand" "i,i")))
11747 (clobber (reg:CC 17))]
11748 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11749 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11750 "@
11751 {cqto|cqo}
11752 sar{q}\t{%2, %0|%0, %2}"
11753 [(set_attr "type" "imovx,ishift")
11754 (set_attr "prefix_0f" "0,*")
11755 (set_attr "length_immediate" "0,*")
11756 (set_attr "modrm" "0,1")
11757 (set_attr "mode" "DI")])
11758
11759 (define_insn "*ashrdi3_1_one_bit_rex64"
11760 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11761 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11762 (match_operand:QI 2 "const_int_1_operand" "")))
11763 (clobber (reg:CC 17))]
11764 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11765 && (TARGET_SHIFT1 || optimize_size)"
11766 "sar{q}\t%0"
11767 [(set_attr "type" "ishift")
11768 (set (attr "length")
11769 (if_then_else (match_operand:DI 0 "register_operand" "")
11770 (const_string "2")
11771 (const_string "*")))])
11772
11773 (define_insn "*ashrdi3_1_rex64"
11774 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11775 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11776 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11777 (clobber (reg:CC 17))]
11778 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11779 "@
11780 sar{q}\t{%2, %0|%0, %2}
11781 sar{q}\t{%b2, %0|%0, %b2}"
11782 [(set_attr "type" "ishift")
11783 (set_attr "mode" "DI")])
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 "*ashrdi3_one_bit_cmp_rex64"
11789 [(set (reg 17)
11790 (compare
11791 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11792 (match_operand:QI 2 "const_int_1_operand" ""))
11793 (const_int 0)))
11794 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11795 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11796 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11797 && (TARGET_SHIFT1 || optimize_size)
11798 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11799 "sar{q}\t%0"
11800 [(set_attr "type" "ishift")
11801 (set (attr "length")
11802 (if_then_else (match_operand:DI 0 "register_operand" "")
11803 (const_string "2")
11804 (const_string "*")))])
11805
11806 ;; This pattern can't accept a variable shift count, since shifts by
11807 ;; zero don't affect the flags. We assume that shifts by constant
11808 ;; zero are optimized away.
11809 (define_insn "*ashrdi3_cmp_rex64"
11810 [(set (reg 17)
11811 (compare
11812 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11813 (match_operand:QI 2 "const_int_operand" "n"))
11814 (const_int 0)))
11815 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11816 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11817 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11818 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11819 "sar{q}\t{%2, %0|%0, %2}"
11820 [(set_attr "type" "ishift")
11821 (set_attr "mode" "DI")])
11822
11823
11824 (define_insn "ashrdi3_1"
11825 [(set (match_operand:DI 0 "register_operand" "=r")
11826 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11827 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11828 (clobber (match_scratch:SI 3 "=&r"))
11829 (clobber (reg:CC 17))]
11830 "!TARGET_64BIT && TARGET_CMOVE"
11831 "#"
11832 [(set_attr "type" "multi")])
11833
11834 (define_insn "*ashrdi3_2"
11835 [(set (match_operand:DI 0 "register_operand" "=r")
11836 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11837 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11838 (clobber (reg:CC 17))]
11839 "!TARGET_64BIT"
11840 "#"
11841 [(set_attr "type" "multi")])
11842
11843 (define_split
11844 [(set (match_operand:DI 0 "register_operand" "")
11845 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11846 (match_operand:QI 2 "nonmemory_operand" "")))
11847 (clobber (match_scratch:SI 3 ""))
11848 (clobber (reg:CC 17))]
11849 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11850 [(const_int 0)]
11851 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11852
11853 (define_split
11854 [(set (match_operand:DI 0 "register_operand" "")
11855 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11856 (match_operand:QI 2 "nonmemory_operand" "")))
11857 (clobber (reg:CC 17))]
11858 "!TARGET_64BIT && reload_completed"
11859 [(const_int 0)]
11860 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11861
11862 (define_insn "x86_shrd_1"
11863 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11864 (ior:SI (ashiftrt:SI (match_dup 0)
11865 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11866 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11867 (minus:QI (const_int 32) (match_dup 2)))))
11868 (clobber (reg:CC 17))]
11869 ""
11870 "@
11871 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11872 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11873 [(set_attr "type" "ishift")
11874 (set_attr "prefix_0f" "1")
11875 (set_attr "pent_pair" "np")
11876 (set_attr "ppro_uops" "few")
11877 (set_attr "mode" "SI")])
11878
11879 (define_expand "x86_shift_adj_3"
11880 [(use (match_operand:SI 0 "register_operand" ""))
11881 (use (match_operand:SI 1 "register_operand" ""))
11882 (use (match_operand:QI 2 "register_operand" ""))]
11883 ""
11884 {
11885 rtx label = gen_label_rtx ();
11886 rtx tmp;
11887
11888 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11889
11890 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11891 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11892 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11893 gen_rtx_LABEL_REF (VOIDmode, label),
11894 pc_rtx);
11895 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11896 JUMP_LABEL (tmp) = label;
11897
11898 emit_move_insn (operands[0], operands[1]);
11899 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11900
11901 emit_label (label);
11902 LABEL_NUSES (label) = 1;
11903
11904 DONE;
11905 })
11906
11907 (define_insn "ashrsi3_31"
11908 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11909 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11910 (match_operand:SI 2 "const_int_operand" "i,i")))
11911 (clobber (reg:CC 17))]
11912 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11913 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11914 "@
11915 {cltd|cdq}
11916 sar{l}\t{%2, %0|%0, %2}"
11917 [(set_attr "type" "imovx,ishift")
11918 (set_attr "prefix_0f" "0,*")
11919 (set_attr "length_immediate" "0,*")
11920 (set_attr "modrm" "0,1")
11921 (set_attr "mode" "SI")])
11922
11923 (define_insn "*ashrsi3_31_zext"
11924 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11925 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11926 (match_operand:SI 2 "const_int_operand" "i,i"))))
11927 (clobber (reg:CC 17))]
11928 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11929 && INTVAL (operands[2]) == 31
11930 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11931 "@
11932 {cltd|cdq}
11933 sar{l}\t{%2, %k0|%k0, %2}"
11934 [(set_attr "type" "imovx,ishift")
11935 (set_attr "prefix_0f" "0,*")
11936 (set_attr "length_immediate" "0,*")
11937 (set_attr "modrm" "0,1")
11938 (set_attr "mode" "SI")])
11939
11940 (define_expand "ashrsi3"
11941 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11942 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11943 (match_operand:QI 2 "nonmemory_operand" "")))
11944 (clobber (reg:CC 17))]
11945 ""
11946 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11947
11948 (define_insn "*ashrsi3_1_one_bit"
11949 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11950 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11951 (match_operand:QI 2 "const_int_1_operand" "")))
11952 (clobber (reg:CC 17))]
11953 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11954 && (TARGET_SHIFT1 || optimize_size)"
11955 "sar{l}\t%0"
11956 [(set_attr "type" "ishift")
11957 (set (attr "length")
11958 (if_then_else (match_operand:SI 0 "register_operand" "")
11959 (const_string "2")
11960 (const_string "*")))])
11961
11962 (define_insn "*ashrsi3_1_one_bit_zext"
11963 [(set (match_operand:DI 0 "register_operand" "=r")
11964 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11965 (match_operand:QI 2 "const_int_1_operand" ""))))
11966 (clobber (reg:CC 17))]
11967 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11968 && (TARGET_SHIFT1 || optimize_size)"
11969 "sar{l}\t%k0"
11970 [(set_attr "type" "ishift")
11971 (set_attr "length" "2")])
11972
11973 (define_insn "*ashrsi3_1"
11974 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11975 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11976 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11977 (clobber (reg:CC 17))]
11978 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11979 "@
11980 sar{l}\t{%2, %0|%0, %2}
11981 sar{l}\t{%b2, %0|%0, %b2}"
11982 [(set_attr "type" "ishift")
11983 (set_attr "mode" "SI")])
11984
11985 (define_insn "*ashrsi3_1_zext"
11986 [(set (match_operand:DI 0 "register_operand" "=r,r")
11987 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11988 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11989 (clobber (reg:CC 17))]
11990 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11991 "@
11992 sar{l}\t{%2, %k0|%k0, %2}
11993 sar{l}\t{%b2, %k0|%k0, %b2}"
11994 [(set_attr "type" "ishift")
11995 (set_attr "mode" "SI")])
11996
11997 ;; This pattern can't accept a variable shift count, since shifts by
11998 ;; zero don't affect the flags. We assume that shifts by constant
11999 ;; zero are optimized away.
12000 (define_insn "*ashrsi3_one_bit_cmp"
12001 [(set (reg 17)
12002 (compare
12003 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12004 (match_operand:QI 2 "const_int_1_operand" ""))
12005 (const_int 0)))
12006 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12007 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12008 "ix86_match_ccmode (insn, CCGOCmode)
12009 && (TARGET_SHIFT1 || optimize_size)
12010 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12011 "sar{l}\t%0"
12012 [(set_attr "type" "ishift")
12013 (set (attr "length")
12014 (if_then_else (match_operand:SI 0 "register_operand" "")
12015 (const_string "2")
12016 (const_string "*")))])
12017
12018 (define_insn "*ashrsi3_one_bit_cmp_zext"
12019 [(set (reg 17)
12020 (compare
12021 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12022 (match_operand:QI 2 "const_int_1_operand" ""))
12023 (const_int 0)))
12024 (set (match_operand:DI 0 "register_operand" "=r")
12025 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12026 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12027 && (TARGET_SHIFT1 || optimize_size)
12028 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12029 "sar{l}\t%k0"
12030 [(set_attr "type" "ishift")
12031 (set_attr "length" "2")])
12032
12033 ;; This pattern can't accept a variable shift count, since shifts by
12034 ;; zero don't affect the flags. We assume that shifts by constant
12035 ;; zero are optimized away.
12036 (define_insn "*ashrsi3_cmp"
12037 [(set (reg 17)
12038 (compare
12039 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12040 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12041 (const_int 0)))
12042 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12043 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12044 "ix86_match_ccmode (insn, CCGOCmode)
12045 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12046 "sar{l}\t{%2, %0|%0, %2}"
12047 [(set_attr "type" "ishift")
12048 (set_attr "mode" "SI")])
12049
12050 (define_insn "*ashrsi3_cmp_zext"
12051 [(set (reg 17)
12052 (compare
12053 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12054 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12055 (const_int 0)))
12056 (set (match_operand:DI 0 "register_operand" "=r")
12057 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12058 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12059 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12060 "sar{l}\t{%2, %k0|%k0, %2}"
12061 [(set_attr "type" "ishift")
12062 (set_attr "mode" "SI")])
12063
12064 (define_expand "ashrhi3"
12065 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12066 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12067 (match_operand:QI 2 "nonmemory_operand" "")))
12068 (clobber (reg:CC 17))]
12069 "TARGET_HIMODE_MATH"
12070 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12071
12072 (define_insn "*ashrhi3_1_one_bit"
12073 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12074 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12075 (match_operand:QI 2 "const_int_1_operand" "")))
12076 (clobber (reg:CC 17))]
12077 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12078 && (TARGET_SHIFT1 || optimize_size)"
12079 "sar{w}\t%0"
12080 [(set_attr "type" "ishift")
12081 (set (attr "length")
12082 (if_then_else (match_operand 0 "register_operand" "")
12083 (const_string "2")
12084 (const_string "*")))])
12085
12086 (define_insn "*ashrhi3_1"
12087 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12088 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12089 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12090 (clobber (reg:CC 17))]
12091 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12092 "@
12093 sar{w}\t{%2, %0|%0, %2}
12094 sar{w}\t{%b2, %0|%0, %b2}"
12095 [(set_attr "type" "ishift")
12096 (set_attr "mode" "HI")])
12097
12098 ;; This pattern can't accept a variable shift count, since shifts by
12099 ;; zero don't affect the flags. We assume that shifts by constant
12100 ;; zero are optimized away.
12101 (define_insn "*ashrhi3_one_bit_cmp"
12102 [(set (reg 17)
12103 (compare
12104 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12105 (match_operand:QI 2 "const_int_1_operand" ""))
12106 (const_int 0)))
12107 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12108 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12109 "ix86_match_ccmode (insn, CCGOCmode)
12110 && (TARGET_SHIFT1 || optimize_size)
12111 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12112 "sar{w}\t%0"
12113 [(set_attr "type" "ishift")
12114 (set (attr "length")
12115 (if_then_else (match_operand 0 "register_operand" "")
12116 (const_string "2")
12117 (const_string "*")))])
12118
12119 ;; This pattern can't accept a variable shift count, since shifts by
12120 ;; zero don't affect the flags. We assume that shifts by constant
12121 ;; zero are optimized away.
12122 (define_insn "*ashrhi3_cmp"
12123 [(set (reg 17)
12124 (compare
12125 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12126 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12127 (const_int 0)))
12128 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12129 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12130 "ix86_match_ccmode (insn, CCGOCmode)
12131 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12132 "sar{w}\t{%2, %0|%0, %2}"
12133 [(set_attr "type" "ishift")
12134 (set_attr "mode" "HI")])
12135
12136 (define_expand "ashrqi3"
12137 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12138 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12139 (match_operand:QI 2 "nonmemory_operand" "")))
12140 (clobber (reg:CC 17))]
12141 "TARGET_QIMODE_MATH"
12142 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12143
12144 (define_insn "*ashrqi3_1_one_bit"
12145 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12146 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12147 (match_operand:QI 2 "const_int_1_operand" "")))
12148 (clobber (reg:CC 17))]
12149 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12150 && (TARGET_SHIFT1 || optimize_size)"
12151 "sar{b}\t%0"
12152 [(set_attr "type" "ishift")
12153 (set (attr "length")
12154 (if_then_else (match_operand 0 "register_operand" "")
12155 (const_string "2")
12156 (const_string "*")))])
12157
12158 (define_insn "*ashrqi3_1_one_bit_slp"
12159 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12160 (ashiftrt:QI (match_dup 0)
12161 (match_operand:QI 1 "const_int_1_operand" "")))
12162 (clobber (reg:CC 17))]
12163 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12164 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12165 && (TARGET_SHIFT1 || optimize_size)"
12166 "sar{b}\t%0"
12167 [(set_attr "type" "ishift1")
12168 (set (attr "length")
12169 (if_then_else (match_operand 0 "register_operand" "")
12170 (const_string "2")
12171 (const_string "*")))])
12172
12173 (define_insn "*ashrqi3_1"
12174 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12175 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12176 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12177 (clobber (reg:CC 17))]
12178 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12179 "@
12180 sar{b}\t{%2, %0|%0, %2}
12181 sar{b}\t{%b2, %0|%0, %b2}"
12182 [(set_attr "type" "ishift")
12183 (set_attr "mode" "QI")])
12184
12185 (define_insn "*ashrqi3_1_slp"
12186 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12187 (ashiftrt:QI (match_dup 0)
12188 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12189 (clobber (reg:CC 17))]
12190 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12191 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12192 "@
12193 sar{b}\t{%1, %0|%0, %1}
12194 sar{b}\t{%b1, %0|%0, %b1}"
12195 [(set_attr "type" "ishift1")
12196 (set_attr "mode" "QI")])
12197
12198 ;; This pattern can't accept a variable shift count, since shifts by
12199 ;; zero don't affect the flags. We assume that shifts by constant
12200 ;; zero are optimized away.
12201 (define_insn "*ashrqi3_one_bit_cmp"
12202 [(set (reg 17)
12203 (compare
12204 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12205 (match_operand:QI 2 "const_int_1_operand" "I"))
12206 (const_int 0)))
12207 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12208 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12209 "ix86_match_ccmode (insn, CCGOCmode)
12210 && (TARGET_SHIFT1 || optimize_size)
12211 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12212 "sar{b}\t%0"
12213 [(set_attr "type" "ishift")
12214 (set (attr "length")
12215 (if_then_else (match_operand 0 "register_operand" "")
12216 (const_string "2")
12217 (const_string "*")))])
12218
12219 ;; This pattern can't accept a variable shift count, since shifts by
12220 ;; zero don't affect the flags. We assume that shifts by constant
12221 ;; zero are optimized away.
12222 (define_insn "*ashrqi3_cmp"
12223 [(set (reg 17)
12224 (compare
12225 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12226 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12227 (const_int 0)))
12228 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12229 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12230 "ix86_match_ccmode (insn, CCGOCmode)
12231 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12232 "sar{b}\t{%2, %0|%0, %2}"
12233 [(set_attr "type" "ishift")
12234 (set_attr "mode" "QI")])
12235 \f
12236 ;; Logical shift instructions
12237
12238 ;; See comment above `ashldi3' about how this works.
12239
12240 (define_expand "lshrdi3"
12241 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12242 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12243 (match_operand:QI 2 "nonmemory_operand" "")))
12244 (clobber (reg:CC 17))])]
12245 ""
12246 {
12247 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12248 {
12249 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12250 DONE;
12251 }
12252 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12253 DONE;
12254 })
12255
12256 (define_insn "*lshrdi3_1_one_bit_rex64"
12257 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12258 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12259 (match_operand:QI 2 "const_int_1_operand" "")))
12260 (clobber (reg:CC 17))]
12261 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12262 && (TARGET_SHIFT1 || optimize_size)"
12263 "shr{q}\t%0"
12264 [(set_attr "type" "ishift")
12265 (set (attr "length")
12266 (if_then_else (match_operand:DI 0 "register_operand" "")
12267 (const_string "2")
12268 (const_string "*")))])
12269
12270 (define_insn "*lshrdi3_1_rex64"
12271 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12272 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12273 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12274 (clobber (reg:CC 17))]
12275 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12276 "@
12277 shr{q}\t{%2, %0|%0, %2}
12278 shr{q}\t{%b2, %0|%0, %b2}"
12279 [(set_attr "type" "ishift")
12280 (set_attr "mode" "DI")])
12281
12282 ;; This pattern can't accept a variable shift count, since shifts by
12283 ;; zero don't affect the flags. We assume that shifts by constant
12284 ;; zero are optimized away.
12285 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12286 [(set (reg 17)
12287 (compare
12288 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12289 (match_operand:QI 2 "const_int_1_operand" ""))
12290 (const_int 0)))
12291 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12292 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12293 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12294 && (TARGET_SHIFT1 || optimize_size)
12295 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12296 "shr{q}\t%0"
12297 [(set_attr "type" "ishift")
12298 (set (attr "length")
12299 (if_then_else (match_operand:DI 0 "register_operand" "")
12300 (const_string "2")
12301 (const_string "*")))])
12302
12303 ;; This pattern can't accept a variable shift count, since shifts by
12304 ;; zero don't affect the flags. We assume that shifts by constant
12305 ;; zero are optimized away.
12306 (define_insn "*lshrdi3_cmp_rex64"
12307 [(set (reg 17)
12308 (compare
12309 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12310 (match_operand:QI 2 "const_int_operand" "e"))
12311 (const_int 0)))
12312 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12313 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12314 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12315 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12316 "shr{q}\t{%2, %0|%0, %2}"
12317 [(set_attr "type" "ishift")
12318 (set_attr "mode" "DI")])
12319
12320 (define_insn "lshrdi3_1"
12321 [(set (match_operand:DI 0 "register_operand" "=r")
12322 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12323 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12324 (clobber (match_scratch:SI 3 "=&r"))
12325 (clobber (reg:CC 17))]
12326 "!TARGET_64BIT && TARGET_CMOVE"
12327 "#"
12328 [(set_attr "type" "multi")])
12329
12330 (define_insn "*lshrdi3_2"
12331 [(set (match_operand:DI 0 "register_operand" "=r")
12332 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12333 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12334 (clobber (reg:CC 17))]
12335 "!TARGET_64BIT"
12336 "#"
12337 [(set_attr "type" "multi")])
12338
12339 (define_split
12340 [(set (match_operand:DI 0 "register_operand" "")
12341 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12342 (match_operand:QI 2 "nonmemory_operand" "")))
12343 (clobber (match_scratch:SI 3 ""))
12344 (clobber (reg:CC 17))]
12345 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12346 [(const_int 0)]
12347 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12348
12349 (define_split
12350 [(set (match_operand:DI 0 "register_operand" "")
12351 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12352 (match_operand:QI 2 "nonmemory_operand" "")))
12353 (clobber (reg:CC 17))]
12354 "!TARGET_64BIT && reload_completed"
12355 [(const_int 0)]
12356 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12357
12358 (define_expand "lshrsi3"
12359 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12360 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12361 (match_operand:QI 2 "nonmemory_operand" "")))
12362 (clobber (reg:CC 17))]
12363 ""
12364 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12365
12366 (define_insn "*lshrsi3_1_one_bit"
12367 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12368 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12369 (match_operand:QI 2 "const_int_1_operand" "")))
12370 (clobber (reg:CC 17))]
12371 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12372 && (TARGET_SHIFT1 || optimize_size)"
12373 "shr{l}\t%0"
12374 [(set_attr "type" "ishift")
12375 (set (attr "length")
12376 (if_then_else (match_operand:SI 0 "register_operand" "")
12377 (const_string "2")
12378 (const_string "*")))])
12379
12380 (define_insn "*lshrsi3_1_one_bit_zext"
12381 [(set (match_operand:DI 0 "register_operand" "=r")
12382 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12383 (match_operand:QI 2 "const_int_1_operand" "")))
12384 (clobber (reg:CC 17))]
12385 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12386 && (TARGET_SHIFT1 || optimize_size)"
12387 "shr{l}\t%k0"
12388 [(set_attr "type" "ishift")
12389 (set_attr "length" "2")])
12390
12391 (define_insn "*lshrsi3_1"
12392 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12393 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12394 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395 (clobber (reg:CC 17))]
12396 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12397 "@
12398 shr{l}\t{%2, %0|%0, %2}
12399 shr{l}\t{%b2, %0|%0, %b2}"
12400 [(set_attr "type" "ishift")
12401 (set_attr "mode" "SI")])
12402
12403 (define_insn "*lshrsi3_1_zext"
12404 [(set (match_operand:DI 0 "register_operand" "=r,r")
12405 (zero_extend:DI
12406 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12407 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12408 (clobber (reg:CC 17))]
12409 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12410 "@
12411 shr{l}\t{%2, %k0|%k0, %2}
12412 shr{l}\t{%b2, %k0|%k0, %b2}"
12413 [(set_attr "type" "ishift")
12414 (set_attr "mode" "SI")])
12415
12416 ;; This pattern can't accept a variable shift count, since shifts by
12417 ;; zero don't affect the flags. We assume that shifts by constant
12418 ;; zero are optimized away.
12419 (define_insn "*lshrsi3_one_bit_cmp"
12420 [(set (reg 17)
12421 (compare
12422 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12423 (match_operand:QI 2 "const_int_1_operand" ""))
12424 (const_int 0)))
12425 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12426 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12427 "ix86_match_ccmode (insn, CCGOCmode)
12428 && (TARGET_SHIFT1 || optimize_size)
12429 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12430 "shr{l}\t%0"
12431 [(set_attr "type" "ishift")
12432 (set (attr "length")
12433 (if_then_else (match_operand:SI 0 "register_operand" "")
12434 (const_string "2")
12435 (const_string "*")))])
12436
12437 (define_insn "*lshrsi3_cmp_one_bit_zext"
12438 [(set (reg 17)
12439 (compare
12440 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12441 (match_operand:QI 2 "const_int_1_operand" ""))
12442 (const_int 0)))
12443 (set (match_operand:DI 0 "register_operand" "=r")
12444 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12445 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12446 && (TARGET_SHIFT1 || optimize_size)
12447 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12448 "shr{l}\t%k0"
12449 [(set_attr "type" "ishift")
12450 (set_attr "length" "2")])
12451
12452 ;; This pattern can't accept a variable shift count, since shifts by
12453 ;; zero don't affect the flags. We assume that shifts by constant
12454 ;; zero are optimized away.
12455 (define_insn "*lshrsi3_cmp"
12456 [(set (reg 17)
12457 (compare
12458 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12459 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12460 (const_int 0)))
12461 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12462 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12463 "ix86_match_ccmode (insn, CCGOCmode)
12464 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12465 "shr{l}\t{%2, %0|%0, %2}"
12466 [(set_attr "type" "ishift")
12467 (set_attr "mode" "SI")])
12468
12469 (define_insn "*lshrsi3_cmp_zext"
12470 [(set (reg 17)
12471 (compare
12472 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12473 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12474 (const_int 0)))
12475 (set (match_operand:DI 0 "register_operand" "=r")
12476 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12477 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12478 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12479 "shr{l}\t{%2, %k0|%k0, %2}"
12480 [(set_attr "type" "ishift")
12481 (set_attr "mode" "SI")])
12482
12483 (define_expand "lshrhi3"
12484 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12485 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12486 (match_operand:QI 2 "nonmemory_operand" "")))
12487 (clobber (reg:CC 17))]
12488 "TARGET_HIMODE_MATH"
12489 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12490
12491 (define_insn "*lshrhi3_1_one_bit"
12492 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12493 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12494 (match_operand:QI 2 "const_int_1_operand" "")))
12495 (clobber (reg:CC 17))]
12496 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12497 && (TARGET_SHIFT1 || optimize_size)"
12498 "shr{w}\t%0"
12499 [(set_attr "type" "ishift")
12500 (set (attr "length")
12501 (if_then_else (match_operand 0 "register_operand" "")
12502 (const_string "2")
12503 (const_string "*")))])
12504
12505 (define_insn "*lshrhi3_1"
12506 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12507 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12508 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12509 (clobber (reg:CC 17))]
12510 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12511 "@
12512 shr{w}\t{%2, %0|%0, %2}
12513 shr{w}\t{%b2, %0|%0, %b2}"
12514 [(set_attr "type" "ishift")
12515 (set_attr "mode" "HI")])
12516
12517 ;; This pattern can't accept a variable shift count, since shifts by
12518 ;; zero don't affect the flags. We assume that shifts by constant
12519 ;; zero are optimized away.
12520 (define_insn "*lshrhi3_one_bit_cmp"
12521 [(set (reg 17)
12522 (compare
12523 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12524 (match_operand:QI 2 "const_int_1_operand" ""))
12525 (const_int 0)))
12526 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12527 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12528 "ix86_match_ccmode (insn, CCGOCmode)
12529 && (TARGET_SHIFT1 || optimize_size)
12530 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12531 "shr{w}\t%0"
12532 [(set_attr "type" "ishift")
12533 (set (attr "length")
12534 (if_then_else (match_operand:SI 0 "register_operand" "")
12535 (const_string "2")
12536 (const_string "*")))])
12537
12538 ;; This pattern can't accept a variable shift count, since shifts by
12539 ;; zero don't affect the flags. We assume that shifts by constant
12540 ;; zero are optimized away.
12541 (define_insn "*lshrhi3_cmp"
12542 [(set (reg 17)
12543 (compare
12544 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12545 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12546 (const_int 0)))
12547 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12548 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12549 "ix86_match_ccmode (insn, CCGOCmode)
12550 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12551 "shr{w}\t{%2, %0|%0, %2}"
12552 [(set_attr "type" "ishift")
12553 (set_attr "mode" "HI")])
12554
12555 (define_expand "lshrqi3"
12556 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12557 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12558 (match_operand:QI 2 "nonmemory_operand" "")))
12559 (clobber (reg:CC 17))]
12560 "TARGET_QIMODE_MATH"
12561 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12562
12563 (define_insn "*lshrqi3_1_one_bit"
12564 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12565 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12566 (match_operand:QI 2 "const_int_1_operand" "")))
12567 (clobber (reg:CC 17))]
12568 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12569 && (TARGET_SHIFT1 || optimize_size)"
12570 "shr{b}\t%0"
12571 [(set_attr "type" "ishift")
12572 (set (attr "length")
12573 (if_then_else (match_operand 0 "register_operand" "")
12574 (const_string "2")
12575 (const_string "*")))])
12576
12577 (define_insn "*lshrqi3_1_one_bit_slp"
12578 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12579 (lshiftrt:QI (match_dup 0)
12580 (match_operand:QI 1 "const_int_1_operand" "")))
12581 (clobber (reg:CC 17))]
12582 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12583 && (TARGET_SHIFT1 || optimize_size)"
12584 "shr{b}\t%0"
12585 [(set_attr "type" "ishift1")
12586 (set (attr "length")
12587 (if_then_else (match_operand 0 "register_operand" "")
12588 (const_string "2")
12589 (const_string "*")))])
12590
12591 (define_insn "*lshrqi3_1"
12592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12593 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12594 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12595 (clobber (reg:CC 17))]
12596 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12597 "@
12598 shr{b}\t{%2, %0|%0, %2}
12599 shr{b}\t{%b2, %0|%0, %b2}"
12600 [(set_attr "type" "ishift")
12601 (set_attr "mode" "QI")])
12602
12603 (define_insn "*lshrqi3_1_slp"
12604 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12605 (lshiftrt:QI (match_dup 0)
12606 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12607 (clobber (reg:CC 17))]
12608 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12609 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12610 "@
12611 shr{b}\t{%1, %0|%0, %1}
12612 shr{b}\t{%b1, %0|%0, %b1}"
12613 [(set_attr "type" "ishift1")
12614 (set_attr "mode" "QI")])
12615
12616 ;; This pattern can't accept a variable shift count, since shifts by
12617 ;; zero don't affect the flags. We assume that shifts by constant
12618 ;; zero are optimized away.
12619 (define_insn "*lshrqi2_one_bit_cmp"
12620 [(set (reg 17)
12621 (compare
12622 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12623 (match_operand:QI 2 "const_int_1_operand" ""))
12624 (const_int 0)))
12625 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12626 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12627 "ix86_match_ccmode (insn, CCGOCmode)
12628 && (TARGET_SHIFT1 || optimize_size)
12629 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12630 "shr{b}\t%0"
12631 [(set_attr "type" "ishift")
12632 (set (attr "length")
12633 (if_then_else (match_operand:SI 0 "register_operand" "")
12634 (const_string "2")
12635 (const_string "*")))])
12636
12637 ;; This pattern can't accept a variable shift count, since shifts by
12638 ;; zero don't affect the flags. We assume that shifts by constant
12639 ;; zero are optimized away.
12640 (define_insn "*lshrqi2_cmp"
12641 [(set (reg 17)
12642 (compare
12643 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12644 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12645 (const_int 0)))
12646 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12647 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12648 "ix86_match_ccmode (insn, CCGOCmode)
12649 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12650 "shr{b}\t{%2, %0|%0, %2}"
12651 [(set_attr "type" "ishift")
12652 (set_attr "mode" "QI")])
12653 \f
12654 ;; Rotate instructions
12655
12656 (define_expand "rotldi3"
12657 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12658 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12659 (match_operand:QI 2 "nonmemory_operand" "")))
12660 (clobber (reg:CC 17))]
12661 "TARGET_64BIT"
12662 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12663
12664 (define_insn "*rotlsi3_1_one_bit_rex64"
12665 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12666 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12667 (match_operand:QI 2 "const_int_1_operand" "")))
12668 (clobber (reg:CC 17))]
12669 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12670 && (TARGET_SHIFT1 || optimize_size)"
12671 "rol{q}\t%0"
12672 [(set_attr "type" "rotate")
12673 (set (attr "length")
12674 (if_then_else (match_operand:DI 0 "register_operand" "")
12675 (const_string "2")
12676 (const_string "*")))])
12677
12678 (define_insn "*rotldi3_1_rex64"
12679 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12680 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12681 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12682 (clobber (reg:CC 17))]
12683 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12684 "@
12685 rol{q}\t{%2, %0|%0, %2}
12686 rol{q}\t{%b2, %0|%0, %b2}"
12687 [(set_attr "type" "rotate")
12688 (set_attr "mode" "DI")])
12689
12690 (define_expand "rotlsi3"
12691 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12692 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12693 (match_operand:QI 2 "nonmemory_operand" "")))
12694 (clobber (reg:CC 17))]
12695 ""
12696 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12697
12698 (define_insn "*rotlsi3_1_one_bit"
12699 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12700 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12701 (match_operand:QI 2 "const_int_1_operand" "")))
12702 (clobber (reg:CC 17))]
12703 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12704 && (TARGET_SHIFT1 || optimize_size)"
12705 "rol{l}\t%0"
12706 [(set_attr "type" "rotate")
12707 (set (attr "length")
12708 (if_then_else (match_operand:SI 0 "register_operand" "")
12709 (const_string "2")
12710 (const_string "*")))])
12711
12712 (define_insn "*rotlsi3_1_one_bit_zext"
12713 [(set (match_operand:DI 0 "register_operand" "=r")
12714 (zero_extend:DI
12715 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12716 (match_operand:QI 2 "const_int_1_operand" ""))))
12717 (clobber (reg:CC 17))]
12718 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12719 && (TARGET_SHIFT1 || optimize_size)"
12720 "rol{l}\t%k0"
12721 [(set_attr "type" "rotate")
12722 (set_attr "length" "2")])
12723
12724 (define_insn "*rotlsi3_1"
12725 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12726 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12727 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12728 (clobber (reg:CC 17))]
12729 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12730 "@
12731 rol{l}\t{%2, %0|%0, %2}
12732 rol{l}\t{%b2, %0|%0, %b2}"
12733 [(set_attr "type" "rotate")
12734 (set_attr "mode" "SI")])
12735
12736 (define_insn "*rotlsi3_1_zext"
12737 [(set (match_operand:DI 0 "register_operand" "=r,r")
12738 (zero_extend:DI
12739 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12740 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12741 (clobber (reg:CC 17))]
12742 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12743 "@
12744 rol{l}\t{%2, %k0|%k0, %2}
12745 rol{l}\t{%b2, %k0|%k0, %b2}"
12746 [(set_attr "type" "rotate")
12747 (set_attr "mode" "SI")])
12748
12749 (define_expand "rotlhi3"
12750 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12751 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12752 (match_operand:QI 2 "nonmemory_operand" "")))
12753 (clobber (reg:CC 17))]
12754 "TARGET_HIMODE_MATH"
12755 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12756
12757 (define_insn "*rotlhi3_1_one_bit"
12758 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12759 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12760 (match_operand:QI 2 "const_int_1_operand" "")))
12761 (clobber (reg:CC 17))]
12762 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12763 && (TARGET_SHIFT1 || optimize_size)"
12764 "rol{w}\t%0"
12765 [(set_attr "type" "rotate")
12766 (set (attr "length")
12767 (if_then_else (match_operand 0 "register_operand" "")
12768 (const_string "2")
12769 (const_string "*")))])
12770
12771 (define_insn "*rotlhi3_1"
12772 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12773 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12774 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12775 (clobber (reg:CC 17))]
12776 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12777 "@
12778 rol{w}\t{%2, %0|%0, %2}
12779 rol{w}\t{%b2, %0|%0, %b2}"
12780 [(set_attr "type" "rotate")
12781 (set_attr "mode" "HI")])
12782
12783 (define_expand "rotlqi3"
12784 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12785 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12786 (match_operand:QI 2 "nonmemory_operand" "")))
12787 (clobber (reg:CC 17))]
12788 "TARGET_QIMODE_MATH"
12789 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12790
12791 (define_insn "*rotlqi3_1_one_bit_slp"
12792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12793 (rotate:QI (match_dup 0)
12794 (match_operand:QI 1 "const_int_1_operand" "")))
12795 (clobber (reg:CC 17))]
12796 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12797 && (TARGET_SHIFT1 || optimize_size)"
12798 "rol{b}\t%0"
12799 [(set_attr "type" "rotate1")
12800 (set (attr "length")
12801 (if_then_else (match_operand 0 "register_operand" "")
12802 (const_string "2")
12803 (const_string "*")))])
12804
12805 (define_insn "*rotlqi3_1_one_bit"
12806 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12807 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12808 (match_operand:QI 2 "const_int_1_operand" "")))
12809 (clobber (reg:CC 17))]
12810 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12811 && (TARGET_SHIFT1 || optimize_size)"
12812 "rol{b}\t%0"
12813 [(set_attr "type" "rotate")
12814 (set (attr "length")
12815 (if_then_else (match_operand 0 "register_operand" "")
12816 (const_string "2")
12817 (const_string "*")))])
12818
12819 (define_insn "*rotlqi3_1_slp"
12820 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12821 (rotate:QI (match_dup 0)
12822 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12823 (clobber (reg:CC 17))]
12824 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12825 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12826 "@
12827 rol{b}\t{%1, %0|%0, %1}
12828 rol{b}\t{%b1, %0|%0, %b1}"
12829 [(set_attr "type" "rotate1")
12830 (set_attr "mode" "QI")])
12831
12832 (define_insn "*rotlqi3_1"
12833 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12834 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12835 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12836 (clobber (reg:CC 17))]
12837 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12838 "@
12839 rol{b}\t{%2, %0|%0, %2}
12840 rol{b}\t{%b2, %0|%0, %b2}"
12841 [(set_attr "type" "rotate")
12842 (set_attr "mode" "QI")])
12843
12844 (define_expand "rotrdi3"
12845 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12846 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12847 (match_operand:QI 2 "nonmemory_operand" "")))
12848 (clobber (reg:CC 17))]
12849 "TARGET_64BIT"
12850 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12851
12852 (define_insn "*rotrdi3_1_one_bit_rex64"
12853 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12854 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12855 (match_operand:QI 2 "const_int_1_operand" "")))
12856 (clobber (reg:CC 17))]
12857 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12858 && (TARGET_SHIFT1 || optimize_size)"
12859 "ror{q}\t%0"
12860 [(set_attr "type" "rotate")
12861 (set (attr "length")
12862 (if_then_else (match_operand:DI 0 "register_operand" "")
12863 (const_string "2")
12864 (const_string "*")))])
12865
12866 (define_insn "*rotrdi3_1_rex64"
12867 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12868 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12869 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12870 (clobber (reg:CC 17))]
12871 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12872 "@
12873 ror{q}\t{%2, %0|%0, %2}
12874 ror{q}\t{%b2, %0|%0, %b2}"
12875 [(set_attr "type" "rotate")
12876 (set_attr "mode" "DI")])
12877
12878 (define_expand "rotrsi3"
12879 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12880 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12881 (match_operand:QI 2 "nonmemory_operand" "")))
12882 (clobber (reg:CC 17))]
12883 ""
12884 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12885
12886 (define_insn "*rotrsi3_1_one_bit"
12887 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12888 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12889 (match_operand:QI 2 "const_int_1_operand" "")))
12890 (clobber (reg:CC 17))]
12891 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12892 && (TARGET_SHIFT1 || optimize_size)"
12893 "ror{l}\t%0"
12894 [(set_attr "type" "rotate")
12895 (set (attr "length")
12896 (if_then_else (match_operand:SI 0 "register_operand" "")
12897 (const_string "2")
12898 (const_string "*")))])
12899
12900 (define_insn "*rotrsi3_1_one_bit_zext"
12901 [(set (match_operand:DI 0 "register_operand" "=r")
12902 (zero_extend:DI
12903 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12904 (match_operand:QI 2 "const_int_1_operand" ""))))
12905 (clobber (reg:CC 17))]
12906 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12907 && (TARGET_SHIFT1 || optimize_size)"
12908 "ror{l}\t%k0"
12909 [(set_attr "type" "rotate")
12910 (set (attr "length")
12911 (if_then_else (match_operand:SI 0 "register_operand" "")
12912 (const_string "2")
12913 (const_string "*")))])
12914
12915 (define_insn "*rotrsi3_1"
12916 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12917 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12918 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12919 (clobber (reg:CC 17))]
12920 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12921 "@
12922 ror{l}\t{%2, %0|%0, %2}
12923 ror{l}\t{%b2, %0|%0, %b2}"
12924 [(set_attr "type" "rotate")
12925 (set_attr "mode" "SI")])
12926
12927 (define_insn "*rotrsi3_1_zext"
12928 [(set (match_operand:DI 0 "register_operand" "=r,r")
12929 (zero_extend:DI
12930 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12931 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12932 (clobber (reg:CC 17))]
12933 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12934 "@
12935 ror{l}\t{%2, %k0|%k0, %2}
12936 ror{l}\t{%b2, %k0|%k0, %b2}"
12937 [(set_attr "type" "rotate")
12938 (set_attr "mode" "SI")])
12939
12940 (define_expand "rotrhi3"
12941 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12942 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12943 (match_operand:QI 2 "nonmemory_operand" "")))
12944 (clobber (reg:CC 17))]
12945 "TARGET_HIMODE_MATH"
12946 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12947
12948 (define_insn "*rotrhi3_one_bit"
12949 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12950 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12951 (match_operand:QI 2 "const_int_1_operand" "")))
12952 (clobber (reg:CC 17))]
12953 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12954 && (TARGET_SHIFT1 || optimize_size)"
12955 "ror{w}\t%0"
12956 [(set_attr "type" "rotate")
12957 (set (attr "length")
12958 (if_then_else (match_operand 0 "register_operand" "")
12959 (const_string "2")
12960 (const_string "*")))])
12961
12962 (define_insn "*rotrhi3"
12963 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12964 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12965 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12966 (clobber (reg:CC 17))]
12967 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12968 "@
12969 ror{w}\t{%2, %0|%0, %2}
12970 ror{w}\t{%b2, %0|%0, %b2}"
12971 [(set_attr "type" "rotate")
12972 (set_attr "mode" "HI")])
12973
12974 (define_expand "rotrqi3"
12975 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12976 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12977 (match_operand:QI 2 "nonmemory_operand" "")))
12978 (clobber (reg:CC 17))]
12979 "TARGET_QIMODE_MATH"
12980 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12981
12982 (define_insn "*rotrqi3_1_one_bit"
12983 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12984 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12985 (match_operand:QI 2 "const_int_1_operand" "")))
12986 (clobber (reg:CC 17))]
12987 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12988 && (TARGET_SHIFT1 || optimize_size)"
12989 "ror{b}\t%0"
12990 [(set_attr "type" "rotate")
12991 (set (attr "length")
12992 (if_then_else (match_operand 0 "register_operand" "")
12993 (const_string "2")
12994 (const_string "*")))])
12995
12996 (define_insn "*rotrqi3_1_one_bit_slp"
12997 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12998 (rotatert:QI (match_dup 0)
12999 (match_operand:QI 1 "const_int_1_operand" "")))
13000 (clobber (reg:CC 17))]
13001 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13002 && (TARGET_SHIFT1 || optimize_size)"
13003 "ror{b}\t%0"
13004 [(set_attr "type" "rotate1")
13005 (set (attr "length")
13006 (if_then_else (match_operand 0 "register_operand" "")
13007 (const_string "2")
13008 (const_string "*")))])
13009
13010 (define_insn "*rotrqi3_1"
13011 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13012 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13013 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13014 (clobber (reg:CC 17))]
13015 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13016 "@
13017 ror{b}\t{%2, %0|%0, %2}
13018 ror{b}\t{%b2, %0|%0, %b2}"
13019 [(set_attr "type" "rotate")
13020 (set_attr "mode" "QI")])
13021
13022 (define_insn "*rotrqi3_1_slp"
13023 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13024 (rotatert:QI (match_dup 0)
13025 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13026 (clobber (reg:CC 17))]
13027 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13028 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13029 "@
13030 ror{b}\t{%1, %0|%0, %1}
13031 ror{b}\t{%b1, %0|%0, %b1}"
13032 [(set_attr "type" "rotate1")
13033 (set_attr "mode" "QI")])
13034 \f
13035 ;; Bit set / bit test instructions
13036
13037 (define_expand "extv"
13038 [(set (match_operand:SI 0 "register_operand" "")
13039 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13040 (match_operand:SI 2 "immediate_operand" "")
13041 (match_operand:SI 3 "immediate_operand" "")))]
13042 ""
13043 {
13044 /* Handle extractions from %ah et al. */
13045 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13046 FAIL;
13047
13048 /* From mips.md: extract_bit_field doesn't verify that our source
13049 matches the predicate, so check it again here. */
13050 if (! register_operand (operands[1], VOIDmode))
13051 FAIL;
13052 })
13053
13054 (define_expand "extzv"
13055 [(set (match_operand:SI 0 "register_operand" "")
13056 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13057 (match_operand:SI 2 "immediate_operand" "")
13058 (match_operand:SI 3 "immediate_operand" "")))]
13059 ""
13060 {
13061 /* Handle extractions from %ah et al. */
13062 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13063 FAIL;
13064
13065 /* From mips.md: extract_bit_field doesn't verify that our source
13066 matches the predicate, so check it again here. */
13067 if (! register_operand (operands[1], VOIDmode))
13068 FAIL;
13069 })
13070
13071 (define_expand "insv"
13072 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13073 (match_operand:SI 1 "immediate_operand" "")
13074 (match_operand:SI 2 "immediate_operand" ""))
13075 (match_operand:SI 3 "register_operand" ""))]
13076 ""
13077 {
13078 /* Handle extractions from %ah et al. */
13079 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13080 FAIL;
13081
13082 /* From mips.md: insert_bit_field doesn't verify that our source
13083 matches the predicate, so check it again here. */
13084 if (! register_operand (operands[0], VOIDmode))
13085 FAIL;
13086 })
13087
13088 ;; %%% bts, btr, btc, bt.
13089 \f
13090 ;; Store-flag instructions.
13091
13092 ;; For all sCOND expanders, also expand the compare or test insn that
13093 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13094
13095 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13096 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13097 ;; way, which can later delete the movzx if only QImode is needed.
13098
13099 (define_expand "seq"
13100 [(set (match_operand:QI 0 "register_operand" "")
13101 (eq:QI (reg:CC 17) (const_int 0)))]
13102 ""
13103 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13104
13105 (define_expand "sne"
13106 [(set (match_operand:QI 0 "register_operand" "")
13107 (ne:QI (reg:CC 17) (const_int 0)))]
13108 ""
13109 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13110
13111 (define_expand "sgt"
13112 [(set (match_operand:QI 0 "register_operand" "")
13113 (gt:QI (reg:CC 17) (const_int 0)))]
13114 ""
13115 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13116
13117 (define_expand "sgtu"
13118 [(set (match_operand:QI 0 "register_operand" "")
13119 (gtu:QI (reg:CC 17) (const_int 0)))]
13120 ""
13121 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13122
13123 (define_expand "slt"
13124 [(set (match_operand:QI 0 "register_operand" "")
13125 (lt:QI (reg:CC 17) (const_int 0)))]
13126 ""
13127 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13128
13129 (define_expand "sltu"
13130 [(set (match_operand:QI 0 "register_operand" "")
13131 (ltu:QI (reg:CC 17) (const_int 0)))]
13132 ""
13133 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13134
13135 (define_expand "sge"
13136 [(set (match_operand:QI 0 "register_operand" "")
13137 (ge:QI (reg:CC 17) (const_int 0)))]
13138 ""
13139 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13140
13141 (define_expand "sgeu"
13142 [(set (match_operand:QI 0 "register_operand" "")
13143 (geu:QI (reg:CC 17) (const_int 0)))]
13144 ""
13145 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13146
13147 (define_expand "sle"
13148 [(set (match_operand:QI 0 "register_operand" "")
13149 (le:QI (reg:CC 17) (const_int 0)))]
13150 ""
13151 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13152
13153 (define_expand "sleu"
13154 [(set (match_operand:QI 0 "register_operand" "")
13155 (leu:QI (reg:CC 17) (const_int 0)))]
13156 ""
13157 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13158
13159 (define_expand "sunordered"
13160 [(set (match_operand:QI 0 "register_operand" "")
13161 (unordered:QI (reg:CC 17) (const_int 0)))]
13162 "TARGET_80387 || TARGET_SSE"
13163 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13164
13165 (define_expand "sordered"
13166 [(set (match_operand:QI 0 "register_operand" "")
13167 (ordered:QI (reg:CC 17) (const_int 0)))]
13168 "TARGET_80387"
13169 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13170
13171 (define_expand "suneq"
13172 [(set (match_operand:QI 0 "register_operand" "")
13173 (uneq:QI (reg:CC 17) (const_int 0)))]
13174 "TARGET_80387 || TARGET_SSE"
13175 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13176
13177 (define_expand "sunge"
13178 [(set (match_operand:QI 0 "register_operand" "")
13179 (unge:QI (reg:CC 17) (const_int 0)))]
13180 "TARGET_80387 || TARGET_SSE"
13181 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13182
13183 (define_expand "sungt"
13184 [(set (match_operand:QI 0 "register_operand" "")
13185 (ungt:QI (reg:CC 17) (const_int 0)))]
13186 "TARGET_80387 || TARGET_SSE"
13187 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13188
13189 (define_expand "sunle"
13190 [(set (match_operand:QI 0 "register_operand" "")
13191 (unle:QI (reg:CC 17) (const_int 0)))]
13192 "TARGET_80387 || TARGET_SSE"
13193 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13194
13195 (define_expand "sunlt"
13196 [(set (match_operand:QI 0 "register_operand" "")
13197 (unlt:QI (reg:CC 17) (const_int 0)))]
13198 "TARGET_80387 || TARGET_SSE"
13199 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13200
13201 (define_expand "sltgt"
13202 [(set (match_operand:QI 0 "register_operand" "")
13203 (ltgt:QI (reg:CC 17) (const_int 0)))]
13204 "TARGET_80387 || TARGET_SSE"
13205 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13206
13207 (define_insn "*setcc_1"
13208 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13209 (match_operator:QI 1 "ix86_comparison_operator"
13210 [(reg 17) (const_int 0)]))]
13211 ""
13212 "set%C1\t%0"
13213 [(set_attr "type" "setcc")
13214 (set_attr "mode" "QI")])
13215
13216 (define_insn "setcc_2"
13217 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13218 (match_operator:QI 1 "ix86_comparison_operator"
13219 [(reg 17) (const_int 0)]))]
13220 ""
13221 "set%C1\t%0"
13222 [(set_attr "type" "setcc")
13223 (set_attr "mode" "QI")])
13224
13225 ;; In general it is not safe to assume too much about CCmode registers,
13226 ;; so simplify-rtx stops when it sees a second one. Under certain
13227 ;; conditions this is safe on x86, so help combine not create
13228 ;;
13229 ;; seta %al
13230 ;; testb %al, %al
13231 ;; sete %al
13232
13233 (define_split
13234 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13235 (ne:QI (match_operator 1 "ix86_comparison_operator"
13236 [(reg 17) (const_int 0)])
13237 (const_int 0)))]
13238 ""
13239 [(set (match_dup 0) (match_dup 1))]
13240 {
13241 PUT_MODE (operands[1], QImode);
13242 })
13243
13244 (define_split
13245 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13246 (ne:QI (match_operator 1 "ix86_comparison_operator"
13247 [(reg 17) (const_int 0)])
13248 (const_int 0)))]
13249 ""
13250 [(set (match_dup 0) (match_dup 1))]
13251 {
13252 PUT_MODE (operands[1], QImode);
13253 })
13254
13255 (define_split
13256 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13257 (eq:QI (match_operator 1 "ix86_comparison_operator"
13258 [(reg 17) (const_int 0)])
13259 (const_int 0)))]
13260 ""
13261 [(set (match_dup 0) (match_dup 1))]
13262 {
13263 rtx new_op1 = copy_rtx (operands[1]);
13264 operands[1] = new_op1;
13265 PUT_MODE (new_op1, QImode);
13266 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13267 GET_MODE (XEXP (new_op1, 0))));
13268
13269 /* Make sure that (a) the CCmode we have for the flags is strong
13270 enough for the reversed compare or (b) we have a valid FP compare. */
13271 if (! ix86_comparison_operator (new_op1, VOIDmode))
13272 FAIL;
13273 })
13274
13275 (define_split
13276 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13277 (eq:QI (match_operator 1 "ix86_comparison_operator"
13278 [(reg 17) (const_int 0)])
13279 (const_int 0)))]
13280 ""
13281 [(set (match_dup 0) (match_dup 1))]
13282 {
13283 rtx new_op1 = copy_rtx (operands[1]);
13284 operands[1] = new_op1;
13285 PUT_MODE (new_op1, QImode);
13286 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13287 GET_MODE (XEXP (new_op1, 0))));
13288
13289 /* Make sure that (a) the CCmode we have for the flags is strong
13290 enough for the reversed compare or (b) we have a valid FP compare. */
13291 if (! ix86_comparison_operator (new_op1, VOIDmode))
13292 FAIL;
13293 })
13294
13295 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13296 ;; subsequent logical operations are used to imitate conditional moves.
13297 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13298 ;; it directly. Further holding this value in pseudo register might bring
13299 ;; problem in implicit normalization in spill code.
13300 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13301 ;; instructions after reload by splitting the conditional move patterns.
13302
13303 (define_insn "*sse_setccsf"
13304 [(set (match_operand:SF 0 "register_operand" "=x")
13305 (match_operator:SF 1 "sse_comparison_operator"
13306 [(match_operand:SF 2 "register_operand" "0")
13307 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13308 "TARGET_SSE && reload_completed"
13309 "cmp%D1ss\t{%3, %0|%0, %3}"
13310 [(set_attr "type" "ssecmp")
13311 (set_attr "mode" "SF")])
13312
13313 (define_insn "*sse_setccdf"
13314 [(set (match_operand:DF 0 "register_operand" "=Y")
13315 (match_operator:DF 1 "sse_comparison_operator"
13316 [(match_operand:DF 2 "register_operand" "0")
13317 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13318 "TARGET_SSE2 && reload_completed"
13319 "cmp%D1sd\t{%3, %0|%0, %3}"
13320 [(set_attr "type" "ssecmp")
13321 (set_attr "mode" "DF")])
13322 \f
13323 ;; Basic conditional jump instructions.
13324 ;; We ignore the overflow flag for signed branch instructions.
13325
13326 ;; For all bCOND expanders, also expand the compare or test insn that
13327 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13328
13329 (define_expand "beq"
13330 [(set (pc)
13331 (if_then_else (match_dup 1)
13332 (label_ref (match_operand 0 "" ""))
13333 (pc)))]
13334 ""
13335 "ix86_expand_branch (EQ, operands[0]); DONE;")
13336
13337 (define_expand "bne"
13338 [(set (pc)
13339 (if_then_else (match_dup 1)
13340 (label_ref (match_operand 0 "" ""))
13341 (pc)))]
13342 ""
13343 "ix86_expand_branch (NE, operands[0]); DONE;")
13344
13345 (define_expand "bgt"
13346 [(set (pc)
13347 (if_then_else (match_dup 1)
13348 (label_ref (match_operand 0 "" ""))
13349 (pc)))]
13350 ""
13351 "ix86_expand_branch (GT, operands[0]); DONE;")
13352
13353 (define_expand "bgtu"
13354 [(set (pc)
13355 (if_then_else (match_dup 1)
13356 (label_ref (match_operand 0 "" ""))
13357 (pc)))]
13358 ""
13359 "ix86_expand_branch (GTU, operands[0]); DONE;")
13360
13361 (define_expand "blt"
13362 [(set (pc)
13363 (if_then_else (match_dup 1)
13364 (label_ref (match_operand 0 "" ""))
13365 (pc)))]
13366 ""
13367 "ix86_expand_branch (LT, operands[0]); DONE;")
13368
13369 (define_expand "bltu"
13370 [(set (pc)
13371 (if_then_else (match_dup 1)
13372 (label_ref (match_operand 0 "" ""))
13373 (pc)))]
13374 ""
13375 "ix86_expand_branch (LTU, operands[0]); DONE;")
13376
13377 (define_expand "bge"
13378 [(set (pc)
13379 (if_then_else (match_dup 1)
13380 (label_ref (match_operand 0 "" ""))
13381 (pc)))]
13382 ""
13383 "ix86_expand_branch (GE, operands[0]); DONE;")
13384
13385 (define_expand "bgeu"
13386 [(set (pc)
13387 (if_then_else (match_dup 1)
13388 (label_ref (match_operand 0 "" ""))
13389 (pc)))]
13390 ""
13391 "ix86_expand_branch (GEU, operands[0]); DONE;")
13392
13393 (define_expand "ble"
13394 [(set (pc)
13395 (if_then_else (match_dup 1)
13396 (label_ref (match_operand 0 "" ""))
13397 (pc)))]
13398 ""
13399 "ix86_expand_branch (LE, operands[0]); DONE;")
13400
13401 (define_expand "bleu"
13402 [(set (pc)
13403 (if_then_else (match_dup 1)
13404 (label_ref (match_operand 0 "" ""))
13405 (pc)))]
13406 ""
13407 "ix86_expand_branch (LEU, operands[0]); DONE;")
13408
13409 (define_expand "bunordered"
13410 [(set (pc)
13411 (if_then_else (match_dup 1)
13412 (label_ref (match_operand 0 "" ""))
13413 (pc)))]
13414 "TARGET_80387 || TARGET_SSE"
13415 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13416
13417 (define_expand "bordered"
13418 [(set (pc)
13419 (if_then_else (match_dup 1)
13420 (label_ref (match_operand 0 "" ""))
13421 (pc)))]
13422 "TARGET_80387 || TARGET_SSE"
13423 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13424
13425 (define_expand "buneq"
13426 [(set (pc)
13427 (if_then_else (match_dup 1)
13428 (label_ref (match_operand 0 "" ""))
13429 (pc)))]
13430 "TARGET_80387 || TARGET_SSE"
13431 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13432
13433 (define_expand "bunge"
13434 [(set (pc)
13435 (if_then_else (match_dup 1)
13436 (label_ref (match_operand 0 "" ""))
13437 (pc)))]
13438 "TARGET_80387 || TARGET_SSE"
13439 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13440
13441 (define_expand "bungt"
13442 [(set (pc)
13443 (if_then_else (match_dup 1)
13444 (label_ref (match_operand 0 "" ""))
13445 (pc)))]
13446 "TARGET_80387 || TARGET_SSE"
13447 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13448
13449 (define_expand "bunle"
13450 [(set (pc)
13451 (if_then_else (match_dup 1)
13452 (label_ref (match_operand 0 "" ""))
13453 (pc)))]
13454 "TARGET_80387 || TARGET_SSE"
13455 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13456
13457 (define_expand "bunlt"
13458 [(set (pc)
13459 (if_then_else (match_dup 1)
13460 (label_ref (match_operand 0 "" ""))
13461 (pc)))]
13462 "TARGET_80387 || TARGET_SSE"
13463 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13464
13465 (define_expand "bltgt"
13466 [(set (pc)
13467 (if_then_else (match_dup 1)
13468 (label_ref (match_operand 0 "" ""))
13469 (pc)))]
13470 "TARGET_80387 || TARGET_SSE"
13471 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13472
13473 (define_insn "*jcc_1"
13474 [(set (pc)
13475 (if_then_else (match_operator 1 "ix86_comparison_operator"
13476 [(reg 17) (const_int 0)])
13477 (label_ref (match_operand 0 "" ""))
13478 (pc)))]
13479 ""
13480 "%+j%C1\t%l0"
13481 [(set_attr "type" "ibr")
13482 (set_attr "modrm" "0")
13483 (set (attr "length")
13484 (if_then_else (and (ge (minus (match_dup 0) (pc))
13485 (const_int -126))
13486 (lt (minus (match_dup 0) (pc))
13487 (const_int 128)))
13488 (const_int 2)
13489 (const_int 6)))])
13490
13491 (define_insn "*jcc_2"
13492 [(set (pc)
13493 (if_then_else (match_operator 1 "ix86_comparison_operator"
13494 [(reg 17) (const_int 0)])
13495 (pc)
13496 (label_ref (match_operand 0 "" ""))))]
13497 ""
13498 "%+j%c1\t%l0"
13499 [(set_attr "type" "ibr")
13500 (set_attr "modrm" "0")
13501 (set (attr "length")
13502 (if_then_else (and (ge (minus (match_dup 0) (pc))
13503 (const_int -126))
13504 (lt (minus (match_dup 0) (pc))
13505 (const_int 128)))
13506 (const_int 2)
13507 (const_int 6)))])
13508
13509 ;; In general it is not safe to assume too much about CCmode registers,
13510 ;; so simplify-rtx stops when it sees a second one. Under certain
13511 ;; conditions this is safe on x86, so help combine not create
13512 ;;
13513 ;; seta %al
13514 ;; testb %al, %al
13515 ;; je Lfoo
13516
13517 (define_split
13518 [(set (pc)
13519 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13520 [(reg 17) (const_int 0)])
13521 (const_int 0))
13522 (label_ref (match_operand 1 "" ""))
13523 (pc)))]
13524 ""
13525 [(set (pc)
13526 (if_then_else (match_dup 0)
13527 (label_ref (match_dup 1))
13528 (pc)))]
13529 {
13530 PUT_MODE (operands[0], VOIDmode);
13531 })
13532
13533 (define_split
13534 [(set (pc)
13535 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13536 [(reg 17) (const_int 0)])
13537 (const_int 0))
13538 (label_ref (match_operand 1 "" ""))
13539 (pc)))]
13540 ""
13541 [(set (pc)
13542 (if_then_else (match_dup 0)
13543 (label_ref (match_dup 1))
13544 (pc)))]
13545 {
13546 rtx new_op0 = copy_rtx (operands[0]);
13547 operands[0] = new_op0;
13548 PUT_MODE (new_op0, VOIDmode);
13549 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13550 GET_MODE (XEXP (new_op0, 0))));
13551
13552 /* Make sure that (a) the CCmode we have for the flags is strong
13553 enough for the reversed compare or (b) we have a valid FP compare. */
13554 if (! ix86_comparison_operator (new_op0, VOIDmode))
13555 FAIL;
13556 })
13557
13558 ;; Define combination compare-and-branch fp compare instructions to use
13559 ;; during early optimization. Splitting the operation apart early makes
13560 ;; for bad code when we want to reverse the operation.
13561
13562 (define_insn "*fp_jcc_1"
13563 [(set (pc)
13564 (if_then_else (match_operator 0 "comparison_operator"
13565 [(match_operand 1 "register_operand" "f")
13566 (match_operand 2 "register_operand" "f")])
13567 (label_ref (match_operand 3 "" ""))
13568 (pc)))
13569 (clobber (reg:CCFP 18))
13570 (clobber (reg:CCFP 17))]
13571 "TARGET_CMOVE && TARGET_80387
13572 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13573 && FLOAT_MODE_P (GET_MODE (operands[1]))
13574 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13575 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13576 "#")
13577
13578 (define_insn "*fp_jcc_1_sse"
13579 [(set (pc)
13580 (if_then_else (match_operator 0 "comparison_operator"
13581 [(match_operand 1 "register_operand" "f#x,x#f")
13582 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13583 (label_ref (match_operand 3 "" ""))
13584 (pc)))
13585 (clobber (reg:CCFP 18))
13586 (clobber (reg:CCFP 17))]
13587 "TARGET_80387
13588 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13589 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13590 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13591 "#")
13592
13593 (define_insn "*fp_jcc_1_sse_only"
13594 [(set (pc)
13595 (if_then_else (match_operator 0 "comparison_operator"
13596 [(match_operand 1 "register_operand" "x")
13597 (match_operand 2 "nonimmediate_operand" "xm")])
13598 (label_ref (match_operand 3 "" ""))
13599 (pc)))
13600 (clobber (reg:CCFP 18))
13601 (clobber (reg:CCFP 17))]
13602 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13603 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13604 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13605 "#")
13606
13607 (define_insn "*fp_jcc_2"
13608 [(set (pc)
13609 (if_then_else (match_operator 0 "comparison_operator"
13610 [(match_operand 1 "register_operand" "f")
13611 (match_operand 2 "register_operand" "f")])
13612 (pc)
13613 (label_ref (match_operand 3 "" ""))))
13614 (clobber (reg:CCFP 18))
13615 (clobber (reg:CCFP 17))]
13616 "TARGET_CMOVE && TARGET_80387
13617 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13618 && FLOAT_MODE_P (GET_MODE (operands[1]))
13619 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13620 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13621 "#")
13622
13623 (define_insn "*fp_jcc_2_sse"
13624 [(set (pc)
13625 (if_then_else (match_operator 0 "comparison_operator"
13626 [(match_operand 1 "register_operand" "f#x,x#f")
13627 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13628 (pc)
13629 (label_ref (match_operand 3 "" ""))))
13630 (clobber (reg:CCFP 18))
13631 (clobber (reg:CCFP 17))]
13632 "TARGET_80387
13633 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13634 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13635 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13636 "#")
13637
13638 (define_insn "*fp_jcc_2_sse_only"
13639 [(set (pc)
13640 (if_then_else (match_operator 0 "comparison_operator"
13641 [(match_operand 1 "register_operand" "x")
13642 (match_operand 2 "nonimmediate_operand" "xm")])
13643 (pc)
13644 (label_ref (match_operand 3 "" ""))))
13645 (clobber (reg:CCFP 18))
13646 (clobber (reg:CCFP 17))]
13647 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13648 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13649 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13650 "#")
13651
13652 (define_insn "*fp_jcc_3"
13653 [(set (pc)
13654 (if_then_else (match_operator 0 "comparison_operator"
13655 [(match_operand 1 "register_operand" "f")
13656 (match_operand 2 "nonimmediate_operand" "fm")])
13657 (label_ref (match_operand 3 "" ""))
13658 (pc)))
13659 (clobber (reg:CCFP 18))
13660 (clobber (reg:CCFP 17))
13661 (clobber (match_scratch:HI 4 "=a"))]
13662 "TARGET_80387
13663 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13664 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13665 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13666 && SELECT_CC_MODE (GET_CODE (operands[0]),
13667 operands[1], operands[2]) == CCFPmode
13668 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13669 "#")
13670
13671 (define_insn "*fp_jcc_4"
13672 [(set (pc)
13673 (if_then_else (match_operator 0 "comparison_operator"
13674 [(match_operand 1 "register_operand" "f")
13675 (match_operand 2 "nonimmediate_operand" "fm")])
13676 (pc)
13677 (label_ref (match_operand 3 "" ""))))
13678 (clobber (reg:CCFP 18))
13679 (clobber (reg:CCFP 17))
13680 (clobber (match_scratch:HI 4 "=a"))]
13681 "TARGET_80387
13682 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13683 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13684 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13685 && SELECT_CC_MODE (GET_CODE (operands[0]),
13686 operands[1], operands[2]) == CCFPmode
13687 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13688 "#")
13689
13690 (define_insn "*fp_jcc_5"
13691 [(set (pc)
13692 (if_then_else (match_operator 0 "comparison_operator"
13693 [(match_operand 1 "register_operand" "f")
13694 (match_operand 2 "register_operand" "f")])
13695 (label_ref (match_operand 3 "" ""))
13696 (pc)))
13697 (clobber (reg:CCFP 18))
13698 (clobber (reg:CCFP 17))
13699 (clobber (match_scratch:HI 4 "=a"))]
13700 "TARGET_80387
13701 && FLOAT_MODE_P (GET_MODE (operands[1]))
13702 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13703 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13704 "#")
13705
13706 (define_insn "*fp_jcc_6"
13707 [(set (pc)
13708 (if_then_else (match_operator 0 "comparison_operator"
13709 [(match_operand 1 "register_operand" "f")
13710 (match_operand 2 "register_operand" "f")])
13711 (pc)
13712 (label_ref (match_operand 3 "" ""))))
13713 (clobber (reg:CCFP 18))
13714 (clobber (reg:CCFP 17))
13715 (clobber (match_scratch:HI 4 "=a"))]
13716 "TARGET_80387
13717 && FLOAT_MODE_P (GET_MODE (operands[1]))
13718 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13719 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13720 "#")
13721
13722 (define_split
13723 [(set (pc)
13724 (if_then_else (match_operator 0 "comparison_operator"
13725 [(match_operand 1 "register_operand" "")
13726 (match_operand 2 "nonimmediate_operand" "")])
13727 (match_operand 3 "" "")
13728 (match_operand 4 "" "")))
13729 (clobber (reg:CCFP 18))
13730 (clobber (reg:CCFP 17))]
13731 "reload_completed"
13732 [(const_int 0)]
13733 {
13734 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13735 operands[3], operands[4], NULL_RTX);
13736 DONE;
13737 })
13738
13739 (define_split
13740 [(set (pc)
13741 (if_then_else (match_operator 0 "comparison_operator"
13742 [(match_operand 1 "register_operand" "")
13743 (match_operand 2 "nonimmediate_operand" "")])
13744 (match_operand 3 "" "")
13745 (match_operand 4 "" "")))
13746 (clobber (reg:CCFP 18))
13747 (clobber (reg:CCFP 17))
13748 (clobber (match_scratch:HI 5 "=a"))]
13749 "reload_completed"
13750 [(set (pc)
13751 (if_then_else (match_dup 6)
13752 (match_dup 3)
13753 (match_dup 4)))]
13754 {
13755 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13756 operands[3], operands[4], operands[5]);
13757 DONE;
13758 })
13759 \f
13760 ;; Unconditional and other jump instructions
13761
13762 (define_insn "jump"
13763 [(set (pc)
13764 (label_ref (match_operand 0 "" "")))]
13765 ""
13766 "jmp\t%l0"
13767 [(set_attr "type" "ibr")
13768 (set (attr "length")
13769 (if_then_else (and (ge (minus (match_dup 0) (pc))
13770 (const_int -126))
13771 (lt (minus (match_dup 0) (pc))
13772 (const_int 128)))
13773 (const_int 2)
13774 (const_int 5)))
13775 (set_attr "modrm" "0")])
13776
13777 (define_expand "indirect_jump"
13778 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13779 ""
13780 "")
13781
13782 (define_insn "*indirect_jump"
13783 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13784 "!TARGET_64BIT"
13785 "jmp\t%A0"
13786 [(set_attr "type" "ibr")
13787 (set_attr "length_immediate" "0")])
13788
13789 (define_insn "*indirect_jump_rtx64"
13790 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13791 "TARGET_64BIT"
13792 "jmp\t%A0"
13793 [(set_attr "type" "ibr")
13794 (set_attr "length_immediate" "0")])
13795
13796 (define_expand "tablejump"
13797 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13798 (use (label_ref (match_operand 1 "" "")))])]
13799 ""
13800 {
13801 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13802 relative. Convert the relative address to an absolute address. */
13803 if (flag_pic)
13804 {
13805 rtx op0, op1;
13806 enum rtx_code code;
13807
13808 if (TARGET_64BIT)
13809 {
13810 code = PLUS;
13811 op0 = operands[0];
13812 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13813 }
13814 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13815 {
13816 code = PLUS;
13817 op0 = operands[0];
13818 op1 = pic_offset_table_rtx;
13819 }
13820 else
13821 {
13822 code = MINUS;
13823 op0 = pic_offset_table_rtx;
13824 op1 = operands[0];
13825 }
13826
13827 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13828 OPTAB_DIRECT);
13829 }
13830 })
13831
13832 (define_insn "*tablejump_1"
13833 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13834 (use (label_ref (match_operand 1 "" "")))]
13835 "!TARGET_64BIT"
13836 "jmp\t%A0"
13837 [(set_attr "type" "ibr")
13838 (set_attr "length_immediate" "0")])
13839
13840 (define_insn "*tablejump_1_rtx64"
13841 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13842 (use (label_ref (match_operand 1 "" "")))]
13843 "TARGET_64BIT"
13844 "jmp\t%A0"
13845 [(set_attr "type" "ibr")
13846 (set_attr "length_immediate" "0")])
13847 \f
13848 ;; Loop instruction
13849 ;;
13850 ;; This is all complicated by the fact that since this is a jump insn
13851 ;; we must handle our own reloads.
13852
13853 (define_expand "doloop_end"
13854 [(use (match_operand 0 "" "")) ; loop pseudo
13855 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13856 (use (match_operand 2 "" "")) ; max iterations
13857 (use (match_operand 3 "" "")) ; loop level
13858 (use (match_operand 4 "" ""))] ; label
13859 "!TARGET_64BIT && TARGET_USE_LOOP"
13860 "
13861 {
13862 /* Only use cloop on innermost loops. */
13863 if (INTVAL (operands[3]) > 1)
13864 FAIL;
13865 if (GET_MODE (operands[0]) != SImode)
13866 FAIL;
13867 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13868 operands[0]));
13869 DONE;
13870 }")
13871
13872 (define_insn "doloop_end_internal"
13873 [(set (pc)
13874 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13875 (const_int 1))
13876 (label_ref (match_operand 0 "" ""))
13877 (pc)))
13878 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13879 (plus:SI (match_dup 1)
13880 (const_int -1)))
13881 (clobber (match_scratch:SI 3 "=X,X,r"))
13882 (clobber (reg:CC 17))]
13883 "!TARGET_64BIT && TARGET_USE_LOOP"
13884 {
13885 if (which_alternative != 0)
13886 return "#";
13887 if (get_attr_length (insn) == 2)
13888 return "%+loop\t%l0";
13889 else
13890 return "dec{l}\t%1\;%+jne\t%l0";
13891 }
13892 [(set_attr "ppro_uops" "many")
13893 (set (attr "length")
13894 (if_then_else (and (eq_attr "alternative" "0")
13895 (and (ge (minus (match_dup 0) (pc))
13896 (const_int -126))
13897 (lt (minus (match_dup 0) (pc))
13898 (const_int 128))))
13899 (const_int 2)
13900 (const_int 16)))
13901 ;; We don't know the type before shorten branches. Optimistically expect
13902 ;; the loop instruction to match.
13903 (set (attr "type") (const_string "ibr"))])
13904
13905 (define_split
13906 [(set (pc)
13907 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13908 (const_int 1))
13909 (match_operand 0 "" "")
13910 (pc)))
13911 (set (match_dup 1)
13912 (plus:SI (match_dup 1)
13913 (const_int -1)))
13914 (clobber (match_scratch:SI 2 ""))
13915 (clobber (reg:CC 17))]
13916 "!TARGET_64BIT && TARGET_USE_LOOP
13917 && reload_completed
13918 && REGNO (operands[1]) != 2"
13919 [(parallel [(set (reg:CCZ 17)
13920 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13921 (const_int 0)))
13922 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13923 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13924 (match_dup 0)
13925 (pc)))]
13926 "")
13927
13928 (define_split
13929 [(set (pc)
13930 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13931 (const_int 1))
13932 (match_operand 0 "" "")
13933 (pc)))
13934 (set (match_operand:SI 2 "nonimmediate_operand" "")
13935 (plus:SI (match_dup 1)
13936 (const_int -1)))
13937 (clobber (match_scratch:SI 3 ""))
13938 (clobber (reg:CC 17))]
13939 "!TARGET_64BIT && TARGET_USE_LOOP
13940 && reload_completed
13941 && (! REG_P (operands[2])
13942 || ! rtx_equal_p (operands[1], operands[2]))"
13943 [(set (match_dup 3) (match_dup 1))
13944 (parallel [(set (reg:CCZ 17)
13945 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13946 (const_int 0)))
13947 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13948 (set (match_dup 2) (match_dup 3))
13949 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13950 (match_dup 0)
13951 (pc)))]
13952 "")
13953
13954 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13955
13956 (define_peephole2
13957 [(set (reg 17) (match_operand 0 "" ""))
13958 (set (match_operand:QI 1 "register_operand" "")
13959 (match_operator:QI 2 "ix86_comparison_operator"
13960 [(reg 17) (const_int 0)]))
13961 (set (match_operand 3 "q_regs_operand" "")
13962 (zero_extend (match_dup 1)))]
13963 "(peep2_reg_dead_p (3, operands[1])
13964 || operands_match_p (operands[1], operands[3]))
13965 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13966 [(set (match_dup 4) (match_dup 0))
13967 (set (strict_low_part (match_dup 5))
13968 (match_dup 2))]
13969 {
13970 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13971 operands[5] = gen_lowpart (QImode, operands[3]);
13972 ix86_expand_clear (operands[3]);
13973 })
13974
13975 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13976
13977 (define_peephole2
13978 [(set (reg 17) (match_operand 0 "" ""))
13979 (set (match_operand:QI 1 "register_operand" "")
13980 (match_operator:QI 2 "ix86_comparison_operator"
13981 [(reg 17) (const_int 0)]))
13982 (parallel [(set (match_operand 3 "q_regs_operand" "")
13983 (zero_extend (match_dup 1)))
13984 (clobber (reg:CC 17))])]
13985 "(peep2_reg_dead_p (3, operands[1])
13986 || operands_match_p (operands[1], operands[3]))
13987 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13988 [(set (match_dup 4) (match_dup 0))
13989 (set (strict_low_part (match_dup 5))
13990 (match_dup 2))]
13991 {
13992 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13993 operands[5] = gen_lowpart (QImode, operands[3]);
13994 ix86_expand_clear (operands[3]);
13995 })
13996 \f
13997 ;; Call instructions.
13998
13999 ;; The predicates normally associated with named expanders are not properly
14000 ;; checked for calls. This is a bug in the generic code, but it isn't that
14001 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14002
14003 ;; Call subroutine returning no value.
14004
14005 (define_expand "call_pop"
14006 [(parallel [(call (match_operand:QI 0 "" "")
14007 (match_operand:SI 1 "" ""))
14008 (set (reg:SI 7)
14009 (plus:SI (reg:SI 7)
14010 (match_operand:SI 3 "" "")))])]
14011 "!TARGET_64BIT"
14012 {
14013 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14014 DONE;
14015 })
14016
14017 (define_insn "*call_pop_0"
14018 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14019 (match_operand:SI 1 "" ""))
14020 (set (reg:SI 7) (plus:SI (reg:SI 7)
14021 (match_operand:SI 2 "immediate_operand" "")))]
14022 "!TARGET_64BIT"
14023 {
14024 if (SIBLING_CALL_P (insn))
14025 return "jmp\t%P0";
14026 else
14027 return "call\t%P0";
14028 }
14029 [(set_attr "type" "call")])
14030
14031 (define_insn "*call_pop_1"
14032 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14033 (match_operand:SI 1 "" ""))
14034 (set (reg:SI 7) (plus:SI (reg:SI 7)
14035 (match_operand:SI 2 "immediate_operand" "i")))]
14036 "!TARGET_64BIT"
14037 {
14038 if (constant_call_address_operand (operands[0], Pmode))
14039 {
14040 if (SIBLING_CALL_P (insn))
14041 return "jmp\t%P0";
14042 else
14043 return "call\t%P0";
14044 }
14045 if (SIBLING_CALL_P (insn))
14046 return "jmp\t%A0";
14047 else
14048 return "call\t%A0";
14049 }
14050 [(set_attr "type" "call")])
14051
14052 (define_expand "call"
14053 [(call (match_operand:QI 0 "" "")
14054 (match_operand 1 "" ""))
14055 (use (match_operand 2 "" ""))]
14056 ""
14057 {
14058 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14059 DONE;
14060 })
14061
14062 (define_expand "sibcall"
14063 [(call (match_operand:QI 0 "" "")
14064 (match_operand 1 "" ""))
14065 (use (match_operand 2 "" ""))]
14066 ""
14067 {
14068 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14069 DONE;
14070 })
14071
14072 (define_insn "*call_0"
14073 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14074 (match_operand 1 "" ""))]
14075 ""
14076 {
14077 if (SIBLING_CALL_P (insn))
14078 return "jmp\t%P0";
14079 else
14080 return "call\t%P0";
14081 }
14082 [(set_attr "type" "call")])
14083
14084 (define_insn "*call_1"
14085 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14086 (match_operand 1 "" ""))]
14087 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14088 {
14089 if (constant_call_address_operand (operands[0], QImode))
14090 return "call\t%P0";
14091 return "call\t%A0";
14092 }
14093 [(set_attr "type" "call")])
14094
14095 (define_insn "*sibcall_1"
14096 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14097 (match_operand 1 "" ""))]
14098 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14099 {
14100 if (constant_call_address_operand (operands[0], QImode))
14101 return "jmp\t%P0";
14102 return "jmp\t%A0";
14103 }
14104 [(set_attr "type" "call")])
14105
14106 (define_insn "*call_1_rex64"
14107 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14108 (match_operand 1 "" ""))]
14109 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14110 {
14111 if (constant_call_address_operand (operands[0], QImode))
14112 return "call\t%P0";
14113 return "call\t%A0";
14114 }
14115 [(set_attr "type" "call")])
14116
14117 (define_insn "*sibcall_1_rex64"
14118 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14119 (match_operand 1 "" ""))]
14120 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14121 "jmp\t%P0"
14122 [(set_attr "type" "call")])
14123
14124 (define_insn "*sibcall_1_rex64_v"
14125 [(call (mem:QI (reg:DI 40))
14126 (match_operand 0 "" ""))]
14127 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14128 "jmp\t*%%r11"
14129 [(set_attr "type" "call")])
14130
14131
14132 ;; Call subroutine, returning value in operand 0
14133
14134 (define_expand "call_value_pop"
14135 [(parallel [(set (match_operand 0 "" "")
14136 (call (match_operand:QI 1 "" "")
14137 (match_operand:SI 2 "" "")))
14138 (set (reg:SI 7)
14139 (plus:SI (reg:SI 7)
14140 (match_operand:SI 4 "" "")))])]
14141 "!TARGET_64BIT"
14142 {
14143 ix86_expand_call (operands[0], operands[1], operands[2],
14144 operands[3], operands[4], 0);
14145 DONE;
14146 })
14147
14148 (define_expand "call_value"
14149 [(set (match_operand 0 "" "")
14150 (call (match_operand:QI 1 "" "")
14151 (match_operand:SI 2 "" "")))
14152 (use (match_operand:SI 3 "" ""))]
14153 ;; Operand 2 not used on the i386.
14154 ""
14155 {
14156 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14157 DONE;
14158 })
14159
14160 (define_expand "sibcall_value"
14161 [(set (match_operand 0 "" "")
14162 (call (match_operand:QI 1 "" "")
14163 (match_operand:SI 2 "" "")))
14164 (use (match_operand:SI 3 "" ""))]
14165 ;; Operand 2 not used on the i386.
14166 ""
14167 {
14168 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14169 DONE;
14170 })
14171
14172 ;; Call subroutine returning any type.
14173
14174 (define_expand "untyped_call"
14175 [(parallel [(call (match_operand 0 "" "")
14176 (const_int 0))
14177 (match_operand 1 "" "")
14178 (match_operand 2 "" "")])]
14179 ""
14180 {
14181 int i;
14182
14183 /* In order to give reg-stack an easier job in validating two
14184 coprocessor registers as containing a possible return value,
14185 simply pretend the untyped call returns a complex long double
14186 value. */
14187
14188 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14189 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14190 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14191 NULL, 0);
14192
14193 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14194 {
14195 rtx set = XVECEXP (operands[2], 0, i);
14196 emit_move_insn (SET_DEST (set), SET_SRC (set));
14197 }
14198
14199 /* The optimizer does not know that the call sets the function value
14200 registers we stored in the result block. We avoid problems by
14201 claiming that all hard registers are used and clobbered at this
14202 point. */
14203 emit_insn (gen_blockage (const0_rtx));
14204
14205 DONE;
14206 })
14207 \f
14208 ;; Prologue and epilogue instructions
14209
14210 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14211 ;; all of memory. This blocks insns from being moved across this point.
14212
14213 (define_insn "blockage"
14214 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14215 ""
14216 ""
14217 [(set_attr "length" "0")])
14218
14219 ;; Insn emitted into the body of a function to return from a function.
14220 ;; This is only done if the function's epilogue is known to be simple.
14221 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14222
14223 (define_expand "return"
14224 [(return)]
14225 "ix86_can_use_return_insn_p ()"
14226 {
14227 if (current_function_pops_args)
14228 {
14229 rtx popc = GEN_INT (current_function_pops_args);
14230 emit_jump_insn (gen_return_pop_internal (popc));
14231 DONE;
14232 }
14233 })
14234
14235 (define_insn "return_internal"
14236 [(return)]
14237 "reload_completed"
14238 "ret"
14239 [(set_attr "length" "1")
14240 (set_attr "length_immediate" "0")
14241 (set_attr "modrm" "0")])
14242
14243 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14244 ;; instruction Athlon and K8 have.
14245
14246 (define_insn "return_internal_long"
14247 [(return)
14248 (unspec [(const_int 0)] UNSPEC_REP)]
14249 "reload_completed"
14250 "rep {;} ret"
14251 [(set_attr "length" "1")
14252 (set_attr "length_immediate" "0")
14253 (set_attr "prefix_rep" "1")
14254 (set_attr "modrm" "0")])
14255
14256 (define_insn "return_pop_internal"
14257 [(return)
14258 (use (match_operand:SI 0 "const_int_operand" ""))]
14259 "reload_completed"
14260 "ret\t%0"
14261 [(set_attr "length" "3")
14262 (set_attr "length_immediate" "2")
14263 (set_attr "modrm" "0")])
14264
14265 (define_insn "return_indirect_internal"
14266 [(return)
14267 (use (match_operand:SI 0 "register_operand" "r"))]
14268 "reload_completed"
14269 "jmp\t%A0"
14270 [(set_attr "type" "ibr")
14271 (set_attr "length_immediate" "0")])
14272
14273 (define_insn "nop"
14274 [(const_int 0)]
14275 ""
14276 "nop"
14277 [(set_attr "length" "1")
14278 (set_attr "length_immediate" "0")
14279 (set_attr "modrm" "0")
14280 (set_attr "ppro_uops" "one")])
14281
14282 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14283 ;; branch prediction penalty for the third jump in a 16-byte
14284 ;; block on K8.
14285
14286 (define_insn "align"
14287 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14288 ""
14289 {
14290 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14291 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, INTVAL (operands[0]));
14292 #else
14293 ASM_OUTPUT_ALIGN (asm_out_file, 4);
14294 #endif
14295 return "";
14296 }
14297 [(set_attr "length" "16")])
14298
14299 (define_expand "prologue"
14300 [(const_int 1)]
14301 ""
14302 "ix86_expand_prologue (); DONE;")
14303
14304 (define_insn "set_got"
14305 [(set (match_operand:SI 0 "register_operand" "=r")
14306 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14307 (clobber (reg:CC 17))]
14308 "!TARGET_64BIT"
14309 { return output_set_got (operands[0]); }
14310 [(set_attr "type" "multi")
14311 (set_attr "length" "12")])
14312
14313 (define_expand "epilogue"
14314 [(const_int 1)]
14315 ""
14316 "ix86_expand_epilogue (1); DONE;")
14317
14318 (define_expand "sibcall_epilogue"
14319 [(const_int 1)]
14320 ""
14321 "ix86_expand_epilogue (0); DONE;")
14322
14323 (define_expand "eh_return"
14324 [(use (match_operand 0 "register_operand" ""))]
14325 ""
14326 {
14327 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14328
14329 /* Tricky bit: we write the address of the handler to which we will
14330 be returning into someone else's stack frame, one word below the
14331 stack address we wish to restore. */
14332 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14333 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14334 tmp = gen_rtx_MEM (Pmode, tmp);
14335 emit_move_insn (tmp, ra);
14336
14337 if (Pmode == SImode)
14338 emit_insn (gen_eh_return_si (sa));
14339 else
14340 emit_insn (gen_eh_return_di (sa));
14341 emit_barrier ();
14342 DONE;
14343 })
14344
14345 (define_insn_and_split "eh_return_si"
14346 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14347 UNSPECV_EH_RETURN)]
14348 "!TARGET_64BIT"
14349 "#"
14350 "reload_completed"
14351 [(const_int 1)]
14352 "ix86_expand_epilogue (2); DONE;")
14353
14354 (define_insn_and_split "eh_return_di"
14355 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14356 UNSPECV_EH_RETURN)]
14357 "TARGET_64BIT"
14358 "#"
14359 "reload_completed"
14360 [(const_int 1)]
14361 "ix86_expand_epilogue (2); DONE;")
14362
14363 (define_insn "leave"
14364 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14365 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14366 (clobber (mem:BLK (scratch)))]
14367 "!TARGET_64BIT"
14368 "leave"
14369 [(set_attr "type" "leave")])
14370
14371 (define_insn "leave_rex64"
14372 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14373 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14374 (clobber (mem:BLK (scratch)))]
14375 "TARGET_64BIT"
14376 "leave"
14377 [(set_attr "type" "leave")])
14378 \f
14379 (define_expand "ffssi2"
14380 [(parallel
14381 [(set (match_operand:SI 0 "register_operand" "")
14382 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14383 (clobber (match_scratch:SI 2 ""))
14384 (clobber (reg:CC 17))])]
14385 ""
14386 "")
14387
14388 (define_insn_and_split "*ffs_cmove"
14389 [(set (match_operand:SI 0 "register_operand" "=r")
14390 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14391 (clobber (match_scratch:SI 2 "=&r"))
14392 (clobber (reg:CC 17))]
14393 "TARGET_CMOVE"
14394 "#"
14395 "&& reload_completed"
14396 [(set (match_dup 2) (const_int -1))
14397 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14398 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14399 (set (match_dup 0) (if_then_else:SI
14400 (eq (reg:CCZ 17) (const_int 0))
14401 (match_dup 2)
14402 (match_dup 0)))
14403 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14404 (clobber (reg:CC 17))])]
14405 "")
14406
14407 (define_insn_and_split "*ffs_no_cmove"
14408 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14409 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14410 (clobber (match_scratch:SI 2 "=&r"))
14411 (clobber (reg:CC 17))]
14412 ""
14413 "#"
14414 "reload_completed"
14415 [(parallel [(set (match_dup 2) (const_int 0))
14416 (clobber (reg:CC 17))])
14417 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14418 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14419 (set (strict_low_part (match_dup 3))
14420 (eq:QI (reg:CCZ 17) (const_int 0)))
14421 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14422 (clobber (reg:CC 17))])
14423 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14424 (clobber (reg:CC 17))])
14425 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14426 (clobber (reg:CC 17))])]
14427 {
14428 operands[3] = gen_lowpart (QImode, operands[2]);
14429 })
14430
14431 (define_insn "*ffssi_1"
14432 [(set (reg:CCZ 17)
14433 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14434 (const_int 0)))
14435 (set (match_operand:SI 0 "register_operand" "=r")
14436 (ctz:SI (match_dup 1)))]
14437 ""
14438 "bsf{l}\t{%1, %0|%0, %1}"
14439 [(set_attr "prefix_0f" "1")
14440 (set_attr "ppro_uops" "few")])
14441
14442 (define_insn "ctzsi2"
14443 [(set (match_operand:SI 0 "register_operand" "=r")
14444 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14445 (clobber (reg:CC 17))]
14446 ""
14447 "bsf{l}\t{%1, %0|%0, %1}"
14448 [(set_attr "prefix_0f" "1")
14449 (set_attr "ppro_uops" "few")])
14450
14451 (define_expand "clzsi2"
14452 [(parallel
14453 [(set (match_operand:SI 0 "register_operand" "")
14454 (minus:SI (const_int 31)
14455 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14456 (clobber (reg:CC 17))])
14457 (parallel
14458 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14459 (clobber (reg:CC 17))])]
14460 ""
14461 "")
14462
14463 (define_insn "*bsr"
14464 [(set (match_operand:SI 0 "register_operand" "=r")
14465 (minus:SI (const_int 31)
14466 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14467 (clobber (reg:CC 17))]
14468 ""
14469 "bsr{l}\t{%1, %0|%0, %1}"
14470 [(set_attr "prefix_0f" "1")
14471 (set_attr "ppro_uops" "few")])
14472 \f
14473 ;; Thread-local storage patterns for ELF.
14474 ;;
14475 ;; Note that these code sequences must appear exactly as shown
14476 ;; in order to allow linker relaxation.
14477
14478 (define_insn "*tls_global_dynamic_32_gnu"
14479 [(set (match_operand:SI 0 "register_operand" "=a")
14480 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14481 (match_operand:SI 2 "tls_symbolic_operand" "")
14482 (match_operand:SI 3 "call_insn_operand" "")]
14483 UNSPEC_TLS_GD))
14484 (clobber (match_scratch:SI 4 "=d"))
14485 (clobber (match_scratch:SI 5 "=c"))
14486 (clobber (reg:CC 17))]
14487 "!TARGET_64BIT && TARGET_GNU_TLS"
14488 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14489 [(set_attr "type" "multi")
14490 (set_attr "length" "12")])
14491
14492 (define_insn "*tls_global_dynamic_32_sun"
14493 [(set (match_operand:SI 0 "register_operand" "=a")
14494 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14495 (match_operand:SI 2 "tls_symbolic_operand" "")
14496 (match_operand:SI 3 "call_insn_operand" "")]
14497 UNSPEC_TLS_GD))
14498 (clobber (match_scratch:SI 4 "=d"))
14499 (clobber (match_scratch:SI 5 "=c"))
14500 (clobber (reg:CC 17))]
14501 "!TARGET_64BIT && TARGET_SUN_TLS"
14502 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14503 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14504 [(set_attr "type" "multi")
14505 (set_attr "length" "14")])
14506
14507 (define_expand "tls_global_dynamic_32"
14508 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14509 (unspec:SI
14510 [(match_dup 2)
14511 (match_operand:SI 1 "tls_symbolic_operand" "")
14512 (match_dup 3)]
14513 UNSPEC_TLS_GD))
14514 (clobber (match_scratch:SI 4 ""))
14515 (clobber (match_scratch:SI 5 ""))
14516 (clobber (reg:CC 17))])]
14517 ""
14518 {
14519 if (flag_pic)
14520 operands[2] = pic_offset_table_rtx;
14521 else
14522 {
14523 operands[2] = gen_reg_rtx (Pmode);
14524 emit_insn (gen_set_got (operands[2]));
14525 }
14526 operands[3] = ix86_tls_get_addr ();
14527 })
14528
14529 (define_insn "*tls_global_dynamic_64"
14530 [(set (match_operand:DI 0 "register_operand" "=a")
14531 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14532 (match_operand:DI 3 "" "")))
14533 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14534 UNSPEC_TLS_GD)]
14535 "TARGET_64BIT"
14536 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14537 [(set_attr "type" "multi")
14538 (set_attr "length" "16")])
14539
14540 (define_expand "tls_global_dynamic_64"
14541 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14542 (call (mem:QI (match_dup 2)) (const_int 0)))
14543 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14544 UNSPEC_TLS_GD)])]
14545 ""
14546 {
14547 operands[2] = ix86_tls_get_addr ();
14548 })
14549
14550 (define_insn "*tls_local_dynamic_base_32_gnu"
14551 [(set (match_operand:SI 0 "register_operand" "=a")
14552 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14553 (match_operand:SI 2 "call_insn_operand" "")]
14554 UNSPEC_TLS_LD_BASE))
14555 (clobber (match_scratch:SI 3 "=d"))
14556 (clobber (match_scratch:SI 4 "=c"))
14557 (clobber (reg:CC 17))]
14558 "!TARGET_64BIT && TARGET_GNU_TLS"
14559 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14560 [(set_attr "type" "multi")
14561 (set_attr "length" "11")])
14562
14563 (define_insn "*tls_local_dynamic_base_32_sun"
14564 [(set (match_operand:SI 0 "register_operand" "=a")
14565 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14566 (match_operand:SI 2 "call_insn_operand" "")]
14567 UNSPEC_TLS_LD_BASE))
14568 (clobber (match_scratch:SI 3 "=d"))
14569 (clobber (match_scratch:SI 4 "=c"))
14570 (clobber (reg:CC 17))]
14571 "!TARGET_64BIT && TARGET_SUN_TLS"
14572 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14573 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14574 [(set_attr "type" "multi")
14575 (set_attr "length" "13")])
14576
14577 (define_expand "tls_local_dynamic_base_32"
14578 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14579 (unspec:SI [(match_dup 1) (match_dup 2)]
14580 UNSPEC_TLS_LD_BASE))
14581 (clobber (match_scratch:SI 3 ""))
14582 (clobber (match_scratch:SI 4 ""))
14583 (clobber (reg:CC 17))])]
14584 ""
14585 {
14586 if (flag_pic)
14587 operands[1] = pic_offset_table_rtx;
14588 else
14589 {
14590 operands[1] = gen_reg_rtx (Pmode);
14591 emit_insn (gen_set_got (operands[1]));
14592 }
14593 operands[2] = ix86_tls_get_addr ();
14594 })
14595
14596 (define_insn "*tls_local_dynamic_base_64"
14597 [(set (match_operand:DI 0 "register_operand" "=a")
14598 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14599 (match_operand:DI 2 "" "")))
14600 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14601 "TARGET_64BIT"
14602 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14603 [(set_attr "type" "multi")
14604 (set_attr "length" "12")])
14605
14606 (define_expand "tls_local_dynamic_base_64"
14607 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14608 (call (mem:QI (match_dup 1)) (const_int 0)))
14609 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14610 ""
14611 {
14612 operands[1] = ix86_tls_get_addr ();
14613 })
14614
14615 ;; Local dynamic of a single variable is a lose. Show combine how
14616 ;; to convert that back to global dynamic.
14617
14618 (define_insn_and_split "*tls_local_dynamic_32_once"
14619 [(set (match_operand:SI 0 "register_operand" "=a")
14620 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14621 (match_operand:SI 2 "call_insn_operand" "")]
14622 UNSPEC_TLS_LD_BASE)
14623 (const:SI (unspec:SI
14624 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14625 UNSPEC_DTPOFF))))
14626 (clobber (match_scratch:SI 4 "=d"))
14627 (clobber (match_scratch:SI 5 "=c"))
14628 (clobber (reg:CC 17))]
14629 ""
14630 "#"
14631 ""
14632 [(parallel [(set (match_dup 0)
14633 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14634 UNSPEC_TLS_GD))
14635 (clobber (match_dup 4))
14636 (clobber (match_dup 5))
14637 (clobber (reg:CC 17))])]
14638 "")
14639 \f
14640 ;; These patterns match the binary 387 instructions for addM3, subM3,
14641 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14642 ;; SFmode. The first is the normal insn, the second the same insn but
14643 ;; with one operand a conversion, and the third the same insn but with
14644 ;; the other operand a conversion. The conversion may be SFmode or
14645 ;; SImode if the target mode DFmode, but only SImode if the target mode
14646 ;; is SFmode.
14647
14648 ;; Gcc is slightly more smart about handling normal two address instructions
14649 ;; so use special patterns for add and mull.
14650 (define_insn "*fop_sf_comm_nosse"
14651 [(set (match_operand:SF 0 "register_operand" "=f")
14652 (match_operator:SF 3 "binary_fp_operator"
14653 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14654 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14655 "TARGET_80387 && !TARGET_SSE_MATH
14656 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14657 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14658 "* return output_387_binary_op (insn, operands);"
14659 [(set (attr "type")
14660 (if_then_else (match_operand:SF 3 "mult_operator" "")
14661 (const_string "fmul")
14662 (const_string "fop")))
14663 (set_attr "mode" "SF")])
14664
14665 (define_insn "*fop_sf_comm"
14666 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14667 (match_operator:SF 3 "binary_fp_operator"
14668 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14669 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14670 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14671 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14672 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14673 "* return output_387_binary_op (insn, operands);"
14674 [(set (attr "type")
14675 (if_then_else (eq_attr "alternative" "1")
14676 (if_then_else (match_operand:SF 3 "mult_operator" "")
14677 (const_string "ssemul")
14678 (const_string "sseadd"))
14679 (if_then_else (match_operand:SF 3 "mult_operator" "")
14680 (const_string "fmul")
14681 (const_string "fop"))))
14682 (set_attr "mode" "SF")])
14683
14684 (define_insn "*fop_sf_comm_sse"
14685 [(set (match_operand:SF 0 "register_operand" "=x")
14686 (match_operator:SF 3 "binary_fp_operator"
14687 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14688 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14689 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14690 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14691 "* return output_387_binary_op (insn, operands);"
14692 [(set (attr "type")
14693 (if_then_else (match_operand:SF 3 "mult_operator" "")
14694 (const_string "ssemul")
14695 (const_string "sseadd")))
14696 (set_attr "mode" "SF")])
14697
14698 (define_insn "*fop_df_comm_nosse"
14699 [(set (match_operand:DF 0 "register_operand" "=f")
14700 (match_operator:DF 3 "binary_fp_operator"
14701 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14702 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14703 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14704 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14705 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14706 "* return output_387_binary_op (insn, operands);"
14707 [(set (attr "type")
14708 (if_then_else (match_operand:SF 3 "mult_operator" "")
14709 (const_string "fmul")
14710 (const_string "fop")))
14711 (set_attr "mode" "DF")])
14712
14713 (define_insn "*fop_df_comm"
14714 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14715 (match_operator:DF 3 "binary_fp_operator"
14716 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14717 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14718 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14719 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14720 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14721 "* return output_387_binary_op (insn, operands);"
14722 [(set (attr "type")
14723 (if_then_else (eq_attr "alternative" "1")
14724 (if_then_else (match_operand:SF 3 "mult_operator" "")
14725 (const_string "ssemul")
14726 (const_string "sseadd"))
14727 (if_then_else (match_operand:SF 3 "mult_operator" "")
14728 (const_string "fmul")
14729 (const_string "fop"))))
14730 (set_attr "mode" "DF")])
14731
14732 (define_insn "*fop_df_comm_sse"
14733 [(set (match_operand:DF 0 "register_operand" "=Y")
14734 (match_operator:DF 3 "binary_fp_operator"
14735 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14736 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14737 "TARGET_SSE2 && TARGET_SSE_MATH
14738 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14739 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14740 "* return output_387_binary_op (insn, operands);"
14741 [(set (attr "type")
14742 (if_then_else (match_operand:SF 3 "mult_operator" "")
14743 (const_string "ssemul")
14744 (const_string "sseadd")))
14745 (set_attr "mode" "DF")])
14746
14747 (define_insn "*fop_xf_comm"
14748 [(set (match_operand:XF 0 "register_operand" "=f")
14749 (match_operator:XF 3 "binary_fp_operator"
14750 [(match_operand:XF 1 "register_operand" "%0")
14751 (match_operand:XF 2 "register_operand" "f")]))]
14752 "!TARGET_64BIT && TARGET_80387
14753 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14754 "* return output_387_binary_op (insn, operands);"
14755 [(set (attr "type")
14756 (if_then_else (match_operand:XF 3 "mult_operator" "")
14757 (const_string "fmul")
14758 (const_string "fop")))
14759 (set_attr "mode" "XF")])
14760
14761 (define_insn "*fop_tf_comm"
14762 [(set (match_operand:TF 0 "register_operand" "=f")
14763 (match_operator:TF 3 "binary_fp_operator"
14764 [(match_operand:TF 1 "register_operand" "%0")
14765 (match_operand:TF 2 "register_operand" "f")]))]
14766 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14767 "* return output_387_binary_op (insn, operands);"
14768 [(set (attr "type")
14769 (if_then_else (match_operand:TF 3 "mult_operator" "")
14770 (const_string "fmul")
14771 (const_string "fop")))
14772 (set_attr "mode" "XF")])
14773
14774 (define_insn "*fop_sf_1_nosse"
14775 [(set (match_operand:SF 0 "register_operand" "=f,f")
14776 (match_operator:SF 3 "binary_fp_operator"
14777 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14778 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14779 "TARGET_80387 && !TARGET_SSE_MATH
14780 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14781 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14782 "* return output_387_binary_op (insn, operands);"
14783 [(set (attr "type")
14784 (cond [(match_operand:SF 3 "mult_operator" "")
14785 (const_string "fmul")
14786 (match_operand:SF 3 "div_operator" "")
14787 (const_string "fdiv")
14788 ]
14789 (const_string "fop")))
14790 (set_attr "mode" "SF")])
14791
14792 (define_insn "*fop_sf_1"
14793 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14794 (match_operator:SF 3 "binary_fp_operator"
14795 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14796 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14797 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14798 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14799 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14800 "* return output_387_binary_op (insn, operands);"
14801 [(set (attr "type")
14802 (cond [(and (eq_attr "alternative" "2")
14803 (match_operand:SF 3 "mult_operator" ""))
14804 (const_string "ssemul")
14805 (and (eq_attr "alternative" "2")
14806 (match_operand:SF 3 "div_operator" ""))
14807 (const_string "ssediv")
14808 (eq_attr "alternative" "2")
14809 (const_string "sseadd")
14810 (match_operand:SF 3 "mult_operator" "")
14811 (const_string "fmul")
14812 (match_operand:SF 3 "div_operator" "")
14813 (const_string "fdiv")
14814 ]
14815 (const_string "fop")))
14816 (set_attr "mode" "SF")])
14817
14818 (define_insn "*fop_sf_1_sse"
14819 [(set (match_operand:SF 0 "register_operand" "=x")
14820 (match_operator:SF 3 "binary_fp_operator"
14821 [(match_operand:SF 1 "register_operand" "0")
14822 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14823 "TARGET_SSE_MATH
14824 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14825 "* return output_387_binary_op (insn, operands);"
14826 [(set (attr "type")
14827 (cond [(match_operand:SF 3 "mult_operator" "")
14828 (const_string "ssemul")
14829 (match_operand:SF 3 "div_operator" "")
14830 (const_string "ssediv")
14831 ]
14832 (const_string "sseadd")))
14833 (set_attr "mode" "SF")])
14834
14835 ;; ??? Add SSE splitters for these!
14836 (define_insn "*fop_sf_2"
14837 [(set (match_operand:SF 0 "register_operand" "=f,f")
14838 (match_operator:SF 3 "binary_fp_operator"
14839 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14840 (match_operand:SF 2 "register_operand" "0,0")]))]
14841 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14842 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14843 [(set (attr "type")
14844 (cond [(match_operand:SF 3 "mult_operator" "")
14845 (const_string "fmul")
14846 (match_operand:SF 3 "div_operator" "")
14847 (const_string "fdiv")
14848 ]
14849 (const_string "fop")))
14850 (set_attr "fp_int_src" "true")
14851 (set_attr "ppro_uops" "many")
14852 (set_attr "mode" "SI")])
14853
14854 (define_insn "*fop_sf_3"
14855 [(set (match_operand:SF 0 "register_operand" "=f,f")
14856 (match_operator:SF 3 "binary_fp_operator"
14857 [(match_operand:SF 1 "register_operand" "0,0")
14858 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14859 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14860 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14861 [(set (attr "type")
14862 (cond [(match_operand:SF 3 "mult_operator" "")
14863 (const_string "fmul")
14864 (match_operand:SF 3 "div_operator" "")
14865 (const_string "fdiv")
14866 ]
14867 (const_string "fop")))
14868 (set_attr "fp_int_src" "true")
14869 (set_attr "ppro_uops" "many")
14870 (set_attr "mode" "SI")])
14871
14872 (define_insn "*fop_df_1_nosse"
14873 [(set (match_operand:DF 0 "register_operand" "=f,f")
14874 (match_operator:DF 3 "binary_fp_operator"
14875 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14876 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14877 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14878 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14879 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14880 "* return output_387_binary_op (insn, operands);"
14881 [(set (attr "type")
14882 (cond [(match_operand:DF 3 "mult_operator" "")
14883 (const_string "fmul")
14884 (match_operand:DF 3 "div_operator" "")
14885 (const_string "fdiv")
14886 ]
14887 (const_string "fop")))
14888 (set_attr "mode" "DF")])
14889
14890
14891 (define_insn "*fop_df_1"
14892 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14893 (match_operator:DF 3 "binary_fp_operator"
14894 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14895 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14896 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14897 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14898 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14899 "* return output_387_binary_op (insn, operands);"
14900 [(set (attr "type")
14901 (cond [(and (eq_attr "alternative" "2")
14902 (match_operand:SF 3 "mult_operator" ""))
14903 (const_string "ssemul")
14904 (and (eq_attr "alternative" "2")
14905 (match_operand:SF 3 "div_operator" ""))
14906 (const_string "ssediv")
14907 (eq_attr "alternative" "2")
14908 (const_string "sseadd")
14909 (match_operand:DF 3 "mult_operator" "")
14910 (const_string "fmul")
14911 (match_operand:DF 3 "div_operator" "")
14912 (const_string "fdiv")
14913 ]
14914 (const_string "fop")))
14915 (set_attr "mode" "DF")])
14916
14917 (define_insn "*fop_df_1_sse"
14918 [(set (match_operand:DF 0 "register_operand" "=Y")
14919 (match_operator:DF 3 "binary_fp_operator"
14920 [(match_operand:DF 1 "register_operand" "0")
14921 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14922 "TARGET_SSE2 && TARGET_SSE_MATH
14923 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14924 "* return output_387_binary_op (insn, operands);"
14925 [(set_attr "mode" "DF")
14926 (set (attr "type")
14927 (cond [(match_operand:SF 3 "mult_operator" "")
14928 (const_string "ssemul")
14929 (match_operand:SF 3 "div_operator" "")
14930 (const_string "ssediv")
14931 ]
14932 (const_string "sseadd")))])
14933
14934 ;; ??? Add SSE splitters for these!
14935 (define_insn "*fop_df_2"
14936 [(set (match_operand:DF 0 "register_operand" "=f,f")
14937 (match_operator:DF 3 "binary_fp_operator"
14938 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14939 (match_operand:DF 2 "register_operand" "0,0")]))]
14940 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14941 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14942 [(set (attr "type")
14943 (cond [(match_operand:DF 3 "mult_operator" "")
14944 (const_string "fmul")
14945 (match_operand:DF 3 "div_operator" "")
14946 (const_string "fdiv")
14947 ]
14948 (const_string "fop")))
14949 (set_attr "fp_int_src" "true")
14950 (set_attr "ppro_uops" "many")
14951 (set_attr "mode" "SI")])
14952
14953 (define_insn "*fop_df_3"
14954 [(set (match_operand:DF 0 "register_operand" "=f,f")
14955 (match_operator:DF 3 "binary_fp_operator"
14956 [(match_operand:DF 1 "register_operand" "0,0")
14957 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14958 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14959 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14960 [(set (attr "type")
14961 (cond [(match_operand:DF 3 "mult_operator" "")
14962 (const_string "fmul")
14963 (match_operand:DF 3 "div_operator" "")
14964 (const_string "fdiv")
14965 ]
14966 (const_string "fop")))
14967 (set_attr "fp_int_src" "true")
14968 (set_attr "ppro_uops" "many")
14969 (set_attr "mode" "SI")])
14970
14971 (define_insn "*fop_df_4"
14972 [(set (match_operand:DF 0 "register_operand" "=f,f")
14973 (match_operator:DF 3 "binary_fp_operator"
14974 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14975 (match_operand:DF 2 "register_operand" "0,f")]))]
14976 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14977 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14978 "* return output_387_binary_op (insn, operands);"
14979 [(set (attr "type")
14980 (cond [(match_operand:DF 3 "mult_operator" "")
14981 (const_string "fmul")
14982 (match_operand:DF 3 "div_operator" "")
14983 (const_string "fdiv")
14984 ]
14985 (const_string "fop")))
14986 (set_attr "mode" "SF")])
14987
14988 (define_insn "*fop_df_5"
14989 [(set (match_operand:DF 0 "register_operand" "=f,f")
14990 (match_operator:DF 3 "binary_fp_operator"
14991 [(match_operand:DF 1 "register_operand" "0,f")
14992 (float_extend:DF
14993 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14994 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14995 "* return output_387_binary_op (insn, operands);"
14996 [(set (attr "type")
14997 (cond [(match_operand:DF 3 "mult_operator" "")
14998 (const_string "fmul")
14999 (match_operand:DF 3 "div_operator" "")
15000 (const_string "fdiv")
15001 ]
15002 (const_string "fop")))
15003 (set_attr "mode" "SF")])
15004
15005 (define_insn "*fop_df_6"
15006 [(set (match_operand:DF 0 "register_operand" "=f,f")
15007 (match_operator:DF 3 "binary_fp_operator"
15008 [(float_extend:DF
15009 (match_operand:SF 1 "register_operand" "0,f"))
15010 (float_extend:DF
15011 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15012 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15013 "* return output_387_binary_op (insn, operands);"
15014 [(set (attr "type")
15015 (cond [(match_operand:DF 3 "mult_operator" "")
15016 (const_string "fmul")
15017 (match_operand:DF 3 "div_operator" "")
15018 (const_string "fdiv")
15019 ]
15020 (const_string "fop")))
15021 (set_attr "mode" "SF")])
15022
15023 (define_insn "*fop_xf_1"
15024 [(set (match_operand:XF 0 "register_operand" "=f,f")
15025 (match_operator:XF 3 "binary_fp_operator"
15026 [(match_operand:XF 1 "register_operand" "0,f")
15027 (match_operand:XF 2 "register_operand" "f,0")]))]
15028 "!TARGET_64BIT && TARGET_80387
15029 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15030 "* return output_387_binary_op (insn, operands);"
15031 [(set (attr "type")
15032 (cond [(match_operand:XF 3 "mult_operator" "")
15033 (const_string "fmul")
15034 (match_operand:XF 3 "div_operator" "")
15035 (const_string "fdiv")
15036 ]
15037 (const_string "fop")))
15038 (set_attr "mode" "XF")])
15039
15040 (define_insn "*fop_tf_1"
15041 [(set (match_operand:TF 0 "register_operand" "=f,f")
15042 (match_operator:TF 3 "binary_fp_operator"
15043 [(match_operand:TF 1 "register_operand" "0,f")
15044 (match_operand:TF 2 "register_operand" "f,0")]))]
15045 "TARGET_80387
15046 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15047 "* return output_387_binary_op (insn, operands);"
15048 [(set (attr "type")
15049 (cond [(match_operand:TF 3 "mult_operator" "")
15050 (const_string "fmul")
15051 (match_operand:TF 3 "div_operator" "")
15052 (const_string "fdiv")
15053 ]
15054 (const_string "fop")))
15055 (set_attr "mode" "XF")])
15056
15057 (define_insn "*fop_xf_2"
15058 [(set (match_operand:XF 0 "register_operand" "=f,f")
15059 (match_operator:XF 3 "binary_fp_operator"
15060 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15061 (match_operand:XF 2 "register_operand" "0,0")]))]
15062 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
15063 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15064 [(set (attr "type")
15065 (cond [(match_operand:XF 3 "mult_operator" "")
15066 (const_string "fmul")
15067 (match_operand:XF 3 "div_operator" "")
15068 (const_string "fdiv")
15069 ]
15070 (const_string "fop")))
15071 (set_attr "fp_int_src" "true")
15072 (set_attr "mode" "SI")
15073 (set_attr "ppro_uops" "many")])
15074
15075 (define_insn "*fop_tf_2"
15076 [(set (match_operand:TF 0 "register_operand" "=f,f")
15077 (match_operator:TF 3 "binary_fp_operator"
15078 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15079 (match_operand:TF 2 "register_operand" "0,0")]))]
15080 "TARGET_80387 && TARGET_USE_FIOP"
15081 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15082 [(set (attr "type")
15083 (cond [(match_operand:TF 3 "mult_operator" "")
15084 (const_string "fmul")
15085 (match_operand:TF 3 "div_operator" "")
15086 (const_string "fdiv")
15087 ]
15088 (const_string "fop")))
15089 (set_attr "fp_int_src" "true")
15090 (set_attr "mode" "SI")
15091 (set_attr "ppro_uops" "many")])
15092
15093 (define_insn "*fop_xf_3"
15094 [(set (match_operand:XF 0 "register_operand" "=f,f")
15095 (match_operator:XF 3 "binary_fp_operator"
15096 [(match_operand:XF 1 "register_operand" "0,0")
15097 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15098 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
15099 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15100 [(set (attr "type")
15101 (cond [(match_operand:XF 3 "mult_operator" "")
15102 (const_string "fmul")
15103 (match_operand:XF 3 "div_operator" "")
15104 (const_string "fdiv")
15105 ]
15106 (const_string "fop")))
15107 (set_attr "fp_int_src" "true")
15108 (set_attr "mode" "SI")
15109 (set_attr "ppro_uops" "many")])
15110
15111 (define_insn "*fop_tf_3"
15112 [(set (match_operand:TF 0 "register_operand" "=f,f")
15113 (match_operator:TF 3 "binary_fp_operator"
15114 [(match_operand:TF 1 "register_operand" "0,0")
15115 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15116 "TARGET_80387 && TARGET_USE_FIOP"
15117 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15118 [(set (attr "type")
15119 (cond [(match_operand:TF 3 "mult_operator" "")
15120 (const_string "fmul")
15121 (match_operand:TF 3 "div_operator" "")
15122 (const_string "fdiv")
15123 ]
15124 (const_string "fop")))
15125 (set_attr "fp_int_src" "true")
15126 (set_attr "mode" "SI")
15127 (set_attr "ppro_uops" "many")])
15128
15129 (define_insn "*fop_xf_4"
15130 [(set (match_operand:XF 0 "register_operand" "=f,f")
15131 (match_operator:XF 3 "binary_fp_operator"
15132 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15133 (match_operand:XF 2 "register_operand" "0,f")]))]
15134 "!TARGET_64BIT && TARGET_80387"
15135 "* return output_387_binary_op (insn, operands);"
15136 [(set (attr "type")
15137 (cond [(match_operand:XF 3 "mult_operator" "")
15138 (const_string "fmul")
15139 (match_operand:XF 3 "div_operator" "")
15140 (const_string "fdiv")
15141 ]
15142 (const_string "fop")))
15143 (set_attr "mode" "SF")])
15144
15145 (define_insn "*fop_tf_4"
15146 [(set (match_operand:TF 0 "register_operand" "=f,f")
15147 (match_operator:TF 3 "binary_fp_operator"
15148 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15149 (match_operand:TF 2 "register_operand" "0,f")]))]
15150 "TARGET_80387"
15151 "* return output_387_binary_op (insn, operands);"
15152 [(set (attr "type")
15153 (cond [(match_operand:TF 3 "mult_operator" "")
15154 (const_string "fmul")
15155 (match_operand:TF 3 "div_operator" "")
15156 (const_string "fdiv")
15157 ]
15158 (const_string "fop")))
15159 (set_attr "mode" "SF")])
15160
15161 (define_insn "*fop_xf_5"
15162 [(set (match_operand:XF 0 "register_operand" "=f,f")
15163 (match_operator:XF 3 "binary_fp_operator"
15164 [(match_operand:XF 1 "register_operand" "0,f")
15165 (float_extend:XF
15166 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15167 "!TARGET_64BIT && TARGET_80387"
15168 "* return output_387_binary_op (insn, operands);"
15169 [(set (attr "type")
15170 (cond [(match_operand:XF 3 "mult_operator" "")
15171 (const_string "fmul")
15172 (match_operand:XF 3 "div_operator" "")
15173 (const_string "fdiv")
15174 ]
15175 (const_string "fop")))
15176 (set_attr "mode" "SF")])
15177
15178 (define_insn "*fop_tf_5"
15179 [(set (match_operand:TF 0 "register_operand" "=f,f")
15180 (match_operator:TF 3 "binary_fp_operator"
15181 [(match_operand:TF 1 "register_operand" "0,f")
15182 (float_extend:TF
15183 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15184 "TARGET_80387"
15185 "* return output_387_binary_op (insn, operands);"
15186 [(set (attr "type")
15187 (cond [(match_operand:TF 3 "mult_operator" "")
15188 (const_string "fmul")
15189 (match_operand:TF 3 "div_operator" "")
15190 (const_string "fdiv")
15191 ]
15192 (const_string "fop")))
15193 (set_attr "mode" "SF")])
15194
15195 (define_insn "*fop_xf_6"
15196 [(set (match_operand:XF 0 "register_operand" "=f,f")
15197 (match_operator:XF 3 "binary_fp_operator"
15198 [(float_extend:XF
15199 (match_operand 1 "register_operand" "0,f"))
15200 (float_extend:XF
15201 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15202 "!TARGET_64BIT && TARGET_80387"
15203 "* return output_387_binary_op (insn, operands);"
15204 [(set (attr "type")
15205 (cond [(match_operand:XF 3 "mult_operator" "")
15206 (const_string "fmul")
15207 (match_operand:XF 3 "div_operator" "")
15208 (const_string "fdiv")
15209 ]
15210 (const_string "fop")))
15211 (set_attr "mode" "SF")])
15212
15213 (define_insn "*fop_tf_6"
15214 [(set (match_operand:TF 0 "register_operand" "=f,f")
15215 (match_operator:TF 3 "binary_fp_operator"
15216 [(float_extend:TF
15217 (match_operand 1 "register_operand" "0,f"))
15218 (float_extend:TF
15219 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15220 "TARGET_80387"
15221 "* return output_387_binary_op (insn, operands);"
15222 [(set (attr "type")
15223 (cond [(match_operand:TF 3 "mult_operator" "")
15224 (const_string "fmul")
15225 (match_operand:TF 3 "div_operator" "")
15226 (const_string "fdiv")
15227 ]
15228 (const_string "fop")))
15229 (set_attr "mode" "SF")])
15230
15231 (define_split
15232 [(set (match_operand 0 "register_operand" "")
15233 (match_operator 3 "binary_fp_operator"
15234 [(float (match_operand:SI 1 "register_operand" ""))
15235 (match_operand 2 "register_operand" "")]))]
15236 "TARGET_80387 && reload_completed
15237 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15238 [(const_int 0)]
15239 {
15240 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15241 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15242 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15243 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15244 GET_MODE (operands[3]),
15245 operands[4],
15246 operands[2])));
15247 ix86_free_from_memory (GET_MODE (operands[1]));
15248 DONE;
15249 })
15250
15251 (define_split
15252 [(set (match_operand 0 "register_operand" "")
15253 (match_operator 3 "binary_fp_operator"
15254 [(match_operand 1 "register_operand" "")
15255 (float (match_operand:SI 2 "register_operand" ""))]))]
15256 "TARGET_80387 && reload_completed
15257 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15258 [(const_int 0)]
15259 {
15260 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15261 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15262 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15263 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15264 GET_MODE (operands[3]),
15265 operands[1],
15266 operands[4])));
15267 ix86_free_from_memory (GET_MODE (operands[2]));
15268 DONE;
15269 })
15270 \f
15271 ;; FPU special functions.
15272
15273 (define_expand "sqrtsf2"
15274 [(set (match_operand:SF 0 "register_operand" "")
15275 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15276 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15277 {
15278 if (!TARGET_SSE_MATH)
15279 operands[1] = force_reg (SFmode, operands[1]);
15280 })
15281
15282 (define_insn "sqrtsf2_1"
15283 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15284 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15285 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15286 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15287 "@
15288 fsqrt
15289 sqrtss\t{%1, %0|%0, %1}"
15290 [(set_attr "type" "fpspc,sse")
15291 (set_attr "mode" "SF,SF")
15292 (set_attr "athlon_decode" "direct,*")])
15293
15294 (define_insn "sqrtsf2_1_sse_only"
15295 [(set (match_operand:SF 0 "register_operand" "=x")
15296 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15297 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15298 "sqrtss\t{%1, %0|%0, %1}"
15299 [(set_attr "type" "sse")
15300 (set_attr "mode" "SF")
15301 (set_attr "athlon_decode" "*")])
15302
15303 (define_insn "sqrtsf2_i387"
15304 [(set (match_operand:SF 0 "register_operand" "=f")
15305 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15306 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15307 && !TARGET_SSE_MATH"
15308 "fsqrt"
15309 [(set_attr "type" "fpspc")
15310 (set_attr "mode" "SF")
15311 (set_attr "athlon_decode" "direct")])
15312
15313 (define_expand "sqrtdf2"
15314 [(set (match_operand:DF 0 "register_operand" "")
15315 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15316 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15317 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15318 {
15319 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15320 operands[1] = force_reg (DFmode, operands[1]);
15321 })
15322
15323 (define_insn "sqrtdf2_1"
15324 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15325 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15326 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15327 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15328 "@
15329 fsqrt
15330 sqrtsd\t{%1, %0|%0, %1}"
15331 [(set_attr "type" "fpspc,sse")
15332 (set_attr "mode" "DF,DF")
15333 (set_attr "athlon_decode" "direct,*")])
15334
15335 (define_insn "sqrtdf2_1_sse_only"
15336 [(set (match_operand:DF 0 "register_operand" "=Y")
15337 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15338 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15339 "sqrtsd\t{%1, %0|%0, %1}"
15340 [(set_attr "type" "sse")
15341 (set_attr "mode" "DF")
15342 (set_attr "athlon_decode" "*")])
15343
15344 (define_insn "sqrtdf2_i387"
15345 [(set (match_operand:DF 0 "register_operand" "=f")
15346 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15347 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15348 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15349 "fsqrt"
15350 [(set_attr "type" "fpspc")
15351 (set_attr "mode" "DF")
15352 (set_attr "athlon_decode" "direct")])
15353
15354 (define_insn "*sqrtextendsfdf2"
15355 [(set (match_operand:DF 0 "register_operand" "=f")
15356 (sqrt:DF (float_extend:DF
15357 (match_operand:SF 1 "register_operand" "0"))))]
15358 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15359 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15360 "fsqrt"
15361 [(set_attr "type" "fpspc")
15362 (set_attr "mode" "DF")
15363 (set_attr "athlon_decode" "direct")])
15364
15365 (define_insn "sqrtxf2"
15366 [(set (match_operand:XF 0 "register_operand" "=f")
15367 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15368 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15369 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15370 "fsqrt"
15371 [(set_attr "type" "fpspc")
15372 (set_attr "mode" "XF")
15373 (set_attr "athlon_decode" "direct")])
15374
15375 (define_insn "sqrttf2"
15376 [(set (match_operand:TF 0 "register_operand" "=f")
15377 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15378 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15379 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15380 "fsqrt"
15381 [(set_attr "type" "fpspc")
15382 (set_attr "mode" "XF")
15383 (set_attr "athlon_decode" "direct")])
15384
15385 (define_insn "*sqrtextenddfxf2"
15386 [(set (match_operand:XF 0 "register_operand" "=f")
15387 (sqrt:XF (float_extend:XF
15388 (match_operand:DF 1 "register_operand" "0"))))]
15389 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15390 "fsqrt"
15391 [(set_attr "type" "fpspc")
15392 (set_attr "mode" "XF")
15393 (set_attr "athlon_decode" "direct")])
15394
15395 (define_insn "*sqrtextenddftf2"
15396 [(set (match_operand:TF 0 "register_operand" "=f")
15397 (sqrt:TF (float_extend:TF
15398 (match_operand:DF 1 "register_operand" "0"))))]
15399 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15400 "fsqrt"
15401 [(set_attr "type" "fpspc")
15402 (set_attr "mode" "XF")
15403 (set_attr "athlon_decode" "direct")])
15404
15405 (define_insn "*sqrtextendsfxf2"
15406 [(set (match_operand:XF 0 "register_operand" "=f")
15407 (sqrt:XF (float_extend:XF
15408 (match_operand:SF 1 "register_operand" "0"))))]
15409 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15410 "fsqrt"
15411 [(set_attr "type" "fpspc")
15412 (set_attr "mode" "XF")
15413 (set_attr "athlon_decode" "direct")])
15414
15415 (define_insn "*sqrtextendsftf2"
15416 [(set (match_operand:TF 0 "register_operand" "=f")
15417 (sqrt:TF (float_extend:TF
15418 (match_operand:SF 1 "register_operand" "0"))))]
15419 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15420 "fsqrt"
15421 [(set_attr "type" "fpspc")
15422 (set_attr "mode" "XF")
15423 (set_attr "athlon_decode" "direct")])
15424
15425 (define_insn "sindf2"
15426 [(set (match_operand:DF 0 "register_operand" "=f")
15427 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15428 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15429 && flag_unsafe_math_optimizations"
15430 "fsin"
15431 [(set_attr "type" "fpspc")
15432 (set_attr "mode" "DF")])
15433
15434 (define_insn "sinsf2"
15435 [(set (match_operand:SF 0 "register_operand" "=f")
15436 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15437 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15438 && flag_unsafe_math_optimizations"
15439 "fsin"
15440 [(set_attr "type" "fpspc")
15441 (set_attr "mode" "SF")])
15442
15443 (define_insn "*sinextendsfdf2"
15444 [(set (match_operand:DF 0 "register_operand" "=f")
15445 (unspec:DF [(float_extend:DF
15446 (match_operand:SF 1 "register_operand" "0"))]
15447 UNSPEC_SIN))]
15448 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15449 && flag_unsafe_math_optimizations"
15450 "fsin"
15451 [(set_attr "type" "fpspc")
15452 (set_attr "mode" "DF")])
15453
15454 (define_insn "sinxf2"
15455 [(set (match_operand:XF 0 "register_operand" "=f")
15456 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15457 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15458 && flag_unsafe_math_optimizations"
15459 "fsin"
15460 [(set_attr "type" "fpspc")
15461 (set_attr "mode" "XF")])
15462
15463 (define_insn "sintf2"
15464 [(set (match_operand:TF 0 "register_operand" "=f")
15465 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15466 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15467 && flag_unsafe_math_optimizations"
15468 "fsin"
15469 [(set_attr "type" "fpspc")
15470 (set_attr "mode" "XF")])
15471
15472 (define_insn "cosdf2"
15473 [(set (match_operand:DF 0 "register_operand" "=f")
15474 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15475 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15476 && flag_unsafe_math_optimizations"
15477 "fcos"
15478 [(set_attr "type" "fpspc")
15479 (set_attr "mode" "DF")])
15480
15481 (define_insn "cossf2"
15482 [(set (match_operand:SF 0 "register_operand" "=f")
15483 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15484 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15485 && flag_unsafe_math_optimizations"
15486 "fcos"
15487 [(set_attr "type" "fpspc")
15488 (set_attr "mode" "SF")])
15489
15490 (define_insn "*cosextendsfdf2"
15491 [(set (match_operand:DF 0 "register_operand" "=f")
15492 (unspec:DF [(float_extend:DF
15493 (match_operand:SF 1 "register_operand" "0"))]
15494 UNSPEC_COS))]
15495 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15496 && flag_unsafe_math_optimizations"
15497 "fcos"
15498 [(set_attr "type" "fpspc")
15499 (set_attr "mode" "DF")])
15500
15501 (define_insn "cosxf2"
15502 [(set (match_operand:XF 0 "register_operand" "=f")
15503 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15504 "!TARGET_64BIT && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15505 && flag_unsafe_math_optimizations"
15506 "fcos"
15507 [(set_attr "type" "fpspc")
15508 (set_attr "mode" "XF")])
15509
15510 (define_insn "costf2"
15511 [(set (match_operand:TF 0 "register_operand" "=f")
15512 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15513 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15514 && flag_unsafe_math_optimizations"
15515 "fcos"
15516 [(set_attr "type" "fpspc")
15517 (set_attr "mode" "XF")])
15518
15519 (define_insn "atan2df3"
15520 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15521 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15522 (match_operand:DF 1 "register_operand" "u")]
15523 UNSPEC_FPATAN))
15524 (clobber (match_dup 1))])]
15525 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15526 && flag_unsafe_math_optimizations"
15527 "fpatan"
15528 [(set_attr "type" "fpspc")
15529 (set_attr "mode" "DF")])
15530
15531 (define_insn "atan2sf3"
15532 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15533 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15534 (match_operand:SF 1 "register_operand" "u")]
15535 UNSPEC_FPATAN))
15536 (clobber (match_dup 1))])]
15537 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15538 && flag_unsafe_math_optimizations"
15539 "fpatan"
15540 [(set_attr "type" "fpspc")
15541 (set_attr "mode" "SF")])
15542
15543 (define_insn "atan2xf3"
15544 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15545 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15546 (match_operand:XF 1 "register_operand" "u")]
15547 UNSPEC_FPATAN))
15548 (clobber (match_dup 1))])]
15549 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15550 && flag_unsafe_math_optimizations"
15551 "fpatan"
15552 [(set_attr "type" "fpspc")
15553 (set_attr "mode" "XF")])
15554
15555 (define_insn "atan2tf3"
15556 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15557 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15558 (match_operand:TF 1 "register_operand" "u")]
15559 UNSPEC_FPATAN))
15560 (clobber (match_dup 1))])]
15561 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15562 && flag_unsafe_math_optimizations"
15563 "fpatan"
15564 [(set_attr "type" "fpspc")
15565 (set_attr "mode" "XF")])
15566
15567 (define_insn "*fyl2x_sfxf3"
15568 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15569 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15570 (match_operand:XF 1 "register_operand" "u")]
15571 UNSPEC_FYL2X))
15572 (clobber (match_dup 1))])]
15573 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15574 && flag_unsafe_math_optimizations"
15575 "fyl2x"
15576 [(set_attr "type" "fpspc")
15577 (set_attr "mode" "SF")])
15578
15579 (define_insn "*fyl2x_dfxf3"
15580 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15581 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15582 (match_operand:XF 1 "register_operand" "u")]
15583 UNSPEC_FYL2X))
15584 (clobber (match_dup 1))])]
15585 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15586 && flag_unsafe_math_optimizations"
15587 "fyl2x"
15588 [(set_attr "type" "fpspc")
15589 (set_attr "mode" "DF")])
15590
15591 (define_insn "*fyl2x_xf3"
15592 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15593 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15594 (match_operand:XF 1 "register_operand" "u")]
15595 UNSPEC_FYL2X))
15596 (clobber (match_dup 1))])]
15597 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15598 && flag_unsafe_math_optimizations"
15599 "fyl2x"
15600 [(set_attr "type" "fpspc")
15601 (set_attr "mode" "XF")])
15602
15603 (define_insn "*fyl2x_tfxf3"
15604 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15605 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15606 (match_operand:XF 1 "register_operand" "u")]
15607 UNSPEC_FYL2X))
15608 (clobber (match_dup 1))])]
15609 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15610 && flag_unsafe_math_optimizations"
15611 "fyl2x"
15612 [(set_attr "type" "fpspc")
15613 (set_attr "mode" "XF")])
15614
15615 (define_expand "logsf2"
15616 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15617 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15618 (match_dup 2)] UNSPEC_FYL2X))
15619 (clobber (match_dup 2))])]
15620 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15621 && flag_unsafe_math_optimizations"
15622 {
15623 rtx temp;
15624
15625 operands[2] = gen_reg_rtx (XFmode);
15626 temp = standard_80387_constant_rtx (4); /* fldln2 */
15627 emit_move_insn (operands[2], temp);
15628 })
15629
15630 (define_expand "logdf2"
15631 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15632 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15633 (match_dup 2)] UNSPEC_FYL2X))
15634 (clobber (match_dup 2))])]
15635 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15636 && flag_unsafe_math_optimizations"
15637 {
15638 rtx temp;
15639
15640 operands[2] = gen_reg_rtx (XFmode);
15641 temp = standard_80387_constant_rtx (4); /* fldln2 */
15642 emit_move_insn (operands[2], temp);
15643 })
15644
15645 (define_expand "logxf2"
15646 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15647 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15648 (match_dup 2)] UNSPEC_FYL2X))
15649 (clobber (match_dup 2))])]
15650 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15651 && flag_unsafe_math_optimizations"
15652 {
15653 rtx temp;
15654
15655 operands[2] = gen_reg_rtx (XFmode);
15656 temp = standard_80387_constant_rtx (4); /* fldln2 */
15657 emit_move_insn (operands[2], temp);
15658 })
15659
15660 (define_expand "logtf2"
15661 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15662 (unspec:TF [(match_operand:TF 1 "register_operand" "")
15663 (match_dup 2)] UNSPEC_FYL2X))
15664 (clobber (match_dup 2))])]
15665 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15666 && flag_unsafe_math_optimizations"
15667 {
15668 rtx temp;
15669
15670 operands[2] = gen_reg_rtx (XFmode);
15671 temp = standard_80387_constant_rtx (4); /* fldln2 */
15672 emit_move_insn (operands[2], temp);
15673 })
15674 \f
15675 ;; Block operation instructions
15676
15677 (define_insn "cld"
15678 [(set (reg:SI 19) (const_int 0))]
15679 ""
15680 "cld"
15681 [(set_attr "type" "cld")])
15682
15683 (define_expand "movstrsi"
15684 [(use (match_operand:BLK 0 "memory_operand" ""))
15685 (use (match_operand:BLK 1 "memory_operand" ""))
15686 (use (match_operand:SI 2 "nonmemory_operand" ""))
15687 (use (match_operand:SI 3 "const_int_operand" ""))]
15688 ""
15689 {
15690 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15691 DONE;
15692 else
15693 FAIL;
15694 })
15695
15696 (define_expand "movstrdi"
15697 [(use (match_operand:BLK 0 "memory_operand" ""))
15698 (use (match_operand:BLK 1 "memory_operand" ""))
15699 (use (match_operand:DI 2 "nonmemory_operand" ""))
15700 (use (match_operand:DI 3 "const_int_operand" ""))]
15701 "TARGET_64BIT"
15702 {
15703 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15704 DONE;
15705 else
15706 FAIL;
15707 })
15708
15709 ;; Most CPUs don't like single string operations
15710 ;; Handle this case here to simplify previous expander.
15711
15712 (define_expand "strmovdi_rex64"
15713 [(set (match_dup 2)
15714 (mem:DI (match_operand:DI 1 "register_operand" "")))
15715 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15716 (match_dup 2))
15717 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15718 (clobber (reg:CC 17))])
15719 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15720 (clobber (reg:CC 17))])]
15721 "TARGET_64BIT"
15722 {
15723 if (TARGET_SINGLE_STRINGOP || optimize_size)
15724 {
15725 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15726 operands[1]));
15727 DONE;
15728 }
15729 else
15730 operands[2] = gen_reg_rtx (DImode);
15731 })
15732
15733
15734 (define_expand "strmovsi"
15735 [(set (match_dup 2)
15736 (mem:SI (match_operand:SI 1 "register_operand" "")))
15737 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15738 (match_dup 2))
15739 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15740 (clobber (reg:CC 17))])
15741 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15742 (clobber (reg:CC 17))])]
15743 ""
15744 {
15745 if (TARGET_64BIT)
15746 {
15747 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15748 DONE;
15749 }
15750 if (TARGET_SINGLE_STRINGOP || optimize_size)
15751 {
15752 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15753 operands[1]));
15754 DONE;
15755 }
15756 else
15757 operands[2] = gen_reg_rtx (SImode);
15758 })
15759
15760 (define_expand "strmovsi_rex64"
15761 [(set (match_dup 2)
15762 (mem:SI (match_operand:DI 1 "register_operand" "")))
15763 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15764 (match_dup 2))
15765 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15766 (clobber (reg:CC 17))])
15767 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15768 (clobber (reg:CC 17))])]
15769 "TARGET_64BIT"
15770 {
15771 if (TARGET_SINGLE_STRINGOP || optimize_size)
15772 {
15773 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15774 operands[1]));
15775 DONE;
15776 }
15777 else
15778 operands[2] = gen_reg_rtx (SImode);
15779 })
15780
15781 (define_expand "strmovhi"
15782 [(set (match_dup 2)
15783 (mem:HI (match_operand:SI 1 "register_operand" "")))
15784 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15785 (match_dup 2))
15786 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15787 (clobber (reg:CC 17))])
15788 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15789 (clobber (reg:CC 17))])]
15790 ""
15791 {
15792 if (TARGET_64BIT)
15793 {
15794 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15795 DONE;
15796 }
15797 if (TARGET_SINGLE_STRINGOP || optimize_size)
15798 {
15799 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15800 operands[1]));
15801 DONE;
15802 }
15803 else
15804 operands[2] = gen_reg_rtx (HImode);
15805 })
15806
15807 (define_expand "strmovhi_rex64"
15808 [(set (match_dup 2)
15809 (mem:HI (match_operand:DI 1 "register_operand" "")))
15810 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15811 (match_dup 2))
15812 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15813 (clobber (reg:CC 17))])
15814 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15815 (clobber (reg:CC 17))])]
15816 "TARGET_64BIT"
15817 {
15818 if (TARGET_SINGLE_STRINGOP || optimize_size)
15819 {
15820 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15821 operands[1]));
15822 DONE;
15823 }
15824 else
15825 operands[2] = gen_reg_rtx (HImode);
15826 })
15827
15828 (define_expand "strmovqi"
15829 [(set (match_dup 2)
15830 (mem:QI (match_operand:SI 1 "register_operand" "")))
15831 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15832 (match_dup 2))
15833 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15834 (clobber (reg:CC 17))])
15835 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15836 (clobber (reg:CC 17))])]
15837 ""
15838 {
15839 if (TARGET_64BIT)
15840 {
15841 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15842 DONE;
15843 }
15844 if (TARGET_SINGLE_STRINGOP || optimize_size)
15845 {
15846 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15847 operands[1]));
15848 DONE;
15849 }
15850 else
15851 operands[2] = gen_reg_rtx (QImode);
15852 })
15853
15854 (define_expand "strmovqi_rex64"
15855 [(set (match_dup 2)
15856 (mem:QI (match_operand:DI 1 "register_operand" "")))
15857 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15858 (match_dup 2))
15859 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15860 (clobber (reg:CC 17))])
15861 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15862 (clobber (reg:CC 17))])]
15863 "TARGET_64BIT"
15864 {
15865 if (TARGET_SINGLE_STRINGOP || optimize_size)
15866 {
15867 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15868 operands[1]));
15869 DONE;
15870 }
15871 else
15872 operands[2] = gen_reg_rtx (QImode);
15873 })
15874
15875 (define_insn "strmovdi_rex_1"
15876 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15877 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15878 (set (match_operand:DI 0 "register_operand" "=D")
15879 (plus:DI (match_dup 2)
15880 (const_int 8)))
15881 (set (match_operand:DI 1 "register_operand" "=S")
15882 (plus:DI (match_dup 3)
15883 (const_int 8)))
15884 (use (reg:SI 19))]
15885 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15886 "movsq"
15887 [(set_attr "type" "str")
15888 (set_attr "mode" "DI")
15889 (set_attr "memory" "both")])
15890
15891 (define_insn "strmovsi_1"
15892 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15893 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15894 (set (match_operand:SI 0 "register_operand" "=D")
15895 (plus:SI (match_dup 2)
15896 (const_int 4)))
15897 (set (match_operand:SI 1 "register_operand" "=S")
15898 (plus:SI (match_dup 3)
15899 (const_int 4)))
15900 (use (reg:SI 19))]
15901 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15902 "{movsl|movsd}"
15903 [(set_attr "type" "str")
15904 (set_attr "mode" "SI")
15905 (set_attr "memory" "both")])
15906
15907 (define_insn "strmovsi_rex_1"
15908 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15909 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15910 (set (match_operand:DI 0 "register_operand" "=D")
15911 (plus:DI (match_dup 2)
15912 (const_int 4)))
15913 (set (match_operand:DI 1 "register_operand" "=S")
15914 (plus:DI (match_dup 3)
15915 (const_int 4)))
15916 (use (reg:SI 19))]
15917 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15918 "{movsl|movsd}"
15919 [(set_attr "type" "str")
15920 (set_attr "mode" "SI")
15921 (set_attr "memory" "both")])
15922
15923 (define_insn "strmovhi_1"
15924 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15925 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15926 (set (match_operand:SI 0 "register_operand" "=D")
15927 (plus:SI (match_dup 2)
15928 (const_int 2)))
15929 (set (match_operand:SI 1 "register_operand" "=S")
15930 (plus:SI (match_dup 3)
15931 (const_int 2)))
15932 (use (reg:SI 19))]
15933 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15934 "movsw"
15935 [(set_attr "type" "str")
15936 (set_attr "memory" "both")
15937 (set_attr "mode" "HI")])
15938
15939 (define_insn "strmovhi_rex_1"
15940 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15941 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15942 (set (match_operand:DI 0 "register_operand" "=D")
15943 (plus:DI (match_dup 2)
15944 (const_int 2)))
15945 (set (match_operand:DI 1 "register_operand" "=S")
15946 (plus:DI (match_dup 3)
15947 (const_int 2)))
15948 (use (reg:SI 19))]
15949 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15950 "movsw"
15951 [(set_attr "type" "str")
15952 (set_attr "memory" "both")
15953 (set_attr "mode" "HI")])
15954
15955 (define_insn "strmovqi_1"
15956 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15957 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15958 (set (match_operand:SI 0 "register_operand" "=D")
15959 (plus:SI (match_dup 2)
15960 (const_int 1)))
15961 (set (match_operand:SI 1 "register_operand" "=S")
15962 (plus:SI (match_dup 3)
15963 (const_int 1)))
15964 (use (reg:SI 19))]
15965 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15966 "movsb"
15967 [(set_attr "type" "str")
15968 (set_attr "memory" "both")
15969 (set_attr "mode" "QI")])
15970
15971 (define_insn "strmovqi_rex_1"
15972 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15973 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15974 (set (match_operand:DI 0 "register_operand" "=D")
15975 (plus:DI (match_dup 2)
15976 (const_int 1)))
15977 (set (match_operand:DI 1 "register_operand" "=S")
15978 (plus:DI (match_dup 3)
15979 (const_int 1)))
15980 (use (reg:SI 19))]
15981 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15982 "movsb"
15983 [(set_attr "type" "str")
15984 (set_attr "memory" "both")
15985 (set_attr "mode" "QI")])
15986
15987 (define_insn "rep_movdi_rex64"
15988 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15989 (set (match_operand:DI 0 "register_operand" "=D")
15990 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15991 (const_int 3))
15992 (match_operand:DI 3 "register_operand" "0")))
15993 (set (match_operand:DI 1 "register_operand" "=S")
15994 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15995 (match_operand:DI 4 "register_operand" "1")))
15996 (set (mem:BLK (match_dup 3))
15997 (mem:BLK (match_dup 4)))
15998 (use (match_dup 5))
15999 (use (reg:SI 19))]
16000 "TARGET_64BIT"
16001 "{rep\;movsq|rep movsq}"
16002 [(set_attr "type" "str")
16003 (set_attr "prefix_rep" "1")
16004 (set_attr "memory" "both")
16005 (set_attr "mode" "DI")])
16006
16007 (define_insn "rep_movsi"
16008 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16009 (set (match_operand:SI 0 "register_operand" "=D")
16010 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16011 (const_int 2))
16012 (match_operand:SI 3 "register_operand" "0")))
16013 (set (match_operand:SI 1 "register_operand" "=S")
16014 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16015 (match_operand:SI 4 "register_operand" "1")))
16016 (set (mem:BLK (match_dup 3))
16017 (mem:BLK (match_dup 4)))
16018 (use (match_dup 5))
16019 (use (reg:SI 19))]
16020 "!TARGET_64BIT"
16021 "{rep\;movsl|rep movsd}"
16022 [(set_attr "type" "str")
16023 (set_attr "prefix_rep" "1")
16024 (set_attr "memory" "both")
16025 (set_attr "mode" "SI")])
16026
16027 (define_insn "rep_movsi_rex64"
16028 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16029 (set (match_operand:DI 0 "register_operand" "=D")
16030 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16031 (const_int 2))
16032 (match_operand:DI 3 "register_operand" "0")))
16033 (set (match_operand:DI 1 "register_operand" "=S")
16034 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16035 (match_operand:DI 4 "register_operand" "1")))
16036 (set (mem:BLK (match_dup 3))
16037 (mem:BLK (match_dup 4)))
16038 (use (match_dup 5))
16039 (use (reg:SI 19))]
16040 "TARGET_64BIT"
16041 "{rep\;movsl|rep movsd}"
16042 [(set_attr "type" "str")
16043 (set_attr "prefix_rep" "1")
16044 (set_attr "memory" "both")
16045 (set_attr "mode" "SI")])
16046
16047 (define_insn "rep_movqi"
16048 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16049 (set (match_operand:SI 0 "register_operand" "=D")
16050 (plus:SI (match_operand:SI 3 "register_operand" "0")
16051 (match_operand:SI 5 "register_operand" "2")))
16052 (set (match_operand:SI 1 "register_operand" "=S")
16053 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16054 (set (mem:BLK (match_dup 3))
16055 (mem:BLK (match_dup 4)))
16056 (use (match_dup 5))
16057 (use (reg:SI 19))]
16058 "!TARGET_64BIT"
16059 "{rep\;movsb|rep movsb}"
16060 [(set_attr "type" "str")
16061 (set_attr "prefix_rep" "1")
16062 (set_attr "memory" "both")
16063 (set_attr "mode" "SI")])
16064
16065 (define_insn "rep_movqi_rex64"
16066 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16067 (set (match_operand:DI 0 "register_operand" "=D")
16068 (plus:DI (match_operand:DI 3 "register_operand" "0")
16069 (match_operand:DI 5 "register_operand" "2")))
16070 (set (match_operand:DI 1 "register_operand" "=S")
16071 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16072 (set (mem:BLK (match_dup 3))
16073 (mem:BLK (match_dup 4)))
16074 (use (match_dup 5))
16075 (use (reg:SI 19))]
16076 "TARGET_64BIT"
16077 "{rep\;movsb|rep movsb}"
16078 [(set_attr "type" "str")
16079 (set_attr "prefix_rep" "1")
16080 (set_attr "memory" "both")
16081 (set_attr "mode" "SI")])
16082
16083 (define_expand "clrstrsi"
16084 [(use (match_operand:BLK 0 "memory_operand" ""))
16085 (use (match_operand:SI 1 "nonmemory_operand" ""))
16086 (use (match_operand 2 "const_int_operand" ""))]
16087 ""
16088 {
16089 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16090 DONE;
16091 else
16092 FAIL;
16093 })
16094
16095 (define_expand "clrstrdi"
16096 [(use (match_operand:BLK 0 "memory_operand" ""))
16097 (use (match_operand:DI 1 "nonmemory_operand" ""))
16098 (use (match_operand 2 "const_int_operand" ""))]
16099 "TARGET_64BIT"
16100 {
16101 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16102 DONE;
16103 else
16104 FAIL;
16105 })
16106
16107 ;; Most CPUs don't like single string operations
16108 ;; Handle this case here to simplify previous expander.
16109
16110 (define_expand "strsetdi_rex64"
16111 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
16112 (match_operand:DI 1 "register_operand" ""))
16113 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16114 (clobber (reg:CC 17))])]
16115 "TARGET_64BIT"
16116 {
16117 if (TARGET_SINGLE_STRINGOP || optimize_size)
16118 {
16119 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
16120 DONE;
16121 }
16122 })
16123
16124 (define_expand "strsetsi"
16125 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
16126 (match_operand:SI 1 "register_operand" ""))
16127 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16128 (clobber (reg:CC 17))])]
16129 ""
16130 {
16131 if (TARGET_64BIT)
16132 {
16133 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
16134 DONE;
16135 }
16136 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16137 {
16138 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
16139 DONE;
16140 }
16141 })
16142
16143 (define_expand "strsetsi_rex64"
16144 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
16145 (match_operand:SI 1 "register_operand" ""))
16146 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16147 (clobber (reg:CC 17))])]
16148 "TARGET_64BIT"
16149 {
16150 if (TARGET_SINGLE_STRINGOP || optimize_size)
16151 {
16152 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16153 DONE;
16154 }
16155 })
16156
16157 (define_expand "strsethi"
16158 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16159 (match_operand:HI 1 "register_operand" ""))
16160 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16161 (clobber (reg:CC 17))])]
16162 ""
16163 {
16164 if (TARGET_64BIT)
16165 {
16166 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16167 DONE;
16168 }
16169 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16170 {
16171 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16172 DONE;
16173 }
16174 })
16175
16176 (define_expand "strsethi_rex64"
16177 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16178 (match_operand:HI 1 "register_operand" ""))
16179 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16180 (clobber (reg:CC 17))])]
16181 "TARGET_64BIT"
16182 {
16183 if (TARGET_SINGLE_STRINGOP || optimize_size)
16184 {
16185 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16186 DONE;
16187 }
16188 })
16189
16190 (define_expand "strsetqi"
16191 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16192 (match_operand:QI 1 "register_operand" ""))
16193 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16194 (clobber (reg:CC 17))])]
16195 ""
16196 {
16197 if (TARGET_64BIT)
16198 {
16199 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16200 DONE;
16201 }
16202 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16203 {
16204 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16205 DONE;
16206 }
16207 })
16208
16209 (define_expand "strsetqi_rex64"
16210 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16211 (match_operand:QI 1 "register_operand" ""))
16212 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16213 (clobber (reg:CC 17))])]
16214 "TARGET_64BIT"
16215 {
16216 if (TARGET_SINGLE_STRINGOP || optimize_size)
16217 {
16218 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16219 DONE;
16220 }
16221 })
16222
16223 (define_insn "strsetdi_rex_1"
16224 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16225 (match_operand:SI 2 "register_operand" "a"))
16226 (set (match_operand:DI 0 "register_operand" "=D")
16227 (plus:DI (match_dup 1)
16228 (const_int 8)))
16229 (use (reg:SI 19))]
16230 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16231 "stosq"
16232 [(set_attr "type" "str")
16233 (set_attr "memory" "store")
16234 (set_attr "mode" "DI")])
16235
16236 (define_insn "strsetsi_1"
16237 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16238 (match_operand:SI 2 "register_operand" "a"))
16239 (set (match_operand:SI 0 "register_operand" "=D")
16240 (plus:SI (match_dup 1)
16241 (const_int 4)))
16242 (use (reg:SI 19))]
16243 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16244 "{stosl|stosd}"
16245 [(set_attr "type" "str")
16246 (set_attr "memory" "store")
16247 (set_attr "mode" "SI")])
16248
16249 (define_insn "strsetsi_rex_1"
16250 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16251 (match_operand:SI 2 "register_operand" "a"))
16252 (set (match_operand:DI 0 "register_operand" "=D")
16253 (plus:DI (match_dup 1)
16254 (const_int 4)))
16255 (use (reg:SI 19))]
16256 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16257 "{stosl|stosd}"
16258 [(set_attr "type" "str")
16259 (set_attr "memory" "store")
16260 (set_attr "mode" "SI")])
16261
16262 (define_insn "strsethi_1"
16263 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16264 (match_operand:HI 2 "register_operand" "a"))
16265 (set (match_operand:SI 0 "register_operand" "=D")
16266 (plus:SI (match_dup 1)
16267 (const_int 2)))
16268 (use (reg:SI 19))]
16269 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16270 "stosw"
16271 [(set_attr "type" "str")
16272 (set_attr "memory" "store")
16273 (set_attr "mode" "HI")])
16274
16275 (define_insn "strsethi_rex_1"
16276 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16277 (match_operand:HI 2 "register_operand" "a"))
16278 (set (match_operand:DI 0 "register_operand" "=D")
16279 (plus:DI (match_dup 1)
16280 (const_int 2)))
16281 (use (reg:SI 19))]
16282 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16283 "stosw"
16284 [(set_attr "type" "str")
16285 (set_attr "memory" "store")
16286 (set_attr "mode" "HI")])
16287
16288 (define_insn "strsetqi_1"
16289 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16290 (match_operand:QI 2 "register_operand" "a"))
16291 (set (match_operand:SI 0 "register_operand" "=D")
16292 (plus:SI (match_dup 1)
16293 (const_int 1)))
16294 (use (reg:SI 19))]
16295 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16296 "stosb"
16297 [(set_attr "type" "str")
16298 (set_attr "memory" "store")
16299 (set_attr "mode" "QI")])
16300
16301 (define_insn "strsetqi_rex_1"
16302 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16303 (match_operand:QI 2 "register_operand" "a"))
16304 (set (match_operand:DI 0 "register_operand" "=D")
16305 (plus:DI (match_dup 1)
16306 (const_int 1)))
16307 (use (reg:SI 19))]
16308 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16309 "stosb"
16310 [(set_attr "type" "str")
16311 (set_attr "memory" "store")
16312 (set_attr "mode" "QI")])
16313
16314 (define_insn "rep_stosdi_rex64"
16315 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16316 (set (match_operand:DI 0 "register_operand" "=D")
16317 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16318 (const_int 3))
16319 (match_operand:DI 3 "register_operand" "0")))
16320 (set (mem:BLK (match_dup 3))
16321 (const_int 0))
16322 (use (match_operand:DI 2 "register_operand" "a"))
16323 (use (match_dup 4))
16324 (use (reg:SI 19))]
16325 "TARGET_64BIT"
16326 "{rep\;stosq|rep stosq}"
16327 [(set_attr "type" "str")
16328 (set_attr "prefix_rep" "1")
16329 (set_attr "memory" "store")
16330 (set_attr "mode" "DI")])
16331
16332 (define_insn "rep_stossi"
16333 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16334 (set (match_operand:SI 0 "register_operand" "=D")
16335 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16336 (const_int 2))
16337 (match_operand:SI 3 "register_operand" "0")))
16338 (set (mem:BLK (match_dup 3))
16339 (const_int 0))
16340 (use (match_operand:SI 2 "register_operand" "a"))
16341 (use (match_dup 4))
16342 (use (reg:SI 19))]
16343 "!TARGET_64BIT"
16344 "{rep\;stosl|rep stosd}"
16345 [(set_attr "type" "str")
16346 (set_attr "prefix_rep" "1")
16347 (set_attr "memory" "store")
16348 (set_attr "mode" "SI")])
16349
16350 (define_insn "rep_stossi_rex64"
16351 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16352 (set (match_operand:DI 0 "register_operand" "=D")
16353 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16354 (const_int 2))
16355 (match_operand:DI 3 "register_operand" "0")))
16356 (set (mem:BLK (match_dup 3))
16357 (const_int 0))
16358 (use (match_operand:SI 2 "register_operand" "a"))
16359 (use (match_dup 4))
16360 (use (reg:SI 19))]
16361 "TARGET_64BIT"
16362 "{rep\;stosl|rep stosd}"
16363 [(set_attr "type" "str")
16364 (set_attr "prefix_rep" "1")
16365 (set_attr "memory" "store")
16366 (set_attr "mode" "SI")])
16367
16368 (define_insn "rep_stosqi"
16369 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16370 (set (match_operand:SI 0 "register_operand" "=D")
16371 (plus:SI (match_operand:SI 3 "register_operand" "0")
16372 (match_operand:SI 4 "register_operand" "1")))
16373 (set (mem:BLK (match_dup 3))
16374 (const_int 0))
16375 (use (match_operand:QI 2 "register_operand" "a"))
16376 (use (match_dup 4))
16377 (use (reg:SI 19))]
16378 "!TARGET_64BIT"
16379 "{rep\;stosb|rep stosb}"
16380 [(set_attr "type" "str")
16381 (set_attr "prefix_rep" "1")
16382 (set_attr "memory" "store")
16383 (set_attr "mode" "QI")])
16384
16385 (define_insn "rep_stosqi_rex64"
16386 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16387 (set (match_operand:DI 0 "register_operand" "=D")
16388 (plus:DI (match_operand:DI 3 "register_operand" "0")
16389 (match_operand:DI 4 "register_operand" "1")))
16390 (set (mem:BLK (match_dup 3))
16391 (const_int 0))
16392 (use (match_operand:QI 2 "register_operand" "a"))
16393 (use (match_dup 4))
16394 (use (reg:DI 19))]
16395 "TARGET_64BIT"
16396 "{rep\;stosb|rep stosb}"
16397 [(set_attr "type" "str")
16398 (set_attr "prefix_rep" "1")
16399 (set_attr "memory" "store")
16400 (set_attr "mode" "QI")])
16401
16402 (define_expand "cmpstrsi"
16403 [(set (match_operand:SI 0 "register_operand" "")
16404 (compare:SI (match_operand:BLK 1 "general_operand" "")
16405 (match_operand:BLK 2 "general_operand" "")))
16406 (use (match_operand 3 "general_operand" ""))
16407 (use (match_operand 4 "immediate_operand" ""))]
16408 ""
16409 {
16410 rtx addr1, addr2, out, outlow, count, countreg, align;
16411
16412 /* Can't use this if the user has appropriated esi or edi. */
16413 if (global_regs[4] || global_regs[5])
16414 FAIL;
16415
16416 out = operands[0];
16417 if (GET_CODE (out) != REG)
16418 out = gen_reg_rtx (SImode);
16419
16420 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16421 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16422
16423 count = operands[3];
16424 countreg = ix86_zero_extend_to_Pmode (count);
16425
16426 /* %%% Iff we are testing strict equality, we can use known alignment
16427 to good advantage. This may be possible with combine, particularly
16428 once cc0 is dead. */
16429 align = operands[4];
16430
16431 emit_insn (gen_cld ());
16432 if (GET_CODE (count) == CONST_INT)
16433 {
16434 if (INTVAL (count) == 0)
16435 {
16436 emit_move_insn (operands[0], const0_rtx);
16437 DONE;
16438 }
16439 if (TARGET_64BIT)
16440 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16441 addr1, addr2, countreg));
16442 else
16443 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16444 addr1, addr2, countreg));
16445 }
16446 else
16447 {
16448 if (TARGET_64BIT)
16449 {
16450 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16451 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16452 addr1, addr2, countreg));
16453 }
16454 else
16455 {
16456 emit_insn (gen_cmpsi_1 (countreg, countreg));
16457 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16458 addr1, addr2, countreg));
16459 }
16460 }
16461
16462 outlow = gen_lowpart (QImode, out);
16463 emit_insn (gen_cmpintqi (outlow));
16464 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16465
16466 if (operands[0] != out)
16467 emit_move_insn (operands[0], out);
16468
16469 DONE;
16470 })
16471
16472 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16473
16474 (define_expand "cmpintqi"
16475 [(set (match_dup 1)
16476 (gtu:QI (reg:CC 17) (const_int 0)))
16477 (set (match_dup 2)
16478 (ltu:QI (reg:CC 17) (const_int 0)))
16479 (parallel [(set (match_operand:QI 0 "register_operand" "")
16480 (minus:QI (match_dup 1)
16481 (match_dup 2)))
16482 (clobber (reg:CC 17))])]
16483 ""
16484 "operands[1] = gen_reg_rtx (QImode);
16485 operands[2] = gen_reg_rtx (QImode);")
16486
16487 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16488 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16489
16490 (define_insn "cmpstrqi_nz_1"
16491 [(set (reg:CC 17)
16492 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16493 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16494 (use (match_operand:SI 6 "register_operand" "2"))
16495 (use (match_operand:SI 3 "immediate_operand" "i"))
16496 (use (reg:SI 19))
16497 (clobber (match_operand:SI 0 "register_operand" "=S"))
16498 (clobber (match_operand:SI 1 "register_operand" "=D"))
16499 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16500 "!TARGET_64BIT"
16501 "repz{\;| }cmpsb"
16502 [(set_attr "type" "str")
16503 (set_attr "mode" "QI")
16504 (set_attr "prefix_rep" "1")])
16505
16506 (define_insn "cmpstrqi_nz_rex_1"
16507 [(set (reg:CC 17)
16508 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16509 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16510 (use (match_operand:DI 6 "register_operand" "2"))
16511 (use (match_operand:SI 3 "immediate_operand" "i"))
16512 (use (reg:SI 19))
16513 (clobber (match_operand:DI 0 "register_operand" "=S"))
16514 (clobber (match_operand:DI 1 "register_operand" "=D"))
16515 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16516 "TARGET_64BIT"
16517 "repz{\;| }cmpsb"
16518 [(set_attr "type" "str")
16519 (set_attr "mode" "QI")
16520 (set_attr "prefix_rep" "1")])
16521
16522 ;; The same, but the count is not known to not be zero.
16523
16524 (define_insn "cmpstrqi_1"
16525 [(set (reg:CC 17)
16526 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16527 (const_int 0))
16528 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16529 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16530 (const_int 0)))
16531 (use (match_operand:SI 3 "immediate_operand" "i"))
16532 (use (reg:CC 17))
16533 (use (reg:SI 19))
16534 (clobber (match_operand:SI 0 "register_operand" "=S"))
16535 (clobber (match_operand:SI 1 "register_operand" "=D"))
16536 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16537 "!TARGET_64BIT"
16538 "repz{\;| }cmpsb"
16539 [(set_attr "type" "str")
16540 (set_attr "mode" "QI")
16541 (set_attr "prefix_rep" "1")])
16542
16543 (define_insn "cmpstrqi_rex_1"
16544 [(set (reg:CC 17)
16545 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16546 (const_int 0))
16547 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16548 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16549 (const_int 0)))
16550 (use (match_operand:SI 3 "immediate_operand" "i"))
16551 (use (reg:CC 17))
16552 (use (reg:SI 19))
16553 (clobber (match_operand:DI 0 "register_operand" "=S"))
16554 (clobber (match_operand:DI 1 "register_operand" "=D"))
16555 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16556 "TARGET_64BIT"
16557 "repz{\;| }cmpsb"
16558 [(set_attr "type" "str")
16559 (set_attr "mode" "QI")
16560 (set_attr "prefix_rep" "1")])
16561
16562 (define_expand "strlensi"
16563 [(set (match_operand:SI 0 "register_operand" "")
16564 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16565 (match_operand:QI 2 "immediate_operand" "")
16566 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16567 ""
16568 {
16569 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16570 DONE;
16571 else
16572 FAIL;
16573 })
16574
16575 (define_expand "strlendi"
16576 [(set (match_operand:DI 0 "register_operand" "")
16577 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16578 (match_operand:QI 2 "immediate_operand" "")
16579 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16580 ""
16581 {
16582 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16583 DONE;
16584 else
16585 FAIL;
16586 })
16587
16588 (define_insn "strlenqi_1"
16589 [(set (match_operand:SI 0 "register_operand" "=&c")
16590 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16591 (match_operand:QI 2 "register_operand" "a")
16592 (match_operand:SI 3 "immediate_operand" "i")
16593 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16594 (use (reg:SI 19))
16595 (clobber (match_operand:SI 1 "register_operand" "=D"))
16596 (clobber (reg:CC 17))]
16597 "!TARGET_64BIT"
16598 "repnz{\;| }scasb"
16599 [(set_attr "type" "str")
16600 (set_attr "mode" "QI")
16601 (set_attr "prefix_rep" "1")])
16602
16603 (define_insn "strlenqi_rex_1"
16604 [(set (match_operand:DI 0 "register_operand" "=&c")
16605 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16606 (match_operand:QI 2 "register_operand" "a")
16607 (match_operand:DI 3 "immediate_operand" "i")
16608 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16609 (use (reg:SI 19))
16610 (clobber (match_operand:DI 1 "register_operand" "=D"))
16611 (clobber (reg:CC 17))]
16612 "TARGET_64BIT"
16613 "repnz{\;| }scasb"
16614 [(set_attr "type" "str")
16615 (set_attr "mode" "QI")
16616 (set_attr "prefix_rep" "1")])
16617
16618 ;; Peephole optimizations to clean up after cmpstr*. This should be
16619 ;; handled in combine, but it is not currently up to the task.
16620 ;; When used for their truth value, the cmpstr* expanders generate
16621 ;; code like this:
16622 ;;
16623 ;; repz cmpsb
16624 ;; seta %al
16625 ;; setb %dl
16626 ;; cmpb %al, %dl
16627 ;; jcc label
16628 ;;
16629 ;; The intermediate three instructions are unnecessary.
16630
16631 ;; This one handles cmpstr*_nz_1...
16632 (define_peephole2
16633 [(parallel[
16634 (set (reg:CC 17)
16635 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16636 (mem:BLK (match_operand 5 "register_operand" ""))))
16637 (use (match_operand 6 "register_operand" ""))
16638 (use (match_operand:SI 3 "immediate_operand" ""))
16639 (use (reg:SI 19))
16640 (clobber (match_operand 0 "register_operand" ""))
16641 (clobber (match_operand 1 "register_operand" ""))
16642 (clobber (match_operand 2 "register_operand" ""))])
16643 (set (match_operand:QI 7 "register_operand" "")
16644 (gtu:QI (reg:CC 17) (const_int 0)))
16645 (set (match_operand:QI 8 "register_operand" "")
16646 (ltu:QI (reg:CC 17) (const_int 0)))
16647 (set (reg 17)
16648 (compare (match_dup 7) (match_dup 8)))
16649 ]
16650 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16651 [(parallel[
16652 (set (reg:CC 17)
16653 (compare:CC (mem:BLK (match_dup 4))
16654 (mem:BLK (match_dup 5))))
16655 (use (match_dup 6))
16656 (use (match_dup 3))
16657 (use (reg:SI 19))
16658 (clobber (match_dup 0))
16659 (clobber (match_dup 1))
16660 (clobber (match_dup 2))])]
16661 "")
16662
16663 ;; ...and this one handles cmpstr*_1.
16664 (define_peephole2
16665 [(parallel[
16666 (set (reg:CC 17)
16667 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16668 (const_int 0))
16669 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16670 (mem:BLK (match_operand 5 "register_operand" "")))
16671 (const_int 0)))
16672 (use (match_operand:SI 3 "immediate_operand" ""))
16673 (use (reg:CC 17))
16674 (use (reg:SI 19))
16675 (clobber (match_operand 0 "register_operand" ""))
16676 (clobber (match_operand 1 "register_operand" ""))
16677 (clobber (match_operand 2 "register_operand" ""))])
16678 (set (match_operand:QI 7 "register_operand" "")
16679 (gtu:QI (reg:CC 17) (const_int 0)))
16680 (set (match_operand:QI 8 "register_operand" "")
16681 (ltu:QI (reg:CC 17) (const_int 0)))
16682 (set (reg 17)
16683 (compare (match_dup 7) (match_dup 8)))
16684 ]
16685 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16686 [(parallel[
16687 (set (reg:CC 17)
16688 (if_then_else:CC (ne (match_dup 6)
16689 (const_int 0))
16690 (compare:CC (mem:BLK (match_dup 4))
16691 (mem:BLK (match_dup 5)))
16692 (const_int 0)))
16693 (use (match_dup 3))
16694 (use (reg:CC 17))
16695 (use (reg:SI 19))
16696 (clobber (match_dup 0))
16697 (clobber (match_dup 1))
16698 (clobber (match_dup 2))])]
16699 "")
16700
16701
16702 \f
16703 ;; Conditional move instructions.
16704
16705 (define_expand "movdicc"
16706 [(set (match_operand:DI 0 "register_operand" "")
16707 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16708 (match_operand:DI 2 "general_operand" "")
16709 (match_operand:DI 3 "general_operand" "")))]
16710 "TARGET_64BIT"
16711 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16712
16713 (define_insn "x86_movdicc_0_m1_rex64"
16714 [(set (match_operand:DI 0 "register_operand" "=r")
16715 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16716 (const_int -1)
16717 (const_int 0)))
16718 (clobber (reg:CC 17))]
16719 "TARGET_64BIT"
16720 "sbb{q}\t%0, %0"
16721 ; Since we don't have the proper number of operands for an alu insn,
16722 ; fill in all the blanks.
16723 [(set_attr "type" "alu")
16724 (set_attr "pent_pair" "pu")
16725 (set_attr "memory" "none")
16726 (set_attr "imm_disp" "false")
16727 (set_attr "mode" "DI")
16728 (set_attr "length_immediate" "0")])
16729
16730 (define_insn "movdicc_c_rex64"
16731 [(set (match_operand:DI 0 "register_operand" "=r,r")
16732 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16733 [(reg 17) (const_int 0)])
16734 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16735 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16736 "TARGET_64BIT && TARGET_CMOVE
16737 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16738 "@
16739 cmov%O2%C1\t{%2, %0|%0, %2}
16740 cmov%O2%c1\t{%3, %0|%0, %3}"
16741 [(set_attr "type" "icmov")
16742 (set_attr "mode" "DI")])
16743
16744 (define_expand "movsicc"
16745 [(set (match_operand:SI 0 "register_operand" "")
16746 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16747 (match_operand:SI 2 "general_operand" "")
16748 (match_operand:SI 3 "general_operand" "")))]
16749 ""
16750 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16751
16752 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16753 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16754 ;; So just document what we're doing explicitly.
16755
16756 (define_insn "x86_movsicc_0_m1"
16757 [(set (match_operand:SI 0 "register_operand" "=r")
16758 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16759 (const_int -1)
16760 (const_int 0)))
16761 (clobber (reg:CC 17))]
16762 ""
16763 "sbb{l}\t%0, %0"
16764 ; Since we don't have the proper number of operands for an alu insn,
16765 ; fill in all the blanks.
16766 [(set_attr "type" "alu")
16767 (set_attr "pent_pair" "pu")
16768 (set_attr "memory" "none")
16769 (set_attr "imm_disp" "false")
16770 (set_attr "mode" "SI")
16771 (set_attr "length_immediate" "0")])
16772
16773 (define_insn "*movsicc_noc"
16774 [(set (match_operand:SI 0 "register_operand" "=r,r")
16775 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16776 [(reg 17) (const_int 0)])
16777 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16778 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16779 "TARGET_CMOVE
16780 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16781 "@
16782 cmov%O2%C1\t{%2, %0|%0, %2}
16783 cmov%O2%c1\t{%3, %0|%0, %3}"
16784 [(set_attr "type" "icmov")
16785 (set_attr "mode" "SI")])
16786
16787 (define_expand "movhicc"
16788 [(set (match_operand:HI 0 "register_operand" "")
16789 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16790 (match_operand:HI 2 "general_operand" "")
16791 (match_operand:HI 3 "general_operand" "")))]
16792 "TARGET_HIMODE_MATH"
16793 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16794
16795 (define_insn "*movhicc_noc"
16796 [(set (match_operand:HI 0 "register_operand" "=r,r")
16797 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16798 [(reg 17) (const_int 0)])
16799 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16800 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16801 "TARGET_CMOVE
16802 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16803 "@
16804 cmov%O2%C1\t{%2, %0|%0, %2}
16805 cmov%O2%c1\t{%3, %0|%0, %3}"
16806 [(set_attr "type" "icmov")
16807 (set_attr "mode" "HI")])
16808
16809 (define_expand "movqicc"
16810 [(set (match_operand:QI 0 "register_operand" "")
16811 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16812 (match_operand:QI 2 "general_operand" "")
16813 (match_operand:QI 3 "general_operand" "")))]
16814 "TARGET_QIMODE_MATH"
16815 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16816
16817 (define_insn_and_split "*movqicc_noc"
16818 [(set (match_operand:QI 0 "register_operand" "=r,r")
16819 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16820 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16821 (match_operand:QI 2 "register_operand" "r,0")
16822 (match_operand:QI 3 "register_operand" "0,r")))]
16823 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16824 "#"
16825 "&& reload_completed"
16826 [(set (match_dup 0)
16827 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16828 (match_dup 2)
16829 (match_dup 3)))]
16830 "operands[0] = gen_lowpart (SImode, operands[0]);
16831 operands[2] = gen_lowpart (SImode, operands[2]);
16832 operands[3] = gen_lowpart (SImode, operands[3]);"
16833 [(set_attr "type" "icmov")
16834 (set_attr "mode" "SI")])
16835
16836 (define_expand "movsfcc"
16837 [(set (match_operand:SF 0 "register_operand" "")
16838 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16839 (match_operand:SF 2 "register_operand" "")
16840 (match_operand:SF 3 "register_operand" "")))]
16841 "TARGET_CMOVE"
16842 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16843
16844 (define_insn "*movsfcc_1"
16845 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16846 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16847 [(reg 17) (const_int 0)])
16848 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16849 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16850 "TARGET_CMOVE
16851 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16852 "@
16853 fcmov%F1\t{%2, %0|%0, %2}
16854 fcmov%f1\t{%3, %0|%0, %3}
16855 cmov%O2%C1\t{%2, %0|%0, %2}
16856 cmov%O2%c1\t{%3, %0|%0, %3}"
16857 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16858 (set_attr "mode" "SF,SF,SI,SI")])
16859
16860 (define_expand "movdfcc"
16861 [(set (match_operand:DF 0 "register_operand" "")
16862 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16863 (match_operand:DF 2 "register_operand" "")
16864 (match_operand:DF 3 "register_operand" "")))]
16865 "TARGET_CMOVE"
16866 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16867
16868 (define_insn "*movdfcc_1"
16869 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16870 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16871 [(reg 17) (const_int 0)])
16872 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16873 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16874 "!TARGET_64BIT && TARGET_CMOVE
16875 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16876 "@
16877 fcmov%F1\t{%2, %0|%0, %2}
16878 fcmov%f1\t{%3, %0|%0, %3}
16879 #
16880 #"
16881 [(set_attr "type" "fcmov,fcmov,multi,multi")
16882 (set_attr "mode" "DF")])
16883
16884 (define_insn "*movdfcc_1_rex64"
16885 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16886 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16887 [(reg 17) (const_int 0)])
16888 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16889 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16890 "TARGET_64BIT && TARGET_CMOVE
16891 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16892 "@
16893 fcmov%F1\t{%2, %0|%0, %2}
16894 fcmov%f1\t{%3, %0|%0, %3}
16895 cmov%O2%C1\t{%2, %0|%0, %2}
16896 cmov%O2%c1\t{%3, %0|%0, %3}"
16897 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16898 (set_attr "mode" "DF")])
16899
16900 (define_split
16901 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16902 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16903 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16904 (match_operand:DF 2 "nonimmediate_operand" "")
16905 (match_operand:DF 3 "nonimmediate_operand" "")))]
16906 "!TARGET_64BIT && reload_completed"
16907 [(set (match_dup 2)
16908 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16909 (match_dup 5)
16910 (match_dup 7)))
16911 (set (match_dup 3)
16912 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16913 (match_dup 6)
16914 (match_dup 8)))]
16915 "split_di (operands+2, 1, operands+5, operands+6);
16916 split_di (operands+3, 1, operands+7, operands+8);
16917 split_di (operands, 1, operands+2, operands+3);")
16918
16919 (define_expand "movxfcc"
16920 [(set (match_operand:XF 0 "register_operand" "")
16921 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16922 (match_operand:XF 2 "register_operand" "")
16923 (match_operand:XF 3 "register_operand" "")))]
16924 "!TARGET_64BIT && TARGET_CMOVE"
16925 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16926
16927 (define_expand "movtfcc"
16928 [(set (match_operand:TF 0 "register_operand" "")
16929 (if_then_else:TF (match_operand 1 "comparison_operator" "")
16930 (match_operand:TF 2 "register_operand" "")
16931 (match_operand:TF 3 "register_operand" "")))]
16932 "TARGET_CMOVE"
16933 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16934
16935 (define_insn "*movxfcc_1"
16936 [(set (match_operand:XF 0 "register_operand" "=f,f")
16937 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16938 [(reg 17) (const_int 0)])
16939 (match_operand:XF 2 "register_operand" "f,0")
16940 (match_operand:XF 3 "register_operand" "0,f")))]
16941 "!TARGET_64BIT && TARGET_CMOVE"
16942 "@
16943 fcmov%F1\t{%2, %0|%0, %2}
16944 fcmov%f1\t{%3, %0|%0, %3}"
16945 [(set_attr "type" "fcmov")
16946 (set_attr "mode" "XF")])
16947
16948 (define_insn "*movtfcc_1"
16949 [(set (match_operand:TF 0 "register_operand" "=f,f")
16950 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
16951 [(reg 17) (const_int 0)])
16952 (match_operand:TF 2 "register_operand" "f,0")
16953 (match_operand:TF 3 "register_operand" "0,f")))]
16954 "TARGET_CMOVE"
16955 "@
16956 fcmov%F1\t{%2, %0|%0, %2}
16957 fcmov%f1\t{%3, %0|%0, %3}"
16958 [(set_attr "type" "fcmov")
16959 (set_attr "mode" "XF")])
16960
16961 (define_expand "minsf3"
16962 [(parallel [
16963 (set (match_operand:SF 0 "register_operand" "")
16964 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16965 (match_operand:SF 2 "nonimmediate_operand" ""))
16966 (match_dup 1)
16967 (match_dup 2)))
16968 (clobber (reg:CC 17))])]
16969 "TARGET_SSE"
16970 "")
16971
16972 (define_insn "*minsf"
16973 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16974 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16975 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16976 (match_dup 1)
16977 (match_dup 2)))
16978 (clobber (reg:CC 17))]
16979 "TARGET_SSE && TARGET_IEEE_FP"
16980 "#")
16981
16982 (define_insn "*minsf_nonieee"
16983 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16984 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16985 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16986 (match_dup 1)
16987 (match_dup 2)))
16988 (clobber (reg:CC 17))]
16989 "TARGET_SSE && !TARGET_IEEE_FP
16990 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16991 "#")
16992
16993 (define_split
16994 [(set (match_operand:SF 0 "register_operand" "")
16995 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16996 (match_operand:SF 2 "nonimmediate_operand" ""))
16997 (match_operand:SF 3 "register_operand" "")
16998 (match_operand:SF 4 "nonimmediate_operand" "")))
16999 (clobber (reg:CC 17))]
17000 "SSE_REG_P (operands[0]) && reload_completed
17001 && ((operands_match_p (operands[1], operands[3])
17002 && operands_match_p (operands[2], operands[4]))
17003 || (operands_match_p (operands[1], operands[4])
17004 && operands_match_p (operands[2], operands[3])))"
17005 [(set (match_dup 0)
17006 (if_then_else:SF (lt (match_dup 1)
17007 (match_dup 2))
17008 (match_dup 1)
17009 (match_dup 2)))])
17010
17011 ;; Conditional addition patterns
17012 (define_expand "addqicc"
17013 [(match_operand:QI 0 "register_operand" "")
17014 (match_operand 1 "comparison_operator" "")
17015 (match_operand:QI 2 "register_operand" "")
17016 (match_operand:QI 3 "const_int_operand" "")]
17017 ""
17018 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17019
17020 (define_expand "addhicc"
17021 [(match_operand:HI 0 "register_operand" "")
17022 (match_operand 1 "comparison_operator" "")
17023 (match_operand:HI 2 "register_operand" "")
17024 (match_operand:HI 3 "const_int_operand" "")]
17025 ""
17026 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17027
17028 (define_expand "addsicc"
17029 [(match_operand:SI 0 "register_operand" "")
17030 (match_operand 1 "comparison_operator" "")
17031 (match_operand:SI 2 "register_operand" "")
17032 (match_operand:SI 3 "const_int_operand" "")]
17033 ""
17034 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17035
17036 (define_expand "adddicc"
17037 [(match_operand:DI 0 "register_operand" "")
17038 (match_operand 1 "comparison_operator" "")
17039 (match_operand:DI 2 "register_operand" "")
17040 (match_operand:DI 3 "const_int_operand" "")]
17041 "TARGET_64BIT"
17042 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17043
17044 ;; We can't represent the LT test directly. Do this by swapping the operands.
17045
17046 (define_split
17047 [(set (match_operand:SF 0 "fp_register_operand" "")
17048 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17049 (match_operand:SF 2 "register_operand" ""))
17050 (match_operand:SF 3 "register_operand" "")
17051 (match_operand:SF 4 "register_operand" "")))
17052 (clobber (reg:CC 17))]
17053 "reload_completed
17054 && ((operands_match_p (operands[1], operands[3])
17055 && operands_match_p (operands[2], operands[4]))
17056 || (operands_match_p (operands[1], operands[4])
17057 && operands_match_p (operands[2], operands[3])))"
17058 [(set (reg:CCFP 17)
17059 (compare:CCFP (match_dup 2)
17060 (match_dup 1)))
17061 (set (match_dup 0)
17062 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17063 (match_dup 1)
17064 (match_dup 2)))])
17065
17066 (define_insn "*minsf_sse"
17067 [(set (match_operand:SF 0 "register_operand" "=x")
17068 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17069 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17070 (match_dup 1)
17071 (match_dup 2)))]
17072 "TARGET_SSE && reload_completed"
17073 "minss\t{%2, %0|%0, %2}"
17074 [(set_attr "type" "sse")
17075 (set_attr "mode" "SF")])
17076
17077 (define_expand "mindf3"
17078 [(parallel [
17079 (set (match_operand:DF 0 "register_operand" "")
17080 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17081 (match_operand:DF 2 "nonimmediate_operand" ""))
17082 (match_dup 1)
17083 (match_dup 2)))
17084 (clobber (reg:CC 17))])]
17085 "TARGET_SSE2 && TARGET_SSE_MATH"
17086 "#")
17087
17088 (define_insn "*mindf"
17089 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17090 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17091 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17092 (match_dup 1)
17093 (match_dup 2)))
17094 (clobber (reg:CC 17))]
17095 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17096 "#")
17097
17098 (define_insn "*mindf_nonieee"
17099 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17100 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17101 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17102 (match_dup 1)
17103 (match_dup 2)))
17104 (clobber (reg:CC 17))]
17105 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17106 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17107 "#")
17108
17109 (define_split
17110 [(set (match_operand:DF 0 "register_operand" "")
17111 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17112 (match_operand:DF 2 "nonimmediate_operand" ""))
17113 (match_operand:DF 3 "register_operand" "")
17114 (match_operand:DF 4 "nonimmediate_operand" "")))
17115 (clobber (reg:CC 17))]
17116 "SSE_REG_P (operands[0]) && reload_completed
17117 && ((operands_match_p (operands[1], operands[3])
17118 && operands_match_p (operands[2], operands[4]))
17119 || (operands_match_p (operands[1], operands[4])
17120 && operands_match_p (operands[2], operands[3])))"
17121 [(set (match_dup 0)
17122 (if_then_else:DF (lt (match_dup 1)
17123 (match_dup 2))
17124 (match_dup 1)
17125 (match_dup 2)))])
17126
17127 ;; We can't represent the LT test directly. Do this by swapping the operands.
17128 (define_split
17129 [(set (match_operand:DF 0 "fp_register_operand" "")
17130 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17131 (match_operand:DF 2 "register_operand" ""))
17132 (match_operand:DF 3 "register_operand" "")
17133 (match_operand:DF 4 "register_operand" "")))
17134 (clobber (reg:CC 17))]
17135 "reload_completed
17136 && ((operands_match_p (operands[1], operands[3])
17137 && operands_match_p (operands[2], operands[4]))
17138 || (operands_match_p (operands[1], operands[4])
17139 && operands_match_p (operands[2], operands[3])))"
17140 [(set (reg:CCFP 17)
17141 (compare:CCFP (match_dup 2)
17142 (match_dup 2)))
17143 (set (match_dup 0)
17144 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17145 (match_dup 1)
17146 (match_dup 2)))])
17147
17148 (define_insn "*mindf_sse"
17149 [(set (match_operand:DF 0 "register_operand" "=Y")
17150 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17151 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17152 (match_dup 1)
17153 (match_dup 2)))]
17154 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17155 "minsd\t{%2, %0|%0, %2}"
17156 [(set_attr "type" "sse")
17157 (set_attr "mode" "DF")])
17158
17159 (define_expand "maxsf3"
17160 [(parallel [
17161 (set (match_operand:SF 0 "register_operand" "")
17162 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17163 (match_operand:SF 2 "nonimmediate_operand" ""))
17164 (match_dup 1)
17165 (match_dup 2)))
17166 (clobber (reg:CC 17))])]
17167 "TARGET_SSE"
17168 "#")
17169
17170 (define_insn "*maxsf"
17171 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17172 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17173 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17174 (match_dup 1)
17175 (match_dup 2)))
17176 (clobber (reg:CC 17))]
17177 "TARGET_SSE && TARGET_IEEE_FP"
17178 "#")
17179
17180 (define_insn "*maxsf_nonieee"
17181 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17182 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17183 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17184 (match_dup 1)
17185 (match_dup 2)))
17186 (clobber (reg:CC 17))]
17187 "TARGET_SSE && !TARGET_IEEE_FP
17188 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17189 "#")
17190
17191 (define_split
17192 [(set (match_operand:SF 0 "register_operand" "")
17193 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17194 (match_operand:SF 2 "nonimmediate_operand" ""))
17195 (match_operand:SF 3 "register_operand" "")
17196 (match_operand:SF 4 "nonimmediate_operand" "")))
17197 (clobber (reg:CC 17))]
17198 "SSE_REG_P (operands[0]) && reload_completed
17199 && ((operands_match_p (operands[1], operands[3])
17200 && operands_match_p (operands[2], operands[4]))
17201 || (operands_match_p (operands[1], operands[4])
17202 && operands_match_p (operands[2], operands[3])))"
17203 [(set (match_dup 0)
17204 (if_then_else:SF (gt (match_dup 1)
17205 (match_dup 2))
17206 (match_dup 1)
17207 (match_dup 2)))])
17208
17209 (define_split
17210 [(set (match_operand:SF 0 "fp_register_operand" "")
17211 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17212 (match_operand:SF 2 "register_operand" ""))
17213 (match_operand:SF 3 "register_operand" "")
17214 (match_operand:SF 4 "register_operand" "")))
17215 (clobber (reg:CC 17))]
17216 "reload_completed
17217 && ((operands_match_p (operands[1], operands[3])
17218 && operands_match_p (operands[2], operands[4]))
17219 || (operands_match_p (operands[1], operands[4])
17220 && operands_match_p (operands[2], operands[3])))"
17221 [(set (reg:CCFP 17)
17222 (compare:CCFP (match_dup 1)
17223 (match_dup 2)))
17224 (set (match_dup 0)
17225 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17226 (match_dup 1)
17227 (match_dup 2)))])
17228
17229 (define_insn "*maxsf_sse"
17230 [(set (match_operand:SF 0 "register_operand" "=x")
17231 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17232 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17233 (match_dup 1)
17234 (match_dup 2)))]
17235 "TARGET_SSE && reload_completed"
17236 "maxss\t{%2, %0|%0, %2}"
17237 [(set_attr "type" "sse")
17238 (set_attr "mode" "SF")])
17239
17240 (define_expand "maxdf3"
17241 [(parallel [
17242 (set (match_operand:DF 0 "register_operand" "")
17243 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17244 (match_operand:DF 2 "nonimmediate_operand" ""))
17245 (match_dup 1)
17246 (match_dup 2)))
17247 (clobber (reg:CC 17))])]
17248 "TARGET_SSE2 && TARGET_SSE_MATH"
17249 "#")
17250
17251 (define_insn "*maxdf"
17252 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17253 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17254 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17255 (match_dup 1)
17256 (match_dup 2)))
17257 (clobber (reg:CC 17))]
17258 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17259 "#")
17260
17261 (define_insn "*maxdf_nonieee"
17262 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17263 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17264 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17265 (match_dup 1)
17266 (match_dup 2)))
17267 (clobber (reg:CC 17))]
17268 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17269 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17270 "#")
17271
17272 (define_split
17273 [(set (match_operand:DF 0 "register_operand" "")
17274 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17275 (match_operand:DF 2 "nonimmediate_operand" ""))
17276 (match_operand:DF 3 "register_operand" "")
17277 (match_operand:DF 4 "nonimmediate_operand" "")))
17278 (clobber (reg:CC 17))]
17279 "SSE_REG_P (operands[0]) && reload_completed
17280 && ((operands_match_p (operands[1], operands[3])
17281 && operands_match_p (operands[2], operands[4]))
17282 || (operands_match_p (operands[1], operands[4])
17283 && operands_match_p (operands[2], operands[3])))"
17284 [(set (match_dup 0)
17285 (if_then_else:DF (gt (match_dup 1)
17286 (match_dup 2))
17287 (match_dup 1)
17288 (match_dup 2)))])
17289
17290 (define_split
17291 [(set (match_operand:DF 0 "fp_register_operand" "")
17292 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17293 (match_operand:DF 2 "register_operand" ""))
17294 (match_operand:DF 3 "register_operand" "")
17295 (match_operand:DF 4 "register_operand" "")))
17296 (clobber (reg:CC 17))]
17297 "reload_completed
17298 && ((operands_match_p (operands[1], operands[3])
17299 && operands_match_p (operands[2], operands[4]))
17300 || (operands_match_p (operands[1], operands[4])
17301 && operands_match_p (operands[2], operands[3])))"
17302 [(set (reg:CCFP 17)
17303 (compare:CCFP (match_dup 1)
17304 (match_dup 2)))
17305 (set (match_dup 0)
17306 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17307 (match_dup 1)
17308 (match_dup 2)))])
17309
17310 (define_insn "*maxdf_sse"
17311 [(set (match_operand:DF 0 "register_operand" "=Y")
17312 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17313 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17314 (match_dup 1)
17315 (match_dup 2)))]
17316 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17317 "maxsd\t{%2, %0|%0, %2}"
17318 [(set_attr "type" "sse")
17319 (set_attr "mode" "DF")])
17320 \f
17321 ;; Misc patterns (?)
17322
17323 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17324 ;; Otherwise there will be nothing to keep
17325 ;;
17326 ;; [(set (reg ebp) (reg esp))]
17327 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17328 ;; (clobber (eflags)]
17329 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17330 ;;
17331 ;; in proper program order.
17332 (define_expand "pro_epilogue_adjust_stack"
17333 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17334 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17335 (match_operand:SI 2 "immediate_operand" "i,i")))
17336 (clobber (reg:CC 17))
17337 (clobber (mem:BLK (scratch)))])]
17338 ""
17339 {
17340 if (TARGET_64BIT)
17341 {
17342 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17343 (operands[0], operands[1], operands[2]));
17344 DONE;
17345 }
17346 })
17347
17348 (define_insn "*pro_epilogue_adjust_stack_1"
17349 [(set (match_operand:SI 0 "register_operand" "=r,r")
17350 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17351 (match_operand:SI 2 "immediate_operand" "i,i")))
17352 (clobber (reg:CC 17))
17353 (clobber (mem:BLK (scratch)))]
17354 "!TARGET_64BIT"
17355 {
17356 switch (get_attr_type (insn))
17357 {
17358 case TYPE_IMOV:
17359 return "mov{l}\t{%1, %0|%0, %1}";
17360
17361 case TYPE_ALU:
17362 if (GET_CODE (operands[2]) == CONST_INT
17363 && (INTVAL (operands[2]) == 128
17364 || (INTVAL (operands[2]) < 0
17365 && INTVAL (operands[2]) != -128)))
17366 {
17367 operands[2] = GEN_INT (-INTVAL (operands[2]));
17368 return "sub{l}\t{%2, %0|%0, %2}";
17369 }
17370 return "add{l}\t{%2, %0|%0, %2}";
17371
17372 case TYPE_LEA:
17373 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17374 return "lea{l}\t{%a2, %0|%0, %a2}";
17375
17376 default:
17377 abort ();
17378 }
17379 }
17380 [(set (attr "type")
17381 (cond [(eq_attr "alternative" "0")
17382 (const_string "alu")
17383 (match_operand:SI 2 "const0_operand" "")
17384 (const_string "imov")
17385 ]
17386 (const_string "lea")))
17387 (set_attr "mode" "SI")])
17388
17389 (define_insn "pro_epilogue_adjust_stack_rex64"
17390 [(set (match_operand:DI 0 "register_operand" "=r,r")
17391 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17392 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17393 (clobber (reg:CC 17))
17394 (clobber (mem:BLK (scratch)))]
17395 "TARGET_64BIT"
17396 {
17397 switch (get_attr_type (insn))
17398 {
17399 case TYPE_IMOV:
17400 return "mov{q}\t{%1, %0|%0, %1}";
17401
17402 case TYPE_ALU:
17403 if (GET_CODE (operands[2]) == CONST_INT
17404 && (INTVAL (operands[2]) == 128
17405 || (INTVAL (operands[2]) < 0
17406 && INTVAL (operands[2]) != -128)))
17407 {
17408 operands[2] = GEN_INT (-INTVAL (operands[2]));
17409 return "sub{q}\t{%2, %0|%0, %2}";
17410 }
17411 return "add{q}\t{%2, %0|%0, %2}";
17412
17413 case TYPE_LEA:
17414 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17415 return "lea{q}\t{%a2, %0|%0, %a2}";
17416
17417 default:
17418 abort ();
17419 }
17420 }
17421 [(set (attr "type")
17422 (cond [(eq_attr "alternative" "0")
17423 (const_string "alu")
17424 (match_operand:DI 2 "const0_operand" "")
17425 (const_string "imov")
17426 ]
17427 (const_string "lea")))
17428 (set_attr "mode" "DI")])
17429
17430
17431 ;; Placeholder for the conditional moves. This one is split either to SSE
17432 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17433 ;; fact is that compares supported by the cmp??ss instructions are exactly
17434 ;; swapped of those supported by cmove sequence.
17435 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17436 ;; supported by i387 comparisons and we do need to emit two conditional moves
17437 ;; in tandem.
17438
17439 (define_insn "sse_movsfcc"
17440 [(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")
17441 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17442 [(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")
17443 (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")])
17444 (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")
17445 (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")))
17446 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17447 (clobber (reg:CC 17))]
17448 "TARGET_SSE
17449 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17450 /* Avoid combine from being smart and converting min/max
17451 instruction patterns into conditional moves. */
17452 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17453 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17454 || !rtx_equal_p (operands[4], operands[2])
17455 || !rtx_equal_p (operands[5], operands[3]))
17456 && (!TARGET_IEEE_FP
17457 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17458 "#")
17459
17460 (define_insn "sse_movsfcc_eq"
17461 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17462 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17463 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17464 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17465 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17466 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17467 (clobber (reg:CC 17))]
17468 "TARGET_SSE
17469 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17470 "#")
17471
17472 (define_insn "sse_movdfcc"
17473 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
17474 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17475 [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
17476 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
17477 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
17478 (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
17479 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17480 (clobber (reg:CC 17))]
17481 "TARGET_SSE2
17482 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17483 /* Avoid combine from being smart and converting min/max
17484 instruction patterns into conditional moves. */
17485 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17486 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17487 || !rtx_equal_p (operands[4], operands[2])
17488 || !rtx_equal_p (operands[5], operands[3]))
17489 && (!TARGET_IEEE_FP
17490 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17491 "#")
17492
17493 (define_insn "sse_movdfcc_eq"
17494 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17495 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17496 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17497 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17498 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17499 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17500 (clobber (reg:CC 17))]
17501 "TARGET_SSE
17502 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17503 "#")
17504
17505 ;; For non-sse moves just expand the usual cmove sequence.
17506 (define_split
17507 [(set (match_operand 0 "register_operand" "")
17508 (if_then_else (match_operator 1 "comparison_operator"
17509 [(match_operand 4 "nonimmediate_operand" "")
17510 (match_operand 5 "register_operand" "")])
17511 (match_operand 2 "nonimmediate_operand" "")
17512 (match_operand 3 "nonimmediate_operand" "")))
17513 (clobber (match_operand 6 "" ""))
17514 (clobber (reg:CC 17))]
17515 "!SSE_REG_P (operands[0]) && reload_completed
17516 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17517 [(const_int 0)]
17518 {
17519 ix86_compare_op0 = operands[5];
17520 ix86_compare_op1 = operands[4];
17521 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17522 VOIDmode, operands[5], operands[4]);
17523 ix86_expand_fp_movcc (operands);
17524 DONE;
17525 })
17526
17527 ;; Split SSE based conditional move into sequence:
17528 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17529 ;; and op2, op0 - zero op2 if comparison was false
17530 ;; nand op0, op3 - load op3 to op0 if comparison was false
17531 ;; or op2, op0 - get the nonzero one into the result.
17532 (define_split
17533 [(set (match_operand 0 "register_operand" "")
17534 (if_then_else (match_operator 1 "sse_comparison_operator"
17535 [(match_operand 4 "register_operand" "")
17536 (match_operand 5 "nonimmediate_operand" "")])
17537 (match_operand 2 "register_operand" "")
17538 (match_operand 3 "register_operand" "")))
17539 (clobber (match_operand 6 "" ""))
17540 (clobber (reg:CC 17))]
17541 "SSE_REG_P (operands[0]) && reload_completed"
17542 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17543 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17544 (subreg:TI (match_dup 4) 0)))
17545 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17546 (subreg:TI (match_dup 3) 0)))
17547 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17548 (subreg:TI (match_dup 7) 0)))]
17549 {
17550 if (GET_MODE (operands[2]) == DFmode
17551 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17552 {
17553 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17554 emit_insn (gen_sse2_unpcklpd (op, op, op));
17555 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17556 emit_insn (gen_sse2_unpcklpd (op, op, op));
17557 }
17558
17559 /* If op2 == op3, op3 would be clobbered before it is used. */
17560 if (operands_match_p (operands[2], operands[3]))
17561 {
17562 emit_move_insn (operands[0], operands[2]);
17563 DONE;
17564 }
17565
17566 PUT_MODE (operands[1], GET_MODE (operands[0]));
17567 if (operands_match_p (operands[0], operands[4]))
17568 operands[6] = operands[4], operands[7] = operands[2];
17569 else
17570 operands[6] = operands[2], operands[7] = operands[4];
17571 })
17572
17573 ;; Special case of conditional move we can handle effectively.
17574 ;; Do not brother with the integer/floating point case, since these are
17575 ;; bot considerably slower, unlike in the generic case.
17576 (define_insn "*sse_movsfcc_const0_1"
17577 [(set (match_operand:SF 0 "register_operand" "=&x")
17578 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17579 [(match_operand:SF 4 "register_operand" "0")
17580 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17581 (match_operand:SF 2 "register_operand" "x")
17582 (match_operand:SF 3 "const0_operand" "X")))]
17583 "TARGET_SSE"
17584 "#")
17585
17586 (define_insn "*sse_movsfcc_const0_2"
17587 [(set (match_operand:SF 0 "register_operand" "=&x")
17588 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17589 [(match_operand:SF 4 "register_operand" "0")
17590 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17591 (match_operand:SF 2 "const0_operand" "X")
17592 (match_operand:SF 3 "register_operand" "x")))]
17593 "TARGET_SSE"
17594 "#")
17595
17596 (define_insn "*sse_movsfcc_const0_3"
17597 [(set (match_operand:SF 0 "register_operand" "=&x")
17598 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17599 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17600 (match_operand:SF 5 "register_operand" "0")])
17601 (match_operand:SF 2 "register_operand" "x")
17602 (match_operand:SF 3 "const0_operand" "X")))]
17603 "TARGET_SSE"
17604 "#")
17605
17606 (define_insn "*sse_movsfcc_const0_4"
17607 [(set (match_operand:SF 0 "register_operand" "=&x")
17608 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17609 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17610 (match_operand:SF 5 "register_operand" "0")])
17611 (match_operand:SF 2 "const0_operand" "X")
17612 (match_operand:SF 3 "register_operand" "x")))]
17613 "TARGET_SSE"
17614 "#")
17615
17616 (define_insn "*sse_movdfcc_const0_1"
17617 [(set (match_operand:DF 0 "register_operand" "=&Y")
17618 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17619 [(match_operand:DF 4 "register_operand" "0")
17620 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17621 (match_operand:DF 2 "register_operand" "Y")
17622 (match_operand:DF 3 "const0_operand" "X")))]
17623 "TARGET_SSE2"
17624 "#")
17625
17626 (define_insn "*sse_movdfcc_const0_2"
17627 [(set (match_operand:DF 0 "register_operand" "=&Y")
17628 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17629 [(match_operand:DF 4 "register_operand" "0")
17630 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17631 (match_operand:DF 2 "const0_operand" "X")
17632 (match_operand:DF 3 "register_operand" "Y")))]
17633 "TARGET_SSE2"
17634 "#")
17635
17636 (define_insn "*sse_movdfcc_const0_3"
17637 [(set (match_operand:DF 0 "register_operand" "=&Y")
17638 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17639 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17640 (match_operand:DF 5 "register_operand" "0")])
17641 (match_operand:DF 2 "register_operand" "Y")
17642 (match_operand:DF 3 "const0_operand" "X")))]
17643 "TARGET_SSE2"
17644 "#")
17645
17646 (define_insn "*sse_movdfcc_const0_4"
17647 [(set (match_operand:DF 0 "register_operand" "=&Y")
17648 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17649 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17650 (match_operand:DF 5 "register_operand" "0")])
17651 (match_operand:DF 2 "const0_operand" "X")
17652 (match_operand:DF 3 "register_operand" "Y")))]
17653 "TARGET_SSE2"
17654 "#")
17655
17656 (define_split
17657 [(set (match_operand 0 "register_operand" "")
17658 (if_then_else (match_operator 1 "comparison_operator"
17659 [(match_operand 4 "nonimmediate_operand" "")
17660 (match_operand 5 "nonimmediate_operand" "")])
17661 (match_operand 2 "nonmemory_operand" "")
17662 (match_operand 3 "nonmemory_operand" "")))]
17663 "SSE_REG_P (operands[0]) && reload_completed
17664 && (const0_operand (operands[2], GET_MODE (operands[0]))
17665 || const0_operand (operands[3], GET_MODE (operands[0])))"
17666 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17667 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17668 (match_dup 7)))]
17669 {
17670 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17671 && GET_MODE (operands[2]) == DFmode)
17672 {
17673 if (REG_P (operands[2]))
17674 {
17675 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17676 emit_insn (gen_sse2_unpcklpd (op, op, op));
17677 }
17678 if (REG_P (operands[3]))
17679 {
17680 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17681 emit_insn (gen_sse2_unpcklpd (op, op, op));
17682 }
17683 }
17684 PUT_MODE (operands[1], GET_MODE (operands[0]));
17685 if (!sse_comparison_operator (operands[1], VOIDmode)
17686 || !rtx_equal_p (operands[0], operands[4]))
17687 {
17688 rtx tmp = operands[5];
17689 operands[5] = operands[4];
17690 operands[4] = tmp;
17691 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17692 }
17693 if (!rtx_equal_p (operands[0], operands[4]))
17694 abort ();
17695 if (const0_operand (operands[2], GET_MODE (operands[0])))
17696 {
17697 operands[7] = operands[3];
17698 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17699 0));
17700 }
17701 else
17702 {
17703 operands[7] = operands[2];
17704 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17705 }
17706 operands[7] = simplify_gen_subreg (TImode, operands[7],
17707 GET_MODE (operands[7]), 0);
17708 })
17709
17710 (define_expand "allocate_stack_worker"
17711 [(match_operand:SI 0 "register_operand" "")]
17712 "TARGET_STACK_PROBE"
17713 {
17714 if (TARGET_64BIT)
17715 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17716 else
17717 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17718 DONE;
17719 })
17720
17721 (define_insn "allocate_stack_worker_1"
17722 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17723 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17724 (clobber (match_dup 0))
17725 (clobber (reg:CC 17))]
17726 "!TARGET_64BIT && TARGET_STACK_PROBE"
17727 "call\t__alloca"
17728 [(set_attr "type" "multi")
17729 (set_attr "length" "5")])
17730
17731 (define_insn "allocate_stack_worker_rex64"
17732 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17733 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17734 (clobber (match_dup 0))
17735 (clobber (reg:CC 17))]
17736 "TARGET_64BIT && TARGET_STACK_PROBE"
17737 "call\t__alloca"
17738 [(set_attr "type" "multi")
17739 (set_attr "length" "5")])
17740
17741 (define_expand "allocate_stack"
17742 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17743 (minus:SI (reg:SI 7)
17744 (match_operand:SI 1 "general_operand" "")))
17745 (clobber (reg:CC 17))])
17746 (parallel [(set (reg:SI 7)
17747 (minus:SI (reg:SI 7) (match_dup 1)))
17748 (clobber (reg:CC 17))])]
17749 "TARGET_STACK_PROBE"
17750 {
17751 #ifdef CHECK_STACK_LIMIT
17752 if (GET_CODE (operands[1]) == CONST_INT
17753 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17754 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17755 operands[1]));
17756 else
17757 #endif
17758 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17759 operands[1])));
17760
17761 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17762 DONE;
17763 })
17764
17765 (define_expand "builtin_setjmp_receiver"
17766 [(label_ref (match_operand 0 "" ""))]
17767 "!TARGET_64BIT && flag_pic"
17768 {
17769 emit_insn (gen_set_got (pic_offset_table_rtx));
17770 DONE;
17771 })
17772 \f
17773 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17774
17775 (define_split
17776 [(set (match_operand 0 "register_operand" "")
17777 (match_operator 3 "promotable_binary_operator"
17778 [(match_operand 1 "register_operand" "")
17779 (match_operand 2 "aligned_operand" "")]))
17780 (clobber (reg:CC 17))]
17781 "! TARGET_PARTIAL_REG_STALL && reload_completed
17782 && ((GET_MODE (operands[0]) == HImode
17783 && ((!optimize_size && !TARGET_FAST_PREFIX)
17784 || GET_CODE (operands[2]) != CONST_INT
17785 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17786 || (GET_MODE (operands[0]) == QImode
17787 && (TARGET_PROMOTE_QImode || optimize_size)))"
17788 [(parallel [(set (match_dup 0)
17789 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17790 (clobber (reg:CC 17))])]
17791 "operands[0] = gen_lowpart (SImode, operands[0]);
17792 operands[1] = gen_lowpart (SImode, operands[1]);
17793 if (GET_CODE (operands[3]) != ASHIFT)
17794 operands[2] = gen_lowpart (SImode, operands[2]);
17795 PUT_MODE (operands[3], SImode);")
17796
17797 ; Promote the QImode tests, as i386 has encoding of the AND
17798 ; instruction with 32-bit sign-extended immediate and thus the
17799 ; instruction size is unchanged, except in the %eax case for
17800 ; which it is increased by one byte, hence the ! optimize_size.
17801 (define_split
17802 [(set (reg 17)
17803 (compare (and (match_operand 1 "aligned_operand" "")
17804 (match_operand 2 "const_int_operand" ""))
17805 (const_int 0)))
17806 (set (match_operand 0 "register_operand" "")
17807 (and (match_dup 1) (match_dup 2)))]
17808 "! TARGET_PARTIAL_REG_STALL && reload_completed
17809 /* Ensure that the operand will remain sign-extended immediate. */
17810 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17811 && ! optimize_size
17812 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17813 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17814 [(parallel [(set (reg:CCNO 17)
17815 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17816 (const_int 0)))
17817 (set (match_dup 0)
17818 (and:SI (match_dup 1) (match_dup 2)))])]
17819 "operands[2]
17820 = gen_int_mode (INTVAL (operands[2])
17821 & GET_MODE_MASK (GET_MODE (operands[0])),
17822 SImode);
17823 operands[0] = gen_lowpart (SImode, operands[0]);
17824 operands[1] = gen_lowpart (SImode, operands[1]);")
17825
17826 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17827 ; the TEST instruction with 32-bit sign-extended immediate and thus
17828 ; the instruction size would at least double, which is not what we
17829 ; want even with ! optimize_size.
17830 (define_split
17831 [(set (reg 17)
17832 (compare (and (match_operand:HI 0 "aligned_operand" "")
17833 (match_operand:HI 1 "const_int_operand" ""))
17834 (const_int 0)))]
17835 "! TARGET_PARTIAL_REG_STALL && reload_completed
17836 /* Ensure that the operand will remain sign-extended immediate. */
17837 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17838 && ! TARGET_FAST_PREFIX
17839 && ! optimize_size"
17840 [(set (reg:CCNO 17)
17841 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17842 (const_int 0)))]
17843 "operands[1]
17844 = gen_int_mode (INTVAL (operands[1])
17845 & GET_MODE_MASK (GET_MODE (operands[0])),
17846 SImode);
17847 operands[0] = gen_lowpart (SImode, operands[0]);")
17848
17849 (define_split
17850 [(set (match_operand 0 "register_operand" "")
17851 (neg (match_operand 1 "register_operand" "")))
17852 (clobber (reg:CC 17))]
17853 "! TARGET_PARTIAL_REG_STALL && reload_completed
17854 && (GET_MODE (operands[0]) == HImode
17855 || (GET_MODE (operands[0]) == QImode
17856 && (TARGET_PROMOTE_QImode || optimize_size)))"
17857 [(parallel [(set (match_dup 0)
17858 (neg:SI (match_dup 1)))
17859 (clobber (reg:CC 17))])]
17860 "operands[0] = gen_lowpart (SImode, operands[0]);
17861 operands[1] = gen_lowpart (SImode, operands[1]);")
17862
17863 (define_split
17864 [(set (match_operand 0 "register_operand" "")
17865 (not (match_operand 1 "register_operand" "")))]
17866 "! TARGET_PARTIAL_REG_STALL && reload_completed
17867 && (GET_MODE (operands[0]) == HImode
17868 || (GET_MODE (operands[0]) == QImode
17869 && (TARGET_PROMOTE_QImode || optimize_size)))"
17870 [(set (match_dup 0)
17871 (not:SI (match_dup 1)))]
17872 "operands[0] = gen_lowpart (SImode, operands[0]);
17873 operands[1] = gen_lowpart (SImode, operands[1]);")
17874
17875 (define_split
17876 [(set (match_operand 0 "register_operand" "")
17877 (if_then_else (match_operator 1 "comparison_operator"
17878 [(reg 17) (const_int 0)])
17879 (match_operand 2 "register_operand" "")
17880 (match_operand 3 "register_operand" "")))]
17881 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17882 && (GET_MODE (operands[0]) == HImode
17883 || (GET_MODE (operands[0]) == QImode
17884 && (TARGET_PROMOTE_QImode || optimize_size)))"
17885 [(set (match_dup 0)
17886 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17887 "operands[0] = gen_lowpart (SImode, operands[0]);
17888 operands[2] = gen_lowpart (SImode, operands[2]);
17889 operands[3] = gen_lowpart (SImode, operands[3]);")
17890
17891 \f
17892 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17893 ;; transform a complex memory operation into two memory to register operations.
17894
17895 ;; Don't push memory operands
17896 (define_peephole2
17897 [(set (match_operand:SI 0 "push_operand" "")
17898 (match_operand:SI 1 "memory_operand" ""))
17899 (match_scratch:SI 2 "r")]
17900 "! optimize_size && ! TARGET_PUSH_MEMORY"
17901 [(set (match_dup 2) (match_dup 1))
17902 (set (match_dup 0) (match_dup 2))]
17903 "")
17904
17905 (define_peephole2
17906 [(set (match_operand:DI 0 "push_operand" "")
17907 (match_operand:DI 1 "memory_operand" ""))
17908 (match_scratch:DI 2 "r")]
17909 "! optimize_size && ! TARGET_PUSH_MEMORY"
17910 [(set (match_dup 2) (match_dup 1))
17911 (set (match_dup 0) (match_dup 2))]
17912 "")
17913
17914 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17915 ;; SImode pushes.
17916 (define_peephole2
17917 [(set (match_operand:SF 0 "push_operand" "")
17918 (match_operand:SF 1 "memory_operand" ""))
17919 (match_scratch:SF 2 "r")]
17920 "! optimize_size && ! TARGET_PUSH_MEMORY"
17921 [(set (match_dup 2) (match_dup 1))
17922 (set (match_dup 0) (match_dup 2))]
17923 "")
17924
17925 (define_peephole2
17926 [(set (match_operand:HI 0 "push_operand" "")
17927 (match_operand:HI 1 "memory_operand" ""))
17928 (match_scratch:HI 2 "r")]
17929 "! optimize_size && ! TARGET_PUSH_MEMORY"
17930 [(set (match_dup 2) (match_dup 1))
17931 (set (match_dup 0) (match_dup 2))]
17932 "")
17933
17934 (define_peephole2
17935 [(set (match_operand:QI 0 "push_operand" "")
17936 (match_operand:QI 1 "memory_operand" ""))
17937 (match_scratch:QI 2 "q")]
17938 "! optimize_size && ! TARGET_PUSH_MEMORY"
17939 [(set (match_dup 2) (match_dup 1))
17940 (set (match_dup 0) (match_dup 2))]
17941 "")
17942
17943 ;; Don't move an immediate directly to memory when the instruction
17944 ;; gets too big.
17945 (define_peephole2
17946 [(match_scratch:SI 1 "r")
17947 (set (match_operand:SI 0 "memory_operand" "")
17948 (const_int 0))]
17949 "! optimize_size
17950 && ! TARGET_USE_MOV0
17951 && TARGET_SPLIT_LONG_MOVES
17952 && get_attr_length (insn) >= ix86_cost->large_insn
17953 && peep2_regno_dead_p (0, FLAGS_REG)"
17954 [(parallel [(set (match_dup 1) (const_int 0))
17955 (clobber (reg:CC 17))])
17956 (set (match_dup 0) (match_dup 1))]
17957 "")
17958
17959 (define_peephole2
17960 [(match_scratch:HI 1 "r")
17961 (set (match_operand:HI 0 "memory_operand" "")
17962 (const_int 0))]
17963 "! optimize_size
17964 && ! TARGET_USE_MOV0
17965 && TARGET_SPLIT_LONG_MOVES
17966 && get_attr_length (insn) >= ix86_cost->large_insn
17967 && peep2_regno_dead_p (0, FLAGS_REG)"
17968 [(parallel [(set (match_dup 2) (const_int 0))
17969 (clobber (reg:CC 17))])
17970 (set (match_dup 0) (match_dup 1))]
17971 "operands[2] = gen_lowpart (SImode, operands[1]);")
17972
17973 (define_peephole2
17974 [(match_scratch:QI 1 "q")
17975 (set (match_operand:QI 0 "memory_operand" "")
17976 (const_int 0))]
17977 "! optimize_size
17978 && ! TARGET_USE_MOV0
17979 && TARGET_SPLIT_LONG_MOVES
17980 && get_attr_length (insn) >= ix86_cost->large_insn
17981 && peep2_regno_dead_p (0, FLAGS_REG)"
17982 [(parallel [(set (match_dup 2) (const_int 0))
17983 (clobber (reg:CC 17))])
17984 (set (match_dup 0) (match_dup 1))]
17985 "operands[2] = gen_lowpart (SImode, operands[1]);")
17986
17987 (define_peephole2
17988 [(match_scratch:SI 2 "r")
17989 (set (match_operand:SI 0 "memory_operand" "")
17990 (match_operand:SI 1 "immediate_operand" ""))]
17991 "! optimize_size
17992 && get_attr_length (insn) >= ix86_cost->large_insn
17993 && TARGET_SPLIT_LONG_MOVES"
17994 [(set (match_dup 2) (match_dup 1))
17995 (set (match_dup 0) (match_dup 2))]
17996 "")
17997
17998 (define_peephole2
17999 [(match_scratch:HI 2 "r")
18000 (set (match_operand:HI 0 "memory_operand" "")
18001 (match_operand:HI 1 "immediate_operand" ""))]
18002 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18003 && TARGET_SPLIT_LONG_MOVES"
18004 [(set (match_dup 2) (match_dup 1))
18005 (set (match_dup 0) (match_dup 2))]
18006 "")
18007
18008 (define_peephole2
18009 [(match_scratch:QI 2 "q")
18010 (set (match_operand:QI 0 "memory_operand" "")
18011 (match_operand:QI 1 "immediate_operand" ""))]
18012 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18013 && TARGET_SPLIT_LONG_MOVES"
18014 [(set (match_dup 2) (match_dup 1))
18015 (set (match_dup 0) (match_dup 2))]
18016 "")
18017
18018 ;; Don't compare memory with zero, load and use a test instead.
18019 (define_peephole2
18020 [(set (reg 17)
18021 (compare (match_operand:SI 0 "memory_operand" "")
18022 (const_int 0)))
18023 (match_scratch:SI 3 "r")]
18024 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18025 [(set (match_dup 3) (match_dup 0))
18026 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18027 "")
18028
18029 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18030 ;; Don't split NOTs with a displacement operand, because resulting XOR
18031 ;; will not be pairable anyway.
18032 ;;
18033 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18034 ;; represented using a modRM byte. The XOR replacement is long decoded,
18035 ;; so this split helps here as well.
18036 ;;
18037 ;; Note: Can't do this as a regular split because we can't get proper
18038 ;; lifetime information then.
18039
18040 (define_peephole2
18041 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18042 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18043 "!optimize_size
18044 && peep2_regno_dead_p (0, FLAGS_REG)
18045 && ((TARGET_PENTIUM
18046 && (GET_CODE (operands[0]) != MEM
18047 || !memory_displacement_operand (operands[0], SImode)))
18048 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18049 [(parallel [(set (match_dup 0)
18050 (xor:SI (match_dup 1) (const_int -1)))
18051 (clobber (reg:CC 17))])]
18052 "")
18053
18054 (define_peephole2
18055 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18056 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18057 "!optimize_size
18058 && peep2_regno_dead_p (0, FLAGS_REG)
18059 && ((TARGET_PENTIUM
18060 && (GET_CODE (operands[0]) != MEM
18061 || !memory_displacement_operand (operands[0], HImode)))
18062 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18063 [(parallel [(set (match_dup 0)
18064 (xor:HI (match_dup 1) (const_int -1)))
18065 (clobber (reg:CC 17))])]
18066 "")
18067
18068 (define_peephole2
18069 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18070 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18071 "!optimize_size
18072 && peep2_regno_dead_p (0, FLAGS_REG)
18073 && ((TARGET_PENTIUM
18074 && (GET_CODE (operands[0]) != MEM
18075 || !memory_displacement_operand (operands[0], QImode)))
18076 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18077 [(parallel [(set (match_dup 0)
18078 (xor:QI (match_dup 1) (const_int -1)))
18079 (clobber (reg:CC 17))])]
18080 "")
18081
18082 ;; Non pairable "test imm, reg" instructions can be translated to
18083 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18084 ;; byte opcode instead of two, have a short form for byte operands),
18085 ;; so do it for other CPUs as well. Given that the value was dead,
18086 ;; this should not create any new dependencies. Pass on the sub-word
18087 ;; versions if we're concerned about partial register stalls.
18088
18089 (define_peephole2
18090 [(set (reg 17)
18091 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18092 (match_operand:SI 1 "immediate_operand" ""))
18093 (const_int 0)))]
18094 "ix86_match_ccmode (insn, CCNOmode)
18095 && (true_regnum (operands[0]) != 0
18096 || (GET_CODE (operands[1]) == CONST_INT
18097 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18098 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18099 [(parallel
18100 [(set (reg:CCNO 17)
18101 (compare:CCNO (and:SI (match_dup 0)
18102 (match_dup 1))
18103 (const_int 0)))
18104 (set (match_dup 0)
18105 (and:SI (match_dup 0) (match_dup 1)))])]
18106 "")
18107
18108 ;; We don't need to handle HImode case, because it will be promoted to SImode
18109 ;; on ! TARGET_PARTIAL_REG_STALL
18110
18111 (define_peephole2
18112 [(set (reg 17)
18113 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18114 (match_operand:QI 1 "immediate_operand" ""))
18115 (const_int 0)))]
18116 "! TARGET_PARTIAL_REG_STALL
18117 && ix86_match_ccmode (insn, CCNOmode)
18118 && true_regnum (operands[0]) != 0
18119 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18120 [(parallel
18121 [(set (reg:CCNO 17)
18122 (compare:CCNO (and:QI (match_dup 0)
18123 (match_dup 1))
18124 (const_int 0)))
18125 (set (match_dup 0)
18126 (and:QI (match_dup 0) (match_dup 1)))])]
18127 "")
18128
18129 (define_peephole2
18130 [(set (reg 17)
18131 (compare
18132 (and:SI
18133 (zero_extract:SI
18134 (match_operand 0 "ext_register_operand" "")
18135 (const_int 8)
18136 (const_int 8))
18137 (match_operand 1 "const_int_operand" ""))
18138 (const_int 0)))]
18139 "! TARGET_PARTIAL_REG_STALL
18140 && ix86_match_ccmode (insn, CCNOmode)
18141 && true_regnum (operands[0]) != 0
18142 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18143 [(parallel [(set (reg:CCNO 17)
18144 (compare:CCNO
18145 (and:SI
18146 (zero_extract:SI
18147 (match_dup 0)
18148 (const_int 8)
18149 (const_int 8))
18150 (match_dup 1))
18151 (const_int 0)))
18152 (set (zero_extract:SI (match_dup 0)
18153 (const_int 8)
18154 (const_int 8))
18155 (and:SI
18156 (zero_extract:SI
18157 (match_dup 0)
18158 (const_int 8)
18159 (const_int 8))
18160 (match_dup 1)))])]
18161 "")
18162
18163 ;; Don't do logical operations with memory inputs.
18164 (define_peephole2
18165 [(match_scratch:SI 2 "r")
18166 (parallel [(set (match_operand:SI 0 "register_operand" "")
18167 (match_operator:SI 3 "arith_or_logical_operator"
18168 [(match_dup 0)
18169 (match_operand:SI 1 "memory_operand" "")]))
18170 (clobber (reg:CC 17))])]
18171 "! optimize_size && ! TARGET_READ_MODIFY"
18172 [(set (match_dup 2) (match_dup 1))
18173 (parallel [(set (match_dup 0)
18174 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18175 (clobber (reg:CC 17))])]
18176 "")
18177
18178 (define_peephole2
18179 [(match_scratch:SI 2 "r")
18180 (parallel [(set (match_operand:SI 0 "register_operand" "")
18181 (match_operator:SI 3 "arith_or_logical_operator"
18182 [(match_operand:SI 1 "memory_operand" "")
18183 (match_dup 0)]))
18184 (clobber (reg:CC 17))])]
18185 "! optimize_size && ! TARGET_READ_MODIFY"
18186 [(set (match_dup 2) (match_dup 1))
18187 (parallel [(set (match_dup 0)
18188 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18189 (clobber (reg:CC 17))])]
18190 "")
18191
18192 ; Don't do logical operations with memory outputs
18193 ;
18194 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18195 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18196 ; the same decoder scheduling characteristics as the original.
18197
18198 (define_peephole2
18199 [(match_scratch:SI 2 "r")
18200 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18201 (match_operator:SI 3 "arith_or_logical_operator"
18202 [(match_dup 0)
18203 (match_operand:SI 1 "nonmemory_operand" "")]))
18204 (clobber (reg:CC 17))])]
18205 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18206 [(set (match_dup 2) (match_dup 0))
18207 (parallel [(set (match_dup 2)
18208 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18209 (clobber (reg:CC 17))])
18210 (set (match_dup 0) (match_dup 2))]
18211 "")
18212
18213 (define_peephole2
18214 [(match_scratch:SI 2 "r")
18215 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18216 (match_operator:SI 3 "arith_or_logical_operator"
18217 [(match_operand:SI 1 "nonmemory_operand" "")
18218 (match_dup 0)]))
18219 (clobber (reg:CC 17))])]
18220 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18221 [(set (match_dup 2) (match_dup 0))
18222 (parallel [(set (match_dup 2)
18223 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18224 (clobber (reg:CC 17))])
18225 (set (match_dup 0) (match_dup 2))]
18226 "")
18227
18228 ;; Attempt to always use XOR for zeroing registers.
18229 (define_peephole2
18230 [(set (match_operand 0 "register_operand" "")
18231 (const_int 0))]
18232 "(GET_MODE (operands[0]) == QImode
18233 || GET_MODE (operands[0]) == HImode
18234 || GET_MODE (operands[0]) == SImode
18235 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18236 && (! TARGET_USE_MOV0 || optimize_size)
18237 && peep2_regno_dead_p (0, FLAGS_REG)"
18238 [(parallel [(set (match_dup 0) (const_int 0))
18239 (clobber (reg:CC 17))])]
18240 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18241 operands[0]);")
18242
18243 (define_peephole2
18244 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18245 (const_int 0))]
18246 "(GET_MODE (operands[0]) == QImode
18247 || GET_MODE (operands[0]) == HImode)
18248 && (! TARGET_USE_MOV0 || optimize_size)
18249 && peep2_regno_dead_p (0, FLAGS_REG)"
18250 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18251 (clobber (reg:CC 17))])])
18252
18253 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18254 (define_peephole2
18255 [(set (match_operand 0 "register_operand" "")
18256 (const_int -1))]
18257 "(GET_MODE (operands[0]) == HImode
18258 || GET_MODE (operands[0]) == SImode
18259 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18260 && (optimize_size || TARGET_PENTIUM)
18261 && peep2_regno_dead_p (0, FLAGS_REG)"
18262 [(parallel [(set (match_dup 0) (const_int -1))
18263 (clobber (reg:CC 17))])]
18264 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18265 operands[0]);")
18266
18267 ;; Attempt to convert simple leas to adds. These can be created by
18268 ;; move expanders.
18269 (define_peephole2
18270 [(set (match_operand:SI 0 "register_operand" "")
18271 (plus:SI (match_dup 0)
18272 (match_operand:SI 1 "nonmemory_operand" "")))]
18273 "peep2_regno_dead_p (0, FLAGS_REG)"
18274 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18275 (clobber (reg:CC 17))])]
18276 "")
18277
18278 (define_peephole2
18279 [(set (match_operand:SI 0 "register_operand" "")
18280 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18281 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18282 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18283 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18284 (clobber (reg:CC 17))])]
18285 "operands[2] = gen_lowpart (SImode, operands[2]);")
18286
18287 (define_peephole2
18288 [(set (match_operand:DI 0 "register_operand" "")
18289 (plus:DI (match_dup 0)
18290 (match_operand:DI 1 "x86_64_general_operand" "")))]
18291 "peep2_regno_dead_p (0, FLAGS_REG)"
18292 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18293 (clobber (reg:CC 17))])]
18294 "")
18295
18296 (define_peephole2
18297 [(set (match_operand:SI 0 "register_operand" "")
18298 (mult:SI (match_dup 0)
18299 (match_operand:SI 1 "const_int_operand" "")))]
18300 "exact_log2 (INTVAL (operands[1])) >= 0
18301 && peep2_regno_dead_p (0, FLAGS_REG)"
18302 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18303 (clobber (reg:CC 17))])]
18304 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18305
18306 (define_peephole2
18307 [(set (match_operand:DI 0 "register_operand" "")
18308 (mult:DI (match_dup 0)
18309 (match_operand:DI 1 "const_int_operand" "")))]
18310 "exact_log2 (INTVAL (operands[1])) >= 0
18311 && peep2_regno_dead_p (0, FLAGS_REG)"
18312 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18313 (clobber (reg:CC 17))])]
18314 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18315
18316 (define_peephole2
18317 [(set (match_operand:SI 0 "register_operand" "")
18318 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18319 (match_operand:DI 2 "const_int_operand" "")) 0))]
18320 "exact_log2 (INTVAL (operands[2])) >= 0
18321 && REGNO (operands[0]) == REGNO (operands[1])
18322 && peep2_regno_dead_p (0, FLAGS_REG)"
18323 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18324 (clobber (reg:CC 17))])]
18325 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18326
18327 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18328 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18329 ;; many CPUs it is also faster, since special hardware to avoid esp
18330 ;; dependencies is present.
18331
18332 ;; While some of these conversions may be done using splitters, we use peepholes
18333 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18334
18335 ;; Convert prologue esp subtractions to push.
18336 ;; We need register to push. In order to keep verify_flow_info happy we have
18337 ;; two choices
18338 ;; - use scratch and clobber it in order to avoid dependencies
18339 ;; - use already live register
18340 ;; We can't use the second way right now, since there is no reliable way how to
18341 ;; verify that given register is live. First choice will also most likely in
18342 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18343 ;; call clobbered registers are dead. We may want to use base pointer as an
18344 ;; alternative when no register is available later.
18345
18346 (define_peephole2
18347 [(match_scratch:SI 0 "r")
18348 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18349 (clobber (reg:CC 17))
18350 (clobber (mem:BLK (scratch)))])]
18351 "optimize_size || !TARGET_SUB_ESP_4"
18352 [(clobber (match_dup 0))
18353 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18354 (clobber (mem:BLK (scratch)))])])
18355
18356 (define_peephole2
18357 [(match_scratch:SI 0 "r")
18358 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18359 (clobber (reg:CC 17))
18360 (clobber (mem:BLK (scratch)))])]
18361 "optimize_size || !TARGET_SUB_ESP_8"
18362 [(clobber (match_dup 0))
18363 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18364 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18365 (clobber (mem:BLK (scratch)))])])
18366
18367 ;; Convert esp subtractions to push.
18368 (define_peephole2
18369 [(match_scratch:SI 0 "r")
18370 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18371 (clobber (reg:CC 17))])]
18372 "optimize_size || !TARGET_SUB_ESP_4"
18373 [(clobber (match_dup 0))
18374 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18375
18376 (define_peephole2
18377 [(match_scratch:SI 0 "r")
18378 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18379 (clobber (reg:CC 17))])]
18380 "optimize_size || !TARGET_SUB_ESP_8"
18381 [(clobber (match_dup 0))
18382 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18383 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18384
18385 ;; Convert epilogue deallocator to pop.
18386 (define_peephole2
18387 [(match_scratch:SI 0 "r")
18388 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18389 (clobber (reg:CC 17))
18390 (clobber (mem:BLK (scratch)))])]
18391 "optimize_size || !TARGET_ADD_ESP_4"
18392 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18393 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18394 (clobber (mem:BLK (scratch)))])]
18395 "")
18396
18397 ;; Two pops case is tricky, since pop causes dependency on destination register.
18398 ;; We use two registers if available.
18399 (define_peephole2
18400 [(match_scratch:SI 0 "r")
18401 (match_scratch:SI 1 "r")
18402 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18403 (clobber (reg:CC 17))
18404 (clobber (mem:BLK (scratch)))])]
18405 "optimize_size || !TARGET_ADD_ESP_8"
18406 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18407 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18408 (clobber (mem:BLK (scratch)))])
18409 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18410 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18411 "")
18412
18413 (define_peephole2
18414 [(match_scratch:SI 0 "r")
18415 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18416 (clobber (reg:CC 17))
18417 (clobber (mem:BLK (scratch)))])]
18418 "optimize_size"
18419 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18420 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18421 (clobber (mem:BLK (scratch)))])
18422 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18423 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18424 "")
18425
18426 ;; Convert esp additions to pop.
18427 (define_peephole2
18428 [(match_scratch:SI 0 "r")
18429 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18430 (clobber (reg:CC 17))])]
18431 ""
18432 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18433 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18434 "")
18435
18436 ;; Two pops case is tricky, since pop causes dependency on destination register.
18437 ;; We use two registers if available.
18438 (define_peephole2
18439 [(match_scratch:SI 0 "r")
18440 (match_scratch:SI 1 "r")
18441 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18442 (clobber (reg:CC 17))])]
18443 ""
18444 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18445 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18446 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18447 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18448 "")
18449
18450 (define_peephole2
18451 [(match_scratch:SI 0 "r")
18452 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18453 (clobber (reg:CC 17))])]
18454 "optimize_size"
18455 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18456 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18457 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18458 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18459 "")
18460 \f
18461 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18462 ;; required and register dies.
18463 (define_peephole2
18464 [(set (reg 17)
18465 (compare (match_operand:SI 0 "register_operand" "")
18466 (match_operand:SI 1 "incdec_operand" "")))]
18467 "ix86_match_ccmode (insn, CCGCmode)
18468 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18469 [(parallel [(set (reg:CCGC 17)
18470 (compare:CCGC (match_dup 0)
18471 (match_dup 1)))
18472 (clobber (match_dup 0))])]
18473 "")
18474
18475 (define_peephole2
18476 [(set (reg 17)
18477 (compare (match_operand:HI 0 "register_operand" "")
18478 (match_operand:HI 1 "incdec_operand" "")))]
18479 "ix86_match_ccmode (insn, CCGCmode)
18480 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18481 [(parallel [(set (reg:CCGC 17)
18482 (compare:CCGC (match_dup 0)
18483 (match_dup 1)))
18484 (clobber (match_dup 0))])]
18485 "")
18486
18487 (define_peephole2
18488 [(set (reg 17)
18489 (compare (match_operand:QI 0 "register_operand" "")
18490 (match_operand:QI 1 "incdec_operand" "")))]
18491 "ix86_match_ccmode (insn, CCGCmode)
18492 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18493 [(parallel [(set (reg:CCGC 17)
18494 (compare:CCGC (match_dup 0)
18495 (match_dup 1)))
18496 (clobber (match_dup 0))])]
18497 "")
18498
18499 ;; Convert compares with 128 to shorter add -128
18500 (define_peephole2
18501 [(set (reg 17)
18502 (compare (match_operand:SI 0 "register_operand" "")
18503 (const_int 128)))]
18504 "ix86_match_ccmode (insn, CCGCmode)
18505 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18506 [(parallel [(set (reg:CCGC 17)
18507 (compare:CCGC (match_dup 0)
18508 (const_int 128)))
18509 (clobber (match_dup 0))])]
18510 "")
18511
18512 (define_peephole2
18513 [(set (reg 17)
18514 (compare (match_operand:HI 0 "register_operand" "")
18515 (const_int 128)))]
18516 "ix86_match_ccmode (insn, CCGCmode)
18517 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18518 [(parallel [(set (reg:CCGC 17)
18519 (compare:CCGC (match_dup 0)
18520 (const_int 128)))
18521 (clobber (match_dup 0))])]
18522 "")
18523 \f
18524 (define_peephole2
18525 [(match_scratch:DI 0 "r")
18526 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18527 (clobber (reg:CC 17))
18528 (clobber (mem:BLK (scratch)))])]
18529 "optimize_size || !TARGET_SUB_ESP_4"
18530 [(clobber (match_dup 0))
18531 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18532 (clobber (mem:BLK (scratch)))])])
18533
18534 (define_peephole2
18535 [(match_scratch:DI 0 "r")
18536 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18537 (clobber (reg:CC 17))
18538 (clobber (mem:BLK (scratch)))])]
18539 "optimize_size || !TARGET_SUB_ESP_8"
18540 [(clobber (match_dup 0))
18541 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18542 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18543 (clobber (mem:BLK (scratch)))])])
18544
18545 ;; Convert esp subtractions to push.
18546 (define_peephole2
18547 [(match_scratch:DI 0 "r")
18548 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18549 (clobber (reg:CC 17))])]
18550 "optimize_size || !TARGET_SUB_ESP_4"
18551 [(clobber (match_dup 0))
18552 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18553
18554 (define_peephole2
18555 [(match_scratch:DI 0 "r")
18556 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18557 (clobber (reg:CC 17))])]
18558 "optimize_size || !TARGET_SUB_ESP_8"
18559 [(clobber (match_dup 0))
18560 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18561 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18562
18563 ;; Convert epilogue deallocator to pop.
18564 (define_peephole2
18565 [(match_scratch:DI 0 "r")
18566 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18567 (clobber (reg:CC 17))
18568 (clobber (mem:BLK (scratch)))])]
18569 "optimize_size || !TARGET_ADD_ESP_4"
18570 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18571 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18572 (clobber (mem:BLK (scratch)))])]
18573 "")
18574
18575 ;; Two pops case is tricky, since pop causes dependency on destination register.
18576 ;; We use two registers if available.
18577 (define_peephole2
18578 [(match_scratch:DI 0 "r")
18579 (match_scratch:DI 1 "r")
18580 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18581 (clobber (reg:CC 17))
18582 (clobber (mem:BLK (scratch)))])]
18583 "optimize_size || !TARGET_ADD_ESP_8"
18584 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18585 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18586 (clobber (mem:BLK (scratch)))])
18587 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18588 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18589 "")
18590
18591 (define_peephole2
18592 [(match_scratch:DI 0 "r")
18593 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18594 (clobber (reg:CC 17))
18595 (clobber (mem:BLK (scratch)))])]
18596 "optimize_size"
18597 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18598 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18599 (clobber (mem:BLK (scratch)))])
18600 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18601 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18602 "")
18603
18604 ;; Convert esp additions to pop.
18605 (define_peephole2
18606 [(match_scratch:DI 0 "r")
18607 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18608 (clobber (reg:CC 17))])]
18609 ""
18610 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18611 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18612 "")
18613
18614 ;; Two pops case is tricky, since pop causes dependency on destination register.
18615 ;; We use two registers if available.
18616 (define_peephole2
18617 [(match_scratch:DI 0 "r")
18618 (match_scratch:DI 1 "r")
18619 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18620 (clobber (reg:CC 17))])]
18621 ""
18622 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18623 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18624 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18625 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18626 "")
18627
18628 (define_peephole2
18629 [(match_scratch:DI 0 "r")
18630 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18631 (clobber (reg:CC 17))])]
18632 "optimize_size"
18633 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18634 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18635 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18636 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18637 "")
18638 \f
18639 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18640 ;; imul $32bit_imm, reg, reg is direct decoded.
18641 (define_peephole2
18642 [(match_scratch:DI 3 "r")
18643 (parallel [(set (match_operand:DI 0 "register_operand" "")
18644 (mult:DI (match_operand:DI 1 "memory_operand" "")
18645 (match_operand:DI 2 "immediate_operand" "")))
18646 (clobber (reg:CC 17))])]
18647 "TARGET_K8 && !optimize_size
18648 && (GET_CODE (operands[2]) != CONST_INT
18649 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18650 [(set (match_dup 3) (match_dup 1))
18651 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18652 (clobber (reg:CC 17))])]
18653 "")
18654
18655 (define_peephole2
18656 [(match_scratch:SI 3 "r")
18657 (parallel [(set (match_operand:SI 0 "register_operand" "")
18658 (mult:SI (match_operand:SI 1 "memory_operand" "")
18659 (match_operand:SI 2 "immediate_operand" "")))
18660 (clobber (reg:CC 17))])]
18661 "TARGET_K8 && !optimize_size
18662 && (GET_CODE (operands[2]) != CONST_INT
18663 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18664 [(set (match_dup 3) (match_dup 1))
18665 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18666 (clobber (reg:CC 17))])]
18667 "")
18668
18669 (define_peephole2
18670 [(match_scratch:SI 3 "r")
18671 (parallel [(set (match_operand:DI 0 "register_operand" "")
18672 (zero_extend:DI
18673 (mult:SI (match_operand:SI 1 "memory_operand" "")
18674 (match_operand:SI 2 "immediate_operand" ""))))
18675 (clobber (reg:CC 17))])]
18676 "TARGET_K8 && !optimize_size
18677 && (GET_CODE (operands[2]) != CONST_INT
18678 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18679 [(set (match_dup 3) (match_dup 1))
18680 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18681 (clobber (reg:CC 17))])]
18682 "")
18683
18684 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18685 ;; Convert it into imul reg, reg
18686 ;; It would be better to force assembler to encode instruction using long
18687 ;; immediate, but there is apparently no way to do so.
18688 (define_peephole2
18689 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18690 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18691 (match_operand:DI 2 "const_int_operand" "")))
18692 (clobber (reg:CC 17))])
18693 (match_scratch:DI 3 "r")]
18694 "TARGET_K8 && !optimize_size
18695 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18696 [(set (match_dup 3) (match_dup 2))
18697 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18698 (clobber (reg:CC 17))])]
18699 {
18700 if (!rtx_equal_p (operands[0], operands[1]))
18701 emit_move_insn (operands[0], operands[1]);
18702 })
18703
18704 (define_peephole2
18705 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18706 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18707 (match_operand:SI 2 "const_int_operand" "")))
18708 (clobber (reg:CC 17))])
18709 (match_scratch:SI 3 "r")]
18710 "TARGET_K8 && !optimize_size
18711 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18712 [(set (match_dup 3) (match_dup 2))
18713 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18714 (clobber (reg:CC 17))])]
18715 {
18716 if (!rtx_equal_p (operands[0], operands[1]))
18717 emit_move_insn (operands[0], operands[1]);
18718 })
18719
18720 (define_peephole2
18721 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18722 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18723 (match_operand:HI 2 "immediate_operand" "")))
18724 (clobber (reg:CC 17))])
18725 (match_scratch:HI 3 "r")]
18726 "TARGET_K8 && !optimize_size"
18727 [(set (match_dup 3) (match_dup 2))
18728 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18729 (clobber (reg:CC 17))])]
18730 {
18731 if (!rtx_equal_p (operands[0], operands[1]))
18732 emit_move_insn (operands[0], operands[1]);
18733 })
18734 \f
18735 ;; Call-value patterns last so that the wildcard operand does not
18736 ;; disrupt insn-recog's switch tables.
18737
18738 (define_insn "*call_value_pop_0"
18739 [(set (match_operand 0 "" "")
18740 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18741 (match_operand:SI 2 "" "")))
18742 (set (reg:SI 7) (plus:SI (reg:SI 7)
18743 (match_operand:SI 3 "immediate_operand" "")))]
18744 "!TARGET_64BIT"
18745 {
18746 if (SIBLING_CALL_P (insn))
18747 return "jmp\t%P1";
18748 else
18749 return "call\t%P1";
18750 }
18751 [(set_attr "type" "callv")])
18752
18753 (define_insn "*call_value_pop_1"
18754 [(set (match_operand 0 "" "")
18755 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18756 (match_operand:SI 2 "" "")))
18757 (set (reg:SI 7) (plus:SI (reg:SI 7)
18758 (match_operand:SI 3 "immediate_operand" "i")))]
18759 "!TARGET_64BIT"
18760 {
18761 if (constant_call_address_operand (operands[1], QImode))
18762 {
18763 if (SIBLING_CALL_P (insn))
18764 return "jmp\t%P1";
18765 else
18766 return "call\t%P1";
18767 }
18768 if (SIBLING_CALL_P (insn))
18769 return "jmp\t%A1";
18770 else
18771 return "call\t%A1";
18772 }
18773 [(set_attr "type" "callv")])
18774
18775 (define_insn "*call_value_0"
18776 [(set (match_operand 0 "" "")
18777 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18778 (match_operand:SI 2 "" "")))]
18779 "!TARGET_64BIT"
18780 {
18781 if (SIBLING_CALL_P (insn))
18782 return "jmp\t%P1";
18783 else
18784 return "call\t%P1";
18785 }
18786 [(set_attr "type" "callv")])
18787
18788 (define_insn "*call_value_0_rex64"
18789 [(set (match_operand 0 "" "")
18790 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18791 (match_operand:DI 2 "const_int_operand" "")))]
18792 "TARGET_64BIT"
18793 {
18794 if (SIBLING_CALL_P (insn))
18795 return "jmp\t%P1";
18796 else
18797 return "call\t%P1";
18798 }
18799 [(set_attr "type" "callv")])
18800
18801 (define_insn "*call_value_1"
18802 [(set (match_operand 0 "" "")
18803 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18804 (match_operand:SI 2 "" "")))]
18805 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18806 {
18807 if (constant_call_address_operand (operands[1], QImode))
18808 return "call\t%P1";
18809 return "call\t%*%1";
18810 }
18811 [(set_attr "type" "callv")])
18812
18813 (define_insn "*sibcall_value_1"
18814 [(set (match_operand 0 "" "")
18815 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18816 (match_operand:SI 2 "" "")))]
18817 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18818 {
18819 if (constant_call_address_operand (operands[1], QImode))
18820 return "jmp\t%P1";
18821 return "jmp\t%*%1";
18822 }
18823 [(set_attr "type" "callv")])
18824
18825 (define_insn "*call_value_1_rex64"
18826 [(set (match_operand 0 "" "")
18827 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18828 (match_operand:DI 2 "" "")))]
18829 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18830 {
18831 if (constant_call_address_operand (operands[1], QImode))
18832 return "call\t%P1";
18833 return "call\t%A1";
18834 }
18835 [(set_attr "type" "callv")])
18836
18837 (define_insn "*sibcall_value_1_rex64"
18838 [(set (match_operand 0 "" "")
18839 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18840 (match_operand:DI 2 "" "")))]
18841 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18842 "jmp\t%P1"
18843 [(set_attr "type" "callv")])
18844
18845 (define_insn "*sibcall_value_1_rex64_v"
18846 [(set (match_operand 0 "" "")
18847 (call (mem:QI (reg:DI 40))
18848 (match_operand:DI 1 "" "")))]
18849 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18850 "jmp\t*%%r11"
18851 [(set_attr "type" "callv")])
18852 \f
18853 (define_insn "trap"
18854 [(trap_if (const_int 1) (const_int 5))]
18855 ""
18856 "int\t$5")
18857
18858 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18859 ;;; for the sake of bounds checking. By emitting bounds checks as
18860 ;;; conditional traps rather than as conditional jumps around
18861 ;;; unconditional traps we avoid introducing spurious basic-block
18862 ;;; boundaries and facilitate elimination of redundant checks. In
18863 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18864 ;;; interrupt 5.
18865 ;;;
18866 ;;; FIXME: Static branch prediction rules for ix86 are such that
18867 ;;; forward conditional branches predict as untaken. As implemented
18868 ;;; below, pseudo conditional traps violate that rule. We should use
18869 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18870 ;;; section loaded at the end of the text segment and branch forward
18871 ;;; there on bounds-failure, and then jump back immediately (in case
18872 ;;; the system chooses to ignore bounds violations, or to report
18873 ;;; violations and continue execution).
18874
18875 (define_expand "conditional_trap"
18876 [(trap_if (match_operator 0 "comparison_operator"
18877 [(match_dup 2) (const_int 0)])
18878 (match_operand 1 "const_int_operand" ""))]
18879 ""
18880 {
18881 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18882 ix86_expand_compare (GET_CODE (operands[0]),
18883 NULL, NULL),
18884 operands[1]));
18885 DONE;
18886 })
18887
18888 (define_insn "*conditional_trap_1"
18889 [(trap_if (match_operator 0 "comparison_operator"
18890 [(reg 17) (const_int 0)])
18891 (match_operand 1 "const_int_operand" ""))]
18892 ""
18893 {
18894 operands[2] = gen_label_rtx ();
18895 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18896 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18897 CODE_LABEL_NUMBER (operands[2]));
18898 RET;
18899 })
18900
18901 ;; Pentium III SIMD instructions.
18902
18903 ;; Moves for SSE/MMX regs.
18904
18905 (define_insn "movv4sf_internal"
18906 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18907 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18908 "TARGET_SSE"
18909 "@
18910 xorps\t%0, %0
18911 movaps\t{%1, %0|%0, %1}
18912 movaps\t{%1, %0|%0, %1}"
18913 [(set_attr "type" "ssemov")
18914 (set_attr "mode" "V4SF")])
18915
18916 (define_split
18917 [(set (match_operand:V4SF 0 "register_operand" "")
18918 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18919 "TARGET_SSE"
18920 [(set (match_dup 0)
18921 (vec_merge:V4SF
18922 (vec_duplicate:V4SF (match_dup 1))
18923 (match_dup 2)
18924 (const_int 1)))]
18925 {
18926 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18927 operands[2] = CONST0_RTX (V4SFmode);
18928 })
18929
18930 (define_insn "movv4si_internal"
18931 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18932 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18933 "TARGET_SSE"
18934 {
18935 switch (which_alternative)
18936 {
18937 case 0:
18938 if (get_attr_mode (insn) == MODE_V4SF)
18939 return "xorps\t%0, %0";
18940 else
18941 return "pxor\t%0, %0";
18942 case 1:
18943 case 2:
18944 if (get_attr_mode (insn) == MODE_V4SF)
18945 return "movaps\t{%1, %0|%0, %1}";
18946 else
18947 return "movdqa\t{%1, %0|%0, %1}";
18948 default:
18949 abort ();
18950 }
18951 }
18952 [(set_attr "type" "ssemov")
18953 (set (attr "mode")
18954 (cond [(eq_attr "alternative" "0,1")
18955 (if_then_else
18956 (ne (symbol_ref "optimize_size")
18957 (const_int 0))
18958 (const_string "V4SF")
18959 (const_string "TI"))
18960 (eq_attr "alternative" "2")
18961 (if_then_else
18962 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18963 (const_int 0))
18964 (ne (symbol_ref "optimize_size")
18965 (const_int 0)))
18966 (const_string "V4SF")
18967 (const_string "TI"))]
18968 (const_string "TI")))])
18969
18970 (define_insn "movv2di_internal"
18971 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18972 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18973 "TARGET_SSE2"
18974 {
18975 switch (which_alternative)
18976 {
18977 case 0:
18978 if (get_attr_mode (insn) == MODE_V4SF)
18979 return "xorps\t%0, %0";
18980 else
18981 return "pxor\t%0, %0";
18982 case 1:
18983 case 2:
18984 if (get_attr_mode (insn) == MODE_V4SF)
18985 return "movaps\t{%1, %0|%0, %1}";
18986 else
18987 return "movdqa\t{%1, %0|%0, %1}";
18988 default:
18989 abort ();
18990 }
18991 }
18992 [(set_attr "type" "ssemov")
18993 (set (attr "mode")
18994 (cond [(eq_attr "alternative" "0,1")
18995 (if_then_else
18996 (ne (symbol_ref "optimize_size")
18997 (const_int 0))
18998 (const_string "V4SF")
18999 (const_string "TI"))
19000 (eq_attr "alternative" "2")
19001 (if_then_else
19002 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19003 (const_int 0))
19004 (ne (symbol_ref "optimize_size")
19005 (const_int 0)))
19006 (const_string "V4SF")
19007 (const_string "TI"))]
19008 (const_string "TI")))])
19009
19010 (define_split
19011 [(set (match_operand:V2DF 0 "register_operand" "")
19012 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19013 "TARGET_SSE2"
19014 [(set (match_dup 0)
19015 (vec_merge:V2DF
19016 (vec_duplicate:V2DF (match_dup 1))
19017 (match_dup 2)
19018 (const_int 1)))]
19019 {
19020 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19021 operands[2] = CONST0_RTX (V2DFmode);
19022 })
19023
19024 (define_insn "movv8qi_internal"
19025 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19026 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19027 "TARGET_MMX
19028 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19029 "@
19030 pxor\t%0, %0
19031 movq\t{%1, %0|%0, %1}
19032 movq\t{%1, %0|%0, %1}"
19033 [(set_attr "type" "mmxmov")
19034 (set_attr "mode" "DI")])
19035
19036 (define_insn "movv4hi_internal"
19037 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19038 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19039 "TARGET_MMX
19040 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19041 "@
19042 pxor\t%0, %0
19043 movq\t{%1, %0|%0, %1}
19044 movq\t{%1, %0|%0, %1}"
19045 [(set_attr "type" "mmxmov")
19046 (set_attr "mode" "DI")])
19047
19048 (define_insn "movv2si_internal"
19049 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19050 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19051 "TARGET_MMX
19052 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19053 "@
19054 pxor\t%0, %0
19055 movq\t{%1, %0|%0, %1}
19056 movq\t{%1, %0|%0, %1}"
19057 [(set_attr "type" "mmxcvt")
19058 (set_attr "mode" "DI")])
19059
19060 (define_insn "movv2sf_internal"
19061 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19062 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19063 "TARGET_3DNOW
19064 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19065 "@
19066 pxor\t%0, %0
19067 movq\t{%1, %0|%0, %1}
19068 movq\t{%1, %0|%0, %1}"
19069 [(set_attr "type" "mmxcvt")
19070 (set_attr "mode" "DI")])
19071
19072 (define_expand "movti"
19073 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19074 (match_operand:TI 1 "nonimmediate_operand" ""))]
19075 "TARGET_SSE || TARGET_64BIT"
19076 {
19077 if (TARGET_64BIT)
19078 ix86_expand_move (TImode, operands);
19079 else
19080 ix86_expand_vector_move (TImode, operands);
19081 DONE;
19082 })
19083
19084 (define_insn "movv2df_internal"
19085 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19086 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19087 "TARGET_SSE2
19088 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19089 {
19090 switch (which_alternative)
19091 {
19092 case 0:
19093 if (get_attr_mode (insn) == MODE_V4SF)
19094 return "xorps\t%0, %0";
19095 else
19096 return "xorpd\t%0, %0";
19097 case 1:
19098 case 2:
19099 if (get_attr_mode (insn) == MODE_V4SF)
19100 return "movaps\t{%1, %0|%0, %1}";
19101 else
19102 return "movapd\t{%1, %0|%0, %1}";
19103 default:
19104 abort ();
19105 }
19106 }
19107 [(set_attr "type" "ssemov")
19108 (set (attr "mode")
19109 (cond [(eq_attr "alternative" "0,1")
19110 (if_then_else
19111 (ne (symbol_ref "optimize_size")
19112 (const_int 0))
19113 (const_string "V4SF")
19114 (const_string "V2DF"))
19115 (eq_attr "alternative" "2")
19116 (if_then_else
19117 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19118 (const_int 0))
19119 (ne (symbol_ref "optimize_size")
19120 (const_int 0)))
19121 (const_string "V4SF")
19122 (const_string "V2DF"))]
19123 (const_string "V2DF")))])
19124
19125 (define_insn "movv8hi_internal"
19126 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19127 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19128 "TARGET_SSE2
19129 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19130 {
19131 switch (which_alternative)
19132 {
19133 case 0:
19134 if (get_attr_mode (insn) == MODE_V4SF)
19135 return "xorps\t%0, %0";
19136 else
19137 return "pxor\t%0, %0";
19138 case 1:
19139 case 2:
19140 if (get_attr_mode (insn) == MODE_V4SF)
19141 return "movaps\t{%1, %0|%0, %1}";
19142 else
19143 return "movdqa\t{%1, %0|%0, %1}";
19144 default:
19145 abort ();
19146 }
19147 }
19148 [(set_attr "type" "ssemov")
19149 (set (attr "mode")
19150 (cond [(eq_attr "alternative" "0,1")
19151 (if_then_else
19152 (ne (symbol_ref "optimize_size")
19153 (const_int 0))
19154 (const_string "V4SF")
19155 (const_string "TI"))
19156 (eq_attr "alternative" "2")
19157 (if_then_else
19158 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19159 (const_int 0))
19160 (ne (symbol_ref "optimize_size")
19161 (const_int 0)))
19162 (const_string "V4SF")
19163 (const_string "TI"))]
19164 (const_string "TI")))])
19165
19166 (define_insn "movv16qi_internal"
19167 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19168 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19169 "TARGET_SSE2
19170 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19171 {
19172 switch (which_alternative)
19173 {
19174 case 0:
19175 if (get_attr_mode (insn) == MODE_V4SF)
19176 return "xorps\t%0, %0";
19177 else
19178 return "pxor\t%0, %0";
19179 case 1:
19180 case 2:
19181 if (get_attr_mode (insn) == MODE_V4SF)
19182 return "movaps\t{%1, %0|%0, %1}";
19183 else
19184 return "movdqa\t{%1, %0|%0, %1}";
19185 default:
19186 abort ();
19187 }
19188 }
19189 [(set_attr "type" "ssemov")
19190 (set (attr "mode")
19191 (cond [(eq_attr "alternative" "0,1")
19192 (if_then_else
19193 (ne (symbol_ref "optimize_size")
19194 (const_int 0))
19195 (const_string "V4SF")
19196 (const_string "TI"))
19197 (eq_attr "alternative" "2")
19198 (if_then_else
19199 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19200 (const_int 0))
19201 (ne (symbol_ref "optimize_size")
19202 (const_int 0)))
19203 (const_string "V4SF")
19204 (const_string "TI"))]
19205 (const_string "TI")))])
19206
19207 (define_expand "movv2df"
19208 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19209 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19210 "TARGET_SSE2"
19211 {
19212 ix86_expand_vector_move (V2DFmode, operands);
19213 DONE;
19214 })
19215
19216 (define_expand "movv8hi"
19217 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19218 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19219 "TARGET_SSE2"
19220 {
19221 ix86_expand_vector_move (V8HImode, operands);
19222 DONE;
19223 })
19224
19225 (define_expand "movv16qi"
19226 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19227 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19228 "TARGET_SSE2"
19229 {
19230 ix86_expand_vector_move (V16QImode, operands);
19231 DONE;
19232 })
19233
19234 (define_expand "movv4sf"
19235 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19236 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19237 "TARGET_SSE"
19238 {
19239 ix86_expand_vector_move (V4SFmode, operands);
19240 DONE;
19241 })
19242
19243 (define_expand "movv4si"
19244 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19245 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19246 "TARGET_SSE"
19247 {
19248 ix86_expand_vector_move (V4SImode, operands);
19249 DONE;
19250 })
19251
19252 (define_expand "movv2di"
19253 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19254 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19255 "TARGET_SSE"
19256 {
19257 ix86_expand_vector_move (V2DImode, operands);
19258 DONE;
19259 })
19260
19261 (define_expand "movv2si"
19262 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19263 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19264 "TARGET_MMX"
19265 {
19266 ix86_expand_vector_move (V2SImode, operands);
19267 DONE;
19268 })
19269
19270 (define_expand "movv4hi"
19271 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19272 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19273 "TARGET_MMX"
19274 {
19275 ix86_expand_vector_move (V4HImode, operands);
19276 DONE;
19277 })
19278
19279 (define_expand "movv8qi"
19280 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19281 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19282 "TARGET_MMX"
19283 {
19284 ix86_expand_vector_move (V8QImode, operands);
19285 DONE;
19286 })
19287
19288 (define_expand "movv2sf"
19289 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19290 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19291 "TARGET_3DNOW"
19292 {
19293 ix86_expand_vector_move (V2SFmode, operands);
19294 DONE;
19295 })
19296
19297 (define_insn "*pushti"
19298 [(set (match_operand:TI 0 "push_operand" "=<")
19299 (match_operand:TI 1 "register_operand" "x"))]
19300 "TARGET_SSE"
19301 "#")
19302
19303 (define_insn "*pushv2df"
19304 [(set (match_operand:V2DF 0 "push_operand" "=<")
19305 (match_operand:V2DF 1 "register_operand" "x"))]
19306 "TARGET_SSE"
19307 "#")
19308
19309 (define_insn "*pushv2di"
19310 [(set (match_operand:V2DI 0 "push_operand" "=<")
19311 (match_operand:V2DI 1 "register_operand" "x"))]
19312 "TARGET_SSE2"
19313 "#")
19314
19315 (define_insn "*pushv8hi"
19316 [(set (match_operand:V8HI 0 "push_operand" "=<")
19317 (match_operand:V8HI 1 "register_operand" "x"))]
19318 "TARGET_SSE2"
19319 "#")
19320
19321 (define_insn "*pushv16qi"
19322 [(set (match_operand:V16QI 0 "push_operand" "=<")
19323 (match_operand:V16QI 1 "register_operand" "x"))]
19324 "TARGET_SSE2"
19325 "#")
19326
19327 (define_insn "*pushv4sf"
19328 [(set (match_operand:V4SF 0 "push_operand" "=<")
19329 (match_operand:V4SF 1 "register_operand" "x"))]
19330 "TARGET_SSE"
19331 "#")
19332
19333 (define_insn "*pushv4si"
19334 [(set (match_operand:V4SI 0 "push_operand" "=<")
19335 (match_operand:V4SI 1 "register_operand" "x"))]
19336 "TARGET_SSE2"
19337 "#")
19338
19339 (define_insn "*pushv2si"
19340 [(set (match_operand:V2SI 0 "push_operand" "=<")
19341 (match_operand:V2SI 1 "register_operand" "y"))]
19342 "TARGET_MMX"
19343 "#")
19344
19345 (define_insn "*pushv4hi"
19346 [(set (match_operand:V4HI 0 "push_operand" "=<")
19347 (match_operand:V4HI 1 "register_operand" "y"))]
19348 "TARGET_MMX"
19349 "#")
19350
19351 (define_insn "*pushv8qi"
19352 [(set (match_operand:V8QI 0 "push_operand" "=<")
19353 (match_operand:V8QI 1 "register_operand" "y"))]
19354 "TARGET_MMX"
19355 "#")
19356
19357 (define_insn "*pushv2sf"
19358 [(set (match_operand:V2SF 0 "push_operand" "=<")
19359 (match_operand:V2SF 1 "register_operand" "y"))]
19360 "TARGET_3DNOW"
19361 "#")
19362
19363 (define_split
19364 [(set (match_operand 0 "push_operand" "")
19365 (match_operand 1 "register_operand" ""))]
19366 "!TARGET_64BIT && reload_completed
19367 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19368 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19369 (set (match_dup 2) (match_dup 1))]
19370 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19371 stack_pointer_rtx);
19372 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19373
19374 (define_split
19375 [(set (match_operand 0 "push_operand" "")
19376 (match_operand 1 "register_operand" ""))]
19377 "TARGET_64BIT && reload_completed
19378 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19379 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19380 (set (match_dup 2) (match_dup 1))]
19381 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19382 stack_pointer_rtx);
19383 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19384
19385
19386 (define_insn "movti_internal"
19387 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19388 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19389 "TARGET_SSE && !TARGET_64BIT
19390 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19391 {
19392 switch (which_alternative)
19393 {
19394 case 0:
19395 if (get_attr_mode (insn) == MODE_V4SF)
19396 return "xorps\t%0, %0";
19397 else
19398 return "pxor\t%0, %0";
19399 case 1:
19400 case 2:
19401 if (get_attr_mode (insn) == MODE_V4SF)
19402 return "movaps\t{%1, %0|%0, %1}";
19403 else
19404 return "movdqa\t{%1, %0|%0, %1}";
19405 default:
19406 abort ();
19407 }
19408 }
19409 [(set_attr "type" "ssemov,ssemov,ssemov")
19410 (set (attr "mode")
19411 (cond [(eq_attr "alternative" "0,1")
19412 (if_then_else
19413 (ne (symbol_ref "optimize_size")
19414 (const_int 0))
19415 (const_string "V4SF")
19416 (const_string "TI"))
19417 (eq_attr "alternative" "2")
19418 (if_then_else
19419 (ne (symbol_ref "optimize_size")
19420 (const_int 0))
19421 (const_string "V4SF")
19422 (const_string "TI"))]
19423 (const_string "TI")))])
19424
19425 (define_insn "*movti_rex64"
19426 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19427 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19428 "TARGET_64BIT
19429 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19430 {
19431 switch (which_alternative)
19432 {
19433 case 0:
19434 case 1:
19435 return "#";
19436 case 2:
19437 if (get_attr_mode (insn) == MODE_V4SF)
19438 return "xorps\t%0, %0";
19439 else
19440 return "pxor\t%0, %0";
19441 case 3:
19442 case 4:
19443 if (get_attr_mode (insn) == MODE_V4SF)
19444 return "movaps\t{%1, %0|%0, %1}";
19445 else
19446 return "movdqa\t{%1, %0|%0, %1}";
19447 default:
19448 abort ();
19449 }
19450 }
19451 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19452 (set (attr "mode")
19453 (cond [(eq_attr "alternative" "2,3")
19454 (if_then_else
19455 (ne (symbol_ref "optimize_size")
19456 (const_int 0))
19457 (const_string "V4SF")
19458 (const_string "TI"))
19459 (eq_attr "alternative" "4")
19460 (if_then_else
19461 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19462 (const_int 0))
19463 (ne (symbol_ref "optimize_size")
19464 (const_int 0)))
19465 (const_string "V4SF")
19466 (const_string "TI"))]
19467 (const_string "DI")))])
19468
19469 (define_split
19470 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19471 (match_operand:TI 1 "general_operand" ""))]
19472 "reload_completed && !SSE_REG_P (operands[0])
19473 && !SSE_REG_P (operands[1])"
19474 [(const_int 0)]
19475 "ix86_split_long_move (operands); DONE;")
19476
19477 ;; These two patterns are useful for specifying exactly whether to use
19478 ;; movaps or movups
19479 (define_insn "sse_movaps"
19480 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19481 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19482 UNSPEC_MOVA))]
19483 "TARGET_SSE
19484 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19485 "movaps\t{%1, %0|%0, %1}"
19486 [(set_attr "type" "ssemov,ssemov")
19487 (set_attr "mode" "V4SF")])
19488
19489 (define_insn "sse_movups"
19490 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19491 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19492 UNSPEC_MOVU))]
19493 "TARGET_SSE
19494 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19495 "movups\t{%1, %0|%0, %1}"
19496 [(set_attr "type" "ssecvt,ssecvt")
19497 (set_attr "mode" "V4SF")])
19498
19499
19500 ;; SSE Strange Moves.
19501
19502 (define_insn "sse_movmskps"
19503 [(set (match_operand:SI 0 "register_operand" "=r")
19504 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19505 UNSPEC_MOVMSK))]
19506 "TARGET_SSE"
19507 "movmskps\t{%1, %0|%0, %1}"
19508 [(set_attr "type" "ssecvt")
19509 (set_attr "mode" "V4SF")])
19510
19511 (define_insn "mmx_pmovmskb"
19512 [(set (match_operand:SI 0 "register_operand" "=r")
19513 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19514 UNSPEC_MOVMSK))]
19515 "TARGET_SSE || TARGET_3DNOW_A"
19516 "pmovmskb\t{%1, %0|%0, %1}"
19517 [(set_attr "type" "ssecvt")
19518 (set_attr "mode" "V4SF")])
19519
19520
19521 (define_insn "mmx_maskmovq"
19522 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19523 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19524 (match_operand:V8QI 2 "register_operand" "y")]
19525 UNSPEC_MASKMOV))]
19526 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19527 ;; @@@ check ordering of operands in intel/nonintel syntax
19528 "maskmovq\t{%2, %1|%1, %2}"
19529 [(set_attr "type" "mmxcvt")
19530 (set_attr "mode" "DI")])
19531
19532 (define_insn "mmx_maskmovq_rex"
19533 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19534 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19535 (match_operand:V8QI 2 "register_operand" "y")]
19536 UNSPEC_MASKMOV))]
19537 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19538 ;; @@@ check ordering of operands in intel/nonintel syntax
19539 "maskmovq\t{%2, %1|%1, %2}"
19540 [(set_attr "type" "mmxcvt")
19541 (set_attr "mode" "DI")])
19542
19543 (define_insn "sse_movntv4sf"
19544 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19545 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19546 UNSPEC_MOVNT))]
19547 "TARGET_SSE"
19548 "movntps\t{%1, %0|%0, %1}"
19549 [(set_attr "type" "ssemov")
19550 (set_attr "mode" "V4SF")])
19551
19552 (define_insn "sse_movntdi"
19553 [(set (match_operand:DI 0 "memory_operand" "=m")
19554 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19555 UNSPEC_MOVNT))]
19556 "TARGET_SSE || TARGET_3DNOW_A"
19557 "movntq\t{%1, %0|%0, %1}"
19558 [(set_attr "type" "mmxmov")
19559 (set_attr "mode" "DI")])
19560
19561 (define_insn "sse_movhlps"
19562 [(set (match_operand:V4SF 0 "register_operand" "=x")
19563 (vec_merge:V4SF
19564 (match_operand:V4SF 1 "register_operand" "0")
19565 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19566 (parallel [(const_int 2)
19567 (const_int 3)
19568 (const_int 0)
19569 (const_int 1)]))
19570 (const_int 3)))]
19571 "TARGET_SSE"
19572 "movhlps\t{%2, %0|%0, %2}"
19573 [(set_attr "type" "ssecvt")
19574 (set_attr "mode" "V4SF")])
19575
19576 (define_insn "sse_movlhps"
19577 [(set (match_operand:V4SF 0 "register_operand" "=x")
19578 (vec_merge:V4SF
19579 (match_operand:V4SF 1 "register_operand" "0")
19580 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19581 (parallel [(const_int 2)
19582 (const_int 3)
19583 (const_int 0)
19584 (const_int 1)]))
19585 (const_int 12)))]
19586 "TARGET_SSE"
19587 "movlhps\t{%2, %0|%0, %2}"
19588 [(set_attr "type" "ssecvt")
19589 (set_attr "mode" "V4SF")])
19590
19591 (define_insn "sse_movhps"
19592 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19593 (vec_merge:V4SF
19594 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19595 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19596 (const_int 12)))]
19597 "TARGET_SSE
19598 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19599 "movhps\t{%2, %0|%0, %2}"
19600 [(set_attr "type" "ssecvt")
19601 (set_attr "mode" "V4SF")])
19602
19603 (define_insn "sse_movlps"
19604 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19605 (vec_merge:V4SF
19606 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19607 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19608 (const_int 3)))]
19609 "TARGET_SSE
19610 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19611 "movlps\t{%2, %0|%0, %2}"
19612 [(set_attr "type" "ssecvt")
19613 (set_attr "mode" "V4SF")])
19614
19615 (define_expand "sse_loadss"
19616 [(match_operand:V4SF 0 "register_operand" "")
19617 (match_operand:SF 1 "memory_operand" "")]
19618 "TARGET_SSE"
19619 {
19620 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19621 CONST0_RTX (V4SFmode)));
19622 DONE;
19623 })
19624
19625 (define_insn "sse_loadss_1"
19626 [(set (match_operand:V4SF 0 "register_operand" "=x")
19627 (vec_merge:V4SF
19628 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19629 (match_operand:V4SF 2 "const0_operand" "X")
19630 (const_int 1)))]
19631 "TARGET_SSE"
19632 "movss\t{%1, %0|%0, %1}"
19633 [(set_attr "type" "ssemov")
19634 (set_attr "mode" "SF")])
19635
19636 (define_insn "sse_movss"
19637 [(set (match_operand:V4SF 0 "register_operand" "=x")
19638 (vec_merge:V4SF
19639 (match_operand:V4SF 1 "register_operand" "0")
19640 (match_operand:V4SF 2 "register_operand" "x")
19641 (const_int 1)))]
19642 "TARGET_SSE"
19643 "movss\t{%2, %0|%0, %2}"
19644 [(set_attr "type" "ssemov")
19645 (set_attr "mode" "SF")])
19646
19647 (define_insn "sse_storess"
19648 [(set (match_operand:SF 0 "memory_operand" "=m")
19649 (vec_select:SF
19650 (match_operand:V4SF 1 "register_operand" "x")
19651 (parallel [(const_int 0)])))]
19652 "TARGET_SSE"
19653 "movss\t{%1, %0|%0, %1}"
19654 [(set_attr "type" "ssemov")
19655 (set_attr "mode" "SF")])
19656
19657 (define_insn "sse_shufps"
19658 [(set (match_operand:V4SF 0 "register_operand" "=x")
19659 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19660 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19661 (match_operand:SI 3 "immediate_operand" "i")]
19662 UNSPEC_SHUFFLE))]
19663 "TARGET_SSE"
19664 ;; @@@ check operand order for intel/nonintel syntax
19665 "shufps\t{%3, %2, %0|%0, %2, %3}"
19666 [(set_attr "type" "ssecvt")
19667 (set_attr "mode" "V4SF")])
19668
19669
19670 ;; SSE arithmetic
19671
19672 (define_insn "addv4sf3"
19673 [(set (match_operand:V4SF 0 "register_operand" "=x")
19674 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19675 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19676 "TARGET_SSE"
19677 "addps\t{%2, %0|%0, %2}"
19678 [(set_attr "type" "sseadd")
19679 (set_attr "mode" "V4SF")])
19680
19681 (define_insn "vmaddv4sf3"
19682 [(set (match_operand:V4SF 0 "register_operand" "=x")
19683 (vec_merge:V4SF
19684 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19685 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19686 (match_dup 1)
19687 (const_int 1)))]
19688 "TARGET_SSE"
19689 "addss\t{%2, %0|%0, %2}"
19690 [(set_attr "type" "sseadd")
19691 (set_attr "mode" "SF")])
19692
19693 (define_insn "subv4sf3"
19694 [(set (match_operand:V4SF 0 "register_operand" "=x")
19695 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19696 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19697 "TARGET_SSE"
19698 "subps\t{%2, %0|%0, %2}"
19699 [(set_attr "type" "sseadd")
19700 (set_attr "mode" "V4SF")])
19701
19702 (define_insn "vmsubv4sf3"
19703 [(set (match_operand:V4SF 0 "register_operand" "=x")
19704 (vec_merge:V4SF
19705 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19706 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19707 (match_dup 1)
19708 (const_int 1)))]
19709 "TARGET_SSE"
19710 "subss\t{%2, %0|%0, %2}"
19711 [(set_attr "type" "sseadd")
19712 (set_attr "mode" "SF")])
19713
19714 (define_insn "mulv4sf3"
19715 [(set (match_operand:V4SF 0 "register_operand" "=x")
19716 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19717 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19718 "TARGET_SSE"
19719 "mulps\t{%2, %0|%0, %2}"
19720 [(set_attr "type" "ssemul")
19721 (set_attr "mode" "V4SF")])
19722
19723 (define_insn "vmmulv4sf3"
19724 [(set (match_operand:V4SF 0 "register_operand" "=x")
19725 (vec_merge:V4SF
19726 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19727 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19728 (match_dup 1)
19729 (const_int 1)))]
19730 "TARGET_SSE"
19731 "mulss\t{%2, %0|%0, %2}"
19732 [(set_attr "type" "ssemul")
19733 (set_attr "mode" "SF")])
19734
19735 (define_insn "divv4sf3"
19736 [(set (match_operand:V4SF 0 "register_operand" "=x")
19737 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19738 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19739 "TARGET_SSE"
19740 "divps\t{%2, %0|%0, %2}"
19741 [(set_attr "type" "ssediv")
19742 (set_attr "mode" "V4SF")])
19743
19744 (define_insn "vmdivv4sf3"
19745 [(set (match_operand:V4SF 0 "register_operand" "=x")
19746 (vec_merge:V4SF
19747 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19748 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19749 (match_dup 1)
19750 (const_int 1)))]
19751 "TARGET_SSE"
19752 "divss\t{%2, %0|%0, %2}"
19753 [(set_attr "type" "ssediv")
19754 (set_attr "mode" "SF")])
19755
19756
19757 ;; SSE square root/reciprocal
19758
19759 (define_insn "rcpv4sf2"
19760 [(set (match_operand:V4SF 0 "register_operand" "=x")
19761 (unspec:V4SF
19762 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19763 "TARGET_SSE"
19764 "rcpps\t{%1, %0|%0, %1}"
19765 [(set_attr "type" "sse")
19766 (set_attr "mode" "V4SF")])
19767
19768 (define_insn "vmrcpv4sf2"
19769 [(set (match_operand:V4SF 0 "register_operand" "=x")
19770 (vec_merge:V4SF
19771 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19772 UNSPEC_RCP)
19773 (match_operand:V4SF 2 "register_operand" "0")
19774 (const_int 1)))]
19775 "TARGET_SSE"
19776 "rcpss\t{%1, %0|%0, %1}"
19777 [(set_attr "type" "sse")
19778 (set_attr "mode" "SF")])
19779
19780 (define_insn "rsqrtv4sf2"
19781 [(set (match_operand:V4SF 0 "register_operand" "=x")
19782 (unspec:V4SF
19783 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19784 "TARGET_SSE"
19785 "rsqrtps\t{%1, %0|%0, %1}"
19786 [(set_attr "type" "sse")
19787 (set_attr "mode" "V4SF")])
19788
19789 (define_insn "vmrsqrtv4sf2"
19790 [(set (match_operand:V4SF 0 "register_operand" "=x")
19791 (vec_merge:V4SF
19792 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19793 UNSPEC_RSQRT)
19794 (match_operand:V4SF 2 "register_operand" "0")
19795 (const_int 1)))]
19796 "TARGET_SSE"
19797 "rsqrtss\t{%1, %0|%0, %1}"
19798 [(set_attr "type" "sse")
19799 (set_attr "mode" "SF")])
19800
19801 (define_insn "sqrtv4sf2"
19802 [(set (match_operand:V4SF 0 "register_operand" "=x")
19803 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19804 "TARGET_SSE"
19805 "sqrtps\t{%1, %0|%0, %1}"
19806 [(set_attr "type" "sse")
19807 (set_attr "mode" "V4SF")])
19808
19809 (define_insn "vmsqrtv4sf2"
19810 [(set (match_operand:V4SF 0 "register_operand" "=x")
19811 (vec_merge:V4SF
19812 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19813 (match_operand:V4SF 2 "register_operand" "0")
19814 (const_int 1)))]
19815 "TARGET_SSE"
19816 "sqrtss\t{%1, %0|%0, %1}"
19817 [(set_attr "type" "sse")
19818 (set_attr "mode" "SF")])
19819
19820 ;; SSE logical operations.
19821
19822 ;; SSE defines logical operations on floating point values. This brings
19823 ;; interesting challenge to RTL representation where logicals are only valid
19824 ;; on integral types. We deal with this by representing the floating point
19825 ;; logical as logical on arguments casted to TImode as this is what hardware
19826 ;; really does. Unfortunately hardware requires the type information to be
19827 ;; present and thus we must avoid subregs from being simplified and eliminated
19828 ;; in later compilation phases.
19829 ;;
19830 ;; We have following variants from each instruction:
19831 ;; sse_andsf3 - the operation taking V4SF vector operands
19832 ;; and doing TImode cast on them
19833 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19834 ;; TImode, since backend insist on eliminating casts
19835 ;; on memory operands
19836 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19837 ;; We can not accept memory operand here as instruction reads
19838 ;; whole scalar. This is generated only post reload by GCC
19839 ;; scalar float operations that expands to logicals (fabs)
19840 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19841 ;; memory operand. Eventually combine can be able
19842 ;; to synthesize these using splitter.
19843 ;; sse2_anddf3, *sse2_anddf3_memory
19844 ;;
19845 ;;
19846 ;; These are not called andti3 etc. because we really really don't want
19847 ;; the compiler to widen DImode ands to TImode ands and then try to move
19848 ;; into DImode subregs of SSE registers, and them together, and move out
19849 ;; of DImode subregs again!
19850 ;; SSE1 single precision floating point logical operation
19851 (define_expand "sse_andv4sf3"
19852 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19853 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19854 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19855 "TARGET_SSE"
19856 "")
19857
19858 (define_insn "*sse_andv4sf3"
19859 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19860 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19861 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19862 "TARGET_SSE
19863 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19864 "andps\t{%2, %0|%0, %2}"
19865 [(set_attr "type" "sselog")
19866 (set_attr "mode" "V4SF")])
19867
19868 (define_insn "*sse_andsf3"
19869 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19870 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19871 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19872 "TARGET_SSE
19873 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19874 "andps\t{%2, %0|%0, %2}"
19875 [(set_attr "type" "sselog")
19876 (set_attr "mode" "V4SF")])
19877
19878 (define_expand "sse_nandv4sf3"
19879 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19880 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19881 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19882 "TARGET_SSE"
19883 "")
19884
19885 (define_insn "*sse_nandv4sf3"
19886 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19887 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19888 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19889 "TARGET_SSE"
19890 "andnps\t{%2, %0|%0, %2}"
19891 [(set_attr "type" "sselog")
19892 (set_attr "mode" "V4SF")])
19893
19894 (define_insn "*sse_nandsf3"
19895 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19896 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19897 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19898 "TARGET_SSE"
19899 "andnps\t{%2, %0|%0, %2}"
19900 [(set_attr "type" "sselog")
19901 (set_attr "mode" "V4SF")])
19902
19903 (define_expand "sse_iorv4sf3"
19904 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19905 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19906 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19907 "TARGET_SSE"
19908 "")
19909
19910 (define_insn "*sse_iorv4sf3"
19911 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19912 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19913 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19914 "TARGET_SSE
19915 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19916 "orps\t{%2, %0|%0, %2}"
19917 [(set_attr "type" "sselog")
19918 (set_attr "mode" "V4SF")])
19919
19920 (define_insn "*sse_iorsf3"
19921 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19922 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19923 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19924 "TARGET_SSE
19925 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19926 "orps\t{%2, %0|%0, %2}"
19927 [(set_attr "type" "sselog")
19928 (set_attr "mode" "V4SF")])
19929
19930 (define_expand "sse_xorv4sf3"
19931 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19932 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19933 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19934 "TARGET_SSE
19935 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19936 "")
19937
19938 (define_insn "*sse_xorv4sf3"
19939 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19940 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19941 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19942 "TARGET_SSE
19943 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19944 "xorps\t{%2, %0|%0, %2}"
19945 [(set_attr "type" "sselog")
19946 (set_attr "mode" "V4SF")])
19947
19948 (define_insn "*sse_xorsf3"
19949 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19950 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19951 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19952 "TARGET_SSE
19953 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19954 "xorps\t{%2, %0|%0, %2}"
19955 [(set_attr "type" "sselog")
19956 (set_attr "mode" "V4SF")])
19957
19958 ;; SSE2 double precision floating point logical operation
19959
19960 (define_expand "sse2_andv2df3"
19961 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19962 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19963 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19964 "TARGET_SSE2"
19965 "")
19966
19967 (define_insn "*sse2_andv2df3"
19968 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19969 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19970 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19971 "TARGET_SSE2
19972 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19973 "andpd\t{%2, %0|%0, %2}"
19974 [(set_attr "type" "sselog")
19975 (set_attr "mode" "V2DF")])
19976
19977 (define_insn "*sse2_andv2df3"
19978 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19979 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19980 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19981 "TARGET_SSE2
19982 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19983 "andpd\t{%2, %0|%0, %2}"
19984 [(set_attr "type" "sselog")
19985 (set_attr "mode" "V2DF")])
19986
19987 (define_expand "sse2_nandv2df3"
19988 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19989 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19990 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19991 "TARGET_SSE2"
19992 "")
19993
19994 (define_insn "*sse2_nandv2df3"
19995 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19996 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19997 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19998 "TARGET_SSE2"
19999 "andnpd\t{%2, %0|%0, %2}"
20000 [(set_attr "type" "sselog")
20001 (set_attr "mode" "V2DF")])
20002
20003 (define_insn "*sse_nandti3_df"
20004 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
20005 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20006 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
20007 "TARGET_SSE2"
20008 "andnpd\t{%2, %0|%0, %2}"
20009 [(set_attr "type" "sselog")
20010 (set_attr "mode" "V2DF")])
20011
20012 (define_expand "sse2_iorv2df3"
20013 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20014 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20015 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20016 "TARGET_SSE2"
20017 "")
20018
20019 (define_insn "*sse2_iorv2df3"
20020 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20021 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20022 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20023 "TARGET_SSE2
20024 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20025 "orpd\t{%2, %0|%0, %2}"
20026 [(set_attr "type" "sselog")
20027 (set_attr "mode" "V2DF")])
20028
20029 (define_insn "*sse2_iordf3"
20030 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20031 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20032 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20033 "TARGET_SSE2
20034 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20035 "orpd\t{%2, %0|%0, %2}"
20036 [(set_attr "type" "sselog")
20037 (set_attr "mode" "V2DF")])
20038
20039 (define_expand "sse2_xorv2df3"
20040 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20041 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
20042 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20043 "TARGET_SSE2"
20044 "")
20045
20046 (define_insn "*sse2_xorv2df3"
20047 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20048 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20049 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20050 "TARGET_SSE2
20051 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20052 "xorpd\t{%2, %0|%0, %2}"
20053 [(set_attr "type" "sselog")
20054 (set_attr "mode" "V2DF")])
20055
20056 (define_insn "*sse2_xordf3"
20057 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20058 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20059 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20060 "TARGET_SSE2
20061 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20062 "xorpd\t{%2, %0|%0, %2}"
20063 [(set_attr "type" "sselog")
20064 (set_attr "mode" "V2DF")])
20065
20066 ;; SSE2 integral logicals. These patterns must always come after floating
20067 ;; point ones since we don't want compiler to use integer opcodes on floating
20068 ;; point SSE values to avoid matching of subregs in the match_operand.
20069 (define_insn "*sse2_andti3"
20070 [(set (match_operand:TI 0 "register_operand" "=x")
20071 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20072 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20073 "TARGET_SSE2
20074 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20075 "pand\t{%2, %0|%0, %2}"
20076 [(set_attr "type" "sselog")
20077 (set_attr "mode" "TI")])
20078
20079 (define_insn "sse2_andv2di3"
20080 [(set (match_operand:V2DI 0 "register_operand" "=x")
20081 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20082 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20083 "TARGET_SSE2
20084 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20085 "pand\t{%2, %0|%0, %2}"
20086 [(set_attr "type" "sselog")
20087 (set_attr "mode" "TI")])
20088
20089 (define_insn "*sse2_nandti3"
20090 [(set (match_operand:TI 0 "register_operand" "=x")
20091 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20092 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20093 "TARGET_SSE2"
20094 "pandn\t{%2, %0|%0, %2}"
20095 [(set_attr "type" "sselog")
20096 (set_attr "mode" "TI")])
20097
20098 (define_insn "sse2_nandv2di3"
20099 [(set (match_operand:V2DI 0 "register_operand" "=x")
20100 (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "0"))
20101 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20102 "TARGET_SSE2
20103 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20104 "pandn\t{%2, %0|%0, %2}"
20105 [(set_attr "type" "sselog")
20106 (set_attr "mode" "TI")])
20107
20108 (define_insn "*sse2_iorti3"
20109 [(set (match_operand:TI 0 "register_operand" "=x")
20110 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20111 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20112 "TARGET_SSE2
20113 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20114 "por\t{%2, %0|%0, %2}"
20115 [(set_attr "type" "sselog")
20116 (set_attr "mode" "TI")])
20117
20118 (define_insn "sse2_iorv2di3"
20119 [(set (match_operand:V2DI 0 "register_operand" "=x")
20120 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20121 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20122 "TARGET_SSE2
20123 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20124 "por\t{%2, %0|%0, %2}"
20125 [(set_attr "type" "sselog")
20126 (set_attr "mode" "TI")])
20127
20128 (define_insn "*sse2_xorti3"
20129 [(set (match_operand:TI 0 "register_operand" "=x")
20130 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20131 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20132 "TARGET_SSE2
20133 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20134 "pxor\t{%2, %0|%0, %2}"
20135 [(set_attr "type" "sselog")
20136 (set_attr "mode" "TI")])
20137
20138 (define_insn "sse2_xorv2di3"
20139 [(set (match_operand:V2DI 0 "register_operand" "=x")
20140 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20141 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20142 "TARGET_SSE2
20143 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20144 "pxor\t{%2, %0|%0, %2}"
20145 [(set_attr "type" "sselog")
20146 (set_attr "mode" "TI")])
20147
20148 ;; Use xor, but don't show input operands so they aren't live before
20149 ;; this insn.
20150 (define_insn "sse_clrv4sf"
20151 [(set (match_operand:V4SF 0 "register_operand" "=x")
20152 (match_operand:V4SF 1 "const0_operand" "X"))]
20153 "TARGET_SSE"
20154 {
20155 if (get_attr_mode (insn) == MODE_TI)
20156 return "pxor\t{%0, %0|%0, %0}";
20157 else
20158 return "xorps\t{%0, %0|%0, %0}";
20159 }
20160 [(set_attr "type" "sselog")
20161 (set_attr "memory" "none")
20162 (set (attr "mode")
20163 (if_then_else
20164 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20165 (const_int 0))
20166 (ne (symbol_ref "TARGET_SSE2")
20167 (const_int 0)))
20168 (eq (symbol_ref "optimize_size")
20169 (const_int 0)))
20170 (const_string "TI")
20171 (const_string "V4SF")))])
20172
20173 ;; Use xor, but don't show input operands so they aren't live before
20174 ;; this insn.
20175 (define_insn "sse_clrv2df"
20176 [(set (match_operand:V2DF 0 "register_operand" "=x")
20177 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20178 "TARGET_SSE2"
20179 "xorpd\t{%0, %0|%0, %0}"
20180 [(set_attr "type" "sselog")
20181 (set_attr "memory" "none")
20182 (set_attr "mode" "V4SF")])
20183
20184 ;; SSE mask-generating compares
20185
20186 (define_insn "maskcmpv4sf3"
20187 [(set (match_operand:V4SI 0 "register_operand" "=x")
20188 (match_operator:V4SI 3 "sse_comparison_operator"
20189 [(match_operand:V4SF 1 "register_operand" "0")
20190 (match_operand:V4SF 2 "register_operand" "x")]))]
20191 "TARGET_SSE"
20192 "cmp%D3ps\t{%2, %0|%0, %2}"
20193 [(set_attr "type" "ssecmp")
20194 (set_attr "mode" "V4SF")])
20195
20196 (define_insn "maskncmpv4sf3"
20197 [(set (match_operand:V4SI 0 "register_operand" "=x")
20198 (not:V4SI
20199 (match_operator:V4SI 3 "sse_comparison_operator"
20200 [(match_operand:V4SF 1 "register_operand" "0")
20201 (match_operand:V4SF 2 "register_operand" "x")])))]
20202 "TARGET_SSE"
20203 {
20204 if (GET_CODE (operands[3]) == UNORDERED)
20205 return "cmpordps\t{%2, %0|%0, %2}";
20206 else
20207 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20208 }
20209 [(set_attr "type" "ssecmp")
20210 (set_attr "mode" "V4SF")])
20211
20212 (define_insn "vmmaskcmpv4sf3"
20213 [(set (match_operand:V4SI 0 "register_operand" "=x")
20214 (vec_merge:V4SI
20215 (match_operator:V4SI 3 "sse_comparison_operator"
20216 [(match_operand:V4SF 1 "register_operand" "0")
20217 (match_operand:V4SF 2 "register_operand" "x")])
20218 (subreg:V4SI (match_dup 1) 0)
20219 (const_int 1)))]
20220 "TARGET_SSE"
20221 "cmp%D3ss\t{%2, %0|%0, %2}"
20222 [(set_attr "type" "ssecmp")
20223 (set_attr "mode" "SF")])
20224
20225 (define_insn "vmmaskncmpv4sf3"
20226 [(set (match_operand:V4SI 0 "register_operand" "=x")
20227 (vec_merge:V4SI
20228 (not:V4SI
20229 (match_operator:V4SI 3 "sse_comparison_operator"
20230 [(match_operand:V4SF 1 "register_operand" "0")
20231 (match_operand:V4SF 2 "register_operand" "x")]))
20232 (subreg:V4SI (match_dup 1) 0)
20233 (const_int 1)))]
20234 "TARGET_SSE"
20235 {
20236 if (GET_CODE (operands[3]) == UNORDERED)
20237 return "cmpordss\t{%2, %0|%0, %2}";
20238 else
20239 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20240 }
20241 [(set_attr "type" "ssecmp")
20242 (set_attr "mode" "SF")])
20243
20244 (define_insn "sse_comi"
20245 [(set (reg:CCFP 17)
20246 (compare:CCFP (vec_select:SF
20247 (match_operand:V4SF 0 "register_operand" "x")
20248 (parallel [(const_int 0)]))
20249 (vec_select:SF
20250 (match_operand:V4SF 1 "register_operand" "x")
20251 (parallel [(const_int 0)]))))]
20252 "TARGET_SSE"
20253 "comiss\t{%1, %0|%0, %1}"
20254 [(set_attr "type" "ssecomi")
20255 (set_attr "mode" "SF")])
20256
20257 (define_insn "sse_ucomi"
20258 [(set (reg:CCFPU 17)
20259 (compare:CCFPU (vec_select:SF
20260 (match_operand:V4SF 0 "register_operand" "x")
20261 (parallel [(const_int 0)]))
20262 (vec_select:SF
20263 (match_operand:V4SF 1 "register_operand" "x")
20264 (parallel [(const_int 0)]))))]
20265 "TARGET_SSE"
20266 "ucomiss\t{%1, %0|%0, %1}"
20267 [(set_attr "type" "ssecomi")
20268 (set_attr "mode" "SF")])
20269
20270
20271 ;; SSE unpack
20272
20273 (define_insn "sse_unpckhps"
20274 [(set (match_operand:V4SF 0 "register_operand" "=x")
20275 (vec_merge:V4SF
20276 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20277 (parallel [(const_int 2)
20278 (const_int 0)
20279 (const_int 3)
20280 (const_int 1)]))
20281 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20282 (parallel [(const_int 0)
20283 (const_int 2)
20284 (const_int 1)
20285 (const_int 3)]))
20286 (const_int 5)))]
20287 "TARGET_SSE"
20288 "unpckhps\t{%2, %0|%0, %2}"
20289 [(set_attr "type" "ssecvt")
20290 (set_attr "mode" "V4SF")])
20291
20292 (define_insn "sse_unpcklps"
20293 [(set (match_operand:V4SF 0 "register_operand" "=x")
20294 (vec_merge:V4SF
20295 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20296 (parallel [(const_int 0)
20297 (const_int 2)
20298 (const_int 1)
20299 (const_int 3)]))
20300 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20301 (parallel [(const_int 2)
20302 (const_int 0)
20303 (const_int 3)
20304 (const_int 1)]))
20305 (const_int 5)))]
20306 "TARGET_SSE"
20307 "unpcklps\t{%2, %0|%0, %2}"
20308 [(set_attr "type" "ssecvt")
20309 (set_attr "mode" "V4SF")])
20310
20311
20312 ;; SSE min/max
20313
20314 (define_insn "smaxv4sf3"
20315 [(set (match_operand:V4SF 0 "register_operand" "=x")
20316 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20317 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20318 "TARGET_SSE"
20319 "maxps\t{%2, %0|%0, %2}"
20320 [(set_attr "type" "sse")
20321 (set_attr "mode" "V4SF")])
20322
20323 (define_insn "vmsmaxv4sf3"
20324 [(set (match_operand:V4SF 0 "register_operand" "=x")
20325 (vec_merge:V4SF
20326 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20327 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20328 (match_dup 1)
20329 (const_int 1)))]
20330 "TARGET_SSE"
20331 "maxss\t{%2, %0|%0, %2}"
20332 [(set_attr "type" "sse")
20333 (set_attr "mode" "SF")])
20334
20335 (define_insn "sminv4sf3"
20336 [(set (match_operand:V4SF 0 "register_operand" "=x")
20337 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20338 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20339 "TARGET_SSE"
20340 "minps\t{%2, %0|%0, %2}"
20341 [(set_attr "type" "sse")
20342 (set_attr "mode" "V4SF")])
20343
20344 (define_insn "vmsminv4sf3"
20345 [(set (match_operand:V4SF 0 "register_operand" "=x")
20346 (vec_merge:V4SF
20347 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20348 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20349 (match_dup 1)
20350 (const_int 1)))]
20351 "TARGET_SSE"
20352 "minss\t{%2, %0|%0, %2}"
20353 [(set_attr "type" "sse")
20354 (set_attr "mode" "SF")])
20355
20356 ;; SSE <-> integer/MMX conversions
20357
20358 (define_insn "cvtpi2ps"
20359 [(set (match_operand:V4SF 0 "register_operand" "=x")
20360 (vec_merge:V4SF
20361 (match_operand:V4SF 1 "register_operand" "0")
20362 (vec_duplicate:V4SF
20363 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20364 (const_int 12)))]
20365 "TARGET_SSE"
20366 "cvtpi2ps\t{%2, %0|%0, %2}"
20367 [(set_attr "type" "ssecvt")
20368 (set_attr "mode" "V4SF")])
20369
20370 (define_insn "cvtps2pi"
20371 [(set (match_operand:V2SI 0 "register_operand" "=y")
20372 (vec_select:V2SI
20373 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20374 (parallel [(const_int 0) (const_int 1)])))]
20375 "TARGET_SSE"
20376 "cvtps2pi\t{%1, %0|%0, %1}"
20377 [(set_attr "type" "ssecvt")
20378 (set_attr "mode" "V4SF")])
20379
20380 (define_insn "cvttps2pi"
20381 [(set (match_operand:V2SI 0 "register_operand" "=y")
20382 (vec_select:V2SI
20383 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20384 UNSPEC_FIX)
20385 (parallel [(const_int 0) (const_int 1)])))]
20386 "TARGET_SSE"
20387 "cvttps2pi\t{%1, %0|%0, %1}"
20388 [(set_attr "type" "ssecvt")
20389 (set_attr "mode" "SF")])
20390
20391 (define_insn "cvtsi2ss"
20392 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20393 (vec_merge:V4SF
20394 (match_operand:V4SF 1 "register_operand" "0,0")
20395 (vec_duplicate:V4SF
20396 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20397 (const_int 14)))]
20398 "TARGET_SSE"
20399 "cvtsi2ss\t{%2, %0|%0, %2}"
20400 [(set_attr "type" "sseicvt")
20401 (set_attr "athlon_decode" "vector,double")
20402 (set_attr "mode" "SF")])
20403
20404 (define_insn "cvtsi2ssq"
20405 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20406 (vec_merge:V4SF
20407 (match_operand:V4SF 1 "register_operand" "0,0")
20408 (vec_duplicate:V4SF
20409 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20410 (const_int 14)))]
20411 "TARGET_SSE && TARGET_64BIT"
20412 "cvtsi2ssq\t{%2, %0|%0, %2}"
20413 [(set_attr "type" "sseicvt")
20414 (set_attr "athlon_decode" "vector,double")
20415 (set_attr "mode" "SF")])
20416
20417 (define_insn "cvtss2si"
20418 [(set (match_operand:SI 0 "register_operand" "=r,r")
20419 (vec_select:SI
20420 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20421 (parallel [(const_int 0)])))]
20422 "TARGET_SSE"
20423 "cvtss2si\t{%1, %0|%0, %1}"
20424 [(set_attr "type" "sseicvt")
20425 (set_attr "athlon_decode" "double,vector")
20426 (set_attr "mode" "SI")])
20427
20428 (define_insn "cvtss2siq"
20429 [(set (match_operand:DI 0 "register_operand" "=r,r")
20430 (vec_select:DI
20431 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20432 (parallel [(const_int 0)])))]
20433 "TARGET_SSE"
20434 "cvtss2siq\t{%1, %0|%0, %1}"
20435 [(set_attr "type" "sseicvt")
20436 (set_attr "athlon_decode" "double,vector")
20437 (set_attr "mode" "DI")])
20438
20439 (define_insn "cvttss2si"
20440 [(set (match_operand:SI 0 "register_operand" "=r,r")
20441 (vec_select:SI
20442 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20443 UNSPEC_FIX)
20444 (parallel [(const_int 0)])))]
20445 "TARGET_SSE"
20446 "cvttss2si\t{%1, %0|%0, %1}"
20447 [(set_attr "type" "sseicvt")
20448 (set_attr "mode" "SF")
20449 (set_attr "athlon_decode" "double,vector")])
20450
20451 (define_insn "cvttss2siq"
20452 [(set (match_operand:DI 0 "register_operand" "=r,r")
20453 (vec_select:DI
20454 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20455 UNSPEC_FIX)
20456 (parallel [(const_int 0)])))]
20457 "TARGET_SSE && TARGET_64BIT"
20458 "cvttss2siq\t{%1, %0|%0, %1}"
20459 [(set_attr "type" "sseicvt")
20460 (set_attr "mode" "SF")
20461 (set_attr "athlon_decode" "double,vector")])
20462
20463
20464 ;; MMX insns
20465
20466 ;; MMX arithmetic
20467
20468 (define_insn "addv8qi3"
20469 [(set (match_operand:V8QI 0 "register_operand" "=y")
20470 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20471 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20472 "TARGET_MMX"
20473 "paddb\t{%2, %0|%0, %2}"
20474 [(set_attr "type" "mmxadd")
20475 (set_attr "mode" "DI")])
20476
20477 (define_insn "addv4hi3"
20478 [(set (match_operand:V4HI 0 "register_operand" "=y")
20479 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20480 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20481 "TARGET_MMX"
20482 "paddw\t{%2, %0|%0, %2}"
20483 [(set_attr "type" "mmxadd")
20484 (set_attr "mode" "DI")])
20485
20486 (define_insn "addv2si3"
20487 [(set (match_operand:V2SI 0 "register_operand" "=y")
20488 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20489 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20490 "TARGET_MMX"
20491 "paddd\t{%2, %0|%0, %2}"
20492 [(set_attr "type" "mmxadd")
20493 (set_attr "mode" "DI")])
20494
20495 (define_insn "mmx_adddi3"
20496 [(set (match_operand:DI 0 "register_operand" "=y")
20497 (unspec:DI
20498 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20499 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20500 UNSPEC_NOP))]
20501 "TARGET_MMX"
20502 "paddq\t{%2, %0|%0, %2}"
20503 [(set_attr "type" "mmxadd")
20504 (set_attr "mode" "DI")])
20505
20506 (define_insn "ssaddv8qi3"
20507 [(set (match_operand:V8QI 0 "register_operand" "=y")
20508 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20509 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20510 "TARGET_MMX"
20511 "paddsb\t{%2, %0|%0, %2}"
20512 [(set_attr "type" "mmxadd")
20513 (set_attr "mode" "DI")])
20514
20515 (define_insn "ssaddv4hi3"
20516 [(set (match_operand:V4HI 0 "register_operand" "=y")
20517 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20518 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20519 "TARGET_MMX"
20520 "paddsw\t{%2, %0|%0, %2}"
20521 [(set_attr "type" "mmxadd")
20522 (set_attr "mode" "DI")])
20523
20524 (define_insn "usaddv8qi3"
20525 [(set (match_operand:V8QI 0 "register_operand" "=y")
20526 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20527 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20528 "TARGET_MMX"
20529 "paddusb\t{%2, %0|%0, %2}"
20530 [(set_attr "type" "mmxadd")
20531 (set_attr "mode" "DI")])
20532
20533 (define_insn "usaddv4hi3"
20534 [(set (match_operand:V4HI 0 "register_operand" "=y")
20535 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20536 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20537 "TARGET_MMX"
20538 "paddusw\t{%2, %0|%0, %2}"
20539 [(set_attr "type" "mmxadd")
20540 (set_attr "mode" "DI")])
20541
20542 (define_insn "subv8qi3"
20543 [(set (match_operand:V8QI 0 "register_operand" "=y")
20544 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20545 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20546 "TARGET_MMX"
20547 "psubb\t{%2, %0|%0, %2}"
20548 [(set_attr "type" "mmxadd")
20549 (set_attr "mode" "DI")])
20550
20551 (define_insn "subv4hi3"
20552 [(set (match_operand:V4HI 0 "register_operand" "=y")
20553 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20554 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20555 "TARGET_MMX"
20556 "psubw\t{%2, %0|%0, %2}"
20557 [(set_attr "type" "mmxadd")
20558 (set_attr "mode" "DI")])
20559
20560 (define_insn "subv2si3"
20561 [(set (match_operand:V2SI 0 "register_operand" "=y")
20562 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20563 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20564 "TARGET_MMX"
20565 "psubd\t{%2, %0|%0, %2}"
20566 [(set_attr "type" "mmxadd")
20567 (set_attr "mode" "DI")])
20568
20569 (define_insn "mmx_subdi3"
20570 [(set (match_operand:DI 0 "register_operand" "=y")
20571 (unspec:DI
20572 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20573 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20574 UNSPEC_NOP))]
20575 "TARGET_MMX"
20576 "psubq\t{%2, %0|%0, %2}"
20577 [(set_attr "type" "mmxadd")
20578 (set_attr "mode" "DI")])
20579
20580 (define_insn "sssubv8qi3"
20581 [(set (match_operand:V8QI 0 "register_operand" "=y")
20582 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20583 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20584 "TARGET_MMX"
20585 "psubsb\t{%2, %0|%0, %2}"
20586 [(set_attr "type" "mmxadd")
20587 (set_attr "mode" "DI")])
20588
20589 (define_insn "sssubv4hi3"
20590 [(set (match_operand:V4HI 0 "register_operand" "=y")
20591 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20592 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20593 "TARGET_MMX"
20594 "psubsw\t{%2, %0|%0, %2}"
20595 [(set_attr "type" "mmxadd")
20596 (set_attr "mode" "DI")])
20597
20598 (define_insn "ussubv8qi3"
20599 [(set (match_operand:V8QI 0 "register_operand" "=y")
20600 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20601 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20602 "TARGET_MMX"
20603 "psubusb\t{%2, %0|%0, %2}"
20604 [(set_attr "type" "mmxadd")
20605 (set_attr "mode" "DI")])
20606
20607 (define_insn "ussubv4hi3"
20608 [(set (match_operand:V4HI 0 "register_operand" "=y")
20609 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20610 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20611 "TARGET_MMX"
20612 "psubusw\t{%2, %0|%0, %2}"
20613 [(set_attr "type" "mmxadd")
20614 (set_attr "mode" "DI")])
20615
20616 (define_insn "mulv4hi3"
20617 [(set (match_operand:V4HI 0 "register_operand" "=y")
20618 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20619 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20620 "TARGET_MMX"
20621 "pmullw\t{%2, %0|%0, %2}"
20622 [(set_attr "type" "mmxmul")
20623 (set_attr "mode" "DI")])
20624
20625 (define_insn "smulv4hi3_highpart"
20626 [(set (match_operand:V4HI 0 "register_operand" "=y")
20627 (truncate:V4HI
20628 (lshiftrt:V4SI
20629 (mult:V4SI (sign_extend:V4SI
20630 (match_operand:V4HI 1 "register_operand" "0"))
20631 (sign_extend:V4SI
20632 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20633 (const_int 16))))]
20634 "TARGET_MMX"
20635 "pmulhw\t{%2, %0|%0, %2}"
20636 [(set_attr "type" "mmxmul")
20637 (set_attr "mode" "DI")])
20638
20639 (define_insn "umulv4hi3_highpart"
20640 [(set (match_operand:V4HI 0 "register_operand" "=y")
20641 (truncate:V4HI
20642 (lshiftrt:V4SI
20643 (mult:V4SI (zero_extend:V4SI
20644 (match_operand:V4HI 1 "register_operand" "0"))
20645 (zero_extend:V4SI
20646 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20647 (const_int 16))))]
20648 "TARGET_SSE || TARGET_3DNOW_A"
20649 "pmulhuw\t{%2, %0|%0, %2}"
20650 [(set_attr "type" "mmxmul")
20651 (set_attr "mode" "DI")])
20652
20653 (define_insn "mmx_pmaddwd"
20654 [(set (match_operand:V2SI 0 "register_operand" "=y")
20655 (plus:V2SI
20656 (mult:V2SI
20657 (sign_extend:V2SI
20658 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20659 (parallel [(const_int 0) (const_int 2)])))
20660 (sign_extend:V2SI
20661 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20662 (parallel [(const_int 0) (const_int 2)]))))
20663 (mult:V2SI
20664 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20665 (parallel [(const_int 1)
20666 (const_int 3)])))
20667 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20668 (parallel [(const_int 1)
20669 (const_int 3)]))))))]
20670 "TARGET_MMX"
20671 "pmaddwd\t{%2, %0|%0, %2}"
20672 [(set_attr "type" "mmxmul")
20673 (set_attr "mode" "DI")])
20674
20675
20676 ;; MMX logical operations
20677 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20678 ;; normal code that also wants to use the FPU from getting broken.
20679 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20680 (define_insn "mmx_iordi3"
20681 [(set (match_operand:DI 0 "register_operand" "=y")
20682 (unspec:DI
20683 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20684 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20685 UNSPEC_NOP))]
20686 "TARGET_MMX"
20687 "por\t{%2, %0|%0, %2}"
20688 [(set_attr "type" "mmxadd")
20689 (set_attr "mode" "DI")])
20690
20691 (define_insn "mmx_xordi3"
20692 [(set (match_operand:DI 0 "register_operand" "=y")
20693 (unspec:DI
20694 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20695 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20696 UNSPEC_NOP))]
20697 "TARGET_MMX"
20698 "pxor\t{%2, %0|%0, %2}"
20699 [(set_attr "type" "mmxadd")
20700 (set_attr "mode" "DI")
20701 (set_attr "memory" "none")])
20702
20703 ;; Same as pxor, but don't show input operands so that we don't think
20704 ;; they are live.
20705 (define_insn "mmx_clrdi"
20706 [(set (match_operand:DI 0 "register_operand" "=y")
20707 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20708 "TARGET_MMX"
20709 "pxor\t{%0, %0|%0, %0}"
20710 [(set_attr "type" "mmxadd")
20711 (set_attr "mode" "DI")
20712 (set_attr "memory" "none")])
20713
20714 (define_insn "mmx_anddi3"
20715 [(set (match_operand:DI 0 "register_operand" "=y")
20716 (unspec:DI
20717 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20718 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20719 UNSPEC_NOP))]
20720 "TARGET_MMX"
20721 "pand\t{%2, %0|%0, %2}"
20722 [(set_attr "type" "mmxadd")
20723 (set_attr "mode" "DI")])
20724
20725 (define_insn "mmx_nanddi3"
20726 [(set (match_operand:DI 0 "register_operand" "=y")
20727 (unspec:DI
20728 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20729 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20730 UNSPEC_NOP))]
20731 "TARGET_MMX"
20732 "pandn\t{%2, %0|%0, %2}"
20733 [(set_attr "type" "mmxadd")
20734 (set_attr "mode" "DI")])
20735
20736
20737 ;; MMX unsigned averages/sum of absolute differences
20738
20739 (define_insn "mmx_uavgv8qi3"
20740 [(set (match_operand:V8QI 0 "register_operand" "=y")
20741 (ashiftrt:V8QI
20742 (plus:V8QI (plus:V8QI
20743 (match_operand:V8QI 1 "register_operand" "0")
20744 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20745 (const_vector:V8QI [(const_int 1)
20746 (const_int 1)
20747 (const_int 1)
20748 (const_int 1)
20749 (const_int 1)
20750 (const_int 1)
20751 (const_int 1)
20752 (const_int 1)]))
20753 (const_int 1)))]
20754 "TARGET_SSE || TARGET_3DNOW_A"
20755 "pavgb\t{%2, %0|%0, %2}"
20756 [(set_attr "type" "mmxshft")
20757 (set_attr "mode" "DI")])
20758
20759 (define_insn "mmx_uavgv4hi3"
20760 [(set (match_operand:V4HI 0 "register_operand" "=y")
20761 (ashiftrt:V4HI
20762 (plus:V4HI (plus:V4HI
20763 (match_operand:V4HI 1 "register_operand" "0")
20764 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20765 (const_vector:V4HI [(const_int 1)
20766 (const_int 1)
20767 (const_int 1)
20768 (const_int 1)]))
20769 (const_int 1)))]
20770 "TARGET_SSE || TARGET_3DNOW_A"
20771 "pavgw\t{%2, %0|%0, %2}"
20772 [(set_attr "type" "mmxshft")
20773 (set_attr "mode" "DI")])
20774
20775 (define_insn "mmx_psadbw"
20776 [(set (match_operand:DI 0 "register_operand" "=y")
20777 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20778 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20779 UNSPEC_PSADBW))]
20780 "TARGET_SSE || TARGET_3DNOW_A"
20781 "psadbw\t{%2, %0|%0, %2}"
20782 [(set_attr "type" "mmxshft")
20783 (set_attr "mode" "DI")])
20784
20785
20786 ;; MMX insert/extract/shuffle
20787
20788 (define_insn "mmx_pinsrw"
20789 [(set (match_operand:V4HI 0 "register_operand" "=y")
20790 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20791 (vec_duplicate:V4HI
20792 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20793 (match_operand:SI 3 "immediate_operand" "i")))]
20794 "TARGET_SSE || TARGET_3DNOW_A"
20795 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20796 [(set_attr "type" "mmxcvt")
20797 (set_attr "mode" "DI")])
20798
20799 (define_insn "mmx_pextrw"
20800 [(set (match_operand:SI 0 "register_operand" "=r")
20801 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20802 (parallel
20803 [(match_operand:SI 2 "immediate_operand" "i")]))))]
20804 "TARGET_SSE || TARGET_3DNOW_A"
20805 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20806 [(set_attr "type" "mmxcvt")
20807 (set_attr "mode" "DI")])
20808
20809 (define_insn "mmx_pshufw"
20810 [(set (match_operand:V4HI 0 "register_operand" "=y")
20811 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20812 (match_operand:SI 2 "immediate_operand" "i")]
20813 UNSPEC_SHUFFLE))]
20814 "TARGET_SSE || TARGET_3DNOW_A"
20815 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20816 [(set_attr "type" "mmxcvt")
20817 (set_attr "mode" "DI")])
20818
20819
20820 ;; MMX mask-generating comparisons
20821
20822 (define_insn "eqv8qi3"
20823 [(set (match_operand:V8QI 0 "register_operand" "=y")
20824 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20825 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20826 "TARGET_MMX"
20827 "pcmpeqb\t{%2, %0|%0, %2}"
20828 [(set_attr "type" "mmxcmp")
20829 (set_attr "mode" "DI")])
20830
20831 (define_insn "eqv4hi3"
20832 [(set (match_operand:V4HI 0 "register_operand" "=y")
20833 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20834 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20835 "TARGET_MMX"
20836 "pcmpeqw\t{%2, %0|%0, %2}"
20837 [(set_attr "type" "mmxcmp")
20838 (set_attr "mode" "DI")])
20839
20840 (define_insn "eqv2si3"
20841 [(set (match_operand:V2SI 0 "register_operand" "=y")
20842 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20843 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20844 "TARGET_MMX"
20845 "pcmpeqd\t{%2, %0|%0, %2}"
20846 [(set_attr "type" "mmxcmp")
20847 (set_attr "mode" "DI")])
20848
20849 (define_insn "gtv8qi3"
20850 [(set (match_operand:V8QI 0 "register_operand" "=y")
20851 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20852 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20853 "TARGET_MMX"
20854 "pcmpgtb\t{%2, %0|%0, %2}"
20855 [(set_attr "type" "mmxcmp")
20856 (set_attr "mode" "DI")])
20857
20858 (define_insn "gtv4hi3"
20859 [(set (match_operand:V4HI 0 "register_operand" "=y")
20860 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20861 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20862 "TARGET_MMX"
20863 "pcmpgtw\t{%2, %0|%0, %2}"
20864 [(set_attr "type" "mmxcmp")
20865 (set_attr "mode" "DI")])
20866
20867 (define_insn "gtv2si3"
20868 [(set (match_operand:V2SI 0 "register_operand" "=y")
20869 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20870 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20871 "TARGET_MMX"
20872 "pcmpgtd\t{%2, %0|%0, %2}"
20873 [(set_attr "type" "mmxcmp")
20874 (set_attr "mode" "DI")])
20875
20876
20877 ;; MMX max/min insns
20878
20879 (define_insn "umaxv8qi3"
20880 [(set (match_operand:V8QI 0 "register_operand" "=y")
20881 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20882 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20883 "TARGET_SSE || TARGET_3DNOW_A"
20884 "pmaxub\t{%2, %0|%0, %2}"
20885 [(set_attr "type" "mmxadd")
20886 (set_attr "mode" "DI")])
20887
20888 (define_insn "smaxv4hi3"
20889 [(set (match_operand:V4HI 0 "register_operand" "=y")
20890 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20891 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20892 "TARGET_SSE || TARGET_3DNOW_A"
20893 "pmaxsw\t{%2, %0|%0, %2}"
20894 [(set_attr "type" "mmxadd")
20895 (set_attr "mode" "DI")])
20896
20897 (define_insn "uminv8qi3"
20898 [(set (match_operand:V8QI 0 "register_operand" "=y")
20899 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20900 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20901 "TARGET_SSE || TARGET_3DNOW_A"
20902 "pminub\t{%2, %0|%0, %2}"
20903 [(set_attr "type" "mmxadd")
20904 (set_attr "mode" "DI")])
20905
20906 (define_insn "sminv4hi3"
20907 [(set (match_operand:V4HI 0 "register_operand" "=y")
20908 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20909 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20910 "TARGET_SSE || TARGET_3DNOW_A"
20911 "pminsw\t{%2, %0|%0, %2}"
20912 [(set_attr "type" "mmxadd")
20913 (set_attr "mode" "DI")])
20914
20915
20916 ;; MMX shifts
20917
20918 (define_insn "ashrv4hi3"
20919 [(set (match_operand:V4HI 0 "register_operand" "=y")
20920 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20921 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20922 "TARGET_MMX"
20923 "psraw\t{%2, %0|%0, %2}"
20924 [(set_attr "type" "mmxshft")
20925 (set_attr "mode" "DI")])
20926
20927 (define_insn "ashrv2si3"
20928 [(set (match_operand:V2SI 0 "register_operand" "=y")
20929 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20930 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20931 "TARGET_MMX"
20932 "psrad\t{%2, %0|%0, %2}"
20933 [(set_attr "type" "mmxshft")
20934 (set_attr "mode" "DI")])
20935
20936 (define_insn "lshrv4hi3"
20937 [(set (match_operand:V4HI 0 "register_operand" "=y")
20938 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20939 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20940 "TARGET_MMX"
20941 "psrlw\t{%2, %0|%0, %2}"
20942 [(set_attr "type" "mmxshft")
20943 (set_attr "mode" "DI")])
20944
20945 (define_insn "lshrv2si3"
20946 [(set (match_operand:V2SI 0 "register_operand" "=y")
20947 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20948 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20949 "TARGET_MMX"
20950 "psrld\t{%2, %0|%0, %2}"
20951 [(set_attr "type" "mmxshft")
20952 (set_attr "mode" "DI")])
20953
20954 ;; See logical MMX insns.
20955 (define_insn "mmx_lshrdi3"
20956 [(set (match_operand:DI 0 "register_operand" "=y")
20957 (unspec:DI
20958 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20959 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20960 UNSPEC_NOP))]
20961 "TARGET_MMX"
20962 "psrlq\t{%2, %0|%0, %2}"
20963 [(set_attr "type" "mmxshft")
20964 (set_attr "mode" "DI")])
20965
20966 (define_insn "ashlv4hi3"
20967 [(set (match_operand:V4HI 0 "register_operand" "=y")
20968 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20969 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20970 "TARGET_MMX"
20971 "psllw\t{%2, %0|%0, %2}"
20972 [(set_attr "type" "mmxshft")
20973 (set_attr "mode" "DI")])
20974
20975 (define_insn "ashlv2si3"
20976 [(set (match_operand:V2SI 0 "register_operand" "=y")
20977 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20978 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20979 "TARGET_MMX"
20980 "pslld\t{%2, %0|%0, %2}"
20981 [(set_attr "type" "mmxshft")
20982 (set_attr "mode" "DI")])
20983
20984 ;; See logical MMX insns.
20985 (define_insn "mmx_ashldi3"
20986 [(set (match_operand:DI 0 "register_operand" "=y")
20987 (unspec:DI
20988 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20989 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20990 UNSPEC_NOP))]
20991 "TARGET_MMX"
20992 "psllq\t{%2, %0|%0, %2}"
20993 [(set_attr "type" "mmxshft")
20994 (set_attr "mode" "DI")])
20995
20996
20997 ;; MMX pack/unpack insns.
20998
20999 (define_insn "mmx_packsswb"
21000 [(set (match_operand:V8QI 0 "register_operand" "=y")
21001 (vec_concat:V8QI
21002 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21003 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21004 "TARGET_MMX"
21005 "packsswb\t{%2, %0|%0, %2}"
21006 [(set_attr "type" "mmxshft")
21007 (set_attr "mode" "DI")])
21008
21009 (define_insn "mmx_packssdw"
21010 [(set (match_operand:V4HI 0 "register_operand" "=y")
21011 (vec_concat:V4HI
21012 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21013 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21014 "TARGET_MMX"
21015 "packssdw\t{%2, %0|%0, %2}"
21016 [(set_attr "type" "mmxshft")
21017 (set_attr "mode" "DI")])
21018
21019 (define_insn "mmx_packuswb"
21020 [(set (match_operand:V8QI 0 "register_operand" "=y")
21021 (vec_concat:V8QI
21022 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21023 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21024 "TARGET_MMX"
21025 "packuswb\t{%2, %0|%0, %2}"
21026 [(set_attr "type" "mmxshft")
21027 (set_attr "mode" "DI")])
21028
21029 (define_insn "mmx_punpckhbw"
21030 [(set (match_operand:V8QI 0 "register_operand" "=y")
21031 (vec_merge:V8QI
21032 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21033 (parallel [(const_int 4)
21034 (const_int 0)
21035 (const_int 5)
21036 (const_int 1)
21037 (const_int 6)
21038 (const_int 2)
21039 (const_int 7)
21040 (const_int 3)]))
21041 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21042 (parallel [(const_int 0)
21043 (const_int 4)
21044 (const_int 1)
21045 (const_int 5)
21046 (const_int 2)
21047 (const_int 6)
21048 (const_int 3)
21049 (const_int 7)]))
21050 (const_int 85)))]
21051 "TARGET_MMX"
21052 "punpckhbw\t{%2, %0|%0, %2}"
21053 [(set_attr "type" "mmxcvt")
21054 (set_attr "mode" "DI")])
21055
21056 (define_insn "mmx_punpckhwd"
21057 [(set (match_operand:V4HI 0 "register_operand" "=y")
21058 (vec_merge:V4HI
21059 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21060 (parallel [(const_int 0)
21061 (const_int 2)
21062 (const_int 1)
21063 (const_int 3)]))
21064 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21065 (parallel [(const_int 2)
21066 (const_int 0)
21067 (const_int 3)
21068 (const_int 1)]))
21069 (const_int 5)))]
21070 "TARGET_MMX"
21071 "punpckhwd\t{%2, %0|%0, %2}"
21072 [(set_attr "type" "mmxcvt")
21073 (set_attr "mode" "DI")])
21074
21075 (define_insn "mmx_punpckhdq"
21076 [(set (match_operand:V2SI 0 "register_operand" "=y")
21077 (vec_merge:V2SI
21078 (match_operand:V2SI 1 "register_operand" "0")
21079 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21080 (parallel [(const_int 1)
21081 (const_int 0)]))
21082 (const_int 1)))]
21083 "TARGET_MMX"
21084 "punpckhdq\t{%2, %0|%0, %2}"
21085 [(set_attr "type" "mmxcvt")
21086 (set_attr "mode" "DI")])
21087
21088 (define_insn "mmx_punpcklbw"
21089 [(set (match_operand:V8QI 0 "register_operand" "=y")
21090 (vec_merge:V8QI
21091 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21092 (parallel [(const_int 0)
21093 (const_int 4)
21094 (const_int 1)
21095 (const_int 5)
21096 (const_int 2)
21097 (const_int 6)
21098 (const_int 3)
21099 (const_int 7)]))
21100 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21101 (parallel [(const_int 4)
21102 (const_int 0)
21103 (const_int 5)
21104 (const_int 1)
21105 (const_int 6)
21106 (const_int 2)
21107 (const_int 7)
21108 (const_int 3)]))
21109 (const_int 85)))]
21110 "TARGET_MMX"
21111 "punpcklbw\t{%2, %0|%0, %2}"
21112 [(set_attr "type" "mmxcvt")
21113 (set_attr "mode" "DI")])
21114
21115 (define_insn "mmx_punpcklwd"
21116 [(set (match_operand:V4HI 0 "register_operand" "=y")
21117 (vec_merge:V4HI
21118 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21119 (parallel [(const_int 2)
21120 (const_int 0)
21121 (const_int 3)
21122 (const_int 1)]))
21123 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21124 (parallel [(const_int 0)
21125 (const_int 2)
21126 (const_int 1)
21127 (const_int 3)]))
21128 (const_int 5)))]
21129 "TARGET_MMX"
21130 "punpcklwd\t{%2, %0|%0, %2}"
21131 [(set_attr "type" "mmxcvt")
21132 (set_attr "mode" "DI")])
21133
21134 (define_insn "mmx_punpckldq"
21135 [(set (match_operand:V2SI 0 "register_operand" "=y")
21136 (vec_merge:V2SI
21137 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21138 (parallel [(const_int 1)
21139 (const_int 0)]))
21140 (match_operand:V2SI 2 "register_operand" "y")
21141 (const_int 1)))]
21142 "TARGET_MMX"
21143 "punpckldq\t{%2, %0|%0, %2}"
21144 [(set_attr "type" "mmxcvt")
21145 (set_attr "mode" "DI")])
21146
21147
21148 ;; Miscellaneous stuff
21149
21150 (define_insn "emms"
21151 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21152 (clobber (reg:XF 8))
21153 (clobber (reg:XF 9))
21154 (clobber (reg:XF 10))
21155 (clobber (reg:XF 11))
21156 (clobber (reg:XF 12))
21157 (clobber (reg:XF 13))
21158 (clobber (reg:XF 14))
21159 (clobber (reg:XF 15))
21160 (clobber (reg:DI 29))
21161 (clobber (reg:DI 30))
21162 (clobber (reg:DI 31))
21163 (clobber (reg:DI 32))
21164 (clobber (reg:DI 33))
21165 (clobber (reg:DI 34))
21166 (clobber (reg:DI 35))
21167 (clobber (reg:DI 36))]
21168 "TARGET_MMX"
21169 "emms"
21170 [(set_attr "type" "mmx")
21171 (set_attr "memory" "unknown")])
21172
21173 (define_insn "ldmxcsr"
21174 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21175 UNSPECV_LDMXCSR)]
21176 "TARGET_SSE"
21177 "ldmxcsr\t%0"
21178 [(set_attr "type" "sse")
21179 (set_attr "memory" "load")])
21180
21181 (define_insn "stmxcsr"
21182 [(set (match_operand:SI 0 "memory_operand" "=m")
21183 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21184 "TARGET_SSE"
21185 "stmxcsr\t%0"
21186 [(set_attr "type" "sse")
21187 (set_attr "memory" "store")])
21188
21189 (define_expand "sfence"
21190 [(set (match_dup 0)
21191 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21192 "TARGET_SSE || TARGET_3DNOW_A"
21193 {
21194 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21195 MEM_VOLATILE_P (operands[0]) = 1;
21196 })
21197
21198 (define_insn "*sfence_insn"
21199 [(set (match_operand:BLK 0 "" "")
21200 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21201 "TARGET_SSE || TARGET_3DNOW_A"
21202 "sfence"
21203 [(set_attr "type" "sse")
21204 (set_attr "memory" "unknown")])
21205
21206 (define_expand "sse_prologue_save"
21207 [(parallel [(set (match_operand:BLK 0 "" "")
21208 (unspec:BLK [(reg:DI 21)
21209 (reg:DI 22)
21210 (reg:DI 23)
21211 (reg:DI 24)
21212 (reg:DI 25)
21213 (reg:DI 26)
21214 (reg:DI 27)
21215 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21216 (use (match_operand:DI 1 "register_operand" ""))
21217 (use (match_operand:DI 2 "immediate_operand" ""))
21218 (use (label_ref:DI (match_operand 3 "" "")))])]
21219 "TARGET_64BIT"
21220 "")
21221
21222 (define_insn "*sse_prologue_save_insn"
21223 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21224 (match_operand:DI 4 "const_int_operand" "n")))
21225 (unspec:BLK [(reg:DI 21)
21226 (reg:DI 22)
21227 (reg:DI 23)
21228 (reg:DI 24)
21229 (reg:DI 25)
21230 (reg:DI 26)
21231 (reg:DI 27)
21232 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21233 (use (match_operand:DI 1 "register_operand" "r"))
21234 (use (match_operand:DI 2 "const_int_operand" "i"))
21235 (use (label_ref:DI (match_operand 3 "" "X")))]
21236 "TARGET_64BIT
21237 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21238 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21239 "*
21240 {
21241 int i;
21242 operands[0] = gen_rtx_MEM (Pmode,
21243 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21244 output_asm_insn (\"jmp\\t%A1\", operands);
21245 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21246 {
21247 operands[4] = adjust_address (operands[0], DImode, i*16);
21248 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21249 PUT_MODE (operands[4], TImode);
21250 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21251 output_asm_insn (\"rex\", operands);
21252 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21253 }
21254 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21255 CODE_LABEL_NUMBER (operands[3]));
21256 RET;
21257 }
21258 "
21259 [(set_attr "type" "other")
21260 (set_attr "length_immediate" "0")
21261 (set_attr "length_address" "0")
21262 (set_attr "length" "135")
21263 (set_attr "memory" "store")
21264 (set_attr "modrm" "0")
21265 (set_attr "mode" "DI")])
21266
21267 ;; 3Dnow! instructions
21268
21269 (define_insn "addv2sf3"
21270 [(set (match_operand:V2SF 0 "register_operand" "=y")
21271 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21272 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21273 "TARGET_3DNOW"
21274 "pfadd\\t{%2, %0|%0, %2}"
21275 [(set_attr "type" "mmxadd")
21276 (set_attr "mode" "V2SF")])
21277
21278 (define_insn "subv2sf3"
21279 [(set (match_operand:V2SF 0 "register_operand" "=y")
21280 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21281 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21282 "TARGET_3DNOW"
21283 "pfsub\\t{%2, %0|%0, %2}"
21284 [(set_attr "type" "mmxadd")
21285 (set_attr "mode" "V2SF")])
21286
21287 (define_insn "subrv2sf3"
21288 [(set (match_operand:V2SF 0 "register_operand" "=y")
21289 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21290 (match_operand:V2SF 1 "register_operand" "0")))]
21291 "TARGET_3DNOW"
21292 "pfsubr\\t{%2, %0|%0, %2}"
21293 [(set_attr "type" "mmxadd")
21294 (set_attr "mode" "V2SF")])
21295
21296 (define_insn "gtv2sf3"
21297 [(set (match_operand:V2SI 0 "register_operand" "=y")
21298 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21299 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21300 "TARGET_3DNOW"
21301 "pfcmpgt\\t{%2, %0|%0, %2}"
21302 [(set_attr "type" "mmxcmp")
21303 (set_attr "mode" "V2SF")])
21304
21305 (define_insn "gev2sf3"
21306 [(set (match_operand:V2SI 0 "register_operand" "=y")
21307 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21308 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21309 "TARGET_3DNOW"
21310 "pfcmpge\\t{%2, %0|%0, %2}"
21311 [(set_attr "type" "mmxcmp")
21312 (set_attr "mode" "V2SF")])
21313
21314 (define_insn "eqv2sf3"
21315 [(set (match_operand:V2SI 0 "register_operand" "=y")
21316 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21317 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21318 "TARGET_3DNOW"
21319 "pfcmpeq\\t{%2, %0|%0, %2}"
21320 [(set_attr "type" "mmxcmp")
21321 (set_attr "mode" "V2SF")])
21322
21323 (define_insn "pfmaxv2sf3"
21324 [(set (match_operand:V2SF 0 "register_operand" "=y")
21325 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21326 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21327 "TARGET_3DNOW"
21328 "pfmax\\t{%2, %0|%0, %2}"
21329 [(set_attr "type" "mmxadd")
21330 (set_attr "mode" "V2SF")])
21331
21332 (define_insn "pfminv2sf3"
21333 [(set (match_operand:V2SF 0 "register_operand" "=y")
21334 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21335 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21336 "TARGET_3DNOW"
21337 "pfmin\\t{%2, %0|%0, %2}"
21338 [(set_attr "type" "mmxadd")
21339 (set_attr "mode" "V2SF")])
21340
21341 (define_insn "mulv2sf3"
21342 [(set (match_operand:V2SF 0 "register_operand" "=y")
21343 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21344 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21345 "TARGET_3DNOW"
21346 "pfmul\\t{%2, %0|%0, %2}"
21347 [(set_attr "type" "mmxmul")
21348 (set_attr "mode" "V2SF")])
21349
21350 (define_insn "femms"
21351 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21352 (clobber (reg:XF 8))
21353 (clobber (reg:XF 9))
21354 (clobber (reg:XF 10))
21355 (clobber (reg:XF 11))
21356 (clobber (reg:XF 12))
21357 (clobber (reg:XF 13))
21358 (clobber (reg:XF 14))
21359 (clobber (reg:XF 15))
21360 (clobber (reg:DI 29))
21361 (clobber (reg:DI 30))
21362 (clobber (reg:DI 31))
21363 (clobber (reg:DI 32))
21364 (clobber (reg:DI 33))
21365 (clobber (reg:DI 34))
21366 (clobber (reg:DI 35))
21367 (clobber (reg:DI 36))]
21368 "TARGET_3DNOW"
21369 "femms"
21370 [(set_attr "type" "mmx")
21371 (set_attr "memory" "none")])
21372
21373 (define_insn "pf2id"
21374 [(set (match_operand:V2SI 0 "register_operand" "=y")
21375 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21376 "TARGET_3DNOW"
21377 "pf2id\\t{%1, %0|%0, %1}"
21378 [(set_attr "type" "mmxcvt")
21379 (set_attr "mode" "V2SF")])
21380
21381 (define_insn "pf2iw"
21382 [(set (match_operand:V2SI 0 "register_operand" "=y")
21383 (sign_extend:V2SI
21384 (ss_truncate:V2HI
21385 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21386 "TARGET_3DNOW_A"
21387 "pf2iw\\t{%1, %0|%0, %1}"
21388 [(set_attr "type" "mmxcvt")
21389 (set_attr "mode" "V2SF")])
21390
21391 (define_insn "pfacc"
21392 [(set (match_operand:V2SF 0 "register_operand" "=y")
21393 (vec_concat:V2SF
21394 (plus:SF
21395 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21396 (parallel [(const_int 0)]))
21397 (vec_select:SF (match_dup 1)
21398 (parallel [(const_int 1)])))
21399 (plus:SF
21400 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21401 (parallel [(const_int 0)]))
21402 (vec_select:SF (match_dup 2)
21403 (parallel [(const_int 1)])))))]
21404 "TARGET_3DNOW"
21405 "pfacc\\t{%2, %0|%0, %2}"
21406 [(set_attr "type" "mmxadd")
21407 (set_attr "mode" "V2SF")])
21408
21409 (define_insn "pfnacc"
21410 [(set (match_operand:V2SF 0 "register_operand" "=y")
21411 (vec_concat:V2SF
21412 (minus:SF
21413 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21414 (parallel [(const_int 0)]))
21415 (vec_select:SF (match_dup 1)
21416 (parallel [(const_int 1)])))
21417 (minus:SF
21418 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21419 (parallel [(const_int 0)]))
21420 (vec_select:SF (match_dup 2)
21421 (parallel [(const_int 1)])))))]
21422 "TARGET_3DNOW_A"
21423 "pfnacc\\t{%2, %0|%0, %2}"
21424 [(set_attr "type" "mmxadd")
21425 (set_attr "mode" "V2SF")])
21426
21427 (define_insn "pfpnacc"
21428 [(set (match_operand:V2SF 0 "register_operand" "=y")
21429 (vec_concat:V2SF
21430 (minus:SF
21431 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21432 (parallel [(const_int 0)]))
21433 (vec_select:SF (match_dup 1)
21434 (parallel [(const_int 1)])))
21435 (plus:SF
21436 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21437 (parallel [(const_int 0)]))
21438 (vec_select:SF (match_dup 2)
21439 (parallel [(const_int 1)])))))]
21440 "TARGET_3DNOW_A"
21441 "pfpnacc\\t{%2, %0|%0, %2}"
21442 [(set_attr "type" "mmxadd")
21443 (set_attr "mode" "V2SF")])
21444
21445 (define_insn "pi2fw"
21446 [(set (match_operand:V2SF 0 "register_operand" "=y")
21447 (float:V2SF
21448 (vec_concat:V2SI
21449 (sign_extend:SI
21450 (truncate:HI
21451 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21452 (parallel [(const_int 0)]))))
21453 (sign_extend:SI
21454 (truncate:HI
21455 (vec_select:SI (match_dup 1)
21456 (parallel [(const_int 1)])))))))]
21457 "TARGET_3DNOW_A"
21458 "pi2fw\\t{%1, %0|%0, %1}"
21459 [(set_attr "type" "mmxcvt")
21460 (set_attr "mode" "V2SF")])
21461
21462 (define_insn "floatv2si2"
21463 [(set (match_operand:V2SF 0 "register_operand" "=y")
21464 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21465 "TARGET_3DNOW"
21466 "pi2fd\\t{%1, %0|%0, %1}"
21467 [(set_attr "type" "mmxcvt")
21468 (set_attr "mode" "V2SF")])
21469
21470 ;; This insn is identical to pavgb in operation, but the opcode is
21471 ;; different. To avoid accidentally matching pavgb, use an unspec.
21472
21473 (define_insn "pavgusb"
21474 [(set (match_operand:V8QI 0 "register_operand" "=y")
21475 (unspec:V8QI
21476 [(match_operand:V8QI 1 "register_operand" "0")
21477 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21478 UNSPEC_PAVGUSB))]
21479 "TARGET_3DNOW"
21480 "pavgusb\\t{%2, %0|%0, %2}"
21481 [(set_attr "type" "mmxshft")
21482 (set_attr "mode" "TI")])
21483
21484 ;; 3DNow reciprocal and sqrt
21485
21486 (define_insn "pfrcpv2sf2"
21487 [(set (match_operand:V2SF 0 "register_operand" "=y")
21488 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21489 UNSPEC_PFRCP))]
21490 "TARGET_3DNOW"
21491 "pfrcp\\t{%1, %0|%0, %1}"
21492 [(set_attr "type" "mmx")
21493 (set_attr "mode" "TI")])
21494
21495 (define_insn "pfrcpit1v2sf3"
21496 [(set (match_operand:V2SF 0 "register_operand" "=y")
21497 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21498 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21499 UNSPEC_PFRCPIT1))]
21500 "TARGET_3DNOW"
21501 "pfrcpit1\\t{%2, %0|%0, %2}"
21502 [(set_attr "type" "mmx")
21503 (set_attr "mode" "TI")])
21504
21505 (define_insn "pfrcpit2v2sf3"
21506 [(set (match_operand:V2SF 0 "register_operand" "=y")
21507 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21508 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21509 UNSPEC_PFRCPIT2))]
21510 "TARGET_3DNOW"
21511 "pfrcpit2\\t{%2, %0|%0, %2}"
21512 [(set_attr "type" "mmx")
21513 (set_attr "mode" "TI")])
21514
21515 (define_insn "pfrsqrtv2sf2"
21516 [(set (match_operand:V2SF 0 "register_operand" "=y")
21517 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21518 UNSPEC_PFRSQRT))]
21519 "TARGET_3DNOW"
21520 "pfrsqrt\\t{%1, %0|%0, %1}"
21521 [(set_attr "type" "mmx")
21522 (set_attr "mode" "TI")])
21523
21524 (define_insn "pfrsqit1v2sf3"
21525 [(set (match_operand:V2SF 0 "register_operand" "=y")
21526 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21527 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21528 UNSPEC_PFRSQIT1))]
21529 "TARGET_3DNOW"
21530 "pfrsqit1\\t{%2, %0|%0, %2}"
21531 [(set_attr "type" "mmx")
21532 (set_attr "mode" "TI")])
21533
21534 (define_insn "pmulhrwv4hi3"
21535 [(set (match_operand:V4HI 0 "register_operand" "=y")
21536 (truncate:V4HI
21537 (lshiftrt:V4SI
21538 (plus:V4SI
21539 (mult:V4SI
21540 (sign_extend:V4SI
21541 (match_operand:V4HI 1 "register_operand" "0"))
21542 (sign_extend:V4SI
21543 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21544 (const_vector:V4SI [(const_int 32768)
21545 (const_int 32768)
21546 (const_int 32768)
21547 (const_int 32768)]))
21548 (const_int 16))))]
21549 "TARGET_3DNOW"
21550 "pmulhrw\\t{%2, %0|%0, %2}"
21551 [(set_attr "type" "mmxmul")
21552 (set_attr "mode" "TI")])
21553
21554 (define_insn "pswapdv2si2"
21555 [(set (match_operand:V2SI 0 "register_operand" "=y")
21556 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21557 (parallel [(const_int 1) (const_int 0)])))]
21558 "TARGET_3DNOW_A"
21559 "pswapd\\t{%1, %0|%0, %1}"
21560 [(set_attr "type" "mmxcvt")
21561 (set_attr "mode" "TI")])
21562
21563 (define_insn "pswapdv2sf2"
21564 [(set (match_operand:V2SF 0 "register_operand" "=y")
21565 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21566 (parallel [(const_int 1) (const_int 0)])))]
21567 "TARGET_3DNOW_A"
21568 "pswapd\\t{%1, %0|%0, %1}"
21569 [(set_attr "type" "mmxcvt")
21570 (set_attr "mode" "TI")])
21571
21572 (define_expand "prefetch"
21573 [(prefetch (match_operand 0 "address_operand" "")
21574 (match_operand:SI 1 "const_int_operand" "")
21575 (match_operand:SI 2 "const_int_operand" ""))]
21576 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21577 {
21578 int rw = INTVAL (operands[1]);
21579 int locality = INTVAL (operands[2]);
21580
21581 if (rw != 0 && rw != 1)
21582 abort ();
21583 if (locality < 0 || locality > 3)
21584 abort ();
21585 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21586 abort ();
21587
21588 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21589 suported by SSE counterpart or the SSE prefetch is not available
21590 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21591 of locality. */
21592 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21593 operands[2] = GEN_INT (3);
21594 else
21595 operands[1] = const0_rtx;
21596 })
21597
21598 (define_insn "*prefetch_sse"
21599 [(prefetch (match_operand:SI 0 "address_operand" "p")
21600 (const_int 0)
21601 (match_operand:SI 1 "const_int_operand" ""))]
21602 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21603 {
21604 static const char * const patterns[4] = {
21605 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21606 };
21607
21608 int locality = INTVAL (operands[1]);
21609 if (locality < 0 || locality > 3)
21610 abort ();
21611
21612 return patterns[locality];
21613 }
21614 [(set_attr "type" "sse")
21615 (set_attr "memory" "none")])
21616
21617 (define_insn "*prefetch_sse_rex"
21618 [(prefetch (match_operand:DI 0 "address_operand" "p")
21619 (const_int 0)
21620 (match_operand:SI 1 "const_int_operand" ""))]
21621 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21622 {
21623 static const char * const patterns[4] = {
21624 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21625 };
21626
21627 int locality = INTVAL (operands[1]);
21628 if (locality < 0 || locality > 3)
21629 abort ();
21630
21631 return patterns[locality];
21632 }
21633 [(set_attr "type" "sse")
21634 (set_attr "memory" "none")])
21635
21636 (define_insn "*prefetch_3dnow"
21637 [(prefetch (match_operand:SI 0 "address_operand" "p")
21638 (match_operand:SI 1 "const_int_operand" "n")
21639 (const_int 3))]
21640 "TARGET_3DNOW && !TARGET_64BIT"
21641 {
21642 if (INTVAL (operands[1]) == 0)
21643 return "prefetch\t%a0";
21644 else
21645 return "prefetchw\t%a0";
21646 }
21647 [(set_attr "type" "mmx")
21648 (set_attr "memory" "none")])
21649
21650 (define_insn "*prefetch_3dnow_rex"
21651 [(prefetch (match_operand:DI 0 "address_operand" "p")
21652 (match_operand:SI 1 "const_int_operand" "n")
21653 (const_int 3))]
21654 "TARGET_3DNOW && TARGET_64BIT"
21655 {
21656 if (INTVAL (operands[1]) == 0)
21657 return "prefetch\t%a0";
21658 else
21659 return "prefetchw\t%a0";
21660 }
21661 [(set_attr "type" "mmx")
21662 (set_attr "memory" "none")])
21663
21664 ;; SSE2 support
21665
21666 (define_insn "addv2df3"
21667 [(set (match_operand:V2DF 0 "register_operand" "=x")
21668 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21669 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21670 "TARGET_SSE2"
21671 "addpd\t{%2, %0|%0, %2}"
21672 [(set_attr "type" "sseadd")
21673 (set_attr "mode" "V2DF")])
21674
21675 (define_insn "vmaddv2df3"
21676 [(set (match_operand:V2DF 0 "register_operand" "=x")
21677 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21678 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21679 (match_dup 1)
21680 (const_int 1)))]
21681 "TARGET_SSE2"
21682 "addsd\t{%2, %0|%0, %2}"
21683 [(set_attr "type" "sseadd")
21684 (set_attr "mode" "DF")])
21685
21686 (define_insn "subv2df3"
21687 [(set (match_operand:V2DF 0 "register_operand" "=x")
21688 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21689 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21690 "TARGET_SSE2"
21691 "subpd\t{%2, %0|%0, %2}"
21692 [(set_attr "type" "sseadd")
21693 (set_attr "mode" "V2DF")])
21694
21695 (define_insn "vmsubv2df3"
21696 [(set (match_operand:V2DF 0 "register_operand" "=x")
21697 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21698 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21699 (match_dup 1)
21700 (const_int 1)))]
21701 "TARGET_SSE2"
21702 "subsd\t{%2, %0|%0, %2}"
21703 [(set_attr "type" "sseadd")
21704 (set_attr "mode" "DF")])
21705
21706 (define_insn "mulv2df3"
21707 [(set (match_operand:V2DF 0 "register_operand" "=x")
21708 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21709 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21710 "TARGET_SSE2"
21711 "mulpd\t{%2, %0|%0, %2}"
21712 [(set_attr "type" "ssemul")
21713 (set_attr "mode" "V2DF")])
21714
21715 (define_insn "vmmulv2df3"
21716 [(set (match_operand:V2DF 0 "register_operand" "=x")
21717 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21718 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21719 (match_dup 1)
21720 (const_int 1)))]
21721 "TARGET_SSE2"
21722 "mulsd\t{%2, %0|%0, %2}"
21723 [(set_attr "type" "ssemul")
21724 (set_attr "mode" "DF")])
21725
21726 (define_insn "divv2df3"
21727 [(set (match_operand:V2DF 0 "register_operand" "=x")
21728 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21729 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21730 "TARGET_SSE2"
21731 "divpd\t{%2, %0|%0, %2}"
21732 [(set_attr "type" "ssediv")
21733 (set_attr "mode" "V2DF")])
21734
21735 (define_insn "vmdivv2df3"
21736 [(set (match_operand:V2DF 0 "register_operand" "=x")
21737 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21738 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21739 (match_dup 1)
21740 (const_int 1)))]
21741 "TARGET_SSE2"
21742 "divsd\t{%2, %0|%0, %2}"
21743 [(set_attr "type" "ssediv")
21744 (set_attr "mode" "DF")])
21745
21746 ;; SSE min/max
21747
21748 (define_insn "smaxv2df3"
21749 [(set (match_operand:V2DF 0 "register_operand" "=x")
21750 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21751 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21752 "TARGET_SSE2"
21753 "maxpd\t{%2, %0|%0, %2}"
21754 [(set_attr "type" "sseadd")
21755 (set_attr "mode" "V2DF")])
21756
21757 (define_insn "vmsmaxv2df3"
21758 [(set (match_operand:V2DF 0 "register_operand" "=x")
21759 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21760 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21761 (match_dup 1)
21762 (const_int 1)))]
21763 "TARGET_SSE2"
21764 "maxsd\t{%2, %0|%0, %2}"
21765 [(set_attr "type" "sseadd")
21766 (set_attr "mode" "DF")])
21767
21768 (define_insn "sminv2df3"
21769 [(set (match_operand:V2DF 0 "register_operand" "=x")
21770 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21771 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21772 "TARGET_SSE2"
21773 "minpd\t{%2, %0|%0, %2}"
21774 [(set_attr "type" "sseadd")
21775 (set_attr "mode" "V2DF")])
21776
21777 (define_insn "vmsminv2df3"
21778 [(set (match_operand:V2DF 0 "register_operand" "=x")
21779 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21780 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21781 (match_dup 1)
21782 (const_int 1)))]
21783 "TARGET_SSE2"
21784 "minsd\t{%2, %0|%0, %2}"
21785 [(set_attr "type" "sseadd")
21786 (set_attr "mode" "DF")])
21787 ;; SSE2 square root. There doesn't appear to be an extension for the
21788 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21789
21790 (define_insn "sqrtv2df2"
21791 [(set (match_operand:V2DF 0 "register_operand" "=x")
21792 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21793 "TARGET_SSE2"
21794 "sqrtpd\t{%1, %0|%0, %1}"
21795 [(set_attr "type" "sse")
21796 (set_attr "mode" "V2DF")])
21797
21798 (define_insn "vmsqrtv2df2"
21799 [(set (match_operand:V2DF 0 "register_operand" "=x")
21800 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21801 (match_operand:V2DF 2 "register_operand" "0")
21802 (const_int 1)))]
21803 "TARGET_SSE2"
21804 "sqrtsd\t{%1, %0|%0, %1}"
21805 [(set_attr "type" "sse")
21806 (set_attr "mode" "SF")])
21807
21808 ;; SSE mask-generating compares
21809
21810 (define_insn "maskcmpv2df3"
21811 [(set (match_operand:V2DI 0 "register_operand" "=x")
21812 (match_operator:V2DI 3 "sse_comparison_operator"
21813 [(match_operand:V2DF 1 "register_operand" "0")
21814 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21815 "TARGET_SSE2"
21816 "cmp%D3pd\t{%2, %0|%0, %2}"
21817 [(set_attr "type" "ssecmp")
21818 (set_attr "mode" "V2DF")])
21819
21820 (define_insn "maskncmpv2df3"
21821 [(set (match_operand:V2DI 0 "register_operand" "=x")
21822 (not:V2DI
21823 (match_operator:V2DI 3 "sse_comparison_operator"
21824 [(match_operand:V2DF 1 "register_operand" "0")
21825 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21826 "TARGET_SSE2"
21827 {
21828 if (GET_CODE (operands[3]) == UNORDERED)
21829 return "cmpordps\t{%2, %0|%0, %2}";
21830 else
21831 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21832 }
21833 [(set_attr "type" "ssecmp")
21834 (set_attr "mode" "V2DF")])
21835
21836 (define_insn "vmmaskcmpv2df3"
21837 [(set (match_operand:V2DI 0 "register_operand" "=x")
21838 (vec_merge:V2DI
21839 (match_operator:V2DI 3 "sse_comparison_operator"
21840 [(match_operand:V2DF 1 "register_operand" "0")
21841 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21842 (subreg:V2DI (match_dup 1) 0)
21843 (const_int 1)))]
21844 "TARGET_SSE2"
21845 "cmp%D3sd\t{%2, %0|%0, %2}"
21846 [(set_attr "type" "ssecmp")
21847 (set_attr "mode" "DF")])
21848
21849 (define_insn "vmmaskncmpv2df3"
21850 [(set (match_operand:V2DI 0 "register_operand" "=x")
21851 (vec_merge:V2DI
21852 (not:V2DI
21853 (match_operator:V2DI 3 "sse_comparison_operator"
21854 [(match_operand:V2DF 1 "register_operand" "0")
21855 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21856 (subreg:V2DI (match_dup 1) 0)
21857 (const_int 1)))]
21858 "TARGET_SSE2"
21859 {
21860 if (GET_CODE (operands[3]) == UNORDERED)
21861 return "cmpordsd\t{%2, %0|%0, %2}";
21862 else
21863 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21864 }
21865 [(set_attr "type" "ssecmp")
21866 (set_attr "mode" "DF")])
21867
21868 (define_insn "sse2_comi"
21869 [(set (reg:CCFP 17)
21870 (compare:CCFP (vec_select:DF
21871 (match_operand:V2DF 0 "register_operand" "x")
21872 (parallel [(const_int 0)]))
21873 (vec_select:DF
21874 (match_operand:V2DF 1 "register_operand" "x")
21875 (parallel [(const_int 0)]))))]
21876 "TARGET_SSE2"
21877 "comisd\t{%1, %0|%0, %1}"
21878 [(set_attr "type" "ssecomi")
21879 (set_attr "mode" "DF")])
21880
21881 (define_insn "sse2_ucomi"
21882 [(set (reg:CCFPU 17)
21883 (compare:CCFPU (vec_select:DF
21884 (match_operand:V2DF 0 "register_operand" "x")
21885 (parallel [(const_int 0)]))
21886 (vec_select:DF
21887 (match_operand:V2DF 1 "register_operand" "x")
21888 (parallel [(const_int 0)]))))]
21889 "TARGET_SSE2"
21890 "ucomisd\t{%1, %0|%0, %1}"
21891 [(set_attr "type" "ssecomi")
21892 (set_attr "mode" "DF")])
21893
21894 ;; SSE Strange Moves.
21895
21896 (define_insn "sse2_movmskpd"
21897 [(set (match_operand:SI 0 "register_operand" "=r")
21898 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21899 UNSPEC_MOVMSK))]
21900 "TARGET_SSE2"
21901 "movmskpd\t{%1, %0|%0, %1}"
21902 [(set_attr "type" "ssecvt")
21903 (set_attr "mode" "V2DF")])
21904
21905 (define_insn "sse2_pmovmskb"
21906 [(set (match_operand:SI 0 "register_operand" "=r")
21907 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21908 UNSPEC_MOVMSK))]
21909 "TARGET_SSE2"
21910 "pmovmskb\t{%1, %0|%0, %1}"
21911 [(set_attr "type" "ssecvt")
21912 (set_attr "mode" "V2DF")])
21913
21914 (define_insn "sse2_maskmovdqu"
21915 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21916 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21917 (match_operand:V16QI 2 "register_operand" "x")]
21918 UNSPEC_MASKMOV))]
21919 "TARGET_SSE2"
21920 ;; @@@ check ordering of operands in intel/nonintel syntax
21921 "maskmovdqu\t{%2, %1|%1, %2}"
21922 [(set_attr "type" "ssecvt")
21923 (set_attr "mode" "TI")])
21924
21925 (define_insn "sse2_maskmovdqu_rex64"
21926 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21927 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21928 (match_operand:V16QI 2 "register_operand" "x")]
21929 UNSPEC_MASKMOV))]
21930 "TARGET_SSE2"
21931 ;; @@@ check ordering of operands in intel/nonintel syntax
21932 "maskmovdqu\t{%2, %1|%1, %2}"
21933 [(set_attr "type" "ssecvt")
21934 (set_attr "mode" "TI")])
21935
21936 (define_insn "sse2_movntv2df"
21937 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21938 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21939 UNSPEC_MOVNT))]
21940 "TARGET_SSE2"
21941 "movntpd\t{%1, %0|%0, %1}"
21942 [(set_attr "type" "ssecvt")
21943 (set_attr "mode" "V2DF")])
21944
21945 (define_insn "sse2_movntv2di"
21946 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21947 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21948 UNSPEC_MOVNT))]
21949 "TARGET_SSE2"
21950 "movntdq\t{%1, %0|%0, %1}"
21951 [(set_attr "type" "ssecvt")
21952 (set_attr "mode" "TI")])
21953
21954 (define_insn "sse2_movntsi"
21955 [(set (match_operand:SI 0 "memory_operand" "=m")
21956 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21957 UNSPEC_MOVNT))]
21958 "TARGET_SSE2"
21959 "movnti\t{%1, %0|%0, %1}"
21960 [(set_attr "type" "ssecvt")
21961 (set_attr "mode" "V2DF")])
21962
21963 ;; SSE <-> integer/MMX conversions
21964
21965 ;; Conversions between SI and SF
21966
21967 (define_insn "cvtdq2ps"
21968 [(set (match_operand:V4SF 0 "register_operand" "=x")
21969 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21970 "TARGET_SSE2"
21971 "cvtdq2ps\t{%1, %0|%0, %1}"
21972 [(set_attr "type" "ssecvt")
21973 (set_attr "mode" "V2DF")])
21974
21975 (define_insn "cvtps2dq"
21976 [(set (match_operand:V4SI 0 "register_operand" "=x")
21977 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21978 "TARGET_SSE2"
21979 "cvtps2dq\t{%1, %0|%0, %1}"
21980 [(set_attr "type" "ssecvt")
21981 (set_attr "mode" "TI")])
21982
21983 (define_insn "cvttps2dq"
21984 [(set (match_operand:V4SI 0 "register_operand" "=x")
21985 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21986 UNSPEC_FIX))]
21987 "TARGET_SSE2"
21988 "cvttps2dq\t{%1, %0|%0, %1}"
21989 [(set_attr "type" "ssecvt")
21990 (set_attr "mode" "TI")])
21991
21992 ;; Conversions between SI and DF
21993
21994 (define_insn "cvtdq2pd"
21995 [(set (match_operand:V2DF 0 "register_operand" "=x")
21996 (float:V2DF (vec_select:V2SI
21997 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21998 (parallel
21999 [(const_int 0)
22000 (const_int 1)]))))]
22001 "TARGET_SSE2"
22002 "cvtdq2pd\t{%1, %0|%0, %1}"
22003 [(set_attr "type" "ssecvt")
22004 (set_attr "mode" "V2DF")])
22005
22006 (define_insn "cvtpd2dq"
22007 [(set (match_operand:V4SI 0 "register_operand" "=x")
22008 (vec_concat:V4SI
22009 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22010 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22011 "TARGET_SSE2"
22012 "cvtpd2dq\t{%1, %0|%0, %1}"
22013 [(set_attr "type" "ssecvt")
22014 (set_attr "mode" "TI")])
22015
22016 (define_insn "cvttpd2dq"
22017 [(set (match_operand:V4SI 0 "register_operand" "=x")
22018 (vec_concat:V4SI
22019 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22020 UNSPEC_FIX)
22021 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22022 "TARGET_SSE2"
22023 "cvttpd2dq\t{%1, %0|%0, %1}"
22024 [(set_attr "type" "ssecvt")
22025 (set_attr "mode" "TI")])
22026
22027 (define_insn "cvtpd2pi"
22028 [(set (match_operand:V2SI 0 "register_operand" "=y")
22029 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22030 "TARGET_SSE2"
22031 "cvtpd2pi\t{%1, %0|%0, %1}"
22032 [(set_attr "type" "ssecvt")
22033 (set_attr "mode" "TI")])
22034
22035 (define_insn "cvttpd2pi"
22036 [(set (match_operand:V2SI 0 "register_operand" "=y")
22037 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22038 UNSPEC_FIX))]
22039 "TARGET_SSE2"
22040 "cvttpd2pi\t{%1, %0|%0, %1}"
22041 [(set_attr "type" "ssecvt")
22042 (set_attr "mode" "TI")])
22043
22044 (define_insn "cvtpi2pd"
22045 [(set (match_operand:V2DF 0 "register_operand" "=x")
22046 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22047 "TARGET_SSE2"
22048 "cvtpi2pd\t{%1, %0|%0, %1}"
22049 [(set_attr "type" "ssecvt")
22050 (set_attr "mode" "TI")])
22051
22052 ;; Conversions between SI and DF
22053
22054 (define_insn "cvtsd2si"
22055 [(set (match_operand:SI 0 "register_operand" "=r,r")
22056 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22057 (parallel [(const_int 0)]))))]
22058 "TARGET_SSE2"
22059 "cvtsd2si\t{%1, %0|%0, %1}"
22060 [(set_attr "type" "sseicvt")
22061 (set_attr "athlon_decode" "double,vector")
22062 (set_attr "mode" "SI")])
22063
22064 (define_insn "cvtsd2siq"
22065 [(set (match_operand:DI 0 "register_operand" "=r,r")
22066 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22067 (parallel [(const_int 0)]))))]
22068 "TARGET_SSE2 && TARGET_64BIT"
22069 "cvtsd2siq\t{%1, %0|%0, %1}"
22070 [(set_attr "type" "sseicvt")
22071 (set_attr "athlon_decode" "double,vector")
22072 (set_attr "mode" "DI")])
22073
22074 (define_insn "cvttsd2si"
22075 [(set (match_operand:SI 0 "register_operand" "=r,r")
22076 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22077 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22078 "TARGET_SSE2"
22079 "cvttsd2si\t{%1, %0|%0, %1}"
22080 [(set_attr "type" "sseicvt")
22081 (set_attr "mode" "SI")
22082 (set_attr "athlon_decode" "double,vector")])
22083
22084 (define_insn "cvttsd2siq"
22085 [(set (match_operand:DI 0 "register_operand" "=r,r")
22086 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22087 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22088 "TARGET_SSE2 && TARGET_64BIT"
22089 "cvttsd2siq\t{%1, %0|%0, %1}"
22090 [(set_attr "type" "sseicvt")
22091 (set_attr "mode" "DI")
22092 (set_attr "athlon_decode" "double,vector")])
22093
22094 (define_insn "cvtsi2sd"
22095 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22096 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22097 (vec_duplicate:V2DF
22098 (float:DF
22099 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22100 (const_int 2)))]
22101 "TARGET_SSE2"
22102 "cvtsi2sd\t{%2, %0|%0, %2}"
22103 [(set_attr "type" "sseicvt")
22104 (set_attr "mode" "DF")
22105 (set_attr "athlon_decode" "double,direct")])
22106
22107 (define_insn "cvtsi2sdq"
22108 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22109 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22110 (vec_duplicate:V2DF
22111 (float:DF
22112 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22113 (const_int 2)))]
22114 "TARGET_SSE2 && TARGET_64BIT"
22115 "cvtsi2sdq\t{%2, %0|%0, %2}"
22116 [(set_attr "type" "sseicvt")
22117 (set_attr "mode" "DF")
22118 (set_attr "athlon_decode" "double,direct")])
22119
22120 ;; Conversions between SF and DF
22121
22122 (define_insn "cvtsd2ss"
22123 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22124 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22125 (vec_duplicate:V4SF
22126 (float_truncate:V2SF
22127 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22128 (const_int 14)))]
22129 "TARGET_SSE2"
22130 "cvtsd2ss\t{%2, %0|%0, %2}"
22131 [(set_attr "type" "ssecvt")
22132 (set_attr "athlon_decode" "vector,double")
22133 (set_attr "mode" "SF")])
22134
22135 (define_insn "cvtss2sd"
22136 [(set (match_operand:V2DF 0 "register_operand" "=x")
22137 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22138 (float_extend:V2DF
22139 (vec_select:V2SF
22140 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22141 (parallel [(const_int 0)
22142 (const_int 1)])))
22143 (const_int 2)))]
22144 "TARGET_SSE2"
22145 "cvtss2sd\t{%2, %0|%0, %2}"
22146 [(set_attr "type" "ssecvt")
22147 (set_attr "mode" "DF")])
22148
22149 (define_insn "cvtpd2ps"
22150 [(set (match_operand:V4SF 0 "register_operand" "=x")
22151 (subreg:V4SF
22152 (vec_concat:V4SI
22153 (subreg:V2SI (float_truncate:V2SF
22154 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22155 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22156 "TARGET_SSE2"
22157 "cvtpd2ps\t{%1, %0|%0, %1}"
22158 [(set_attr "type" "ssecvt")
22159 (set_attr "mode" "V4SF")])
22160
22161 (define_insn "cvtps2pd"
22162 [(set (match_operand:V2DF 0 "register_operand" "=x")
22163 (float_extend:V2DF
22164 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22165 (parallel [(const_int 0)
22166 (const_int 1)]))))]
22167 "TARGET_SSE2"
22168 "cvtps2pd\t{%1, %0|%0, %1}"
22169 [(set_attr "type" "ssecvt")
22170 (set_attr "mode" "V2DF")])
22171
22172 ;; SSE2 variants of MMX insns
22173
22174 ;; MMX arithmetic
22175
22176 (define_insn "addv16qi3"
22177 [(set (match_operand:V16QI 0 "register_operand" "=x")
22178 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22179 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22180 "TARGET_SSE2"
22181 "paddb\t{%2, %0|%0, %2}"
22182 [(set_attr "type" "sseiadd")
22183 (set_attr "mode" "TI")])
22184
22185 (define_insn "addv8hi3"
22186 [(set (match_operand:V8HI 0 "register_operand" "=x")
22187 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22188 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22189 "TARGET_SSE2"
22190 "paddw\t{%2, %0|%0, %2}"
22191 [(set_attr "type" "sseiadd")
22192 (set_attr "mode" "TI")])
22193
22194 (define_insn "addv4si3"
22195 [(set (match_operand:V4SI 0 "register_operand" "=x")
22196 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22197 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22198 "TARGET_SSE2"
22199 "paddd\t{%2, %0|%0, %2}"
22200 [(set_attr "type" "sseiadd")
22201 (set_attr "mode" "TI")])
22202
22203 (define_insn "addv2di3"
22204 [(set (match_operand:V2DI 0 "register_operand" "=x")
22205 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22206 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22207 "TARGET_SSE2"
22208 "paddq\t{%2, %0|%0, %2}"
22209 [(set_attr "type" "sseiadd")
22210 (set_attr "mode" "TI")])
22211
22212 (define_insn "ssaddv16qi3"
22213 [(set (match_operand:V16QI 0 "register_operand" "=x")
22214 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22215 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22216 "TARGET_SSE2"
22217 "paddsb\t{%2, %0|%0, %2}"
22218 [(set_attr "type" "sseiadd")
22219 (set_attr "mode" "TI")])
22220
22221 (define_insn "ssaddv8hi3"
22222 [(set (match_operand:V8HI 0 "register_operand" "=x")
22223 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22224 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22225 "TARGET_SSE2"
22226 "paddsw\t{%2, %0|%0, %2}"
22227 [(set_attr "type" "sseiadd")
22228 (set_attr "mode" "TI")])
22229
22230 (define_insn "usaddv16qi3"
22231 [(set (match_operand:V16QI 0 "register_operand" "=x")
22232 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22233 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22234 "TARGET_SSE2"
22235 "paddusb\t{%2, %0|%0, %2}"
22236 [(set_attr "type" "sseiadd")
22237 (set_attr "mode" "TI")])
22238
22239 (define_insn "usaddv8hi3"
22240 [(set (match_operand:V8HI 0 "register_operand" "=x")
22241 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22242 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22243 "TARGET_SSE2"
22244 "paddusw\t{%2, %0|%0, %2}"
22245 [(set_attr "type" "sseiadd")
22246 (set_attr "mode" "TI")])
22247
22248 (define_insn "subv16qi3"
22249 [(set (match_operand:V16QI 0 "register_operand" "=x")
22250 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22251 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22252 "TARGET_SSE2"
22253 "psubb\t{%2, %0|%0, %2}"
22254 [(set_attr "type" "sseiadd")
22255 (set_attr "mode" "TI")])
22256
22257 (define_insn "subv8hi3"
22258 [(set (match_operand:V8HI 0 "register_operand" "=x")
22259 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22260 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22261 "TARGET_SSE2"
22262 "psubw\t{%2, %0|%0, %2}"
22263 [(set_attr "type" "sseiadd")
22264 (set_attr "mode" "TI")])
22265
22266 (define_insn "subv4si3"
22267 [(set (match_operand:V4SI 0 "register_operand" "=x")
22268 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22269 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22270 "TARGET_SSE2"
22271 "psubd\t{%2, %0|%0, %2}"
22272 [(set_attr "type" "sseiadd")
22273 (set_attr "mode" "TI")])
22274
22275 (define_insn "subv2di3"
22276 [(set (match_operand:V2DI 0 "register_operand" "=x")
22277 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22278 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22279 "TARGET_SSE2"
22280 "psubq\t{%2, %0|%0, %2}"
22281 [(set_attr "type" "sseiadd")
22282 (set_attr "mode" "TI")])
22283
22284 (define_insn "sssubv16qi3"
22285 [(set (match_operand:V16QI 0 "register_operand" "=x")
22286 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22287 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22288 "TARGET_SSE2"
22289 "psubsb\t{%2, %0|%0, %2}"
22290 [(set_attr "type" "sseiadd")
22291 (set_attr "mode" "TI")])
22292
22293 (define_insn "sssubv8hi3"
22294 [(set (match_operand:V8HI 0 "register_operand" "=x")
22295 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22296 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22297 "TARGET_SSE2"
22298 "psubsw\t{%2, %0|%0, %2}"
22299 [(set_attr "type" "sseiadd")
22300 (set_attr "mode" "TI")])
22301
22302 (define_insn "ussubv16qi3"
22303 [(set (match_operand:V16QI 0 "register_operand" "=x")
22304 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22305 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22306 "TARGET_SSE2"
22307 "psubusb\t{%2, %0|%0, %2}"
22308 [(set_attr "type" "sseiadd")
22309 (set_attr "mode" "TI")])
22310
22311 (define_insn "ussubv8hi3"
22312 [(set (match_operand:V8HI 0 "register_operand" "=x")
22313 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22314 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22315 "TARGET_SSE2"
22316 "psubusw\t{%2, %0|%0, %2}"
22317 [(set_attr "type" "sseiadd")
22318 (set_attr "mode" "TI")])
22319
22320 (define_insn "mulv8hi3"
22321 [(set (match_operand:V8HI 0 "register_operand" "=x")
22322 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22323 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22324 "TARGET_SSE2"
22325 "pmullw\t{%2, %0|%0, %2}"
22326 [(set_attr "type" "sseimul")
22327 (set_attr "mode" "TI")])
22328
22329 (define_insn "smulv8hi3_highpart"
22330 [(set (match_operand:V8HI 0 "register_operand" "=x")
22331 (truncate:V8HI
22332 (lshiftrt:V8SI
22333 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22334 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22335 (const_int 16))))]
22336 "TARGET_SSE2"
22337 "pmulhw\t{%2, %0|%0, %2}"
22338 [(set_attr "type" "sseimul")
22339 (set_attr "mode" "TI")])
22340
22341 (define_insn "umulv8hi3_highpart"
22342 [(set (match_operand:V8HI 0 "register_operand" "=x")
22343 (truncate:V8HI
22344 (lshiftrt:V8SI
22345 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22346 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22347 (const_int 16))))]
22348 "TARGET_SSE2"
22349 "pmulhuw\t{%2, %0|%0, %2}"
22350 [(set_attr "type" "sseimul")
22351 (set_attr "mode" "TI")])
22352
22353 (define_insn "sse2_umulsidi3"
22354 [(set (match_operand:DI 0 "register_operand" "=y")
22355 (mult:DI (zero_extend:DI (vec_select:SI
22356 (match_operand:V2SI 1 "register_operand" "0")
22357 (parallel [(const_int 0)])))
22358 (zero_extend:DI (vec_select:SI
22359 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22360 (parallel [(const_int 0)])))))]
22361 "TARGET_SSE2"
22362 "pmuludq\t{%2, %0|%0, %2}"
22363 [(set_attr "type" "sseimul")
22364 (set_attr "mode" "TI")])
22365
22366 (define_insn "sse2_umulv2siv2di3"
22367 [(set (match_operand:V2DI 0 "register_operand" "=x")
22368 (mult:V2DI (zero_extend:V2DI
22369 (vec_select:V2SI
22370 (match_operand:V4SI 1 "register_operand" "0")
22371 (parallel [(const_int 0) (const_int 2)])))
22372 (zero_extend:V2DI
22373 (vec_select:V2SI
22374 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22375 (parallel [(const_int 0) (const_int 2)])))))]
22376 "TARGET_SSE2"
22377 "pmuludq\t{%2, %0|%0, %2}"
22378 [(set_attr "type" "sseimul")
22379 (set_attr "mode" "TI")])
22380
22381 (define_insn "sse2_pmaddwd"
22382 [(set (match_operand:V4SI 0 "register_operand" "=x")
22383 (plus:V4SI
22384 (mult:V4SI
22385 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22386 (parallel [(const_int 0)
22387 (const_int 2)
22388 (const_int 4)
22389 (const_int 6)])))
22390 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22391 (parallel [(const_int 0)
22392 (const_int 2)
22393 (const_int 4)
22394 (const_int 6)]))))
22395 (mult:V4SI
22396 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22397 (parallel [(const_int 1)
22398 (const_int 3)
22399 (const_int 5)
22400 (const_int 7)])))
22401 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22402 (parallel [(const_int 1)
22403 (const_int 3)
22404 (const_int 5)
22405 (const_int 7)]))))))]
22406 "TARGET_SSE2"
22407 "pmaddwd\t{%2, %0|%0, %2}"
22408 [(set_attr "type" "sseiadd")
22409 (set_attr "mode" "TI")])
22410
22411 ;; Same as pxor, but don't show input operands so that we don't think
22412 ;; they are live.
22413 (define_insn "sse2_clrti"
22414 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22415 "TARGET_SSE2"
22416 {
22417 if (get_attr_mode (insn) == MODE_TI)
22418 return "pxor\t%0, %0";
22419 else
22420 return "xorps\t%0, %0";
22421 }
22422 [(set_attr "type" "ssemov")
22423 (set_attr "memory" "none")
22424 (set (attr "mode")
22425 (if_then_else
22426 (ne (symbol_ref "optimize_size")
22427 (const_int 0))
22428 (const_string "V4SF")
22429 (const_string "TI")))])
22430
22431 ;; MMX unsigned averages/sum of absolute differences
22432
22433 (define_insn "sse2_uavgv16qi3"
22434 [(set (match_operand:V16QI 0 "register_operand" "=x")
22435 (ashiftrt:V16QI
22436 (plus:V16QI (plus:V16QI
22437 (match_operand:V16QI 1 "register_operand" "0")
22438 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22439 (const_vector:V16QI [(const_int 1) (const_int 1)
22440 (const_int 1) (const_int 1)
22441 (const_int 1) (const_int 1)
22442 (const_int 1) (const_int 1)
22443 (const_int 1) (const_int 1)
22444 (const_int 1) (const_int 1)
22445 (const_int 1) (const_int 1)
22446 (const_int 1) (const_int 1)]))
22447 (const_int 1)))]
22448 "TARGET_SSE2"
22449 "pavgb\t{%2, %0|%0, %2}"
22450 [(set_attr "type" "sseiadd")
22451 (set_attr "mode" "TI")])
22452
22453 (define_insn "sse2_uavgv8hi3"
22454 [(set (match_operand:V8HI 0 "register_operand" "=x")
22455 (ashiftrt:V8HI
22456 (plus:V8HI (plus:V8HI
22457 (match_operand:V8HI 1 "register_operand" "0")
22458 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22459 (const_vector:V8HI [(const_int 1) (const_int 1)
22460 (const_int 1) (const_int 1)
22461 (const_int 1) (const_int 1)
22462 (const_int 1) (const_int 1)]))
22463 (const_int 1)))]
22464 "TARGET_SSE2"
22465 "pavgw\t{%2, %0|%0, %2}"
22466 [(set_attr "type" "sseiadd")
22467 (set_attr "mode" "TI")])
22468
22469 ;; @@@ this isn't the right representation.
22470 (define_insn "sse2_psadbw"
22471 [(set (match_operand:V2DI 0 "register_operand" "=x")
22472 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22473 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22474 UNSPEC_PSADBW))]
22475 "TARGET_SSE2"
22476 "psadbw\t{%2, %0|%0, %2}"
22477 [(set_attr "type" "sseiadd")
22478 (set_attr "mode" "TI")])
22479
22480
22481 ;; MMX insert/extract/shuffle
22482
22483 (define_insn "sse2_pinsrw"
22484 [(set (match_operand:V8HI 0 "register_operand" "=x")
22485 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22486 (vec_duplicate:V8HI
22487 (truncate:HI
22488 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22489 (match_operand:SI 3 "immediate_operand" "i")))]
22490 "TARGET_SSE2"
22491 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22492 [(set_attr "type" "ssecvt")
22493 (set_attr "mode" "TI")])
22494
22495 (define_insn "sse2_pextrw"
22496 [(set (match_operand:SI 0 "register_operand" "=r")
22497 (zero_extend:SI
22498 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22499 (parallel
22500 [(match_operand:SI 2 "immediate_operand" "i")]))))]
22501 "TARGET_SSE2"
22502 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22503 [(set_attr "type" "ssecvt")
22504 (set_attr "mode" "TI")])
22505
22506 (define_insn "sse2_pshufd"
22507 [(set (match_operand:V4SI 0 "register_operand" "=x")
22508 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22509 (match_operand:SI 2 "immediate_operand" "i")]
22510 UNSPEC_SHUFFLE))]
22511 "TARGET_SSE2"
22512 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22513 [(set_attr "type" "ssecvt")
22514 (set_attr "mode" "TI")])
22515
22516 (define_insn "sse2_pshuflw"
22517 [(set (match_operand:V8HI 0 "register_operand" "=x")
22518 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22519 (match_operand:SI 2 "immediate_operand" "i")]
22520 UNSPEC_PSHUFLW))]
22521 "TARGET_SSE2"
22522 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22523 [(set_attr "type" "ssecvt")
22524 (set_attr "mode" "TI")])
22525
22526 (define_insn "sse2_pshufhw"
22527 [(set (match_operand:V8HI 0 "register_operand" "=x")
22528 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22529 (match_operand:SI 2 "immediate_operand" "i")]
22530 UNSPEC_PSHUFHW))]
22531 "TARGET_SSE2"
22532 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22533 [(set_attr "type" "ssecvt")
22534 (set_attr "mode" "TI")])
22535
22536 ;; MMX mask-generating comparisons
22537
22538 (define_insn "eqv16qi3"
22539 [(set (match_operand:V16QI 0 "register_operand" "=x")
22540 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22541 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22542 "TARGET_SSE2"
22543 "pcmpeqb\t{%2, %0|%0, %2}"
22544 [(set_attr "type" "ssecmp")
22545 (set_attr "mode" "TI")])
22546
22547 (define_insn "eqv8hi3"
22548 [(set (match_operand:V8HI 0 "register_operand" "=x")
22549 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22550 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22551 "TARGET_SSE2"
22552 "pcmpeqw\t{%2, %0|%0, %2}"
22553 [(set_attr "type" "ssecmp")
22554 (set_attr "mode" "TI")])
22555
22556 (define_insn "eqv4si3"
22557 [(set (match_operand:V4SI 0 "register_operand" "=x")
22558 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22559 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22560 "TARGET_SSE2"
22561 "pcmpeqd\t{%2, %0|%0, %2}"
22562 [(set_attr "type" "ssecmp")
22563 (set_attr "mode" "TI")])
22564
22565 (define_insn "gtv16qi3"
22566 [(set (match_operand:V16QI 0 "register_operand" "=x")
22567 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22568 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22569 "TARGET_SSE2"
22570 "pcmpgtb\t{%2, %0|%0, %2}"
22571 [(set_attr "type" "ssecmp")
22572 (set_attr "mode" "TI")])
22573
22574 (define_insn "gtv8hi3"
22575 [(set (match_operand:V8HI 0 "register_operand" "=x")
22576 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22577 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22578 "TARGET_SSE2"
22579 "pcmpgtw\t{%2, %0|%0, %2}"
22580 [(set_attr "type" "ssecmp")
22581 (set_attr "mode" "TI")])
22582
22583 (define_insn "gtv4si3"
22584 [(set (match_operand:V4SI 0 "register_operand" "=x")
22585 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22586 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22587 "TARGET_SSE2"
22588 "pcmpgtd\t{%2, %0|%0, %2}"
22589 [(set_attr "type" "ssecmp")
22590 (set_attr "mode" "TI")])
22591
22592
22593 ;; MMX max/min insns
22594
22595 (define_insn "umaxv16qi3"
22596 [(set (match_operand:V16QI 0 "register_operand" "=x")
22597 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22598 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22599 "TARGET_SSE2"
22600 "pmaxub\t{%2, %0|%0, %2}"
22601 [(set_attr "type" "sseiadd")
22602 (set_attr "mode" "TI")])
22603
22604 (define_insn "smaxv8hi3"
22605 [(set (match_operand:V8HI 0 "register_operand" "=x")
22606 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22607 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22608 "TARGET_SSE2"
22609 "pmaxsw\t{%2, %0|%0, %2}"
22610 [(set_attr "type" "sseiadd")
22611 (set_attr "mode" "TI")])
22612
22613 (define_insn "uminv16qi3"
22614 [(set (match_operand:V16QI 0 "register_operand" "=x")
22615 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22616 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22617 "TARGET_SSE2"
22618 "pminub\t{%2, %0|%0, %2}"
22619 [(set_attr "type" "sseiadd")
22620 (set_attr "mode" "TI")])
22621
22622 (define_insn "sminv8hi3"
22623 [(set (match_operand:V8HI 0 "register_operand" "=x")
22624 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22625 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22626 "TARGET_SSE2"
22627 "pminsw\t{%2, %0|%0, %2}"
22628 [(set_attr "type" "sseiadd")
22629 (set_attr "mode" "TI")])
22630
22631
22632 ;; MMX shifts
22633
22634 (define_insn "ashrv8hi3"
22635 [(set (match_operand:V8HI 0 "register_operand" "=x")
22636 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22637 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22638 "TARGET_SSE2"
22639 "psraw\t{%2, %0|%0, %2}"
22640 [(set_attr "type" "sseishft")
22641 (set_attr "mode" "TI")])
22642
22643 (define_insn "ashrv4si3"
22644 [(set (match_operand:V4SI 0 "register_operand" "=x")
22645 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22646 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22647 "TARGET_SSE2"
22648 "psrad\t{%2, %0|%0, %2}"
22649 [(set_attr "type" "sseishft")
22650 (set_attr "mode" "TI")])
22651
22652 (define_insn "lshrv8hi3"
22653 [(set (match_operand:V8HI 0 "register_operand" "=x")
22654 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22655 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22656 "TARGET_SSE2"
22657 "psrlw\t{%2, %0|%0, %2}"
22658 [(set_attr "type" "sseishft")
22659 (set_attr "mode" "TI")])
22660
22661 (define_insn "lshrv4si3"
22662 [(set (match_operand:V4SI 0 "register_operand" "=x")
22663 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22664 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22665 "TARGET_SSE2"
22666 "psrld\t{%2, %0|%0, %2}"
22667 [(set_attr "type" "sseishft")
22668 (set_attr "mode" "TI")])
22669
22670 (define_insn "lshrv2di3"
22671 [(set (match_operand:V2DI 0 "register_operand" "=x")
22672 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22673 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22674 "TARGET_SSE2"
22675 "psrlq\t{%2, %0|%0, %2}"
22676 [(set_attr "type" "sseishft")
22677 (set_attr "mode" "TI")])
22678
22679 (define_insn "ashlv8hi3"
22680 [(set (match_operand:V8HI 0 "register_operand" "=x")
22681 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22682 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22683 "TARGET_SSE2"
22684 "psllw\t{%2, %0|%0, %2}"
22685 [(set_attr "type" "sseishft")
22686 (set_attr "mode" "TI")])
22687
22688 (define_insn "ashlv4si3"
22689 [(set (match_operand:V4SI 0 "register_operand" "=x")
22690 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22691 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22692 "TARGET_SSE2"
22693 "pslld\t{%2, %0|%0, %2}"
22694 [(set_attr "type" "sseishft")
22695 (set_attr "mode" "TI")])
22696
22697 (define_insn "ashlv2di3"
22698 [(set (match_operand:V2DI 0 "register_operand" "=x")
22699 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22700 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22701 "TARGET_SSE2"
22702 "psllq\t{%2, %0|%0, %2}"
22703 [(set_attr "type" "sseishft")
22704 (set_attr "mode" "TI")])
22705
22706 (define_insn "ashrv8hi3_ti"
22707 [(set (match_operand:V8HI 0 "register_operand" "=x")
22708 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22709 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22710 "TARGET_SSE2"
22711 "psraw\t{%2, %0|%0, %2}"
22712 [(set_attr "type" "sseishft")
22713 (set_attr "mode" "TI")])
22714
22715 (define_insn "ashrv4si3_ti"
22716 [(set (match_operand:V4SI 0 "register_operand" "=x")
22717 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22718 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22719 "TARGET_SSE2"
22720 "psrad\t{%2, %0|%0, %2}"
22721 [(set_attr "type" "sseishft")
22722 (set_attr "mode" "TI")])
22723
22724 (define_insn "lshrv8hi3_ti"
22725 [(set (match_operand:V8HI 0 "register_operand" "=x")
22726 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22727 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22728 "TARGET_SSE2"
22729 "psrlw\t{%2, %0|%0, %2}"
22730 [(set_attr "type" "sseishft")
22731 (set_attr "mode" "TI")])
22732
22733 (define_insn "lshrv4si3_ti"
22734 [(set (match_operand:V4SI 0 "register_operand" "=x")
22735 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22736 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22737 "TARGET_SSE2"
22738 "psrld\t{%2, %0|%0, %2}"
22739 [(set_attr "type" "sseishft")
22740 (set_attr "mode" "TI")])
22741
22742 (define_insn "lshrv2di3_ti"
22743 [(set (match_operand:V2DI 0 "register_operand" "=x")
22744 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22745 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22746 "TARGET_SSE2"
22747 "psrlq\t{%2, %0|%0, %2}"
22748 [(set_attr "type" "sseishft")
22749 (set_attr "mode" "TI")])
22750
22751 (define_insn "ashlv8hi3_ti"
22752 [(set (match_operand:V8HI 0 "register_operand" "=x")
22753 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22754 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22755 "TARGET_SSE2"
22756 "psllw\t{%2, %0|%0, %2}"
22757 [(set_attr "type" "sseishft")
22758 (set_attr "mode" "TI")])
22759
22760 (define_insn "ashlv4si3_ti"
22761 [(set (match_operand:V4SI 0 "register_operand" "=x")
22762 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22763 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22764 "TARGET_SSE2"
22765 "pslld\t{%2, %0|%0, %2}"
22766 [(set_attr "type" "sseishft")
22767 (set_attr "mode" "TI")])
22768
22769 (define_insn "ashlv2di3_ti"
22770 [(set (match_operand:V2DI 0 "register_operand" "=x")
22771 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22772 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22773 "TARGET_SSE2"
22774 "psllq\t{%2, %0|%0, %2}"
22775 [(set_attr "type" "sseishft")
22776 (set_attr "mode" "TI")])
22777
22778 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22779 ;; we wouldn't need here it since we never generate TImode arithmetic.
22780
22781 ;; There has to be some kind of prize for the weirdest new instruction...
22782 (define_insn "sse2_ashlti3"
22783 [(set (match_operand:TI 0 "register_operand" "=x")
22784 (unspec:TI
22785 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22786 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22787 (const_int 8)))] UNSPEC_NOP))]
22788 "TARGET_SSE2"
22789 "pslldq\t{%2, %0|%0, %2}"
22790 [(set_attr "type" "sseishft")
22791 (set_attr "mode" "TI")])
22792
22793 (define_insn "sse2_lshrti3"
22794 [(set (match_operand:TI 0 "register_operand" "=x")
22795 (unspec:TI
22796 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22797 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22798 (const_int 8)))] UNSPEC_NOP))]
22799 "TARGET_SSE2"
22800 "psrldq\t{%2, %0|%0, %2}"
22801 [(set_attr "type" "sseishft")
22802 (set_attr "mode" "TI")])
22803
22804 ;; SSE unpack
22805
22806 (define_insn "sse2_unpckhpd"
22807 [(set (match_operand:V2DF 0 "register_operand" "=x")
22808 (vec_concat:V2DF
22809 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22810 (parallel [(const_int 1)]))
22811 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22812 (parallel [(const_int 0)]))))]
22813 "TARGET_SSE2"
22814 "unpckhpd\t{%2, %0|%0, %2}"
22815 [(set_attr "type" "ssecvt")
22816 (set_attr "mode" "TI")])
22817
22818 (define_insn "sse2_unpcklpd"
22819 [(set (match_operand:V2DF 0 "register_operand" "=x")
22820 (vec_concat:V2DF
22821 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22822 (parallel [(const_int 0)]))
22823 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22824 (parallel [(const_int 1)]))))]
22825 "TARGET_SSE2"
22826 "unpcklpd\t{%2, %0|%0, %2}"
22827 [(set_attr "type" "ssecvt")
22828 (set_attr "mode" "TI")])
22829
22830 ;; MMX pack/unpack insns.
22831
22832 (define_insn "sse2_packsswb"
22833 [(set (match_operand:V16QI 0 "register_operand" "=x")
22834 (vec_concat:V16QI
22835 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22836 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22837 "TARGET_SSE2"
22838 "packsswb\t{%2, %0|%0, %2}"
22839 [(set_attr "type" "ssecvt")
22840 (set_attr "mode" "TI")])
22841
22842 (define_insn "sse2_packssdw"
22843 [(set (match_operand:V8HI 0 "register_operand" "=x")
22844 (vec_concat:V8HI
22845 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22846 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22847 "TARGET_SSE2"
22848 "packssdw\t{%2, %0|%0, %2}"
22849 [(set_attr "type" "ssecvt")
22850 (set_attr "mode" "TI")])
22851
22852 (define_insn "sse2_packuswb"
22853 [(set (match_operand:V16QI 0 "register_operand" "=x")
22854 (vec_concat:V16QI
22855 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22856 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22857 "TARGET_SSE2"
22858 "packuswb\t{%2, %0|%0, %2}"
22859 [(set_attr "type" "ssecvt")
22860 (set_attr "mode" "TI")])
22861
22862 (define_insn "sse2_punpckhbw"
22863 [(set (match_operand:V16QI 0 "register_operand" "=x")
22864 (vec_merge:V16QI
22865 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22866 (parallel [(const_int 8) (const_int 0)
22867 (const_int 9) (const_int 1)
22868 (const_int 10) (const_int 2)
22869 (const_int 11) (const_int 3)
22870 (const_int 12) (const_int 4)
22871 (const_int 13) (const_int 5)
22872 (const_int 14) (const_int 6)
22873 (const_int 15) (const_int 7)]))
22874 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22875 (parallel [(const_int 0) (const_int 8)
22876 (const_int 1) (const_int 9)
22877 (const_int 2) (const_int 10)
22878 (const_int 3) (const_int 11)
22879 (const_int 4) (const_int 12)
22880 (const_int 5) (const_int 13)
22881 (const_int 6) (const_int 14)
22882 (const_int 7) (const_int 15)]))
22883 (const_int 21845)))]
22884 "TARGET_SSE2"
22885 "punpckhbw\t{%2, %0|%0, %2}"
22886 [(set_attr "type" "ssecvt")
22887 (set_attr "mode" "TI")])
22888
22889 (define_insn "sse2_punpckhwd"
22890 [(set (match_operand:V8HI 0 "register_operand" "=x")
22891 (vec_merge:V8HI
22892 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22893 (parallel [(const_int 4) (const_int 0)
22894 (const_int 5) (const_int 1)
22895 (const_int 6) (const_int 2)
22896 (const_int 7) (const_int 3)]))
22897 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22898 (parallel [(const_int 0) (const_int 4)
22899 (const_int 1) (const_int 5)
22900 (const_int 2) (const_int 6)
22901 (const_int 3) (const_int 7)]))
22902 (const_int 85)))]
22903 "TARGET_SSE2"
22904 "punpckhwd\t{%2, %0|%0, %2}"
22905 [(set_attr "type" "ssecvt")
22906 (set_attr "mode" "TI")])
22907
22908 (define_insn "sse2_punpckhdq"
22909 [(set (match_operand:V4SI 0 "register_operand" "=x")
22910 (vec_merge:V4SI
22911 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22912 (parallel [(const_int 2) (const_int 0)
22913 (const_int 3) (const_int 1)]))
22914 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22915 (parallel [(const_int 0) (const_int 2)
22916 (const_int 1) (const_int 3)]))
22917 (const_int 5)))]
22918 "TARGET_SSE2"
22919 "punpckhdq\t{%2, %0|%0, %2}"
22920 [(set_attr "type" "ssecvt")
22921 (set_attr "mode" "TI")])
22922
22923 (define_insn "sse2_punpcklbw"
22924 [(set (match_operand:V16QI 0 "register_operand" "=x")
22925 (vec_merge:V16QI
22926 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22927 (parallel [(const_int 0) (const_int 8)
22928 (const_int 1) (const_int 9)
22929 (const_int 2) (const_int 10)
22930 (const_int 3) (const_int 11)
22931 (const_int 4) (const_int 12)
22932 (const_int 5) (const_int 13)
22933 (const_int 6) (const_int 14)
22934 (const_int 7) (const_int 15)]))
22935 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22936 (parallel [(const_int 8) (const_int 0)
22937 (const_int 9) (const_int 1)
22938 (const_int 10) (const_int 2)
22939 (const_int 11) (const_int 3)
22940 (const_int 12) (const_int 4)
22941 (const_int 13) (const_int 5)
22942 (const_int 14) (const_int 6)
22943 (const_int 15) (const_int 7)]))
22944 (const_int 21845)))]
22945 "TARGET_SSE2"
22946 "punpcklbw\t{%2, %0|%0, %2}"
22947 [(set_attr "type" "ssecvt")
22948 (set_attr "mode" "TI")])
22949
22950 (define_insn "sse2_punpcklwd"
22951 [(set (match_operand:V8HI 0 "register_operand" "=x")
22952 (vec_merge:V8HI
22953 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22954 (parallel [(const_int 0) (const_int 4)
22955 (const_int 1) (const_int 5)
22956 (const_int 2) (const_int 6)
22957 (const_int 3) (const_int 7)]))
22958 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22959 (parallel [(const_int 4) (const_int 0)
22960 (const_int 5) (const_int 1)
22961 (const_int 6) (const_int 2)
22962 (const_int 7) (const_int 3)]))
22963 (const_int 85)))]
22964 "TARGET_SSE2"
22965 "punpcklwd\t{%2, %0|%0, %2}"
22966 [(set_attr "type" "ssecvt")
22967 (set_attr "mode" "TI")])
22968
22969 (define_insn "sse2_punpckldq"
22970 [(set (match_operand:V4SI 0 "register_operand" "=x")
22971 (vec_merge:V4SI
22972 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22973 (parallel [(const_int 0) (const_int 2)
22974 (const_int 1) (const_int 3)]))
22975 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22976 (parallel [(const_int 2) (const_int 0)
22977 (const_int 3) (const_int 1)]))
22978 (const_int 5)))]
22979 "TARGET_SSE2"
22980 "punpckldq\t{%2, %0|%0, %2}"
22981 [(set_attr "type" "ssecvt")
22982 (set_attr "mode" "TI")])
22983
22984 (define_insn "sse2_punpcklqdq"
22985 [(set (match_operand:V2DI 0 "register_operand" "=x")
22986 (vec_merge:V2DI
22987 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22988 (parallel [(const_int 1)
22989 (const_int 0)]))
22990 (match_operand:V2DI 1 "register_operand" "0")
22991 (const_int 1)))]
22992 "TARGET_SSE2"
22993 "punpcklqdq\t{%2, %0|%0, %2}"
22994 [(set_attr "type" "ssecvt")
22995 (set_attr "mode" "TI")])
22996
22997 (define_insn "sse2_punpckhqdq"
22998 [(set (match_operand:V2DI 0 "register_operand" "=x")
22999 (vec_merge:V2DI
23000 (match_operand:V2DI 1 "register_operand" "0")
23001 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23002 (parallel [(const_int 1)
23003 (const_int 0)]))
23004 (const_int 1)))]
23005 "TARGET_SSE2"
23006 "punpckhqdq\t{%2, %0|%0, %2}"
23007 [(set_attr "type" "ssecvt")
23008 (set_attr "mode" "TI")])
23009
23010 ;; SSE2 moves
23011
23012 (define_insn "sse2_movapd"
23013 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23014 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23015 UNSPEC_MOVA))]
23016 "TARGET_SSE2
23017 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23018 "movapd\t{%1, %0|%0, %1}"
23019 [(set_attr "type" "ssemov")
23020 (set_attr "mode" "V2DF")])
23021
23022 (define_insn "sse2_movupd"
23023 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23024 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23025 UNSPEC_MOVU))]
23026 "TARGET_SSE2
23027 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23028 "movupd\t{%1, %0|%0, %1}"
23029 [(set_attr "type" "ssecvt")
23030 (set_attr "mode" "V2DF")])
23031
23032 (define_insn "sse2_movdqa"
23033 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23034 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23035 UNSPEC_MOVA))]
23036 "TARGET_SSE2
23037 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23038 "movdqa\t{%1, %0|%0, %1}"
23039 [(set_attr "type" "ssemov")
23040 (set_attr "mode" "TI")])
23041
23042 (define_insn "sse2_movdqu"
23043 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23044 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23045 UNSPEC_MOVU))]
23046 "TARGET_SSE2
23047 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23048 "movdqu\t{%1, %0|%0, %1}"
23049 [(set_attr "type" "ssecvt")
23050 (set_attr "mode" "TI")])
23051
23052 (define_insn "sse2_movdq2q"
23053 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23054 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23055 (parallel [(const_int 0)])))]
23056 "TARGET_SSE2 && !TARGET_64BIT"
23057 "@
23058 movq\t{%1, %0|%0, %1}
23059 movdq2q\t{%1, %0|%0, %1}"
23060 [(set_attr "type" "ssecvt")
23061 (set_attr "mode" "TI")])
23062
23063 (define_insn "sse2_movdq2q_rex64"
23064 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23065 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23066 (parallel [(const_int 0)])))]
23067 "TARGET_SSE2 && TARGET_64BIT"
23068 "@
23069 movq\t{%1, %0|%0, %1}
23070 movdq2q\t{%1, %0|%0, %1}
23071 movd\t{%1, %0|%0, %1}"
23072 [(set_attr "type" "ssecvt")
23073 (set_attr "mode" "TI")])
23074
23075 (define_insn "sse2_movq2dq"
23076 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23077 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23078 (const_int 0)))]
23079 "TARGET_SSE2 && !TARGET_64BIT"
23080 "@
23081 movq\t{%1, %0|%0, %1}
23082 movq2dq\t{%1, %0|%0, %1}"
23083 [(set_attr "type" "ssecvt,ssemov")
23084 (set_attr "mode" "TI")])
23085
23086 (define_insn "sse2_movq2dq_rex64"
23087 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23088 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23089 (const_int 0)))]
23090 "TARGET_SSE2 && TARGET_64BIT"
23091 "@
23092 movq\t{%1, %0|%0, %1}
23093 movq2dq\t{%1, %0|%0, %1}
23094 movd\t{%1, %0|%0, %1}"
23095 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23096 (set_attr "mode" "TI")])
23097
23098 (define_insn "sse2_movq"
23099 [(set (match_operand:V2DI 0 "register_operand" "=x")
23100 (vec_concat:V2DI (vec_select:DI
23101 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23102 (parallel [(const_int 0)]))
23103 (const_int 0)))]
23104 "TARGET_SSE2"
23105 "movq\t{%1, %0|%0, %1}"
23106 [(set_attr "type" "ssemov")
23107 (set_attr "mode" "TI")])
23108
23109 (define_insn "sse2_loadd"
23110 [(set (match_operand:V4SI 0 "register_operand" "=x")
23111 (vec_merge:V4SI
23112 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23113 (const_vector:V4SI [(const_int 0)
23114 (const_int 0)
23115 (const_int 0)
23116 (const_int 0)])
23117 (const_int 1)))]
23118 "TARGET_SSE2"
23119 "movd\t{%1, %0|%0, %1}"
23120 [(set_attr "type" "ssemov")
23121 (set_attr "mode" "TI")])
23122
23123 (define_insn "sse2_stored"
23124 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23125 (vec_select:SI
23126 (match_operand:V4SI 1 "register_operand" "x")
23127 (parallel [(const_int 0)])))]
23128 "TARGET_SSE2"
23129 "movd\t{%1, %0|%0, %1}"
23130 [(set_attr "type" "ssemov")
23131 (set_attr "mode" "TI")])
23132
23133 (define_insn "sse2_movhpd"
23134 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23135 (vec_merge:V2DF
23136 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23137 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23138 (const_int 2)))]
23139 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23140 "movhpd\t{%2, %0|%0, %2}"
23141 [(set_attr "type" "ssecvt")
23142 (set_attr "mode" "V2DF")])
23143
23144 (define_insn "sse2_movlpd"
23145 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23146 (vec_merge:V2DF
23147 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23148 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23149 (const_int 1)))]
23150 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23151 "movlpd\t{%2, %0|%0, %2}"
23152 [(set_attr "type" "ssecvt")
23153 (set_attr "mode" "V2DF")])
23154
23155 (define_expand "sse2_loadsd"
23156 [(match_operand:V2DF 0 "register_operand" "")
23157 (match_operand:DF 1 "memory_operand" "")]
23158 "TARGET_SSE2"
23159 {
23160 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23161 CONST0_RTX (V2DFmode)));
23162 DONE;
23163 })
23164
23165 (define_insn "sse2_loadsd_1"
23166 [(set (match_operand:V2DF 0 "register_operand" "=x")
23167 (vec_merge:V2DF
23168 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23169 (match_operand:V2DF 2 "const0_operand" "X")
23170 (const_int 1)))]
23171 "TARGET_SSE2"
23172 "movsd\t{%1, %0|%0, %1}"
23173 [(set_attr "type" "ssecvt")
23174 (set_attr "mode" "DF")])
23175
23176 (define_insn "sse2_movsd"
23177 [(set (match_operand:V2DF 0 "register_operand" "=x")
23178 (vec_merge:V2DF
23179 (match_operand:V2DF 1 "register_operand" "0")
23180 (match_operand:V2DF 2 "register_operand" "x")
23181 (const_int 1)))]
23182 "TARGET_SSE2"
23183 "movsd\t{%2, %0|%0, %2}"
23184 [(set_attr "type" "ssecvt")
23185 (set_attr "mode" "DF")])
23186
23187 (define_insn "sse2_storesd"
23188 [(set (match_operand:DF 0 "memory_operand" "=m")
23189 (vec_select:DF
23190 (match_operand:V2DF 1 "register_operand" "x")
23191 (parallel [(const_int 0)])))]
23192 "TARGET_SSE2"
23193 "movsd\t{%1, %0|%0, %1}"
23194 [(set_attr "type" "ssecvt")
23195 (set_attr "mode" "DF")])
23196
23197 (define_insn "sse2_shufpd"
23198 [(set (match_operand:V2DF 0 "register_operand" "=x")
23199 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23200 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23201 (match_operand:SI 3 "immediate_operand" "i")]
23202 UNSPEC_SHUFFLE))]
23203 "TARGET_SSE2"
23204 ;; @@@ check operand order for intel/nonintel syntax
23205 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23206 [(set_attr "type" "ssecvt")
23207 (set_attr "mode" "V2DF")])
23208
23209 (define_insn "sse2_clflush"
23210 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23211 UNSPECV_CLFLUSH)]
23212 "TARGET_SSE2"
23213 "clflush %0"
23214 [(set_attr "type" "sse")
23215 (set_attr "memory" "unknown")])
23216
23217 (define_expand "sse2_mfence"
23218 [(set (match_dup 0)
23219 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23220 "TARGET_SSE2"
23221 {
23222 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23223 MEM_VOLATILE_P (operands[0]) = 1;
23224 })
23225
23226 (define_insn "*mfence_insn"
23227 [(set (match_operand:BLK 0 "" "")
23228 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23229 "TARGET_SSE2"
23230 "mfence"
23231 [(set_attr "type" "sse")
23232 (set_attr "memory" "unknown")])
23233
23234 (define_expand "sse2_lfence"
23235 [(set (match_dup 0)
23236 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23237 "TARGET_SSE2"
23238 {
23239 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23240 MEM_VOLATILE_P (operands[0]) = 1;
23241 })
23242
23243 (define_insn "*lfence_insn"
23244 [(set (match_operand:BLK 0 "" "")
23245 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23246 "TARGET_SSE2"
23247 "lfence"
23248 [(set_attr "type" "sse")
23249 (set_attr "memory" "unknown")])