]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
Merge basic-improvements-branch to trunk
[thirdparty/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, 2001, 2002
3 ;; Free Software Foundation, Inc.
4 ;; Mostly by William Schelter.
5 ;; x86_64 support added by Jan Hubicka
6 ;;
7 ;; This file is part of GNU CC.
8 ;;
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13 ;;
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18 ;;
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
30 ;; updates for most instructions.
31 ;;
32 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
33 ;; constraint letters.
34 ;;
35 ;; The special asm out single letter directives following a '%' are:
36 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
37 ;; operands[1].
38 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
39 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
40 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
41 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
42 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
43 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
44 ;; 'J' Print the appropriate jump operand.
45 ;;
46 ;; 'b' Print the QImode name of the register for the indicated operand.
47 ;; %b0 would print %al if operands[0] is reg 0.
48 ;; 'w' Likewise, print the HImode name of the register.
49 ;; 'k' Likewise, print the SImode name of the register.
50 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; 'y' Print "st(0)" instead of "st" as a register.
52
53 ;; UNSPEC usage:
54
55 (define_constants
56 [; Relocation specifiers
57 (UNSPEC_GOT 0)
58 (UNSPEC_GOTOFF 1)
59 (UNSPEC_GOTPCREL 2)
60 (UNSPEC_GOTTPOFF 3)
61 (UNSPEC_TPOFF 4)
62 (UNSPEC_NTPOFF 5)
63 (UNSPEC_DTPOFF 6)
64 (UNSPEC_GOTNTPOFF 7)
65 (UNSPEC_INDNTPOFF 8)
66
67 ; Prologue support
68 (UNSPEC_STACK_PROBE 10)
69 (UNSPEC_STACK_ALLOC 11)
70 (UNSPEC_SET_GOT 12)
71 (UNSPEC_SSE_PROLOGUE_SAVE 13)
72
73 ; TLS support
74 (UNSPEC_TP 15)
75 (UNSPEC_TLS_GD 16)
76 (UNSPEC_TLS_LD_BASE 17)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 20)
80 (UNSPEC_SIN 21)
81 (UNSPEC_COS 22)
82 (UNSPEC_BSF 23)
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
114 (define_constants
115 [(UNSPECV_BLOCKAGE 0)
116 (UNSPECV_EH_RETURN 13)
117 (UNSPECV_EMMS 31)
118 (UNSPECV_LDMXCSR 37)
119 (UNSPECV_STMXCSR 40)
120 (UNSPECV_FEMMS 46)
121 (UNSPECV_CLFLUSH 57)
122 ])
123
124 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
125 ;; from i386.c.
126
127 ;; In C guard expressions, put expressions which may be compile-time
128 ;; constants first. This allows for better optimization. For
129 ;; example, write "TARGET_64BIT && reload_completed", not
130 ;; "reload_completed && TARGET_64BIT".
131
132 \f
133 ;; Processor type. This attribute must exactly match the processor_type
134 ;; enumeration in i386.h.
135 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
136 (const (symbol_ref "ix86_cpu")))
137
138 ;; A basic instruction type. Refinements due to arguments to be
139 ;; provided in other attributes.
140 (define_attr "type"
141 "other,multi,
142 alu,alu1,negnot,imov,imovx,lea,
143 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
144 icmp,test,ibr,setcc,icmov,
145 push,pop,call,callv,leave,
146 str,cld,
147 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
148 sselog,sseiadd,sseishft,sseimul,
149 sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
150 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
151 (const_string "other"))
152
153 ;; Main data type used by the insn
154 (define_attr "mode"
155 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
156 (const_string "unknown"))
157
158 ;; The CPU unit operations uses.
159 (define_attr "unit" "integer,i387,sse,mmx,unknown"
160 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
161 (const_string "i387")
162 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
163 sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv")
164 (const_string "sse")
165 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
166 (const_string "mmx")
167 (eq_attr "type" "other")
168 (const_string "unknown")]
169 (const_string "integer")))
170
171 ;; The (bounding maximum) length of an instruction immediate.
172 (define_attr "length_immediate" ""
173 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
174 (const_int 0)
175 (eq_attr "unit" "i387,sse,mmx")
176 (const_int 0)
177 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
178 imul,icmp,push,pop")
179 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
180 (eq_attr "type" "imov,test")
181 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
182 (eq_attr "type" "call")
183 (if_then_else (match_operand 0 "constant_call_address_operand" "")
184 (const_int 4)
185 (const_int 0))
186 (eq_attr "type" "callv")
187 (if_then_else (match_operand 1 "constant_call_address_operand" "")
188 (const_int 4)
189 (const_int 0))
190 ;; We don't know the size before shorten_branches. Expect
191 ;; the instruction to fit for better scheduling.
192 (eq_attr "type" "ibr")
193 (const_int 1)
194 ]
195 (symbol_ref "/* Update immediate_length and other attributes! */
196 abort(),1")))
197
198 ;; The (bounding maximum) length of an instruction address.
199 (define_attr "length_address" ""
200 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
201 (const_int 0)
202 (and (eq_attr "type" "call")
203 (match_operand 0 "constant_call_address_operand" ""))
204 (const_int 0)
205 (and (eq_attr "type" "callv")
206 (match_operand 1 "constant_call_address_operand" ""))
207 (const_int 0)
208 ]
209 (symbol_ref "ix86_attr_length_address_default (insn)")))
210
211 ;; Set when length prefix is used.
212 (define_attr "prefix_data16" ""
213 (if_then_else (ior (eq_attr "mode" "HI")
214 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
215 (const_int 1)
216 (const_int 0)))
217
218 ;; Set when string REP prefix is used.
219 (define_attr "prefix_rep" ""
220 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
221 (const_int 1)
222 (const_int 0)))
223
224 ;; Set when 0f opcode prefix is used.
225 (define_attr "prefix_0f" ""
226 (if_then_else
227 (eq_attr "type"
228 "imovx,setcc,icmov,
229 sselog,sseiadd,sseishft,sseimul,
230 sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
231 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
232 (const_int 1)
233 (const_int 0)))
234
235 ;; Set when 0f opcode prefix is used.
236 (define_attr "prefix_rex" ""
237 (cond [(and (eq_attr "mode" "DI")
238 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
239 (const_int 1)
240 (and (eq_attr "mode" "QI")
241 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
242 (const_int 0)))
243 (const_int 1)
244 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
245 (const_int 0))
246 (const_int 1)
247 ]
248 (const_int 0)))
249
250 ;; Set when modrm byte is used.
251 (define_attr "modrm" ""
252 (cond [(eq_attr "type" "str,cld,leave")
253 (const_int 0)
254 (eq_attr "unit" "i387")
255 (const_int 0)
256 (and (eq_attr "type" "incdec")
257 (ior (match_operand:SI 1 "register_operand" "")
258 (match_operand:HI 1 "register_operand" "")))
259 (const_int 0)
260 (and (eq_attr "type" "push")
261 (not (match_operand 1 "memory_operand" "")))
262 (const_int 0)
263 (and (eq_attr "type" "pop")
264 (not (match_operand 0 "memory_operand" "")))
265 (const_int 0)
266 (and (eq_attr "type" "imov")
267 (and (match_operand 0 "register_operand" "")
268 (match_operand 1 "immediate_operand" "")))
269 (const_int 0)
270 (and (eq_attr "type" "call")
271 (match_operand 0 "constant_call_address_operand" ""))
272 (const_int 0)
273 (and (eq_attr "type" "callv")
274 (match_operand 1 "constant_call_address_operand" ""))
275 (const_int 0)
276 ]
277 (const_int 1)))
278
279 ;; The (bounding maximum) length of an instruction in bytes.
280 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
281 ;; to split it and compute proper length as for other insns.
282 (define_attr "length" ""
283 (cond [(eq_attr "type" "other,multi,fistp")
284 (const_int 16)
285 (eq_attr "unit" "i387")
286 (plus (const_int 2)
287 (plus (attr "prefix_data16")
288 (attr "length_address")))]
289 (plus (plus (attr "modrm")
290 (plus (attr "prefix_0f")
291 (plus (attr "prefix_rex")
292 (const_int 1))))
293 (plus (attr "prefix_rep")
294 (plus (attr "prefix_data16")
295 (plus (attr "length_immediate")
296 (attr "length_address")))))))
297
298 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
299 ;; `store' if there is a simple memory reference therein, or `unknown'
300 ;; if the instruction is complex.
301
302 (define_attr "memory" "none,load,store,both,unknown"
303 (cond [(eq_attr "type" "other,multi,str")
304 (const_string "unknown")
305 (eq_attr "type" "lea,fcmov,fpspc,cld")
306 (const_string "none")
307 (eq_attr "type" "fistp,leave")
308 (const_string "both")
309 (eq_attr "type" "push")
310 (if_then_else (match_operand 1 "memory_operand" "")
311 (const_string "both")
312 (const_string "store"))
313 (eq_attr "type" "pop,setcc")
314 (if_then_else (match_operand 0 "memory_operand" "")
315 (const_string "both")
316 (const_string "load"))
317 (eq_attr "type" "icmp,test,ssecmp,mmxcmp,fcmp")
318 (if_then_else (ior (match_operand 0 "memory_operand" "")
319 (match_operand 1 "memory_operand" ""))
320 (const_string "load")
321 (const_string "none"))
322 (eq_attr "type" "ibr")
323 (if_then_else (match_operand 0 "memory_operand" "")
324 (const_string "load")
325 (const_string "none"))
326 (eq_attr "type" "call")
327 (if_then_else (match_operand 0 "constant_call_address_operand" "")
328 (const_string "none")
329 (const_string "load"))
330 (eq_attr "type" "callv")
331 (if_then_else (match_operand 1 "constant_call_address_operand" "")
332 (const_string "none")
333 (const_string "load"))
334 (and (eq_attr "type" "alu1,negnot")
335 (match_operand 1 "memory_operand" ""))
336 (const_string "both")
337 (and (match_operand 0 "memory_operand" "")
338 (match_operand 1 "memory_operand" ""))
339 (const_string "both")
340 (match_operand 0 "memory_operand" "")
341 (const_string "store")
342 (match_operand 1 "memory_operand" "")
343 (const_string "load")
344 (and (eq_attr "type"
345 "!alu1,negnot,
346 imov,imovx,icmp,test,
347 fmov,fcmp,fsgn,
348 sse,ssemov,ssecmp,ssecvt,
349 mmx,mmxmov,mmxcmp,mmxcvt")
350 (match_operand 2 "memory_operand" ""))
351 (const_string "load")
352 (and (eq_attr "type" "icmov")
353 (match_operand 3 "memory_operand" ""))
354 (const_string "load")
355 ]
356 (const_string "none")))
357
358 ;; Indicates if an instruction has both an immediate and a displacement.
359
360 (define_attr "imm_disp" "false,true,unknown"
361 (cond [(eq_attr "type" "other,multi")
362 (const_string "unknown")
363 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
364 (and (match_operand 0 "memory_displacement_operand" "")
365 (match_operand 1 "immediate_operand" "")))
366 (const_string "true")
367 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
368 (and (match_operand 0 "memory_displacement_operand" "")
369 (match_operand 2 "immediate_operand" "")))
370 (const_string "true")
371 ]
372 (const_string "false")))
373
374 ;; Indicates if an FP operation has an integer source.
375
376 (define_attr "fp_int_src" "false,true"
377 (const_string "false"))
378
379 ;; Describe a user's asm statement.
380 (define_asm_attributes
381 [(set_attr "length" "128")
382 (set_attr "type" "multi")])
383 \f
384 (include "pentium.md")
385 (include "ppro.md")
386 (include "k6.md")
387 (include "athlon.md")
388 \f
389 ;; Compare instructions.
390
391 ;; All compare insns have expanders that save the operands away without
392 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
393 ;; after the cmp) will actually emit the cmpM.
394
395 (define_expand "cmpdi"
396 [(set (reg:CC 17)
397 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
398 (match_operand:DI 1 "x86_64_general_operand" "")))]
399 ""
400 {
401 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
402 operands[0] = force_reg (DImode, operands[0]);
403 ix86_compare_op0 = operands[0];
404 ix86_compare_op1 = operands[1];
405 DONE;
406 })
407
408 (define_expand "cmpsi"
409 [(set (reg:CC 17)
410 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
411 (match_operand:SI 1 "general_operand" "")))]
412 ""
413 {
414 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
415 operands[0] = force_reg (SImode, operands[0]);
416 ix86_compare_op0 = operands[0];
417 ix86_compare_op1 = operands[1];
418 DONE;
419 })
420
421 (define_expand "cmphi"
422 [(set (reg:CC 17)
423 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
424 (match_operand:HI 1 "general_operand" "")))]
425 ""
426 {
427 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
428 operands[0] = force_reg (HImode, operands[0]);
429 ix86_compare_op0 = operands[0];
430 ix86_compare_op1 = operands[1];
431 DONE;
432 })
433
434 (define_expand "cmpqi"
435 [(set (reg:CC 17)
436 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
437 (match_operand:QI 1 "general_operand" "")))]
438 "TARGET_QIMODE_MATH"
439 {
440 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
441 operands[0] = force_reg (QImode, operands[0]);
442 ix86_compare_op0 = operands[0];
443 ix86_compare_op1 = operands[1];
444 DONE;
445 })
446
447 (define_insn "cmpdi_ccno_1_rex64"
448 [(set (reg 17)
449 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
450 (match_operand:DI 1 "const0_operand" "n,n")))]
451 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
452 "@
453 test{q}\t{%0, %0|%0, %0}
454 cmp{q}\t{%1, %0|%0, %1}"
455 [(set_attr "type" "test,icmp")
456 (set_attr "length_immediate" "0,1")
457 (set_attr "mode" "DI")])
458
459 (define_insn "*cmpdi_minus_1_rex64"
460 [(set (reg 17)
461 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
462 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
463 (const_int 0)))]
464 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
465 "cmp{q}\t{%1, %0|%0, %1}"
466 [(set_attr "type" "icmp")
467 (set_attr "mode" "DI")])
468
469 (define_expand "cmpdi_1_rex64"
470 [(set (reg:CC 17)
471 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
472 (match_operand:DI 1 "general_operand" "")))]
473 "TARGET_64BIT"
474 "")
475
476 (define_insn "cmpdi_1_insn_rex64"
477 [(set (reg 17)
478 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
479 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
480 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
481 "cmp{q}\t{%1, %0|%0, %1}"
482 [(set_attr "type" "icmp")
483 (set_attr "mode" "DI")])
484
485
486 (define_insn "*cmpsi_ccno_1"
487 [(set (reg 17)
488 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
489 (match_operand:SI 1 "const0_operand" "n,n")))]
490 "ix86_match_ccmode (insn, CCNOmode)"
491 "@
492 test{l}\t{%0, %0|%0, %0}
493 cmp{l}\t{%1, %0|%0, %1}"
494 [(set_attr "type" "test,icmp")
495 (set_attr "length_immediate" "0,1")
496 (set_attr "mode" "SI")])
497
498 (define_insn "*cmpsi_minus_1"
499 [(set (reg 17)
500 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
501 (match_operand:SI 1 "general_operand" "ri,mr"))
502 (const_int 0)))]
503 "ix86_match_ccmode (insn, CCGOCmode)"
504 "cmp{l}\t{%1, %0|%0, %1}"
505 [(set_attr "type" "icmp")
506 (set_attr "mode" "SI")])
507
508 (define_expand "cmpsi_1"
509 [(set (reg:CC 17)
510 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
511 (match_operand:SI 1 "general_operand" "ri,mr")))]
512 ""
513 "")
514
515 (define_insn "*cmpsi_1_insn"
516 [(set (reg 17)
517 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
518 (match_operand:SI 1 "general_operand" "ri,mr")))]
519 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
520 && ix86_match_ccmode (insn, CCmode)"
521 "cmp{l}\t{%1, %0|%0, %1}"
522 [(set_attr "type" "icmp")
523 (set_attr "mode" "SI")])
524
525 (define_insn "*cmphi_ccno_1"
526 [(set (reg 17)
527 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
528 (match_operand:HI 1 "const0_operand" "n,n")))]
529 "ix86_match_ccmode (insn, CCNOmode)"
530 "@
531 test{w}\t{%0, %0|%0, %0}
532 cmp{w}\t{%1, %0|%0, %1}"
533 [(set_attr "type" "test,icmp")
534 (set_attr "length_immediate" "0,1")
535 (set_attr "mode" "HI")])
536
537 (define_insn "*cmphi_minus_1"
538 [(set (reg 17)
539 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
540 (match_operand:HI 1 "general_operand" "ri,mr"))
541 (const_int 0)))]
542 "ix86_match_ccmode (insn, CCGOCmode)"
543 "cmp{w}\t{%1, %0|%0, %1}"
544 [(set_attr "type" "icmp")
545 (set_attr "mode" "HI")])
546
547 (define_insn "*cmphi_1"
548 [(set (reg 17)
549 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
550 (match_operand:HI 1 "general_operand" "ri,mr")))]
551 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
552 && ix86_match_ccmode (insn, CCmode)"
553 "cmp{w}\t{%1, %0|%0, %1}"
554 [(set_attr "type" "icmp")
555 (set_attr "mode" "HI")])
556
557 (define_insn "*cmpqi_ccno_1"
558 [(set (reg 17)
559 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
560 (match_operand:QI 1 "const0_operand" "n,n")))]
561 "ix86_match_ccmode (insn, CCNOmode)"
562 "@
563 test{b}\t{%0, %0|%0, %0}
564 cmp{b}\t{$0, %0|%0, 0}"
565 [(set_attr "type" "test,icmp")
566 (set_attr "length_immediate" "0,1")
567 (set_attr "mode" "QI")])
568
569 (define_insn "*cmpqi_1"
570 [(set (reg 17)
571 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
572 (match_operand:QI 1 "general_operand" "qi,mq")))]
573 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
574 && ix86_match_ccmode (insn, CCmode)"
575 "cmp{b}\t{%1, %0|%0, %1}"
576 [(set_attr "type" "icmp")
577 (set_attr "mode" "QI")])
578
579 (define_insn "*cmpqi_minus_1"
580 [(set (reg 17)
581 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
582 (match_operand:QI 1 "general_operand" "qi,mq"))
583 (const_int 0)))]
584 "ix86_match_ccmode (insn, CCGOCmode)"
585 "cmp{b}\t{%1, %0|%0, %1}"
586 [(set_attr "type" "icmp")
587 (set_attr "mode" "QI")])
588
589 (define_insn "*cmpqi_ext_1"
590 [(set (reg 17)
591 (compare
592 (match_operand:QI 0 "general_operand" "Qm")
593 (subreg:QI
594 (zero_extract:SI
595 (match_operand 1 "ext_register_operand" "Q")
596 (const_int 8)
597 (const_int 8)) 0)))]
598 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
599 "cmp{b}\t{%h1, %0|%0, %h1}"
600 [(set_attr "type" "icmp")
601 (set_attr "mode" "QI")])
602
603 (define_insn "*cmpqi_ext_1_rex64"
604 [(set (reg 17)
605 (compare
606 (match_operand:QI 0 "register_operand" "Q")
607 (subreg:QI
608 (zero_extract:SI
609 (match_operand 1 "ext_register_operand" "Q")
610 (const_int 8)
611 (const_int 8)) 0)))]
612 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
613 "cmp{b}\t{%h1, %0|%0, %h1}"
614 [(set_attr "type" "icmp")
615 (set_attr "mode" "QI")])
616
617 (define_insn "*cmpqi_ext_2"
618 [(set (reg 17)
619 (compare
620 (subreg:QI
621 (zero_extract:SI
622 (match_operand 0 "ext_register_operand" "Q")
623 (const_int 8)
624 (const_int 8)) 0)
625 (match_operand:QI 1 "const0_operand" "n")))]
626 "ix86_match_ccmode (insn, CCNOmode)"
627 "test{b}\t%h0, %h0"
628 [(set_attr "type" "test")
629 (set_attr "length_immediate" "0")
630 (set_attr "mode" "QI")])
631
632 (define_expand "cmpqi_ext_3"
633 [(set (reg:CC 17)
634 (compare:CC
635 (subreg:QI
636 (zero_extract:SI
637 (match_operand 0 "ext_register_operand" "")
638 (const_int 8)
639 (const_int 8)) 0)
640 (match_operand:QI 1 "general_operand" "")))]
641 ""
642 "")
643
644 (define_insn "cmpqi_ext_3_insn"
645 [(set (reg 17)
646 (compare
647 (subreg:QI
648 (zero_extract:SI
649 (match_operand 0 "ext_register_operand" "Q")
650 (const_int 8)
651 (const_int 8)) 0)
652 (match_operand:QI 1 "general_operand" "Qmn")))]
653 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
654 "cmp{b}\t{%1, %h0|%h0, %1}"
655 [(set_attr "type" "icmp")
656 (set_attr "mode" "QI")])
657
658 (define_insn "cmpqi_ext_3_insn_rex64"
659 [(set (reg 17)
660 (compare
661 (subreg:QI
662 (zero_extract:SI
663 (match_operand 0 "ext_register_operand" "Q")
664 (const_int 8)
665 (const_int 8)) 0)
666 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
667 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
668 "cmp{b}\t{%1, %h0|%h0, %1}"
669 [(set_attr "type" "icmp")
670 (set_attr "mode" "QI")])
671
672 (define_insn "*cmpqi_ext_4"
673 [(set (reg 17)
674 (compare
675 (subreg:QI
676 (zero_extract:SI
677 (match_operand 0 "ext_register_operand" "Q")
678 (const_int 8)
679 (const_int 8)) 0)
680 (subreg:QI
681 (zero_extract:SI
682 (match_operand 1 "ext_register_operand" "Q")
683 (const_int 8)
684 (const_int 8)) 0)))]
685 "ix86_match_ccmode (insn, CCmode)"
686 "cmp{b}\t{%h1, %h0|%h0, %h1}"
687 [(set_attr "type" "icmp")
688 (set_attr "mode" "QI")])
689
690 ;; These implement float point compares.
691 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
692 ;; which would allow mix and match FP modes on the compares. Which is what
693 ;; the old patterns did, but with many more of them.
694
695 (define_expand "cmpxf"
696 [(set (reg:CC 17)
697 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
698 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
699 "!TARGET_64BIT && TARGET_80387"
700 {
701 ix86_compare_op0 = operands[0];
702 ix86_compare_op1 = operands[1];
703 DONE;
704 })
705
706 (define_expand "cmptf"
707 [(set (reg:CC 17)
708 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
709 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
710 "TARGET_80387"
711 {
712 ix86_compare_op0 = operands[0];
713 ix86_compare_op1 = operands[1];
714 DONE;
715 })
716
717 (define_expand "cmpdf"
718 [(set (reg:CC 17)
719 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
720 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
721 "TARGET_80387 || TARGET_SSE2"
722 {
723 ix86_compare_op0 = operands[0];
724 ix86_compare_op1 = operands[1];
725 DONE;
726 })
727
728 (define_expand "cmpsf"
729 [(set (reg:CC 17)
730 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
731 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
732 "TARGET_80387 || TARGET_SSE"
733 {
734 ix86_compare_op0 = operands[0];
735 ix86_compare_op1 = operands[1];
736 DONE;
737 })
738
739 ;; FP compares, step 1:
740 ;; Set the FP condition codes.
741 ;;
742 ;; CCFPmode compare with exceptions
743 ;; CCFPUmode compare with no exceptions
744
745 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
746 ;; and that fp moves clobber the condition codes, and that there is
747 ;; currently no way to describe this fact to reg-stack. So there are
748 ;; no splitters yet for this.
749
750 ;; %%% YIKES! This scheme does not retain a strong connection between
751 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
752 ;; work! Only allow tos/mem with tos in op 0.
753 ;;
754 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
755 ;; things aren't as bad as they sound...
756
757 (define_insn "*cmpfp_0"
758 [(set (match_operand:HI 0 "register_operand" "=a")
759 (unspec:HI
760 [(compare:CCFP (match_operand 1 "register_operand" "f")
761 (match_operand 2 "const0_operand" "X"))]
762 UNSPEC_FNSTSW))]
763 "TARGET_80387
764 && FLOAT_MODE_P (GET_MODE (operands[1]))
765 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
766 {
767 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
768 return "ftst\;fnstsw\t%0\;fstp\t%y0";
769 else
770 return "ftst\;fnstsw\t%0";
771 }
772 [(set_attr "type" "multi")
773 (set (attr "mode")
774 (cond [(match_operand:SF 1 "" "")
775 (const_string "SF")
776 (match_operand:DF 1 "" "")
777 (const_string "DF")
778 ]
779 (const_string "XF")))])
780
781 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
782 ;; used to manage the reg stack popping would not be preserved.
783
784 (define_insn "*cmpfp_2_sf"
785 [(set (reg:CCFP 18)
786 (compare:CCFP
787 (match_operand:SF 0 "register_operand" "f")
788 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
789 "TARGET_80387"
790 "* return output_fp_compare (insn, operands, 0, 0);"
791 [(set_attr "type" "fcmp")
792 (set_attr "mode" "SF")])
793
794 (define_insn "*cmpfp_2_sf_1"
795 [(set (match_operand:HI 0 "register_operand" "=a")
796 (unspec:HI
797 [(compare:CCFP
798 (match_operand:SF 1 "register_operand" "f")
799 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
800 UNSPEC_FNSTSW))]
801 "TARGET_80387"
802 "* return output_fp_compare (insn, operands, 2, 0);"
803 [(set_attr "type" "fcmp")
804 (set_attr "mode" "SF")])
805
806 (define_insn "*cmpfp_2_df"
807 [(set (reg:CCFP 18)
808 (compare:CCFP
809 (match_operand:DF 0 "register_operand" "f")
810 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
811 "TARGET_80387"
812 "* return output_fp_compare (insn, operands, 0, 0);"
813 [(set_attr "type" "fcmp")
814 (set_attr "mode" "DF")])
815
816 (define_insn "*cmpfp_2_df_1"
817 [(set (match_operand:HI 0 "register_operand" "=a")
818 (unspec:HI
819 [(compare:CCFP
820 (match_operand:DF 1 "register_operand" "f")
821 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
822 UNSPEC_FNSTSW))]
823 "TARGET_80387"
824 "* return output_fp_compare (insn, operands, 2, 0);"
825 [(set_attr "type" "multi")
826 (set_attr "mode" "DF")])
827
828 (define_insn "*cmpfp_2_xf"
829 [(set (reg:CCFP 18)
830 (compare:CCFP
831 (match_operand:XF 0 "register_operand" "f")
832 (match_operand:XF 1 "register_operand" "f")))]
833 "!TARGET_64BIT && TARGET_80387"
834 "* return output_fp_compare (insn, operands, 0, 0);"
835 [(set_attr "type" "fcmp")
836 (set_attr "mode" "XF")])
837
838 (define_insn "*cmpfp_2_tf"
839 [(set (reg:CCFP 18)
840 (compare:CCFP
841 (match_operand:TF 0 "register_operand" "f")
842 (match_operand:TF 1 "register_operand" "f")))]
843 "TARGET_80387"
844 "* return output_fp_compare (insn, operands, 0, 0);"
845 [(set_attr "type" "fcmp")
846 (set_attr "mode" "XF")])
847
848 (define_insn "*cmpfp_2_xf_1"
849 [(set (match_operand:HI 0 "register_operand" "=a")
850 (unspec:HI
851 [(compare:CCFP
852 (match_operand:XF 1 "register_operand" "f")
853 (match_operand:XF 2 "register_operand" "f"))]
854 UNSPEC_FNSTSW))]
855 "!TARGET_64BIT && TARGET_80387"
856 "* return output_fp_compare (insn, operands, 2, 0);"
857 [(set_attr "type" "multi")
858 (set_attr "mode" "XF")])
859
860 (define_insn "*cmpfp_2_tf_1"
861 [(set (match_operand:HI 0 "register_operand" "=a")
862 (unspec:HI
863 [(compare:CCFP
864 (match_operand:TF 1 "register_operand" "f")
865 (match_operand:TF 2 "register_operand" "f"))]
866 UNSPEC_FNSTSW))]
867 "TARGET_80387"
868 "* return output_fp_compare (insn, operands, 2, 0);"
869 [(set_attr "type" "multi")
870 (set_attr "mode" "XF")])
871
872 (define_insn "*cmpfp_2u"
873 [(set (reg:CCFPU 18)
874 (compare:CCFPU
875 (match_operand 0 "register_operand" "f")
876 (match_operand 1 "register_operand" "f")))]
877 "TARGET_80387
878 && FLOAT_MODE_P (GET_MODE (operands[0]))
879 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
880 "* return output_fp_compare (insn, operands, 0, 1);"
881 [(set_attr "type" "fcmp")
882 (set (attr "mode")
883 (cond [(match_operand:SF 1 "" "")
884 (const_string "SF")
885 (match_operand:DF 1 "" "")
886 (const_string "DF")
887 ]
888 (const_string "XF")))])
889
890 (define_insn "*cmpfp_2u_1"
891 [(set (match_operand:HI 0 "register_operand" "=a")
892 (unspec:HI
893 [(compare:CCFPU
894 (match_operand 1 "register_operand" "f")
895 (match_operand 2 "register_operand" "f"))]
896 UNSPEC_FNSTSW))]
897 "TARGET_80387
898 && FLOAT_MODE_P (GET_MODE (operands[1]))
899 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
900 "* return output_fp_compare (insn, operands, 2, 1);"
901 [(set_attr "type" "multi")
902 (set (attr "mode")
903 (cond [(match_operand:SF 1 "" "")
904 (const_string "SF")
905 (match_operand:DF 1 "" "")
906 (const_string "DF")
907 ]
908 (const_string "XF")))])
909
910 ;; Patterns to match the SImode-in-memory ficom instructions.
911 ;;
912 ;; %%% Play games with accepting gp registers, as otherwise we have to
913 ;; force them to memory during rtl generation, which is no good. We
914 ;; can get rid of this once we teach reload to do memory input reloads
915 ;; via pushes.
916
917 (define_insn "*ficom_1"
918 [(set (reg:CCFP 18)
919 (compare:CCFP
920 (match_operand 0 "register_operand" "f,f")
921 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
922 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
923 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
924 "#")
925
926 ;; Split the not-really-implemented gp register case into a
927 ;; push-op-pop sequence.
928 ;;
929 ;; %%% This is most efficient, but am I gonna get in trouble
930 ;; for separating cc0_setter and cc0_user?
931
932 (define_split
933 [(set (reg:CCFP 18)
934 (compare:CCFP
935 (match_operand:SF 0 "register_operand" "")
936 (float (match_operand:SI 1 "register_operand" ""))))]
937 "0 && TARGET_80387 && reload_completed"
938 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
939 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
940 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
941 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
942 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
943 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
944
945 ;; FP compares, step 2
946 ;; Move the fpsw to ax.
947
948 (define_insn "*x86_fnstsw_1"
949 [(set (match_operand:HI 0 "register_operand" "=a")
950 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
951 "TARGET_80387"
952 "fnstsw\t%0"
953 [(set_attr "length" "2")
954 (set_attr "mode" "SI")
955 (set_attr "unit" "i387")
956 (set_attr "ppro_uops" "few")])
957
958 ;; FP compares, step 3
959 ;; Get ax into flags, general case.
960
961 (define_insn "x86_sahf_1"
962 [(set (reg:CC 17)
963 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
964 "!TARGET_64BIT"
965 "sahf"
966 [(set_attr "length" "1")
967 (set_attr "athlon_decode" "vector")
968 (set_attr "mode" "SI")
969 (set_attr "ppro_uops" "one")])
970
971 ;; Pentium Pro can do steps 1 through 3 in one go.
972
973 (define_insn "*cmpfp_i"
974 [(set (reg:CCFP 17)
975 (compare:CCFP (match_operand 0 "register_operand" "f")
976 (match_operand 1 "register_operand" "f")))]
977 "TARGET_80387 && TARGET_CMOVE
978 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
979 && FLOAT_MODE_P (GET_MODE (operands[0]))
980 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
981 "* return output_fp_compare (insn, operands, 1, 0);"
982 [(set_attr "type" "fcmp")
983 (set (attr "mode")
984 (cond [(match_operand:SF 1 "" "")
985 (const_string "SF")
986 (match_operand:DF 1 "" "")
987 (const_string "DF")
988 ]
989 (const_string "XF")))
990 (set_attr "athlon_decode" "vector")])
991
992 (define_insn "*cmpfp_i_sse"
993 [(set (reg:CCFP 17)
994 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
995 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
996 "TARGET_80387
997 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
998 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
999 "* return output_fp_compare (insn, operands, 1, 0);"
1000 [(set_attr "type" "fcmp,ssecmp")
1001 (set (attr "mode")
1002 (if_then_else (match_operand:SF 1 "" "")
1003 (const_string "SF")
1004 (const_string "DF")))
1005 (set_attr "athlon_decode" "vector")])
1006
1007 (define_insn "*cmpfp_i_sse_only"
1008 [(set (reg:CCFP 17)
1009 (compare:CCFP (match_operand 0 "register_operand" "x")
1010 (match_operand 1 "nonimmediate_operand" "xm")))]
1011 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1012 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1013 "* return output_fp_compare (insn, operands, 1, 0);"
1014 [(set_attr "type" "ssecmp")
1015 (set (attr "mode")
1016 (if_then_else (match_operand:SF 1 "" "")
1017 (const_string "SF")
1018 (const_string "DF")))
1019 (set_attr "athlon_decode" "vector")])
1020
1021 (define_insn "*cmpfp_iu"
1022 [(set (reg:CCFPU 17)
1023 (compare:CCFPU (match_operand 0 "register_operand" "f")
1024 (match_operand 1 "register_operand" "f")))]
1025 "TARGET_80387 && TARGET_CMOVE
1026 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1027 && FLOAT_MODE_P (GET_MODE (operands[0]))
1028 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1029 "* return output_fp_compare (insn, operands, 1, 1);"
1030 [(set_attr "type" "fcmp")
1031 (set (attr "mode")
1032 (cond [(match_operand:SF 1 "" "")
1033 (const_string "SF")
1034 (match_operand:DF 1 "" "")
1035 (const_string "DF")
1036 ]
1037 (const_string "XF")))
1038 (set_attr "athlon_decode" "vector")])
1039
1040 (define_insn "*cmpfp_iu_sse"
1041 [(set (reg:CCFPU 17)
1042 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1043 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1044 "TARGET_80387
1045 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1046 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1047 "* return output_fp_compare (insn, operands, 1, 1);"
1048 [(set_attr "type" "fcmp,ssecmp")
1049 (set (attr "mode")
1050 (if_then_else (match_operand:SF 1 "" "")
1051 (const_string "SF")
1052 (const_string "DF")))
1053 (set_attr "athlon_decode" "vector")])
1054
1055 (define_insn "*cmpfp_iu_sse_only"
1056 [(set (reg:CCFPU 17)
1057 (compare:CCFPU (match_operand 0 "register_operand" "x")
1058 (match_operand 1 "nonimmediate_operand" "xm")))]
1059 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1060 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1061 "* return output_fp_compare (insn, operands, 1, 1);"
1062 [(set_attr "type" "ssecmp")
1063 (set (attr "mode")
1064 (if_then_else (match_operand:SF 1 "" "")
1065 (const_string "SF")
1066 (const_string "DF")))
1067 (set_attr "athlon_decode" "vector")])
1068 \f
1069 ;; Move instructions.
1070
1071 ;; General case of fullword move.
1072
1073 (define_expand "movsi"
1074 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1075 (match_operand:SI 1 "general_operand" ""))]
1076 ""
1077 "ix86_expand_move (SImode, operands); DONE;")
1078
1079 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1080 ;; general_operand.
1081 ;;
1082 ;; %%% We don't use a post-inc memory reference because x86 is not a
1083 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1084 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1085 ;; targets without our curiosities, and it is just as easy to represent
1086 ;; this differently.
1087
1088 (define_insn "*pushsi2"
1089 [(set (match_operand:SI 0 "push_operand" "=<")
1090 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1091 "!TARGET_64BIT"
1092 "push{l}\t%1"
1093 [(set_attr "type" "push")
1094 (set_attr "mode" "SI")])
1095
1096 ;; For 64BIT abi we always round up to 8 bytes.
1097 (define_insn "*pushsi2_rex64"
1098 [(set (match_operand:SI 0 "push_operand" "=X")
1099 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1100 "TARGET_64BIT"
1101 "push{q}\t%q1"
1102 [(set_attr "type" "push")
1103 (set_attr "mode" "SI")])
1104
1105 (define_insn "*pushsi2_prologue"
1106 [(set (match_operand:SI 0 "push_operand" "=<")
1107 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1108 (clobber (mem:BLK (scratch)))]
1109 "!TARGET_64BIT"
1110 "push{l}\t%1"
1111 [(set_attr "type" "push")
1112 (set_attr "mode" "SI")])
1113
1114 (define_insn "*popsi1_epilogue"
1115 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1116 (mem:SI (reg:SI 7)))
1117 (set (reg:SI 7)
1118 (plus:SI (reg:SI 7) (const_int 4)))
1119 (clobber (mem:BLK (scratch)))]
1120 "!TARGET_64BIT"
1121 "pop{l}\t%0"
1122 [(set_attr "type" "pop")
1123 (set_attr "mode" "SI")])
1124
1125 (define_insn "popsi1"
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 "!TARGET_64BIT"
1131 "pop{l}\t%0"
1132 [(set_attr "type" "pop")
1133 (set_attr "mode" "SI")])
1134
1135 (define_insn "*movsi_xor"
1136 [(set (match_operand:SI 0 "register_operand" "=r")
1137 (match_operand:SI 1 "const0_operand" "i"))
1138 (clobber (reg:CC 17))]
1139 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1140 "xor{l}\t{%0, %0|%0, %0}"
1141 [(set_attr "type" "alu1")
1142 (set_attr "mode" "SI")
1143 (set_attr "length_immediate" "0")])
1144
1145 (define_insn "*movsi_or"
1146 [(set (match_operand:SI 0 "register_operand" "=r")
1147 (match_operand:SI 1 "immediate_operand" "i"))
1148 (clobber (reg:CC 17))]
1149 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1150 && INTVAL (operands[1]) == -1
1151 && (TARGET_PENTIUM || optimize_size)"
1152 {
1153 operands[1] = constm1_rtx;
1154 return "or{l}\t{%1, %0|%0, %1}";
1155 }
1156 [(set_attr "type" "alu1")
1157 (set_attr "mode" "SI")
1158 (set_attr "length_immediate" "1")])
1159
1160 ; The first alternative is used only to compute proper length of instruction.
1161 ; Reload's algorithm does not take into account the cost of spill instructions
1162 ; needed to free register in given class, so avoid it from choosing the first
1163 ; alternative when eax is not available.
1164
1165 (define_insn "*movsi_1"
1166 [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1167 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
1168 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1169 {
1170 switch (get_attr_type (insn))
1171 {
1172 case TYPE_SSEMOV:
1173 if (get_attr_mode (insn) == TImode)
1174 return "movdqa\t{%1, %0|%0, %1}";
1175 return "movd\t{%1, %0|%0, %1}";
1176
1177 case TYPE_MMXMOV:
1178 if (get_attr_mode (insn) == DImode)
1179 return "movq\t{%1, %0|%0, %1}";
1180 return "movd\t{%1, %0|%0, %1}";
1181
1182 case TYPE_LEA:
1183 return "lea{l}\t{%1, %0|%0, %1}";
1184
1185 default:
1186 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1187 abort();
1188 return "mov{l}\t{%1, %0|%0, %1}";
1189 }
1190 }
1191 [(set (attr "type")
1192 (cond [(eq_attr "alternative" "4,5,6")
1193 (const_string "mmxmov")
1194 (eq_attr "alternative" "7,8,9")
1195 (const_string "ssemov")
1196 (and (ne (symbol_ref "flag_pic") (const_int 0))
1197 (match_operand:SI 1 "symbolic_operand" ""))
1198 (const_string "lea")
1199 ]
1200 (const_string "imov")))
1201 (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
1202 (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
1203
1204 ;; Stores and loads of ax to arbitary constant address.
1205 ;; We fake an second form of instruction to force reload to load address
1206 ;; into register when rax is not available
1207 (define_insn "*movabssi_1_rex64"
1208 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1209 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1210 "TARGET_64BIT"
1211 "@
1212 movabs{l}\t{%1, %P0|%P0, %1}
1213 mov{l}\t{%1, %a0|%a0, %1}
1214 movabs{l}\t{%1, %a0|%a0, %1}"
1215 [(set_attr "type" "imov")
1216 (set_attr "modrm" "0,*,*")
1217 (set_attr "length_address" "8,0,0")
1218 (set_attr "length_immediate" "0,*,*")
1219 (set_attr "memory" "store")
1220 (set_attr "mode" "SI")])
1221
1222 (define_insn "*movabssi_2_rex64"
1223 [(set (match_operand:SI 0 "register_operand" "=a,r")
1224 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1225 "TARGET_64BIT"
1226 "@
1227 movabs{l}\t{%P1, %0|%0, %P1}
1228 mov{l}\t{%a1, %0|%0, %a1}"
1229 [(set_attr "type" "imov")
1230 (set_attr "modrm" "0,*")
1231 (set_attr "length_address" "8,0")
1232 (set_attr "length_immediate" "0")
1233 (set_attr "memory" "load")
1234 (set_attr "mode" "SI")])
1235
1236 (define_insn "*swapsi"
1237 [(set (match_operand:SI 0 "register_operand" "+r")
1238 (match_operand:SI 1 "register_operand" "+r"))
1239 (set (match_dup 1)
1240 (match_dup 0))]
1241 ""
1242 "xchg{l}\t%1, %0"
1243 [(set_attr "type" "imov")
1244 (set_attr "pent_pair" "np")
1245 (set_attr "athlon_decode" "vector")
1246 (set_attr "mode" "SI")
1247 (set_attr "modrm" "0")
1248 (set_attr "ppro_uops" "few")])
1249
1250 (define_expand "movhi"
1251 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1252 (match_operand:HI 1 "general_operand" ""))]
1253 ""
1254 "ix86_expand_move (HImode, operands); DONE;")
1255
1256 (define_insn "*pushhi2"
1257 [(set (match_operand:HI 0 "push_operand" "=<,<")
1258 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1259 "!TARGET_64BIT"
1260 "@
1261 push{w}\t{|WORD PTR }%1
1262 push{w}\t%1"
1263 [(set_attr "type" "push")
1264 (set_attr "mode" "HI")])
1265
1266 ;; For 64BIT abi we always round up to 8 bytes.
1267 (define_insn "*pushhi2_rex64"
1268 [(set (match_operand:HI 0 "push_operand" "=X")
1269 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1270 "TARGET_64BIT"
1271 "push{q}\t%q1"
1272 [(set_attr "type" "push")
1273 (set_attr "mode" "QI")])
1274
1275 ; The first alternative is used only to compute proper length of instruction.
1276 ; Reload's algorithm does not take into account the cost of spill instructions
1277 ; needed to free register in given class, so avoid it from choosing the first
1278 ; alternative when eax is not available.
1279
1280 (define_insn "*movhi_1"
1281 [(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
1282 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1283 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1284 {
1285 switch (get_attr_type (insn))
1286 {
1287 case TYPE_IMOVX:
1288 /* movzwl is faster than movw on p2 due to partial word stalls,
1289 though not as fast as an aligned movl. */
1290 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1291 default:
1292 if (get_attr_mode (insn) == MODE_SI)
1293 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1294 else
1295 return "mov{w}\t{%1, %0|%0, %1}";
1296 }
1297 }
1298 [(set (attr "type")
1299 (cond [(and (eq_attr "alternative" "0,1")
1300 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1301 (const_int 0))
1302 (eq (symbol_ref "TARGET_HIMODE_MATH")
1303 (const_int 0))))
1304 (const_string "imov")
1305 (and (eq_attr "alternative" "2,3,4")
1306 (match_operand:HI 1 "aligned_operand" ""))
1307 (const_string "imov")
1308 (and (ne (symbol_ref "TARGET_MOVX")
1309 (const_int 0))
1310 (eq_attr "alternative" "0,1,3,4"))
1311 (const_string "imovx")
1312 ]
1313 (const_string "imov")))
1314 (set (attr "mode")
1315 (cond [(eq_attr "type" "imovx")
1316 (const_string "SI")
1317 (and (eq_attr "alternative" "2,3,4")
1318 (match_operand:HI 1 "aligned_operand" ""))
1319 (const_string "SI")
1320 (and (eq_attr "alternative" "0,1")
1321 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1322 (const_int 0))
1323 (eq (symbol_ref "TARGET_HIMODE_MATH")
1324 (const_int 0))))
1325 (const_string "SI")
1326 ]
1327 (const_string "HI")))
1328 (set_attr "modrm" "0,*,*,0,*,*")])
1329
1330 ;; Stores and loads of ax to arbitary constant address.
1331 ;; We fake an second form of instruction to force reload to load address
1332 ;; into register when rax is not available
1333 (define_insn "*movabshi_1_rex64"
1334 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1335 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1336 "TARGET_64BIT"
1337 "@
1338 movabs{w}\t{%1, %P0|%P0, %1}
1339 mov{w}\t{%1, %a0|%a0, %1}
1340 movabs{w}\t{%1, %a0|%a0, %1}"
1341 [(set_attr "type" "imov")
1342 (set_attr "modrm" "0,*,*")
1343 (set_attr "length_address" "8,0,0")
1344 (set_attr "length_immediate" "0,*,*")
1345 (set_attr "memory" "store")
1346 (set_attr "mode" "HI")])
1347
1348 (define_insn "*movabshi_2_rex64"
1349 [(set (match_operand:HI 0 "register_operand" "=a,r")
1350 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1351 "TARGET_64BIT"
1352 "@
1353 movabs{w}\t{%P1, %0|%0, %P1}
1354 mov{w}\t{%a1, %0|%0, %a1}"
1355 [(set_attr "type" "imov")
1356 (set_attr "modrm" "0,*")
1357 (set_attr "length_address" "8,0")
1358 (set_attr "length_immediate" "0")
1359 (set_attr "memory" "load")
1360 (set_attr "mode" "HI")])
1361
1362 (define_insn "*swaphi_1"
1363 [(set (match_operand:HI 0 "register_operand" "+r")
1364 (match_operand:HI 1 "register_operand" "+r"))
1365 (set (match_dup 1)
1366 (match_dup 0))]
1367 "TARGET_PARTIAL_REG_STALL"
1368 "xchg{w}\t%1, %0"
1369 [(set_attr "type" "imov")
1370 (set_attr "pent_pair" "np")
1371 (set_attr "mode" "HI")
1372 (set_attr "modrm" "0")
1373 (set_attr "ppro_uops" "few")])
1374
1375 (define_insn "*swaphi_2"
1376 [(set (match_operand:HI 0 "register_operand" "+r")
1377 (match_operand:HI 1 "register_operand" "+r"))
1378 (set (match_dup 1)
1379 (match_dup 0))]
1380 "! TARGET_PARTIAL_REG_STALL"
1381 "xchg{l}\t%k1, %k0"
1382 [(set_attr "type" "imov")
1383 (set_attr "pent_pair" "np")
1384 (set_attr "mode" "SI")
1385 (set_attr "modrm" "0")
1386 (set_attr "ppro_uops" "few")])
1387
1388 (define_expand "movstricthi"
1389 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1390 (match_operand:HI 1 "general_operand" ""))]
1391 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1392 {
1393 /* Don't generate memory->memory moves, go through a register */
1394 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1395 operands[1] = force_reg (HImode, operands[1]);
1396 })
1397
1398 (define_insn "*movstricthi_1"
1399 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1400 (match_operand:HI 1 "general_operand" "rn,m"))]
1401 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1402 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1403 "mov{w}\t{%1, %0|%0, %1}"
1404 [(set_attr "type" "imov")
1405 (set_attr "mode" "HI")])
1406
1407 (define_insn "*movstricthi_xor"
1408 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1409 (match_operand:HI 1 "const0_operand" "i"))
1410 (clobber (reg:CC 17))]
1411 "reload_completed
1412 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1413 "xor{w}\t{%0, %0|%0, %0}"
1414 [(set_attr "type" "alu1")
1415 (set_attr "mode" "HI")
1416 (set_attr "length_immediate" "0")])
1417
1418 (define_expand "movqi"
1419 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1420 (match_operand:QI 1 "general_operand" ""))]
1421 ""
1422 "ix86_expand_move (QImode, operands); DONE;")
1423
1424 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1425 ;; "push a byte". But actually we use pushw, which has the effect
1426 ;; of rounding the amount pushed up to a halfword.
1427
1428 (define_insn "*pushqi2"
1429 [(set (match_operand:QI 0 "push_operand" "=X,X")
1430 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1431 "!TARGET_64BIT"
1432 "@
1433 push{w}\t{|word ptr }%1
1434 push{w}\t%w1"
1435 [(set_attr "type" "push")
1436 (set_attr "mode" "HI")])
1437
1438 ;; For 64BIT abi we always round up to 8 bytes.
1439 (define_insn "*pushqi2_rex64"
1440 [(set (match_operand:QI 0 "push_operand" "=X")
1441 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1442 "TARGET_64BIT"
1443 "push{q}\t%q1"
1444 [(set_attr "type" "push")
1445 (set_attr "mode" "QI")])
1446
1447 ;; Situation is quite tricky about when to choose full sized (SImode) move
1448 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1449 ;; partial register dependency machines (such as AMD Athlon), where QImode
1450 ;; moves issue extra dependency and for partial register stalls machines
1451 ;; that don't use QImode patterns (and QImode move cause stall on the next
1452 ;; instruction).
1453 ;;
1454 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1455 ;; register stall machines with, where we use QImode instructions, since
1456 ;; partial register stall can be caused there. Then we use movzx.
1457 (define_insn "*movqi_1"
1458 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1459 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1460 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1461 {
1462 switch (get_attr_type (insn))
1463 {
1464 case TYPE_IMOVX:
1465 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1466 abort ();
1467 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1468 default:
1469 if (get_attr_mode (insn) == MODE_SI)
1470 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1471 else
1472 return "mov{b}\t{%1, %0|%0, %1}";
1473 }
1474 }
1475 [(set (attr "type")
1476 (cond [(and (eq_attr "alternative" "3")
1477 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1478 (const_int 0))
1479 (eq (symbol_ref "TARGET_QIMODE_MATH")
1480 (const_int 0))))
1481 (const_string "imov")
1482 (eq_attr "alternative" "3,5")
1483 (const_string "imovx")
1484 (and (ne (symbol_ref "TARGET_MOVX")
1485 (const_int 0))
1486 (eq_attr "alternative" "2"))
1487 (const_string "imovx")
1488 ]
1489 (const_string "imov")))
1490 (set (attr "mode")
1491 (cond [(eq_attr "alternative" "3,4,5")
1492 (const_string "SI")
1493 (eq_attr "alternative" "6")
1494 (const_string "QI")
1495 (eq_attr "type" "imovx")
1496 (const_string "SI")
1497 (and (eq_attr "type" "imov")
1498 (and (eq_attr "alternative" "0,1,2")
1499 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1500 (const_int 0))))
1501 (const_string "SI")
1502 ;; Avoid partial register stalls when not using QImode arithmetic
1503 (and (eq_attr "type" "imov")
1504 (and (eq_attr "alternative" "0,1,2")
1505 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1506 (const_int 0))
1507 (eq (symbol_ref "TARGET_QIMODE_MATH")
1508 (const_int 0)))))
1509 (const_string "SI")
1510 ]
1511 (const_string "QI")))])
1512
1513 (define_expand "reload_outqi"
1514 [(parallel [(match_operand:QI 0 "" "=m")
1515 (match_operand:QI 1 "register_operand" "r")
1516 (match_operand:QI 2 "register_operand" "=&q")])]
1517 ""
1518 {
1519 rtx op0, op1, op2;
1520 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1521
1522 if (reg_overlap_mentioned_p (op2, op0))
1523 abort ();
1524 if (! q_regs_operand (op1, QImode))
1525 {
1526 emit_insn (gen_movqi (op2, op1));
1527 op1 = op2;
1528 }
1529 emit_insn (gen_movqi (op0, op1));
1530 DONE;
1531 })
1532
1533 (define_insn "*swapqi"
1534 [(set (match_operand:QI 0 "register_operand" "+r")
1535 (match_operand:QI 1 "register_operand" "+r"))
1536 (set (match_dup 1)
1537 (match_dup 0))]
1538 ""
1539 "xchg{b}\t%1, %0"
1540 [(set_attr "type" "imov")
1541 (set_attr "pent_pair" "np")
1542 (set_attr "mode" "QI")
1543 (set_attr "modrm" "0")
1544 (set_attr "ppro_uops" "few")])
1545
1546 (define_expand "movstrictqi"
1547 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1548 (match_operand:QI 1 "general_operand" ""))]
1549 "! TARGET_PARTIAL_REG_STALL"
1550 {
1551 /* Don't generate memory->memory moves, go through a register. */
1552 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1553 operands[1] = force_reg (QImode, operands[1]);
1554 })
1555
1556 (define_insn "*movstrictqi_1"
1557 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1558 (match_operand:QI 1 "general_operand" "*qn,m"))]
1559 "! TARGET_PARTIAL_REG_STALL
1560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1561 "mov{b}\t{%1, %0|%0, %1}"
1562 [(set_attr "type" "imov")
1563 (set_attr "mode" "QI")])
1564
1565 (define_insn "*movstrictqi_xor"
1566 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1567 (match_operand:QI 1 "const0_operand" "i"))
1568 (clobber (reg:CC 17))]
1569 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1570 "xor{b}\t{%0, %0|%0, %0}"
1571 [(set_attr "type" "alu1")
1572 (set_attr "mode" "QI")
1573 (set_attr "length_immediate" "0")])
1574
1575 (define_insn "*movsi_extv_1"
1576 [(set (match_operand:SI 0 "register_operand" "=R")
1577 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1578 (const_int 8)
1579 (const_int 8)))]
1580 ""
1581 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1582 [(set_attr "type" "imovx")
1583 (set_attr "mode" "SI")])
1584
1585 (define_insn "*movhi_extv_1"
1586 [(set (match_operand:HI 0 "register_operand" "=R")
1587 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1588 (const_int 8)
1589 (const_int 8)))]
1590 ""
1591 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1592 [(set_attr "type" "imovx")
1593 (set_attr "mode" "SI")])
1594
1595 (define_insn "*movqi_extv_1"
1596 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1597 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1598 (const_int 8)
1599 (const_int 8)))]
1600 "!TARGET_64BIT"
1601 {
1602 switch (get_attr_type (insn))
1603 {
1604 case TYPE_IMOVX:
1605 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1606 default:
1607 return "mov{b}\t{%h1, %0|%0, %h1}";
1608 }
1609 }
1610 [(set (attr "type")
1611 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1612 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1613 (ne (symbol_ref "TARGET_MOVX")
1614 (const_int 0))))
1615 (const_string "imovx")
1616 (const_string "imov")))
1617 (set (attr "mode")
1618 (if_then_else (eq_attr "type" "imovx")
1619 (const_string "SI")
1620 (const_string "QI")))])
1621
1622 (define_insn "*movqi_extv_1_rex64"
1623 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1624 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1625 (const_int 8)
1626 (const_int 8)))]
1627 "TARGET_64BIT"
1628 {
1629 switch (get_attr_type (insn))
1630 {
1631 case TYPE_IMOVX:
1632 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1633 default:
1634 return "mov{b}\t{%h1, %0|%0, %h1}";
1635 }
1636 }
1637 [(set (attr "type")
1638 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1639 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1640 (ne (symbol_ref "TARGET_MOVX")
1641 (const_int 0))))
1642 (const_string "imovx")
1643 (const_string "imov")))
1644 (set (attr "mode")
1645 (if_then_else (eq_attr "type" "imovx")
1646 (const_string "SI")
1647 (const_string "QI")))])
1648
1649 ;; Stores and loads of ax to arbitary constant address.
1650 ;; We fake an second form of instruction to force reload to load address
1651 ;; into register when rax is not available
1652 (define_insn "*movabsqi_1_rex64"
1653 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1654 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1655 "TARGET_64BIT"
1656 "@
1657 movabs{b}\t{%1, %P0|%P0, %1}
1658 mov{b}\t{%1, %a0|%a0, %1}
1659 movabs{b}\t{%1, %a0|%a0, %1}"
1660 [(set_attr "type" "imov")
1661 (set_attr "modrm" "0,*,*")
1662 (set_attr "length_address" "8,0,0")
1663 (set_attr "length_immediate" "0,*,*")
1664 (set_attr "memory" "store")
1665 (set_attr "mode" "QI")])
1666
1667 (define_insn "*movabsqi_2_rex64"
1668 [(set (match_operand:QI 0 "register_operand" "=a,r")
1669 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1670 "TARGET_64BIT"
1671 "@
1672 movabs{b}\t{%P1, %0|%0, %P1}
1673 mov{b}\t{%a1, %0|%0, %a1}"
1674 [(set_attr "type" "imov")
1675 (set_attr "modrm" "0,*")
1676 (set_attr "length_address" "8,0")
1677 (set_attr "length_immediate" "0")
1678 (set_attr "memory" "load")
1679 (set_attr "mode" "QI")])
1680
1681 (define_insn "*movsi_extzv_1"
1682 [(set (match_operand:SI 0 "register_operand" "=R")
1683 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1684 (const_int 8)
1685 (const_int 8)))]
1686 ""
1687 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1688 [(set_attr "type" "imovx")
1689 (set_attr "mode" "SI")])
1690
1691 (define_insn "*movqi_extzv_2"
1692 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1693 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1694 (const_int 8)
1695 (const_int 8)) 0))]
1696 "!TARGET_64BIT"
1697 {
1698 switch (get_attr_type (insn))
1699 {
1700 case TYPE_IMOVX:
1701 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1702 default:
1703 return "mov{b}\t{%h1, %0|%0, %h1}";
1704 }
1705 }
1706 [(set (attr "type")
1707 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1708 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1709 (ne (symbol_ref "TARGET_MOVX")
1710 (const_int 0))))
1711 (const_string "imovx")
1712 (const_string "imov")))
1713 (set (attr "mode")
1714 (if_then_else (eq_attr "type" "imovx")
1715 (const_string "SI")
1716 (const_string "QI")))])
1717
1718 (define_insn "*movqi_extzv_2_rex64"
1719 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1720 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1721 (const_int 8)
1722 (const_int 8)) 0))]
1723 "TARGET_64BIT"
1724 {
1725 switch (get_attr_type (insn))
1726 {
1727 case TYPE_IMOVX:
1728 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1729 default:
1730 return "mov{b}\t{%h1, %0|%0, %h1}";
1731 }
1732 }
1733 [(set (attr "type")
1734 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1735 (ne (symbol_ref "TARGET_MOVX")
1736 (const_int 0)))
1737 (const_string "imovx")
1738 (const_string "imov")))
1739 (set (attr "mode")
1740 (if_then_else (eq_attr "type" "imovx")
1741 (const_string "SI")
1742 (const_string "QI")))])
1743
1744 (define_insn "movsi_insv_1"
1745 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1746 (const_int 8)
1747 (const_int 8))
1748 (match_operand:SI 1 "general_operand" "Qmn"))]
1749 "!TARGET_64BIT"
1750 "mov{b}\t{%b1, %h0|%h0, %b1}"
1751 [(set_attr "type" "imov")
1752 (set_attr "mode" "QI")])
1753
1754 (define_insn "*movsi_insv_1_rex64"
1755 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1756 (const_int 8)
1757 (const_int 8))
1758 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1759 "TARGET_64BIT"
1760 "mov{b}\t{%b1, %h0|%h0, %b1}"
1761 [(set_attr "type" "imov")
1762 (set_attr "mode" "QI")])
1763
1764 (define_insn "*movqi_insv_2"
1765 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1766 (const_int 8)
1767 (const_int 8))
1768 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1769 (const_int 8))
1770 (const_int 255)))]
1771 ""
1772 "mov{b}\t{%h1, %h0|%h0, %h1}"
1773 [(set_attr "type" "imov")
1774 (set_attr "mode" "QI")])
1775
1776 (define_expand "movdi"
1777 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1778 (match_operand:DI 1 "general_operand" ""))]
1779 ""
1780 "ix86_expand_move (DImode, operands); DONE;")
1781
1782 (define_insn "*pushdi"
1783 [(set (match_operand:DI 0 "push_operand" "=<")
1784 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1785 "!TARGET_64BIT"
1786 "#")
1787
1788 (define_insn "pushdi2_rex64"
1789 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1790 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1791 "TARGET_64BIT"
1792 "@
1793 push{q}\t%1
1794 #"
1795 [(set_attr "type" "push,multi")
1796 (set_attr "mode" "DI")])
1797
1798 ;; Convert impossible pushes of immediate to existing instructions.
1799 ;; First try to get scratch register and go through it. In case this
1800 ;; fails, push sign extended lower part first and then overwrite
1801 ;; upper part by 32bit move.
1802 (define_peephole2
1803 [(match_scratch:DI 2 "r")
1804 (set (match_operand:DI 0 "push_operand" "")
1805 (match_operand:DI 1 "immediate_operand" ""))]
1806 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807 && !x86_64_immediate_operand (operands[1], DImode)"
1808 [(set (match_dup 2) (match_dup 1))
1809 (set (match_dup 0) (match_dup 2))]
1810 "")
1811
1812 ;; We need to define this as both peepholer and splitter for case
1813 ;; peephole2 pass is not run.
1814 (define_peephole2
1815 [(set (match_operand:DI 0 "push_operand" "")
1816 (match_operand:DI 1 "immediate_operand" ""))]
1817 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1818 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1819 [(set (match_dup 0) (match_dup 1))
1820 (set (match_dup 2) (match_dup 3))]
1821 "split_di (operands + 1, 1, operands + 2, operands + 3);
1822 operands[1] = gen_lowpart (DImode, operands[2]);
1823 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1824 GEN_INT (4)));
1825 ")
1826
1827 (define_split
1828 [(set (match_operand:DI 0 "push_operand" "")
1829 (match_operand:DI 1 "immediate_operand" ""))]
1830 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1831 && !symbolic_operand (operands[1], DImode)
1832 && !x86_64_immediate_operand (operands[1], DImode)"
1833 [(set (match_dup 0) (match_dup 1))
1834 (set (match_dup 2) (match_dup 3))]
1835 "split_di (operands + 1, 1, operands + 2, operands + 3);
1836 operands[1] = gen_lowpart (DImode, operands[2]);
1837 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1838 GEN_INT (4)));
1839 ")
1840
1841 (define_insn "*pushdi2_prologue_rex64"
1842 [(set (match_operand:DI 0 "push_operand" "=<")
1843 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1844 (clobber (mem:BLK (scratch)))]
1845 "TARGET_64BIT"
1846 "push{q}\t%1"
1847 [(set_attr "type" "push")
1848 (set_attr "mode" "DI")])
1849
1850 (define_insn "*popdi1_epilogue_rex64"
1851 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1852 (mem:DI (reg:DI 7)))
1853 (set (reg:DI 7)
1854 (plus:DI (reg:DI 7) (const_int 8)))
1855 (clobber (mem:BLK (scratch)))]
1856 "TARGET_64BIT"
1857 "pop{q}\t%0"
1858 [(set_attr "type" "pop")
1859 (set_attr "mode" "DI")])
1860
1861 (define_insn "popdi1"
1862 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1863 (mem:DI (reg:DI 7)))
1864 (set (reg:DI 7)
1865 (plus:DI (reg:DI 7) (const_int 8)))]
1866 "TARGET_64BIT"
1867 "pop{q}\t%0"
1868 [(set_attr "type" "pop")
1869 (set_attr "mode" "DI")])
1870
1871 (define_insn "*movdi_xor_rex64"
1872 [(set (match_operand:DI 0 "register_operand" "=r")
1873 (match_operand:DI 1 "const0_operand" "i"))
1874 (clobber (reg:CC 17))]
1875 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1876 && reload_completed"
1877 "xor{l}\t{%k0, %k0|%k0, %k0}"
1878 [(set_attr "type" "alu1")
1879 (set_attr "mode" "SI")
1880 (set_attr "length_immediate" "0")])
1881
1882 (define_insn "*movdi_or_rex64"
1883 [(set (match_operand:DI 0 "register_operand" "=r")
1884 (match_operand:DI 1 "const_int_operand" "i"))
1885 (clobber (reg:CC 17))]
1886 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1887 && reload_completed
1888 && GET_CODE (operands[1]) == CONST_INT
1889 && INTVAL (operands[1]) == -1"
1890 {
1891 operands[1] = constm1_rtx;
1892 return "or{q}\t{%1, %0|%0, %1}";
1893 }
1894 [(set_attr "type" "alu1")
1895 (set_attr "mode" "DI")
1896 (set_attr "length_immediate" "1")])
1897
1898 (define_insn "*movdi_2"
1899 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1900 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1901 "!TARGET_64BIT
1902 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1903 "@
1904 #
1905 #
1906 movq\t{%1, %0|%0, %1}
1907 movq\t{%1, %0|%0, %1}
1908 movq\t{%1, %0|%0, %1}
1909 movdqa\t{%1, %0|%0, %1}
1910 movq\t{%1, %0|%0, %1}"
1911 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1912 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1913
1914 (define_split
1915 [(set (match_operand:DI 0 "push_operand" "")
1916 (match_operand:DI 1 "general_operand" ""))]
1917 "!TARGET_64BIT && reload_completed
1918 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1919 [(const_int 0)]
1920 "ix86_split_long_move (operands); DONE;")
1921
1922 ;; %%% This multiword shite has got to go.
1923 (define_split
1924 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1925 (match_operand:DI 1 "general_operand" ""))]
1926 "!TARGET_64BIT && reload_completed
1927 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1928 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1929 [(const_int 0)]
1930 "ix86_split_long_move (operands); DONE;")
1931
1932 (define_insn "*movdi_1_rex64"
1933 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
1934 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
1935 "TARGET_64BIT
1936 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1937 {
1938 switch (get_attr_type (insn))
1939 {
1940 case TYPE_SSEMOV:
1941 if (register_operand (operands[0], DImode)
1942 && register_operand (operands[1], DImode))
1943 return "movdqa\t{%1, %0|%0, %1}";
1944 /* FALLTHRU */
1945 case TYPE_MMXMOV:
1946 return "movq\t{%1, %0|%0, %1}";
1947 case TYPE_MULTI:
1948 return "#";
1949 case TYPE_LEA:
1950 return "lea{q}\t{%a1, %0|%0, %a1}";
1951 default:
1952 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1953 abort ();
1954 if (get_attr_mode (insn) == MODE_SI)
1955 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1956 else if (which_alternative == 2)
1957 return "movabs{q}\t{%1, %0|%0, %1}";
1958 else
1959 return "mov{q}\t{%1, %0|%0, %1}";
1960 }
1961 }
1962 [(set (attr "type")
1963 (cond [(eq_attr "alternative" "5,6")
1964 (const_string "mmxmov")
1965 (eq_attr "alternative" "7,8")
1966 (const_string "ssemov")
1967 (eq_attr "alternative" "4")
1968 (const_string "multi")
1969 (and (ne (symbol_ref "flag_pic") (const_int 0))
1970 (match_operand:DI 1 "symbolic_operand" ""))
1971 (const_string "lea")
1972 ]
1973 (const_string "imov")))
1974 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
1975 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
1976 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
1977
1978 ;; Stores and loads of ax to arbitary constant address.
1979 ;; We fake an second form of instruction to force reload to load address
1980 ;; into register when rax is not available
1981 (define_insn "*movabsdi_1_rex64"
1982 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1983 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
1984 "TARGET_64BIT"
1985 "@
1986 movabs{q}\t{%1, %P0|%P0, %1}
1987 mov{q}\t{%1, %a0|%a0, %1}
1988 movabs{q}\t{%1, %a0|%a0, %1}"
1989 [(set_attr "type" "imov")
1990 (set_attr "modrm" "0,*,*")
1991 (set_attr "length_address" "8,0,0")
1992 (set_attr "length_immediate" "0,*,*")
1993 (set_attr "memory" "store")
1994 (set_attr "mode" "DI")])
1995
1996 (define_insn "*movabsdi_2_rex64"
1997 [(set (match_operand:DI 0 "register_operand" "=a,r")
1998 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1999 "TARGET_64BIT"
2000 "@
2001 movabs{q}\t{%P1, %0|%0, %P1}
2002 mov{q}\t{%a1, %0|%0, %a1}"
2003 [(set_attr "type" "imov")
2004 (set_attr "modrm" "0,*")
2005 (set_attr "length_address" "8,0")
2006 (set_attr "length_immediate" "0")
2007 (set_attr "memory" "load")
2008 (set_attr "mode" "DI")])
2009
2010 ;; Convert impossible stores of immediate to existing instructions.
2011 ;; First try to get scratch register and go through it. In case this
2012 ;; fails, move by 32bit parts.
2013 (define_peephole2
2014 [(match_scratch:DI 2 "r")
2015 (set (match_operand:DI 0 "memory_operand" "")
2016 (match_operand:DI 1 "immediate_operand" ""))]
2017 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2018 && !x86_64_immediate_operand (operands[1], DImode)"
2019 [(set (match_dup 2) (match_dup 1))
2020 (set (match_dup 0) (match_dup 2))]
2021 "")
2022
2023 ;; We need to define this as both peepholer and splitter for case
2024 ;; peephole2 pass is not run.
2025 (define_peephole2
2026 [(set (match_operand:DI 0 "memory_operand" "")
2027 (match_operand:DI 1 "immediate_operand" ""))]
2028 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2029 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2030 [(set (match_dup 2) (match_dup 3))
2031 (set (match_dup 4) (match_dup 5))]
2032 "split_di (operands, 2, operands + 2, operands + 4);")
2033
2034 (define_split
2035 [(set (match_operand:DI 0 "memory_operand" "")
2036 (match_operand:DI 1 "immediate_operand" ""))]
2037 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2038 && !symbolic_operand (operands[1], DImode)
2039 && !x86_64_immediate_operand (operands[1], DImode)"
2040 [(set (match_dup 2) (match_dup 3))
2041 (set (match_dup 4) (match_dup 5))]
2042 "split_di (operands, 2, operands + 2, operands + 4);")
2043
2044 (define_insn "*swapdi_rex64"
2045 [(set (match_operand:DI 0 "register_operand" "+r")
2046 (match_operand:DI 1 "register_operand" "+r"))
2047 (set (match_dup 1)
2048 (match_dup 0))]
2049 "TARGET_64BIT"
2050 "xchg{q}\t%1, %0"
2051 [(set_attr "type" "imov")
2052 (set_attr "pent_pair" "np")
2053 (set_attr "athlon_decode" "vector")
2054 (set_attr "mode" "DI")
2055 (set_attr "modrm" "0")
2056 (set_attr "ppro_uops" "few")])
2057
2058
2059 (define_expand "movsf"
2060 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2061 (match_operand:SF 1 "general_operand" ""))]
2062 ""
2063 "ix86_expand_move (SFmode, operands); DONE;")
2064
2065 (define_insn "*pushsf"
2066 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2067 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2068 "!TARGET_64BIT"
2069 {
2070 switch (which_alternative)
2071 {
2072 case 1:
2073 return "push{l}\t%1";
2074
2075 default:
2076 /* This insn should be already splitted before reg-stack. */
2077 abort ();
2078 }
2079 }
2080 [(set_attr "type" "multi,push,multi")
2081 (set_attr "mode" "SF,SI,SF")])
2082
2083 (define_insn "*pushsf_rex64"
2084 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2085 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2086 "TARGET_64BIT"
2087 {
2088 switch (which_alternative)
2089 {
2090 case 1:
2091 return "push{q}\t%q1";
2092
2093 default:
2094 /* This insn should be already splitted before reg-stack. */
2095 abort ();
2096 }
2097 }
2098 [(set_attr "type" "multi,push,multi")
2099 (set_attr "mode" "SF,DI,SF")])
2100
2101 (define_split
2102 [(set (match_operand:SF 0 "push_operand" "")
2103 (match_operand:SF 1 "memory_operand" ""))]
2104 "reload_completed
2105 && GET_CODE (operands[1]) == MEM
2106 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2107 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2108 [(set (match_dup 0)
2109 (match_dup 1))]
2110 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2111
2112
2113 ;; %%% Kill this when call knows how to work this out.
2114 (define_split
2115 [(set (match_operand:SF 0 "push_operand" "")
2116 (match_operand:SF 1 "any_fp_register_operand" ""))]
2117 "!TARGET_64BIT"
2118 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2119 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2120
2121 (define_split
2122 [(set (match_operand:SF 0 "push_operand" "")
2123 (match_operand:SF 1 "any_fp_register_operand" ""))]
2124 "TARGET_64BIT"
2125 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2126 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2127
2128 (define_insn "*movsf_1"
2129 [(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")
2130 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2131 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2132 && (reload_in_progress || reload_completed
2133 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2134 || GET_CODE (operands[1]) != CONST_DOUBLE
2135 || memory_operand (operands[0], SFmode))"
2136 {
2137 switch (which_alternative)
2138 {
2139 case 0:
2140 if (REG_P (operands[1])
2141 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2142 {
2143 if (REGNO (operands[0]) == FIRST_STACK_REG
2144 && TARGET_USE_FFREEP)
2145 return "ffreep\t%y0";
2146 return "fstp\t%y0";
2147 }
2148 else if (STACK_TOP_P (operands[0]))
2149 return "fld%z1\t%y1";
2150 else
2151 return "fst\t%y0";
2152
2153 case 1:
2154 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2155 return "fstp%z0\t%y0";
2156 else
2157 return "fst%z0\t%y0";
2158
2159 case 2:
2160 switch (standard_80387_constant_p (operands[1]))
2161 {
2162 case 1:
2163 return "fldz";
2164 case 2:
2165 return "fld1";
2166 }
2167 abort();
2168
2169 case 3:
2170 case 4:
2171 return "mov{l}\t{%1, %0|%0, %1}";
2172 case 5:
2173 if (get_attr_mode (insn) == MODE_TI)
2174 return "pxor\t%0, %0";
2175 else
2176 return "xorps\t%0, %0";
2177 case 6:
2178 if (get_attr_mode (insn) == MODE_V4SF)
2179 return "movaps\t{%1, %0|%0, %1}";
2180 else
2181 return "movss\t{%1, %0|%0, %1}";
2182 case 7:
2183 case 8:
2184 return "movss\t{%1, %0|%0, %1}";
2185
2186 case 9:
2187 case 10:
2188 return "movd\t{%1, %0|%0, %1}";
2189
2190 case 11:
2191 return "movq\t{%1, %0|%0, %1}";
2192
2193 default:
2194 abort();
2195 }
2196 }
2197 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2198 (set (attr "mode")
2199 (cond [(eq_attr "alternative" "3,4,9,10")
2200 (const_string "SI")
2201 (eq_attr "alternative" "5")
2202 (if_then_else
2203 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2204 (const_int 0))
2205 (ne (symbol_ref "TARGET_SSE2")
2206 (const_int 0)))
2207 (eq (symbol_ref "optimize_size")
2208 (const_int 0)))
2209 (const_string "TI")
2210 (const_string "V4SF"))
2211 /* For architectures resolving dependencies on
2212 whole SSE registers use APS move to break dependency
2213 chains, otherwise use short move to avoid extra work.
2214
2215 Do the same for architectures resolving dependencies on
2216 the parts. While in DF mode it is better to always handle
2217 just register parts, the SF mode is different due to lack
2218 of instructions to load just part of the register. It is
2219 better to maintain the whole registers in single format
2220 to avoid problems on using packed logical operations. */
2221 (eq_attr "alternative" "6")
2222 (if_then_else
2223 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2224 (const_int 0))
2225 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2226 (const_int 0)))
2227 (const_string "V4SF")
2228 (const_string "SF"))
2229 (eq_attr "alternative" "11")
2230 (const_string "DI")]
2231 (const_string "SF")))])
2232
2233 (define_insn "*swapsf"
2234 [(set (match_operand:SF 0 "register_operand" "+f")
2235 (match_operand:SF 1 "register_operand" "+f"))
2236 (set (match_dup 1)
2237 (match_dup 0))]
2238 "reload_completed || !TARGET_SSE"
2239 {
2240 if (STACK_TOP_P (operands[0]))
2241 return "fxch\t%1";
2242 else
2243 return "fxch\t%0";
2244 }
2245 [(set_attr "type" "fxch")
2246 (set_attr "mode" "SF")])
2247
2248 (define_expand "movdf"
2249 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2250 (match_operand:DF 1 "general_operand" ""))]
2251 ""
2252 "ix86_expand_move (DFmode, operands); DONE;")
2253
2254 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2255 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2256 ;; On the average, pushdf using integers can be still shorter. Allow this
2257 ;; pattern for optimize_size too.
2258
2259 (define_insn "*pushdf_nointeger"
2260 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2261 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2262 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2263 {
2264 /* This insn should be already splitted before reg-stack. */
2265 abort ();
2266 }
2267 [(set_attr "type" "multi")
2268 (set_attr "mode" "DF,SI,SI,DF")])
2269
2270 (define_insn "*pushdf_integer"
2271 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2272 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2273 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2274 {
2275 /* This insn should be already splitted before reg-stack. */
2276 abort ();
2277 }
2278 [(set_attr "type" "multi")
2279 (set_attr "mode" "DF,SI,DF")])
2280
2281 ;; %%% Kill this when call knows how to work this out.
2282 (define_split
2283 [(set (match_operand:DF 0 "push_operand" "")
2284 (match_operand:DF 1 "any_fp_register_operand" ""))]
2285 "!TARGET_64BIT && reload_completed"
2286 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2287 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2288 "")
2289
2290 (define_split
2291 [(set (match_operand:DF 0 "push_operand" "")
2292 (match_operand:DF 1 "any_fp_register_operand" ""))]
2293 "TARGET_64BIT && reload_completed"
2294 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2295 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2296 "")
2297
2298 (define_split
2299 [(set (match_operand:DF 0 "push_operand" "")
2300 (match_operand:DF 1 "general_operand" ""))]
2301 "reload_completed"
2302 [(const_int 0)]
2303 "ix86_split_long_move (operands); DONE;")
2304
2305 ;; Moving is usually shorter when only FP registers are used. This separate
2306 ;; movdf pattern avoids the use of integer registers for FP operations
2307 ;; when optimizing for size.
2308
2309 (define_insn "*movdf_nointeger"
2310 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2311 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2312 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2313 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2314 && (reload_in_progress || reload_completed
2315 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2316 || GET_CODE (operands[1]) != CONST_DOUBLE
2317 || memory_operand (operands[0], DFmode))"
2318 {
2319 switch (which_alternative)
2320 {
2321 case 0:
2322 if (REG_P (operands[1])
2323 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2324 {
2325 if (REGNO (operands[0]) == FIRST_STACK_REG
2326 && TARGET_USE_FFREEP)
2327 return "ffreep\t%y0";
2328 return "fstp\t%y0";
2329 }
2330 else if (STACK_TOP_P (operands[0]))
2331 return "fld%z1\t%y1";
2332 else
2333 return "fst\t%y0";
2334
2335 case 1:
2336 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2337 return "fstp%z0\t%y0";
2338 else
2339 return "fst%z0\t%y0";
2340
2341 case 2:
2342 switch (standard_80387_constant_p (operands[1]))
2343 {
2344 case 1:
2345 return "fldz";
2346 case 2:
2347 return "fld1";
2348 }
2349 abort();
2350
2351 case 3:
2352 case 4:
2353 return "#";
2354 case 5:
2355 switch (get_attr_mode (insn))
2356 {
2357 case MODE_V4SF:
2358 return "xorps\t%0, %0";
2359 case MODE_V2DF:
2360 return "xorpd\t%0, %0";
2361 case MODE_TI:
2362 return "pxor\t%0, %0";
2363 default:
2364 abort ();
2365 }
2366 case 6:
2367 switch (get_attr_mode (insn))
2368 {
2369 case MODE_V4SF:
2370 return "movaps\t{%1, %0|%0, %1}";
2371 case MODE_V2DF:
2372 return "movapd\t{%1, %0|%0, %1}";
2373 case MODE_DF:
2374 return "movsd\t{%1, %0|%0, %1}";
2375 default:
2376 abort ();
2377 }
2378 case 7:
2379 if (get_attr_mode (insn) == MODE_V2DF)
2380 return "movlpd\t{%1, %0|%0, %1}";
2381 else
2382 return "movsd\t{%1, %0|%0, %1}";
2383 case 8:
2384 return "movsd\t{%1, %0|%0, %1}";
2385
2386 default:
2387 abort();
2388 }
2389 }
2390 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2391 (set (attr "mode")
2392 (cond [(eq_attr "alternative" "3,4")
2393 (const_string "SI")
2394 /* xorps is one byte shorter. */
2395 (eq_attr "alternative" "5")
2396 (cond [(ne (symbol_ref "optimize_size")
2397 (const_int 0))
2398 (const_string "V4SF")
2399 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2400 (const_int 0))
2401 (const_string "TI")]
2402 (const_string "V2DF"))
2403 /* For architectures resolving dependencies on
2404 whole SSE registers use APD move to break dependency
2405 chains, otherwise use short move to avoid extra work.
2406
2407 movaps encodes one byte shorter. */
2408 (eq_attr "alternative" "6")
2409 (cond
2410 [(ne (symbol_ref "optimize_size")
2411 (const_int 0))
2412 (const_string "V4SF")
2413 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2414 (const_int 0))
2415 (const_string "V2DF")]
2416 (const_string "DF"))
2417 /* For achitectures resolving dependencies on register
2418 parts we may avoid extra work to zero out upper part
2419 of register. */
2420 (eq_attr "alternative" "7")
2421 (if_then_else
2422 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2423 (const_int 0))
2424 (const_string "V2DF")
2425 (const_string "DF"))]
2426 (const_string "DF")))])
2427
2428 (define_insn "*movdf_integer"
2429 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2430 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2431 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2432 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2433 && (reload_in_progress || reload_completed
2434 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2435 || GET_CODE (operands[1]) != CONST_DOUBLE
2436 || memory_operand (operands[0], DFmode))"
2437 {
2438 switch (which_alternative)
2439 {
2440 case 0:
2441 if (REG_P (operands[1])
2442 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2443 {
2444 if (REGNO (operands[0]) == FIRST_STACK_REG
2445 && TARGET_USE_FFREEP)
2446 return "ffreep\t%y0";
2447 return "fstp\t%y0";
2448 }
2449 else if (STACK_TOP_P (operands[0]))
2450 return "fld%z1\t%y1";
2451 else
2452 return "fst\t%y0";
2453
2454 case 1:
2455 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2456 return "fstp%z0\t%y0";
2457 else
2458 return "fst%z0\t%y0";
2459
2460 case 2:
2461 switch (standard_80387_constant_p (operands[1]))
2462 {
2463 case 1:
2464 return "fldz";
2465 case 2:
2466 return "fld1";
2467 }
2468 abort();
2469
2470 case 3:
2471 case 4:
2472 return "#";
2473
2474 case 5:
2475 switch (get_attr_mode (insn))
2476 {
2477 case MODE_V4SF:
2478 return "xorps\t%0, %0";
2479 case MODE_V2DF:
2480 return "xorpd\t%0, %0";
2481 case MODE_TI:
2482 return "pxor\t%0, %0";
2483 default:
2484 abort ();
2485 }
2486 case 6:
2487 switch (get_attr_mode (insn))
2488 {
2489 case MODE_V4SF:
2490 return "movaps\t{%1, %0|%0, %1}";
2491 case MODE_V2DF:
2492 return "movapd\t{%1, %0|%0, %1}";
2493 case MODE_DF:
2494 return "movsd\t{%1, %0|%0, %1}";
2495 default:
2496 abort ();
2497 }
2498 case 7:
2499 if (get_attr_mode (insn) == MODE_V2DF)
2500 return "movlpd\t{%1, %0|%0, %1}";
2501 else
2502 return "movsd\t{%1, %0|%0, %1}";
2503 case 8:
2504 return "movsd\t{%1, %0|%0, %1}";
2505
2506 default:
2507 abort();
2508 }
2509 }
2510 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2511 (set (attr "mode")
2512 (cond [(eq_attr "alternative" "3,4")
2513 (const_string "SI")
2514 /* xorps is one byte shorter. */
2515 (eq_attr "alternative" "5")
2516 (cond [(ne (symbol_ref "optimize_size")
2517 (const_int 0))
2518 (const_string "V4SF")
2519 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2520 (const_int 0))
2521 (const_string "TI")]
2522 (const_string "V2DF"))
2523 /* For architectures resolving dependencies on
2524 whole SSE registers use APD move to break dependency
2525 chains, otherwise use short move to avoid extra work.
2526
2527 movaps encodes one byte shorter. */
2528 (eq_attr "alternative" "6")
2529 (cond
2530 [(ne (symbol_ref "optimize_size")
2531 (const_int 0))
2532 (const_string "V4SF")
2533 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2534 (const_int 0))
2535 (const_string "V2DF")]
2536 (const_string "DF"))
2537 /* For achitectures resolving dependencies on register
2538 parts we may avoid extra work to zero out upper part
2539 of register. */
2540 (eq_attr "alternative" "7")
2541 (if_then_else
2542 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2543 (const_int 0))
2544 (const_string "V2DF")
2545 (const_string "DF"))]
2546 (const_string "DF")))])
2547
2548 (define_split
2549 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2550 (match_operand:DF 1 "general_operand" ""))]
2551 "reload_completed
2552 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2553 && ! (ANY_FP_REG_P (operands[0]) ||
2554 (GET_CODE (operands[0]) == SUBREG
2555 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2556 && ! (ANY_FP_REG_P (operands[1]) ||
2557 (GET_CODE (operands[1]) == SUBREG
2558 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2559 [(const_int 0)]
2560 "ix86_split_long_move (operands); DONE;")
2561
2562 (define_insn "*swapdf"
2563 [(set (match_operand:DF 0 "register_operand" "+f")
2564 (match_operand:DF 1 "register_operand" "+f"))
2565 (set (match_dup 1)
2566 (match_dup 0))]
2567 "reload_completed || !TARGET_SSE2"
2568 {
2569 if (STACK_TOP_P (operands[0]))
2570 return "fxch\t%1";
2571 else
2572 return "fxch\t%0";
2573 }
2574 [(set_attr "type" "fxch")
2575 (set_attr "mode" "DF")])
2576
2577 (define_expand "movxf"
2578 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2579 (match_operand:XF 1 "general_operand" ""))]
2580 "!TARGET_64BIT"
2581 "ix86_expand_move (XFmode, operands); DONE;")
2582
2583 (define_expand "movtf"
2584 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2585 (match_operand:TF 1 "general_operand" ""))]
2586 ""
2587 "ix86_expand_move (TFmode, operands); DONE;")
2588
2589 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2590 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2591 ;; Pushing using integer instructions is longer except for constants
2592 ;; and direct memory references.
2593 ;; (assuming that any given constant is pushed only once, but this ought to be
2594 ;; handled elsewhere).
2595
2596 (define_insn "*pushxf_nointeger"
2597 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2598 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2599 "!TARGET_64BIT && optimize_size"
2600 {
2601 /* This insn should be already splitted before reg-stack. */
2602 abort ();
2603 }
2604 [(set_attr "type" "multi")
2605 (set_attr "mode" "XF,SI,SI")])
2606
2607 (define_insn "*pushtf_nointeger"
2608 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2609 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2610 "optimize_size"
2611 {
2612 /* This insn should be already splitted before reg-stack. */
2613 abort ();
2614 }
2615 [(set_attr "type" "multi")
2616 (set_attr "mode" "XF,SI,SI")])
2617
2618 (define_insn "*pushxf_integer"
2619 [(set (match_operand:XF 0 "push_operand" "=<,<")
2620 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2621 "!TARGET_64BIT && !optimize_size"
2622 {
2623 /* This insn should be already splitted before reg-stack. */
2624 abort ();
2625 }
2626 [(set_attr "type" "multi")
2627 (set_attr "mode" "XF,SI")])
2628
2629 (define_insn "*pushtf_integer"
2630 [(set (match_operand:TF 0 "push_operand" "=<,<")
2631 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2632 "!optimize_size"
2633 {
2634 /* This insn should be already splitted before reg-stack. */
2635 abort ();
2636 }
2637 [(set_attr "type" "multi")
2638 (set_attr "mode" "XF,SI")])
2639
2640 (define_split
2641 [(set (match_operand 0 "push_operand" "")
2642 (match_operand 1 "general_operand" ""))]
2643 "reload_completed
2644 && (GET_MODE (operands[0]) == XFmode
2645 || GET_MODE (operands[0]) == TFmode
2646 || GET_MODE (operands[0]) == DFmode)
2647 && !ANY_FP_REG_P (operands[1])"
2648 [(const_int 0)]
2649 "ix86_split_long_move (operands); DONE;")
2650
2651 (define_split
2652 [(set (match_operand:XF 0 "push_operand" "")
2653 (match_operand:XF 1 "any_fp_register_operand" ""))]
2654 "!TARGET_64BIT"
2655 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2656 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2657
2658 (define_split
2659 [(set (match_operand:TF 0 "push_operand" "")
2660 (match_operand:TF 1 "any_fp_register_operand" ""))]
2661 "!TARGET_64BIT"
2662 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2663 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2664
2665 (define_split
2666 [(set (match_operand:TF 0 "push_operand" "")
2667 (match_operand:TF 1 "any_fp_register_operand" ""))]
2668 "TARGET_64BIT"
2669 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2670 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2671
2672 ;; Do not use integer registers when optimizing for size
2673 (define_insn "*movxf_nointeger"
2674 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2675 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2676 "!TARGET_64BIT
2677 && optimize_size
2678 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2679 && (reload_in_progress || reload_completed
2680 || GET_CODE (operands[1]) != CONST_DOUBLE
2681 || memory_operand (operands[0], XFmode))"
2682 {
2683 switch (which_alternative)
2684 {
2685 case 0:
2686 if (REG_P (operands[1])
2687 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2688 {
2689 if (REGNO (operands[0]) == FIRST_STACK_REG
2690 && TARGET_USE_FFREEP)
2691 return "ffreep\t%y0";
2692 return "fstp\t%y0";
2693 }
2694 else if (STACK_TOP_P (operands[0]))
2695 return "fld%z1\t%y1";
2696 else
2697 return "fst\t%y0";
2698
2699 case 1:
2700 /* There is no non-popping store to memory for XFmode. So if
2701 we need one, follow the store with a load. */
2702 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2703 return "fstp%z0\t%y0\;fld%z0\t%y0";
2704 else
2705 return "fstp%z0\t%y0";
2706
2707 case 2:
2708 switch (standard_80387_constant_p (operands[1]))
2709 {
2710 case 1:
2711 return "fldz";
2712 case 2:
2713 return "fld1";
2714 }
2715 break;
2716
2717 case 3: case 4:
2718 return "#";
2719 }
2720 abort();
2721 }
2722 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2723 (set_attr "mode" "XF,XF,XF,SI,SI")])
2724
2725 (define_insn "*movtf_nointeger"
2726 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2727 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2728 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2729 && optimize_size
2730 && (reload_in_progress || reload_completed
2731 || GET_CODE (operands[1]) != CONST_DOUBLE
2732 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2733 || memory_operand (operands[0], TFmode))"
2734 {
2735 switch (which_alternative)
2736 {
2737 case 0:
2738 if (REG_P (operands[1])
2739 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2740 {
2741 if (REGNO (operands[0]) == FIRST_STACK_REG
2742 && TARGET_USE_FFREEP)
2743 return "ffreep\t%y0";
2744 return "fstp\t%y0";
2745 }
2746 else if (STACK_TOP_P (operands[0]))
2747 return "fld%z1\t%y1";
2748 else
2749 return "fst\t%y0";
2750
2751 case 1:
2752 /* There is no non-popping store to memory for XFmode. So if
2753 we need one, follow the store with a load. */
2754 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2755 return "fstp%z0\t%y0\;fld%z0\t%y0";
2756 else
2757 return "fstp%z0\t%y0";
2758
2759 case 2:
2760 switch (standard_80387_constant_p (operands[1]))
2761 {
2762 case 1:
2763 return "fldz";
2764 case 2:
2765 return "fld1";
2766 }
2767 break;
2768
2769 case 3: case 4:
2770 return "#";
2771 }
2772 abort();
2773 }
2774 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2775 (set_attr "mode" "XF,XF,XF,SI,SI")])
2776
2777 (define_insn "*movxf_integer"
2778 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2779 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2780 "!TARGET_64BIT
2781 && !optimize_size
2782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2783 && (reload_in_progress || reload_completed
2784 || GET_CODE (operands[1]) != CONST_DOUBLE
2785 || memory_operand (operands[0], XFmode))"
2786 {
2787 switch (which_alternative)
2788 {
2789 case 0:
2790 if (REG_P (operands[1])
2791 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2792 {
2793 if (REGNO (operands[0]) == FIRST_STACK_REG
2794 && TARGET_USE_FFREEP)
2795 return "ffreep\t%y0";
2796 return "fstp\t%y0";
2797 }
2798 else if (STACK_TOP_P (operands[0]))
2799 return "fld%z1\t%y1";
2800 else
2801 return "fst\t%y0";
2802
2803 case 1:
2804 /* There is no non-popping store to memory for XFmode. So if
2805 we need one, follow the store with a load. */
2806 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2807 return "fstp%z0\t%y0\;fld%z0\t%y0";
2808 else
2809 return "fstp%z0\t%y0";
2810
2811 case 2:
2812 switch (standard_80387_constant_p (operands[1]))
2813 {
2814 case 1:
2815 return "fldz";
2816 case 2:
2817 return "fld1";
2818 }
2819 break;
2820
2821 case 3: case 4:
2822 return "#";
2823 }
2824 abort();
2825 }
2826 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2827 (set_attr "mode" "XF,XF,XF,SI,SI")])
2828
2829 (define_insn "*movtf_integer"
2830 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2831 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2832 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2833 && !optimize_size
2834 && (reload_in_progress || reload_completed
2835 || GET_CODE (operands[1]) != CONST_DOUBLE
2836 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2837 || memory_operand (operands[0], TFmode))"
2838 {
2839 switch (which_alternative)
2840 {
2841 case 0:
2842 if (REG_P (operands[1])
2843 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2844 {
2845 if (REGNO (operands[0]) == FIRST_STACK_REG
2846 && TARGET_USE_FFREEP)
2847 return "ffreep\t%y0";
2848 return "fstp\t%y0";
2849 }
2850 else if (STACK_TOP_P (operands[0]))
2851 return "fld%z1\t%y1";
2852 else
2853 return "fst\t%y0";
2854
2855 case 1:
2856 /* There is no non-popping store to memory for XFmode. So if
2857 we need one, follow the store with a load. */
2858 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2859 return "fstp%z0\t%y0\;fld%z0\t%y0";
2860 else
2861 return "fstp%z0\t%y0";
2862
2863 case 2:
2864 switch (standard_80387_constant_p (operands[1]))
2865 {
2866 case 1:
2867 return "fldz";
2868 case 2:
2869 return "fld1";
2870 }
2871 break;
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_split
2882 [(set (match_operand 0 "nonimmediate_operand" "")
2883 (match_operand 1 "general_operand" ""))]
2884 "reload_completed
2885 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2886 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
2887 && ! (ANY_FP_REG_P (operands[0]) ||
2888 (GET_CODE (operands[0]) == SUBREG
2889 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2890 && ! (ANY_FP_REG_P (operands[1]) ||
2891 (GET_CODE (operands[1]) == SUBREG
2892 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2893 [(const_int 0)]
2894 "ix86_split_long_move (operands); DONE;")
2895
2896 (define_split
2897 [(set (match_operand 0 "register_operand" "")
2898 (match_operand 1 "memory_operand" ""))]
2899 "reload_completed
2900 && GET_CODE (operands[1]) == MEM
2901 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
2902 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2903 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2904 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2905 && (!(SSE_REG_P (operands[0]) ||
2906 (GET_CODE (operands[0]) == SUBREG
2907 && SSE_REG_P (SUBREG_REG (operands[0]))))
2908 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
2909 && (!(FP_REG_P (operands[0]) ||
2910 (GET_CODE (operands[0]) == SUBREG
2911 && FP_REG_P (SUBREG_REG (operands[0]))))
2912 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2913 [(set (match_dup 0)
2914 (match_dup 1))]
2915 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2916
2917 (define_insn "swapxf"
2918 [(set (match_operand:XF 0 "register_operand" "+f")
2919 (match_operand:XF 1 "register_operand" "+f"))
2920 (set (match_dup 1)
2921 (match_dup 0))]
2922 ""
2923 {
2924 if (STACK_TOP_P (operands[0]))
2925 return "fxch\t%1";
2926 else
2927 return "fxch\t%0";
2928 }
2929 [(set_attr "type" "fxch")
2930 (set_attr "mode" "XF")])
2931
2932 (define_insn "swaptf"
2933 [(set (match_operand:TF 0 "register_operand" "+f")
2934 (match_operand:TF 1 "register_operand" "+f"))
2935 (set (match_dup 1)
2936 (match_dup 0))]
2937 ""
2938 {
2939 if (STACK_TOP_P (operands[0]))
2940 return "fxch\t%1";
2941 else
2942 return "fxch\t%0";
2943 }
2944 [(set_attr "type" "fxch")
2945 (set_attr "mode" "XF")])
2946 \f
2947 ;; Zero extension instructions
2948
2949 (define_expand "zero_extendhisi2"
2950 [(set (match_operand:SI 0 "register_operand" "")
2951 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2952 ""
2953 {
2954 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2955 {
2956 operands[1] = force_reg (HImode, operands[1]);
2957 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2958 DONE;
2959 }
2960 })
2961
2962 (define_insn "zero_extendhisi2_and"
2963 [(set (match_operand:SI 0 "register_operand" "=r")
2964 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2965 (clobber (reg:CC 17))]
2966 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2967 "#"
2968 [(set_attr "type" "alu1")
2969 (set_attr "mode" "SI")])
2970
2971 (define_split
2972 [(set (match_operand:SI 0 "register_operand" "")
2973 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2974 (clobber (reg:CC 17))]
2975 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2976 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2977 (clobber (reg:CC 17))])]
2978 "")
2979
2980 (define_insn "*zero_extendhisi2_movzwl"
2981 [(set (match_operand:SI 0 "register_operand" "=r")
2982 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2983 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2984 "movz{wl|x}\t{%1, %0|%0, %1}"
2985 [(set_attr "type" "imovx")
2986 (set_attr "mode" "SI")])
2987
2988 (define_expand "zero_extendqihi2"
2989 [(parallel
2990 [(set (match_operand:HI 0 "register_operand" "")
2991 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2992 (clobber (reg:CC 17))])]
2993 ""
2994 "")
2995
2996 (define_insn "*zero_extendqihi2_and"
2997 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2998 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2999 (clobber (reg:CC 17))]
3000 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3001 "#"
3002 [(set_attr "type" "alu1")
3003 (set_attr "mode" "HI")])
3004
3005 (define_insn "*zero_extendqihi2_movzbw_and"
3006 [(set (match_operand:HI 0 "register_operand" "=r,r")
3007 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3008 (clobber (reg:CC 17))]
3009 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3010 "#"
3011 [(set_attr "type" "imovx,alu1")
3012 (set_attr "mode" "HI")])
3013
3014 (define_insn "*zero_extendqihi2_movzbw"
3015 [(set (match_operand:HI 0 "register_operand" "=r")
3016 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3017 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3018 "movz{bw|x}\t{%1, %0|%0, %1}"
3019 [(set_attr "type" "imovx")
3020 (set_attr "mode" "HI")])
3021
3022 ;; For the movzbw case strip only the clobber
3023 (define_split
3024 [(set (match_operand:HI 0 "register_operand" "")
3025 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3026 (clobber (reg:CC 17))]
3027 "reload_completed
3028 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3029 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3030 [(set (match_operand:HI 0 "register_operand" "")
3031 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3032
3033 ;; When source and destination does not overlap, clear destination
3034 ;; first and then do the movb
3035 (define_split
3036 [(set (match_operand:HI 0 "register_operand" "")
3037 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3038 (clobber (reg:CC 17))]
3039 "reload_completed
3040 && ANY_QI_REG_P (operands[0])
3041 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3042 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3043 [(set (match_dup 0) (const_int 0))
3044 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3045 "operands[2] = gen_lowpart (QImode, operands[0]);")
3046
3047 ;; Rest is handled by single and.
3048 (define_split
3049 [(set (match_operand:HI 0 "register_operand" "")
3050 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3051 (clobber (reg:CC 17))]
3052 "reload_completed
3053 && true_regnum (operands[0]) == true_regnum (operands[1])"
3054 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3055 (clobber (reg:CC 17))])]
3056 "")
3057
3058 (define_expand "zero_extendqisi2"
3059 [(parallel
3060 [(set (match_operand:SI 0 "register_operand" "")
3061 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3062 (clobber (reg:CC 17))])]
3063 ""
3064 "")
3065
3066 (define_insn "*zero_extendqisi2_and"
3067 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3068 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3069 (clobber (reg:CC 17))]
3070 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3071 "#"
3072 [(set_attr "type" "alu1")
3073 (set_attr "mode" "SI")])
3074
3075 (define_insn "*zero_extendqisi2_movzbw_and"
3076 [(set (match_operand:SI 0 "register_operand" "=r,r")
3077 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3078 (clobber (reg:CC 17))]
3079 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3080 "#"
3081 [(set_attr "type" "imovx,alu1")
3082 (set_attr "mode" "SI")])
3083
3084 (define_insn "*zero_extendqisi2_movzbw"
3085 [(set (match_operand:SI 0 "register_operand" "=r")
3086 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3087 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3088 "movz{bl|x}\t{%1, %0|%0, %1}"
3089 [(set_attr "type" "imovx")
3090 (set_attr "mode" "SI")])
3091
3092 ;; For the movzbl case strip only the clobber
3093 (define_split
3094 [(set (match_operand:SI 0 "register_operand" "")
3095 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3096 (clobber (reg:CC 17))]
3097 "reload_completed
3098 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3099 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3100 [(set (match_dup 0)
3101 (zero_extend:SI (match_dup 1)))])
3102
3103 ;; When source and destination does not overlap, clear destination
3104 ;; first and then do the movb
3105 (define_split
3106 [(set (match_operand:SI 0 "register_operand" "")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3108 (clobber (reg:CC 17))]
3109 "reload_completed
3110 && ANY_QI_REG_P (operands[0])
3111 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3112 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3113 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3114 [(set (match_dup 0) (const_int 0))
3115 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3116 "operands[2] = gen_lowpart (QImode, operands[0]);")
3117
3118 ;; Rest is handled by single and.
3119 (define_split
3120 [(set (match_operand:SI 0 "register_operand" "")
3121 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3122 (clobber (reg:CC 17))]
3123 "reload_completed
3124 && true_regnum (operands[0]) == true_regnum (operands[1])"
3125 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3126 (clobber (reg:CC 17))])]
3127 "")
3128
3129 ;; %%% Kill me once multi-word ops are sane.
3130 (define_expand "zero_extendsidi2"
3131 [(set (match_operand:DI 0 "register_operand" "=r")
3132 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3133 ""
3134 "if (!TARGET_64BIT)
3135 {
3136 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3137 DONE;
3138 }
3139 ")
3140
3141 (define_insn "zero_extendsidi2_32"
3142 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3143 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3144 (clobber (reg:CC 17))]
3145 "!TARGET_64BIT"
3146 "#"
3147 [(set_attr "mode" "SI")])
3148
3149 (define_insn "zero_extendsidi2_rex64"
3150 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3151 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3152 "TARGET_64BIT"
3153 "@
3154 mov\t{%k1, %k0|%k0, %k1}
3155 #"
3156 [(set_attr "type" "imovx,imov")
3157 (set_attr "mode" "SI,DI")])
3158
3159 (define_split
3160 [(set (match_operand:DI 0 "memory_operand" "")
3161 (zero_extend:DI (match_dup 0)))]
3162 "TARGET_64BIT"
3163 [(set (match_dup 4) (const_int 0))]
3164 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3165
3166 (define_split
3167 [(set (match_operand:DI 0 "register_operand" "")
3168 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3169 (clobber (reg:CC 17))]
3170 "!TARGET_64BIT && reload_completed
3171 && true_regnum (operands[0]) == true_regnum (operands[1])"
3172 [(set (match_dup 4) (const_int 0))]
3173 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3174
3175 (define_split
3176 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3177 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3178 (clobber (reg:CC 17))]
3179 "!TARGET_64BIT && reload_completed"
3180 [(set (match_dup 3) (match_dup 1))
3181 (set (match_dup 4) (const_int 0))]
3182 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3183
3184 (define_insn "zero_extendhidi2"
3185 [(set (match_operand:DI 0 "register_operand" "=r,r")
3186 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3187 "TARGET_64BIT"
3188 "@
3189 movz{wl|x}\t{%1, %k0|%k0, %1}
3190 movz{wq|x}\t{%1, %0|%0, %1}"
3191 [(set_attr "type" "imovx")
3192 (set_attr "mode" "SI,DI")])
3193
3194 (define_insn "zero_extendqidi2"
3195 [(set (match_operand:DI 0 "register_operand" "=r,r")
3196 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3197 "TARGET_64BIT"
3198 "@
3199 movz{bl|x}\t{%1, %k0|%k0, %1}
3200 movz{bq|x}\t{%1, %0|%0, %1}"
3201 [(set_attr "type" "imovx")
3202 (set_attr "mode" "SI,DI")])
3203 \f
3204 ;; Sign extension instructions
3205
3206 (define_expand "extendsidi2"
3207 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3208 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3209 (clobber (reg:CC 17))
3210 (clobber (match_scratch:SI 2 ""))])]
3211 ""
3212 {
3213 if (TARGET_64BIT)
3214 {
3215 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3216 DONE;
3217 }
3218 })
3219
3220 (define_insn "*extendsidi2_1"
3221 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3222 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3223 (clobber (reg:CC 17))
3224 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3225 "!TARGET_64BIT"
3226 "#")
3227
3228 (define_insn "extendsidi2_rex64"
3229 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3230 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3231 "TARGET_64BIT"
3232 "@
3233 {cltq|cdqe}
3234 movs{lq|x}\t{%1,%0|%0, %1}"
3235 [(set_attr "type" "imovx")
3236 (set_attr "mode" "DI")
3237 (set_attr "prefix_0f" "0")
3238 (set_attr "modrm" "0,1")])
3239
3240 (define_insn "extendhidi2"
3241 [(set (match_operand:DI 0 "register_operand" "=r")
3242 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243 "TARGET_64BIT"
3244 "movs{wq|x}\t{%1,%0|%0, %1}"
3245 [(set_attr "type" "imovx")
3246 (set_attr "mode" "DI")])
3247
3248 (define_insn "extendqidi2"
3249 [(set (match_operand:DI 0 "register_operand" "=r")
3250 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3251 "TARGET_64BIT"
3252 "movs{bq|x}\t{%1,%0|%0, %1}"
3253 [(set_attr "type" "imovx")
3254 (set_attr "mode" "DI")])
3255
3256 ;; Extend to memory case when source register does die.
3257 (define_split
3258 [(set (match_operand:DI 0 "memory_operand" "")
3259 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3260 (clobber (reg:CC 17))
3261 (clobber (match_operand:SI 2 "register_operand" ""))]
3262 "(reload_completed
3263 && dead_or_set_p (insn, operands[1])
3264 && !reg_mentioned_p (operands[1], operands[0]))"
3265 [(set (match_dup 3) (match_dup 1))
3266 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3267 (clobber (reg:CC 17))])
3268 (set (match_dup 4) (match_dup 1))]
3269 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3270
3271 ;; Extend to memory case when source register does not die.
3272 (define_split
3273 [(set (match_operand:DI 0 "memory_operand" "")
3274 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3275 (clobber (reg:CC 17))
3276 (clobber (match_operand:SI 2 "register_operand" ""))]
3277 "reload_completed"
3278 [(const_int 0)]
3279 {
3280 split_di (&operands[0], 1, &operands[3], &operands[4]);
3281
3282 emit_move_insn (operands[3], operands[1]);
3283
3284 /* Generate a cltd if possible and doing so it profitable. */
3285 if (true_regnum (operands[1]) == 0
3286 && true_regnum (operands[2]) == 1
3287 && (optimize_size || TARGET_USE_CLTD))
3288 {
3289 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3290 }
3291 else
3292 {
3293 emit_move_insn (operands[2], operands[1]);
3294 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3295 }
3296 emit_move_insn (operands[4], operands[2]);
3297 DONE;
3298 })
3299
3300 ;; Extend to register case. Optimize case where source and destination
3301 ;; registers match and cases where we can use cltd.
3302 (define_split
3303 [(set (match_operand:DI 0 "register_operand" "")
3304 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305 (clobber (reg:CC 17))
3306 (clobber (match_scratch:SI 2 ""))]
3307 "reload_completed"
3308 [(const_int 0)]
3309 {
3310 split_di (&operands[0], 1, &operands[3], &operands[4]);
3311
3312 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3313 emit_move_insn (operands[3], operands[1]);
3314
3315 /* Generate a cltd if possible and doing so it profitable. */
3316 if (true_regnum (operands[3]) == 0
3317 && (optimize_size || TARGET_USE_CLTD))
3318 {
3319 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3320 DONE;
3321 }
3322
3323 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3324 emit_move_insn (operands[4], operands[1]);
3325
3326 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3327 DONE;
3328 })
3329
3330 (define_insn "extendhisi2"
3331 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3332 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3333 ""
3334 {
3335 switch (get_attr_prefix_0f (insn))
3336 {
3337 case 0:
3338 return "{cwtl|cwde}";
3339 default:
3340 return "movs{wl|x}\t{%1,%0|%0, %1}";
3341 }
3342 }
3343 [(set_attr "type" "imovx")
3344 (set_attr "mode" "SI")
3345 (set (attr "prefix_0f")
3346 ;; movsx is short decodable while cwtl is vector decoded.
3347 (if_then_else (and (eq_attr "cpu" "!k6")
3348 (eq_attr "alternative" "0"))
3349 (const_string "0")
3350 (const_string "1")))
3351 (set (attr "modrm")
3352 (if_then_else (eq_attr "prefix_0f" "0")
3353 (const_string "0")
3354 (const_string "1")))])
3355
3356 (define_insn "*extendhisi2_zext"
3357 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3358 (zero_extend:DI
3359 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3360 "TARGET_64BIT"
3361 {
3362 switch (get_attr_prefix_0f (insn))
3363 {
3364 case 0:
3365 return "{cwtl|cwde}";
3366 default:
3367 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3368 }
3369 }
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI")
3372 (set (attr "prefix_0f")
3373 ;; movsx is short decodable while cwtl is vector decoded.
3374 (if_then_else (and (eq_attr "cpu" "!k6")
3375 (eq_attr "alternative" "0"))
3376 (const_string "0")
3377 (const_string "1")))
3378 (set (attr "modrm")
3379 (if_then_else (eq_attr "prefix_0f" "0")
3380 (const_string "0")
3381 (const_string "1")))])
3382
3383 (define_insn "extendqihi2"
3384 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3385 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3386 ""
3387 {
3388 switch (get_attr_prefix_0f (insn))
3389 {
3390 case 0:
3391 return "{cbtw|cbw}";
3392 default:
3393 return "movs{bw|x}\t{%1,%0|%0, %1}";
3394 }
3395 }
3396 [(set_attr "type" "imovx")
3397 (set_attr "mode" "HI")
3398 (set (attr "prefix_0f")
3399 ;; movsx is short decodable while cwtl is vector decoded.
3400 (if_then_else (and (eq_attr "cpu" "!k6")
3401 (eq_attr "alternative" "0"))
3402 (const_string "0")
3403 (const_string "1")))
3404 (set (attr "modrm")
3405 (if_then_else (eq_attr "prefix_0f" "0")
3406 (const_string "0")
3407 (const_string "1")))])
3408
3409 (define_insn "extendqisi2"
3410 [(set (match_operand:SI 0 "register_operand" "=r")
3411 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3412 ""
3413 "movs{bl|x}\t{%1,%0|%0, %1}"
3414 [(set_attr "type" "imovx")
3415 (set_attr "mode" "SI")])
3416
3417 (define_insn "*extendqisi2_zext"
3418 [(set (match_operand:DI 0 "register_operand" "=r")
3419 (zero_extend:DI
3420 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3421 "TARGET_64BIT"
3422 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3423 [(set_attr "type" "imovx")
3424 (set_attr "mode" "SI")])
3425 \f
3426 ;; Conversions between float and double.
3427
3428 ;; These are all no-ops in the model used for the 80387. So just
3429 ;; emit moves.
3430
3431 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3432 (define_insn "*dummy_extendsfdf2"
3433 [(set (match_operand:DF 0 "push_operand" "=<")
3434 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3435 "0"
3436 "#")
3437
3438 (define_split
3439 [(set (match_operand:DF 0 "push_operand" "")
3440 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3441 "!TARGET_64BIT"
3442 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3443 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3444
3445 (define_split
3446 [(set (match_operand:DF 0 "push_operand" "")
3447 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3448 "TARGET_64BIT"
3449 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3450 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3451
3452 (define_insn "*dummy_extendsfxf2"
3453 [(set (match_operand:XF 0 "push_operand" "=<")
3454 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3455 "0"
3456 "#")
3457
3458 (define_split
3459 [(set (match_operand:XF 0 "push_operand" "")
3460 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461 "!TARGET_64BIT"
3462 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3463 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3464
3465 (define_insn "*dummy_extendsftf2"
3466 [(set (match_operand:TF 0 "push_operand" "=<")
3467 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3468 "0"
3469 "#")
3470
3471 (define_split
3472 [(set (match_operand:TF 0 "push_operand" "")
3473 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3474 "!TARGET_64BIT"
3475 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3476 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3477
3478 (define_split
3479 [(set (match_operand:TF 0 "push_operand" "")
3480 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3481 "TARGET_64BIT"
3482 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3483 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3484
3485 (define_insn "*dummy_extenddfxf2"
3486 [(set (match_operand:XF 0 "push_operand" "=<")
3487 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3488 "0"
3489 "#")
3490
3491 (define_split
3492 [(set (match_operand:XF 0 "push_operand" "")
3493 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3494 "!TARGET_64BIT"
3495 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3496 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3497
3498 (define_insn "*dummy_extenddftf2"
3499 [(set (match_operand:TF 0 "push_operand" "=<")
3500 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3501 "0"
3502 "#")
3503
3504 (define_split
3505 [(set (match_operand:TF 0 "push_operand" "")
3506 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3507 "!TARGET_64BIT"
3508 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3509 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3510
3511 (define_split
3512 [(set (match_operand:TF 0 "push_operand" "")
3513 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3514 "TARGET_64BIT"
3515 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3516 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3517
3518 (define_expand "extendsfdf2"
3519 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3520 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3521 "TARGET_80387 || TARGET_SSE2"
3522 {
3523 /* ??? Needed for compress_float_constant since all fp constants
3524 are LEGITIMATE_CONSTANT_P. */
3525 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3526 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3527 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3528 operands[1] = force_reg (SFmode, operands[1]);
3529 })
3530
3531 (define_insn "*extendsfdf2_1"
3532 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3533 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3534 "(TARGET_80387 || TARGET_SSE2)
3535 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3536 {
3537 switch (which_alternative)
3538 {
3539 case 0:
3540 if (REG_P (operands[1])
3541 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3542 return "fstp\t%y0";
3543 else if (STACK_TOP_P (operands[0]))
3544 return "fld%z1\t%y1";
3545 else
3546 return "fst\t%y0";
3547
3548 case 1:
3549 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3550 return "fstp%z0\t%y0";
3551
3552 else
3553 return "fst%z0\t%y0";
3554 case 2:
3555 return "cvtss2sd\t{%1, %0|%0, %1}";
3556
3557 default:
3558 abort ();
3559 }
3560 }
3561 [(set_attr "type" "fmov,fmov,ssecvt")
3562 (set_attr "mode" "SF,XF,DF")])
3563
3564 (define_insn "*extendsfdf2_1_sse_only"
3565 [(set (match_operand:DF 0 "register_operand" "=Y")
3566 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3567 "!TARGET_80387 && TARGET_SSE2
3568 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3569 "cvtss2sd\t{%1, %0|%0, %1}"
3570 [(set_attr "type" "ssecvt")
3571 (set_attr "mode" "DF")])
3572
3573 (define_expand "extendsfxf2"
3574 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3575 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3576 "!TARGET_64BIT && TARGET_80387"
3577 {
3578 /* ??? Needed for compress_float_constant since all fp constants
3579 are LEGITIMATE_CONSTANT_P. */
3580 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3581 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3582 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3583 operands[1] = force_reg (SFmode, operands[1]);
3584 })
3585
3586 (define_insn "*extendsfxf2_1"
3587 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3588 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3589 "!TARGET_64BIT && TARGET_80387
3590 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3591 {
3592 switch (which_alternative)
3593 {
3594 case 0:
3595 if (REG_P (operands[1])
3596 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3597 return "fstp\t%y0";
3598 else if (STACK_TOP_P (operands[0]))
3599 return "fld%z1\t%y1";
3600 else
3601 return "fst\t%y0";
3602
3603 case 1:
3604 /* There is no non-popping store to memory for XFmode. So if
3605 we need one, follow the store with a load. */
3606 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3607 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3608 else
3609 return "fstp%z0\t%y0";
3610
3611 default:
3612 abort ();
3613 }
3614 }
3615 [(set_attr "type" "fmov")
3616 (set_attr "mode" "SF,XF")])
3617
3618 (define_expand "extendsftf2"
3619 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3620 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3621 "TARGET_80387"
3622 {
3623 /* ??? Needed for compress_float_constant since all fp constants
3624 are LEGITIMATE_CONSTANT_P. */
3625 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3626 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3627 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3628 operands[1] = force_reg (SFmode, operands[1]);
3629 })
3630
3631 (define_insn "*extendsftf2_1"
3632 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3633 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3634 "TARGET_80387
3635 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3636 {
3637 switch (which_alternative)
3638 {
3639 case 0:
3640 if (REG_P (operands[1])
3641 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3642 return "fstp\t%y0";
3643 else if (STACK_TOP_P (operands[0]))
3644 return "fld%z1\t%y1";
3645 else
3646 return "fst\t%y0";
3647
3648 case 1:
3649 /* There is no non-popping store to memory for XFmode. So if
3650 we need one, follow the store with a load. */
3651 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3652 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3653 else
3654 return "fstp%z0\t%y0";
3655
3656 default:
3657 abort ();
3658 }
3659 }
3660 [(set_attr "type" "fmov")
3661 (set_attr "mode" "SF,XF")])
3662
3663 (define_expand "extenddfxf2"
3664 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3665 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3666 "!TARGET_64BIT && TARGET_80387"
3667 {
3668 /* ??? Needed for compress_float_constant since all fp constants
3669 are LEGITIMATE_CONSTANT_P. */
3670 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3671 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3672 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3673 operands[1] = force_reg (DFmode, operands[1]);
3674 })
3675
3676 (define_insn "*extenddfxf2_1"
3677 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3678 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3679 "!TARGET_64BIT && TARGET_80387
3680 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3681 {
3682 switch (which_alternative)
3683 {
3684 case 0:
3685 if (REG_P (operands[1])
3686 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3687 return "fstp\t%y0";
3688 else if (STACK_TOP_P (operands[0]))
3689 return "fld%z1\t%y1";
3690 else
3691 return "fst\t%y0";
3692
3693 case 1:
3694 /* There is no non-popping store to memory for XFmode. So if
3695 we need one, follow the store with a load. */
3696 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3698 else
3699 return "fstp%z0\t%y0";
3700
3701 default:
3702 abort ();
3703 }
3704 }
3705 [(set_attr "type" "fmov")
3706 (set_attr "mode" "DF,XF")])
3707
3708 (define_expand "extenddftf2"
3709 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3710 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3711 "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 (DFmode, operands[1]));
3717 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3718 operands[1] = force_reg (DFmode, operands[1]);
3719 })
3720
3721 (define_insn "*extenddftf2_1"
3722 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3723 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3724 "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" "DF,XF")])
3752
3753 ;; %%% This seems bad bad news.
3754 ;; This cannot output into an f-reg because there is no way to be sure
3755 ;; of truncating in that case. Otherwise this is just like a simple move
3756 ;; insn. So we pretend we can output to a reg in order to get better
3757 ;; register preferencing, but we really use a stack slot.
3758
3759 (define_expand "truncdfsf2"
3760 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3761 (float_truncate:SF
3762 (match_operand:DF 1 "register_operand" "")))
3763 (clobber (match_dup 2))])]
3764 "TARGET_80387 || TARGET_SSE2"
3765 "
3766 if (TARGET_80387)
3767 operands[2] = assign_386_stack_local (SFmode, 0);
3768 else
3769 {
3770 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3771 DONE;
3772 }
3773 ")
3774
3775 (define_insn "*truncdfsf2_1"
3776 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3777 (float_truncate:SF
3778 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3779 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3780 "TARGET_80387 && !TARGET_SSE2"
3781 {
3782 switch (which_alternative)
3783 {
3784 case 0:
3785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786 return "fstp%z0\t%y0";
3787 else
3788 return "fst%z0\t%y0";
3789 default:
3790 abort ();
3791 }
3792 }
3793 [(set_attr "type" "fmov,multi,multi,multi")
3794 (set_attr "mode" "SF,SF,SF,SF")])
3795
3796 (define_insn "*truncdfsf2_1_sse"
3797 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3798 (float_truncate:SF
3799 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3800 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3801 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3802 {
3803 switch (which_alternative)
3804 {
3805 case 0:
3806 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3807 return "fstp%z0\t%y0";
3808 else
3809 return "fst%z0\t%y0";
3810 case 4:
3811 return "#";
3812 default:
3813 abort ();
3814 }
3815 }
3816 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3817 (set_attr "mode" "SF,SF,SF,SF,DF")])
3818
3819 (define_insn "*truncdfsf2_1_sse_nooverlap"
3820 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3821 (float_truncate:SF
3822 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3823 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3824 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3825 {
3826 switch (which_alternative)
3827 {
3828 case 0:
3829 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3830 return "fstp%z0\t%y0";
3831 else
3832 return "fst%z0\t%y0";
3833 case 4:
3834 return "#";
3835 default:
3836 abort ();
3837 }
3838 }
3839 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3840 (set_attr "mode" "SF,SF,SF,SF,DF")])
3841
3842 (define_insn "*truncdfsf2_2"
3843 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
3844 (float_truncate:SF
3845 (match_operand:DF 1 "nonimmediate_operand" "mY,f#Y")))]
3846 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3847 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3848 {
3849 switch (which_alternative)
3850 {
3851 case 0:
3852 return "cvtsd2ss\t{%1, %0|%0, %1}";
3853 case 1:
3854 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3855 return "fstp%z0\t%y0";
3856 else
3857 return "fst%z0\t%y0";
3858 default:
3859 abort ();
3860 }
3861 }
3862 [(set_attr "type" "ssecvt,fmov")
3863 (set_attr "mode" "DF,SF")])
3864
3865 (define_insn "*truncdfsf2_2_nooverlap"
3866 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3867 (float_truncate:SF
3868 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3869 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3871 {
3872 switch (which_alternative)
3873 {
3874 case 0:
3875 return "#";
3876 case 1:
3877 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3878 return "fstp%z0\t%y0";
3879 else
3880 return "fst%z0\t%y0";
3881 default:
3882 abort ();
3883 }
3884 }
3885 [(set_attr "type" "ssecvt,fmov")
3886 (set_attr "mode" "DF,SF")])
3887
3888 (define_insn "*truncdfsf2_3"
3889 [(set (match_operand:SF 0 "memory_operand" "=m")
3890 (float_truncate:SF
3891 (match_operand:DF 1 "register_operand" "f")))]
3892 "TARGET_80387"
3893 {
3894 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3895 return "fstp%z0\t%y0";
3896 else
3897 return "fst%z0\t%y0";
3898 }
3899 [(set_attr "type" "fmov")
3900 (set_attr "mode" "SF")])
3901
3902 (define_insn "truncdfsf2_sse_only"
3903 [(set (match_operand:SF 0 "register_operand" "=Y")
3904 (float_truncate:SF
3905 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3906 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3907 "cvtsd2ss\t{%1, %0|%0, %1}"
3908 [(set_attr "type" "ssecvt")
3909 (set_attr "mode" "DF")])
3910
3911 (define_insn "*truncdfsf2_sse_only_nooverlap"
3912 [(set (match_operand:SF 0 "register_operand" "=&Y")
3913 (float_truncate:SF
3914 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3915 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3916 "#"
3917 [(set_attr "type" "ssecvt")
3918 (set_attr "mode" "DF")])
3919
3920 (define_split
3921 [(set (match_operand:SF 0 "memory_operand" "")
3922 (float_truncate:SF
3923 (match_operand:DF 1 "register_operand" "")))
3924 (clobber (match_operand:SF 2 "memory_operand" ""))]
3925 "TARGET_80387"
3926 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3927 "")
3928
3929 ; Avoid possible reformating penalty on the destination by first
3930 ; zeroing it out
3931 (define_split
3932 [(set (match_operand:SF 0 "register_operand" "")
3933 (float_truncate:SF
3934 (match_operand:DF 1 "nonimmediate_operand" "")))
3935 (clobber (match_operand 2 "" ""))]
3936 "TARGET_80387 && reload_completed
3937 && SSE_REG_P (operands[0])
3938 && !STACK_REG_P (operands[1])"
3939 [(const_int 0)]
3940 {
3941 rtx src, dest;
3942 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3943 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3944 else
3945 {
3946 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3947 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3948 /* simplify_gen_subreg refuses to widen memory references. */
3949 if (GET_CODE (src) == SUBREG)
3950 alter_subreg (&src);
3951 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3952 abort ();
3953 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3954 emit_insn (gen_cvtsd2ss (dest, dest, src));
3955 }
3956 DONE;
3957 })
3958
3959 (define_split
3960 [(set (match_operand:SF 0 "register_operand" "")
3961 (float_truncate:SF
3962 (match_operand:DF 1 "nonimmediate_operand" "")))]
3963 "TARGET_80387 && reload_completed
3964 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3965 [(const_int 0)]
3966 {
3967 rtx src, dest;
3968 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3969 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3970 /* simplify_gen_subreg refuses to widen memory references. */
3971 if (GET_CODE (src) == SUBREG)
3972 alter_subreg (&src);
3973 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3974 abort ();
3975 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3976 emit_insn (gen_cvtsd2ss (dest, dest, src));
3977 DONE;
3978 })
3979
3980 (define_split
3981 [(set (match_operand:SF 0 "register_operand" "")
3982 (float_truncate:SF
3983 (match_operand:DF 1 "fp_register_operand" "")))
3984 (clobber (match_operand:SF 2 "memory_operand" ""))]
3985 "TARGET_80387 && reload_completed"
3986 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3987 (set (match_dup 0) (match_dup 2))]
3988 "")
3989
3990 (define_expand "truncxfsf2"
3991 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3992 (float_truncate:SF
3993 (match_operand:XF 1 "register_operand" "")))
3994 (clobber (match_dup 2))])]
3995 "!TARGET_64BIT && TARGET_80387"
3996 "operands[2] = assign_386_stack_local (SFmode, 0);")
3997
3998 (define_insn "*truncxfsf2_1"
3999 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4000 (float_truncate:SF
4001 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4002 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4003 "!TARGET_64BIT && TARGET_80387"
4004 {
4005 switch (which_alternative)
4006 {
4007 case 0:
4008 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4009 return "fstp%z0\t%y0";
4010 else
4011 return "fst%z0\t%y0";
4012 default:
4013 abort();
4014 }
4015 }
4016 [(set_attr "type" "fmov,multi,multi,multi")
4017 (set_attr "mode" "SF")])
4018
4019 (define_insn "*truncxfsf2_2"
4020 [(set (match_operand:SF 0 "memory_operand" "=m")
4021 (float_truncate:SF
4022 (match_operand:XF 1 "register_operand" "f")))]
4023 "!TARGET_64BIT && TARGET_80387"
4024 {
4025 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4026 return "fstp%z0\t%y0";
4027 else
4028 return "fst%z0\t%y0";
4029 }
4030 [(set_attr "type" "fmov")
4031 (set_attr "mode" "SF")])
4032
4033 (define_split
4034 [(set (match_operand:SF 0 "memory_operand" "")
4035 (float_truncate:SF
4036 (match_operand:XF 1 "register_operand" "")))
4037 (clobber (match_operand:SF 2 "memory_operand" ""))]
4038 "TARGET_80387"
4039 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4040 "")
4041
4042 (define_split
4043 [(set (match_operand:SF 0 "register_operand" "")
4044 (float_truncate:SF
4045 (match_operand:XF 1 "register_operand" "")))
4046 (clobber (match_operand:SF 2 "memory_operand" ""))]
4047 "TARGET_80387 && reload_completed"
4048 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4049 (set (match_dup 0) (match_dup 2))]
4050 "")
4051
4052 (define_expand "trunctfsf2"
4053 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4054 (float_truncate:SF
4055 (match_operand:TF 1 "register_operand" "")))
4056 (clobber (match_dup 2))])]
4057 "TARGET_80387"
4058 "operands[2] = assign_386_stack_local (SFmode, 0);")
4059
4060 (define_insn "*trunctfsf2_1"
4061 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4062 (float_truncate:SF
4063 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4064 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4065 "TARGET_80387"
4066 {
4067 switch (which_alternative)
4068 {
4069 case 0:
4070 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4071 return "fstp%z0\t%y0";
4072 else
4073 return "fst%z0\t%y0";
4074 default:
4075 abort();
4076 }
4077 }
4078 [(set_attr "type" "fmov,multi,multi,multi")
4079 (set_attr "mode" "SF")])
4080
4081 (define_insn "*trunctfsf2_2"
4082 [(set (match_operand:SF 0 "memory_operand" "=m")
4083 (float_truncate:SF
4084 (match_operand:TF 1 "register_operand" "f")))]
4085 "TARGET_80387"
4086 {
4087 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4088 return "fstp%z0\t%y0";
4089 else
4090 return "fst%z0\t%y0";
4091 }
4092 [(set_attr "type" "fmov")
4093 (set_attr "mode" "SF")])
4094
4095 (define_split
4096 [(set (match_operand:SF 0 "memory_operand" "")
4097 (float_truncate:SF
4098 (match_operand:TF 1 "register_operand" "")))
4099 (clobber (match_operand:SF 2 "memory_operand" ""))]
4100 "TARGET_80387"
4101 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4102 "")
4103
4104 (define_split
4105 [(set (match_operand:SF 0 "register_operand" "")
4106 (float_truncate:SF
4107 (match_operand:TF 1 "register_operand" "")))
4108 (clobber (match_operand:SF 2 "memory_operand" ""))]
4109 "TARGET_80387 && reload_completed"
4110 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4111 (set (match_dup 0) (match_dup 2))]
4112 "")
4113
4114
4115 (define_expand "truncxfdf2"
4116 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4117 (float_truncate:DF
4118 (match_operand:XF 1 "register_operand" "")))
4119 (clobber (match_dup 2))])]
4120 "!TARGET_64BIT && TARGET_80387"
4121 "operands[2] = assign_386_stack_local (DFmode, 0);")
4122
4123 (define_insn "*truncxfdf2_1"
4124 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4125 (float_truncate:DF
4126 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4127 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4128 "!TARGET_64BIT && TARGET_80387"
4129 {
4130 switch (which_alternative)
4131 {
4132 case 0:
4133 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4134 return "fstp%z0\t%y0";
4135 else
4136 return "fst%z0\t%y0";
4137 default:
4138 abort();
4139 }
4140 abort ();
4141 }
4142 [(set_attr "type" "fmov,multi,multi,multi")
4143 (set_attr "mode" "DF")])
4144
4145 (define_insn "*truncxfdf2_2"
4146 [(set (match_operand:DF 0 "memory_operand" "=m")
4147 (float_truncate:DF
4148 (match_operand:XF 1 "register_operand" "f")))]
4149 "!TARGET_64BIT && TARGET_80387"
4150 {
4151 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4152 return "fstp%z0\t%y0";
4153 else
4154 return "fst%z0\t%y0";
4155 }
4156 [(set_attr "type" "fmov")
4157 (set_attr "mode" "DF")])
4158
4159 (define_split
4160 [(set (match_operand:DF 0 "memory_operand" "")
4161 (float_truncate:DF
4162 (match_operand:XF 1 "register_operand" "")))
4163 (clobber (match_operand:DF 2 "memory_operand" ""))]
4164 "TARGET_80387"
4165 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4166 "")
4167
4168 (define_split
4169 [(set (match_operand:DF 0 "register_operand" "")
4170 (float_truncate:DF
4171 (match_operand:XF 1 "register_operand" "")))
4172 (clobber (match_operand:DF 2 "memory_operand" ""))]
4173 "TARGET_80387 && reload_completed"
4174 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4175 (set (match_dup 0) (match_dup 2))]
4176 "")
4177
4178 (define_expand "trunctfdf2"
4179 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4180 (float_truncate:DF
4181 (match_operand:TF 1 "register_operand" "")))
4182 (clobber (match_dup 2))])]
4183 "TARGET_80387"
4184 "operands[2] = assign_386_stack_local (DFmode, 0);")
4185
4186 (define_insn "*trunctfdf2_1"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4188 (float_truncate:DF
4189 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4190 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4191 "TARGET_80387"
4192 {
4193 switch (which_alternative)
4194 {
4195 case 0:
4196 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4197 return "fstp%z0\t%y0";
4198 else
4199 return "fst%z0\t%y0";
4200 default:
4201 abort();
4202 }
4203 abort ();
4204 }
4205 [(set_attr "type" "fmov,multi,multi,multi")
4206 (set_attr "mode" "DF")])
4207
4208 (define_insn "*trunctfdf2_2"
4209 [(set (match_operand:DF 0 "memory_operand" "=m")
4210 (float_truncate:DF
4211 (match_operand:TF 1 "register_operand" "f")))]
4212 "TARGET_80387"
4213 {
4214 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4215 return "fstp%z0\t%y0";
4216 else
4217 return "fst%z0\t%y0";
4218 }
4219 [(set_attr "type" "fmov")
4220 (set_attr "mode" "DF")])
4221
4222 (define_split
4223 [(set (match_operand:DF 0 "memory_operand" "")
4224 (float_truncate:DF
4225 (match_operand:TF 1 "register_operand" "")))
4226 (clobber (match_operand:DF 2 "memory_operand" ""))]
4227 "TARGET_80387"
4228 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4229 "")
4230
4231 (define_split
4232 [(set (match_operand:DF 0 "register_operand" "")
4233 (float_truncate:DF
4234 (match_operand:TF 1 "register_operand" "")))
4235 (clobber (match_operand:DF 2 "memory_operand" ""))]
4236 "TARGET_80387 && reload_completed"
4237 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4238 (set (match_dup 0) (match_dup 2))]
4239 "")
4240
4241 \f
4242 ;; %%% Break up all these bad boys.
4243
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4249 "!TARGET_64BIT && TARGET_80387"
4250 "")
4251
4252 (define_expand "fix_trunctfdi2"
4253 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4254 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4255 "TARGET_80387"
4256 "")
4257
4258 (define_expand "fix_truncdfdi2"
4259 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4260 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4261 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4262 {
4263 if (TARGET_64BIT && TARGET_SSE2)
4264 {
4265 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4266 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4267 if (out != operands[0])
4268 emit_move_insn (operands[0], out);
4269 DONE;
4270 }
4271 })
4272
4273 (define_expand "fix_truncsfdi2"
4274 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4275 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4276 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4277 {
4278 if (TARGET_SSE && TARGET_64BIT)
4279 {
4280 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4281 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4282 if (out != operands[0])
4283 emit_move_insn (operands[0], out);
4284 DONE;
4285 }
4286 })
4287
4288 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4289 ;; of the machinery.
4290 (define_insn_and_split "*fix_truncdi_1"
4291 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4292 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4293 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4294 && !reload_completed && !reload_in_progress
4295 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4296 "#"
4297 "&& 1"
4298 [(const_int 0)]
4299 {
4300 operands[2] = assign_386_stack_local (HImode, 1);
4301 operands[3] = assign_386_stack_local (HImode, 2);
4302 if (memory_operand (operands[0], VOIDmode))
4303 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4304 operands[2], operands[3]));
4305 else
4306 {
4307 operands[4] = assign_386_stack_local (DImode, 0);
4308 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4309 operands[2], operands[3],
4310 operands[4]));
4311 }
4312 DONE;
4313 }
4314 [(set_attr "type" "fistp")])
4315
4316 (define_insn "fix_truncdi_nomemory"
4317 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4318 (fix:DI (match_operand 1 "register_operand" "f,f")))
4319 (use (match_operand:HI 2 "memory_operand" "m,m"))
4320 (use (match_operand:HI 3 "memory_operand" "m,m"))
4321 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4322 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4323 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4324 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4325 "#"
4326 [(set_attr "type" "fistp")])
4327
4328 (define_insn "fix_truncdi_memory"
4329 [(set (match_operand:DI 0 "memory_operand" "=m")
4330 (fix:DI (match_operand 1 "register_operand" "f")))
4331 (use (match_operand:HI 2 "memory_operand" "m"))
4332 (use (match_operand:HI 3 "memory_operand" "m"))
4333 (clobber (match_scratch:DF 4 "=&1f"))]
4334 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4335 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4336 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4337 [(set_attr "type" "fistp")])
4338
4339 (define_split
4340 [(set (match_operand:DI 0 "register_operand" "")
4341 (fix:DI (match_operand 1 "register_operand" "")))
4342 (use (match_operand:HI 2 "memory_operand" ""))
4343 (use (match_operand:HI 3 "memory_operand" ""))
4344 (clobber (match_operand:DI 4 "memory_operand" ""))
4345 (clobber (match_scratch 5 ""))]
4346 "reload_completed"
4347 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4348 (use (match_dup 2))
4349 (use (match_dup 3))
4350 (clobber (match_dup 5))])
4351 (set (match_dup 0) (match_dup 4))]
4352 "")
4353
4354 (define_split
4355 [(set (match_operand:DI 0 "memory_operand" "")
4356 (fix:DI (match_operand 1 "register_operand" "")))
4357 (use (match_operand:HI 2 "memory_operand" ""))
4358 (use (match_operand:HI 3 "memory_operand" ""))
4359 (clobber (match_operand:DI 4 "memory_operand" ""))
4360 (clobber (match_scratch 5 ""))]
4361 "reload_completed"
4362 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4363 (use (match_dup 2))
4364 (use (match_dup 3))
4365 (clobber (match_dup 5))])]
4366 "")
4367
4368 ;; When SSE available, it is always faster to use it!
4369 (define_insn "fix_truncsfdi_sse"
4370 [(set (match_operand:DI 0 "register_operand" "=r")
4371 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4372 "TARGET_64BIT && TARGET_SSE"
4373 "cvttss2si{q}\t{%1, %0|%0, %1}"
4374 [(set_attr "type" "ssecvt")])
4375
4376 (define_insn "fix_truncdfdi_sse"
4377 [(set (match_operand:DI 0 "register_operand" "=r")
4378 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4379 "TARGET_64BIT && TARGET_SSE2"
4380 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4381 [(set_attr "type" "ssecvt")])
4382
4383 ;; Signed conversion to SImode.
4384
4385 (define_expand "fix_truncxfsi2"
4386 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4387 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4388 "!TARGET_64BIT && TARGET_80387"
4389 "")
4390
4391 (define_expand "fix_trunctfsi2"
4392 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4393 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4394 "TARGET_80387"
4395 "")
4396
4397 (define_expand "fix_truncdfsi2"
4398 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4399 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4400 "TARGET_80387 || TARGET_SSE2"
4401 {
4402 if (TARGET_SSE2)
4403 {
4404 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4405 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4406 if (out != operands[0])
4407 emit_move_insn (operands[0], out);
4408 DONE;
4409 }
4410 })
4411
4412 (define_expand "fix_truncsfsi2"
4413 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4414 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4415 "TARGET_80387 || TARGET_SSE"
4416 {
4417 if (TARGET_SSE)
4418 {
4419 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4420 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4421 if (out != operands[0])
4422 emit_move_insn (operands[0], out);
4423 DONE;
4424 }
4425 })
4426
4427 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4428 ;; of the machinery.
4429 (define_insn_and_split "*fix_truncsi_1"
4430 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4431 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4432 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4433 && !reload_completed && !reload_in_progress
4434 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4435 "#"
4436 "&& 1"
4437 [(const_int 0)]
4438 {
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_truncsi_memory (operands[0], operands[1],
4443 operands[2], operands[3]));
4444 else
4445 {
4446 operands[4] = assign_386_stack_local (SImode, 0);
4447 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4448 operands[2], operands[3],
4449 operands[4]));
4450 }
4451 DONE;
4452 }
4453 [(set_attr "type" "fistp")])
4454
4455 (define_insn "fix_truncsi_nomemory"
4456 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4457 (fix:SI (match_operand 1 "register_operand" "f,f")))
4458 (use (match_operand:HI 2 "memory_operand" "m,m"))
4459 (use (match_operand:HI 3 "memory_operand" "m,m"))
4460 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4461 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4462 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4463 "#"
4464 [(set_attr "type" "fistp")])
4465
4466 (define_insn "fix_truncsi_memory"
4467 [(set (match_operand:SI 0 "memory_operand" "=m")
4468 (fix:SI (match_operand 1 "register_operand" "f")))
4469 (use (match_operand:HI 2 "memory_operand" "m"))
4470 (use (match_operand:HI 3 "memory_operand" "m"))]
4471 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4472 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4473 "* return output_fix_trunc (insn, operands);"
4474 [(set_attr "type" "fistp")])
4475
4476 ;; When SSE available, it is always faster to use it!
4477 (define_insn "fix_truncsfsi_sse"
4478 [(set (match_operand:SI 0 "register_operand" "=r")
4479 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4480 "TARGET_SSE"
4481 "cvttss2si\t{%1, %0|%0, %1}"
4482 [(set_attr "type" "ssecvt")])
4483
4484 (define_insn "fix_truncdfsi_sse"
4485 [(set (match_operand:SI 0 "register_operand" "=r")
4486 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4487 "TARGET_SSE2"
4488 "cvttsd2si\t{%1, %0|%0, %1}"
4489 [(set_attr "type" "ssecvt")])
4490
4491 (define_split
4492 [(set (match_operand:SI 0 "register_operand" "")
4493 (fix:SI (match_operand 1 "register_operand" "")))
4494 (use (match_operand:HI 2 "memory_operand" ""))
4495 (use (match_operand:HI 3 "memory_operand" ""))
4496 (clobber (match_operand:SI 4 "memory_operand" ""))]
4497 "reload_completed"
4498 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4499 (use (match_dup 2))
4500 (use (match_dup 3))])
4501 (set (match_dup 0) (match_dup 4))]
4502 "")
4503
4504 (define_split
4505 [(set (match_operand:SI 0 "memory_operand" "")
4506 (fix:SI (match_operand 1 "register_operand" "")))
4507 (use (match_operand:HI 2 "memory_operand" ""))
4508 (use (match_operand:HI 3 "memory_operand" ""))
4509 (clobber (match_operand:SI 4 "memory_operand" ""))]
4510 "reload_completed"
4511 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4512 (use (match_dup 2))
4513 (use (match_dup 3))])]
4514 "")
4515
4516 ;; Signed conversion to HImode.
4517
4518 (define_expand "fix_truncxfhi2"
4519 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4520 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4521 "!TARGET_64BIT && TARGET_80387"
4522 "")
4523
4524 (define_expand "fix_trunctfhi2"
4525 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4526 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4527 "TARGET_80387"
4528 "")
4529
4530 (define_expand "fix_truncdfhi2"
4531 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4532 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4533 "TARGET_80387 && !TARGET_SSE2"
4534 "")
4535
4536 (define_expand "fix_truncsfhi2"
4537 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4538 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4539 "TARGET_80387 && !TARGET_SSE"
4540 "")
4541
4542 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4543 ;; of the machinery.
4544 (define_insn_and_split "*fix_trunchi_1"
4545 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4546 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4547 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4548 && !reload_completed && !reload_in_progress
4549 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4550 "#"
4551 ""
4552 [(const_int 0)]
4553 {
4554 operands[2] = assign_386_stack_local (HImode, 1);
4555 operands[3] = assign_386_stack_local (HImode, 2);
4556 if (memory_operand (operands[0], VOIDmode))
4557 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4558 operands[2], operands[3]));
4559 else
4560 {
4561 operands[4] = assign_386_stack_local (HImode, 0);
4562 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4563 operands[2], operands[3],
4564 operands[4]));
4565 }
4566 DONE;
4567 }
4568 [(set_attr "type" "fistp")])
4569
4570 (define_insn "fix_trunchi_nomemory"
4571 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4572 (fix:HI (match_operand 1 "register_operand" "f,f")))
4573 (use (match_operand:HI 2 "memory_operand" "m,m"))
4574 (use (match_operand:HI 3 "memory_operand" "m,m"))
4575 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4576 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4577 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4578 "#"
4579 [(set_attr "type" "fistp")])
4580
4581 (define_insn "fix_trunchi_memory"
4582 [(set (match_operand:HI 0 "memory_operand" "=m")
4583 (fix:HI (match_operand 1 "register_operand" "f")))
4584 (use (match_operand:HI 2 "memory_operand" "m"))
4585 (use (match_operand:HI 3 "memory_operand" "m"))]
4586 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4587 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4588 "* return output_fix_trunc (insn, operands);"
4589 [(set_attr "type" "fistp")])
4590
4591 (define_split
4592 [(set (match_operand:HI 0 "memory_operand" "")
4593 (fix:HI (match_operand 1 "register_operand" "")))
4594 (use (match_operand:HI 2 "memory_operand" ""))
4595 (use (match_operand:HI 3 "memory_operand" ""))
4596 (clobber (match_operand:HI 4 "memory_operand" ""))]
4597 "reload_completed"
4598 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4599 (use (match_dup 2))
4600 (use (match_dup 3))])]
4601 "")
4602
4603 (define_split
4604 [(set (match_operand:HI 0 "register_operand" "")
4605 (fix:HI (match_operand 1 "register_operand" "")))
4606 (use (match_operand:HI 2 "memory_operand" ""))
4607 (use (match_operand:HI 3 "memory_operand" ""))
4608 (clobber (match_operand:HI 4 "memory_operand" ""))]
4609 "reload_completed"
4610 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4611 (use (match_dup 2))
4612 (use (match_dup 3))
4613 (clobber (match_dup 4))])
4614 (set (match_dup 0) (match_dup 4))]
4615 "")
4616
4617 ;; %% Not used yet.
4618 (define_insn "x86_fnstcw_1"
4619 [(set (match_operand:HI 0 "memory_operand" "=m")
4620 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4621 "TARGET_80387"
4622 "fnstcw\t%0"
4623 [(set_attr "length" "2")
4624 (set_attr "mode" "HI")
4625 (set_attr "unit" "i387")
4626 (set_attr "ppro_uops" "few")])
4627
4628 (define_insn "x86_fldcw_1"
4629 [(set (reg:HI 18)
4630 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4631 "TARGET_80387"
4632 "fldcw\t%0"
4633 [(set_attr "length" "2")
4634 (set_attr "mode" "HI")
4635 (set_attr "unit" "i387")
4636 (set_attr "athlon_decode" "vector")
4637 (set_attr "ppro_uops" "few")])
4638 \f
4639 ;; Conversion between fixed point and floating point.
4640
4641 ;; Even though we only accept memory inputs, the backend _really_
4642 ;; wants to be able to do this between registers.
4643
4644 (define_insn "floathisf2"
4645 [(set (match_operand:SF 0 "register_operand" "=f,f")
4646 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4647 "TARGET_80387 && !TARGET_SSE"
4648 "@
4649 fild%z1\t%1
4650 #"
4651 [(set_attr "type" "fmov,multi")
4652 (set_attr "mode" "SF")
4653 (set_attr "fp_int_src" "true")])
4654
4655 (define_expand "floatsisf2"
4656 [(set (match_operand:SF 0 "register_operand" "")
4657 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4658 "TARGET_SSE || TARGET_80387"
4659 "")
4660
4661 (define_insn "*floatsisf2_i387"
4662 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f")
4663 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4664 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4665 "@
4666 fild%z1\t%1
4667 #
4668 cvtsi2ss\t{%1, %0|%0, %1}"
4669 [(set_attr "type" "fmov,multi,ssecvt")
4670 (set_attr "mode" "SF")
4671 (set_attr "fp_int_src" "true")])
4672
4673 (define_insn "*floatsisf2_sse"
4674 [(set (match_operand:SF 0 "register_operand" "=x")
4675 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4676 "TARGET_SSE"
4677 "cvtsi2ss\t{%1, %0|%0, %1}"
4678 [(set_attr "type" "ssecvt")
4679 (set_attr "mode" "SF")
4680 (set_attr "fp_int_src" "true")])
4681
4682 ; Avoid possible reformating penalty on the destination by first
4683 ; zeroing it out
4684 (define_split
4685 [(set (match_operand:SF 0 "register_operand" "")
4686 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4687 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4688 && SSE_REG_P (operands[0])"
4689 [(const_int 0)]
4690 {
4691 rtx dest;
4692 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4693 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4694 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4695 DONE;
4696 })
4697
4698 (define_expand "floatdisf2"
4699 [(set (match_operand:SF 0 "register_operand" "")
4700 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4701 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4702 "")
4703
4704 (define_insn "*floatdisf2_i387_only"
4705 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4706 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4707 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4708 "@
4709 fild%z1\t%1
4710 #"
4711 [(set_attr "type" "fmov,multi")
4712 (set_attr "mode" "SF")
4713 (set_attr "fp_int_src" "true")])
4714
4715 (define_insn "*floatdisf2_i387"
4716 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f")
4717 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
4718 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4719 "@
4720 fild%z1\t%1
4721 #
4722 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4723 [(set_attr "type" "fmov,multi,ssecvt")
4724 (set_attr "mode" "SF")
4725 (set_attr "fp_int_src" "true")])
4726
4727 (define_insn "*floatdisf2_sse"
4728 [(set (match_operand:SF 0 "register_operand" "=x")
4729 (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
4730 "TARGET_64BIT && TARGET_SSE"
4731 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4732 [(set_attr "type" "ssecvt")
4733 (set_attr "mode" "SF")
4734 (set_attr "fp_int_src" "true")])
4735
4736 ; Avoid possible reformating penalty on the destination by first
4737 ; zeroing it out
4738 (define_split
4739 [(set (match_operand:SF 0 "register_operand" "")
4740 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4741 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4742 && SSE_REG_P (operands[0])"
4743 [(const_int 0)]
4744 {
4745 rtx dest;
4746 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4747 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4748 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4749 DONE;
4750 })
4751
4752 (define_insn "floathidf2"
4753 [(set (match_operand:DF 0 "register_operand" "=f,f")
4754 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4755 "TARGET_80387 && !TARGET_SSE2"
4756 "@
4757 fild%z1\t%1
4758 #"
4759 [(set_attr "type" "fmov,multi")
4760 (set_attr "mode" "DF")
4761 (set_attr "fp_int_src" "true")])
4762
4763 (define_expand "floatsidf2"
4764 [(set (match_operand:DF 0 "register_operand" "")
4765 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4766 "TARGET_80387 || TARGET_SSE2"
4767 "")
4768
4769 (define_insn "*floatsidf2_i387"
4770 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f")
4771 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4772 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4773 "@
4774 fild%z1\t%1
4775 #
4776 cvtsi2sd\t{%1, %0|%0, %1}"
4777 [(set_attr "type" "fmov,multi,ssecvt")
4778 (set_attr "mode" "DF")
4779 (set_attr "fp_int_src" "true")])
4780
4781 (define_insn "*floatsidf2_sse"
4782 [(set (match_operand:DF 0 "register_operand" "=Y")
4783 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4784 "TARGET_SSE2"
4785 "cvtsi2sd\t{%1, %0|%0, %1}"
4786 [(set_attr "type" "ssecvt")
4787 (set_attr "mode" "DF")
4788 (set_attr "fp_int_src" "true")])
4789
4790 (define_expand "floatdidf2"
4791 [(set (match_operand:DF 0 "register_operand" "")
4792 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4793 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4794 "")
4795
4796 (define_insn "*floatdidf2_i387_only"
4797 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4798 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4799 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4800 "@
4801 fild%z1\t%1
4802 #"
4803 [(set_attr "type" "fmov,multi")
4804 (set_attr "mode" "DF")
4805 (set_attr "fp_int_src" "true")])
4806
4807 (define_insn "*floatdidf2_i387"
4808 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f")
4809 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
4810 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4811 "@
4812 fild%z1\t%1
4813 #
4814 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4815 [(set_attr "type" "fmov,multi,ssecvt")
4816 (set_attr "mode" "DF")
4817 (set_attr "fp_int_src" "true")])
4818
4819 (define_insn "*floatdidf2_sse"
4820 [(set (match_operand:DF 0 "register_operand" "=Y")
4821 (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
4822 "TARGET_SSE2"
4823 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4824 [(set_attr "type" "ssecvt")
4825 (set_attr "mode" "DF")
4826 (set_attr "fp_int_src" "true")])
4827
4828 (define_insn "floathixf2"
4829 [(set (match_operand:XF 0 "register_operand" "=f,f")
4830 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4831 "!TARGET_64BIT && TARGET_80387"
4832 "@
4833 fild%z1\t%1
4834 #"
4835 [(set_attr "type" "fmov,multi")
4836 (set_attr "mode" "XF")
4837 (set_attr "fp_int_src" "true")])
4838
4839 (define_insn "floathitf2"
4840 [(set (match_operand:TF 0 "register_operand" "=f,f")
4841 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4842 "TARGET_80387"
4843 "@
4844 fild%z1\t%1
4845 #"
4846 [(set_attr "type" "fmov,multi")
4847 (set_attr "mode" "XF")
4848 (set_attr "fp_int_src" "true")])
4849
4850 (define_insn "floatsixf2"
4851 [(set (match_operand:XF 0 "register_operand" "=f,f")
4852 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4853 "!TARGET_64BIT && TARGET_80387"
4854 "@
4855 fild%z1\t%1
4856 #"
4857 [(set_attr "type" "fmov,multi")
4858 (set_attr "mode" "XF")
4859 (set_attr "fp_int_src" "true")])
4860
4861 (define_insn "floatsitf2"
4862 [(set (match_operand:TF 0 "register_operand" "=f,f")
4863 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4864 "TARGET_80387"
4865 "@
4866 fild%z1\t%1
4867 #"
4868 [(set_attr "type" "fmov,multi")
4869 (set_attr "mode" "XF")
4870 (set_attr "fp_int_src" "true")])
4871
4872 (define_insn "floatdixf2"
4873 [(set (match_operand:XF 0 "register_operand" "=f,f")
4874 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4875 "!TARGET_64BIT && TARGET_80387"
4876 "@
4877 fild%z1\t%1
4878 #"
4879 [(set_attr "type" "fmov,multi")
4880 (set_attr "mode" "XF")
4881 (set_attr "fp_int_src" "true")])
4882
4883 (define_insn "floatditf2"
4884 [(set (match_operand:TF 0 "register_operand" "=f,f")
4885 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4886 "TARGET_80387"
4887 "@
4888 fild%z1\t%1
4889 #"
4890 [(set_attr "type" "fmov,multi")
4891 (set_attr "mode" "XF")
4892 (set_attr "fp_int_src" "true")])
4893
4894 ;; %%% Kill these when reload knows how to do it.
4895 (define_split
4896 [(set (match_operand 0 "fp_register_operand" "")
4897 (float (match_operand 1 "register_operand" "")))]
4898 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4899 [(const_int 0)]
4900 {
4901 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4902 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4903 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4904 ix86_free_from_memory (GET_MODE (operands[1]));
4905 DONE;
4906 })
4907 \f
4908 ;; Add instructions
4909
4910 ;; %%% splits for addsidi3
4911 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4912 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4913 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4914
4915 (define_expand "adddi3"
4916 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4917 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4918 (match_operand:DI 2 "x86_64_general_operand" "")))
4919 (clobber (reg:CC 17))]
4920 ""
4921 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4922
4923 (define_insn "*adddi3_1"
4924 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4925 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4926 (match_operand:DI 2 "general_operand" "roiF,riF")))
4927 (clobber (reg:CC 17))]
4928 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4929 "#")
4930
4931 (define_split
4932 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4933 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4934 (match_operand:DI 2 "general_operand" "")))
4935 (clobber (reg:CC 17))]
4936 "!TARGET_64BIT && reload_completed"
4937 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4938 UNSPEC_ADD_CARRY))
4939 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4940 (parallel [(set (match_dup 3)
4941 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4942 (match_dup 4))
4943 (match_dup 5)))
4944 (clobber (reg:CC 17))])]
4945 "split_di (operands+0, 1, operands+0, operands+3);
4946 split_di (operands+1, 1, operands+1, operands+4);
4947 split_di (operands+2, 1, operands+2, operands+5);")
4948
4949 (define_insn "*adddi3_carry_rex64"
4950 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4951 (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
4952 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4953 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4954 (clobber (reg:CC 17))]
4955 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4956 "adc{q}\t{%2, %0|%0, %2}"
4957 [(set_attr "type" "alu")
4958 (set_attr "pent_pair" "pu")
4959 (set_attr "mode" "DI")
4960 (set_attr "ppro_uops" "few")])
4961
4962 (define_insn "*adddi3_cc_rex64"
4963 [(set (reg:CC 17)
4964 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4965 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4966 UNSPEC_ADD_CARRY))
4967 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4968 (plus:DI (match_dup 1) (match_dup 2)))]
4969 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4970 "add{q}\t{%2, %0|%0, %2}"
4971 [(set_attr "type" "alu")
4972 (set_attr "mode" "DI")])
4973
4974 (define_insn "*addsi3_carry"
4975 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4976 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4977 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4978 (match_operand:SI 2 "general_operand" "ri,rm")))
4979 (clobber (reg:CC 17))]
4980 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4981 "adc{l}\t{%2, %0|%0, %2}"
4982 [(set_attr "type" "alu")
4983 (set_attr "pent_pair" "pu")
4984 (set_attr "mode" "SI")
4985 (set_attr "ppro_uops" "few")])
4986
4987 (define_insn "*addsi3_carry_zext"
4988 [(set (match_operand:DI 0 "register_operand" "=r")
4989 (zero_extend:DI
4990 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4991 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4992 (match_operand:SI 2 "general_operand" "rim"))))
4993 (clobber (reg:CC 17))]
4994 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4995 "adc{l}\t{%2, %k0|%k0, %2}"
4996 [(set_attr "type" "alu")
4997 (set_attr "pent_pair" "pu")
4998 (set_attr "mode" "SI")
4999 (set_attr "ppro_uops" "few")])
5000
5001 (define_insn "*addsi3_cc"
5002 [(set (reg:CC 17)
5003 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5004 (match_operand:SI 2 "general_operand" "ri,rm")]
5005 UNSPEC_ADD_CARRY))
5006 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5007 (plus:SI (match_dup 1) (match_dup 2)))]
5008 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5009 "add{l}\t{%2, %0|%0, %2}"
5010 [(set_attr "type" "alu")
5011 (set_attr "mode" "SI")])
5012
5013 (define_insn "addqi3_cc"
5014 [(set (reg:CC 17)
5015 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5016 (match_operand:QI 2 "general_operand" "qi,qm")]
5017 UNSPEC_ADD_CARRY))
5018 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5019 (plus:QI (match_dup 1) (match_dup 2)))]
5020 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5021 "add{b}\t{%2, %0|%0, %2}"
5022 [(set_attr "type" "alu")
5023 (set_attr "mode" "QI")])
5024
5025 (define_expand "addsi3"
5026 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5027 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5028 (match_operand:SI 2 "general_operand" "")))
5029 (clobber (reg:CC 17))])]
5030 ""
5031 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5032
5033 (define_insn "*lea_1"
5034 [(set (match_operand:SI 0 "register_operand" "=r")
5035 (match_operand:SI 1 "address_operand" "p"))]
5036 "!TARGET_64BIT"
5037 "lea{l}\t{%a1, %0|%0, %a1}"
5038 [(set_attr "type" "lea")
5039 (set_attr "mode" "SI")])
5040
5041 (define_insn "*lea_1_rex64"
5042 [(set (match_operand:SI 0 "register_operand" "=r")
5043 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5044 "TARGET_64BIT"
5045 "lea{l}\t{%a1, %0|%0, %a1}"
5046 [(set_attr "type" "lea")
5047 (set_attr "mode" "SI")])
5048
5049 (define_insn "*lea_1_zext"
5050 [(set (match_operand:DI 0 "register_operand" "=r")
5051 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5052 "TARGET_64BIT"
5053 "lea{l}\t{%a1, %k0|%k0, %a1}"
5054 [(set_attr "type" "lea")
5055 (set_attr "mode" "SI")])
5056
5057 (define_insn "*lea_2_rex64"
5058 [(set (match_operand:DI 0 "register_operand" "=r")
5059 (match_operand:DI 1 "address_operand" "p"))]
5060 "TARGET_64BIT"
5061 "lea{q}\t{%a1, %0|%0, %a1}"
5062 [(set_attr "type" "lea")
5063 (set_attr "mode" "DI")])
5064
5065 ;; The lea patterns for non-Pmodes needs to be matched by several
5066 ;; insns converted to real lea by splitters.
5067
5068 (define_insn_and_split "*lea_general_1"
5069 [(set (match_operand 0 "register_operand" "=r")
5070 (plus (plus (match_operand 1 "index_register_operand" "r")
5071 (match_operand 2 "register_operand" "r"))
5072 (match_operand 3 "immediate_operand" "i")))]
5073 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5074 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5075 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5076 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5077 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5078 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5079 || GET_MODE (operands[3]) == VOIDmode)"
5080 "#"
5081 "&& reload_completed"
5082 [(const_int 0)]
5083 {
5084 rtx pat;
5085 operands[0] = gen_lowpart (SImode, operands[0]);
5086 operands[1] = gen_lowpart (Pmode, operands[1]);
5087 operands[2] = gen_lowpart (Pmode, operands[2]);
5088 operands[3] = gen_lowpart (Pmode, operands[3]);
5089 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5090 operands[3]);
5091 if (Pmode != SImode)
5092 pat = gen_rtx_SUBREG (SImode, pat, 0);
5093 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5094 DONE;
5095 }
5096 [(set_attr "type" "lea")
5097 (set_attr "mode" "SI")])
5098
5099 (define_insn_and_split "*lea_general_1_zext"
5100 [(set (match_operand:DI 0 "register_operand" "=r")
5101 (zero_extend:DI
5102 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5103 (match_operand:SI 2 "register_operand" "r"))
5104 (match_operand:SI 3 "immediate_operand" "i"))))]
5105 "TARGET_64BIT"
5106 "#"
5107 "&& reload_completed"
5108 [(set (match_dup 0)
5109 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5110 (match_dup 2))
5111 (match_dup 3)) 0)))]
5112 {
5113 operands[1] = gen_lowpart (Pmode, operands[1]);
5114 operands[2] = gen_lowpart (Pmode, operands[2]);
5115 operands[3] = gen_lowpart (Pmode, operands[3]);
5116 }
5117 [(set_attr "type" "lea")
5118 (set_attr "mode" "SI")])
5119
5120 (define_insn_and_split "*lea_general_2"
5121 [(set (match_operand 0 "register_operand" "=r")
5122 (plus (mult (match_operand 1 "index_register_operand" "r")
5123 (match_operand 2 "const248_operand" "i"))
5124 (match_operand 3 "nonmemory_operand" "ri")))]
5125 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5126 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5127 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5128 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5129 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5130 || GET_MODE (operands[3]) == VOIDmode)"
5131 "#"
5132 "&& reload_completed"
5133 [(const_int 0)]
5134 {
5135 rtx pat;
5136 operands[0] = gen_lowpart (SImode, operands[0]);
5137 operands[1] = gen_lowpart (Pmode, operands[1]);
5138 operands[3] = gen_lowpart (Pmode, operands[3]);
5139 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5140 operands[3]);
5141 if (Pmode != SImode)
5142 pat = gen_rtx_SUBREG (SImode, pat, 0);
5143 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5144 DONE;
5145 }
5146 [(set_attr "type" "lea")
5147 (set_attr "mode" "SI")])
5148
5149 (define_insn_and_split "*lea_general_2_zext"
5150 [(set (match_operand:DI 0 "register_operand" "=r")
5151 (zero_extend:DI
5152 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5153 (match_operand:SI 2 "const248_operand" "n"))
5154 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5155 "TARGET_64BIT"
5156 "#"
5157 "&& reload_completed"
5158 [(set (match_dup 0)
5159 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5160 (match_dup 2))
5161 (match_dup 3)) 0)))]
5162 {
5163 operands[1] = gen_lowpart (Pmode, operands[1]);
5164 operands[3] = gen_lowpart (Pmode, operands[3]);
5165 }
5166 [(set_attr "type" "lea")
5167 (set_attr "mode" "SI")])
5168
5169 (define_insn_and_split "*lea_general_3"
5170 [(set (match_operand 0 "register_operand" "=r")
5171 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5172 (match_operand 2 "const248_operand" "i"))
5173 (match_operand 3 "register_operand" "r"))
5174 (match_operand 4 "immediate_operand" "i")))]
5175 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5176 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5177 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5178 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5179 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5180 "#"
5181 "&& reload_completed"
5182 [(const_int 0)]
5183 {
5184 rtx pat;
5185 operands[0] = gen_lowpart (SImode, operands[0]);
5186 operands[1] = gen_lowpart (Pmode, operands[1]);
5187 operands[3] = gen_lowpart (Pmode, operands[3]);
5188 operands[4] = gen_lowpart (Pmode, operands[4]);
5189 pat = gen_rtx_PLUS (Pmode,
5190 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5191 operands[2]),
5192 operands[3]),
5193 operands[4]);
5194 if (Pmode != SImode)
5195 pat = gen_rtx_SUBREG (SImode, pat, 0);
5196 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5197 DONE;
5198 }
5199 [(set_attr "type" "lea")
5200 (set_attr "mode" "SI")])
5201
5202 (define_insn_and_split "*lea_general_3_zext"
5203 [(set (match_operand:DI 0 "register_operand" "=r")
5204 (zero_extend:DI
5205 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5206 (match_operand:SI 2 "const248_operand" "n"))
5207 (match_operand:SI 3 "register_operand" "r"))
5208 (match_operand:SI 4 "immediate_operand" "i"))))]
5209 "TARGET_64BIT"
5210 "#"
5211 "&& reload_completed"
5212 [(set (match_dup 0)
5213 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5214 (match_dup 2))
5215 (match_dup 3))
5216 (match_dup 4)) 0)))]
5217 {
5218 operands[1] = gen_lowpart (Pmode, operands[1]);
5219 operands[3] = gen_lowpart (Pmode, operands[3]);
5220 operands[4] = gen_lowpart (Pmode, operands[4]);
5221 }
5222 [(set_attr "type" "lea")
5223 (set_attr "mode" "SI")])
5224
5225 (define_insn "*adddi_1_rex64"
5226 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5227 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5228 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5229 (clobber (reg:CC 17))]
5230 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5231 {
5232 switch (get_attr_type (insn))
5233 {
5234 case TYPE_LEA:
5235 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5236 return "lea{q}\t{%a2, %0|%0, %a2}";
5237
5238 case TYPE_INCDEC:
5239 if (! rtx_equal_p (operands[0], operands[1]))
5240 abort ();
5241 if (operands[2] == const1_rtx)
5242 return "inc{q}\t%0";
5243 else if (operands[2] == constm1_rtx)
5244 return "dec{q}\t%0";
5245 else
5246 abort ();
5247
5248 default:
5249 if (! rtx_equal_p (operands[0], operands[1]))
5250 abort ();
5251
5252 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5253 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5254 if (GET_CODE (operands[2]) == CONST_INT
5255 /* Avoid overflows. */
5256 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5257 && (INTVAL (operands[2]) == 128
5258 || (INTVAL (operands[2]) < 0
5259 && INTVAL (operands[2]) != -128)))
5260 {
5261 operands[2] = GEN_INT (-INTVAL (operands[2]));
5262 return "sub{q}\t{%2, %0|%0, %2}";
5263 }
5264 return "add{q}\t{%2, %0|%0, %2}";
5265 }
5266 }
5267 [(set (attr "type")
5268 (cond [(eq_attr "alternative" "2")
5269 (const_string "lea")
5270 ; Current assemblers are broken and do not allow @GOTOFF in
5271 ; ought but a memory context.
5272 (match_operand:DI 2 "pic_symbolic_operand" "")
5273 (const_string "lea")
5274 (match_operand:DI 2 "incdec_operand" "")
5275 (const_string "incdec")
5276 ]
5277 (const_string "alu")))
5278 (set_attr "mode" "DI")])
5279
5280 ;; Convert lea to the lea pattern to avoid flags dependency.
5281 (define_split
5282 [(set (match_operand:DI 0 "register_operand" "")
5283 (plus:DI (match_operand:DI 1 "register_operand" "")
5284 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5285 (clobber (reg:CC 17))]
5286 "TARGET_64BIT && reload_completed
5287 && true_regnum (operands[0]) != true_regnum (operands[1])"
5288 [(set (match_dup 0)
5289 (plus:DI (match_dup 1)
5290 (match_dup 2)))]
5291 "")
5292
5293 (define_insn "*adddi_2_rex64"
5294 [(set (reg 17)
5295 (compare
5296 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5297 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5298 (const_int 0)))
5299 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5300 (plus:DI (match_dup 1) (match_dup 2)))]
5301 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5302 && ix86_binary_operator_ok (PLUS, DImode, operands)
5303 /* Current assemblers are broken and do not allow @GOTOFF in
5304 ought but a memory context. */
5305 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5306 {
5307 switch (get_attr_type (insn))
5308 {
5309 case TYPE_INCDEC:
5310 if (! rtx_equal_p (operands[0], operands[1]))
5311 abort ();
5312 if (operands[2] == const1_rtx)
5313 return "inc{q}\t%0";
5314 else if (operands[2] == constm1_rtx)
5315 return "dec{q}\t%0";
5316 else
5317 abort ();
5318
5319 default:
5320 if (! rtx_equal_p (operands[0], operands[1]))
5321 abort ();
5322 /* ???? We ought to handle there the 32bit case too
5323 - do we need new constrant? */
5324 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5325 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5326 if (GET_CODE (operands[2]) == CONST_INT
5327 /* Avoid overflows. */
5328 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5329 && (INTVAL (operands[2]) == 128
5330 || (INTVAL (operands[2]) < 0
5331 && INTVAL (operands[2]) != -128)))
5332 {
5333 operands[2] = GEN_INT (-INTVAL (operands[2]));
5334 return "sub{q}\t{%2, %0|%0, %2}";
5335 }
5336 return "add{q}\t{%2, %0|%0, %2}";
5337 }
5338 }
5339 [(set (attr "type")
5340 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5341 (const_string "incdec")
5342 (const_string "alu")))
5343 (set_attr "mode" "DI")])
5344
5345 (define_insn "*adddi_3_rex64"
5346 [(set (reg 17)
5347 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5348 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5349 (clobber (match_scratch:DI 0 "=r"))]
5350 "TARGET_64BIT
5351 && ix86_match_ccmode (insn, CCZmode)
5352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5353 /* Current assemblers are broken and do not allow @GOTOFF in
5354 ought but a memory context. */
5355 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5356 {
5357 switch (get_attr_type (insn))
5358 {
5359 case TYPE_INCDEC:
5360 if (! rtx_equal_p (operands[0], operands[1]))
5361 abort ();
5362 if (operands[2] == const1_rtx)
5363 return "inc{q}\t%0";
5364 else if (operands[2] == constm1_rtx)
5365 return "dec{q}\t%0";
5366 else
5367 abort ();
5368
5369 default:
5370 if (! rtx_equal_p (operands[0], operands[1]))
5371 abort ();
5372 /* ???? We ought to handle there the 32bit case too
5373 - do we need new constrant? */
5374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5376 if (GET_CODE (operands[2]) == CONST_INT
5377 /* Avoid overflows. */
5378 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5379 && (INTVAL (operands[2]) == 128
5380 || (INTVAL (operands[2]) < 0
5381 && INTVAL (operands[2]) != -128)))
5382 {
5383 operands[2] = GEN_INT (-INTVAL (operands[2]));
5384 return "sub{q}\t{%2, %0|%0, %2}";
5385 }
5386 return "add{q}\t{%2, %0|%0, %2}";
5387 }
5388 }
5389 [(set (attr "type")
5390 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5391 (const_string "incdec")
5392 (const_string "alu")))
5393 (set_attr "mode" "DI")])
5394
5395 ; For comparisons against 1, -1 and 128, we may generate better code
5396 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5397 ; is matched then. We can't accept general immediate, because for
5398 ; case of overflows, the result is messed up.
5399 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5400 ; when negated.
5401 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5402 ; only for comparisons not depending on it.
5403 (define_insn "*adddi_4_rex64"
5404 [(set (reg 17)
5405 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5406 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5407 (clobber (match_scratch:DI 0 "=rm"))]
5408 "TARGET_64BIT
5409 && ix86_match_ccmode (insn, CCGCmode)"
5410 {
5411 switch (get_attr_type (insn))
5412 {
5413 case TYPE_INCDEC:
5414 if (operands[2] == constm1_rtx)
5415 return "inc{q}\t%0";
5416 else if (operands[2] == const1_rtx)
5417 return "dec{q}\t%0";
5418 else
5419 abort();
5420
5421 default:
5422 if (! rtx_equal_p (operands[0], operands[1]))
5423 abort ();
5424 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5425 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5426 if ((INTVAL (operands[2]) == -128
5427 || (INTVAL (operands[2]) > 0
5428 && INTVAL (operands[2]) != 128))
5429 /* Avoid overflows. */
5430 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5431 return "sub{q}\t{%2, %0|%0, %2}";
5432 operands[2] = GEN_INT (-INTVAL (operands[2]));
5433 return "add{q}\t{%2, %0|%0, %2}";
5434 }
5435 }
5436 [(set (attr "type")
5437 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5438 (const_string "incdec")
5439 (const_string "alu")))
5440 (set_attr "mode" "DI")])
5441
5442 (define_insn "*adddi_5_rex64"
5443 [(set (reg 17)
5444 (compare
5445 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5446 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5447 (const_int 0)))
5448 (clobber (match_scratch:DI 0 "=r"))]
5449 "TARGET_64BIT
5450 && ix86_match_ccmode (insn, CCGOCmode)
5451 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5452 /* Current assemblers are broken and do not allow @GOTOFF in
5453 ought but a memory context. */
5454 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5455 {
5456 switch (get_attr_type (insn))
5457 {
5458 case TYPE_INCDEC:
5459 if (! rtx_equal_p (operands[0], operands[1]))
5460 abort ();
5461 if (operands[2] == const1_rtx)
5462 return "inc{q}\t%0";
5463 else if (operands[2] == constm1_rtx)
5464 return "dec{q}\t%0";
5465 else
5466 abort();
5467
5468 default:
5469 if (! rtx_equal_p (operands[0], operands[1]))
5470 abort ();
5471 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5472 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5473 if (GET_CODE (operands[2]) == CONST_INT
5474 /* Avoid overflows. */
5475 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5476 && (INTVAL (operands[2]) == 128
5477 || (INTVAL (operands[2]) < 0
5478 && INTVAL (operands[2]) != -128)))
5479 {
5480 operands[2] = GEN_INT (-INTVAL (operands[2]));
5481 return "sub{q}\t{%2, %0|%0, %2}";
5482 }
5483 return "add{q}\t{%2, %0|%0, %2}";
5484 }
5485 }
5486 [(set (attr "type")
5487 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5488 (const_string "incdec")
5489 (const_string "alu")))
5490 (set_attr "mode" "DI")])
5491
5492
5493 (define_insn "*addsi_1"
5494 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5495 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5496 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5497 (clobber (reg:CC 17))]
5498 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5499 {
5500 switch (get_attr_type (insn))
5501 {
5502 case TYPE_LEA:
5503 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5504 return "lea{l}\t{%a2, %0|%0, %a2}";
5505
5506 case TYPE_INCDEC:
5507 if (! rtx_equal_p (operands[0], operands[1]))
5508 abort ();
5509 if (operands[2] == const1_rtx)
5510 return "inc{l}\t%0";
5511 else if (operands[2] == constm1_rtx)
5512 return "dec{l}\t%0";
5513 else
5514 abort();
5515
5516 default:
5517 if (! rtx_equal_p (operands[0], operands[1]))
5518 abort ();
5519
5520 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5521 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5522 if (GET_CODE (operands[2]) == CONST_INT
5523 && (INTVAL (operands[2]) == 128
5524 || (INTVAL (operands[2]) < 0
5525 && INTVAL (operands[2]) != -128)))
5526 {
5527 operands[2] = GEN_INT (-INTVAL (operands[2]));
5528 return "sub{l}\t{%2, %0|%0, %2}";
5529 }
5530 return "add{l}\t{%2, %0|%0, %2}";
5531 }
5532 }
5533 [(set (attr "type")
5534 (cond [(eq_attr "alternative" "2")
5535 (const_string "lea")
5536 ; Current assemblers are broken and do not allow @GOTOFF in
5537 ; ought but a memory context.
5538 (match_operand:SI 2 "pic_symbolic_operand" "")
5539 (const_string "lea")
5540 (match_operand:SI 2 "incdec_operand" "")
5541 (const_string "incdec")
5542 ]
5543 (const_string "alu")))
5544 (set_attr "mode" "SI")])
5545
5546 ;; Convert lea to the lea pattern to avoid flags dependency.
5547 (define_split
5548 [(set (match_operand 0 "register_operand" "")
5549 (plus (match_operand 1 "register_operand" "")
5550 (match_operand 2 "nonmemory_operand" "")))
5551 (clobber (reg:CC 17))]
5552 "reload_completed
5553 && true_regnum (operands[0]) != true_regnum (operands[1])"
5554 [(const_int 0)]
5555 {
5556 rtx pat;
5557 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5558 may confuse gen_lowpart. */
5559 if (GET_MODE (operands[0]) != Pmode)
5560 {
5561 operands[1] = gen_lowpart (Pmode, operands[1]);
5562 operands[2] = gen_lowpart (Pmode, operands[2]);
5563 }
5564 operands[0] = gen_lowpart (SImode, operands[0]);
5565 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5566 if (Pmode != SImode)
5567 pat = gen_rtx_SUBREG (SImode, pat, 0);
5568 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5569 DONE;
5570 })
5571
5572 ;; It may seem that nonimmediate operand is proper one for operand 1.
5573 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5574 ;; we take care in ix86_binary_operator_ok to not allow two memory
5575 ;; operands so proper swapping will be done in reload. This allow
5576 ;; patterns constructed from addsi_1 to match.
5577 (define_insn "addsi_1_zext"
5578 [(set (match_operand:DI 0 "register_operand" "=r,r")
5579 (zero_extend:DI
5580 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5581 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5582 (clobber (reg:CC 17))]
5583 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5584 {
5585 switch (get_attr_type (insn))
5586 {
5587 case TYPE_LEA:
5588 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5589 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5590
5591 case TYPE_INCDEC:
5592 if (operands[2] == const1_rtx)
5593 return "inc{l}\t%k0";
5594 else if (operands[2] == constm1_rtx)
5595 return "dec{l}\t%k0";
5596 else
5597 abort();
5598
5599 default:
5600 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5602 if (GET_CODE (operands[2]) == CONST_INT
5603 && (INTVAL (operands[2]) == 128
5604 || (INTVAL (operands[2]) < 0
5605 && INTVAL (operands[2]) != -128)))
5606 {
5607 operands[2] = GEN_INT (-INTVAL (operands[2]));
5608 return "sub{l}\t{%2, %k0|%k0, %2}";
5609 }
5610 return "add{l}\t{%2, %k0|%k0, %2}";
5611 }
5612 }
5613 [(set (attr "type")
5614 (cond [(eq_attr "alternative" "1")
5615 (const_string "lea")
5616 ; Current assemblers are broken and do not allow @GOTOFF in
5617 ; ought but a memory context.
5618 (match_operand:SI 2 "pic_symbolic_operand" "")
5619 (const_string "lea")
5620 (match_operand:SI 2 "incdec_operand" "")
5621 (const_string "incdec")
5622 ]
5623 (const_string "alu")))
5624 (set_attr "mode" "SI")])
5625
5626 ;; Convert lea to the lea pattern to avoid flags dependency.
5627 (define_split
5628 [(set (match_operand:DI 0 "register_operand" "")
5629 (zero_extend:DI
5630 (plus:SI (match_operand:SI 1 "register_operand" "")
5631 (match_operand:SI 2 "nonmemory_operand" ""))))
5632 (clobber (reg:CC 17))]
5633 "reload_completed
5634 && true_regnum (operands[0]) != true_regnum (operands[1])"
5635 [(set (match_dup 0)
5636 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5637 {
5638 operands[1] = gen_lowpart (Pmode, operands[1]);
5639 operands[2] = gen_lowpart (Pmode, operands[2]);
5640 })
5641
5642 (define_insn "*addsi_2"
5643 [(set (reg 17)
5644 (compare
5645 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5646 (match_operand:SI 2 "general_operand" "rmni,rni"))
5647 (const_int 0)))
5648 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5649 (plus:SI (match_dup 1) (match_dup 2)))]
5650 "ix86_match_ccmode (insn, CCGOCmode)
5651 && ix86_binary_operator_ok (PLUS, SImode, operands)
5652 /* Current assemblers are broken and do not allow @GOTOFF in
5653 ought but a memory context. */
5654 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5655 {
5656 switch (get_attr_type (insn))
5657 {
5658 case TYPE_INCDEC:
5659 if (! rtx_equal_p (operands[0], operands[1]))
5660 abort ();
5661 if (operands[2] == const1_rtx)
5662 return "inc{l}\t%0";
5663 else if (operands[2] == constm1_rtx)
5664 return "dec{l}\t%0";
5665 else
5666 abort();
5667
5668 default:
5669 if (! rtx_equal_p (operands[0], operands[1]))
5670 abort ();
5671 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5672 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5673 if (GET_CODE (operands[2]) == CONST_INT
5674 && (INTVAL (operands[2]) == 128
5675 || (INTVAL (operands[2]) < 0
5676 && INTVAL (operands[2]) != -128)))
5677 {
5678 operands[2] = GEN_INT (-INTVAL (operands[2]));
5679 return "sub{l}\t{%2, %0|%0, %2}";
5680 }
5681 return "add{l}\t{%2, %0|%0, %2}";
5682 }
5683 }
5684 [(set (attr "type")
5685 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5686 (const_string "incdec")
5687 (const_string "alu")))
5688 (set_attr "mode" "SI")])
5689
5690 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5691 (define_insn "*addsi_2_zext"
5692 [(set (reg 17)
5693 (compare
5694 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5695 (match_operand:SI 2 "general_operand" "rmni"))
5696 (const_int 0)))
5697 (set (match_operand:DI 0 "register_operand" "=r")
5698 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5699 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5700 && ix86_binary_operator_ok (PLUS, SImode, operands)
5701 /* Current assemblers are broken and do not allow @GOTOFF in
5702 ought but a memory context. */
5703 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5704 {
5705 switch (get_attr_type (insn))
5706 {
5707 case TYPE_INCDEC:
5708 if (operands[2] == const1_rtx)
5709 return "inc{l}\t%k0";
5710 else if (operands[2] == constm1_rtx)
5711 return "dec{l}\t%k0";
5712 else
5713 abort();
5714
5715 default:
5716 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5718 if (GET_CODE (operands[2]) == CONST_INT
5719 && (INTVAL (operands[2]) == 128
5720 || (INTVAL (operands[2]) < 0
5721 && INTVAL (operands[2]) != -128)))
5722 {
5723 operands[2] = GEN_INT (-INTVAL (operands[2]));
5724 return "sub{l}\t{%2, %k0|%k0, %2}";
5725 }
5726 return "add{l}\t{%2, %k0|%k0, %2}";
5727 }
5728 }
5729 [(set (attr "type")
5730 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5731 (const_string "incdec")
5732 (const_string "alu")))
5733 (set_attr "mode" "SI")])
5734
5735 (define_insn "*addsi_3"
5736 [(set (reg 17)
5737 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5738 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5739 (clobber (match_scratch:SI 0 "=r"))]
5740 "ix86_match_ccmode (insn, CCZmode)
5741 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5742 /* Current assemblers are broken and do not allow @GOTOFF in
5743 ought but a memory context. */
5744 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5745 {
5746 switch (get_attr_type (insn))
5747 {
5748 case TYPE_INCDEC:
5749 if (! rtx_equal_p (operands[0], operands[1]))
5750 abort ();
5751 if (operands[2] == const1_rtx)
5752 return "inc{l}\t%0";
5753 else if (operands[2] == constm1_rtx)
5754 return "dec{l}\t%0";
5755 else
5756 abort();
5757
5758 default:
5759 if (! rtx_equal_p (operands[0], operands[1]))
5760 abort ();
5761 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5762 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5763 if (GET_CODE (operands[2]) == CONST_INT
5764 && (INTVAL (operands[2]) == 128
5765 || (INTVAL (operands[2]) < 0
5766 && INTVAL (operands[2]) != -128)))
5767 {
5768 operands[2] = GEN_INT (-INTVAL (operands[2]));
5769 return "sub{l}\t{%2, %0|%0, %2}";
5770 }
5771 return "add{l}\t{%2, %0|%0, %2}";
5772 }
5773 }
5774 [(set (attr "type")
5775 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5776 (const_string "incdec")
5777 (const_string "alu")))
5778 (set_attr "mode" "SI")])
5779
5780 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5781 (define_insn "*addsi_3_zext"
5782 [(set (reg 17)
5783 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5784 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5785 (set (match_operand:DI 0 "register_operand" "=r")
5786 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5787 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5788 && ix86_binary_operator_ok (PLUS, SImode, operands)
5789 /* Current assemblers are broken and do not allow @GOTOFF in
5790 ought but a memory context. */
5791 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5792 {
5793 switch (get_attr_type (insn))
5794 {
5795 case TYPE_INCDEC:
5796 if (operands[2] == const1_rtx)
5797 return "inc{l}\t%k0";
5798 else if (operands[2] == constm1_rtx)
5799 return "dec{l}\t%k0";
5800 else
5801 abort();
5802
5803 default:
5804 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5805 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5806 if (GET_CODE (operands[2]) == CONST_INT
5807 && (INTVAL (operands[2]) == 128
5808 || (INTVAL (operands[2]) < 0
5809 && INTVAL (operands[2]) != -128)))
5810 {
5811 operands[2] = GEN_INT (-INTVAL (operands[2]));
5812 return "sub{l}\t{%2, %k0|%k0, %2}";
5813 }
5814 return "add{l}\t{%2, %k0|%k0, %2}";
5815 }
5816 }
5817 [(set (attr "type")
5818 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5819 (const_string "incdec")
5820 (const_string "alu")))
5821 (set_attr "mode" "SI")])
5822
5823 ; For comparisons agains 1, -1 and 128, we may generate better code
5824 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5825 ; is matched then. We can't accept general immediate, because for
5826 ; case of overflows, the result is messed up.
5827 ; This pattern also don't hold of 0x80000000, since the value overflows
5828 ; when negated.
5829 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5830 ; only for comparisons not depending on it.
5831 (define_insn "*addsi_4"
5832 [(set (reg 17)
5833 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5834 (match_operand:SI 2 "const_int_operand" "n")))
5835 (clobber (match_scratch:SI 0 "=rm"))]
5836 "ix86_match_ccmode (insn, CCGCmode)
5837 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5838 {
5839 switch (get_attr_type (insn))
5840 {
5841 case TYPE_INCDEC:
5842 if (operands[2] == constm1_rtx)
5843 return "inc{l}\t%0";
5844 else if (operands[2] == const1_rtx)
5845 return "dec{l}\t%0";
5846 else
5847 abort();
5848
5849 default:
5850 if (! rtx_equal_p (operands[0], operands[1]))
5851 abort ();
5852 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5853 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5854 if ((INTVAL (operands[2]) == -128
5855 || (INTVAL (operands[2]) > 0
5856 && INTVAL (operands[2]) != 128)))
5857 return "sub{l}\t{%2, %0|%0, %2}";
5858 operands[2] = GEN_INT (-INTVAL (operands[2]));
5859 return "add{l}\t{%2, %0|%0, %2}";
5860 }
5861 }
5862 [(set (attr "type")
5863 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5864 (const_string "incdec")
5865 (const_string "alu")))
5866 (set_attr "mode" "SI")])
5867
5868 (define_insn "*addsi_5"
5869 [(set (reg 17)
5870 (compare
5871 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5872 (match_operand:SI 2 "general_operand" "rmni"))
5873 (const_int 0)))
5874 (clobber (match_scratch:SI 0 "=r"))]
5875 "ix86_match_ccmode (insn, CCGOCmode)
5876 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5877 /* Current assemblers are broken and do not allow @GOTOFF in
5878 ought but a memory context. */
5879 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5880 {
5881 switch (get_attr_type (insn))
5882 {
5883 case TYPE_INCDEC:
5884 if (! rtx_equal_p (operands[0], operands[1]))
5885 abort ();
5886 if (operands[2] == const1_rtx)
5887 return "inc{l}\t%0";
5888 else if (operands[2] == constm1_rtx)
5889 return "dec{l}\t%0";
5890 else
5891 abort();
5892
5893 default:
5894 if (! rtx_equal_p (operands[0], operands[1]))
5895 abort ();
5896 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5897 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5898 if (GET_CODE (operands[2]) == CONST_INT
5899 && (INTVAL (operands[2]) == 128
5900 || (INTVAL (operands[2]) < 0
5901 && INTVAL (operands[2]) != -128)))
5902 {
5903 operands[2] = GEN_INT (-INTVAL (operands[2]));
5904 return "sub{l}\t{%2, %0|%0, %2}";
5905 }
5906 return "add{l}\t{%2, %0|%0, %2}";
5907 }
5908 }
5909 [(set (attr "type")
5910 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5911 (const_string "incdec")
5912 (const_string "alu")))
5913 (set_attr "mode" "SI")])
5914
5915 (define_expand "addhi3"
5916 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5917 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5918 (match_operand:HI 2 "general_operand" "")))
5919 (clobber (reg:CC 17))])]
5920 "TARGET_HIMODE_MATH"
5921 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5922
5923 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5924 ;; type optimizations enabled by define-splits. This is not important
5925 ;; for PII, and in fact harmful because of partial register stalls.
5926
5927 (define_insn "*addhi_1_lea"
5928 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5929 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5930 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5931 (clobber (reg:CC 17))]
5932 "!TARGET_PARTIAL_REG_STALL
5933 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5934 {
5935 switch (get_attr_type (insn))
5936 {
5937 case TYPE_LEA:
5938 return "#";
5939 case TYPE_INCDEC:
5940 if (operands[2] == const1_rtx)
5941 return "inc{w}\t%0";
5942 else if (operands[2] == constm1_rtx)
5943 return "dec{w}\t%0";
5944 abort();
5945
5946 default:
5947 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5948 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5949 if (GET_CODE (operands[2]) == CONST_INT
5950 && (INTVAL (operands[2]) == 128
5951 || (INTVAL (operands[2]) < 0
5952 && INTVAL (operands[2]) != -128)))
5953 {
5954 operands[2] = GEN_INT (-INTVAL (operands[2]));
5955 return "sub{w}\t{%2, %0|%0, %2}";
5956 }
5957 return "add{w}\t{%2, %0|%0, %2}";
5958 }
5959 }
5960 [(set (attr "type")
5961 (if_then_else (eq_attr "alternative" "2")
5962 (const_string "lea")
5963 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5964 (const_string "incdec")
5965 (const_string "alu"))))
5966 (set_attr "mode" "HI,HI,SI")])
5967
5968 (define_insn "*addhi_1"
5969 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5970 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5971 (match_operand:HI 2 "general_operand" "ri,rm")))
5972 (clobber (reg:CC 17))]
5973 "TARGET_PARTIAL_REG_STALL
5974 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5975 {
5976 switch (get_attr_type (insn))
5977 {
5978 case TYPE_INCDEC:
5979 if (operands[2] == const1_rtx)
5980 return "inc{w}\t%0";
5981 else if (operands[2] == constm1_rtx)
5982 return "dec{w}\t%0";
5983 abort();
5984
5985 default:
5986 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5987 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5988 if (GET_CODE (operands[2]) == CONST_INT
5989 && (INTVAL (operands[2]) == 128
5990 || (INTVAL (operands[2]) < 0
5991 && INTVAL (operands[2]) != -128)))
5992 {
5993 operands[2] = GEN_INT (-INTVAL (operands[2]));
5994 return "sub{w}\t{%2, %0|%0, %2}";
5995 }
5996 return "add{w}\t{%2, %0|%0, %2}";
5997 }
5998 }
5999 [(set (attr "type")
6000 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001 (const_string "incdec")
6002 (const_string "alu")))
6003 (set_attr "mode" "HI")])
6004
6005 (define_insn "*addhi_2"
6006 [(set (reg 17)
6007 (compare
6008 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6009 (match_operand:HI 2 "general_operand" "rmni,rni"))
6010 (const_int 0)))
6011 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6012 (plus:HI (match_dup 1) (match_dup 2)))]
6013 "ix86_match_ccmode (insn, CCGOCmode)
6014 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6015 {
6016 switch (get_attr_type (insn))
6017 {
6018 case TYPE_INCDEC:
6019 if (operands[2] == const1_rtx)
6020 return "inc{w}\t%0";
6021 else if (operands[2] == constm1_rtx)
6022 return "dec{w}\t%0";
6023 abort();
6024
6025 default:
6026 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6027 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6028 if (GET_CODE (operands[2]) == CONST_INT
6029 && (INTVAL (operands[2]) == 128
6030 || (INTVAL (operands[2]) < 0
6031 && INTVAL (operands[2]) != -128)))
6032 {
6033 operands[2] = GEN_INT (-INTVAL (operands[2]));
6034 return "sub{w}\t{%2, %0|%0, %2}";
6035 }
6036 return "add{w}\t{%2, %0|%0, %2}";
6037 }
6038 }
6039 [(set (attr "type")
6040 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6041 (const_string "incdec")
6042 (const_string "alu")))
6043 (set_attr "mode" "HI")])
6044
6045 (define_insn "*addhi_3"
6046 [(set (reg 17)
6047 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6048 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6049 (clobber (match_scratch:HI 0 "=r"))]
6050 "ix86_match_ccmode (insn, CCZmode)
6051 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6052 {
6053 switch (get_attr_type (insn))
6054 {
6055 case TYPE_INCDEC:
6056 if (operands[2] == const1_rtx)
6057 return "inc{w}\t%0";
6058 else if (operands[2] == constm1_rtx)
6059 return "dec{w}\t%0";
6060 abort();
6061
6062 default:
6063 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6065 if (GET_CODE (operands[2]) == CONST_INT
6066 && (INTVAL (operands[2]) == 128
6067 || (INTVAL (operands[2]) < 0
6068 && INTVAL (operands[2]) != -128)))
6069 {
6070 operands[2] = GEN_INT (-INTVAL (operands[2]));
6071 return "sub{w}\t{%2, %0|%0, %2}";
6072 }
6073 return "add{w}\t{%2, %0|%0, %2}";
6074 }
6075 }
6076 [(set (attr "type")
6077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078 (const_string "incdec")
6079 (const_string "alu")))
6080 (set_attr "mode" "HI")])
6081
6082 ; See comments above addsi_3_imm for details.
6083 (define_insn "*addhi_4"
6084 [(set (reg 17)
6085 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6086 (match_operand:HI 2 "const_int_operand" "n")))
6087 (clobber (match_scratch:HI 0 "=rm"))]
6088 "ix86_match_ccmode (insn, CCGCmode)
6089 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6090 {
6091 switch (get_attr_type (insn))
6092 {
6093 case TYPE_INCDEC:
6094 if (operands[2] == constm1_rtx)
6095 return "inc{w}\t%0";
6096 else if (operands[2] == const1_rtx)
6097 return "dec{w}\t%0";
6098 else
6099 abort();
6100
6101 default:
6102 if (! rtx_equal_p (operands[0], operands[1]))
6103 abort ();
6104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6106 if ((INTVAL (operands[2]) == -128
6107 || (INTVAL (operands[2]) > 0
6108 && INTVAL (operands[2]) != 128)))
6109 return "sub{w}\t{%2, %0|%0, %2}";
6110 operands[2] = GEN_INT (-INTVAL (operands[2]));
6111 return "add{w}\t{%2, %0|%0, %2}";
6112 }
6113 }
6114 [(set (attr "type")
6115 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6116 (const_string "incdec")
6117 (const_string "alu")))
6118 (set_attr "mode" "SI")])
6119
6120
6121 (define_insn "*addhi_5"
6122 [(set (reg 17)
6123 (compare
6124 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6125 (match_operand:HI 2 "general_operand" "rmni"))
6126 (const_int 0)))
6127 (clobber (match_scratch:HI 0 "=r"))]
6128 "ix86_match_ccmode (insn, CCGOCmode)
6129 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6130 {
6131 switch (get_attr_type (insn))
6132 {
6133 case TYPE_INCDEC:
6134 if (operands[2] == const1_rtx)
6135 return "inc{w}\t%0";
6136 else if (operands[2] == constm1_rtx)
6137 return "dec{w}\t%0";
6138 abort();
6139
6140 default:
6141 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6143 if (GET_CODE (operands[2]) == CONST_INT
6144 && (INTVAL (operands[2]) == 128
6145 || (INTVAL (operands[2]) < 0
6146 && INTVAL (operands[2]) != -128)))
6147 {
6148 operands[2] = GEN_INT (-INTVAL (operands[2]));
6149 return "sub{w}\t{%2, %0|%0, %2}";
6150 }
6151 return "add{w}\t{%2, %0|%0, %2}";
6152 }
6153 }
6154 [(set (attr "type")
6155 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6156 (const_string "incdec")
6157 (const_string "alu")))
6158 (set_attr "mode" "HI")])
6159
6160 (define_expand "addqi3"
6161 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6162 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6163 (match_operand:QI 2 "general_operand" "")))
6164 (clobber (reg:CC 17))])]
6165 "TARGET_QIMODE_MATH"
6166 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6167
6168 ;; %%% Potential partial reg stall on alternative 2. What to do?
6169 (define_insn "*addqi_1_lea"
6170 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6171 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6172 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6173 (clobber (reg:CC 17))]
6174 "!TARGET_PARTIAL_REG_STALL
6175 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6176 {
6177 int widen = (which_alternative == 2);
6178 switch (get_attr_type (insn))
6179 {
6180 case TYPE_LEA:
6181 return "#";
6182 case TYPE_INCDEC:
6183 if (operands[2] == const1_rtx)
6184 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6185 else if (operands[2] == constm1_rtx)
6186 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6187 abort();
6188
6189 default:
6190 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6191 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6192 if (GET_CODE (operands[2]) == CONST_INT
6193 && (INTVAL (operands[2]) == 128
6194 || (INTVAL (operands[2]) < 0
6195 && INTVAL (operands[2]) != -128)))
6196 {
6197 operands[2] = GEN_INT (-INTVAL (operands[2]));
6198 if (widen)
6199 return "sub{l}\t{%2, %k0|%k0, %2}";
6200 else
6201 return "sub{b}\t{%2, %0|%0, %2}";
6202 }
6203 if (widen)
6204 return "add{l}\t{%k2, %k0|%k0, %k2}";
6205 else
6206 return "add{b}\t{%2, %0|%0, %2}";
6207 }
6208 }
6209 [(set (attr "type")
6210 (if_then_else (eq_attr "alternative" "3")
6211 (const_string "lea")
6212 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6213 (const_string "incdec")
6214 (const_string "alu"))))
6215 (set_attr "mode" "QI,QI,SI,SI")])
6216
6217 (define_insn "*addqi_1"
6218 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6219 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6220 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6221 (clobber (reg:CC 17))]
6222 "TARGET_PARTIAL_REG_STALL
6223 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6224 {
6225 int widen = (which_alternative == 2);
6226 switch (get_attr_type (insn))
6227 {
6228 case TYPE_INCDEC:
6229 if (operands[2] == const1_rtx)
6230 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6231 else if (operands[2] == constm1_rtx)
6232 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6233 abort();
6234
6235 default:
6236 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6237 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6238 if (GET_CODE (operands[2]) == CONST_INT
6239 && (INTVAL (operands[2]) == 128
6240 || (INTVAL (operands[2]) < 0
6241 && INTVAL (operands[2]) != -128)))
6242 {
6243 operands[2] = GEN_INT (-INTVAL (operands[2]));
6244 if (widen)
6245 return "sub{l}\t{%2, %k0|%k0, %2}";
6246 else
6247 return "sub{b}\t{%2, %0|%0, %2}";
6248 }
6249 if (widen)
6250 return "add{l}\t{%k2, %k0|%k0, %k2}";
6251 else
6252 return "add{b}\t{%2, %0|%0, %2}";
6253 }
6254 }
6255 [(set (attr "type")
6256 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu")))
6259 (set_attr "mode" "QI,QI,SI")])
6260
6261 (define_insn "*addqi_1_slp"
6262 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6263 (plus:QI (match_dup 0)
6264 (match_operand:QI 1 "general_operand" "qn,qnm")))
6265 (clobber (reg:CC 17))]
6266 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6267 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6268 {
6269 switch (get_attr_type (insn))
6270 {
6271 case TYPE_INCDEC:
6272 if (operands[1] == const1_rtx)
6273 return "inc{b}\t%0";
6274 else if (operands[1] == constm1_rtx)
6275 return "dec{b}\t%0";
6276 abort();
6277
6278 default:
6279 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6280 if (GET_CODE (operands[1]) == CONST_INT
6281 && INTVAL (operands[1]) < 0)
6282 {
6283 operands[2] = GEN_INT (-INTVAL (operands[2]));
6284 return "sub{b}\t{%1, %0|%0, %1}";
6285 }
6286 return "add{b}\t{%1, %0|%0, %1}";
6287 }
6288 }
6289 [(set (attr "type")
6290 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6291 (const_string "incdec")
6292 (const_string "alu1")))
6293 (set_attr "mode" "QI")])
6294
6295 (define_insn "*addqi_2"
6296 [(set (reg 17)
6297 (compare
6298 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6299 (match_operand:QI 2 "general_operand" "qmni,qni"))
6300 (const_int 0)))
6301 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6302 (plus:QI (match_dup 1) (match_dup 2)))]
6303 "ix86_match_ccmode (insn, CCGOCmode)
6304 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6305 {
6306 switch (get_attr_type (insn))
6307 {
6308 case TYPE_INCDEC:
6309 if (operands[2] == const1_rtx)
6310 return "inc{b}\t%0";
6311 else if (operands[2] == constm1_rtx
6312 || (GET_CODE (operands[2]) == CONST_INT
6313 && INTVAL (operands[2]) == 255))
6314 return "dec{b}\t%0";
6315 abort();
6316
6317 default:
6318 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6319 if (GET_CODE (operands[2]) == CONST_INT
6320 && INTVAL (operands[2]) < 0)
6321 {
6322 operands[2] = GEN_INT (-INTVAL (operands[2]));
6323 return "sub{b}\t{%2, %0|%0, %2}";
6324 }
6325 return "add{b}\t{%2, %0|%0, %2}";
6326 }
6327 }
6328 [(set (attr "type")
6329 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6330 (const_string "incdec")
6331 (const_string "alu")))
6332 (set_attr "mode" "QI")])
6333
6334 (define_insn "*addqi_3"
6335 [(set (reg 17)
6336 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6337 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6338 (clobber (match_scratch:QI 0 "=q"))]
6339 "ix86_match_ccmode (insn, CCZmode)
6340 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6341 {
6342 switch (get_attr_type (insn))
6343 {
6344 case TYPE_INCDEC:
6345 if (operands[2] == const1_rtx)
6346 return "inc{b}\t%0";
6347 else if (operands[2] == constm1_rtx
6348 || (GET_CODE (operands[2]) == CONST_INT
6349 && INTVAL (operands[2]) == 255))
6350 return "dec{b}\t%0";
6351 abort();
6352
6353 default:
6354 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6355 if (GET_CODE (operands[2]) == CONST_INT
6356 && INTVAL (operands[2]) < 0)
6357 {
6358 operands[2] = GEN_INT (-INTVAL (operands[2]));
6359 return "sub{b}\t{%2, %0|%0, %2}";
6360 }
6361 return "add{b}\t{%2, %0|%0, %2}";
6362 }
6363 }
6364 [(set (attr "type")
6365 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6366 (const_string "incdec")
6367 (const_string "alu")))
6368 (set_attr "mode" "QI")])
6369
6370 ; See comments above addsi_3_imm for details.
6371 (define_insn "*addqi_4"
6372 [(set (reg 17)
6373 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6374 (match_operand:QI 2 "const_int_operand" "n")))
6375 (clobber (match_scratch:QI 0 "=qm"))]
6376 "ix86_match_ccmode (insn, CCGCmode)
6377 && (INTVAL (operands[2]) & 0xff) != 0x80"
6378 {
6379 switch (get_attr_type (insn))
6380 {
6381 case TYPE_INCDEC:
6382 if (operands[2] == constm1_rtx
6383 || (GET_CODE (operands[2]) == CONST_INT
6384 && INTVAL (operands[2]) == 255))
6385 return "inc{b}\t%0";
6386 else if (operands[2] == const1_rtx)
6387 return "dec{b}\t%0";
6388 else
6389 abort();
6390
6391 default:
6392 if (! rtx_equal_p (operands[0], operands[1]))
6393 abort ();
6394 if (INTVAL (operands[2]) < 0)
6395 {
6396 operands[2] = GEN_INT (-INTVAL (operands[2]));
6397 return "add{b}\t{%2, %0|%0, %2}";
6398 }
6399 return "sub{b}\t{%2, %0|%0, %2}";
6400 }
6401 }
6402 [(set (attr "type")
6403 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6404 (const_string "incdec")
6405 (const_string "alu")))
6406 (set_attr "mode" "QI")])
6407
6408
6409 (define_insn "*addqi_5"
6410 [(set (reg 17)
6411 (compare
6412 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6413 (match_operand:QI 2 "general_operand" "qmni"))
6414 (const_int 0)))
6415 (clobber (match_scratch:QI 0 "=q"))]
6416 "ix86_match_ccmode (insn, CCGOCmode)
6417 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6418 {
6419 switch (get_attr_type (insn))
6420 {
6421 case TYPE_INCDEC:
6422 if (operands[2] == const1_rtx)
6423 return "inc{b}\t%0";
6424 else if (operands[2] == constm1_rtx
6425 || (GET_CODE (operands[2]) == CONST_INT
6426 && INTVAL (operands[2]) == 255))
6427 return "dec{b}\t%0";
6428 abort();
6429
6430 default:
6431 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6432 if (GET_CODE (operands[2]) == CONST_INT
6433 && INTVAL (operands[2]) < 0)
6434 {
6435 operands[2] = GEN_INT (-INTVAL (operands[2]));
6436 return "sub{b}\t{%2, %0|%0, %2}";
6437 }
6438 return "add{b}\t{%2, %0|%0, %2}";
6439 }
6440 }
6441 [(set (attr "type")
6442 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6443 (const_string "incdec")
6444 (const_string "alu")))
6445 (set_attr "mode" "QI")])
6446
6447
6448 (define_insn "addqi_ext_1"
6449 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450 (const_int 8)
6451 (const_int 8))
6452 (plus:SI
6453 (zero_extract:SI
6454 (match_operand 1 "ext_register_operand" "0")
6455 (const_int 8)
6456 (const_int 8))
6457 (match_operand:QI 2 "general_operand" "Qmn")))
6458 (clobber (reg:CC 17))]
6459 "!TARGET_64BIT"
6460 {
6461 switch (get_attr_type (insn))
6462 {
6463 case TYPE_INCDEC:
6464 if (operands[2] == const1_rtx)
6465 return "inc{b}\t%h0";
6466 else if (operands[2] == constm1_rtx
6467 || (GET_CODE (operands[2]) == CONST_INT
6468 && INTVAL (operands[2]) == 255))
6469 return "dec{b}\t%h0";
6470 abort();
6471
6472 default:
6473 return "add{b}\t{%2, %h0|%h0, %2}";
6474 }
6475 }
6476 [(set (attr "type")
6477 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6478 (const_string "incdec")
6479 (const_string "alu")))
6480 (set_attr "mode" "QI")])
6481
6482 (define_insn "*addqi_ext_1_rex64"
6483 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6484 (const_int 8)
6485 (const_int 8))
6486 (plus:SI
6487 (zero_extract:SI
6488 (match_operand 1 "ext_register_operand" "0")
6489 (const_int 8)
6490 (const_int 8))
6491 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6492 (clobber (reg:CC 17))]
6493 "TARGET_64BIT"
6494 {
6495 switch (get_attr_type (insn))
6496 {
6497 case TYPE_INCDEC:
6498 if (operands[2] == const1_rtx)
6499 return "inc{b}\t%h0";
6500 else if (operands[2] == constm1_rtx
6501 || (GET_CODE (operands[2]) == CONST_INT
6502 && INTVAL (operands[2]) == 255))
6503 return "dec{b}\t%h0";
6504 abort();
6505
6506 default:
6507 return "add{b}\t{%2, %h0|%h0, %2}";
6508 }
6509 }
6510 [(set (attr "type")
6511 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6512 (const_string "incdec")
6513 (const_string "alu")))
6514 (set_attr "mode" "QI")])
6515
6516 (define_insn "*addqi_ext_2"
6517 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6518 (const_int 8)
6519 (const_int 8))
6520 (plus:SI
6521 (zero_extract:SI
6522 (match_operand 1 "ext_register_operand" "%0")
6523 (const_int 8)
6524 (const_int 8))
6525 (zero_extract:SI
6526 (match_operand 2 "ext_register_operand" "Q")
6527 (const_int 8)
6528 (const_int 8))))
6529 (clobber (reg:CC 17))]
6530 ""
6531 "add{b}\t{%h2, %h0|%h0, %h2}"
6532 [(set_attr "type" "alu")
6533 (set_attr "mode" "QI")])
6534
6535 ;; The patterns that match these are at the end of this file.
6536
6537 (define_expand "addxf3"
6538 [(set (match_operand:XF 0 "register_operand" "")
6539 (plus:XF (match_operand:XF 1 "register_operand" "")
6540 (match_operand:XF 2 "register_operand" "")))]
6541 "!TARGET_64BIT && TARGET_80387"
6542 "")
6543
6544 (define_expand "addtf3"
6545 [(set (match_operand:TF 0 "register_operand" "")
6546 (plus:TF (match_operand:TF 1 "register_operand" "")
6547 (match_operand:TF 2 "register_operand" "")))]
6548 "TARGET_80387"
6549 "")
6550
6551 (define_expand "adddf3"
6552 [(set (match_operand:DF 0 "register_operand" "")
6553 (plus:DF (match_operand:DF 1 "register_operand" "")
6554 (match_operand:DF 2 "nonimmediate_operand" "")))]
6555 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6556 "")
6557
6558 (define_expand "addsf3"
6559 [(set (match_operand:SF 0 "register_operand" "")
6560 (plus:SF (match_operand:SF 1 "register_operand" "")
6561 (match_operand:SF 2 "nonimmediate_operand" "")))]
6562 "TARGET_80387 || TARGET_SSE_MATH"
6563 "")
6564 \f
6565 ;; Subtract instructions
6566
6567 ;; %%% splits for subsidi3
6568
6569 (define_expand "subdi3"
6570 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6571 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6572 (match_operand:DI 2 "x86_64_general_operand" "")))
6573 (clobber (reg:CC 17))])]
6574 ""
6575 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6576
6577 (define_insn "*subdi3_1"
6578 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6579 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6580 (match_operand:DI 2 "general_operand" "roiF,riF")))
6581 (clobber (reg:CC 17))]
6582 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6583 "#")
6584
6585 (define_split
6586 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6587 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6588 (match_operand:DI 2 "general_operand" "")))
6589 (clobber (reg:CC 17))]
6590 "!TARGET_64BIT && reload_completed"
6591 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6592 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6593 (parallel [(set (match_dup 3)
6594 (minus:SI (match_dup 4)
6595 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6596 (match_dup 5))))
6597 (clobber (reg:CC 17))])]
6598 "split_di (operands+0, 1, operands+0, operands+3);
6599 split_di (operands+1, 1, operands+1, operands+4);
6600 split_di (operands+2, 1, operands+2, operands+5);")
6601
6602 (define_insn "subdi3_carry_rex64"
6603 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6604 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6605 (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6606 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6607 (clobber (reg:CC 17))]
6608 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6609 "sbb{q}\t{%2, %0|%0, %2}"
6610 [(set_attr "type" "alu")
6611 (set_attr "pent_pair" "pu")
6612 (set_attr "ppro_uops" "few")
6613 (set_attr "mode" "DI")])
6614
6615 (define_insn "*subdi_1_rex64"
6616 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6617 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6618 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6619 (clobber (reg:CC 17))]
6620 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6621 "sub{q}\t{%2, %0|%0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "mode" "DI")])
6624
6625 (define_insn "*subdi_2_rex64"
6626 [(set (reg 17)
6627 (compare
6628 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6629 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6630 (const_int 0)))
6631 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6632 (minus:DI (match_dup 1) (match_dup 2)))]
6633 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6634 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6635 "sub{q}\t{%2, %0|%0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "mode" "DI")])
6638
6639 (define_insn "*subdi_3_rex63"
6640 [(set (reg 17)
6641 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6642 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6643 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6644 (minus:DI (match_dup 1) (match_dup 2)))]
6645 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6646 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6647 "sub{q}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "mode" "DI")])
6650
6651
6652 (define_insn "subsi3_carry"
6653 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6654 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6655 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6656 (match_operand:SI 2 "general_operand" "ri,rm"))))
6657 (clobber (reg:CC 17))]
6658 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6659 "sbb{l}\t{%2, %0|%0, %2}"
6660 [(set_attr "type" "alu")
6661 (set_attr "pent_pair" "pu")
6662 (set_attr "ppro_uops" "few")
6663 (set_attr "mode" "SI")])
6664
6665 (define_insn "subsi3_carry_zext"
6666 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6667 (zero_extend:DI
6668 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6669 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6670 (match_operand:SI 2 "general_operand" "ri,rm")))))
6671 (clobber (reg:CC 17))]
6672 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6673 "sbb{l}\t{%2, %k0|%k0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "pent_pair" "pu")
6676 (set_attr "ppro_uops" "few")
6677 (set_attr "mode" "SI")])
6678
6679 (define_expand "subsi3"
6680 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6681 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6682 (match_operand:SI 2 "general_operand" "")))
6683 (clobber (reg:CC 17))])]
6684 ""
6685 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6686
6687 (define_insn "*subsi_1"
6688 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6689 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6690 (match_operand:SI 2 "general_operand" "ri,rm")))
6691 (clobber (reg:CC 17))]
6692 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6693 "sub{l}\t{%2, %0|%0, %2}"
6694 [(set_attr "type" "alu")
6695 (set_attr "mode" "SI")])
6696
6697 (define_insn "*subsi_1_zext"
6698 [(set (match_operand:DI 0 "register_operand" "=r")
6699 (zero_extend:DI
6700 (minus:SI (match_operand:SI 1 "register_operand" "0")
6701 (match_operand:SI 2 "general_operand" "rim"))))
6702 (clobber (reg:CC 17))]
6703 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6704 "sub{l}\t{%2, %k0|%k0, %2}"
6705 [(set_attr "type" "alu")
6706 (set_attr "mode" "SI")])
6707
6708 (define_insn "*subsi_2"
6709 [(set (reg 17)
6710 (compare
6711 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6712 (match_operand:SI 2 "general_operand" "ri,rm"))
6713 (const_int 0)))
6714 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6715 (minus:SI (match_dup 1) (match_dup 2)))]
6716 "ix86_match_ccmode (insn, CCGOCmode)
6717 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6718 "sub{l}\t{%2, %0|%0, %2}"
6719 [(set_attr "type" "alu")
6720 (set_attr "mode" "SI")])
6721
6722 (define_insn "*subsi_2_zext"
6723 [(set (reg 17)
6724 (compare
6725 (minus:SI (match_operand:SI 1 "register_operand" "0")
6726 (match_operand:SI 2 "general_operand" "rim"))
6727 (const_int 0)))
6728 (set (match_operand:DI 0 "register_operand" "=r")
6729 (zero_extend:DI
6730 (minus:SI (match_dup 1)
6731 (match_dup 2))))]
6732 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6733 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6734 "sub{l}\t{%2, %k0|%k0, %2}"
6735 [(set_attr "type" "alu")
6736 (set_attr "mode" "SI")])
6737
6738 (define_insn "*subsi_3"
6739 [(set (reg 17)
6740 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6741 (match_operand:SI 2 "general_operand" "ri,rm")))
6742 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6743 (minus:SI (match_dup 1) (match_dup 2)))]
6744 "ix86_match_ccmode (insn, CCmode)
6745 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6746 "sub{l}\t{%2, %0|%0, %2}"
6747 [(set_attr "type" "alu")
6748 (set_attr "mode" "SI")])
6749
6750 (define_insn "*subsi_3_zext"
6751 [(set (reg 17)
6752 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6753 (match_operand:SI 2 "general_operand" "rim")))
6754 (set (match_operand:DI 0 "register_operand" "=r")
6755 (zero_extend:DI
6756 (minus:SI (match_dup 1)
6757 (match_dup 2))))]
6758 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6759 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6760 "sub{q}\t{%2, %0|%0, %2}"
6761 [(set_attr "type" "alu")
6762 (set_attr "mode" "DI")])
6763
6764 (define_expand "subhi3"
6765 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6766 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6767 (match_operand:HI 2 "general_operand" "")))
6768 (clobber (reg:CC 17))])]
6769 "TARGET_HIMODE_MATH"
6770 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6771
6772 (define_insn "*subhi_1"
6773 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6774 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6775 (match_operand:HI 2 "general_operand" "ri,rm")))
6776 (clobber (reg:CC 17))]
6777 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6778 "sub{w}\t{%2, %0|%0, %2}"
6779 [(set_attr "type" "alu")
6780 (set_attr "mode" "HI")])
6781
6782 (define_insn "*subhi_2"
6783 [(set (reg 17)
6784 (compare
6785 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:HI 2 "general_operand" "ri,rm"))
6787 (const_int 0)))
6788 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6789 (minus:HI (match_dup 1) (match_dup 2)))]
6790 "ix86_match_ccmode (insn, CCGOCmode)
6791 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6792 "sub{w}\t{%2, %0|%0, %2}"
6793 [(set_attr "type" "alu")
6794 (set_attr "mode" "HI")])
6795
6796 (define_insn "*subhi_3"
6797 [(set (reg 17)
6798 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6799 (match_operand:HI 2 "general_operand" "ri,rm")))
6800 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6801 (minus:HI (match_dup 1) (match_dup 2)))]
6802 "ix86_match_ccmode (insn, CCmode)
6803 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6804 "sub{w}\t{%2, %0|%0, %2}"
6805 [(set_attr "type" "alu")
6806 (set_attr "mode" "HI")])
6807
6808 (define_expand "subqi3"
6809 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6810 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6811 (match_operand:QI 2 "general_operand" "")))
6812 (clobber (reg:CC 17))])]
6813 "TARGET_QIMODE_MATH"
6814 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6815
6816 (define_insn "*subqi_1"
6817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6818 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6819 (match_operand:QI 2 "general_operand" "qn,qmn")))
6820 (clobber (reg:CC 17))]
6821 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6822 "sub{b}\t{%2, %0|%0, %2}"
6823 [(set_attr "type" "alu")
6824 (set_attr "mode" "QI")])
6825
6826 (define_insn "*subqi_1_slp"
6827 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6828 (minus:QI (match_dup 0)
6829 (match_operand:QI 1 "general_operand" "qn,qmn")))
6830 (clobber (reg:CC 17))]
6831 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6832 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6833 "sub{b}\t{%1, %0|%0, %1}"
6834 [(set_attr "type" "alu1")
6835 (set_attr "mode" "QI")])
6836
6837 (define_insn "*subqi_2"
6838 [(set (reg 17)
6839 (compare
6840 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6841 (match_operand:QI 2 "general_operand" "qi,qm"))
6842 (const_int 0)))
6843 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6844 (minus:HI (match_dup 1) (match_dup 2)))]
6845 "ix86_match_ccmode (insn, CCGOCmode)
6846 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6847 "sub{b}\t{%2, %0|%0, %2}"
6848 [(set_attr "type" "alu")
6849 (set_attr "mode" "QI")])
6850
6851 (define_insn "*subqi_3"
6852 [(set (reg 17)
6853 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6854 (match_operand:QI 2 "general_operand" "qi,qm")))
6855 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6856 (minus:HI (match_dup 1) (match_dup 2)))]
6857 "ix86_match_ccmode (insn, CCmode)
6858 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6859 "sub{b}\t{%2, %0|%0, %2}"
6860 [(set_attr "type" "alu")
6861 (set_attr "mode" "QI")])
6862
6863 ;; The patterns that match these are at the end of this file.
6864
6865 (define_expand "subxf3"
6866 [(set (match_operand:XF 0 "register_operand" "")
6867 (minus:XF (match_operand:XF 1 "register_operand" "")
6868 (match_operand:XF 2 "register_operand" "")))]
6869 "!TARGET_64BIT && TARGET_80387"
6870 "")
6871
6872 (define_expand "subtf3"
6873 [(set (match_operand:TF 0 "register_operand" "")
6874 (minus:TF (match_operand:TF 1 "register_operand" "")
6875 (match_operand:TF 2 "register_operand" "")))]
6876 "TARGET_80387"
6877 "")
6878
6879 (define_expand "subdf3"
6880 [(set (match_operand:DF 0 "register_operand" "")
6881 (minus:DF (match_operand:DF 1 "register_operand" "")
6882 (match_operand:DF 2 "nonimmediate_operand" "")))]
6883 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6884 "")
6885
6886 (define_expand "subsf3"
6887 [(set (match_operand:SF 0 "register_operand" "")
6888 (minus:SF (match_operand:SF 1 "register_operand" "")
6889 (match_operand:SF 2 "nonimmediate_operand" "")))]
6890 "TARGET_80387 || TARGET_SSE_MATH"
6891 "")
6892 \f
6893 ;; Multiply instructions
6894
6895 (define_expand "muldi3"
6896 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6897 (mult:DI (match_operand:DI 1 "register_operand" "")
6898 (match_operand:DI 2 "x86_64_general_operand" "")))
6899 (clobber (reg:CC 17))])]
6900 "TARGET_64BIT"
6901 "")
6902
6903 (define_insn "*muldi3_1_rex64"
6904 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6905 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
6906 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6907 (clobber (reg:CC 17))]
6908 "TARGET_64BIT
6909 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6910 "@
6911 imul{q}\t{%2, %1, %0|%0, %1, %2}
6912 imul{q}\t{%2, %1, %0|%0, %1, %2}
6913 imul{q}\t{%2, %0|%0, %2}"
6914 [(set_attr "type" "imul")
6915 (set_attr "prefix_0f" "0,0,1")
6916 (set_attr "mode" "DI")])
6917
6918 (define_expand "mulsi3"
6919 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6920 (mult:SI (match_operand:SI 1 "register_operand" "")
6921 (match_operand:SI 2 "general_operand" "")))
6922 (clobber (reg:CC 17))])]
6923 ""
6924 "")
6925
6926 (define_insn "*mulsi3_1"
6927 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6928 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
6929 (match_operand:SI 2 "general_operand" "K,i,mr")))
6930 (clobber (reg:CC 17))]
6931 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6932 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
6933 ; there are two ways of writing the exact same machine instruction
6934 ; in assembly language. One, for example, is:
6935 ;
6936 ; imul $12, %eax
6937 ;
6938 ; while the other is:
6939 ;
6940 ; imul $12, %eax, %eax
6941 ;
6942 ; The first is simply short-hand for the latter. But, some assemblers,
6943 ; like the SCO OSR5 COFF assembler, don't handle the first form.
6944 "@
6945 imul{l}\t{%2, %1, %0|%0, %1, %2}
6946 imul{l}\t{%2, %1, %0|%0, %1, %2}
6947 imul{l}\t{%2, %0|%0, %2}"
6948 [(set_attr "type" "imul")
6949 (set_attr "prefix_0f" "0,0,1")
6950 (set_attr "mode" "SI")])
6951
6952 (define_insn "*mulsi3_1_zext"
6953 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6954 (zero_extend:DI
6955 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
6956 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6957 (clobber (reg:CC 17))]
6958 "TARGET_64BIT
6959 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6960 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
6961 ; there are two ways of writing the exact same machine instruction
6962 ; in assembly language. One, for example, is:
6963 ;
6964 ; imul $12, %eax
6965 ;
6966 ; while the other is:
6967 ;
6968 ; imul $12, %eax, %eax
6969 ;
6970 ; The first is simply short-hand for the latter. But, some assemblers,
6971 ; like the SCO OSR5 COFF assembler, don't handle the first form.
6972 "@
6973 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6974 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6975 imul{l}\t{%2, %k0|%k0, %2}"
6976 [(set_attr "type" "imul")
6977 (set_attr "prefix_0f" "0,0,1")
6978 (set_attr "mode" "SI")])
6979
6980 (define_expand "mulhi3"
6981 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6982 (mult:HI (match_operand:HI 1 "register_operand" "")
6983 (match_operand:HI 2 "general_operand" "")))
6984 (clobber (reg:CC 17))])]
6985 "TARGET_HIMODE_MATH"
6986 "")
6987
6988 (define_insn "*mulhi3_1"
6989 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6990 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
6991 (match_operand:HI 2 "general_operand" "K,i,mr")))
6992 (clobber (reg:CC 17))]
6993 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6994 ; %%% There was a note about "Assembler has weird restrictions",
6995 ; concerning alternative 1 when op1 == op0. True?
6996 "@
6997 imul{w}\t{%2, %1, %0|%0, %1, %2}
6998 imul{w}\t{%2, %1, %0|%0, %1, %2}
6999 imul{w}\t{%2, %0|%0, %2}"
7000 [(set_attr "type" "imul")
7001 (set_attr "prefix_0f" "0,0,1")
7002 (set_attr "mode" "HI")])
7003
7004 (define_expand "mulqi3"
7005 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7006 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7007 (match_operand:QI 2 "register_operand" "")))
7008 (clobber (reg:CC 17))])]
7009 "TARGET_QIMODE_MATH"
7010 "")
7011
7012 (define_insn "*mulqi3_1"
7013 [(set (match_operand:QI 0 "register_operand" "=a")
7014 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7015 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7016 (clobber (reg:CC 17))]
7017 "TARGET_QIMODE_MATH
7018 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7019 "mul{b}\t%2"
7020 [(set_attr "type" "imul")
7021 (set_attr "length_immediate" "0")
7022 (set_attr "mode" "QI")])
7023
7024 (define_expand "umulqihi3"
7025 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7026 (mult:HI (zero_extend:HI
7027 (match_operand:QI 1 "nonimmediate_operand" ""))
7028 (zero_extend:HI
7029 (match_operand:QI 2 "register_operand" ""))))
7030 (clobber (reg:CC 17))])]
7031 "TARGET_QIMODE_MATH"
7032 "")
7033
7034 (define_insn "*umulqihi3_1"
7035 [(set (match_operand:HI 0 "register_operand" "=a")
7036 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7037 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7038 (clobber (reg:CC 17))]
7039 "TARGET_QIMODE_MATH
7040 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7041 "mul{b}\t%2"
7042 [(set_attr "type" "imul")
7043 (set_attr "length_immediate" "0")
7044 (set_attr "mode" "QI")])
7045
7046 (define_expand "mulqihi3"
7047 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7048 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7049 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7050 (clobber (reg:CC 17))])]
7051 "TARGET_QIMODE_MATH"
7052 "")
7053
7054 (define_insn "*mulqihi3_insn"
7055 [(set (match_operand:HI 0 "register_operand" "=a")
7056 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7057 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7058 (clobber (reg:CC 17))]
7059 "TARGET_QIMODE_MATH
7060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7061 "imul{b}\t%2"
7062 [(set_attr "type" "imul")
7063 (set_attr "length_immediate" "0")
7064 (set_attr "mode" "QI")])
7065
7066 (define_expand "umulditi3"
7067 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7068 (mult:TI (zero_extend:TI
7069 (match_operand:DI 1 "nonimmediate_operand" ""))
7070 (zero_extend:TI
7071 (match_operand:DI 2 "register_operand" ""))))
7072 (clobber (reg:CC 17))])]
7073 "TARGET_64BIT"
7074 "")
7075
7076 (define_insn "*umulditi3_insn"
7077 [(set (match_operand:TI 0 "register_operand" "=A")
7078 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7079 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7080 (clobber (reg:CC 17))]
7081 "TARGET_64BIT
7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7083 "mul{q}\t%2"
7084 [(set_attr "type" "imul")
7085 (set_attr "ppro_uops" "few")
7086 (set_attr "length_immediate" "0")
7087 (set_attr "mode" "DI")])
7088
7089 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7090 (define_expand "umulsidi3"
7091 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7092 (mult:DI (zero_extend:DI
7093 (match_operand:SI 1 "nonimmediate_operand" ""))
7094 (zero_extend:DI
7095 (match_operand:SI 2 "register_operand" ""))))
7096 (clobber (reg:CC 17))])]
7097 "!TARGET_64BIT"
7098 "")
7099
7100 (define_insn "*umulsidi3_insn"
7101 [(set (match_operand:DI 0 "register_operand" "=A")
7102 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7103 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7104 (clobber (reg:CC 17))]
7105 "!TARGET_64BIT
7106 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7107 "mul{l}\t%2"
7108 [(set_attr "type" "imul")
7109 (set_attr "ppro_uops" "few")
7110 (set_attr "length_immediate" "0")
7111 (set_attr "mode" "SI")])
7112
7113 (define_expand "mulditi3"
7114 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7115 (mult:TI (sign_extend:TI
7116 (match_operand:DI 1 "nonimmediate_operand" ""))
7117 (sign_extend:TI
7118 (match_operand:DI 2 "register_operand" ""))))
7119 (clobber (reg:CC 17))])]
7120 "TARGET_64BIT"
7121 "")
7122
7123 (define_insn "*mulditi3_insn"
7124 [(set (match_operand:TI 0 "register_operand" "=A")
7125 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7126 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7127 (clobber (reg:CC 17))]
7128 "TARGET_64BIT
7129 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7130 "imul{q}\t%2"
7131 [(set_attr "type" "imul")
7132 (set_attr "length_immediate" "0")
7133 (set_attr "mode" "DI")])
7134
7135 (define_expand "mulsidi3"
7136 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137 (mult:DI (sign_extend:DI
7138 (match_operand:SI 1 "nonimmediate_operand" ""))
7139 (sign_extend:DI
7140 (match_operand:SI 2 "register_operand" ""))))
7141 (clobber (reg:CC 17))])]
7142 "!TARGET_64BIT"
7143 "")
7144
7145 (define_insn "*mulsidi3_insn"
7146 [(set (match_operand:DI 0 "register_operand" "=A")
7147 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7148 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7149 (clobber (reg:CC 17))]
7150 "!TARGET_64BIT
7151 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7152 "imul{l}\t%2"
7153 [(set_attr "type" "imul")
7154 (set_attr "length_immediate" "0")
7155 (set_attr "mode" "SI")])
7156
7157 (define_expand "umuldi3_highpart"
7158 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7159 (truncate:DI
7160 (lshiftrt:TI
7161 (mult:TI (zero_extend:TI
7162 (match_operand:DI 1 "nonimmediate_operand" ""))
7163 (zero_extend:TI
7164 (match_operand:DI 2 "register_operand" "")))
7165 (const_int 64))))
7166 (clobber (match_scratch:DI 3 ""))
7167 (clobber (reg:CC 17))])]
7168 "TARGET_64BIT"
7169 "")
7170
7171 (define_insn "*umuldi3_highpart_rex64"
7172 [(set (match_operand:DI 0 "register_operand" "=d")
7173 (truncate:DI
7174 (lshiftrt:TI
7175 (mult:TI (zero_extend:TI
7176 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7177 (zero_extend:TI
7178 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7179 (const_int 64))))
7180 (clobber (match_scratch:DI 3 "=1"))
7181 (clobber (reg:CC 17))]
7182 "TARGET_64BIT
7183 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7184 "mul{q}\t%2"
7185 [(set_attr "type" "imul")
7186 (set_attr "ppro_uops" "few")
7187 (set_attr "length_immediate" "0")
7188 (set_attr "mode" "DI")])
7189
7190 (define_expand "umulsi3_highpart"
7191 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7192 (truncate:SI
7193 (lshiftrt:DI
7194 (mult:DI (zero_extend:DI
7195 (match_operand:SI 1 "nonimmediate_operand" ""))
7196 (zero_extend:DI
7197 (match_operand:SI 2 "register_operand" "")))
7198 (const_int 32))))
7199 (clobber (match_scratch:SI 3 ""))
7200 (clobber (reg:CC 17))])]
7201 ""
7202 "")
7203
7204 (define_insn "*umulsi3_highpart_insn"
7205 [(set (match_operand:SI 0 "register_operand" "=d")
7206 (truncate:SI
7207 (lshiftrt:DI
7208 (mult:DI (zero_extend:DI
7209 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7210 (zero_extend:DI
7211 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7212 (const_int 32))))
7213 (clobber (match_scratch:SI 3 "=1"))
7214 (clobber (reg:CC 17))]
7215 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7216 "mul{l}\t%2"
7217 [(set_attr "type" "imul")
7218 (set_attr "ppro_uops" "few")
7219 (set_attr "length_immediate" "0")
7220 (set_attr "mode" "SI")])
7221
7222 (define_insn "*umulsi3_highpart_zext"
7223 [(set (match_operand:DI 0 "register_operand" "=d")
7224 (zero_extend:DI (truncate:SI
7225 (lshiftrt:DI
7226 (mult:DI (zero_extend:DI
7227 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7228 (zero_extend:DI
7229 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7230 (const_int 32)))))
7231 (clobber (match_scratch:SI 3 "=1"))
7232 (clobber (reg:CC 17))]
7233 "TARGET_64BIT
7234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235 "mul{l}\t%2"
7236 [(set_attr "type" "imul")
7237 (set_attr "ppro_uops" "few")
7238 (set_attr "length_immediate" "0")
7239 (set_attr "mode" "SI")])
7240
7241 (define_expand "smuldi3_highpart"
7242 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7243 (truncate:DI
7244 (lshiftrt:TI
7245 (mult:TI (sign_extend:TI
7246 (match_operand:DI 1 "nonimmediate_operand" ""))
7247 (sign_extend:TI
7248 (match_operand:DI 2 "register_operand" "")))
7249 (const_int 64))))
7250 (clobber (match_scratch:DI 3 ""))
7251 (clobber (reg:CC 17))])]
7252 "TARGET_64BIT"
7253 "")
7254
7255 (define_insn "*smuldi3_highpart_rex64"
7256 [(set (match_operand:DI 0 "register_operand" "=d")
7257 (truncate:DI
7258 (lshiftrt:TI
7259 (mult:TI (sign_extend:TI
7260 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7261 (sign_extend:TI
7262 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7263 (const_int 64))))
7264 (clobber (match_scratch:DI 3 "=1"))
7265 (clobber (reg:CC 17))]
7266 "TARGET_64BIT
7267 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7268 "imul{q}\t%2"
7269 [(set_attr "type" "imul")
7270 (set_attr "ppro_uops" "few")
7271 (set_attr "mode" "DI")])
7272
7273 (define_expand "smulsi3_highpart"
7274 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7275 (truncate:SI
7276 (lshiftrt:DI
7277 (mult:DI (sign_extend:DI
7278 (match_operand:SI 1 "nonimmediate_operand" ""))
7279 (sign_extend:DI
7280 (match_operand:SI 2 "register_operand" "")))
7281 (const_int 32))))
7282 (clobber (match_scratch:SI 3 ""))
7283 (clobber (reg:CC 17))])]
7284 ""
7285 "")
7286
7287 (define_insn "*smulsi3_highpart_insn"
7288 [(set (match_operand:SI 0 "register_operand" "=d")
7289 (truncate:SI
7290 (lshiftrt:DI
7291 (mult:DI (sign_extend:DI
7292 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7293 (sign_extend:DI
7294 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7295 (const_int 32))))
7296 (clobber (match_scratch:SI 3 "=1"))
7297 (clobber (reg:CC 17))]
7298 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7299 "imul{l}\t%2"
7300 [(set_attr "type" "imul")
7301 (set_attr "ppro_uops" "few")
7302 (set_attr "mode" "SI")])
7303
7304 (define_insn "*smulsi3_highpart_zext"
7305 [(set (match_operand:DI 0 "register_operand" "=d")
7306 (zero_extend:DI (truncate:SI
7307 (lshiftrt:DI
7308 (mult:DI (sign_extend:DI
7309 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7310 (sign_extend:DI
7311 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7312 (const_int 32)))))
7313 (clobber (match_scratch:SI 3 "=1"))
7314 (clobber (reg:CC 17))]
7315 "TARGET_64BIT
7316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7317 "imul{l}\t%2"
7318 [(set_attr "type" "imul")
7319 (set_attr "ppro_uops" "few")
7320 (set_attr "mode" "SI")])
7321
7322 ;; The patterns that match these are at the end of this file.
7323
7324 (define_expand "mulxf3"
7325 [(set (match_operand:XF 0 "register_operand" "")
7326 (mult:XF (match_operand:XF 1 "register_operand" "")
7327 (match_operand:XF 2 "register_operand" "")))]
7328 "!TARGET_64BIT && TARGET_80387"
7329 "")
7330
7331 (define_expand "multf3"
7332 [(set (match_operand:TF 0 "register_operand" "")
7333 (mult:TF (match_operand:TF 1 "register_operand" "")
7334 (match_operand:TF 2 "register_operand" "")))]
7335 "TARGET_80387"
7336 "")
7337
7338 (define_expand "muldf3"
7339 [(set (match_operand:DF 0 "register_operand" "")
7340 (mult:DF (match_operand:DF 1 "register_operand" "")
7341 (match_operand:DF 2 "nonimmediate_operand" "")))]
7342 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7343 "")
7344
7345 (define_expand "mulsf3"
7346 [(set (match_operand:SF 0 "register_operand" "")
7347 (mult:SF (match_operand:SF 1 "register_operand" "")
7348 (match_operand:SF 2 "nonimmediate_operand" "")))]
7349 "TARGET_80387 || TARGET_SSE_MATH"
7350 "")
7351 \f
7352 ;; Divide instructions
7353
7354 (define_insn "divqi3"
7355 [(set (match_operand:QI 0 "register_operand" "=a")
7356 (div:QI (match_operand:HI 1 "register_operand" "0")
7357 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7358 (clobber (reg:CC 17))]
7359 "TARGET_QIMODE_MATH"
7360 "idiv{b}\t%2"
7361 [(set_attr "type" "idiv")
7362 (set_attr "mode" "QI")
7363 (set_attr "ppro_uops" "few")])
7364
7365 (define_insn "udivqi3"
7366 [(set (match_operand:QI 0 "register_operand" "=a")
7367 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7368 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7369 (clobber (reg:CC 17))]
7370 "TARGET_QIMODE_MATH"
7371 "div{b}\t%2"
7372 [(set_attr "type" "idiv")
7373 (set_attr "mode" "QI")
7374 (set_attr "ppro_uops" "few")])
7375
7376 ;; The patterns that match these are at the end of this file.
7377
7378 (define_expand "divxf3"
7379 [(set (match_operand:XF 0 "register_operand" "")
7380 (div:XF (match_operand:XF 1 "register_operand" "")
7381 (match_operand:XF 2 "register_operand" "")))]
7382 "!TARGET_64BIT && TARGET_80387"
7383 "")
7384
7385 (define_expand "divtf3"
7386 [(set (match_operand:TF 0 "register_operand" "")
7387 (div:TF (match_operand:TF 1 "register_operand" "")
7388 (match_operand:TF 2 "register_operand" "")))]
7389 "TARGET_80387"
7390 "")
7391
7392 (define_expand "divdf3"
7393 [(set (match_operand:DF 0 "register_operand" "")
7394 (div:DF (match_operand:DF 1 "register_operand" "")
7395 (match_operand:DF 2 "nonimmediate_operand" "")))]
7396 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7397 "")
7398
7399 (define_expand "divsf3"
7400 [(set (match_operand:SF 0 "register_operand" "")
7401 (div:SF (match_operand:SF 1 "register_operand" "")
7402 (match_operand:SF 2 "nonimmediate_operand" "")))]
7403 "TARGET_80387 || TARGET_SSE_MATH"
7404 "")
7405 \f
7406 ;; Remainder instructions.
7407
7408 (define_expand "divmoddi4"
7409 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7410 (div:DI (match_operand:DI 1 "register_operand" "")
7411 (match_operand:DI 2 "nonimmediate_operand" "")))
7412 (set (match_operand:DI 3 "register_operand" "")
7413 (mod:DI (match_dup 1) (match_dup 2)))
7414 (clobber (reg:CC 17))])]
7415 "TARGET_64BIT"
7416 "")
7417
7418 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7419 ;; Penalize eax case sligthly because it results in worse scheduling
7420 ;; of code.
7421 (define_insn "*divmoddi4_nocltd_rex64"
7422 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7423 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7424 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7425 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7426 (mod:DI (match_dup 2) (match_dup 3)))
7427 (clobber (reg:CC 17))]
7428 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7429 "#"
7430 [(set_attr "type" "multi")])
7431
7432 (define_insn "*divmoddi4_cltd_rex64"
7433 [(set (match_operand:DI 0 "register_operand" "=a")
7434 (div:DI (match_operand:DI 2 "register_operand" "a")
7435 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7436 (set (match_operand:DI 1 "register_operand" "=&d")
7437 (mod:DI (match_dup 2) (match_dup 3)))
7438 (clobber (reg:CC 17))]
7439 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7440 "#"
7441 [(set_attr "type" "multi")])
7442
7443 (define_insn "*divmoddi_noext_rex64"
7444 [(set (match_operand:DI 0 "register_operand" "=a")
7445 (div:DI (match_operand:DI 1 "register_operand" "0")
7446 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7447 (set (match_operand:DI 3 "register_operand" "=d")
7448 (mod:DI (match_dup 1) (match_dup 2)))
7449 (use (match_operand:DI 4 "register_operand" "3"))
7450 (clobber (reg:CC 17))]
7451 "TARGET_64BIT"
7452 "idiv{q}\t%2"
7453 [(set_attr "type" "idiv")
7454 (set_attr "mode" "DI")
7455 (set_attr "ppro_uops" "few")])
7456
7457 (define_split
7458 [(set (match_operand:DI 0 "register_operand" "")
7459 (div:DI (match_operand:DI 1 "register_operand" "")
7460 (match_operand:DI 2 "nonimmediate_operand" "")))
7461 (set (match_operand:DI 3 "register_operand" "")
7462 (mod:DI (match_dup 1) (match_dup 2)))
7463 (clobber (reg:CC 17))]
7464 "TARGET_64BIT && reload_completed"
7465 [(parallel [(set (match_dup 3)
7466 (ashiftrt:DI (match_dup 4) (const_int 63)))
7467 (clobber (reg:CC 17))])
7468 (parallel [(set (match_dup 0)
7469 (div:DI (reg:DI 0) (match_dup 2)))
7470 (set (match_dup 3)
7471 (mod:DI (reg:DI 0) (match_dup 2)))
7472 (use (match_dup 3))
7473 (clobber (reg:CC 17))])]
7474 {
7475 /* Avoid use of cltd in favor of a mov+shift. */
7476 if (!TARGET_USE_CLTD && !optimize_size)
7477 {
7478 if (true_regnum (operands[1]))
7479 emit_move_insn (operands[0], operands[1]);
7480 else
7481 emit_move_insn (operands[3], operands[1]);
7482 operands[4] = operands[3];
7483 }
7484 else
7485 {
7486 if (true_regnum (operands[1]))
7487 abort();
7488 operands[4] = operands[1];
7489 }
7490 })
7491
7492
7493 (define_expand "divmodsi4"
7494 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7495 (div:SI (match_operand:SI 1 "register_operand" "")
7496 (match_operand:SI 2 "nonimmediate_operand" "")))
7497 (set (match_operand:SI 3 "register_operand" "")
7498 (mod:SI (match_dup 1) (match_dup 2)))
7499 (clobber (reg:CC 17))])]
7500 ""
7501 "")
7502
7503 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7504 ;; Penalize eax case sligthly because it results in worse scheduling
7505 ;; of code.
7506 (define_insn "*divmodsi4_nocltd"
7507 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7508 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7509 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7510 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7511 (mod:SI (match_dup 2) (match_dup 3)))
7512 (clobber (reg:CC 17))]
7513 "!optimize_size && !TARGET_USE_CLTD"
7514 "#"
7515 [(set_attr "type" "multi")])
7516
7517 (define_insn "*divmodsi4_cltd"
7518 [(set (match_operand:SI 0 "register_operand" "=a")
7519 (div:SI (match_operand:SI 2 "register_operand" "a")
7520 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7521 (set (match_operand:SI 1 "register_operand" "=&d")
7522 (mod:SI (match_dup 2) (match_dup 3)))
7523 (clobber (reg:CC 17))]
7524 "optimize_size || TARGET_USE_CLTD"
7525 "#"
7526 [(set_attr "type" "multi")])
7527
7528 (define_insn "*divmodsi_noext"
7529 [(set (match_operand:SI 0 "register_operand" "=a")
7530 (div:SI (match_operand:SI 1 "register_operand" "0")
7531 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7532 (set (match_operand:SI 3 "register_operand" "=d")
7533 (mod:SI (match_dup 1) (match_dup 2)))
7534 (use (match_operand:SI 4 "register_operand" "3"))
7535 (clobber (reg:CC 17))]
7536 ""
7537 "idiv{l}\t%2"
7538 [(set_attr "type" "idiv")
7539 (set_attr "mode" "SI")
7540 (set_attr "ppro_uops" "few")])
7541
7542 (define_split
7543 [(set (match_operand:SI 0 "register_operand" "")
7544 (div:SI (match_operand:SI 1 "register_operand" "")
7545 (match_operand:SI 2 "nonimmediate_operand" "")))
7546 (set (match_operand:SI 3 "register_operand" "")
7547 (mod:SI (match_dup 1) (match_dup 2)))
7548 (clobber (reg:CC 17))]
7549 "reload_completed"
7550 [(parallel [(set (match_dup 3)
7551 (ashiftrt:SI (match_dup 4) (const_int 31)))
7552 (clobber (reg:CC 17))])
7553 (parallel [(set (match_dup 0)
7554 (div:SI (reg:SI 0) (match_dup 2)))
7555 (set (match_dup 3)
7556 (mod:SI (reg:SI 0) (match_dup 2)))
7557 (use (match_dup 3))
7558 (clobber (reg:CC 17))])]
7559 {
7560 /* Avoid use of cltd in favor of a mov+shift. */
7561 if (!TARGET_USE_CLTD && !optimize_size)
7562 {
7563 if (true_regnum (operands[1]))
7564 emit_move_insn (operands[0], operands[1]);
7565 else
7566 emit_move_insn (operands[3], operands[1]);
7567 operands[4] = operands[3];
7568 }
7569 else
7570 {
7571 if (true_regnum (operands[1]))
7572 abort();
7573 operands[4] = operands[1];
7574 }
7575 })
7576 ;; %%% Split me.
7577 (define_insn "divmodhi4"
7578 [(set (match_operand:HI 0 "register_operand" "=a")
7579 (div:HI (match_operand:HI 1 "register_operand" "0")
7580 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7581 (set (match_operand:HI 3 "register_operand" "=&d")
7582 (mod:HI (match_dup 1) (match_dup 2)))
7583 (clobber (reg:CC 17))]
7584 "TARGET_HIMODE_MATH"
7585 "cwtd\;idiv{w}\t%2"
7586 [(set_attr "type" "multi")
7587 (set_attr "length_immediate" "0")
7588 (set_attr "mode" "SI")])
7589
7590 (define_insn "udivmoddi4"
7591 [(set (match_operand:DI 0 "register_operand" "=a")
7592 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7593 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7594 (set (match_operand:DI 3 "register_operand" "=&d")
7595 (umod:DI (match_dup 1) (match_dup 2)))
7596 (clobber (reg:CC 17))]
7597 "TARGET_64BIT"
7598 "xor{q}\t%3, %3\;div{q}\t%2"
7599 [(set_attr "type" "multi")
7600 (set_attr "length_immediate" "0")
7601 (set_attr "mode" "DI")])
7602
7603 (define_insn "*udivmoddi4_noext"
7604 [(set (match_operand:DI 0 "register_operand" "=a")
7605 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7606 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7607 (set (match_operand:DI 3 "register_operand" "=d")
7608 (umod:DI (match_dup 1) (match_dup 2)))
7609 (use (match_dup 3))
7610 (clobber (reg:CC 17))]
7611 "TARGET_64BIT"
7612 "div{q}\t%2"
7613 [(set_attr "type" "idiv")
7614 (set_attr "ppro_uops" "few")
7615 (set_attr "mode" "DI")])
7616
7617 (define_split
7618 [(set (match_operand:DI 0 "register_operand" "")
7619 (udiv:DI (match_operand:DI 1 "register_operand" "")
7620 (match_operand:DI 2 "nonimmediate_operand" "")))
7621 (set (match_operand:DI 3 "register_operand" "")
7622 (umod:DI (match_dup 1) (match_dup 2)))
7623 (clobber (reg:CC 17))]
7624 "TARGET_64BIT && reload_completed"
7625 [(set (match_dup 3) (const_int 0))
7626 (parallel [(set (match_dup 0)
7627 (udiv:DI (match_dup 1) (match_dup 2)))
7628 (set (match_dup 3)
7629 (umod:DI (match_dup 1) (match_dup 2)))
7630 (use (match_dup 3))
7631 (clobber (reg:CC 17))])]
7632 "")
7633
7634 (define_insn "udivmodsi4"
7635 [(set (match_operand:SI 0 "register_operand" "=a")
7636 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7637 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7638 (set (match_operand:SI 3 "register_operand" "=&d")
7639 (umod:SI (match_dup 1) (match_dup 2)))
7640 (clobber (reg:CC 17))]
7641 ""
7642 "xor{l}\t%3, %3\;div{l}\t%2"
7643 [(set_attr "type" "multi")
7644 (set_attr "length_immediate" "0")
7645 (set_attr "mode" "SI")])
7646
7647 (define_insn "*udivmodsi4_noext"
7648 [(set (match_operand:SI 0 "register_operand" "=a")
7649 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7650 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7651 (set (match_operand:SI 3 "register_operand" "=d")
7652 (umod:SI (match_dup 1) (match_dup 2)))
7653 (use (match_dup 3))
7654 (clobber (reg:CC 17))]
7655 ""
7656 "div{l}\t%2"
7657 [(set_attr "type" "idiv")
7658 (set_attr "ppro_uops" "few")
7659 (set_attr "mode" "SI")])
7660
7661 (define_split
7662 [(set (match_operand:SI 0 "register_operand" "")
7663 (udiv:SI (match_operand:SI 1 "register_operand" "")
7664 (match_operand:SI 2 "nonimmediate_operand" "")))
7665 (set (match_operand:SI 3 "register_operand" "")
7666 (umod:SI (match_dup 1) (match_dup 2)))
7667 (clobber (reg:CC 17))]
7668 "reload_completed"
7669 [(set (match_dup 3) (const_int 0))
7670 (parallel [(set (match_dup 0)
7671 (udiv:SI (match_dup 1) (match_dup 2)))
7672 (set (match_dup 3)
7673 (umod:SI (match_dup 1) (match_dup 2)))
7674 (use (match_dup 3))
7675 (clobber (reg:CC 17))])]
7676 "")
7677
7678 (define_expand "udivmodhi4"
7679 [(set (match_dup 4) (const_int 0))
7680 (parallel [(set (match_operand:HI 0 "register_operand" "")
7681 (udiv:HI (match_operand:HI 1 "register_operand" "")
7682 (match_operand:HI 2 "nonimmediate_operand" "")))
7683 (set (match_operand:HI 3 "register_operand" "")
7684 (umod:HI (match_dup 1) (match_dup 2)))
7685 (use (match_dup 4))
7686 (clobber (reg:CC 17))])]
7687 "TARGET_HIMODE_MATH"
7688 "operands[4] = gen_reg_rtx (HImode);")
7689
7690 (define_insn "*udivmodhi_noext"
7691 [(set (match_operand:HI 0 "register_operand" "=a")
7692 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7693 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7694 (set (match_operand:HI 3 "register_operand" "=d")
7695 (umod:HI (match_dup 1) (match_dup 2)))
7696 (use (match_operand:HI 4 "register_operand" "3"))
7697 (clobber (reg:CC 17))]
7698 ""
7699 "div{w}\t%2"
7700 [(set_attr "type" "idiv")
7701 (set_attr "mode" "HI")
7702 (set_attr "ppro_uops" "few")])
7703
7704 ;; We can not use div/idiv for double division, because it causes
7705 ;; "division by zero" on the overflow and that's not what we expect
7706 ;; from truncate. Because true (non truncating) double division is
7707 ;; never generated, we can't create this insn anyway.
7708 ;
7709 ;(define_insn ""
7710 ; [(set (match_operand:SI 0 "register_operand" "=a")
7711 ; (truncate:SI
7712 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7713 ; (zero_extend:DI
7714 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7715 ; (set (match_operand:SI 3 "register_operand" "=d")
7716 ; (truncate:SI
7717 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7718 ; (clobber (reg:CC 17))]
7719 ; ""
7720 ; "div{l}\t{%2, %0|%0, %2}"
7721 ; [(set_attr "type" "idiv")
7722 ; (set_attr "ppro_uops" "few")])
7723 \f
7724 ;;- Logical AND instructions
7725
7726 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7727 ;; Note that this excludes ah.
7728
7729 (define_insn "*testdi_1_rex64"
7730 [(set (reg 17)
7731 (compare
7732 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
7733 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
7734 (const_int 0)))]
7735 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7736 "@
7737 test{l}\t{%k1, %k0|%k0, %k1}
7738 test{l}\t{%k1, %k0|%k0, %k1}
7739 test{q}\t{%1, %0|%0, %1}
7740 test{q}\t{%1, %0|%0, %1}
7741 test{q}\t{%1, %0|%0, %1}"
7742 [(set_attr "type" "test")
7743 (set_attr "modrm" "0,1,0,1,1")
7744 (set_attr "mode" "SI,SI,DI,DI,DI")
7745 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7746
7747 (define_insn "testsi_1"
7748 [(set (reg 17)
7749 (compare
7750 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
7751 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
7752 (const_int 0)))]
7753 "ix86_match_ccmode (insn, CCNOmode)"
7754 "test{l}\t{%1, %0|%0, %1}"
7755 [(set_attr "type" "test")
7756 (set_attr "modrm" "0,1,1")
7757 (set_attr "mode" "SI")
7758 (set_attr "pent_pair" "uv,np,uv")])
7759
7760 (define_expand "testsi_ccno_1"
7761 [(set (reg:CCNO 17)
7762 (compare:CCNO
7763 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7764 (match_operand:SI 1 "nonmemory_operand" ""))
7765 (const_int 0)))]
7766 ""
7767 "")
7768
7769 (define_insn "*testhi_1"
7770 [(set (reg 17)
7771 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
7772 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
7773 (const_int 0)))]
7774 "ix86_match_ccmode (insn, CCNOmode)"
7775 "test{w}\t{%1, %0|%0, %1}"
7776 [(set_attr "type" "test")
7777 (set_attr "modrm" "0,1,1")
7778 (set_attr "mode" "HI")
7779 (set_attr "pent_pair" "uv,np,uv")])
7780
7781 (define_expand "testqi_ccz_1"
7782 [(set (reg:CCZ 17)
7783 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7784 (match_operand:QI 1 "nonmemory_operand" ""))
7785 (const_int 0)))]
7786 ""
7787 "")
7788
7789 (define_insn "*testqi_1"
7790 [(set (reg 17)
7791 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
7792 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
7793 (const_int 0)))]
7794 "ix86_match_ccmode (insn, CCNOmode)"
7795 {
7796 if (which_alternative == 3)
7797 {
7798 if (GET_CODE (operands[1]) == CONST_INT
7799 && (INTVAL (operands[1]) & 0xffffff00))
7800 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7801 return "test{l}\t{%1, %k0|%k0, %1}";
7802 }
7803 return "test{b}\t{%1, %0|%0, %1}";
7804 }
7805 [(set_attr "type" "test")
7806 (set_attr "modrm" "0,1,1,1")
7807 (set_attr "mode" "QI,QI,QI,SI")
7808 (set_attr "pent_pair" "uv,np,uv,np")])
7809
7810 (define_expand "testqi_ext_ccno_0"
7811 [(set (reg:CCNO 17)
7812 (compare:CCNO
7813 (and:SI
7814 (zero_extract:SI
7815 (match_operand 0 "ext_register_operand" "")
7816 (const_int 8)
7817 (const_int 8))
7818 (match_operand 1 "const_int_operand" ""))
7819 (const_int 0)))]
7820 ""
7821 "")
7822
7823 (define_insn "*testqi_ext_0"
7824 [(set (reg 17)
7825 (compare
7826 (and:SI
7827 (zero_extract:SI
7828 (match_operand 0 "ext_register_operand" "Q")
7829 (const_int 8)
7830 (const_int 8))
7831 (match_operand 1 "const_int_operand" "n"))
7832 (const_int 0)))]
7833 "ix86_match_ccmode (insn, CCNOmode)"
7834 "test{b}\t{%1, %h0|%h0, %1}"
7835 [(set_attr "type" "test")
7836 (set_attr "mode" "QI")
7837 (set_attr "length_immediate" "1")
7838 (set_attr "pent_pair" "np")])
7839
7840 (define_insn "*testqi_ext_1"
7841 [(set (reg 17)
7842 (compare
7843 (and:SI
7844 (zero_extract:SI
7845 (match_operand 0 "ext_register_operand" "Q")
7846 (const_int 8)
7847 (const_int 8))
7848 (zero_extend:SI
7849 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
7850 (const_int 0)))]
7851 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7852 "test{b}\t{%1, %h0|%h0, %1}"
7853 [(set_attr "type" "test")
7854 (set_attr "mode" "QI")])
7855
7856 (define_insn "*testqi_ext_1_rex64"
7857 [(set (reg 17)
7858 (compare
7859 (and:SI
7860 (zero_extract:SI
7861 (match_operand 0 "ext_register_operand" "Q")
7862 (const_int 8)
7863 (const_int 8))
7864 (zero_extend:SI
7865 (match_operand:QI 1 "register_operand" "Q")))
7866 (const_int 0)))]
7867 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7868 "test{b}\t{%1, %h0|%h0, %1}"
7869 [(set_attr "type" "test")
7870 (set_attr "mode" "QI")])
7871
7872 (define_insn "*testqi_ext_2"
7873 [(set (reg 17)
7874 (compare
7875 (and:SI
7876 (zero_extract:SI
7877 (match_operand 0 "ext_register_operand" "Q")
7878 (const_int 8)
7879 (const_int 8))
7880 (zero_extract:SI
7881 (match_operand 1 "ext_register_operand" "Q")
7882 (const_int 8)
7883 (const_int 8)))
7884 (const_int 0)))]
7885 "ix86_match_ccmode (insn, CCNOmode)"
7886 "test{b}\t{%h1, %h0|%h0, %h1}"
7887 [(set_attr "type" "test")
7888 (set_attr "mode" "QI")])
7889
7890 ;; Combine likes to form bit extractions for some tests. Humor it.
7891 (define_insn "*testqi_ext_3"
7892 [(set (reg 17)
7893 (compare (zero_extract:SI
7894 (match_operand 0 "nonimmediate_operand" "rm")
7895 (match_operand:SI 1 "const_int_operand" "")
7896 (match_operand:SI 2 "const_int_operand" ""))
7897 (const_int 0)))]
7898 "ix86_match_ccmode (insn, CCNOmode)
7899 && (GET_MODE (operands[0]) == SImode
7900 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7901 || GET_MODE (operands[0]) == HImode
7902 || GET_MODE (operands[0]) == QImode)"
7903 "#")
7904
7905 (define_insn "*testqi_ext_3_rex64"
7906 [(set (reg 17)
7907 (compare (zero_extract:DI
7908 (match_operand 0 "nonimmediate_operand" "rm")
7909 (match_operand:DI 1 "const_int_operand" "")
7910 (match_operand:DI 2 "const_int_operand" ""))
7911 (const_int 0)))]
7912 "TARGET_64BIT
7913 && ix86_match_ccmode (insn, CCNOmode)
7914 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7915 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7916 /* Ensure that resulting mask is zero or sign extended operand. */
7917 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7918 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7919 && INTVAL (operands[1]) > 32))
7920 && (GET_MODE (operands[0]) == SImode
7921 || GET_MODE (operands[0]) == DImode
7922 || GET_MODE (operands[0]) == HImode
7923 || GET_MODE (operands[0]) == QImode)"
7924 "#")
7925
7926 (define_split
7927 [(set (reg 17)
7928 (compare (zero_extract
7929 (match_operand 0 "nonimmediate_operand" "")
7930 (match_operand 1 "const_int_operand" "")
7931 (match_operand 2 "const_int_operand" ""))
7932 (const_int 0)))]
7933 "ix86_match_ccmode (insn, CCNOmode)"
7934 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7935 {
7936 HOST_WIDE_INT len = INTVAL (operands[1]);
7937 HOST_WIDE_INT pos = INTVAL (operands[2]);
7938 HOST_WIDE_INT mask;
7939 enum machine_mode mode, submode;
7940
7941 mode = GET_MODE (operands[0]);
7942 if (GET_CODE (operands[0]) == MEM)
7943 {
7944 /* ??? Combine likes to put non-volatile mem extractions in QImode
7945 no matter the size of the test. So find a mode that works. */
7946 if (! MEM_VOLATILE_P (operands[0]))
7947 {
7948 mode = smallest_mode_for_size (pos + len, MODE_INT);
7949 operands[0] = adjust_address (operands[0], mode, 0);
7950 }
7951 }
7952 else if (GET_CODE (operands[0]) == SUBREG
7953 && (submode = GET_MODE (SUBREG_REG (operands[0])),
7954 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7955 && pos + len <= GET_MODE_BITSIZE (submode))
7956 {
7957 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7958 mode = submode;
7959 operands[0] = SUBREG_REG (operands[0]);
7960 }
7961 else if (mode == HImode && pos + len <= 8)
7962 {
7963 /* Small HImode tests can be converted to QImode. */
7964 mode = QImode;
7965 operands[0] = gen_lowpart (QImode, operands[0]);
7966 }
7967
7968 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7969 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7970
7971 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
7972 })
7973
7974 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7975 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7976 ;; this is relatively important trick.
7977 ;; Do the converison only post-reload to avoid limiting of the register class
7978 ;; to QI regs.
7979 (define_split
7980 [(set (reg 17)
7981 (compare
7982 (and (match_operand 0 "register_operand" "")
7983 (match_operand 1 "const_int_operand" ""))
7984 (const_int 0)))]
7985 "reload_completed
7986 && QI_REG_P (operands[0])
7987 && ((ix86_match_ccmode (insn, CCZmode)
7988 && !(INTVAL (operands[1]) & ~(255 << 8)))
7989 || (ix86_match_ccmode (insn, CCNOmode)
7990 && !(INTVAL (operands[1]) & ~(127 << 8))))
7991 && GET_MODE (operands[0]) != QImode"
7992 [(set (reg:CCNO 17)
7993 (compare:CCNO
7994 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7995 (match_dup 1))
7996 (const_int 0)))]
7997 "operands[0] = gen_lowpart (SImode, operands[0]);
7998 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
7999
8000 (define_split
8001 [(set (reg 17)
8002 (compare
8003 (and (match_operand 0 "nonimmediate_operand" "")
8004 (match_operand 1 "const_int_operand" ""))
8005 (const_int 0)))]
8006 "reload_completed
8007 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8008 && ((ix86_match_ccmode (insn, CCZmode)
8009 && !(INTVAL (operands[1]) & ~255))
8010 || (ix86_match_ccmode (insn, CCNOmode)
8011 && !(INTVAL (operands[1]) & ~127)))
8012 && GET_MODE (operands[0]) != QImode"
8013 [(set (reg:CCNO 17)
8014 (compare:CCNO
8015 (and:QI (match_dup 0)
8016 (match_dup 1))
8017 (const_int 0)))]
8018 "operands[0] = gen_lowpart (QImode, operands[0]);
8019 operands[1] = gen_lowpart (QImode, operands[1]);")
8020
8021
8022 ;; %%% This used to optimize known byte-wide and operations to memory,
8023 ;; and sometimes to QImode registers. If this is considered useful,
8024 ;; it should be done with splitters.
8025
8026 (define_expand "anddi3"
8027 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8028 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8029 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8030 (clobber (reg:CC 17))]
8031 "TARGET_64BIT"
8032 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8033
8034 (define_insn "*anddi_1_rex64"
8035 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8036 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8037 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8038 (clobber (reg:CC 17))]
8039 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8040 {
8041 switch (get_attr_type (insn))
8042 {
8043 case TYPE_IMOVX:
8044 {
8045 enum machine_mode mode;
8046
8047 if (GET_CODE (operands[2]) != CONST_INT)
8048 abort ();
8049 if (INTVAL (operands[2]) == 0xff)
8050 mode = QImode;
8051 else if (INTVAL (operands[2]) == 0xffff)
8052 mode = HImode;
8053 else
8054 abort ();
8055
8056 operands[1] = gen_lowpart (mode, operands[1]);
8057 if (mode == QImode)
8058 return "movz{bq|x}\t{%1,%0|%0, %1}";
8059 else
8060 return "movz{wq|x}\t{%1,%0|%0, %1}";
8061 }
8062
8063 default:
8064 if (! rtx_equal_p (operands[0], operands[1]))
8065 abort ();
8066 if (get_attr_mode (insn) == MODE_SI)
8067 return "and{l}\t{%k2, %k0|%k0, %k2}";
8068 else
8069 return "and{q}\t{%2, %0|%0, %2}";
8070 }
8071 }
8072 [(set_attr "type" "alu,alu,alu,imovx")
8073 (set_attr "length_immediate" "*,*,*,0")
8074 (set_attr "mode" "SI,DI,DI,DI")])
8075
8076 (define_insn "*anddi_2"
8077 [(set (reg 17)
8078 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8079 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8080 (const_int 0)))
8081 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8082 (and:DI (match_dup 1) (match_dup 2)))]
8083 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8084 && ix86_binary_operator_ok (AND, DImode, operands)"
8085 "@
8086 and{l}\t{%k2, %k0|%k0, %k2}
8087 and{q}\t{%2, %0|%0, %2}
8088 and{q}\t{%2, %0|%0, %2}"
8089 [(set_attr "type" "alu")
8090 (set_attr "mode" "SI,DI,DI")])
8091
8092 (define_expand "andsi3"
8093 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8094 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8095 (match_operand:SI 2 "general_operand" "")))
8096 (clobber (reg:CC 17))]
8097 ""
8098 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8099
8100 (define_insn "*andsi_1"
8101 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8102 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8103 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8104 (clobber (reg:CC 17))]
8105 "ix86_binary_operator_ok (AND, SImode, operands)"
8106 {
8107 switch (get_attr_type (insn))
8108 {
8109 case TYPE_IMOVX:
8110 {
8111 enum machine_mode mode;
8112
8113 if (GET_CODE (operands[2]) != CONST_INT)
8114 abort ();
8115 if (INTVAL (operands[2]) == 0xff)
8116 mode = QImode;
8117 else if (INTVAL (operands[2]) == 0xffff)
8118 mode = HImode;
8119 else
8120 abort ();
8121
8122 operands[1] = gen_lowpart (mode, operands[1]);
8123 if (mode == QImode)
8124 return "movz{bl|x}\t{%1,%0|%0, %1}";
8125 else
8126 return "movz{wl|x}\t{%1,%0|%0, %1}";
8127 }
8128
8129 default:
8130 if (! rtx_equal_p (operands[0], operands[1]))
8131 abort ();
8132 return "and{l}\t{%2, %0|%0, %2}";
8133 }
8134 }
8135 [(set_attr "type" "alu,alu,imovx")
8136 (set_attr "length_immediate" "*,*,0")
8137 (set_attr "mode" "SI")])
8138
8139 (define_split
8140 [(set (match_operand 0 "register_operand" "")
8141 (and (match_dup 0)
8142 (const_int -65536)))
8143 (clobber (reg:CC 17))]
8144 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8145 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8146 "operands[1] = gen_lowpart (HImode, operands[0]);")
8147
8148 (define_split
8149 [(set (match_operand 0 "ext_register_operand" "")
8150 (and (match_dup 0)
8151 (const_int -256)))
8152 (clobber (reg:CC 17))]
8153 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8154 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8155 "operands[1] = gen_lowpart (QImode, operands[0]);")
8156
8157 (define_split
8158 [(set (match_operand 0 "ext_register_operand" "")
8159 (and (match_dup 0)
8160 (const_int -65281)))
8161 (clobber (reg:CC 17))]
8162 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8163 [(parallel [(set (zero_extract:SI (match_dup 0)
8164 (const_int 8)
8165 (const_int 8))
8166 (xor:SI
8167 (zero_extract:SI (match_dup 0)
8168 (const_int 8)
8169 (const_int 8))
8170 (zero_extract:SI (match_dup 0)
8171 (const_int 8)
8172 (const_int 8))))
8173 (clobber (reg:CC 17))])]
8174 "operands[0] = gen_lowpart (SImode, operands[0]);")
8175
8176 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8177 (define_insn "*andsi_1_zext"
8178 [(set (match_operand:DI 0 "register_operand" "=r")
8179 (zero_extend:DI
8180 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8181 (match_operand:SI 2 "general_operand" "rim"))))
8182 (clobber (reg:CC 17))]
8183 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8184 "and{l}\t{%2, %k0|%k0, %2}"
8185 [(set_attr "type" "alu")
8186 (set_attr "mode" "SI")])
8187
8188 (define_insn "*andsi_2"
8189 [(set (reg 17)
8190 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8191 (match_operand:SI 2 "general_operand" "rim,ri"))
8192 (const_int 0)))
8193 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8194 (and:SI (match_dup 1) (match_dup 2)))]
8195 "ix86_match_ccmode (insn, CCNOmode)
8196 && ix86_binary_operator_ok (AND, SImode, operands)"
8197 "and{l}\t{%2, %0|%0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "mode" "SI")])
8200
8201 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8202 (define_insn "*andsi_2_zext"
8203 [(set (reg 17)
8204 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8205 (match_operand:SI 2 "general_operand" "rim"))
8206 (const_int 0)))
8207 (set (match_operand:DI 0 "register_operand" "=r")
8208 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8209 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8210 && ix86_binary_operator_ok (AND, SImode, operands)"
8211 "and{l}\t{%2, %k0|%k0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "SI")])
8214
8215 (define_expand "andhi3"
8216 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8217 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8218 (match_operand:HI 2 "general_operand" "")))
8219 (clobber (reg:CC 17))]
8220 "TARGET_HIMODE_MATH"
8221 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8222
8223 (define_insn "*andhi_1"
8224 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8225 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8226 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8227 (clobber (reg:CC 17))]
8228 "ix86_binary_operator_ok (AND, HImode, operands)"
8229 {
8230 switch (get_attr_type (insn))
8231 {
8232 case TYPE_IMOVX:
8233 if (GET_CODE (operands[2]) != CONST_INT)
8234 abort ();
8235 if (INTVAL (operands[2]) == 0xff)
8236 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8237 abort ();
8238
8239 default:
8240 if (! rtx_equal_p (operands[0], operands[1]))
8241 abort ();
8242
8243 return "and{w}\t{%2, %0|%0, %2}";
8244 }
8245 }
8246 [(set_attr "type" "alu,alu,imovx")
8247 (set_attr "length_immediate" "*,*,0")
8248 (set_attr "mode" "HI,HI,SI")])
8249
8250 (define_insn "*andhi_2"
8251 [(set (reg 17)
8252 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8253 (match_operand:HI 2 "general_operand" "rim,ri"))
8254 (const_int 0)))
8255 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8256 (and:HI (match_dup 1) (match_dup 2)))]
8257 "ix86_match_ccmode (insn, CCNOmode)
8258 && ix86_binary_operator_ok (AND, HImode, operands)"
8259 "and{w}\t{%2, %0|%0, %2}"
8260 [(set_attr "type" "alu")
8261 (set_attr "mode" "HI")])
8262
8263 (define_expand "andqi3"
8264 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8265 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8266 (match_operand:QI 2 "general_operand" "")))
8267 (clobber (reg:CC 17))]
8268 "TARGET_QIMODE_MATH"
8269 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8270
8271 ;; %%% Potential partial reg stall on alternative 2. What to do?
8272 (define_insn "*andqi_1"
8273 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8274 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8275 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8276 (clobber (reg:CC 17))]
8277 "ix86_binary_operator_ok (AND, QImode, operands)"
8278 "@
8279 and{b}\t{%2, %0|%0, %2}
8280 and{b}\t{%2, %0|%0, %2}
8281 and{l}\t{%k2, %k0|%k0, %k2}"
8282 [(set_attr "type" "alu")
8283 (set_attr "mode" "QI,QI,SI")])
8284
8285 (define_insn "*andqi_1_slp"
8286 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8287 (and:QI (match_dup 0)
8288 (match_operand:QI 1 "general_operand" "qi,qmi")))
8289 (clobber (reg:CC 17))]
8290 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8291 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8292 "and{b}\t{%1, %0|%0, %1}"
8293 [(set_attr "type" "alu1")
8294 (set_attr "mode" "QI")])
8295
8296 (define_insn "*andqi_2"
8297 [(set (reg 17)
8298 (compare (and:QI
8299 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8300 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8301 (const_int 0)))
8302 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8303 (and:QI (match_dup 1) (match_dup 2)))]
8304 "ix86_match_ccmode (insn, CCNOmode)
8305 && ix86_binary_operator_ok (AND, QImode, operands)"
8306 {
8307 if (which_alternative == 2)
8308 {
8309 if (GET_CODE (operands[2]) == CONST_INT
8310 && (INTVAL (operands[2]) & 0xffffff00))
8311 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8312 return "and{l}\t{%2, %k0|%k0, %2}";
8313 }
8314 return "and{b}\t{%2, %0|%0, %2}";
8315 }
8316 [(set_attr "type" "alu")
8317 (set_attr "mode" "QI,QI,SI")])
8318
8319 (define_insn "*andqi_2_slp"
8320 [(set (reg 17)
8321 (compare (and:QI
8322 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8323 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8324 (const_int 0)))
8325 (set (strict_low_part (match_dup 0))
8326 (and:QI (match_dup 0) (match_dup 1)))]
8327 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8328 && ix86_match_ccmode (insn, CCNOmode)
8329 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8330 "and{b}\t{%1, %0|%0, %1}"
8331 [(set_attr "type" "alu1")
8332 (set_attr "mode" "QI")])
8333
8334 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8335 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8336 ;; for a QImode operand, which of course failed.
8337
8338 (define_insn "andqi_ext_0"
8339 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8340 (const_int 8)
8341 (const_int 8))
8342 (and:SI
8343 (zero_extract:SI
8344 (match_operand 1 "ext_register_operand" "0")
8345 (const_int 8)
8346 (const_int 8))
8347 (match_operand 2 "const_int_operand" "n")))
8348 (clobber (reg:CC 17))]
8349 ""
8350 "and{b}\t{%2, %h0|%h0, %2}"
8351 [(set_attr "type" "alu")
8352 (set_attr "length_immediate" "1")
8353 (set_attr "mode" "QI")])
8354
8355 ;; Generated by peephole translating test to and. This shows up
8356 ;; often in fp comparisons.
8357
8358 (define_insn "*andqi_ext_0_cc"
8359 [(set (reg 17)
8360 (compare
8361 (and:SI
8362 (zero_extract:SI
8363 (match_operand 1 "ext_register_operand" "0")
8364 (const_int 8)
8365 (const_int 8))
8366 (match_operand 2 "const_int_operand" "n"))
8367 (const_int 0)))
8368 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8369 (const_int 8)
8370 (const_int 8))
8371 (and:SI
8372 (zero_extract:SI
8373 (match_dup 1)
8374 (const_int 8)
8375 (const_int 8))
8376 (match_dup 2)))]
8377 "ix86_match_ccmode (insn, CCNOmode)"
8378 "and{b}\t{%2, %h0|%h0, %2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "length_immediate" "1")
8381 (set_attr "mode" "QI")])
8382
8383 (define_insn "*andqi_ext_1"
8384 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8385 (const_int 8)
8386 (const_int 8))
8387 (and:SI
8388 (zero_extract:SI
8389 (match_operand 1 "ext_register_operand" "0")
8390 (const_int 8)
8391 (const_int 8))
8392 (zero_extend:SI
8393 (match_operand:QI 2 "general_operand" "Qm"))))
8394 (clobber (reg:CC 17))]
8395 "!TARGET_64BIT"
8396 "and{b}\t{%2, %h0|%h0, %2}"
8397 [(set_attr "type" "alu")
8398 (set_attr "length_immediate" "0")
8399 (set_attr "mode" "QI")])
8400
8401 (define_insn "*andqi_ext_1_rex64"
8402 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8403 (const_int 8)
8404 (const_int 8))
8405 (and:SI
8406 (zero_extract:SI
8407 (match_operand 1 "ext_register_operand" "0")
8408 (const_int 8)
8409 (const_int 8))
8410 (zero_extend:SI
8411 (match_operand 2 "ext_register_operand" "Q"))))
8412 (clobber (reg:CC 17))]
8413 "TARGET_64BIT"
8414 "and{b}\t{%2, %h0|%h0, %2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "length_immediate" "0")
8417 (set_attr "mode" "QI")])
8418
8419 (define_insn "*andqi_ext_2"
8420 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8421 (const_int 8)
8422 (const_int 8))
8423 (and:SI
8424 (zero_extract:SI
8425 (match_operand 1 "ext_register_operand" "%0")
8426 (const_int 8)
8427 (const_int 8))
8428 (zero_extract:SI
8429 (match_operand 2 "ext_register_operand" "Q")
8430 (const_int 8)
8431 (const_int 8))))
8432 (clobber (reg:CC 17))]
8433 ""
8434 "and{b}\t{%h2, %h0|%h0, %h2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "length_immediate" "0")
8437 (set_attr "mode" "QI")])
8438
8439 ;; Convert wide AND instructions with immediate operand to shorter QImode
8440 ;; equivalents when possible.
8441 ;; Don't do the splitting with memory operands, since it intoduces risc
8442 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8443 ;; for size, but that can (should?) be handled by generic code instead.
8444 (define_split
8445 [(set (match_operand 0 "register_operand" "")
8446 (and (match_operand 1 "register_operand" "")
8447 (match_operand 2 "const_int_operand" "")))
8448 (clobber (reg:CC 17))]
8449 "reload_completed
8450 && QI_REG_P (operands[0])
8451 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8452 && !(~INTVAL (operands[2]) & ~(255 << 8))
8453 && GET_MODE (operands[0]) != QImode"
8454 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8455 (and:SI (zero_extract:SI (match_dup 1)
8456 (const_int 8) (const_int 8))
8457 (match_dup 2)))
8458 (clobber (reg:CC 17))])]
8459 "operands[0] = gen_lowpart (SImode, operands[0]);
8460 operands[1] = gen_lowpart (SImode, operands[1]);
8461 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8462
8463 ;; Since AND can be encoded with sign extended immediate, this is only
8464 ;; profitable when 7th bit is not set.
8465 (define_split
8466 [(set (match_operand 0 "register_operand" "")
8467 (and (match_operand 1 "general_operand" "")
8468 (match_operand 2 "const_int_operand" "")))
8469 (clobber (reg:CC 17))]
8470 "reload_completed
8471 && ANY_QI_REG_P (operands[0])
8472 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8473 && !(~INTVAL (operands[2]) & ~255)
8474 && !(INTVAL (operands[2]) & 128)
8475 && GET_MODE (operands[0]) != QImode"
8476 [(parallel [(set (strict_low_part (match_dup 0))
8477 (and:QI (match_dup 1)
8478 (match_dup 2)))
8479 (clobber (reg:CC 17))])]
8480 "operands[0] = gen_lowpart (QImode, operands[0]);
8481 operands[1] = gen_lowpart (QImode, operands[1]);
8482 operands[2] = gen_lowpart (QImode, operands[2]);")
8483 \f
8484 ;; Logical inclusive OR instructions
8485
8486 ;; %%% This used to optimize known byte-wide and operations to memory.
8487 ;; If this is considered useful, it should be done with splitters.
8488
8489 (define_expand "iordi3"
8490 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8491 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8492 (match_operand:DI 2 "x86_64_general_operand" "")))
8493 (clobber (reg:CC 17))]
8494 "TARGET_64BIT"
8495 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8496
8497 (define_insn "*iordi_1_rex64"
8498 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8499 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8500 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8501 (clobber (reg:CC 17))]
8502 "TARGET_64BIT
8503 && ix86_binary_operator_ok (IOR, DImode, operands)"
8504 "or{q}\t{%2, %0|%0, %2}"
8505 [(set_attr "type" "alu")
8506 (set_attr "mode" "DI")])
8507
8508 (define_insn "*iordi_2_rex64"
8509 [(set (reg 17)
8510 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8511 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8512 (const_int 0)))
8513 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8514 (ior:DI (match_dup 1) (match_dup 2)))]
8515 "TARGET_64BIT
8516 && ix86_match_ccmode (insn, CCNOmode)
8517 && ix86_binary_operator_ok (IOR, DImode, operands)"
8518 "or{q}\t{%2, %0|%0, %2}"
8519 [(set_attr "type" "alu")
8520 (set_attr "mode" "DI")])
8521
8522 (define_insn "*iordi_3_rex64"
8523 [(set (reg 17)
8524 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8525 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8526 (const_int 0)))
8527 (clobber (match_scratch:DI 0 "=r"))]
8528 "TARGET_64BIT
8529 && ix86_match_ccmode (insn, CCNOmode)
8530 && ix86_binary_operator_ok (IOR, DImode, operands)"
8531 "or{q}\t{%2, %0|%0, %2}"
8532 [(set_attr "type" "alu")
8533 (set_attr "mode" "DI")])
8534
8535
8536 (define_expand "iorsi3"
8537 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8538 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8539 (match_operand:SI 2 "general_operand" "")))
8540 (clobber (reg:CC 17))]
8541 ""
8542 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8543
8544 (define_insn "*iorsi_1"
8545 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8546 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8547 (match_operand:SI 2 "general_operand" "ri,rmi")))
8548 (clobber (reg:CC 17))]
8549 "ix86_binary_operator_ok (IOR, SImode, operands)"
8550 "or{l}\t{%2, %0|%0, %2}"
8551 [(set_attr "type" "alu")
8552 (set_attr "mode" "SI")])
8553
8554 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8555 (define_insn "*iorsi_1_zext"
8556 [(set (match_operand:DI 0 "register_operand" "=rm")
8557 (zero_extend:DI
8558 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8559 (match_operand:SI 2 "general_operand" "rim"))))
8560 (clobber (reg:CC 17))]
8561 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8562 "or{l}\t{%2, %k0|%k0, %2}"
8563 [(set_attr "type" "alu")
8564 (set_attr "mode" "SI")])
8565
8566 (define_insn "*iorsi_1_zext_imm"
8567 [(set (match_operand:DI 0 "register_operand" "=rm")
8568 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8569 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8570 (clobber (reg:CC 17))]
8571 "TARGET_64BIT"
8572 "or{l}\t{%2, %k0|%k0, %2}"
8573 [(set_attr "type" "alu")
8574 (set_attr "mode" "SI")])
8575
8576 (define_insn "*iorsi_2"
8577 [(set (reg 17)
8578 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8579 (match_operand:SI 2 "general_operand" "rim,ri"))
8580 (const_int 0)))
8581 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8582 (ior:SI (match_dup 1) (match_dup 2)))]
8583 "ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_binary_operator_ok (IOR, SImode, operands)"
8585 "or{l}\t{%2, %0|%0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "SI")])
8588
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 ;; ??? Special case for immediate operand is missing - it is tricky.
8591 (define_insn "*iorsi_2_zext"
8592 [(set (reg 17)
8593 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8594 (match_operand:SI 2 "general_operand" "rim"))
8595 (const_int 0)))
8596 (set (match_operand:DI 0 "register_operand" "=r")
8597 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599 && ix86_binary_operator_ok (IOR, SImode, operands)"
8600 "or{l}\t{%2, %k0|%k0, %2}"
8601 [(set_attr "type" "alu")
8602 (set_attr "mode" "SI")])
8603
8604 (define_insn "*iorsi_2_zext_imm"
8605 [(set (reg 17)
8606 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8607 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8608 (const_int 0)))
8609 (set (match_operand:DI 0 "register_operand" "=r")
8610 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8611 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8612 && ix86_binary_operator_ok (IOR, SImode, operands)"
8613 "or{l}\t{%2, %k0|%k0, %2}"
8614 [(set_attr "type" "alu")
8615 (set_attr "mode" "SI")])
8616
8617 (define_insn "*iorsi_3"
8618 [(set (reg 17)
8619 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8620 (match_operand:SI 2 "general_operand" "rim"))
8621 (const_int 0)))
8622 (clobber (match_scratch:SI 0 "=r"))]
8623 "ix86_match_ccmode (insn, CCNOmode)
8624 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8625 "or{l}\t{%2, %0|%0, %2}"
8626 [(set_attr "type" "alu")
8627 (set_attr "mode" "SI")])
8628
8629 (define_expand "iorhi3"
8630 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8631 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8632 (match_operand:HI 2 "general_operand" "")))
8633 (clobber (reg:CC 17))]
8634 "TARGET_HIMODE_MATH"
8635 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8636
8637 (define_insn "*iorhi_1"
8638 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8639 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8640 (match_operand:HI 2 "general_operand" "rmi,ri")))
8641 (clobber (reg:CC 17))]
8642 "ix86_binary_operator_ok (IOR, HImode, operands)"
8643 "or{w}\t{%2, %0|%0, %2}"
8644 [(set_attr "type" "alu")
8645 (set_attr "mode" "HI")])
8646
8647 (define_insn "*iorhi_2"
8648 [(set (reg 17)
8649 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8650 (match_operand:HI 2 "general_operand" "rim,ri"))
8651 (const_int 0)))
8652 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8653 (ior:HI (match_dup 1) (match_dup 2)))]
8654 "ix86_match_ccmode (insn, CCNOmode)
8655 && ix86_binary_operator_ok (IOR, HImode, operands)"
8656 "or{w}\t{%2, %0|%0, %2}"
8657 [(set_attr "type" "alu")
8658 (set_attr "mode" "HI")])
8659
8660 (define_insn "*iorhi_3"
8661 [(set (reg 17)
8662 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8663 (match_operand:HI 2 "general_operand" "rim"))
8664 (const_int 0)))
8665 (clobber (match_scratch:HI 0 "=r"))]
8666 "ix86_match_ccmode (insn, CCNOmode)
8667 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8668 "or{w}\t{%2, %0|%0, %2}"
8669 [(set_attr "type" "alu")
8670 (set_attr "mode" "HI")])
8671
8672 (define_expand "iorqi3"
8673 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8674 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8675 (match_operand:QI 2 "general_operand" "")))
8676 (clobber (reg:CC 17))]
8677 "TARGET_QIMODE_MATH"
8678 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8679
8680 ;; %%% Potential partial reg stall on alternative 2. What to do?
8681 (define_insn "*iorqi_1"
8682 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8683 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8684 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8685 (clobber (reg:CC 17))]
8686 "ix86_binary_operator_ok (IOR, QImode, operands)"
8687 "@
8688 or{b}\t{%2, %0|%0, %2}
8689 or{b}\t{%2, %0|%0, %2}
8690 or{l}\t{%k2, %k0|%k0, %k2}"
8691 [(set_attr "type" "alu")
8692 (set_attr "mode" "QI,QI,SI")])
8693
8694 (define_insn "*iorqi_1_slp"
8695 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8696 (ior:QI (match_dup 0)
8697 (match_operand:QI 1 "general_operand" "qmi,qi")))
8698 (clobber (reg:CC 17))]
8699 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8700 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8701 "or{b}\t{%1, %0|%0, %1}"
8702 [(set_attr "type" "alu1")
8703 (set_attr "mode" "QI")])
8704
8705 (define_insn "*iorqi_2"
8706 [(set (reg 17)
8707 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8708 (match_operand:QI 2 "general_operand" "qim,qi"))
8709 (const_int 0)))
8710 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8711 (ior:QI (match_dup 1) (match_dup 2)))]
8712 "ix86_match_ccmode (insn, CCNOmode)
8713 && ix86_binary_operator_ok (IOR, QImode, operands)"
8714 "or{b}\t{%2, %0|%0, %2}"
8715 [(set_attr "type" "alu")
8716 (set_attr "mode" "QI")])
8717
8718 (define_insn "*iorqi_2_slp"
8719 [(set (reg 17)
8720 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8721 (match_operand:QI 1 "general_operand" "qim,qi"))
8722 (const_int 0)))
8723 (set (strict_low_part (match_dup 0))
8724 (ior:QI (match_dup 0) (match_dup 1)))]
8725 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8726 && ix86_match_ccmode (insn, CCNOmode)
8727 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8728 "or{b}\t{%1, %0|%0, %1}"
8729 [(set_attr "type" "alu1")
8730 (set_attr "mode" "QI")])
8731
8732 (define_insn "*iorqi_3"
8733 [(set (reg 17)
8734 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8735 (match_operand:QI 2 "general_operand" "qim"))
8736 (const_int 0)))
8737 (clobber (match_scratch:QI 0 "=q"))]
8738 "ix86_match_ccmode (insn, CCNOmode)
8739 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8740 "or{b}\t{%2, %0|%0, %2}"
8741 [(set_attr "type" "alu")
8742 (set_attr "mode" "QI")])
8743
8744 (define_insn "iorqi_ext_0"
8745 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8746 (const_int 8)
8747 (const_int 8))
8748 (ior:SI
8749 (zero_extract:SI
8750 (match_operand 1 "ext_register_operand" "0")
8751 (const_int 8)
8752 (const_int 8))
8753 (match_operand 2 "const_int_operand" "n")))
8754 (clobber (reg:CC 17))]
8755 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8756 "or{b}\t{%2, %h0|%h0, %2}"
8757 [(set_attr "type" "alu")
8758 (set_attr "length_immediate" "1")
8759 (set_attr "mode" "QI")])
8760
8761 (define_insn "*iorqi_ext_1"
8762 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8763 (const_int 8)
8764 (const_int 8))
8765 (ior:SI
8766 (zero_extract:SI
8767 (match_operand 1 "ext_register_operand" "0")
8768 (const_int 8)
8769 (const_int 8))
8770 (zero_extend:SI
8771 (match_operand:QI 2 "general_operand" "Qm"))))
8772 (clobber (reg:CC 17))]
8773 "!TARGET_64BIT
8774 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8775 "or{b}\t{%2, %h0|%h0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "length_immediate" "0")
8778 (set_attr "mode" "QI")])
8779
8780 (define_insn "*iorqi_ext_1_rex64"
8781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8782 (const_int 8)
8783 (const_int 8))
8784 (ior:SI
8785 (zero_extract:SI
8786 (match_operand 1 "ext_register_operand" "0")
8787 (const_int 8)
8788 (const_int 8))
8789 (zero_extend:SI
8790 (match_operand 2 "ext_register_operand" "Q"))))
8791 (clobber (reg:CC 17))]
8792 "TARGET_64BIT
8793 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8794 "or{b}\t{%2, %h0|%h0, %2}"
8795 [(set_attr "type" "alu")
8796 (set_attr "length_immediate" "0")
8797 (set_attr "mode" "QI")])
8798
8799 (define_insn "*iorqi_ext_2"
8800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8801 (const_int 8)
8802 (const_int 8))
8803 (ior:SI
8804 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8805 (const_int 8)
8806 (const_int 8))
8807 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8808 (const_int 8)
8809 (const_int 8))))
8810 (clobber (reg:CC 17))]
8811 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8812 "ior{b}\t{%h2, %h0|%h0, %h2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "length_immediate" "0")
8815 (set_attr "mode" "QI")])
8816
8817 (define_split
8818 [(set (match_operand 0 "register_operand" "")
8819 (ior (match_operand 1 "register_operand" "")
8820 (match_operand 2 "const_int_operand" "")))
8821 (clobber (reg:CC 17))]
8822 "reload_completed
8823 && QI_REG_P (operands[0])
8824 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8825 && !(INTVAL (operands[2]) & ~(255 << 8))
8826 && GET_MODE (operands[0]) != QImode"
8827 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8828 (ior:SI (zero_extract:SI (match_dup 1)
8829 (const_int 8) (const_int 8))
8830 (match_dup 2)))
8831 (clobber (reg:CC 17))])]
8832 "operands[0] = gen_lowpart (SImode, operands[0]);
8833 operands[1] = gen_lowpart (SImode, operands[1]);
8834 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8835
8836 ;; Since OR can be encoded with sign extended immediate, this is only
8837 ;; profitable when 7th bit is set.
8838 (define_split
8839 [(set (match_operand 0 "register_operand" "")
8840 (ior (match_operand 1 "general_operand" "")
8841 (match_operand 2 "const_int_operand" "")))
8842 (clobber (reg:CC 17))]
8843 "reload_completed
8844 && ANY_QI_REG_P (operands[0])
8845 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8846 && !(INTVAL (operands[2]) & ~255)
8847 && (INTVAL (operands[2]) & 128)
8848 && GET_MODE (operands[0]) != QImode"
8849 [(parallel [(set (strict_low_part (match_dup 0))
8850 (ior:QI (match_dup 1)
8851 (match_dup 2)))
8852 (clobber (reg:CC 17))])]
8853 "operands[0] = gen_lowpart (QImode, operands[0]);
8854 operands[1] = gen_lowpart (QImode, operands[1]);
8855 operands[2] = gen_lowpart (QImode, operands[2]);")
8856 \f
8857 ;; Logical XOR instructions
8858
8859 ;; %%% This used to optimize known byte-wide and operations to memory.
8860 ;; If this is considered useful, it should be done with splitters.
8861
8862 (define_expand "xordi3"
8863 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8864 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8865 (match_operand:DI 2 "x86_64_general_operand" "")))
8866 (clobber (reg:CC 17))]
8867 "TARGET_64BIT"
8868 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8869
8870 (define_insn "*xordi_1_rex64"
8871 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8872 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8873 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8874 (clobber (reg:CC 17))]
8875 "TARGET_64BIT
8876 && ix86_binary_operator_ok (XOR, DImode, operands)"
8877 "@
8878 xor{q}\t{%2, %0|%0, %2}
8879 xor{q}\t{%2, %0|%0, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "mode" "DI,DI")])
8882
8883 (define_insn "*xordi_2_rex64"
8884 [(set (reg 17)
8885 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8886 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8887 (const_int 0)))
8888 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8889 (xor:DI (match_dup 1) (match_dup 2)))]
8890 "TARGET_64BIT
8891 && ix86_match_ccmode (insn, CCNOmode)
8892 && ix86_binary_operator_ok (XOR, DImode, operands)"
8893 "@
8894 xor{q}\t{%2, %0|%0, %2}
8895 xor{q}\t{%2, %0|%0, %2}"
8896 [(set_attr "type" "alu")
8897 (set_attr "mode" "DI,DI")])
8898
8899 (define_insn "*xordi_3_rex64"
8900 [(set (reg 17)
8901 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8902 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8903 (const_int 0)))
8904 (clobber (match_scratch:DI 0 "=r"))]
8905 "TARGET_64BIT
8906 && ix86_match_ccmode (insn, CCNOmode)
8907 && ix86_binary_operator_ok (XOR, DImode, operands)"
8908 "xor{q}\t{%2, %0|%0, %2}"
8909 [(set_attr "type" "alu")
8910 (set_attr "mode" "DI")])
8911
8912 (define_expand "xorsi3"
8913 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8914 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8915 (match_operand:SI 2 "general_operand" "")))
8916 (clobber (reg:CC 17))]
8917 ""
8918 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8919
8920 (define_insn "*xorsi_1"
8921 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8922 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8923 (match_operand:SI 2 "general_operand" "ri,rm")))
8924 (clobber (reg:CC 17))]
8925 "ix86_binary_operator_ok (XOR, SImode, operands)"
8926 "xor{l}\t{%2, %0|%0, %2}"
8927 [(set_attr "type" "alu")
8928 (set_attr "mode" "SI")])
8929
8930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8931 ;; Add speccase for immediates
8932 (define_insn "*xorsi_1_zext"
8933 [(set (match_operand:DI 0 "register_operand" "=r")
8934 (zero_extend:DI
8935 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8936 (match_operand:SI 2 "general_operand" "rim"))))
8937 (clobber (reg:CC 17))]
8938 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8939 "xor{l}\t{%2, %k0|%k0, %2}"
8940 [(set_attr "type" "alu")
8941 (set_attr "mode" "SI")])
8942
8943 (define_insn "*xorsi_1_zext_imm"
8944 [(set (match_operand:DI 0 "register_operand" "=r")
8945 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8946 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8947 (clobber (reg:CC 17))]
8948 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8949 "xor{l}\t{%2, %k0|%k0, %2}"
8950 [(set_attr "type" "alu")
8951 (set_attr "mode" "SI")])
8952
8953 (define_insn "*xorsi_2"
8954 [(set (reg 17)
8955 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8956 (match_operand:SI 2 "general_operand" "rim,ri"))
8957 (const_int 0)))
8958 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8959 (xor:SI (match_dup 1) (match_dup 2)))]
8960 "ix86_match_ccmode (insn, CCNOmode)
8961 && ix86_binary_operator_ok (XOR, SImode, operands)"
8962 "xor{l}\t{%2, %0|%0, %2}"
8963 [(set_attr "type" "alu")
8964 (set_attr "mode" "SI")])
8965
8966 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8967 ;; ??? Special case for immediate operand is missing - it is tricky.
8968 (define_insn "*xorsi_2_zext"
8969 [(set (reg 17)
8970 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8971 (match_operand:SI 2 "general_operand" "rim"))
8972 (const_int 0)))
8973 (set (match_operand:DI 0 "register_operand" "=r")
8974 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8975 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8976 && ix86_binary_operator_ok (XOR, SImode, operands)"
8977 "xor{l}\t{%2, %k0|%k0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "SI")])
8980
8981 (define_insn "*xorsi_2_zext_imm"
8982 [(set (reg 17)
8983 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8984 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8985 (const_int 0)))
8986 (set (match_operand:DI 0 "register_operand" "=r")
8987 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8988 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8989 && ix86_binary_operator_ok (XOR, SImode, operands)"
8990 "xor{l}\t{%2, %k0|%k0, %2}"
8991 [(set_attr "type" "alu")
8992 (set_attr "mode" "SI")])
8993
8994 (define_insn "*xorsi_3"
8995 [(set (reg 17)
8996 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8997 (match_operand:SI 2 "general_operand" "rim"))
8998 (const_int 0)))
8999 (clobber (match_scratch:SI 0 "=r"))]
9000 "ix86_match_ccmode (insn, CCNOmode)
9001 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9002 "xor{l}\t{%2, %0|%0, %2}"
9003 [(set_attr "type" "alu")
9004 (set_attr "mode" "SI")])
9005
9006 (define_expand "xorhi3"
9007 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9008 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9009 (match_operand:HI 2 "general_operand" "")))
9010 (clobber (reg:CC 17))]
9011 "TARGET_HIMODE_MATH"
9012 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9013
9014 (define_insn "*xorhi_1"
9015 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9016 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9017 (match_operand:HI 2 "general_operand" "rmi,ri")))
9018 (clobber (reg:CC 17))]
9019 "ix86_binary_operator_ok (XOR, HImode, operands)"
9020 "xor{w}\t{%2, %0|%0, %2}"
9021 [(set_attr "type" "alu")
9022 (set_attr "mode" "HI")])
9023
9024 (define_insn "*xorhi_2"
9025 [(set (reg 17)
9026 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9027 (match_operand:HI 2 "general_operand" "rim,ri"))
9028 (const_int 0)))
9029 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9030 (xor:HI (match_dup 1) (match_dup 2)))]
9031 "ix86_match_ccmode (insn, CCNOmode)
9032 && ix86_binary_operator_ok (XOR, HImode, operands)"
9033 "xor{w}\t{%2, %0|%0, %2}"
9034 [(set_attr "type" "alu")
9035 (set_attr "mode" "HI")])
9036
9037 (define_insn "*xorhi_3"
9038 [(set (reg 17)
9039 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9040 (match_operand:HI 2 "general_operand" "rim"))
9041 (const_int 0)))
9042 (clobber (match_scratch:HI 0 "=r"))]
9043 "ix86_match_ccmode (insn, CCNOmode)
9044 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9045 "xor{w}\t{%2, %0|%0, %2}"
9046 [(set_attr "type" "alu")
9047 (set_attr "mode" "HI")])
9048
9049 (define_expand "xorqi3"
9050 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9051 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9052 (match_operand:QI 2 "general_operand" "")))
9053 (clobber (reg:CC 17))]
9054 "TARGET_QIMODE_MATH"
9055 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9056
9057 ;; %%% Potential partial reg stall on alternative 2. What to do?
9058 (define_insn "*xorqi_1"
9059 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9060 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9061 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9062 (clobber (reg:CC 17))]
9063 "ix86_binary_operator_ok (XOR, QImode, operands)"
9064 "@
9065 xor{b}\t{%2, %0|%0, %2}
9066 xor{b}\t{%2, %0|%0, %2}
9067 xor{l}\t{%k2, %k0|%k0, %k2}"
9068 [(set_attr "type" "alu")
9069 (set_attr "mode" "QI,QI,SI")])
9070
9071 (define_insn "*xorqi_1_slp"
9072 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9073 (xor:QI (match_dup 0)
9074 (match_operand:QI 1 "general_operand" "qi,qmi")))
9075 (clobber (reg:CC 17))]
9076 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9077 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9078 "xor{b}\t{%1, %0|%0, %1}"
9079 [(set_attr "type" "alu1")
9080 (set_attr "mode" "QI")])
9081
9082 (define_insn "xorqi_ext_0"
9083 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9084 (const_int 8)
9085 (const_int 8))
9086 (xor:SI
9087 (zero_extract:SI
9088 (match_operand 1 "ext_register_operand" "0")
9089 (const_int 8)
9090 (const_int 8))
9091 (match_operand 2 "const_int_operand" "n")))
9092 (clobber (reg:CC 17))]
9093 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9094 "xor{b}\t{%2, %h0|%h0, %2}"
9095 [(set_attr "type" "alu")
9096 (set_attr "length_immediate" "1")
9097 (set_attr "mode" "QI")])
9098
9099 (define_insn "*xorqi_ext_1"
9100 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9101 (const_int 8)
9102 (const_int 8))
9103 (xor:SI
9104 (zero_extract:SI
9105 (match_operand 1 "ext_register_operand" "0")
9106 (const_int 8)
9107 (const_int 8))
9108 (zero_extend:SI
9109 (match_operand:QI 2 "general_operand" "Qm"))))
9110 (clobber (reg:CC 17))]
9111 "!TARGET_64BIT
9112 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9113 "xor{b}\t{%2, %h0|%h0, %2}"
9114 [(set_attr "type" "alu")
9115 (set_attr "length_immediate" "0")
9116 (set_attr "mode" "QI")])
9117
9118 (define_insn "*xorqi_ext_1_rex64"
9119 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9120 (const_int 8)
9121 (const_int 8))
9122 (xor:SI
9123 (zero_extract:SI
9124 (match_operand 1 "ext_register_operand" "0")
9125 (const_int 8)
9126 (const_int 8))
9127 (zero_extend:SI
9128 (match_operand 2 "ext_register_operand" "Q"))))
9129 (clobber (reg:CC 17))]
9130 "TARGET_64BIT
9131 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9132 "xor{b}\t{%2, %h0|%h0, %2}"
9133 [(set_attr "type" "alu")
9134 (set_attr "length_immediate" "0")
9135 (set_attr "mode" "QI")])
9136
9137 (define_insn "*xorqi_ext_2"
9138 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9139 (const_int 8)
9140 (const_int 8))
9141 (xor:SI
9142 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9143 (const_int 8)
9144 (const_int 8))
9145 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9146 (const_int 8)
9147 (const_int 8))))
9148 (clobber (reg:CC 17))]
9149 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9150 "xor{b}\t{%h2, %h0|%h0, %h2}"
9151 [(set_attr "type" "alu")
9152 (set_attr "length_immediate" "0")
9153 (set_attr "mode" "QI")])
9154
9155 (define_insn "*xorqi_cc_1"
9156 [(set (reg 17)
9157 (compare
9158 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9159 (match_operand:QI 2 "general_operand" "qim,qi"))
9160 (const_int 0)))
9161 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9162 (xor:QI (match_dup 1) (match_dup 2)))]
9163 "ix86_match_ccmode (insn, CCNOmode)
9164 && ix86_binary_operator_ok (XOR, QImode, operands)"
9165 "xor{b}\t{%2, %0|%0, %2}"
9166 [(set_attr "type" "alu")
9167 (set_attr "mode" "QI")])
9168
9169 (define_insn "*xorqi_2_slp"
9170 [(set (reg 17)
9171 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9172 (match_operand:QI 1 "general_operand" "qim,qi"))
9173 (const_int 0)))
9174 (set (strict_low_part (match_dup 0))
9175 (xor:QI (match_dup 0) (match_dup 1)))]
9176 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9177 && ix86_match_ccmode (insn, CCNOmode)
9178 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9179 "xor{b}\t{%1, %0|%0, %1}"
9180 [(set_attr "type" "alu1")
9181 (set_attr "mode" "QI")])
9182
9183 (define_insn "*xorqi_cc_2"
9184 [(set (reg 17)
9185 (compare
9186 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9187 (match_operand:QI 2 "general_operand" "qim"))
9188 (const_int 0)))
9189 (clobber (match_scratch:QI 0 "=q"))]
9190 "ix86_match_ccmode (insn, CCNOmode)
9191 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9192 "xor{b}\t{%2, %0|%0, %2}"
9193 [(set_attr "type" "alu")
9194 (set_attr "mode" "QI")])
9195
9196 (define_insn "*xorqi_cc_ext_1"
9197 [(set (reg 17)
9198 (compare
9199 (xor:SI
9200 (zero_extract:SI
9201 (match_operand 1 "ext_register_operand" "0")
9202 (const_int 8)
9203 (const_int 8))
9204 (match_operand:QI 2 "general_operand" "qmn"))
9205 (const_int 0)))
9206 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9207 (const_int 8)
9208 (const_int 8))
9209 (xor:SI
9210 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9211 (match_dup 2)))]
9212 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9213 "xor{b}\t{%2, %h0|%h0, %2}"
9214 [(set_attr "type" "alu")
9215 (set_attr "mode" "QI")])
9216
9217 (define_insn "*xorqi_cc_ext_1_rex64"
9218 [(set (reg 17)
9219 (compare
9220 (xor:SI
9221 (zero_extract:SI
9222 (match_operand 1 "ext_register_operand" "0")
9223 (const_int 8)
9224 (const_int 8))
9225 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9226 (const_int 0)))
9227 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9228 (const_int 8)
9229 (const_int 8))
9230 (xor:SI
9231 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9232 (match_dup 2)))]
9233 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9234 "xor{b}\t{%2, %h0|%h0, %2}"
9235 [(set_attr "type" "alu")
9236 (set_attr "mode" "QI")])
9237
9238 (define_expand "xorqi_cc_ext_1"
9239 [(parallel [
9240 (set (reg:CCNO 17)
9241 (compare:CCNO
9242 (xor:SI
9243 (zero_extract:SI
9244 (match_operand 1 "ext_register_operand" "")
9245 (const_int 8)
9246 (const_int 8))
9247 (match_operand:QI 2 "general_operand" ""))
9248 (const_int 0)))
9249 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9250 (const_int 8)
9251 (const_int 8))
9252 (xor:SI
9253 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9254 (match_dup 2)))])]
9255 ""
9256 "")
9257
9258 (define_split
9259 [(set (match_operand 0 "register_operand" "")
9260 (xor (match_operand 1 "register_operand" "")
9261 (match_operand 2 "const_int_operand" "")))
9262 (clobber (reg:CC 17))]
9263 "reload_completed
9264 && QI_REG_P (operands[0])
9265 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9266 && !(INTVAL (operands[2]) & ~(255 << 8))
9267 && GET_MODE (operands[0]) != QImode"
9268 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9269 (xor:SI (zero_extract:SI (match_dup 1)
9270 (const_int 8) (const_int 8))
9271 (match_dup 2)))
9272 (clobber (reg:CC 17))])]
9273 "operands[0] = gen_lowpart (SImode, operands[0]);
9274 operands[1] = gen_lowpart (SImode, operands[1]);
9275 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9276
9277 ;; Since XOR can be encoded with sign extended immediate, this is only
9278 ;; profitable when 7th bit is set.
9279 (define_split
9280 [(set (match_operand 0 "register_operand" "")
9281 (xor (match_operand 1 "general_operand" "")
9282 (match_operand 2 "const_int_operand" "")))
9283 (clobber (reg:CC 17))]
9284 "reload_completed
9285 && ANY_QI_REG_P (operands[0])
9286 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9287 && !(INTVAL (operands[2]) & ~255)
9288 && (INTVAL (operands[2]) & 128)
9289 && GET_MODE (operands[0]) != QImode"
9290 [(parallel [(set (strict_low_part (match_dup 0))
9291 (xor:QI (match_dup 1)
9292 (match_dup 2)))
9293 (clobber (reg:CC 17))])]
9294 "operands[0] = gen_lowpart (QImode, operands[0]);
9295 operands[1] = gen_lowpart (QImode, operands[1]);
9296 operands[2] = gen_lowpart (QImode, operands[2]);")
9297 \f
9298 ;; Negation instructions
9299
9300 (define_expand "negdi2"
9301 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9302 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9303 (clobber (reg:CC 17))])]
9304 ""
9305 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9306
9307 (define_insn "*negdi2_1"
9308 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9309 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9310 (clobber (reg:CC 17))]
9311 "!TARGET_64BIT
9312 && ix86_unary_operator_ok (NEG, DImode, operands)"
9313 "#")
9314
9315 (define_split
9316 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9317 (neg:DI (match_operand:DI 1 "general_operand" "")))
9318 (clobber (reg:CC 17))]
9319 "!TARGET_64BIT && reload_completed"
9320 [(parallel
9321 [(set (reg:CCZ 17)
9322 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9323 (set (match_dup 0) (neg:SI (match_dup 2)))])
9324 (parallel
9325 [(set (match_dup 1)
9326 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9327 (match_dup 3))
9328 (const_int 0)))
9329 (clobber (reg:CC 17))])
9330 (parallel
9331 [(set (match_dup 1)
9332 (neg:SI (match_dup 1)))
9333 (clobber (reg:CC 17))])]
9334 "split_di (operands+1, 1, operands+2, operands+3);
9335 split_di (operands+0, 1, operands+0, operands+1);")
9336
9337 (define_insn "*negdi2_1_rex64"
9338 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9339 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9340 (clobber (reg:CC 17))]
9341 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9342 "neg{q}\t%0"
9343 [(set_attr "type" "negnot")
9344 (set_attr "mode" "DI")])
9345
9346 ;; The problem with neg is that it does not perform (compare x 0),
9347 ;; it really performs (compare 0 x), which leaves us with the zero
9348 ;; flag being the only useful item.
9349
9350 (define_insn "*negdi2_cmpz_rex64"
9351 [(set (reg:CCZ 17)
9352 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9353 (const_int 0)))
9354 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9355 (neg:DI (match_dup 1)))]
9356 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9357 "neg{q}\t%0"
9358 [(set_attr "type" "negnot")
9359 (set_attr "mode" "DI")])
9360
9361
9362 (define_expand "negsi2"
9363 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9364 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9365 (clobber (reg:CC 17))])]
9366 ""
9367 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9368
9369 (define_insn "*negsi2_1"
9370 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9371 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9372 (clobber (reg:CC 17))]
9373 "ix86_unary_operator_ok (NEG, SImode, operands)"
9374 "neg{l}\t%0"
9375 [(set_attr "type" "negnot")
9376 (set_attr "mode" "SI")])
9377
9378 ;; Combine is quite creative about this pattern.
9379 (define_insn "*negsi2_1_zext"
9380 [(set (match_operand:DI 0 "register_operand" "=r")
9381 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9382 (const_int 32)))
9383 (const_int 32)))
9384 (clobber (reg:CC 17))]
9385 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9386 "neg{l}\t%k0"
9387 [(set_attr "type" "negnot")
9388 (set_attr "mode" "SI")])
9389
9390 ;; The problem with neg is that it does not perform (compare x 0),
9391 ;; it really performs (compare 0 x), which leaves us with the zero
9392 ;; flag being the only useful item.
9393
9394 (define_insn "*negsi2_cmpz"
9395 [(set (reg:CCZ 17)
9396 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9397 (const_int 0)))
9398 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9399 (neg:SI (match_dup 1)))]
9400 "ix86_unary_operator_ok (NEG, SImode, operands)"
9401 "neg{l}\t%0"
9402 [(set_attr "type" "negnot")
9403 (set_attr "mode" "SI")])
9404
9405 (define_insn "*negsi2_cmpz_zext"
9406 [(set (reg:CCZ 17)
9407 (compare:CCZ (lshiftrt:DI
9408 (neg:DI (ashift:DI
9409 (match_operand:DI 1 "register_operand" "0")
9410 (const_int 32)))
9411 (const_int 32))
9412 (const_int 0)))
9413 (set (match_operand:DI 0 "register_operand" "=r")
9414 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9415 (const_int 32)))
9416 (const_int 32)))]
9417 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9418 "neg{l}\t%k0"
9419 [(set_attr "type" "negnot")
9420 (set_attr "mode" "SI")])
9421
9422 (define_expand "neghi2"
9423 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9424 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9425 (clobber (reg:CC 17))])]
9426 "TARGET_HIMODE_MATH"
9427 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9428
9429 (define_insn "*neghi2_1"
9430 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9431 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9432 (clobber (reg:CC 17))]
9433 "ix86_unary_operator_ok (NEG, HImode, operands)"
9434 "neg{w}\t%0"
9435 [(set_attr "type" "negnot")
9436 (set_attr "mode" "HI")])
9437
9438 (define_insn "*neghi2_cmpz"
9439 [(set (reg:CCZ 17)
9440 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9441 (const_int 0)))
9442 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9443 (neg:HI (match_dup 1)))]
9444 "ix86_unary_operator_ok (NEG, HImode, operands)"
9445 "neg{w}\t%0"
9446 [(set_attr "type" "negnot")
9447 (set_attr "mode" "HI")])
9448
9449 (define_expand "negqi2"
9450 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9451 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9452 (clobber (reg:CC 17))])]
9453 "TARGET_QIMODE_MATH"
9454 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9455
9456 (define_insn "*negqi2_1"
9457 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9458 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9459 (clobber (reg:CC 17))]
9460 "ix86_unary_operator_ok (NEG, QImode, operands)"
9461 "neg{b}\t%0"
9462 [(set_attr "type" "negnot")
9463 (set_attr "mode" "QI")])
9464
9465 (define_insn "*negqi2_cmpz"
9466 [(set (reg:CCZ 17)
9467 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9468 (const_int 0)))
9469 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9470 (neg:QI (match_dup 1)))]
9471 "ix86_unary_operator_ok (NEG, QImode, operands)"
9472 "neg{b}\t%0"
9473 [(set_attr "type" "negnot")
9474 (set_attr "mode" "QI")])
9475
9476 ;; Changing of sign for FP values is doable using integer unit too.
9477
9478 (define_expand "negsf2"
9479 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9480 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9481 (clobber (reg:CC 17))])]
9482 "TARGET_80387"
9483 "if (TARGET_SSE)
9484 {
9485 /* In case operand is in memory, we will not use SSE. */
9486 if (memory_operand (operands[0], VOIDmode)
9487 && rtx_equal_p (operands[0], operands[1]))
9488 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9489 else
9490 {
9491 /* Using SSE is tricky, since we need bitwise negation of -0
9492 in register. */
9493 rtx reg = gen_reg_rtx (SFmode);
9494 rtx dest = operands[0];
9495 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9496
9497 operands[1] = force_reg (SFmode, operands[1]);
9498 operands[0] = force_reg (SFmode, operands[0]);
9499 reg = force_reg (V4SFmode,
9500 gen_rtx_CONST_VECTOR (V4SFmode,
9501 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9502 CONST0_RTX (SFmode),
9503 CONST0_RTX (SFmode))));
9504 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9505 if (dest != operands[0])
9506 emit_move_insn (dest, operands[0]);
9507 }
9508 DONE;
9509 }
9510 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9511
9512 (define_insn "negsf2_memory"
9513 [(set (match_operand:SF 0 "memory_operand" "=m")
9514 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9515 (clobber (reg:CC 17))]
9516 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9517 "#")
9518
9519 (define_insn "negsf2_ifs"
9520 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9521 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9522 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9523 (clobber (reg:CC 17))]
9524 "TARGET_SSE
9525 && (reload_in_progress || reload_completed
9526 || (register_operand (operands[0], VOIDmode)
9527 && register_operand (operands[1], VOIDmode)))"
9528 "#")
9529
9530 (define_split
9531 [(set (match_operand:SF 0 "memory_operand" "")
9532 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9533 (use (match_operand:SF 2 "" ""))
9534 (clobber (reg:CC 17))]
9535 ""
9536 [(parallel [(set (match_dup 0)
9537 (neg:SF (match_dup 1)))
9538 (clobber (reg:CC 17))])])
9539
9540 (define_split
9541 [(set (match_operand:SF 0 "register_operand" "")
9542 (neg:SF (match_operand:SF 1 "register_operand" "")))
9543 (use (match_operand:V4SF 2 "" ""))
9544 (clobber (reg:CC 17))]
9545 "reload_completed && !SSE_REG_P (operands[0])"
9546 [(parallel [(set (match_dup 0)
9547 (neg:SF (match_dup 1)))
9548 (clobber (reg:CC 17))])])
9549
9550 (define_split
9551 [(set (match_operand:SF 0 "register_operand" "")
9552 (neg:SF (match_operand:SF 1 "register_operand" "")))
9553 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9554 (clobber (reg:CC 17))]
9555 "reload_completed && SSE_REG_P (operands[0])"
9556 [(set (subreg:TI (match_dup 0) 0)
9557 (xor:TI (match_dup 1)
9558 (match_dup 2)))]
9559 {
9560 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9561 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9562 if (operands_match_p (operands[0], operands[2]))
9563 {
9564 rtx tmp;
9565 tmp = operands[1];
9566 operands[1] = operands[2];
9567 operands[2] = tmp;
9568 }
9569 })
9570
9571
9572 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9573 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9574 ;; to itself.
9575 (define_insn "*negsf2_if"
9576 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9577 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9578 (clobber (reg:CC 17))]
9579 "TARGET_80387 && !TARGET_SSE
9580 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9581 "#")
9582
9583 (define_split
9584 [(set (match_operand:SF 0 "fp_register_operand" "")
9585 (neg:SF (match_operand:SF 1 "register_operand" "")))
9586 (clobber (reg:CC 17))]
9587 "TARGET_80387 && reload_completed"
9588 [(set (match_dup 0)
9589 (neg:SF (match_dup 1)))]
9590 "")
9591
9592 (define_split
9593 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9594 (neg:SF (match_operand:SF 1 "register_operand" "")))
9595 (clobber (reg:CC 17))]
9596 "TARGET_80387 && reload_completed"
9597 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9598 (clobber (reg:CC 17))])]
9599 "operands[1] = gen_int_mode (0x80000000, SImode);
9600 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9601
9602 (define_split
9603 [(set (match_operand 0 "memory_operand" "")
9604 (neg (match_operand 1 "memory_operand" "")))
9605 (clobber (reg:CC 17))]
9606 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9607 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9608 (clobber (reg:CC 17))])]
9609 {
9610 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9611
9612 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9613 if (size >= 12)
9614 size = 10;
9615 operands[0] = adjust_address (operands[0], QImode, size - 1);
9616 operands[1] = gen_int_mode (0x80, QImode);
9617 })
9618
9619 (define_expand "negdf2"
9620 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9621 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9622 (clobber (reg:CC 17))])]
9623 "TARGET_80387"
9624 "if (TARGET_SSE2)
9625 {
9626 /* In case operand is in memory, we will not use SSE. */
9627 if (memory_operand (operands[0], VOIDmode)
9628 && rtx_equal_p (operands[0], operands[1]))
9629 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9630 else
9631 {
9632 /* Using SSE is tricky, since we need bitwise negation of -0
9633 in register. */
9634 rtx reg;
9635 #if HOST_BITS_PER_WIDE_INT >= 64
9636 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9637 #else
9638 rtx imm = immed_double_const (0, 0x80000000, DImode);
9639 #endif
9640 rtx dest = operands[0];
9641
9642 operands[1] = force_reg (DFmode, operands[1]);
9643 operands[0] = force_reg (DFmode, operands[0]);
9644 imm = gen_lowpart (DFmode, imm);
9645 reg = force_reg (V2DFmode,
9646 gen_rtx_CONST_VECTOR (V2DFmode,
9647 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9648 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9649 if (dest != operands[0])
9650 emit_move_insn (dest, operands[0]);
9651 }
9652 DONE;
9653 }
9654 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9655
9656 (define_insn "negdf2_memory"
9657 [(set (match_operand:DF 0 "memory_operand" "=m")
9658 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9659 (clobber (reg:CC 17))]
9660 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9661 "#")
9662
9663 (define_insn "negdf2_ifs"
9664 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9665 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9666 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9667 (clobber (reg:CC 17))]
9668 "!TARGET_64BIT && TARGET_SSE2
9669 && (reload_in_progress || reload_completed
9670 || (register_operand (operands[0], VOIDmode)
9671 && register_operand (operands[1], VOIDmode)))"
9672 "#")
9673
9674 (define_insn "*negdf2_ifs_rex64"
9675 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9676 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9677 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9678 (clobber (reg:CC 17))]
9679 "TARGET_64BIT && TARGET_SSE2
9680 && (reload_in_progress || reload_completed
9681 || (register_operand (operands[0], VOIDmode)
9682 && register_operand (operands[1], VOIDmode)))"
9683 "#")
9684
9685 (define_split
9686 [(set (match_operand:DF 0 "memory_operand" "")
9687 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9688 (use (match_operand:V2DF 2 "" ""))
9689 (clobber (reg:CC 17))]
9690 ""
9691 [(parallel [(set (match_dup 0)
9692 (neg:DF (match_dup 1)))
9693 (clobber (reg:CC 17))])])
9694
9695 (define_split
9696 [(set (match_operand:DF 0 "register_operand" "")
9697 (neg:DF (match_operand:DF 1 "register_operand" "")))
9698 (use (match_operand:V2DF 2 "" ""))
9699 (clobber (reg:CC 17))]
9700 "reload_completed && !SSE_REG_P (operands[0])
9701 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9702 [(parallel [(set (match_dup 0)
9703 (neg:DF (match_dup 1)))
9704 (clobber (reg:CC 17))])])
9705
9706 (define_split
9707 [(set (match_operand:DF 0 "register_operand" "")
9708 (neg:DF (match_operand:DF 1 "register_operand" "")))
9709 (use (match_operand:V2DF 2 "" ""))
9710 (clobber (reg:CC 17))]
9711 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9712 [(parallel [(set (match_dup 0)
9713 (xor:DI (match_dup 1) (match_dup 2)))
9714 (clobber (reg:CC 17))])]
9715 "operands[0] = gen_lowpart (DImode, operands[0]);
9716 operands[1] = gen_lowpart (DImode, operands[1]);
9717 operands[2] = gen_lowpart (DImode, operands[2]);")
9718
9719 (define_split
9720 [(set (match_operand:DF 0 "register_operand" "")
9721 (neg:DF (match_operand:DF 1 "register_operand" "")))
9722 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9723 (clobber (reg:CC 17))]
9724 "reload_completed && SSE_REG_P (operands[0])"
9725 [(set (subreg:TI (match_dup 0) 0)
9726 (xor:TI (match_dup 1)
9727 (match_dup 2)))]
9728 {
9729 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9730 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
9731 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
9732 /* Avoid possible reformating on the operands. */
9733 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9734 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9735 if (operands_match_p (operands[0], operands[2]))
9736 {
9737 rtx tmp;
9738 tmp = operands[1];
9739 operands[1] = operands[2];
9740 operands[2] = tmp;
9741 }
9742 })
9743
9744 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9745 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9746 ;; to itself.
9747 (define_insn "*negdf2_if"
9748 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9749 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9750 (clobber (reg:CC 17))]
9751 "!TARGET_64BIT && TARGET_80387
9752 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9753 "#")
9754
9755 ;; FIXME: We should to allow integer registers here. Problem is that
9756 ;; we need another scratch register to get constant from.
9757 ;; Forcing constant to mem if no register available in peep2 should be
9758 ;; safe even for PIC mode, because of RIP relative addressing.
9759 (define_insn "*negdf2_if_rex64"
9760 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9761 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9762 (clobber (reg:CC 17))]
9763 "TARGET_64BIT && TARGET_80387
9764 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9765 "#")
9766
9767 (define_split
9768 [(set (match_operand:DF 0 "fp_register_operand" "")
9769 (neg:DF (match_operand:DF 1 "register_operand" "")))
9770 (clobber (reg:CC 17))]
9771 "TARGET_80387 && reload_completed"
9772 [(set (match_dup 0)
9773 (neg:DF (match_dup 1)))]
9774 "")
9775
9776 (define_split
9777 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9778 (neg:DF (match_operand:DF 1 "register_operand" "")))
9779 (clobber (reg:CC 17))]
9780 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9781 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9782 (clobber (reg:CC 17))])]
9783 "operands[4] = gen_int_mode (0x80000000, SImode);
9784 split_di (operands+0, 1, operands+2, operands+3);")
9785
9786 (define_expand "negxf2"
9787 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9788 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9789 (clobber (reg:CC 17))])]
9790 "!TARGET_64BIT && TARGET_80387"
9791 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9792
9793 (define_expand "negtf2"
9794 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9795 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9796 (clobber (reg:CC 17))])]
9797 "TARGET_80387"
9798 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9799
9800 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9801 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9802 ;; to itself.
9803 (define_insn "*negxf2_if"
9804 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9805 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9806 (clobber (reg:CC 17))]
9807 "!TARGET_64BIT && TARGET_80387
9808 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9809 "#")
9810
9811 (define_split
9812 [(set (match_operand:XF 0 "fp_register_operand" "")
9813 (neg:XF (match_operand:XF 1 "register_operand" "")))
9814 (clobber (reg:CC 17))]
9815 "TARGET_80387 && reload_completed"
9816 [(set (match_dup 0)
9817 (neg:XF (match_dup 1)))]
9818 "")
9819
9820 (define_split
9821 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9822 (neg:XF (match_operand:XF 1 "register_operand" "")))
9823 (clobber (reg:CC 17))]
9824 "TARGET_80387 && reload_completed"
9825 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9826 (clobber (reg:CC 17))])]
9827 "operands[1] = GEN_INT (0x8000);
9828 operands[0] = gen_rtx_REG (SImode,
9829 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9830
9831 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9832 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9833 ;; to itself.
9834 (define_insn "*negtf2_if"
9835 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9836 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9837 (clobber (reg:CC 17))]
9838 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9839 "#")
9840
9841 (define_split
9842 [(set (match_operand:TF 0 "fp_register_operand" "")
9843 (neg:TF (match_operand:TF 1 "register_operand" "")))
9844 (clobber (reg:CC 17))]
9845 "TARGET_80387 && reload_completed"
9846 [(set (match_dup 0)
9847 (neg:TF (match_dup 1)))]
9848 "")
9849
9850 (define_split
9851 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
9852 (neg:TF (match_operand:TF 1 "register_operand" "")))
9853 (clobber (reg:CC 17))]
9854 "TARGET_80387 && reload_completed"
9855 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9856 (clobber (reg:CC 17))])]
9857 "operands[1] = GEN_INT (0x8000);
9858 operands[0] = gen_rtx_REG (SImode,
9859 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9860
9861 ;; Conditionize these after reload. If they matches before reload, we
9862 ;; lose the clobber and ability to use integer instructions.
9863
9864 (define_insn "*negsf2_1"
9865 [(set (match_operand:SF 0 "register_operand" "=f")
9866 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9867 "TARGET_80387 && reload_completed"
9868 "fchs"
9869 [(set_attr "type" "fsgn")
9870 (set_attr "mode" "SF")
9871 (set_attr "ppro_uops" "few")])
9872
9873 (define_insn "*negdf2_1"
9874 [(set (match_operand:DF 0 "register_operand" "=f")
9875 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9876 "TARGET_80387 && reload_completed"
9877 "fchs"
9878 [(set_attr "type" "fsgn")
9879 (set_attr "mode" "DF")
9880 (set_attr "ppro_uops" "few")])
9881
9882 (define_insn "*negextendsfdf2"
9883 [(set (match_operand:DF 0 "register_operand" "=f")
9884 (neg:DF (float_extend:DF
9885 (match_operand:SF 1 "register_operand" "0"))))]
9886 "TARGET_80387"
9887 "fchs"
9888 [(set_attr "type" "fsgn")
9889 (set_attr "mode" "DF")
9890 (set_attr "ppro_uops" "few")])
9891
9892 (define_insn "*negxf2_1"
9893 [(set (match_operand:XF 0 "register_operand" "=f")
9894 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9895 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9896 "fchs"
9897 [(set_attr "type" "fsgn")
9898 (set_attr "mode" "XF")
9899 (set_attr "ppro_uops" "few")])
9900
9901 (define_insn "*negextenddfxf2"
9902 [(set (match_operand:XF 0 "register_operand" "=f")
9903 (neg:XF (float_extend:XF
9904 (match_operand:DF 1 "register_operand" "0"))))]
9905 "!TARGET_64BIT && TARGET_80387"
9906 "fchs"
9907 [(set_attr "type" "fsgn")
9908 (set_attr "mode" "XF")
9909 (set_attr "ppro_uops" "few")])
9910
9911 (define_insn "*negextendsfxf2"
9912 [(set (match_operand:XF 0 "register_operand" "=f")
9913 (neg:XF (float_extend:XF
9914 (match_operand:SF 1 "register_operand" "0"))))]
9915 "!TARGET_64BIT && TARGET_80387"
9916 "fchs"
9917 [(set_attr "type" "fsgn")
9918 (set_attr "mode" "XF")
9919 (set_attr "ppro_uops" "few")])
9920
9921 (define_insn "*negtf2_1"
9922 [(set (match_operand:TF 0 "register_operand" "=f")
9923 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9924 "TARGET_80387 && reload_completed"
9925 "fchs"
9926 [(set_attr "type" "fsgn")
9927 (set_attr "mode" "XF")
9928 (set_attr "ppro_uops" "few")])
9929
9930 (define_insn "*negextenddftf2"
9931 [(set (match_operand:TF 0 "register_operand" "=f")
9932 (neg:TF (float_extend:TF
9933 (match_operand:DF 1 "register_operand" "0"))))]
9934 "TARGET_80387"
9935 "fchs"
9936 [(set_attr "type" "fsgn")
9937 (set_attr "mode" "XF")
9938 (set_attr "ppro_uops" "few")])
9939
9940 (define_insn "*negextendsftf2"
9941 [(set (match_operand:TF 0 "register_operand" "=f")
9942 (neg:TF (float_extend:TF
9943 (match_operand:SF 1 "register_operand" "0"))))]
9944 "TARGET_80387"
9945 "fchs"
9946 [(set_attr "type" "fsgn")
9947 (set_attr "mode" "XF")
9948 (set_attr "ppro_uops" "few")])
9949 \f
9950 ;; Absolute value instructions
9951
9952 (define_expand "abssf2"
9953 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9954 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9955 (clobber (reg:CC 17))])]
9956 "TARGET_80387"
9957 "if (TARGET_SSE)
9958 {
9959 /* In case operand is in memory, we will not use SSE. */
9960 if (memory_operand (operands[0], VOIDmode)
9961 && rtx_equal_p (operands[0], operands[1]))
9962 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9963 else
9964 {
9965 /* Using SSE is tricky, since we need bitwise negation of -0
9966 in register. */
9967 rtx reg = gen_reg_rtx (V4SFmode);
9968 rtx dest = operands[0];
9969 rtx imm;
9970
9971 operands[1] = force_reg (SFmode, operands[1]);
9972 operands[0] = force_reg (SFmode, operands[0]);
9973 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9974 reg = force_reg (V4SFmode,
9975 gen_rtx_CONST_VECTOR (V4SFmode,
9976 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9977 CONST0_RTX (SFmode),
9978 CONST0_RTX (SFmode))));
9979 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9980 if (dest != operands[0])
9981 emit_move_insn (dest, operands[0]);
9982 }
9983 DONE;
9984 }
9985 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9986
9987 (define_insn "abssf2_memory"
9988 [(set (match_operand:SF 0 "memory_operand" "=m")
9989 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9990 (clobber (reg:CC 17))]
9991 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9992 "#")
9993
9994 (define_insn "abssf2_ifs"
9995 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9996 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9997 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9998 (clobber (reg:CC 17))]
9999 "TARGET_SSE
10000 && (reload_in_progress || reload_completed
10001 || (register_operand (operands[0], VOIDmode)
10002 && register_operand (operands[1], VOIDmode)))"
10003 "#")
10004
10005 (define_split
10006 [(set (match_operand:SF 0 "memory_operand" "")
10007 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10008 (use (match_operand:V4SF 2 "" ""))
10009 (clobber (reg:CC 17))]
10010 ""
10011 [(parallel [(set (match_dup 0)
10012 (abs:SF (match_dup 1)))
10013 (clobber (reg:CC 17))])])
10014
10015 (define_split
10016 [(set (match_operand:SF 0 "register_operand" "")
10017 (abs:SF (match_operand:SF 1 "register_operand" "")))
10018 (use (match_operand:V4SF 2 "" ""))
10019 (clobber (reg:CC 17))]
10020 "reload_completed && !SSE_REG_P (operands[0])"
10021 [(parallel [(set (match_dup 0)
10022 (abs:SF (match_dup 1)))
10023 (clobber (reg:CC 17))])])
10024
10025 (define_split
10026 [(set (match_operand:SF 0 "register_operand" "")
10027 (abs:SF (match_operand:SF 1 "register_operand" "")))
10028 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10029 (clobber (reg:CC 17))]
10030 "reload_completed && SSE_REG_P (operands[0])"
10031 [(set (subreg:TI (match_dup 0) 0)
10032 (and:TI (match_dup 1)
10033 (match_dup 2)))]
10034 {
10035 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10036 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10037 if (operands_match_p (operands[0], operands[2]))
10038 {
10039 rtx tmp;
10040 tmp = operands[1];
10041 operands[1] = operands[2];
10042 operands[2] = tmp;
10043 }
10044 })
10045
10046 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10047 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10048 ;; to itself.
10049 (define_insn "*abssf2_if"
10050 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10051 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10052 (clobber (reg:CC 17))]
10053 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10054 "#")
10055
10056 (define_split
10057 [(set (match_operand:SF 0 "fp_register_operand" "")
10058 (abs:SF (match_operand:SF 1 "register_operand" "")))
10059 (clobber (reg:CC 17))]
10060 "TARGET_80387"
10061 [(set (match_dup 0)
10062 (abs:SF (match_dup 1)))]
10063 "")
10064
10065 (define_split
10066 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10067 (abs:SF (match_operand:SF 1 "register_operand" "")))
10068 (clobber (reg:CC 17))]
10069 "TARGET_80387 && reload_completed"
10070 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10071 (clobber (reg:CC 17))])]
10072 "operands[1] = gen_int_mode (~0x80000000, SImode);
10073 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
10074
10075 (define_split
10076 [(set (match_operand 0 "memory_operand" "")
10077 (abs (match_operand 1 "memory_operand" "")))
10078 (clobber (reg:CC 17))]
10079 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10080 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10081 (clobber (reg:CC 17))])]
10082 {
10083 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10084
10085 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10086 if (size >= 12)
10087 size = 10;
10088 operands[0] = adjust_address (operands[0], QImode, size - 1);
10089 operands[1] = gen_int_mode (~0x80, QImode);
10090 })
10091
10092 (define_expand "absdf2"
10093 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10094 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10095 (clobber (reg:CC 17))])]
10096 "TARGET_80387"
10097 "if (TARGET_SSE2)
10098 {
10099 /* In case operand is in memory, we will not use SSE. */
10100 if (memory_operand (operands[0], VOIDmode)
10101 && rtx_equal_p (operands[0], operands[1]))
10102 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10103 else
10104 {
10105 /* Using SSE is tricky, since we need bitwise negation of -0
10106 in register. */
10107 rtx reg = gen_reg_rtx (V2DFmode);
10108 #if HOST_BITS_PER_WIDE_INT >= 64
10109 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10110 #else
10111 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10112 #endif
10113 rtx dest = operands[0];
10114
10115 operands[1] = force_reg (DFmode, operands[1]);
10116 operands[0] = force_reg (DFmode, operands[0]);
10117
10118 /* Produce LONG_DOUBLE with the proper immediate argument. */
10119 imm = gen_lowpart (DFmode, imm);
10120 reg = force_reg (V2DFmode,
10121 gen_rtx_CONST_VECTOR (V2DFmode,
10122 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10123 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10124 if (dest != operands[0])
10125 emit_move_insn (dest, operands[0]);
10126 }
10127 DONE;
10128 }
10129 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10130
10131 (define_insn "absdf2_memory"
10132 [(set (match_operand:DF 0 "memory_operand" "=m")
10133 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10134 (clobber (reg:CC 17))]
10135 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10136 "#")
10137
10138 (define_insn "absdf2_ifs"
10139 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10140 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10141 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10142 (clobber (reg:CC 17))]
10143 "!TARGET_64BIT && TARGET_SSE2
10144 && (reload_in_progress || reload_completed
10145 || (register_operand (operands[0], VOIDmode)
10146 && register_operand (operands[1], VOIDmode)))"
10147 "#")
10148
10149 (define_insn "*absdf2_ifs_rex64"
10150 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10151 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10152 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10153 (clobber (reg:CC 17))]
10154 "TARGET_64BIT && TARGET_SSE2
10155 && (reload_in_progress || reload_completed
10156 || (register_operand (operands[0], VOIDmode)
10157 && register_operand (operands[1], VOIDmode)))"
10158 "#")
10159
10160 (define_split
10161 [(set (match_operand:DF 0 "memory_operand" "")
10162 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10163 (use (match_operand:V2DF 2 "" ""))
10164 (clobber (reg:CC 17))]
10165 ""
10166 [(parallel [(set (match_dup 0)
10167 (abs:DF (match_dup 1)))
10168 (clobber (reg:CC 17))])])
10169
10170 (define_split
10171 [(set (match_operand:DF 0 "register_operand" "")
10172 (abs:DF (match_operand:DF 1 "register_operand" "")))
10173 (use (match_operand:V2DF 2 "" ""))
10174 (clobber (reg:CC 17))]
10175 "reload_completed && !SSE_REG_P (operands[0])"
10176 [(parallel [(set (match_dup 0)
10177 (abs:DF (match_dup 1)))
10178 (clobber (reg:CC 17))])])
10179
10180 (define_split
10181 [(set (match_operand:DF 0 "register_operand" "")
10182 (abs:DF (match_operand:DF 1 "register_operand" "")))
10183 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10184 (clobber (reg:CC 17))]
10185 "reload_completed && SSE_REG_P (operands[0])"
10186 [(set (subreg:TI (match_dup 0) 0)
10187 (and:TI (match_dup 1)
10188 (match_dup 2)))]
10189 {
10190 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10191 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10192 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10193 /* Avoid possible reformating on the operands. */
10194 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10195 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10196 if (operands_match_p (operands[0], operands[2]))
10197 {
10198 rtx tmp;
10199 tmp = operands[1];
10200 operands[1] = operands[2];
10201 operands[2] = tmp;
10202 }
10203 })
10204
10205
10206 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10207 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10208 ;; to itself.
10209 (define_insn "*absdf2_if"
10210 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10211 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10212 (clobber (reg:CC 17))]
10213 "!TARGET_64BIT && TARGET_80387
10214 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10215 "#")
10216
10217 ;; FIXME: We should to allow integer registers here. Problem is that
10218 ;; we need another scratch register to get constant from.
10219 ;; Forcing constant to mem if no register available in peep2 should be
10220 ;; safe even for PIC mode, because of RIP relative addressing.
10221 (define_insn "*absdf2_if_rex64"
10222 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10223 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10224 (clobber (reg:CC 17))]
10225 "TARGET_64BIT && TARGET_80387
10226 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10227 "#")
10228
10229 (define_split
10230 [(set (match_operand:DF 0 "fp_register_operand" "")
10231 (abs:DF (match_operand:DF 1 "register_operand" "")))
10232 (clobber (reg:CC 17))]
10233 "TARGET_80387 && reload_completed"
10234 [(set (match_dup 0)
10235 (abs:DF (match_dup 1)))]
10236 "")
10237
10238 (define_split
10239 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10240 (abs:DF (match_operand:DF 1 "register_operand" "")))
10241 (clobber (reg:CC 17))]
10242 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10243 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10244 (clobber (reg:CC 17))])]
10245 "operands[4] = gen_int_mode (~0x80000000, SImode);
10246 split_di (operands+0, 1, operands+2, operands+3);")
10247
10248 (define_expand "absxf2"
10249 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10250 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10251 (clobber (reg:CC 17))])]
10252 "!TARGET_64BIT && TARGET_80387"
10253 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10254
10255 (define_expand "abstf2"
10256 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10257 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10258 (clobber (reg:CC 17))])]
10259 "TARGET_80387"
10260 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10261
10262 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10263 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10264 ;; to itself.
10265 (define_insn "*absxf2_if"
10266 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10267 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10268 (clobber (reg:CC 17))]
10269 "!TARGET_64BIT && TARGET_80387
10270 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10271 "#")
10272
10273 (define_split
10274 [(set (match_operand:XF 0 "fp_register_operand" "")
10275 (abs:XF (match_operand:XF 1 "register_operand" "")))
10276 (clobber (reg:CC 17))]
10277 "TARGET_80387 && reload_completed"
10278 [(set (match_dup 0)
10279 (abs:XF (match_dup 1)))]
10280 "")
10281
10282 (define_split
10283 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10284 (abs:XF (match_operand:XF 1 "register_operand" "")))
10285 (clobber (reg:CC 17))]
10286 "TARGET_80387 && reload_completed"
10287 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10288 (clobber (reg:CC 17))])]
10289 "operands[1] = GEN_INT (~0x8000);
10290 operands[0] = gen_rtx_REG (SImode,
10291 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10292
10293 (define_insn "*abstf2_if"
10294 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10295 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10296 (clobber (reg:CC 17))]
10297 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10298 "#")
10299
10300 (define_split
10301 [(set (match_operand:TF 0 "fp_register_operand" "")
10302 (abs:TF (match_operand:TF 1 "register_operand" "")))
10303 (clobber (reg:CC 17))]
10304 "TARGET_80387 && reload_completed"
10305 [(set (match_dup 0)
10306 (abs:TF (match_dup 1)))]
10307 "")
10308
10309 (define_split
10310 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10311 (abs:TF (match_operand:TF 1 "register_operand" "")))
10312 (clobber (reg:CC 17))]
10313 "TARGET_80387 && reload_completed"
10314 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10315 (clobber (reg:CC 17))])]
10316 "operands[1] = GEN_INT (~0x8000);
10317 operands[0] = gen_rtx_REG (SImode,
10318 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10319
10320 (define_insn "*abssf2_1"
10321 [(set (match_operand:SF 0 "register_operand" "=f")
10322 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10323 "TARGET_80387 && reload_completed"
10324 "fabs"
10325 [(set_attr "type" "fsgn")
10326 (set_attr "mode" "SF")])
10327
10328 (define_insn "*absdf2_1"
10329 [(set (match_operand:DF 0 "register_operand" "=f")
10330 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10331 "TARGET_80387 && reload_completed"
10332 "fabs"
10333 [(set_attr "type" "fsgn")
10334 (set_attr "mode" "DF")])
10335
10336 (define_insn "*absextendsfdf2"
10337 [(set (match_operand:DF 0 "register_operand" "=f")
10338 (abs:DF (float_extend:DF
10339 (match_operand:SF 1 "register_operand" "0"))))]
10340 "TARGET_80387"
10341 "fabs"
10342 [(set_attr "type" "fsgn")
10343 (set_attr "mode" "DF")])
10344
10345 (define_insn "*absxf2_1"
10346 [(set (match_operand:XF 0 "register_operand" "=f")
10347 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10348 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10349 "fabs"
10350 [(set_attr "type" "fsgn")
10351 (set_attr "mode" "DF")])
10352
10353 (define_insn "*absextenddfxf2"
10354 [(set (match_operand:XF 0 "register_operand" "=f")
10355 (abs:XF (float_extend:XF
10356 (match_operand:DF 1 "register_operand" "0"))))]
10357 "!TARGET_64BIT && TARGET_80387"
10358 "fabs"
10359 [(set_attr "type" "fsgn")
10360 (set_attr "mode" "XF")])
10361
10362 (define_insn "*absextendsfxf2"
10363 [(set (match_operand:XF 0 "register_operand" "=f")
10364 (abs:XF (float_extend:XF
10365 (match_operand:SF 1 "register_operand" "0"))))]
10366 "!TARGET_64BIT && TARGET_80387"
10367 "fabs"
10368 [(set_attr "type" "fsgn")
10369 (set_attr "mode" "XF")])
10370
10371 (define_insn "*abstf2_1"
10372 [(set (match_operand:TF 0 "register_operand" "=f")
10373 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10374 "TARGET_80387 && reload_completed"
10375 "fabs"
10376 [(set_attr "type" "fsgn")
10377 (set_attr "mode" "DF")])
10378
10379 (define_insn "*absextenddftf2"
10380 [(set (match_operand:TF 0 "register_operand" "=f")
10381 (abs:TF (float_extend:TF
10382 (match_operand:DF 1 "register_operand" "0"))))]
10383 "TARGET_80387"
10384 "fabs"
10385 [(set_attr "type" "fsgn")
10386 (set_attr "mode" "XF")])
10387
10388 (define_insn "*absextendsftf2"
10389 [(set (match_operand:TF 0 "register_operand" "=f")
10390 (abs:TF (float_extend:TF
10391 (match_operand:SF 1 "register_operand" "0"))))]
10392 "TARGET_80387"
10393 "fabs"
10394 [(set_attr "type" "fsgn")
10395 (set_attr "mode" "XF")])
10396 \f
10397 ;; One complement instructions
10398
10399 (define_expand "one_cmpldi2"
10400 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10401 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10402 "TARGET_64BIT"
10403 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10404
10405 (define_insn "*one_cmpldi2_1_rex64"
10406 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10407 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10408 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10409 "not{q}\t%0"
10410 [(set_attr "type" "negnot")
10411 (set_attr "mode" "DI")])
10412
10413 (define_insn "*one_cmpldi2_2_rex64"
10414 [(set (reg 17)
10415 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10416 (const_int 0)))
10417 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10418 (not:DI (match_dup 1)))]
10419 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10420 && ix86_unary_operator_ok (NOT, DImode, operands)"
10421 "#"
10422 [(set_attr "type" "alu1")
10423 (set_attr "mode" "DI")])
10424
10425 (define_split
10426 [(set (reg 17)
10427 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10428 (const_int 0)))
10429 (set (match_operand:DI 0 "nonimmediate_operand" "")
10430 (not:DI (match_dup 1)))]
10431 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10432 [(parallel [(set (reg:CCNO 17)
10433 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10434 (const_int 0)))
10435 (set (match_dup 0)
10436 (xor:DI (match_dup 1) (const_int -1)))])]
10437 "")
10438
10439 (define_expand "one_cmplsi2"
10440 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10441 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10442 ""
10443 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10444
10445 (define_insn "*one_cmplsi2_1"
10446 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10447 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10448 "ix86_unary_operator_ok (NOT, SImode, operands)"
10449 "not{l}\t%0"
10450 [(set_attr "type" "negnot")
10451 (set_attr "mode" "SI")])
10452
10453 ;; ??? Currently never generated - xor is used instead.
10454 (define_insn "*one_cmplsi2_1_zext"
10455 [(set (match_operand:DI 0 "register_operand" "=r")
10456 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10457 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10458 "not{l}\t%k0"
10459 [(set_attr "type" "negnot")
10460 (set_attr "mode" "SI")])
10461
10462 (define_insn "*one_cmplsi2_2"
10463 [(set (reg 17)
10464 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10465 (const_int 0)))
10466 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10467 (not:SI (match_dup 1)))]
10468 "ix86_match_ccmode (insn, CCNOmode)
10469 && ix86_unary_operator_ok (NOT, SImode, operands)"
10470 "#"
10471 [(set_attr "type" "alu1")
10472 (set_attr "mode" "SI")])
10473
10474 (define_split
10475 [(set (reg 17)
10476 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10477 (const_int 0)))
10478 (set (match_operand:SI 0 "nonimmediate_operand" "")
10479 (not:SI (match_dup 1)))]
10480 "ix86_match_ccmode (insn, CCNOmode)"
10481 [(parallel [(set (reg:CCNO 17)
10482 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10483 (const_int 0)))
10484 (set (match_dup 0)
10485 (xor:SI (match_dup 1) (const_int -1)))])]
10486 "")
10487
10488 ;; ??? Currently never generated - xor is used instead.
10489 (define_insn "*one_cmplsi2_2_zext"
10490 [(set (reg 17)
10491 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10492 (const_int 0)))
10493 (set (match_operand:DI 0 "register_operand" "=r")
10494 (zero_extend:DI (not:SI (match_dup 1))))]
10495 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10496 && ix86_unary_operator_ok (NOT, SImode, operands)"
10497 "#"
10498 [(set_attr "type" "alu1")
10499 (set_attr "mode" "SI")])
10500
10501 (define_split
10502 [(set (reg 17)
10503 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10504 (const_int 0)))
10505 (set (match_operand:DI 0 "register_operand" "")
10506 (zero_extend:DI (not:SI (match_dup 1))))]
10507 "ix86_match_ccmode (insn, CCNOmode)"
10508 [(parallel [(set (reg:CCNO 17)
10509 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10510 (const_int 0)))
10511 (set (match_dup 0)
10512 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10513 "")
10514
10515 (define_expand "one_cmplhi2"
10516 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10517 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10518 "TARGET_HIMODE_MATH"
10519 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10520
10521 (define_insn "*one_cmplhi2_1"
10522 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10523 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10524 "ix86_unary_operator_ok (NOT, HImode, operands)"
10525 "not{w}\t%0"
10526 [(set_attr "type" "negnot")
10527 (set_attr "mode" "HI")])
10528
10529 (define_insn "*one_cmplhi2_2"
10530 [(set (reg 17)
10531 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10532 (const_int 0)))
10533 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10534 (not:HI (match_dup 1)))]
10535 "ix86_match_ccmode (insn, CCNOmode)
10536 && ix86_unary_operator_ok (NEG, HImode, operands)"
10537 "#"
10538 [(set_attr "type" "alu1")
10539 (set_attr "mode" "HI")])
10540
10541 (define_split
10542 [(set (reg 17)
10543 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10544 (const_int 0)))
10545 (set (match_operand:HI 0 "nonimmediate_operand" "")
10546 (not:HI (match_dup 1)))]
10547 "ix86_match_ccmode (insn, CCNOmode)"
10548 [(parallel [(set (reg:CCNO 17)
10549 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10550 (const_int 0)))
10551 (set (match_dup 0)
10552 (xor:HI (match_dup 1) (const_int -1)))])]
10553 "")
10554
10555 ;; %%% Potential partial reg stall on alternative 1. What to do?
10556 (define_expand "one_cmplqi2"
10557 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10558 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10559 "TARGET_QIMODE_MATH"
10560 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10561
10562 (define_insn "*one_cmplqi2_1"
10563 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10564 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10565 "ix86_unary_operator_ok (NOT, QImode, operands)"
10566 "@
10567 not{b}\t%0
10568 not{l}\t%k0"
10569 [(set_attr "type" "negnot")
10570 (set_attr "mode" "QI,SI")])
10571
10572 (define_insn "*one_cmplqi2_2"
10573 [(set (reg 17)
10574 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10575 (const_int 0)))
10576 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10577 (not:QI (match_dup 1)))]
10578 "ix86_match_ccmode (insn, CCNOmode)
10579 && ix86_unary_operator_ok (NOT, QImode, operands)"
10580 "#"
10581 [(set_attr "type" "alu1")
10582 (set_attr "mode" "QI")])
10583
10584 (define_split
10585 [(set (reg 17)
10586 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10587 (const_int 0)))
10588 (set (match_operand:QI 0 "nonimmediate_operand" "")
10589 (not:QI (match_dup 1)))]
10590 "ix86_match_ccmode (insn, CCNOmode)"
10591 [(parallel [(set (reg:CCNO 17)
10592 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10593 (const_int 0)))
10594 (set (match_dup 0)
10595 (xor:QI (match_dup 1) (const_int -1)))])]
10596 "")
10597 \f
10598 ;; Arithmetic shift instructions
10599
10600 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10601 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10602 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10603 ;; from the assembler input.
10604 ;;
10605 ;; This instruction shifts the target reg/mem as usual, but instead of
10606 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10607 ;; is a left shift double, bits are taken from the high order bits of
10608 ;; reg, else if the insn is a shift right double, bits are taken from the
10609 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10610 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10611 ;;
10612 ;; Since sh[lr]d does not change the `reg' operand, that is done
10613 ;; separately, making all shifts emit pairs of shift double and normal
10614 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10615 ;; support a 63 bit shift, each shift where the count is in a reg expands
10616 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10617 ;;
10618 ;; If the shift count is a constant, we need never emit more than one
10619 ;; shift pair, instead using moves and sign extension for counts greater
10620 ;; than 31.
10621
10622 (define_expand "ashldi3"
10623 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10624 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10625 (match_operand:QI 2 "nonmemory_operand" "")))
10626 (clobber (reg:CC 17))])]
10627 ""
10628 {
10629 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10630 {
10631 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10632 DONE;
10633 }
10634 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10635 DONE;
10636 })
10637
10638 (define_insn "*ashldi3_1_rex64"
10639 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10640 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10641 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10642 (clobber (reg:CC 17))]
10643 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10644 {
10645 switch (get_attr_type (insn))
10646 {
10647 case TYPE_ALU:
10648 if (operands[2] != const1_rtx)
10649 abort ();
10650 if (!rtx_equal_p (operands[0], operands[1]))
10651 abort ();
10652 return "add{q}\t{%0, %0|%0, %0}";
10653
10654 case TYPE_LEA:
10655 if (GET_CODE (operands[2]) != CONST_INT
10656 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10657 abort ();
10658 operands[1] = gen_rtx_MULT (DImode, operands[1],
10659 GEN_INT (1 << INTVAL (operands[2])));
10660 return "lea{q}\t{%a1, %0|%0, %a1}";
10661
10662 default:
10663 if (REG_P (operands[2]))
10664 return "sal{q}\t{%b2, %0|%0, %b2}";
10665 else if (GET_CODE (operands[2]) == CONST_INT
10666 && INTVAL (operands[2]) == 1
10667 && (TARGET_SHIFT1 || optimize_size))
10668 return "sal{q}\t%0";
10669 else
10670 return "sal{q}\t{%2, %0|%0, %2}";
10671 }
10672 }
10673 [(set (attr "type")
10674 (cond [(eq_attr "alternative" "1")
10675 (const_string "lea")
10676 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10677 (const_int 0))
10678 (match_operand 0 "register_operand" ""))
10679 (match_operand 2 "const1_operand" ""))
10680 (const_string "alu")
10681 ]
10682 (const_string "ishift")))
10683 (set_attr "mode" "DI")])
10684
10685 ;; Convert lea to the lea pattern to avoid flags dependency.
10686 (define_split
10687 [(set (match_operand:DI 0 "register_operand" "")
10688 (ashift:DI (match_operand:DI 1 "register_operand" "")
10689 (match_operand:QI 2 "immediate_operand" "")))
10690 (clobber (reg:CC 17))]
10691 "TARGET_64BIT && reload_completed
10692 && true_regnum (operands[0]) != true_regnum (operands[1])"
10693 [(set (match_dup 0)
10694 (mult:DI (match_dup 1)
10695 (match_dup 2)))]
10696 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10697
10698 ;; This pattern can't accept a variable shift count, since shifts by
10699 ;; zero don't affect the flags. We assume that shifts by constant
10700 ;; zero are optimized away.
10701 (define_insn "*ashldi3_cmp_rex64"
10702 [(set (reg 17)
10703 (compare
10704 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10705 (match_operand:QI 2 "immediate_operand" "e"))
10706 (const_int 0)))
10707 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10708 (ashift:DI (match_dup 1) (match_dup 2)))]
10709 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10710 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10711 {
10712 switch (get_attr_type (insn))
10713 {
10714 case TYPE_ALU:
10715 if (operands[2] != const1_rtx)
10716 abort ();
10717 return "add{q}\t{%0, %0|%0, %0}";
10718
10719 default:
10720 if (REG_P (operands[2]))
10721 return "sal{q}\t{%b2, %0|%0, %b2}";
10722 else if (GET_CODE (operands[2]) == CONST_INT
10723 && INTVAL (operands[2]) == 1
10724 && (TARGET_SHIFT1 || optimize_size))
10725 return "sal{q}\t%0";
10726 else
10727 return "sal{q}\t{%2, %0|%0, %2}";
10728 }
10729 }
10730 [(set (attr "type")
10731 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10732 (const_int 0))
10733 (match_operand 0 "register_operand" ""))
10734 (match_operand 2 "const1_operand" ""))
10735 (const_string "alu")
10736 ]
10737 (const_string "ishift")))
10738 (set_attr "mode" "DI")])
10739
10740 (define_insn "ashldi3_1"
10741 [(set (match_operand:DI 0 "register_operand" "=r")
10742 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10743 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10744 (clobber (match_scratch:SI 3 "=&r"))
10745 (clobber (reg:CC 17))]
10746 "!TARGET_64BIT && TARGET_CMOVE"
10747 "#"
10748 [(set_attr "type" "multi")])
10749
10750 (define_insn "*ashldi3_2"
10751 [(set (match_operand:DI 0 "register_operand" "=r")
10752 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10753 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10754 (clobber (reg:CC 17))]
10755 "!TARGET_64BIT"
10756 "#"
10757 [(set_attr "type" "multi")])
10758
10759 (define_split
10760 [(set (match_operand:DI 0 "register_operand" "")
10761 (ashift:DI (match_operand:DI 1 "register_operand" "")
10762 (match_operand:QI 2 "nonmemory_operand" "")))
10763 (clobber (match_scratch:SI 3 ""))
10764 (clobber (reg:CC 17))]
10765 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10766 [(const_int 0)]
10767 "ix86_split_ashldi (operands, operands[3]); DONE;")
10768
10769 (define_split
10770 [(set (match_operand:DI 0 "register_operand" "")
10771 (ashift:DI (match_operand:DI 1 "register_operand" "")
10772 (match_operand:QI 2 "nonmemory_operand" "")))
10773 (clobber (reg:CC 17))]
10774 "!TARGET_64BIT && reload_completed"
10775 [(const_int 0)]
10776 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10777
10778 (define_insn "x86_shld_1"
10779 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10780 (ior:SI (ashift:SI (match_dup 0)
10781 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10782 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10783 (minus:QI (const_int 32) (match_dup 2)))))
10784 (clobber (reg:CC 17))]
10785 ""
10786 "@
10787 shld{l}\t{%2, %1, %0|%0, %1, %2}
10788 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10789 [(set_attr "type" "ishift")
10790 (set_attr "prefix_0f" "1")
10791 (set_attr "mode" "SI")
10792 (set_attr "pent_pair" "np")
10793 (set_attr "athlon_decode" "vector")
10794 (set_attr "ppro_uops" "few")])
10795
10796 (define_expand "x86_shift_adj_1"
10797 [(set (reg:CCZ 17)
10798 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10799 (const_int 32))
10800 (const_int 0)))
10801 (set (match_operand:SI 0 "register_operand" "")
10802 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10803 (match_operand:SI 1 "register_operand" "")
10804 (match_dup 0)))
10805 (set (match_dup 1)
10806 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10807 (match_operand:SI 3 "register_operand" "r")
10808 (match_dup 1)))]
10809 "TARGET_CMOVE"
10810 "")
10811
10812 (define_expand "x86_shift_adj_2"
10813 [(use (match_operand:SI 0 "register_operand" ""))
10814 (use (match_operand:SI 1 "register_operand" ""))
10815 (use (match_operand:QI 2 "register_operand" ""))]
10816 ""
10817 {
10818 rtx label = gen_label_rtx ();
10819 rtx tmp;
10820
10821 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10822
10823 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10824 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10825 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10826 gen_rtx_LABEL_REF (VOIDmode, label),
10827 pc_rtx);
10828 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10829 JUMP_LABEL (tmp) = label;
10830
10831 emit_move_insn (operands[0], operands[1]);
10832 emit_move_insn (operands[1], const0_rtx);
10833
10834 emit_label (label);
10835 LABEL_NUSES (label) = 1;
10836
10837 DONE;
10838 })
10839
10840 (define_expand "ashlsi3"
10841 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10842 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10843 (match_operand:QI 2 "nonmemory_operand" "")))
10844 (clobber (reg:CC 17))]
10845 ""
10846 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10847
10848 (define_insn "*ashlsi3_1"
10849 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10850 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10851 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10852 (clobber (reg:CC 17))]
10853 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10854 {
10855 switch (get_attr_type (insn))
10856 {
10857 case TYPE_ALU:
10858 if (operands[2] != const1_rtx)
10859 abort ();
10860 if (!rtx_equal_p (operands[0], operands[1]))
10861 abort ();
10862 return "add{l}\t{%0, %0|%0, %0}";
10863
10864 case TYPE_LEA:
10865 return "#";
10866
10867 default:
10868 if (REG_P (operands[2]))
10869 return "sal{l}\t{%b2, %0|%0, %b2}";
10870 else if (GET_CODE (operands[2]) == CONST_INT
10871 && INTVAL (operands[2]) == 1
10872 && (TARGET_SHIFT1 || optimize_size))
10873 return "sal{l}\t%0";
10874 else
10875 return "sal{l}\t{%2, %0|%0, %2}";
10876 }
10877 }
10878 [(set (attr "type")
10879 (cond [(eq_attr "alternative" "1")
10880 (const_string "lea")
10881 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10882 (const_int 0))
10883 (match_operand 0 "register_operand" ""))
10884 (match_operand 2 "const1_operand" ""))
10885 (const_string "alu")
10886 ]
10887 (const_string "ishift")))
10888 (set_attr "mode" "SI")])
10889
10890 ;; Convert lea to the lea pattern to avoid flags dependency.
10891 (define_split
10892 [(set (match_operand 0 "register_operand" "")
10893 (ashift (match_operand 1 "index_register_operand" "")
10894 (match_operand:QI 2 "const_int_operand" "")))
10895 (clobber (reg:CC 17))]
10896 "reload_completed
10897 && true_regnum (operands[0]) != true_regnum (operands[1])"
10898 [(const_int 0)]
10899 {
10900 rtx pat;
10901 operands[0] = gen_lowpart (SImode, operands[0]);
10902 operands[1] = gen_lowpart (Pmode, operands[1]);
10903 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10904 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10905 if (Pmode != SImode)
10906 pat = gen_rtx_SUBREG (SImode, pat, 0);
10907 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10908 DONE;
10909 })
10910
10911 ;; Rare case of shifting RSP is handled by generating move and shift
10912 (define_split
10913 [(set (match_operand 0 "register_operand" "")
10914 (ashift (match_operand 1 "register_operand" "")
10915 (match_operand:QI 2 "const_int_operand" "")))
10916 (clobber (reg:CC 17))]
10917 "reload_completed
10918 && true_regnum (operands[0]) != true_regnum (operands[1])"
10919 [(const_int 0)]
10920 {
10921 rtx pat, clob;
10922 emit_move_insn (operands[1], operands[0]);
10923 pat = gen_rtx_SET (VOIDmode, operands[0],
10924 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10925 operands[0], operands[2]));
10926 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10927 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10928 DONE;
10929 })
10930
10931 (define_insn "*ashlsi3_1_zext"
10932 [(set (match_operand:DI 0 "register_operand" "=r,r")
10933 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10934 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10935 (clobber (reg:CC 17))]
10936 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10937 {
10938 switch (get_attr_type (insn))
10939 {
10940 case TYPE_ALU:
10941 if (operands[2] != const1_rtx)
10942 abort ();
10943 return "add{l}\t{%k0, %k0|%k0, %k0}";
10944
10945 case TYPE_LEA:
10946 return "#";
10947
10948 default:
10949 if (REG_P (operands[2]))
10950 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10951 else if (GET_CODE (operands[2]) == CONST_INT
10952 && INTVAL (operands[2]) == 1
10953 && (TARGET_SHIFT1 || optimize_size))
10954 return "sal{l}\t%k0";
10955 else
10956 return "sal{l}\t{%2, %k0|%k0, %2}";
10957 }
10958 }
10959 [(set (attr "type")
10960 (cond [(eq_attr "alternative" "1")
10961 (const_string "lea")
10962 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10963 (const_int 0))
10964 (match_operand 2 "const1_operand" ""))
10965 (const_string "alu")
10966 ]
10967 (const_string "ishift")))
10968 (set_attr "mode" "SI")])
10969
10970 ;; Convert lea to the lea pattern to avoid flags dependency.
10971 (define_split
10972 [(set (match_operand:DI 0 "register_operand" "")
10973 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10974 (match_operand:QI 2 "const_int_operand" ""))))
10975 (clobber (reg:CC 17))]
10976 "reload_completed
10977 && true_regnum (operands[0]) != true_regnum (operands[1])"
10978 [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10979 {
10980 operands[1] = gen_lowpart (Pmode, operands[1]);
10981 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10982 })
10983
10984 ;; This pattern can't accept a variable shift count, since shifts by
10985 ;; zero don't affect the flags. We assume that shifts by constant
10986 ;; zero are optimized away.
10987 (define_insn "*ashlsi3_cmp"
10988 [(set (reg 17)
10989 (compare
10990 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10991 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10992 (const_int 0)))
10993 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10994 (ashift:SI (match_dup 1) (match_dup 2)))]
10995 "ix86_match_ccmode (insn, CCGOCmode)
10996 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10997 {
10998 switch (get_attr_type (insn))
10999 {
11000 case TYPE_ALU:
11001 if (operands[2] != const1_rtx)
11002 abort ();
11003 return "add{l}\t{%0, %0|%0, %0}";
11004
11005 default:
11006 if (REG_P (operands[2]))
11007 return "sal{l}\t{%b2, %0|%0, %b2}";
11008 else if (GET_CODE (operands[2]) == CONST_INT
11009 && INTVAL (operands[2]) == 1
11010 && (TARGET_SHIFT1 || optimize_size))
11011 return "sal{l}\t%0";
11012 else
11013 return "sal{l}\t{%2, %0|%0, %2}";
11014 }
11015 }
11016 [(set (attr "type")
11017 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11018 (const_int 0))
11019 (match_operand 0 "register_operand" ""))
11020 (match_operand 2 "const1_operand" ""))
11021 (const_string "alu")
11022 ]
11023 (const_string "ishift")))
11024 (set_attr "mode" "SI")])
11025
11026 (define_insn "*ashlsi3_cmp_zext"
11027 [(set (reg 17)
11028 (compare
11029 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11030 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11031 (const_int 0)))
11032 (set (match_operand:DI 0 "register_operand" "=r")
11033 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11034 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11035 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11036 {
11037 switch (get_attr_type (insn))
11038 {
11039 case TYPE_ALU:
11040 if (operands[2] != const1_rtx)
11041 abort ();
11042 return "add{l}\t{%k0, %k0|%k0, %k0}";
11043
11044 default:
11045 if (REG_P (operands[2]))
11046 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11047 else if (GET_CODE (operands[2]) == CONST_INT
11048 && INTVAL (operands[2]) == 1
11049 && (TARGET_SHIFT1 || optimize_size))
11050 return "sal{l}\t%k0";
11051 else
11052 return "sal{l}\t{%2, %k0|%k0, %2}";
11053 }
11054 }
11055 [(set (attr "type")
11056 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11057 (const_int 0))
11058 (match_operand 2 "const1_operand" ""))
11059 (const_string "alu")
11060 ]
11061 (const_string "ishift")))
11062 (set_attr "mode" "SI")])
11063
11064 (define_expand "ashlhi3"
11065 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11066 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11067 (match_operand:QI 2 "nonmemory_operand" "")))
11068 (clobber (reg:CC 17))]
11069 "TARGET_HIMODE_MATH"
11070 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11071
11072 (define_insn "*ashlhi3_1_lea"
11073 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11074 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11075 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11076 (clobber (reg:CC 17))]
11077 "!TARGET_PARTIAL_REG_STALL
11078 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11079 {
11080 switch (get_attr_type (insn))
11081 {
11082 case TYPE_LEA:
11083 return "#";
11084 case TYPE_ALU:
11085 if (operands[2] != const1_rtx)
11086 abort ();
11087 return "add{w}\t{%0, %0|%0, %0}";
11088
11089 default:
11090 if (REG_P (operands[2]))
11091 return "sal{w}\t{%b2, %0|%0, %b2}";
11092 else if (GET_CODE (operands[2]) == CONST_INT
11093 && INTVAL (operands[2]) == 1
11094 && (TARGET_SHIFT1 || optimize_size))
11095 return "sal{w}\t%0";
11096 else
11097 return "sal{w}\t{%2, %0|%0, %2}";
11098 }
11099 }
11100 [(set (attr "type")
11101 (cond [(eq_attr "alternative" "1")
11102 (const_string "lea")
11103 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11104 (const_int 0))
11105 (match_operand 0 "register_operand" ""))
11106 (match_operand 2 "const1_operand" ""))
11107 (const_string "alu")
11108 ]
11109 (const_string "ishift")))
11110 (set_attr "mode" "HI,SI")])
11111
11112 (define_insn "*ashlhi3_1"
11113 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11114 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11115 (match_operand:QI 2 "nonmemory_operand" "cI")))
11116 (clobber (reg:CC 17))]
11117 "TARGET_PARTIAL_REG_STALL
11118 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11119 {
11120 switch (get_attr_type (insn))
11121 {
11122 case TYPE_ALU:
11123 if (operands[2] != const1_rtx)
11124 abort ();
11125 return "add{w}\t{%0, %0|%0, %0}";
11126
11127 default:
11128 if (REG_P (operands[2]))
11129 return "sal{w}\t{%b2, %0|%0, %b2}";
11130 else if (GET_CODE (operands[2]) == CONST_INT
11131 && INTVAL (operands[2]) == 1
11132 && (TARGET_SHIFT1 || optimize_size))
11133 return "sal{w}\t%0";
11134 else
11135 return "sal{w}\t{%2, %0|%0, %2}";
11136 }
11137 }
11138 [(set (attr "type")
11139 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11140 (const_int 0))
11141 (match_operand 0 "register_operand" ""))
11142 (match_operand 2 "const1_operand" ""))
11143 (const_string "alu")
11144 ]
11145 (const_string "ishift")))
11146 (set_attr "mode" "HI")])
11147
11148 ;; This pattern can't accept a variable shift count, since shifts by
11149 ;; zero don't affect the flags. We assume that shifts by constant
11150 ;; zero are optimized away.
11151 (define_insn "*ashlhi3_cmp"
11152 [(set (reg 17)
11153 (compare
11154 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11155 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11156 (const_int 0)))
11157 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11158 (ashift:HI (match_dup 1) (match_dup 2)))]
11159 "ix86_match_ccmode (insn, CCGOCmode)
11160 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11161 {
11162 switch (get_attr_type (insn))
11163 {
11164 case TYPE_ALU:
11165 if (operands[2] != const1_rtx)
11166 abort ();
11167 return "add{w}\t{%0, %0|%0, %0}";
11168
11169 default:
11170 if (REG_P (operands[2]))
11171 return "sal{w}\t{%b2, %0|%0, %b2}";
11172 else if (GET_CODE (operands[2]) == CONST_INT
11173 && INTVAL (operands[2]) == 1
11174 && (TARGET_SHIFT1 || optimize_size))
11175 return "sal{w}\t%0";
11176 else
11177 return "sal{w}\t{%2, %0|%0, %2}";
11178 }
11179 }
11180 [(set (attr "type")
11181 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11182 (const_int 0))
11183 (match_operand 0 "register_operand" ""))
11184 (match_operand 2 "const1_operand" ""))
11185 (const_string "alu")
11186 ]
11187 (const_string "ishift")))
11188 (set_attr "mode" "HI")])
11189
11190 (define_expand "ashlqi3"
11191 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11192 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11193 (match_operand:QI 2 "nonmemory_operand" "")))
11194 (clobber (reg:CC 17))]
11195 "TARGET_QIMODE_MATH"
11196 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11197
11198 ;; %%% Potential partial reg stall on alternative 2. What to do?
11199
11200 (define_insn "*ashlqi3_1_lea"
11201 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11202 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11203 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11204 (clobber (reg:CC 17))]
11205 "!TARGET_PARTIAL_REG_STALL
11206 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11207 {
11208 switch (get_attr_type (insn))
11209 {
11210 case TYPE_LEA:
11211 return "#";
11212 case TYPE_ALU:
11213 if (operands[2] != const1_rtx)
11214 abort ();
11215 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11216 return "add{l}\t{%k0, %k0|%k0, %k0}";
11217 else
11218 return "add{b}\t{%0, %0|%0, %0}";
11219
11220 default:
11221 if (REG_P (operands[2]))
11222 {
11223 if (get_attr_mode (insn) == MODE_SI)
11224 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11225 else
11226 return "sal{b}\t{%b2, %0|%0, %b2}";
11227 }
11228 else if (GET_CODE (operands[2]) == CONST_INT
11229 && INTVAL (operands[2]) == 1
11230 && (TARGET_SHIFT1 || optimize_size))
11231 {
11232 if (get_attr_mode (insn) == MODE_SI)
11233 return "sal{l}\t%0";
11234 else
11235 return "sal{b}\t%0";
11236 }
11237 else
11238 {
11239 if (get_attr_mode (insn) == MODE_SI)
11240 return "sal{l}\t{%2, %k0|%k0, %2}";
11241 else
11242 return "sal{b}\t{%2, %0|%0, %2}";
11243 }
11244 }
11245 }
11246 [(set (attr "type")
11247 (cond [(eq_attr "alternative" "2")
11248 (const_string "lea")
11249 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11250 (const_int 0))
11251 (match_operand 0 "register_operand" ""))
11252 (match_operand 2 "const1_operand" ""))
11253 (const_string "alu")
11254 ]
11255 (const_string "ishift")))
11256 (set_attr "mode" "QI,SI,SI")])
11257
11258 (define_insn "*ashlqi3_1"
11259 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11260 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11261 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11262 (clobber (reg:CC 17))]
11263 "TARGET_PARTIAL_REG_STALL
11264 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11265 {
11266 switch (get_attr_type (insn))
11267 {
11268 case TYPE_ALU:
11269 if (operands[2] != const1_rtx)
11270 abort ();
11271 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11272 return "add{l}\t{%k0, %k0|%k0, %k0}";
11273 else
11274 return "add{b}\t{%0, %0|%0, %0}";
11275
11276 default:
11277 if (REG_P (operands[2]))
11278 {
11279 if (get_attr_mode (insn) == MODE_SI)
11280 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11281 else
11282 return "sal{b}\t{%b2, %0|%0, %b2}";
11283 }
11284 else if (GET_CODE (operands[2]) == CONST_INT
11285 && INTVAL (operands[2]) == 1
11286 && (TARGET_SHIFT1 || optimize_size))
11287 {
11288 if (get_attr_mode (insn) == MODE_SI)
11289 return "sal{l}\t%0";
11290 else
11291 return "sal{b}\t%0";
11292 }
11293 else
11294 {
11295 if (get_attr_mode (insn) == MODE_SI)
11296 return "sal{l}\t{%2, %k0|%k0, %2}";
11297 else
11298 return "sal{b}\t{%2, %0|%0, %2}";
11299 }
11300 }
11301 }
11302 [(set (attr "type")
11303 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11304 (const_int 0))
11305 (match_operand 0 "register_operand" ""))
11306 (match_operand 2 "const1_operand" ""))
11307 (const_string "alu")
11308 ]
11309 (const_string "ishift")))
11310 (set_attr "mode" "QI,SI")])
11311
11312 ;; This pattern can't accept a variable shift count, since shifts by
11313 ;; zero don't affect the flags. We assume that shifts by constant
11314 ;; zero are optimized away.
11315 (define_insn "*ashlqi3_cmp"
11316 [(set (reg 17)
11317 (compare
11318 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11319 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11320 (const_int 0)))
11321 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11322 (ashift:QI (match_dup 1) (match_dup 2)))]
11323 "ix86_match_ccmode (insn, CCGOCmode)
11324 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11325 {
11326 switch (get_attr_type (insn))
11327 {
11328 case TYPE_ALU:
11329 if (operands[2] != const1_rtx)
11330 abort ();
11331 return "add{b}\t{%0, %0|%0, %0}";
11332
11333 default:
11334 if (REG_P (operands[2]))
11335 return "sal{b}\t{%b2, %0|%0, %b2}";
11336 else if (GET_CODE (operands[2]) == CONST_INT
11337 && INTVAL (operands[2]) == 1
11338 && (TARGET_SHIFT1 || optimize_size))
11339 return "sal{b}\t%0";
11340 else
11341 return "sal{b}\t{%2, %0|%0, %2}";
11342 }
11343 }
11344 [(set (attr "type")
11345 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11346 (const_int 0))
11347 (match_operand 0 "register_operand" ""))
11348 (match_operand 2 "const1_operand" ""))
11349 (const_string "alu")
11350 ]
11351 (const_string "ishift")))
11352 (set_attr "mode" "QI")])
11353
11354 ;; See comment above `ashldi3' about how this works.
11355
11356 (define_expand "ashrdi3"
11357 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11358 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11359 (match_operand:QI 2 "nonmemory_operand" "")))
11360 (clobber (reg:CC 17))])]
11361 ""
11362 {
11363 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11364 {
11365 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11366 DONE;
11367 }
11368 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11369 DONE;
11370 })
11371
11372 (define_insn "ashrdi3_63_rex64"
11373 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11374 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11375 (match_operand:DI 2 "const_int_operand" "i,i")))
11376 (clobber (reg:CC 17))]
11377 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11378 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11379 "@
11380 {cqto|cqo}
11381 sar{q}\t{%2, %0|%0, %2}"
11382 [(set_attr "type" "imovx,ishift")
11383 (set_attr "prefix_0f" "0,*")
11384 (set_attr "length_immediate" "0,*")
11385 (set_attr "modrm" "0,1")
11386 (set_attr "mode" "DI")])
11387
11388 (define_insn "*ashrdi3_1_one_bit_rex64"
11389 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11391 (match_operand:QI 2 "const_int_1_operand" "")))
11392 (clobber (reg:CC 17))]
11393 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11394 && (TARGET_SHIFT1 || optimize_size)"
11395 "sar{q}\t%0"
11396 [(set_attr "type" "ishift")
11397 (set (attr "length")
11398 (if_then_else (match_operand:DI 0 "register_operand" "")
11399 (const_string "2")
11400 (const_string "*")))])
11401
11402 (define_insn "*ashrdi3_1_rex64"
11403 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11404 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11405 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11406 (clobber (reg:CC 17))]
11407 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11408 "@
11409 sar{q}\t{%2, %0|%0, %2}
11410 sar{q}\t{%b2, %0|%0, %b2}"
11411 [(set_attr "type" "ishift")
11412 (set_attr "mode" "DI")])
11413
11414 ;; This pattern can't accept a variable shift count, since shifts by
11415 ;; zero don't affect the flags. We assume that shifts by constant
11416 ;; zero are optimized away.
11417 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11418 [(set (reg 17)
11419 (compare
11420 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11421 (match_operand:QI 2 "const_int_1_operand" ""))
11422 (const_int 0)))
11423 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11424 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11425 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11426 && (TARGET_SHIFT1 || optimize_size)
11427 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11428 "sar{q}\t%0"
11429 [(set_attr "type" "ishift")
11430 (set (attr "length")
11431 (if_then_else (match_operand:DI 0 "register_operand" "")
11432 (const_string "2")
11433 (const_string "*")))])
11434
11435 ;; This pattern can't accept a variable shift count, since shifts by
11436 ;; zero don't affect the flags. We assume that shifts by constant
11437 ;; zero are optimized away.
11438 (define_insn "*ashrdi3_cmp_rex64"
11439 [(set (reg 17)
11440 (compare
11441 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11442 (match_operand:QI 2 "const_int_operand" "n"))
11443 (const_int 0)))
11444 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11445 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11446 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11447 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11448 "sar{q}\t{%2, %0|%0, %2}"
11449 [(set_attr "type" "ishift")
11450 (set_attr "mode" "DI")])
11451
11452
11453 (define_insn "ashrdi3_1"
11454 [(set (match_operand:DI 0 "register_operand" "=r")
11455 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11456 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11457 (clobber (match_scratch:SI 3 "=&r"))
11458 (clobber (reg:CC 17))]
11459 "!TARGET_64BIT && TARGET_CMOVE"
11460 "#"
11461 [(set_attr "type" "multi")])
11462
11463 (define_insn "*ashrdi3_2"
11464 [(set (match_operand:DI 0 "register_operand" "=r")
11465 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11466 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11467 (clobber (reg:CC 17))]
11468 "!TARGET_64BIT"
11469 "#"
11470 [(set_attr "type" "multi")])
11471
11472 (define_split
11473 [(set (match_operand:DI 0 "register_operand" "")
11474 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11475 (match_operand:QI 2 "nonmemory_operand" "")))
11476 (clobber (match_scratch:SI 3 ""))
11477 (clobber (reg:CC 17))]
11478 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11479 [(const_int 0)]
11480 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11481
11482 (define_split
11483 [(set (match_operand:DI 0 "register_operand" "")
11484 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11485 (match_operand:QI 2 "nonmemory_operand" "")))
11486 (clobber (reg:CC 17))]
11487 "!TARGET_64BIT && reload_completed"
11488 [(const_int 0)]
11489 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11490
11491 (define_insn "x86_shrd_1"
11492 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11493 (ior:SI (ashiftrt:SI (match_dup 0)
11494 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11495 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11496 (minus:QI (const_int 32) (match_dup 2)))))
11497 (clobber (reg:CC 17))]
11498 ""
11499 "@
11500 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11501 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11502 [(set_attr "type" "ishift")
11503 (set_attr "prefix_0f" "1")
11504 (set_attr "pent_pair" "np")
11505 (set_attr "ppro_uops" "few")
11506 (set_attr "mode" "SI")])
11507
11508 (define_expand "x86_shift_adj_3"
11509 [(use (match_operand:SI 0 "register_operand" ""))
11510 (use (match_operand:SI 1 "register_operand" ""))
11511 (use (match_operand:QI 2 "register_operand" ""))]
11512 ""
11513 {
11514 rtx label = gen_label_rtx ();
11515 rtx tmp;
11516
11517 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11518
11519 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11520 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11521 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11522 gen_rtx_LABEL_REF (VOIDmode, label),
11523 pc_rtx);
11524 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11525 JUMP_LABEL (tmp) = label;
11526
11527 emit_move_insn (operands[0], operands[1]);
11528 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11529
11530 emit_label (label);
11531 LABEL_NUSES (label) = 1;
11532
11533 DONE;
11534 })
11535
11536 (define_insn "ashrsi3_31"
11537 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11538 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11539 (match_operand:SI 2 "const_int_operand" "i,i")))
11540 (clobber (reg:CC 17))]
11541 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11542 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11543 "@
11544 {cltd|cdq}
11545 sar{l}\t{%2, %0|%0, %2}"
11546 [(set_attr "type" "imovx,ishift")
11547 (set_attr "prefix_0f" "0,*")
11548 (set_attr "length_immediate" "0,*")
11549 (set_attr "modrm" "0,1")
11550 (set_attr "mode" "SI")])
11551
11552 (define_insn "*ashrsi3_31_zext"
11553 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11554 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11555 (match_operand:SI 2 "const_int_operand" "i,i"))))
11556 (clobber (reg:CC 17))]
11557 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11558 && INTVAL (operands[2]) == 31
11559 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11560 "@
11561 {cltd|cdq}
11562 sar{l}\t{%2, %k0|%k0, %2}"
11563 [(set_attr "type" "imovx,ishift")
11564 (set_attr "prefix_0f" "0,*")
11565 (set_attr "length_immediate" "0,*")
11566 (set_attr "modrm" "0,1")
11567 (set_attr "mode" "SI")])
11568
11569 (define_expand "ashrsi3"
11570 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11571 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11572 (match_operand:QI 2 "nonmemory_operand" "")))
11573 (clobber (reg:CC 17))]
11574 ""
11575 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11576
11577 (define_insn "*ashrsi3_1_one_bit"
11578 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11579 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11580 (match_operand:QI 2 "const_int_1_operand" "")))
11581 (clobber (reg:CC 17))]
11582 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11583 && (TARGET_SHIFT1 || optimize_size)"
11584 "sar{l}\t%0"
11585 [(set_attr "type" "ishift")
11586 (set (attr "length")
11587 (if_then_else (match_operand:SI 0 "register_operand" "")
11588 (const_string "2")
11589 (const_string "*")))])
11590
11591 (define_insn "*ashrsi3_1_one_bit_zext"
11592 [(set (match_operand:DI 0 "register_operand" "=r")
11593 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11594 (match_operand:QI 2 "const_int_1_operand" ""))))
11595 (clobber (reg:CC 17))]
11596 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11597 && (TARGET_SHIFT1 || optimize_size)"
11598 "sar{l}\t%k0"
11599 [(set_attr "type" "ishift")
11600 (set_attr "length" "2")])
11601
11602 (define_insn "*ashrsi3_1"
11603 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11604 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11605 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11606 (clobber (reg:CC 17))]
11607 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11608 "@
11609 sar{l}\t{%2, %0|%0, %2}
11610 sar{l}\t{%b2, %0|%0, %b2}"
11611 [(set_attr "type" "ishift")
11612 (set_attr "mode" "SI")])
11613
11614 (define_insn "*ashrsi3_1_zext"
11615 [(set (match_operand:DI 0 "register_operand" "=r,r")
11616 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11617 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11618 (clobber (reg:CC 17))]
11619 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620 "@
11621 sar{l}\t{%2, %k0|%k0, %2}
11622 sar{l}\t{%b2, %k0|%k0, %b2}"
11623 [(set_attr "type" "ishift")
11624 (set_attr "mode" "SI")])
11625
11626 ;; This pattern can't accept a variable shift count, since shifts by
11627 ;; zero don't affect the flags. We assume that shifts by constant
11628 ;; zero are optimized away.
11629 (define_insn "*ashrsi3_one_bit_cmp"
11630 [(set (reg 17)
11631 (compare
11632 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11633 (match_operand:QI 2 "const_int_1_operand" ""))
11634 (const_int 0)))
11635 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11636 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11637 "ix86_match_ccmode (insn, CCGOCmode)
11638 && (TARGET_SHIFT1 || optimize_size)
11639 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11640 "sar{l}\t%0"
11641 [(set_attr "type" "ishift")
11642 (set (attr "length")
11643 (if_then_else (match_operand:SI 0 "register_operand" "")
11644 (const_string "2")
11645 (const_string "*")))])
11646
11647 (define_insn "*ashrsi3_one_bit_cmp_zext"
11648 [(set (reg 17)
11649 (compare
11650 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11651 (match_operand:QI 2 "const_int_1_operand" ""))
11652 (const_int 0)))
11653 (set (match_operand:DI 0 "register_operand" "=r")
11654 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11655 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11656 && (TARGET_SHIFT1 || optimize_size)
11657 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11658 "sar{l}\t%k0"
11659 [(set_attr "type" "ishift")
11660 (set_attr "length" "2")])
11661
11662 ;; This pattern can't accept a variable shift count, since shifts by
11663 ;; zero don't affect the flags. We assume that shifts by constant
11664 ;; zero are optimized away.
11665 (define_insn "*ashrsi3_cmp"
11666 [(set (reg 17)
11667 (compare
11668 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11669 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11670 (const_int 0)))
11671 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11672 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11673 "ix86_match_ccmode (insn, CCGOCmode)
11674 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11675 "sar{l}\t{%2, %0|%0, %2}"
11676 [(set_attr "type" "ishift")
11677 (set_attr "mode" "SI")])
11678
11679 (define_insn "*ashrsi3_cmp_zext"
11680 [(set (reg 17)
11681 (compare
11682 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11683 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11684 (const_int 0)))
11685 (set (match_operand:DI 0 "register_operand" "=r")
11686 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11687 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11688 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11689 "sar{l}\t{%2, %k0|%k0, %2}"
11690 [(set_attr "type" "ishift")
11691 (set_attr "mode" "SI")])
11692
11693 (define_expand "ashrhi3"
11694 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11695 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11696 (match_operand:QI 2 "nonmemory_operand" "")))
11697 (clobber (reg:CC 17))]
11698 "TARGET_HIMODE_MATH"
11699 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11700
11701 (define_insn "*ashrhi3_1_one_bit"
11702 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11703 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11704 (match_operand:QI 2 "const_int_1_operand" "")))
11705 (clobber (reg:CC 17))]
11706 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11707 && (TARGET_SHIFT1 || optimize_size)"
11708 "sar{w}\t%0"
11709 [(set_attr "type" "ishift")
11710 (set (attr "length")
11711 (if_then_else (match_operand 0 "register_operand" "")
11712 (const_string "2")
11713 (const_string "*")))])
11714
11715 (define_insn "*ashrhi3_1"
11716 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11717 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11718 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11719 (clobber (reg:CC 17))]
11720 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11721 "@
11722 sar{w}\t{%2, %0|%0, %2}
11723 sar{w}\t{%b2, %0|%0, %b2}"
11724 [(set_attr "type" "ishift")
11725 (set_attr "mode" "HI")])
11726
11727 ;; This pattern can't accept a variable shift count, since shifts by
11728 ;; zero don't affect the flags. We assume that shifts by constant
11729 ;; zero are optimized away.
11730 (define_insn "*ashrhi3_one_bit_cmp"
11731 [(set (reg 17)
11732 (compare
11733 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11734 (match_operand:QI 2 "const_int_1_operand" ""))
11735 (const_int 0)))
11736 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11737 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11738 "ix86_match_ccmode (insn, CCGOCmode)
11739 && (TARGET_SHIFT1 || optimize_size)
11740 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11741 "sar{w}\t%0"
11742 [(set_attr "type" "ishift")
11743 (set (attr "length")
11744 (if_then_else (match_operand 0 "register_operand" "")
11745 (const_string "2")
11746 (const_string "*")))])
11747
11748 ;; This pattern can't accept a variable shift count, since shifts by
11749 ;; zero don't affect the flags. We assume that shifts by constant
11750 ;; zero are optimized away.
11751 (define_insn "*ashrhi3_cmp"
11752 [(set (reg 17)
11753 (compare
11754 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11755 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11756 (const_int 0)))
11757 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11758 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11759 "ix86_match_ccmode (insn, CCGOCmode)
11760 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11761 "sar{w}\t{%2, %0|%0, %2}"
11762 [(set_attr "type" "ishift")
11763 (set_attr "mode" "HI")])
11764
11765 (define_expand "ashrqi3"
11766 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11767 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11768 (match_operand:QI 2 "nonmemory_operand" "")))
11769 (clobber (reg:CC 17))]
11770 "TARGET_QIMODE_MATH"
11771 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11772
11773 (define_insn "*ashrqi3_1_one_bit"
11774 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11775 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11776 (match_operand:QI 2 "const_int_1_operand" "")))
11777 (clobber (reg:CC 17))]
11778 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11779 && (TARGET_SHIFT1 || optimize_size)"
11780 "sar{b}\t%0"
11781 [(set_attr "type" "ishift")
11782 (set (attr "length")
11783 (if_then_else (match_operand 0 "register_operand" "")
11784 (const_string "2")
11785 (const_string "*")))])
11786
11787 (define_insn "*ashrqi3_1_one_bit_slp"
11788 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11789 (ashiftrt:QI (match_dup 0)
11790 (match_operand:QI 1 "const_int_1_operand" "")))
11791 (clobber (reg:CC 17))]
11792 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11793 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11794 && (TARGET_SHIFT1 || optimize_size)"
11795 "sar{b}\t%0"
11796 [(set_attr "type" "ishift1")
11797 (set (attr "length")
11798 (if_then_else (match_operand 0 "register_operand" "")
11799 (const_string "2")
11800 (const_string "*")))])
11801
11802 (define_insn "*ashrqi3_1"
11803 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11804 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11805 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11806 (clobber (reg:CC 17))]
11807 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11808 "@
11809 sar{b}\t{%2, %0|%0, %2}
11810 sar{b}\t{%b2, %0|%0, %b2}"
11811 [(set_attr "type" "ishift")
11812 (set_attr "mode" "QI")])
11813
11814 (define_insn "*ashrqi3_1_slp"
11815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11816 (ashiftrt:QI (match_dup 0)
11817 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11818 (clobber (reg:CC 17))]
11819 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11820 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11821 "@
11822 sar{b}\t{%1, %0|%0, %1}
11823 sar{b}\t{%b1, %0|%0, %b1}"
11824 [(set_attr "type" "ishift1")
11825 (set_attr "mode" "QI")])
11826
11827 ;; This pattern can't accept a variable shift count, since shifts by
11828 ;; zero don't affect the flags. We assume that shifts by constant
11829 ;; zero are optimized away.
11830 (define_insn "*ashrqi3_one_bit_cmp"
11831 [(set (reg 17)
11832 (compare
11833 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11834 (match_operand:QI 2 "const_int_1_operand" "I"))
11835 (const_int 0)))
11836 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11837 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11838 "ix86_match_ccmode (insn, CCGOCmode)
11839 && (TARGET_SHIFT1 || optimize_size)
11840 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11841 "sar{b}\t%0"
11842 [(set_attr "type" "ishift")
11843 (set (attr "length")
11844 (if_then_else (match_operand 0 "register_operand" "")
11845 (const_string "2")
11846 (const_string "*")))])
11847
11848 ;; This pattern can't accept a variable shift count, since shifts by
11849 ;; zero don't affect the flags. We assume that shifts by constant
11850 ;; zero are optimized away.
11851 (define_insn "*ashrqi3_cmp"
11852 [(set (reg 17)
11853 (compare
11854 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11855 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11856 (const_int 0)))
11857 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11858 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11859 "ix86_match_ccmode (insn, CCGOCmode)
11860 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11861 "sar{b}\t{%2, %0|%0, %2}"
11862 [(set_attr "type" "ishift")
11863 (set_attr "mode" "QI")])
11864 \f
11865 ;; Logical shift instructions
11866
11867 ;; See comment above `ashldi3' about how this works.
11868
11869 (define_expand "lshrdi3"
11870 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11871 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11872 (match_operand:QI 2 "nonmemory_operand" "")))
11873 (clobber (reg:CC 17))])]
11874 ""
11875 {
11876 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11877 {
11878 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11879 DONE;
11880 }
11881 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11882 DONE;
11883 })
11884
11885 (define_insn "*lshrdi3_1_one_bit_rex64"
11886 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11887 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11888 (match_operand:QI 2 "const_int_1_operand" "")))
11889 (clobber (reg:CC 17))]
11890 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11891 && (TARGET_SHIFT1 || optimize_size)"
11892 "shr{q}\t%0"
11893 [(set_attr "type" "ishift")
11894 (set (attr "length")
11895 (if_then_else (match_operand:DI 0 "register_operand" "")
11896 (const_string "2")
11897 (const_string "*")))])
11898
11899 (define_insn "*lshrdi3_1_rex64"
11900 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11901 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11902 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11903 (clobber (reg:CC 17))]
11904 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11905 "@
11906 shr{q}\t{%2, %0|%0, %2}
11907 shr{q}\t{%b2, %0|%0, %b2}"
11908 [(set_attr "type" "ishift")
11909 (set_attr "mode" "DI")])
11910
11911 ;; This pattern can't accept a variable shift count, since shifts by
11912 ;; zero don't affect the flags. We assume that shifts by constant
11913 ;; zero are optimized away.
11914 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11915 [(set (reg 17)
11916 (compare
11917 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11918 (match_operand:QI 2 "const_int_1_operand" ""))
11919 (const_int 0)))
11920 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11921 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11922 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11923 && (TARGET_SHIFT1 || optimize_size)
11924 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11925 "shr{q}\t%0"
11926 [(set_attr "type" "ishift")
11927 (set (attr "length")
11928 (if_then_else (match_operand:DI 0 "register_operand" "")
11929 (const_string "2")
11930 (const_string "*")))])
11931
11932 ;; This pattern can't accept a variable shift count, since shifts by
11933 ;; zero don't affect the flags. We assume that shifts by constant
11934 ;; zero are optimized away.
11935 (define_insn "*lshrdi3_cmp_rex64"
11936 [(set (reg 17)
11937 (compare
11938 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11939 (match_operand:QI 2 "const_int_operand" "e"))
11940 (const_int 0)))
11941 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11942 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11943 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11944 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11945 "shr{q}\t{%2, %0|%0, %2}"
11946 [(set_attr "type" "ishift")
11947 (set_attr "mode" "DI")])
11948
11949 (define_insn "lshrdi3_1"
11950 [(set (match_operand:DI 0 "register_operand" "=r")
11951 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11952 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11953 (clobber (match_scratch:SI 3 "=&r"))
11954 (clobber (reg:CC 17))]
11955 "!TARGET_64BIT && TARGET_CMOVE"
11956 "#"
11957 [(set_attr "type" "multi")])
11958
11959 (define_insn "*lshrdi3_2"
11960 [(set (match_operand:DI 0 "register_operand" "=r")
11961 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11962 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11963 (clobber (reg:CC 17))]
11964 "!TARGET_64BIT"
11965 "#"
11966 [(set_attr "type" "multi")])
11967
11968 (define_split
11969 [(set (match_operand:DI 0 "register_operand" "")
11970 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11971 (match_operand:QI 2 "nonmemory_operand" "")))
11972 (clobber (match_scratch:SI 3 ""))
11973 (clobber (reg:CC 17))]
11974 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11975 [(const_int 0)]
11976 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11977
11978 (define_split
11979 [(set (match_operand:DI 0 "register_operand" "")
11980 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11981 (match_operand:QI 2 "nonmemory_operand" "")))
11982 (clobber (reg:CC 17))]
11983 "!TARGET_64BIT && reload_completed"
11984 [(const_int 0)]
11985 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11986
11987 (define_expand "lshrsi3"
11988 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11989 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11990 (match_operand:QI 2 "nonmemory_operand" "")))
11991 (clobber (reg:CC 17))]
11992 ""
11993 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11994
11995 (define_insn "*lshrsi3_1_one_bit"
11996 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11997 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11998 (match_operand:QI 2 "const_int_1_operand" "")))
11999 (clobber (reg:CC 17))]
12000 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12001 && (TARGET_SHIFT1 || optimize_size)"
12002 "shr{l}\t%0"
12003 [(set_attr "type" "ishift")
12004 (set (attr "length")
12005 (if_then_else (match_operand:SI 0 "register_operand" "")
12006 (const_string "2")
12007 (const_string "*")))])
12008
12009 (define_insn "*lshrsi3_1_one_bit_zext"
12010 [(set (match_operand:DI 0 "register_operand" "=r")
12011 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12012 (match_operand:QI 2 "const_int_1_operand" "")))
12013 (clobber (reg:CC 17))]
12014 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12015 && (TARGET_SHIFT1 || optimize_size)"
12016 "shr{l}\t%k0"
12017 [(set_attr "type" "ishift")
12018 (set_attr "length" "2")])
12019
12020 (define_insn "*lshrsi3_1"
12021 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12022 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12023 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12024 (clobber (reg:CC 17))]
12025 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12026 "@
12027 shr{l}\t{%2, %0|%0, %2}
12028 shr{l}\t{%b2, %0|%0, %b2}"
12029 [(set_attr "type" "ishift")
12030 (set_attr "mode" "SI")])
12031
12032 (define_insn "*lshrsi3_1_zext"
12033 [(set (match_operand:DI 0 "register_operand" "=r,r")
12034 (zero_extend:DI
12035 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12036 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12037 (clobber (reg:CC 17))]
12038 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12039 "@
12040 shr{l}\t{%2, %k0|%k0, %2}
12041 shr{l}\t{%b2, %k0|%k0, %b2}"
12042 [(set_attr "type" "ishift")
12043 (set_attr "mode" "SI")])
12044
12045 ;; This pattern can't accept a variable shift count, since shifts by
12046 ;; zero don't affect the flags. We assume that shifts by constant
12047 ;; zero are optimized away.
12048 (define_insn "*lshrsi3_one_bit_cmp"
12049 [(set (reg 17)
12050 (compare
12051 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12052 (match_operand:QI 2 "const_int_1_operand" ""))
12053 (const_int 0)))
12054 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12055 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12056 "ix86_match_ccmode (insn, CCGOCmode)
12057 && (TARGET_SHIFT1 || optimize_size)
12058 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12059 "shr{l}\t%0"
12060 [(set_attr "type" "ishift")
12061 (set (attr "length")
12062 (if_then_else (match_operand:SI 0 "register_operand" "")
12063 (const_string "2")
12064 (const_string "*")))])
12065
12066 (define_insn "*lshrsi3_cmp_one_bit_zext"
12067 [(set (reg 17)
12068 (compare
12069 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12070 (match_operand:QI 2 "const_int_1_operand" ""))
12071 (const_int 0)))
12072 (set (match_operand:DI 0 "register_operand" "=r")
12073 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12074 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12075 && (TARGET_SHIFT1 || optimize_size)
12076 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12077 "shr{l}\t%k0"
12078 [(set_attr "type" "ishift")
12079 (set_attr "length" "2")])
12080
12081 ;; This pattern can't accept a variable shift count, since shifts by
12082 ;; zero don't affect the flags. We assume that shifts by constant
12083 ;; zero are optimized away.
12084 (define_insn "*lshrsi3_cmp"
12085 [(set (reg 17)
12086 (compare
12087 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12088 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12089 (const_int 0)))
12090 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12091 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12092 "ix86_match_ccmode (insn, CCGOCmode)
12093 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12094 "shr{l}\t{%2, %0|%0, %2}"
12095 [(set_attr "type" "ishift")
12096 (set_attr "mode" "SI")])
12097
12098 (define_insn "*lshrsi3_cmp_zext"
12099 [(set (reg 17)
12100 (compare
12101 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12102 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12103 (const_int 0)))
12104 (set (match_operand:DI 0 "register_operand" "=r")
12105 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12106 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12107 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12108 "shr{l}\t{%2, %k0|%k0, %2}"
12109 [(set_attr "type" "ishift")
12110 (set_attr "mode" "SI")])
12111
12112 (define_expand "lshrhi3"
12113 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12114 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12115 (match_operand:QI 2 "nonmemory_operand" "")))
12116 (clobber (reg:CC 17))]
12117 "TARGET_HIMODE_MATH"
12118 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12119
12120 (define_insn "*lshrhi3_1_one_bit"
12121 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12122 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12123 (match_operand:QI 2 "const_int_1_operand" "")))
12124 (clobber (reg:CC 17))]
12125 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12126 && (TARGET_SHIFT1 || optimize_size)"
12127 "shr{w}\t%0"
12128 [(set_attr "type" "ishift")
12129 (set (attr "length")
12130 (if_then_else (match_operand 0 "register_operand" "")
12131 (const_string "2")
12132 (const_string "*")))])
12133
12134 (define_insn "*lshrhi3_1"
12135 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12136 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12137 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12138 (clobber (reg:CC 17))]
12139 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12140 "@
12141 shr{w}\t{%2, %0|%0, %2}
12142 shr{w}\t{%b2, %0|%0, %b2}"
12143 [(set_attr "type" "ishift")
12144 (set_attr "mode" "HI")])
12145
12146 ;; This pattern can't accept a variable shift count, since shifts by
12147 ;; zero don't affect the flags. We assume that shifts by constant
12148 ;; zero are optimized away.
12149 (define_insn "*lshrhi3_one_bit_cmp"
12150 [(set (reg 17)
12151 (compare
12152 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12153 (match_operand:QI 2 "const_int_1_operand" ""))
12154 (const_int 0)))
12155 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12156 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12157 "ix86_match_ccmode (insn, CCGOCmode)
12158 && (TARGET_SHIFT1 || optimize_size)
12159 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12160 "shr{w}\t%0"
12161 [(set_attr "type" "ishift")
12162 (set (attr "length")
12163 (if_then_else (match_operand:SI 0 "register_operand" "")
12164 (const_string "2")
12165 (const_string "*")))])
12166
12167 ;; This pattern can't accept a variable shift count, since shifts by
12168 ;; zero don't affect the flags. We assume that shifts by constant
12169 ;; zero are optimized away.
12170 (define_insn "*lshrhi3_cmp"
12171 [(set (reg 17)
12172 (compare
12173 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12174 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12175 (const_int 0)))
12176 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12177 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12178 "ix86_match_ccmode (insn, CCGOCmode)
12179 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12180 "shr{w}\t{%2, %0|%0, %2}"
12181 [(set_attr "type" "ishift")
12182 (set_attr "mode" "HI")])
12183
12184 (define_expand "lshrqi3"
12185 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12186 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12187 (match_operand:QI 2 "nonmemory_operand" "")))
12188 (clobber (reg:CC 17))]
12189 "TARGET_QIMODE_MATH"
12190 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12191
12192 (define_insn "*lshrqi3_1_one_bit"
12193 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12194 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12195 (match_operand:QI 2 "const_int_1_operand" "")))
12196 (clobber (reg:CC 17))]
12197 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12198 && (TARGET_SHIFT1 || optimize_size)"
12199 "shr{b}\t%0"
12200 [(set_attr "type" "ishift")
12201 (set (attr "length")
12202 (if_then_else (match_operand 0 "register_operand" "")
12203 (const_string "2")
12204 (const_string "*")))])
12205
12206 (define_insn "*lshrqi3_1_one_bit_slp"
12207 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12208 (lshiftrt:QI (match_dup 0)
12209 (match_operand:QI 1 "const_int_1_operand" "")))
12210 (clobber (reg:CC 17))]
12211 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12212 && (TARGET_SHIFT1 || optimize_size)"
12213 "shr{b}\t%0"
12214 [(set_attr "type" "ishift1")
12215 (set (attr "length")
12216 (if_then_else (match_operand 0 "register_operand" "")
12217 (const_string "2")
12218 (const_string "*")))])
12219
12220 (define_insn "*lshrqi3_1"
12221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12222 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12223 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12224 (clobber (reg:CC 17))]
12225 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12226 "@
12227 shr{b}\t{%2, %0|%0, %2}
12228 shr{b}\t{%b2, %0|%0, %b2}"
12229 [(set_attr "type" "ishift")
12230 (set_attr "mode" "QI")])
12231
12232 (define_insn "*lshrqi3_1_slp"
12233 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12234 (lshiftrt:QI (match_dup 0)
12235 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12236 (clobber (reg:CC 17))]
12237 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12238 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12239 "@
12240 shr{b}\t{%1, %0|%0, %1}
12241 shr{b}\t{%b1, %0|%0, %b1}"
12242 [(set_attr "type" "ishift1")
12243 (set_attr "mode" "QI")])
12244
12245 ;; This pattern can't accept a variable shift count, since shifts by
12246 ;; zero don't affect the flags. We assume that shifts by constant
12247 ;; zero are optimized away.
12248 (define_insn "*lshrqi2_one_bit_cmp"
12249 [(set (reg 17)
12250 (compare
12251 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12252 (match_operand:QI 2 "const_int_1_operand" ""))
12253 (const_int 0)))
12254 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12255 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12256 "ix86_match_ccmode (insn, CCGOCmode)
12257 && (TARGET_SHIFT1 || optimize_size)
12258 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12259 "shr{b}\t%0"
12260 [(set_attr "type" "ishift")
12261 (set (attr "length")
12262 (if_then_else (match_operand:SI 0 "register_operand" "")
12263 (const_string "2")
12264 (const_string "*")))])
12265
12266 ;; This pattern can't accept a variable shift count, since shifts by
12267 ;; zero don't affect the flags. We assume that shifts by constant
12268 ;; zero are optimized away.
12269 (define_insn "*lshrqi2_cmp"
12270 [(set (reg 17)
12271 (compare
12272 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12273 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12274 (const_int 0)))
12275 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12276 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12277 "ix86_match_ccmode (insn, CCGOCmode)
12278 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12279 "shr{b}\t{%2, %0|%0, %2}"
12280 [(set_attr "type" "ishift")
12281 (set_attr "mode" "QI")])
12282 \f
12283 ;; Rotate instructions
12284
12285 (define_expand "rotldi3"
12286 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12287 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12288 (match_operand:QI 2 "nonmemory_operand" "")))
12289 (clobber (reg:CC 17))]
12290 "TARGET_64BIT"
12291 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12292
12293 (define_insn "*rotlsi3_1_one_bit_rex64"
12294 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12295 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12296 (match_operand:QI 2 "const_int_1_operand" "")))
12297 (clobber (reg:CC 17))]
12298 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12299 && (TARGET_SHIFT1 || optimize_size)"
12300 "rol{q}\t%0"
12301 [(set_attr "type" "rotate")
12302 (set (attr "length")
12303 (if_then_else (match_operand:DI 0 "register_operand" "")
12304 (const_string "2")
12305 (const_string "*")))])
12306
12307 (define_insn "*rotldi3_1_rex64"
12308 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12309 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12310 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12311 (clobber (reg:CC 17))]
12312 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12313 "@
12314 rol{q}\t{%2, %0|%0, %2}
12315 rol{q}\t{%b2, %0|%0, %b2}"
12316 [(set_attr "type" "rotate")
12317 (set_attr "mode" "DI")])
12318
12319 (define_expand "rotlsi3"
12320 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12321 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12322 (match_operand:QI 2 "nonmemory_operand" "")))
12323 (clobber (reg:CC 17))]
12324 ""
12325 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12326
12327 (define_insn "*rotlsi3_1_one_bit"
12328 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12329 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12330 (match_operand:QI 2 "const_int_1_operand" "")))
12331 (clobber (reg:CC 17))]
12332 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12333 && (TARGET_SHIFT1 || optimize_size)"
12334 "rol{l}\t%0"
12335 [(set_attr "type" "rotate")
12336 (set (attr "length")
12337 (if_then_else (match_operand:SI 0 "register_operand" "")
12338 (const_string "2")
12339 (const_string "*")))])
12340
12341 (define_insn "*rotlsi3_1_one_bit_zext"
12342 [(set (match_operand:DI 0 "register_operand" "=r")
12343 (zero_extend:DI
12344 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12345 (match_operand:QI 2 "const_int_1_operand" ""))))
12346 (clobber (reg:CC 17))]
12347 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12348 && (TARGET_SHIFT1 || optimize_size)"
12349 "rol{l}\t%k0"
12350 [(set_attr "type" "rotate")
12351 (set_attr "length" "2")])
12352
12353 (define_insn "*rotlsi3_1"
12354 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12355 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12356 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12357 (clobber (reg:CC 17))]
12358 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12359 "@
12360 rol{l}\t{%2, %0|%0, %2}
12361 rol{l}\t{%b2, %0|%0, %b2}"
12362 [(set_attr "type" "rotate")
12363 (set_attr "mode" "SI")])
12364
12365 (define_insn "*rotlsi3_1_zext"
12366 [(set (match_operand:DI 0 "register_operand" "=r,r")
12367 (zero_extend:DI
12368 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12369 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12370 (clobber (reg:CC 17))]
12371 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12372 "@
12373 rol{l}\t{%2, %k0|%k0, %2}
12374 rol{l}\t{%b2, %k0|%k0, %b2}"
12375 [(set_attr "type" "rotate")
12376 (set_attr "mode" "SI")])
12377
12378 (define_expand "rotlhi3"
12379 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12380 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12381 (match_operand:QI 2 "nonmemory_operand" "")))
12382 (clobber (reg:CC 17))]
12383 "TARGET_HIMODE_MATH"
12384 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12385
12386 (define_insn "*rotlhi3_1_one_bit"
12387 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12388 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12389 (match_operand:QI 2 "const_int_1_operand" "")))
12390 (clobber (reg:CC 17))]
12391 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12392 && (TARGET_SHIFT1 || optimize_size)"
12393 "rol{w}\t%0"
12394 [(set_attr "type" "rotate")
12395 (set (attr "length")
12396 (if_then_else (match_operand 0 "register_operand" "")
12397 (const_string "2")
12398 (const_string "*")))])
12399
12400 (define_insn "*rotlhi3_1"
12401 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12402 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12403 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12404 (clobber (reg:CC 17))]
12405 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12406 "@
12407 rol{w}\t{%2, %0|%0, %2}
12408 rol{w}\t{%b2, %0|%0, %b2}"
12409 [(set_attr "type" "rotate")
12410 (set_attr "mode" "HI")])
12411
12412 (define_expand "rotlqi3"
12413 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12414 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12415 (match_operand:QI 2 "nonmemory_operand" "")))
12416 (clobber (reg:CC 17))]
12417 "TARGET_QIMODE_MATH"
12418 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12419
12420 (define_insn "*rotlqi3_1_one_bit_slp"
12421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12422 (rotate:QI (match_dup 0)
12423 (match_operand:QI 1 "const_int_1_operand" "")))
12424 (clobber (reg:CC 17))]
12425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12426 && (TARGET_SHIFT1 || optimize_size)"
12427 "rol{b}\t%0"
12428 [(set_attr "type" "rotate1")
12429 (set (attr "length")
12430 (if_then_else (match_operand 0 "register_operand" "")
12431 (const_string "2")
12432 (const_string "*")))])
12433
12434 (define_insn "*rotlqi3_1_one_bit"
12435 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12436 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12437 (match_operand:QI 2 "const_int_1_operand" "")))
12438 (clobber (reg:CC 17))]
12439 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12440 && (TARGET_SHIFT1 || optimize_size)"
12441 "rol{b}\t%0"
12442 [(set_attr "type" "rotate")
12443 (set (attr "length")
12444 (if_then_else (match_operand 0 "register_operand" "")
12445 (const_string "2")
12446 (const_string "*")))])
12447
12448 (define_insn "*rotlqi3_1_slp"
12449 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12450 (rotate:QI (match_dup 0)
12451 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12452 (clobber (reg:CC 17))]
12453 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12454 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12455 "@
12456 rol{b}\t{%1, %0|%0, %1}
12457 rol{b}\t{%b1, %0|%0, %b1}"
12458 [(set_attr "type" "rotate1")
12459 (set_attr "mode" "QI")])
12460
12461 (define_insn "*rotlqi3_1"
12462 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12463 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12464 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12465 (clobber (reg:CC 17))]
12466 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12467 "@
12468 rol{b}\t{%2, %0|%0, %2}
12469 rol{b}\t{%b2, %0|%0, %b2}"
12470 [(set_attr "type" "rotate")
12471 (set_attr "mode" "QI")])
12472
12473 (define_expand "rotrdi3"
12474 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12475 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12476 (match_operand:QI 2 "nonmemory_operand" "")))
12477 (clobber (reg:CC 17))]
12478 "TARGET_64BIT"
12479 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12480
12481 (define_insn "*rotrdi3_1_one_bit_rex64"
12482 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12483 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12484 (match_operand:QI 2 "const_int_1_operand" "")))
12485 (clobber (reg:CC 17))]
12486 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12487 && (TARGET_SHIFT1 || optimize_size)"
12488 "ror{q}\t%0"
12489 [(set_attr "type" "rotate")
12490 (set (attr "length")
12491 (if_then_else (match_operand:DI 0 "register_operand" "")
12492 (const_string "2")
12493 (const_string "*")))])
12494
12495 (define_insn "*rotrdi3_1_rex64"
12496 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12497 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12498 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12499 (clobber (reg:CC 17))]
12500 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12501 "@
12502 ror{q}\t{%2, %0|%0, %2}
12503 ror{q}\t{%b2, %0|%0, %b2}"
12504 [(set_attr "type" "rotate")
12505 (set_attr "mode" "DI")])
12506
12507 (define_expand "rotrsi3"
12508 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12509 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12510 (match_operand:QI 2 "nonmemory_operand" "")))
12511 (clobber (reg:CC 17))]
12512 ""
12513 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12514
12515 (define_insn "*rotrsi3_1_one_bit"
12516 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12517 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12518 (match_operand:QI 2 "const_int_1_operand" "")))
12519 (clobber (reg:CC 17))]
12520 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12521 && (TARGET_SHIFT1 || optimize_size)"
12522 "ror{l}\t%0"
12523 [(set_attr "type" "rotate")
12524 (set (attr "length")
12525 (if_then_else (match_operand:SI 0 "register_operand" "")
12526 (const_string "2")
12527 (const_string "*")))])
12528
12529 (define_insn "*rotrsi3_1_one_bit_zext"
12530 [(set (match_operand:DI 0 "register_operand" "=r")
12531 (zero_extend:DI
12532 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12533 (match_operand:QI 2 "const_int_1_operand" ""))))
12534 (clobber (reg:CC 17))]
12535 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12536 && (TARGET_SHIFT1 || optimize_size)"
12537 "ror{l}\t%k0"
12538 [(set_attr "type" "rotate")
12539 (set (attr "length")
12540 (if_then_else (match_operand:SI 0 "register_operand" "")
12541 (const_string "2")
12542 (const_string "*")))])
12543
12544 (define_insn "*rotrsi3_1"
12545 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12546 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12547 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12548 (clobber (reg:CC 17))]
12549 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12550 "@
12551 ror{l}\t{%2, %0|%0, %2}
12552 ror{l}\t{%b2, %0|%0, %b2}"
12553 [(set_attr "type" "rotate")
12554 (set_attr "mode" "SI")])
12555
12556 (define_insn "*rotrsi3_1_zext"
12557 [(set (match_operand:DI 0 "register_operand" "=r,r")
12558 (zero_extend:DI
12559 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12560 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12561 (clobber (reg:CC 17))]
12562 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12563 "@
12564 ror{l}\t{%2, %k0|%k0, %2}
12565 ror{l}\t{%b2, %k0|%k0, %b2}"
12566 [(set_attr "type" "rotate")
12567 (set_attr "mode" "SI")])
12568
12569 (define_expand "rotrhi3"
12570 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12571 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12572 (match_operand:QI 2 "nonmemory_operand" "")))
12573 (clobber (reg:CC 17))]
12574 "TARGET_HIMODE_MATH"
12575 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12576
12577 (define_insn "*rotrhi3_one_bit"
12578 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12579 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12580 (match_operand:QI 2 "const_int_1_operand" "")))
12581 (clobber (reg:CC 17))]
12582 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12583 && (TARGET_SHIFT1 || optimize_size)"
12584 "ror{w}\t%0"
12585 [(set_attr "type" "rotate")
12586 (set (attr "length")
12587 (if_then_else (match_operand 0 "register_operand" "")
12588 (const_string "2")
12589 (const_string "*")))])
12590
12591 (define_insn "*rotrhi3"
12592 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12593 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12594 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12595 (clobber (reg:CC 17))]
12596 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12597 "@
12598 ror{w}\t{%2, %0|%0, %2}
12599 ror{w}\t{%b2, %0|%0, %b2}"
12600 [(set_attr "type" "rotate")
12601 (set_attr "mode" "HI")])
12602
12603 (define_expand "rotrqi3"
12604 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12605 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12606 (match_operand:QI 2 "nonmemory_operand" "")))
12607 (clobber (reg:CC 17))]
12608 "TARGET_QIMODE_MATH"
12609 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12610
12611 (define_insn "*rotrqi3_1_one_bit"
12612 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12613 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12614 (match_operand:QI 2 "const_int_1_operand" "")))
12615 (clobber (reg:CC 17))]
12616 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12617 && (TARGET_SHIFT1 || optimize_size)"
12618 "ror{b}\t%0"
12619 [(set_attr "type" "rotate")
12620 (set (attr "length")
12621 (if_then_else (match_operand 0 "register_operand" "")
12622 (const_string "2")
12623 (const_string "*")))])
12624
12625 (define_insn "*rotrqi3_1_one_bit_slp"
12626 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12627 (rotatert:QI (match_dup 0)
12628 (match_operand:QI 1 "const_int_1_operand" "")))
12629 (clobber (reg:CC 17))]
12630 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12631 && (TARGET_SHIFT1 || optimize_size)"
12632 "ror{b}\t%0"
12633 [(set_attr "type" "rotate1")
12634 (set (attr "length")
12635 (if_then_else (match_operand 0 "register_operand" "")
12636 (const_string "2")
12637 (const_string "*")))])
12638
12639 (define_insn "*rotrqi3_1"
12640 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12641 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12642 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12643 (clobber (reg:CC 17))]
12644 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12645 "@
12646 ror{b}\t{%2, %0|%0, %2}
12647 ror{b}\t{%b2, %0|%0, %b2}"
12648 [(set_attr "type" "rotate")
12649 (set_attr "mode" "QI")])
12650
12651 (define_insn "*rotrqi3_1_slp"
12652 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12653 (rotatert:QI (match_dup 0)
12654 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12655 (clobber (reg:CC 17))]
12656 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12657 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12658 "@
12659 ror{b}\t{%1, %0|%0, %1}
12660 ror{b}\t{%b1, %0|%0, %b1}"
12661 [(set_attr "type" "rotate1")
12662 (set_attr "mode" "QI")])
12663 \f
12664 ;; Bit set / bit test instructions
12665
12666 (define_expand "extv"
12667 [(set (match_operand:SI 0 "register_operand" "")
12668 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12669 (match_operand:SI 2 "immediate_operand" "")
12670 (match_operand:SI 3 "immediate_operand" "")))]
12671 ""
12672 {
12673 /* Handle extractions from %ah et al. */
12674 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12675 FAIL;
12676
12677 /* From mips.md: extract_bit_field doesn't verify that our source
12678 matches the predicate, so check it again here. */
12679 if (! register_operand (operands[1], VOIDmode))
12680 FAIL;
12681 })
12682
12683 (define_expand "extzv"
12684 [(set (match_operand:SI 0 "register_operand" "")
12685 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12686 (match_operand:SI 2 "immediate_operand" "")
12687 (match_operand:SI 3 "immediate_operand" "")))]
12688 ""
12689 {
12690 /* Handle extractions from %ah et al. */
12691 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12692 FAIL;
12693
12694 /* From mips.md: extract_bit_field doesn't verify that our source
12695 matches the predicate, so check it again here. */
12696 if (! register_operand (operands[1], VOIDmode))
12697 FAIL;
12698 })
12699
12700 (define_expand "insv"
12701 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12702 (match_operand:SI 1 "immediate_operand" "")
12703 (match_operand:SI 2 "immediate_operand" ""))
12704 (match_operand:SI 3 "register_operand" ""))]
12705 ""
12706 {
12707 /* Handle extractions from %ah et al. */
12708 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12709 FAIL;
12710
12711 /* From mips.md: insert_bit_field doesn't verify that our source
12712 matches the predicate, so check it again here. */
12713 if (! register_operand (operands[0], VOIDmode))
12714 FAIL;
12715 })
12716
12717 ;; %%% bts, btr, btc, bt.
12718 \f
12719 ;; Store-flag instructions.
12720
12721 ;; For all sCOND expanders, also expand the compare or test insn that
12722 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12723
12724 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12725 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12726 ;; way, which can later delete the movzx if only QImode is needed.
12727
12728 (define_expand "seq"
12729 [(set (match_operand:QI 0 "register_operand" "")
12730 (eq:QI (reg:CC 17) (const_int 0)))]
12731 ""
12732 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "sne"
12735 [(set (match_operand:QI 0 "register_operand" "")
12736 (ne:QI (reg:CC 17) (const_int 0)))]
12737 ""
12738 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sgt"
12741 [(set (match_operand:QI 0 "register_operand" "")
12742 (gt:QI (reg:CC 17) (const_int 0)))]
12743 ""
12744 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sgtu"
12747 [(set (match_operand:QI 0 "register_operand" "")
12748 (gtu:QI (reg:CC 17) (const_int 0)))]
12749 ""
12750 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12751
12752 (define_expand "slt"
12753 [(set (match_operand:QI 0 "register_operand" "")
12754 (lt:QI (reg:CC 17) (const_int 0)))]
12755 ""
12756 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12757
12758 (define_expand "sltu"
12759 [(set (match_operand:QI 0 "register_operand" "")
12760 (ltu:QI (reg:CC 17) (const_int 0)))]
12761 ""
12762 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12763
12764 (define_expand "sge"
12765 [(set (match_operand:QI 0 "register_operand" "")
12766 (ge:QI (reg:CC 17) (const_int 0)))]
12767 ""
12768 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12769
12770 (define_expand "sgeu"
12771 [(set (match_operand:QI 0 "register_operand" "")
12772 (geu:QI (reg:CC 17) (const_int 0)))]
12773 ""
12774 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12775
12776 (define_expand "sle"
12777 [(set (match_operand:QI 0 "register_operand" "")
12778 (le:QI (reg:CC 17) (const_int 0)))]
12779 ""
12780 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12781
12782 (define_expand "sleu"
12783 [(set (match_operand:QI 0 "register_operand" "")
12784 (leu:QI (reg:CC 17) (const_int 0)))]
12785 ""
12786 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12787
12788 (define_expand "sunordered"
12789 [(set (match_operand:QI 0 "register_operand" "")
12790 (unordered:QI (reg:CC 17) (const_int 0)))]
12791 "TARGET_80387 || TARGET_SSE"
12792 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12793
12794 (define_expand "sordered"
12795 [(set (match_operand:QI 0 "register_operand" "")
12796 (ordered:QI (reg:CC 17) (const_int 0)))]
12797 "TARGET_80387"
12798 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12799
12800 (define_expand "suneq"
12801 [(set (match_operand:QI 0 "register_operand" "")
12802 (uneq:QI (reg:CC 17) (const_int 0)))]
12803 "TARGET_80387 || TARGET_SSE"
12804 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12805
12806 (define_expand "sunge"
12807 [(set (match_operand:QI 0 "register_operand" "")
12808 (unge:QI (reg:CC 17) (const_int 0)))]
12809 "TARGET_80387 || TARGET_SSE"
12810 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12811
12812 (define_expand "sungt"
12813 [(set (match_operand:QI 0 "register_operand" "")
12814 (ungt:QI (reg:CC 17) (const_int 0)))]
12815 "TARGET_80387 || TARGET_SSE"
12816 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12817
12818 (define_expand "sunle"
12819 [(set (match_operand:QI 0 "register_operand" "")
12820 (unle:QI (reg:CC 17) (const_int 0)))]
12821 "TARGET_80387 || TARGET_SSE"
12822 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12823
12824 (define_expand "sunlt"
12825 [(set (match_operand:QI 0 "register_operand" "")
12826 (unlt:QI (reg:CC 17) (const_int 0)))]
12827 "TARGET_80387 || TARGET_SSE"
12828 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12829
12830 (define_expand "sltgt"
12831 [(set (match_operand:QI 0 "register_operand" "")
12832 (ltgt:QI (reg:CC 17) (const_int 0)))]
12833 "TARGET_80387 || TARGET_SSE"
12834 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12835
12836 (define_insn "*setcc_1"
12837 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12838 (match_operator:QI 1 "ix86_comparison_operator"
12839 [(reg 17) (const_int 0)]))]
12840 ""
12841 "set%C1\t%0"
12842 [(set_attr "type" "setcc")
12843 (set_attr "mode" "QI")])
12844
12845 (define_insn "setcc_2"
12846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12847 (match_operator:QI 1 "ix86_comparison_operator"
12848 [(reg 17) (const_int 0)]))]
12849 ""
12850 "set%C1\t%0"
12851 [(set_attr "type" "setcc")
12852 (set_attr "mode" "QI")])
12853
12854 ;; In general it is not safe to assume too much about CCmode registers,
12855 ;; so simplify-rtx stops when it sees a second one. Under certain
12856 ;; conditions this is safe on x86, so help combine not create
12857 ;;
12858 ;; seta %al
12859 ;; testb %al, %al
12860 ;; sete %al
12861
12862 (define_split
12863 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12864 (ne:QI (match_operator 1 "ix86_comparison_operator"
12865 [(reg 17) (const_int 0)])
12866 (const_int 0)))]
12867 ""
12868 [(set (match_dup 0) (match_dup 1))]
12869 {
12870 PUT_MODE (operands[1], QImode);
12871 })
12872
12873 (define_split
12874 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12875 (ne:QI (match_operator 1 "ix86_comparison_operator"
12876 [(reg 17) (const_int 0)])
12877 (const_int 0)))]
12878 ""
12879 [(set (match_dup 0) (match_dup 1))]
12880 {
12881 PUT_MODE (operands[1], QImode);
12882 })
12883
12884 (define_split
12885 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12886 (eq:QI (match_operator 1 "ix86_comparison_operator"
12887 [(reg 17) (const_int 0)])
12888 (const_int 0)))]
12889 ""
12890 [(set (match_dup 0) (match_dup 1))]
12891 {
12892 rtx new_op1 = copy_rtx (operands[1]);
12893 operands[1] = new_op1;
12894 PUT_MODE (new_op1, QImode);
12895 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12896 GET_MODE (XEXP (new_op1, 0))));
12897
12898 /* Make sure that (a) the CCmode we have for the flags is strong
12899 enough for the reversed compare or (b) we have a valid FP compare. */
12900 if (! ix86_comparison_operator (new_op1, VOIDmode))
12901 FAIL;
12902 })
12903
12904 (define_split
12905 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12906 (eq:QI (match_operator 1 "ix86_comparison_operator"
12907 [(reg 17) (const_int 0)])
12908 (const_int 0)))]
12909 ""
12910 [(set (match_dup 0) (match_dup 1))]
12911 {
12912 rtx new_op1 = copy_rtx (operands[1]);
12913 operands[1] = new_op1;
12914 PUT_MODE (new_op1, QImode);
12915 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12916 GET_MODE (XEXP (new_op1, 0))));
12917
12918 /* Make sure that (a) the CCmode we have for the flags is strong
12919 enough for the reversed compare or (b) we have a valid FP compare. */
12920 if (! ix86_comparison_operator (new_op1, VOIDmode))
12921 FAIL;
12922 })
12923
12924 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12925 ;; subsequent logical operations are used to imitate conditional moves.
12926 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12927 ;; it directly. Futher holding this value in pseudo register might bring
12928 ;; problem in implicit normalization in spill code.
12929 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12930 ;; instructions after reload by splitting the conditional move patterns.
12931
12932 (define_insn "*sse_setccsf"
12933 [(set (match_operand:SF 0 "register_operand" "=x")
12934 (match_operator:SF 1 "sse_comparison_operator"
12935 [(match_operand:SF 2 "register_operand" "0")
12936 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12937 "TARGET_SSE && reload_completed"
12938 "cmp%D1ss\t{%3, %0|%0, %3}"
12939 [(set_attr "type" "ssecmp")
12940 (set_attr "mode" "SF")])
12941
12942 (define_insn "*sse_setccdf"
12943 [(set (match_operand:DF 0 "register_operand" "=Y")
12944 (match_operator:DF 1 "sse_comparison_operator"
12945 [(match_operand:DF 2 "register_operand" "0")
12946 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12947 "TARGET_SSE2 && reload_completed"
12948 "cmp%D1sd\t{%3, %0|%0, %3}"
12949 [(set_attr "type" "ssecmp")
12950 (set_attr "mode" "DF")])
12951 \f
12952 ;; Basic conditional jump instructions.
12953 ;; We ignore the overflow flag for signed branch instructions.
12954
12955 ;; For all bCOND expanders, also expand the compare or test insn that
12956 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12957
12958 (define_expand "beq"
12959 [(set (pc)
12960 (if_then_else (match_dup 1)
12961 (label_ref (match_operand 0 "" ""))
12962 (pc)))]
12963 ""
12964 "ix86_expand_branch (EQ, operands[0]); DONE;")
12965
12966 (define_expand "bne"
12967 [(set (pc)
12968 (if_then_else (match_dup 1)
12969 (label_ref (match_operand 0 "" ""))
12970 (pc)))]
12971 ""
12972 "ix86_expand_branch (NE, operands[0]); DONE;")
12973
12974 (define_expand "bgt"
12975 [(set (pc)
12976 (if_then_else (match_dup 1)
12977 (label_ref (match_operand 0 "" ""))
12978 (pc)))]
12979 ""
12980 "ix86_expand_branch (GT, operands[0]); DONE;")
12981
12982 (define_expand "bgtu"
12983 [(set (pc)
12984 (if_then_else (match_dup 1)
12985 (label_ref (match_operand 0 "" ""))
12986 (pc)))]
12987 ""
12988 "ix86_expand_branch (GTU, operands[0]); DONE;")
12989
12990 (define_expand "blt"
12991 [(set (pc)
12992 (if_then_else (match_dup 1)
12993 (label_ref (match_operand 0 "" ""))
12994 (pc)))]
12995 ""
12996 "ix86_expand_branch (LT, operands[0]); DONE;")
12997
12998 (define_expand "bltu"
12999 [(set (pc)
13000 (if_then_else (match_dup 1)
13001 (label_ref (match_operand 0 "" ""))
13002 (pc)))]
13003 ""
13004 "ix86_expand_branch (LTU, operands[0]); DONE;")
13005
13006 (define_expand "bge"
13007 [(set (pc)
13008 (if_then_else (match_dup 1)
13009 (label_ref (match_operand 0 "" ""))
13010 (pc)))]
13011 ""
13012 "ix86_expand_branch (GE, operands[0]); DONE;")
13013
13014 (define_expand "bgeu"
13015 [(set (pc)
13016 (if_then_else (match_dup 1)
13017 (label_ref (match_operand 0 "" ""))
13018 (pc)))]
13019 ""
13020 "ix86_expand_branch (GEU, operands[0]); DONE;")
13021
13022 (define_expand "ble"
13023 [(set (pc)
13024 (if_then_else (match_dup 1)
13025 (label_ref (match_operand 0 "" ""))
13026 (pc)))]
13027 ""
13028 "ix86_expand_branch (LE, operands[0]); DONE;")
13029
13030 (define_expand "bleu"
13031 [(set (pc)
13032 (if_then_else (match_dup 1)
13033 (label_ref (match_operand 0 "" ""))
13034 (pc)))]
13035 ""
13036 "ix86_expand_branch (LEU, operands[0]); DONE;")
13037
13038 (define_expand "bunordered"
13039 [(set (pc)
13040 (if_then_else (match_dup 1)
13041 (label_ref (match_operand 0 "" ""))
13042 (pc)))]
13043 "TARGET_80387 || TARGET_SSE"
13044 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13045
13046 (define_expand "bordered"
13047 [(set (pc)
13048 (if_then_else (match_dup 1)
13049 (label_ref (match_operand 0 "" ""))
13050 (pc)))]
13051 "TARGET_80387 || TARGET_SSE"
13052 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13053
13054 (define_expand "buneq"
13055 [(set (pc)
13056 (if_then_else (match_dup 1)
13057 (label_ref (match_operand 0 "" ""))
13058 (pc)))]
13059 "TARGET_80387 || TARGET_SSE"
13060 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13061
13062 (define_expand "bunge"
13063 [(set (pc)
13064 (if_then_else (match_dup 1)
13065 (label_ref (match_operand 0 "" ""))
13066 (pc)))]
13067 "TARGET_80387 || TARGET_SSE"
13068 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13069
13070 (define_expand "bungt"
13071 [(set (pc)
13072 (if_then_else (match_dup 1)
13073 (label_ref (match_operand 0 "" ""))
13074 (pc)))]
13075 "TARGET_80387 || TARGET_SSE"
13076 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13077
13078 (define_expand "bunle"
13079 [(set (pc)
13080 (if_then_else (match_dup 1)
13081 (label_ref (match_operand 0 "" ""))
13082 (pc)))]
13083 "TARGET_80387 || TARGET_SSE"
13084 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13085
13086 (define_expand "bunlt"
13087 [(set (pc)
13088 (if_then_else (match_dup 1)
13089 (label_ref (match_operand 0 "" ""))
13090 (pc)))]
13091 "TARGET_80387 || TARGET_SSE"
13092 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13093
13094 (define_expand "bltgt"
13095 [(set (pc)
13096 (if_then_else (match_dup 1)
13097 (label_ref (match_operand 0 "" ""))
13098 (pc)))]
13099 "TARGET_80387 || TARGET_SSE"
13100 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13101
13102 (define_insn "*jcc_1"
13103 [(set (pc)
13104 (if_then_else (match_operator 1 "ix86_comparison_operator"
13105 [(reg 17) (const_int 0)])
13106 (label_ref (match_operand 0 "" ""))
13107 (pc)))]
13108 ""
13109 "%+j%C1\t%l0"
13110 [(set_attr "type" "ibr")
13111 (set_attr "modrm" "0")
13112 (set (attr "length")
13113 (if_then_else (and (ge (minus (match_dup 0) (pc))
13114 (const_int -128))
13115 (lt (minus (match_dup 0) (pc))
13116 (const_int 124)))
13117 (const_int 2)
13118 (const_int 6)))])
13119
13120 (define_insn "*jcc_2"
13121 [(set (pc)
13122 (if_then_else (match_operator 1 "ix86_comparison_operator"
13123 [(reg 17) (const_int 0)])
13124 (pc)
13125 (label_ref (match_operand 0 "" ""))))]
13126 ""
13127 "%+j%c1\t%l0"
13128 [(set_attr "type" "ibr")
13129 (set_attr "modrm" "0")
13130 (set (attr "length")
13131 (if_then_else (and (ge (minus (match_dup 0) (pc))
13132 (const_int -128))
13133 (lt (minus (match_dup 0) (pc))
13134 (const_int 124)))
13135 (const_int 2)
13136 (const_int 6)))])
13137
13138 ;; In general it is not safe to assume too much about CCmode registers,
13139 ;; so simplify-rtx stops when it sees a second one. Under certain
13140 ;; conditions this is safe on x86, so help combine not create
13141 ;;
13142 ;; seta %al
13143 ;; testb %al, %al
13144 ;; je Lfoo
13145
13146 (define_split
13147 [(set (pc)
13148 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13149 [(reg 17) (const_int 0)])
13150 (const_int 0))
13151 (label_ref (match_operand 1 "" ""))
13152 (pc)))]
13153 ""
13154 [(set (pc)
13155 (if_then_else (match_dup 0)
13156 (label_ref (match_dup 1))
13157 (pc)))]
13158 {
13159 PUT_MODE (operands[0], VOIDmode);
13160 })
13161
13162 (define_split
13163 [(set (pc)
13164 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13165 [(reg 17) (const_int 0)])
13166 (const_int 0))
13167 (label_ref (match_operand 1 "" ""))
13168 (pc)))]
13169 ""
13170 [(set (pc)
13171 (if_then_else (match_dup 0)
13172 (label_ref (match_dup 1))
13173 (pc)))]
13174 {
13175 rtx new_op0 = copy_rtx (operands[0]);
13176 operands[0] = new_op0;
13177 PUT_MODE (new_op0, VOIDmode);
13178 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13179 GET_MODE (XEXP (new_op0, 0))));
13180
13181 /* Make sure that (a) the CCmode we have for the flags is strong
13182 enough for the reversed compare or (b) we have a valid FP compare. */
13183 if (! ix86_comparison_operator (new_op0, VOIDmode))
13184 FAIL;
13185 })
13186
13187 ;; Define combination compare-and-branch fp compare instructions to use
13188 ;; during early optimization. Splitting the operation apart early makes
13189 ;; for bad code when we want to reverse the operation.
13190
13191 (define_insn "*fp_jcc_1"
13192 [(set (pc)
13193 (if_then_else (match_operator 0 "comparison_operator"
13194 [(match_operand 1 "register_operand" "f")
13195 (match_operand 2 "register_operand" "f")])
13196 (label_ref (match_operand 3 "" ""))
13197 (pc)))
13198 (clobber (reg:CCFP 18))
13199 (clobber (reg:CCFP 17))]
13200 "TARGET_CMOVE && TARGET_80387
13201 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13202 && FLOAT_MODE_P (GET_MODE (operands[1]))
13203 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13204 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13205 "#")
13206
13207 (define_insn "*fp_jcc_1_sse"
13208 [(set (pc)
13209 (if_then_else (match_operator 0 "comparison_operator"
13210 [(match_operand 1 "register_operand" "f#x,x#f")
13211 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13212 (label_ref (match_operand 3 "" ""))
13213 (pc)))
13214 (clobber (reg:CCFP 18))
13215 (clobber (reg:CCFP 17))]
13216 "TARGET_80387
13217 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13218 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13219 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13220 "#")
13221
13222 (define_insn "*fp_jcc_1_sse_only"
13223 [(set (pc)
13224 (if_then_else (match_operator 0 "comparison_operator"
13225 [(match_operand 1 "register_operand" "x")
13226 (match_operand 2 "nonimmediate_operand" "xm")])
13227 (label_ref (match_operand 3 "" ""))
13228 (pc)))
13229 (clobber (reg:CCFP 18))
13230 (clobber (reg:CCFP 17))]
13231 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13232 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13233 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13234 "#")
13235
13236 (define_insn "*fp_jcc_2"
13237 [(set (pc)
13238 (if_then_else (match_operator 0 "comparison_operator"
13239 [(match_operand 1 "register_operand" "f")
13240 (match_operand 2 "register_operand" "f")])
13241 (pc)
13242 (label_ref (match_operand 3 "" ""))))
13243 (clobber (reg:CCFP 18))
13244 (clobber (reg:CCFP 17))]
13245 "TARGET_CMOVE && TARGET_80387
13246 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13247 && FLOAT_MODE_P (GET_MODE (operands[1]))
13248 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13249 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13250 "#")
13251
13252 (define_insn "*fp_jcc_2_sse"
13253 [(set (pc)
13254 (if_then_else (match_operator 0 "comparison_operator"
13255 [(match_operand 1 "register_operand" "f#x,x#f")
13256 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13257 (pc)
13258 (label_ref (match_operand 3 "" ""))))
13259 (clobber (reg:CCFP 18))
13260 (clobber (reg:CCFP 17))]
13261 "TARGET_80387
13262 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13263 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13264 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13265 "#")
13266
13267 (define_insn "*fp_jcc_2_sse_only"
13268 [(set (pc)
13269 (if_then_else (match_operator 0 "comparison_operator"
13270 [(match_operand 1 "register_operand" "x")
13271 (match_operand 2 "nonimmediate_operand" "xm")])
13272 (pc)
13273 (label_ref (match_operand 3 "" ""))))
13274 (clobber (reg:CCFP 18))
13275 (clobber (reg:CCFP 17))]
13276 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13277 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13278 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13279 "#")
13280
13281 (define_insn "*fp_jcc_3"
13282 [(set (pc)
13283 (if_then_else (match_operator 0 "comparison_operator"
13284 [(match_operand 1 "register_operand" "f")
13285 (match_operand 2 "nonimmediate_operand" "fm")])
13286 (label_ref (match_operand 3 "" ""))
13287 (pc)))
13288 (clobber (reg:CCFP 18))
13289 (clobber (reg:CCFP 17))
13290 (clobber (match_scratch:HI 4 "=a"))]
13291 "TARGET_80387
13292 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13293 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13294 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13295 && SELECT_CC_MODE (GET_CODE (operands[0]),
13296 operands[1], operands[2]) == CCFPmode
13297 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13298 "#")
13299
13300 (define_insn "*fp_jcc_4"
13301 [(set (pc)
13302 (if_then_else (match_operator 0 "comparison_operator"
13303 [(match_operand 1 "register_operand" "f")
13304 (match_operand 2 "nonimmediate_operand" "fm")])
13305 (pc)
13306 (label_ref (match_operand 3 "" ""))))
13307 (clobber (reg:CCFP 18))
13308 (clobber (reg:CCFP 17))
13309 (clobber (match_scratch:HI 4 "=a"))]
13310 "TARGET_80387
13311 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13312 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13313 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13314 && SELECT_CC_MODE (GET_CODE (operands[0]),
13315 operands[1], operands[2]) == CCFPmode
13316 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13317 "#")
13318
13319 (define_insn "*fp_jcc_5"
13320 [(set (pc)
13321 (if_then_else (match_operator 0 "comparison_operator"
13322 [(match_operand 1 "register_operand" "f")
13323 (match_operand 2 "register_operand" "f")])
13324 (label_ref (match_operand 3 "" ""))
13325 (pc)))
13326 (clobber (reg:CCFP 18))
13327 (clobber (reg:CCFP 17))
13328 (clobber (match_scratch:HI 4 "=a"))]
13329 "TARGET_80387
13330 && FLOAT_MODE_P (GET_MODE (operands[1]))
13331 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13332 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13333 "#")
13334
13335 (define_insn "*fp_jcc_6"
13336 [(set (pc)
13337 (if_then_else (match_operator 0 "comparison_operator"
13338 [(match_operand 1 "register_operand" "f")
13339 (match_operand 2 "register_operand" "f")])
13340 (pc)
13341 (label_ref (match_operand 3 "" ""))))
13342 (clobber (reg:CCFP 18))
13343 (clobber (reg:CCFP 17))
13344 (clobber (match_scratch:HI 4 "=a"))]
13345 "TARGET_80387
13346 && FLOAT_MODE_P (GET_MODE (operands[1]))
13347 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13348 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13349 "#")
13350
13351 (define_split
13352 [(set (pc)
13353 (if_then_else (match_operator 0 "comparison_operator"
13354 [(match_operand 1 "register_operand" "")
13355 (match_operand 2 "nonimmediate_operand" "")])
13356 (match_operand 3 "" "")
13357 (match_operand 4 "" "")))
13358 (clobber (reg:CCFP 18))
13359 (clobber (reg:CCFP 17))]
13360 "reload_completed"
13361 [(const_int 0)]
13362 {
13363 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13364 operands[3], operands[4], NULL_RTX);
13365 DONE;
13366 })
13367
13368 (define_split
13369 [(set (pc)
13370 (if_then_else (match_operator 0 "comparison_operator"
13371 [(match_operand 1 "register_operand" "")
13372 (match_operand 2 "nonimmediate_operand" "")])
13373 (match_operand 3 "" "")
13374 (match_operand 4 "" "")))
13375 (clobber (reg:CCFP 18))
13376 (clobber (reg:CCFP 17))
13377 (clobber (match_scratch:HI 5 "=a"))]
13378 "reload_completed"
13379 [(set (pc)
13380 (if_then_else (match_dup 6)
13381 (match_dup 3)
13382 (match_dup 4)))]
13383 {
13384 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13385 operands[3], operands[4], operands[5]);
13386 DONE;
13387 })
13388 \f
13389 ;; Unconditional and other jump instructions
13390
13391 (define_insn "jump"
13392 [(set (pc)
13393 (label_ref (match_operand 0 "" "")))]
13394 ""
13395 "jmp\t%l0"
13396 [(set_attr "type" "ibr")
13397 (set (attr "length")
13398 (if_then_else (and (ge (minus (match_dup 0) (pc))
13399 (const_int -128))
13400 (lt (minus (match_dup 0) (pc))
13401 (const_int 124)))
13402 (const_int 2)
13403 (const_int 5)))
13404 (set_attr "modrm" "0")])
13405
13406 (define_expand "indirect_jump"
13407 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13408 ""
13409 "")
13410
13411 (define_insn "*indirect_jump"
13412 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13413 "!TARGET_64BIT"
13414 "jmp\t%A0"
13415 [(set_attr "type" "ibr")
13416 (set_attr "length_immediate" "0")])
13417
13418 (define_insn "*indirect_jump_rtx64"
13419 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13420 "TARGET_64BIT"
13421 "jmp\t%A0"
13422 [(set_attr "type" "ibr")
13423 (set_attr "length_immediate" "0")])
13424
13425 (define_expand "tablejump"
13426 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13427 (use (label_ref (match_operand 1 "" "")))])]
13428 ""
13429 {
13430 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13431 relative. Convert the relative address to an absolute address. */
13432 if (flag_pic)
13433 {
13434 rtx op0, op1;
13435 enum rtx_code code;
13436
13437 if (TARGET_64BIT)
13438 {
13439 code = PLUS;
13440 op0 = operands[0];
13441 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13442 }
13443 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13444 {
13445 code = PLUS;
13446 op0 = operands[0];
13447 op1 = pic_offset_table_rtx;
13448 }
13449 else
13450 {
13451 code = MINUS;
13452 op0 = pic_offset_table_rtx;
13453 op1 = operands[0];
13454 }
13455
13456 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13457 OPTAB_DIRECT);
13458 }
13459 })
13460
13461 (define_insn "*tablejump_1"
13462 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13463 (use (label_ref (match_operand 1 "" "")))]
13464 "!TARGET_64BIT"
13465 "jmp\t%A0"
13466 [(set_attr "type" "ibr")
13467 (set_attr "length_immediate" "0")])
13468
13469 (define_insn "*tablejump_1_rtx64"
13470 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13471 (use (label_ref (match_operand 1 "" "")))]
13472 "TARGET_64BIT"
13473 "jmp\t%A0"
13474 [(set_attr "type" "ibr")
13475 (set_attr "length_immediate" "0")])
13476 \f
13477 ;; Loop instruction
13478 ;;
13479 ;; This is all complicated by the fact that since this is a jump insn
13480 ;; we must handle our own reloads.
13481
13482 (define_expand "doloop_end"
13483 [(use (match_operand 0 "" "")) ; loop pseudo
13484 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13485 (use (match_operand 2 "" "")) ; max iterations
13486 (use (match_operand 3 "" "")) ; loop level
13487 (use (match_operand 4 "" ""))] ; label
13488 "!TARGET_64BIT && TARGET_USE_LOOP"
13489 "
13490 {
13491 /* Only use cloop on innermost loops. */
13492 if (INTVAL (operands[3]) > 1)
13493 FAIL;
13494 if (GET_MODE (operands[0]) != SImode)
13495 FAIL;
13496 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13497 operands[0]));
13498 DONE;
13499 }")
13500
13501 (define_insn "doloop_end_internal"
13502 [(set (pc)
13503 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13504 (const_int 1))
13505 (label_ref (match_operand 0 "" ""))
13506 (pc)))
13507 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13508 (plus:SI (match_dup 1)
13509 (const_int -1)))
13510 (clobber (match_scratch:SI 3 "=X,X,r"))
13511 (clobber (reg:CC 17))]
13512 "!TARGET_64BIT && TARGET_USE_LOOP"
13513 {
13514 if (which_alternative != 0)
13515 return "#";
13516 if (get_attr_length (insn) == 2)
13517 return "%+loop\t%l0";
13518 else
13519 return "dec{l}\t%1\;%+jne\t%l0";
13520 }
13521 [(set_attr "ppro_uops" "many")
13522 (set (attr "length")
13523 (if_then_else (and (eq_attr "alternative" "0")
13524 (and (ge (minus (match_dup 0) (pc))
13525 (const_int -128))
13526 (lt (minus (match_dup 0) (pc))
13527 (const_int 124))))
13528 (const_int 2)
13529 (const_int 16)))
13530 ;; We don't know the type before shorten branches. Optimistically expect
13531 ;; the loop instruction to match.
13532 (set (attr "type") (const_string "ibr"))])
13533
13534 (define_split
13535 [(set (pc)
13536 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13537 (const_int 1))
13538 (match_operand 0 "" "")
13539 (pc)))
13540 (set (match_dup 1)
13541 (plus:SI (match_dup 1)
13542 (const_int -1)))
13543 (clobber (match_scratch:SI 2 ""))
13544 (clobber (reg:CC 17))]
13545 "!TARGET_64BIT && TARGET_USE_LOOP
13546 && reload_completed
13547 && REGNO (operands[1]) != 2"
13548 [(parallel [(set (reg:CCZ 17)
13549 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13550 (const_int 0)))
13551 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13552 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13553 (match_dup 0)
13554 (pc)))]
13555 "")
13556
13557 (define_split
13558 [(set (pc)
13559 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13560 (const_int 1))
13561 (match_operand 0 "" "")
13562 (pc)))
13563 (set (match_operand:SI 2 "nonimmediate_operand" "")
13564 (plus:SI (match_dup 1)
13565 (const_int -1)))
13566 (clobber (match_scratch:SI 3 ""))
13567 (clobber (reg:CC 17))]
13568 "!TARGET_64BIT && TARGET_USE_LOOP
13569 && reload_completed
13570 && (! REG_P (operands[2])
13571 || ! rtx_equal_p (operands[1], operands[2]))"
13572 [(set (match_dup 3) (match_dup 1))
13573 (parallel [(set (reg:CCZ 17)
13574 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13575 (const_int 0)))
13576 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13577 (set (match_dup 2) (match_dup 3))
13578 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13579 (match_dup 0)
13580 (pc)))]
13581 "")
13582
13583 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13584
13585 (define_peephole2
13586 [(set (reg 17) (match_operand 0 "" ""))
13587 (set (match_operand:QI 1 "register_operand" "")
13588 (match_operator:QI 2 "ix86_comparison_operator"
13589 [(reg 17) (const_int 0)]))
13590 (set (match_operand 3 "q_regs_operand" "")
13591 (zero_extend (match_dup 1)))]
13592 "(peep2_reg_dead_p (3, operands[1])
13593 || operands_match_p (operands[1], operands[3]))
13594 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13595 [(set (match_dup 4) (match_dup 0))
13596 (set (strict_low_part (match_dup 5))
13597 (match_dup 2))]
13598 {
13599 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13600 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13601 ix86_expand_clear (operands[3]);
13602 })
13603
13604 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13605
13606 (define_peephole2
13607 [(set (reg 17) (match_operand 0 "" ""))
13608 (set (match_operand:QI 1 "register_operand" "")
13609 (match_operator:QI 2 "ix86_comparison_operator"
13610 [(reg 17) (const_int 0)]))
13611 (parallel [(set (match_operand 3 "q_regs_operand" "")
13612 (zero_extend (match_dup 1)))
13613 (clobber (reg:CC 17))])]
13614 "(peep2_reg_dead_p (3, operands[1])
13615 || operands_match_p (operands[1], operands[3]))
13616 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13617 [(set (match_dup 4) (match_dup 0))
13618 (set (strict_low_part (match_dup 5))
13619 (match_dup 2))]
13620 {
13621 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13622 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13623 ix86_expand_clear (operands[3]);
13624 })
13625 \f
13626 ;; Call instructions.
13627
13628 ;; The predicates normally associated with named expanders are not properly
13629 ;; checked for calls. This is a bug in the generic code, but it isn't that
13630 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13631
13632 ;; Call subroutine returning no value.
13633
13634 (define_expand "call_pop"
13635 [(parallel [(call (match_operand:QI 0 "" "")
13636 (match_operand:SI 1 "" ""))
13637 (set (reg:SI 7)
13638 (plus:SI (reg:SI 7)
13639 (match_operand:SI 3 "" "")))])]
13640 "!TARGET_64BIT"
13641 {
13642 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13643 DONE;
13644 })
13645
13646 (define_insn "*call_pop_0"
13647 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13648 (match_operand:SI 1 "" ""))
13649 (set (reg:SI 7) (plus:SI (reg:SI 7)
13650 (match_operand:SI 2 "immediate_operand" "")))]
13651 "!TARGET_64BIT"
13652 {
13653 if (SIBLING_CALL_P (insn))
13654 return "jmp\t%P0";
13655 else
13656 return "call\t%P0";
13657 }
13658 [(set_attr "type" "call")])
13659
13660 (define_insn "*call_pop_1"
13661 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13662 (match_operand:SI 1 "" ""))
13663 (set (reg:SI 7) (plus:SI (reg:SI 7)
13664 (match_operand:SI 2 "immediate_operand" "i")))]
13665 "!TARGET_64BIT"
13666 {
13667 if (constant_call_address_operand (operands[0], Pmode))
13668 {
13669 if (SIBLING_CALL_P (insn))
13670 return "jmp\t%P0";
13671 else
13672 return "call\t%P0";
13673 }
13674 if (SIBLING_CALL_P (insn))
13675 return "jmp\t%A0";
13676 else
13677 return "call\t%A0";
13678 }
13679 [(set_attr "type" "call")])
13680
13681 (define_expand "call"
13682 [(call (match_operand:QI 0 "" "")
13683 (match_operand 1 "" ""))
13684 (use (match_operand 2 "" ""))]
13685 ""
13686 {
13687 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13688 DONE;
13689 })
13690
13691 (define_expand "sibcall"
13692 [(call (match_operand:QI 0 "" "")
13693 (match_operand 1 "" ""))
13694 (use (match_operand 2 "" ""))]
13695 ""
13696 {
13697 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13698 DONE;
13699 })
13700
13701 (define_insn "*call_0"
13702 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13703 (match_operand 1 "" ""))]
13704 ""
13705 {
13706 if (SIBLING_CALL_P (insn))
13707 return "jmp\t%P0";
13708 else
13709 return "call\t%P0";
13710 }
13711 [(set_attr "type" "call")])
13712
13713 (define_insn "*call_1"
13714 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13715 (match_operand 1 "" ""))]
13716 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13717 {
13718 if (constant_call_address_operand (operands[0], QImode))
13719 return "call\t%P0";
13720 return "call\t%A0";
13721 }
13722 [(set_attr "type" "call")])
13723
13724 (define_insn "*sibcall_1"
13725 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13726 (match_operand 1 "" ""))]
13727 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13728 {
13729 if (constant_call_address_operand (operands[0], QImode))
13730 return "jmp\t%P0";
13731 return "jmp\t%A0";
13732 }
13733 [(set_attr "type" "call")])
13734
13735 (define_insn "*call_1_rex64"
13736 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13737 (match_operand 1 "" ""))]
13738 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13739 {
13740 if (constant_call_address_operand (operands[0], QImode))
13741 return "call\t%P0";
13742 return "call\t%A0";
13743 }
13744 [(set_attr "type" "call")])
13745
13746 (define_insn "*sibcall_1_rex64"
13747 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13748 (match_operand 1 "" ""))]
13749 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13750 "jmp\t%P0"
13751 [(set_attr "type" "call")])
13752
13753 (define_insn "*sibcall_1_rex64_v"
13754 [(call (mem:QI (reg:DI 40))
13755 (match_operand 0 "" ""))]
13756 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13757 "jmp\t*%%r11"
13758 [(set_attr "type" "call")])
13759
13760
13761 ;; Call subroutine, returning value in operand 0
13762
13763 (define_expand "call_value_pop"
13764 [(parallel [(set (match_operand 0 "" "")
13765 (call (match_operand:QI 1 "" "")
13766 (match_operand:SI 2 "" "")))
13767 (set (reg:SI 7)
13768 (plus:SI (reg:SI 7)
13769 (match_operand:SI 4 "" "")))])]
13770 "!TARGET_64BIT"
13771 {
13772 ix86_expand_call (operands[0], operands[1], operands[2],
13773 operands[3], operands[4], 0);
13774 DONE;
13775 })
13776
13777 (define_expand "call_value"
13778 [(set (match_operand 0 "" "")
13779 (call (match_operand:QI 1 "" "")
13780 (match_operand:SI 2 "" "")))
13781 (use (match_operand:SI 3 "" ""))]
13782 ;; Operand 2 not used on the i386.
13783 ""
13784 {
13785 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13786 DONE;
13787 })
13788
13789 (define_expand "sibcall_value"
13790 [(set (match_operand 0 "" "")
13791 (call (match_operand:QI 1 "" "")
13792 (match_operand:SI 2 "" "")))
13793 (use (match_operand:SI 3 "" ""))]
13794 ;; Operand 2 not used on the i386.
13795 ""
13796 {
13797 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13798 DONE;
13799 })
13800
13801 ;; Call subroutine returning any type.
13802
13803 (define_expand "untyped_call"
13804 [(parallel [(call (match_operand 0 "" "")
13805 (const_int 0))
13806 (match_operand 1 "" "")
13807 (match_operand 2 "" "")])]
13808 ""
13809 {
13810 int i;
13811
13812 /* In order to give reg-stack an easier job in validating two
13813 coprocessor registers as containing a possible return value,
13814 simply pretend the untyped call returns a complex long double
13815 value. */
13816
13817 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13818 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13819 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13820 NULL, 0);
13821
13822 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13823 {
13824 rtx set = XVECEXP (operands[2], 0, i);
13825 emit_move_insn (SET_DEST (set), SET_SRC (set));
13826 }
13827
13828 /* The optimizer does not know that the call sets the function value
13829 registers we stored in the result block. We avoid problems by
13830 claiming that all hard registers are used and clobbered at this
13831 point. */
13832 emit_insn (gen_blockage (const0_rtx));
13833
13834 DONE;
13835 })
13836 \f
13837 ;; Prologue and epilogue instructions
13838
13839 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13840 ;; all of memory. This blocks insns from being moved across this point.
13841
13842 (define_insn "blockage"
13843 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13844 ""
13845 ""
13846 [(set_attr "length" "0")])
13847
13848 ;; Insn emitted into the body of a function to return from a function.
13849 ;; This is only done if the function's epilogue is known to be simple.
13850 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13851
13852 (define_expand "return"
13853 [(return)]
13854 "ix86_can_use_return_insn_p ()"
13855 {
13856 if (current_function_pops_args)
13857 {
13858 rtx popc = GEN_INT (current_function_pops_args);
13859 emit_jump_insn (gen_return_pop_internal (popc));
13860 DONE;
13861 }
13862 })
13863
13864 (define_insn "return_internal"
13865 [(return)]
13866 "reload_completed"
13867 "ret"
13868 [(set_attr "length" "1")
13869 (set_attr "length_immediate" "0")
13870 (set_attr "modrm" "0")])
13871
13872 (define_insn "return_pop_internal"
13873 [(return)
13874 (use (match_operand:SI 0 "const_int_operand" ""))]
13875 "reload_completed"
13876 "ret\t%0"
13877 [(set_attr "length" "3")
13878 (set_attr "length_immediate" "2")
13879 (set_attr "modrm" "0")])
13880
13881 (define_insn "return_indirect_internal"
13882 [(return)
13883 (use (match_operand:SI 0 "register_operand" "r"))]
13884 "reload_completed"
13885 "jmp\t%A0"
13886 [(set_attr "type" "ibr")
13887 (set_attr "length_immediate" "0")])
13888
13889 (define_insn "nop"
13890 [(const_int 0)]
13891 ""
13892 "nop"
13893 [(set_attr "length" "1")
13894 (set_attr "length_immediate" "0")
13895 (set_attr "modrm" "0")
13896 (set_attr "ppro_uops" "one")])
13897
13898 (define_expand "prologue"
13899 [(const_int 1)]
13900 ""
13901 "ix86_expand_prologue (); DONE;")
13902
13903 (define_insn "set_got"
13904 [(set (match_operand:SI 0 "register_operand" "=r")
13905 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13906 (clobber (reg:CC 17))]
13907 "!TARGET_64BIT"
13908 { return output_set_got (operands[0]); }
13909 [(set_attr "type" "multi")
13910 (set_attr "length" "12")])
13911
13912 (define_expand "epilogue"
13913 [(const_int 1)]
13914 ""
13915 "ix86_expand_epilogue (1); DONE;")
13916
13917 (define_expand "sibcall_epilogue"
13918 [(const_int 1)]
13919 ""
13920 "ix86_expand_epilogue (0); DONE;")
13921
13922 (define_expand "eh_return"
13923 [(use (match_operand 0 "register_operand" ""))
13924 (use (match_operand 1 "register_operand" ""))]
13925 ""
13926 {
13927 rtx tmp, sa = operands[0], ra = operands[1];
13928
13929 /* Tricky bit: we write the address of the handler to which we will
13930 be returning into someone else's stack frame, one word below the
13931 stack address we wish to restore. */
13932 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13933 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13934 tmp = gen_rtx_MEM (Pmode, tmp);
13935 emit_move_insn (tmp, ra);
13936
13937 if (Pmode == SImode)
13938 emit_insn (gen_eh_return_si (sa));
13939 else
13940 emit_insn (gen_eh_return_di (sa));
13941 emit_barrier ();
13942 DONE;
13943 })
13944
13945 (define_insn_and_split "eh_return_si"
13946 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13947 UNSPECV_EH_RETURN)]
13948 "!TARGET_64BIT"
13949 "#"
13950 "reload_completed"
13951 [(const_int 1)]
13952 "ix86_expand_epilogue (2); DONE;")
13953
13954 (define_insn_and_split "eh_return_di"
13955 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13956 UNSPECV_EH_RETURN)]
13957 "TARGET_64BIT"
13958 "#"
13959 "reload_completed"
13960 [(const_int 1)]
13961 "ix86_expand_epilogue (2); DONE;")
13962
13963 (define_insn "leave"
13964 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13965 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13966 (clobber (mem:BLK (scratch)))]
13967 "!TARGET_64BIT"
13968 "leave"
13969 [(set_attr "type" "leave")])
13970
13971 (define_insn "leave_rex64"
13972 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13973 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13974 (clobber (mem:BLK (scratch)))]
13975 "TARGET_64BIT"
13976 "leave"
13977 [(set_attr "type" "leave")])
13978 \f
13979 (define_expand "ffssi2"
13980 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13981 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13982 ""
13983 {
13984 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13985 rtx in = operands[1];
13986
13987 if (TARGET_CMOVE)
13988 {
13989 emit_move_insn (tmp, constm1_rtx);
13990 emit_insn (gen_ffssi_1 (out, in));
13991 emit_insn (gen_rtx_SET (VOIDmode, out,
13992 gen_rtx_IF_THEN_ELSE (SImode,
13993 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13994 const0_rtx),
13995 tmp,
13996 out)));
13997 emit_insn (gen_addsi3 (out, out, const1_rtx));
13998 emit_move_insn (operands[0], out);
13999 }
14000
14001 /* Pentium bsf instruction is extremly slow. The following code is
14002 recommended by the Intel Optimizing Manual as a reasonable replacement:
14003 TEST EAX,EAX
14004 JZ SHORT BS2
14005 XOR ECX,ECX
14006 MOV DWORD PTR [TEMP+4],ECX
14007 SUB ECX,EAX
14008 AND EAX,ECX
14009 MOV DWORD PTR [TEMP],EAX
14010 FILD QWORD PTR [TEMP]
14011 FSTP QWORD PTR [TEMP]
14012 WAIT ; WAIT only needed for compatibility with
14013 ; earlier processors
14014 MOV ECX, DWORD PTR [TEMP+4]
14015 SHR ECX,20
14016 SUB ECX,3FFH
14017 TEST EAX,EAX ; clear zero flag
14018 BS2:
14019 Following piece of code expand ffs to similar beast.
14020 */
14021
14022 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
14023 {
14024 rtx label = gen_label_rtx ();
14025 rtx lo, hi;
14026 rtx mem = assign_386_stack_local (DImode, 0);
14027 rtx fptmp = gen_reg_rtx (DFmode);
14028 split_di (&mem, 1, &lo, &hi);
14029
14030 emit_move_insn (out, const0_rtx);
14031
14032 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
14033
14034 emit_move_insn (hi, out);
14035 emit_insn (gen_subsi3 (out, out, in));
14036 emit_insn (gen_andsi3 (out, out, in));
14037 emit_move_insn (lo, out);
14038 emit_insn (gen_floatdidf2 (fptmp,mem));
14039 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
14040 emit_move_insn (out, hi);
14041 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
14042 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
14043
14044 emit_label (label);
14045 LABEL_NUSES (label) = 1;
14046
14047 emit_move_insn (operands[0], out);
14048 }
14049 else
14050 {
14051 emit_move_insn (tmp, const0_rtx);
14052 emit_insn (gen_ffssi_1 (out, in));
14053 emit_insn (gen_rtx_SET (VOIDmode,
14054 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
14055 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
14056 const0_rtx)));
14057 emit_insn (gen_negsi2 (tmp, tmp));
14058 emit_insn (gen_iorsi3 (out, out, tmp));
14059 emit_insn (gen_addsi3 (out, out, const1_rtx));
14060 emit_move_insn (operands[0], out);
14061 }
14062 DONE;
14063 })
14064
14065 (define_insn "ffssi_1"
14066 [(set (reg:CCZ 17)
14067 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14068 (const_int 0)))
14069 (set (match_operand:SI 0 "register_operand" "=r")
14070 (unspec:SI [(match_dup 1)] UNSPEC_BSF))]
14071 ""
14072 "bsf{l}\t{%1, %0|%0, %1}"
14073 [(set_attr "prefix_0f" "1")
14074 (set_attr "ppro_uops" "few")])
14075
14076 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
14077 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
14078 \f
14079 ;; Thread-local storage patterns for ELF.
14080 ;;
14081 ;; Note that these code sequences must appear exactly as shown
14082 ;; in order to allow linker relaxation.
14083
14084 (define_insn "*tls_global_dynamic_32_gnu"
14085 [(set (match_operand:SI 0 "register_operand" "=a")
14086 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14087 (match_operand:SI 2 "tls_symbolic_operand" "")
14088 (match_operand:SI 3 "call_insn_operand" "")]
14089 UNSPEC_TLS_GD))
14090 (clobber (match_scratch:SI 4 "=d"))
14091 (clobber (match_scratch:SI 5 "=c"))
14092 (clobber (reg:CC 17))]
14093 "!TARGET_64BIT && TARGET_GNU_TLS"
14094 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14095 [(set_attr "type" "multi")
14096 (set_attr "length" "12")])
14097
14098 (define_insn "*tls_global_dynamic_32_sun"
14099 [(set (match_operand:SI 0 "register_operand" "=a")
14100 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14101 (match_operand:SI 2 "tls_symbolic_operand" "")
14102 (match_operand:SI 3 "call_insn_operand" "")]
14103 UNSPEC_TLS_GD))
14104 (clobber (match_scratch:SI 4 "=d"))
14105 (clobber (match_scratch:SI 5 "=c"))
14106 (clobber (reg:CC 17))]
14107 "!TARGET_64BIT && TARGET_SUN_TLS"
14108 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14109 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14110 [(set_attr "type" "multi")
14111 (set_attr "length" "14")])
14112
14113 (define_expand "tls_global_dynamic_32"
14114 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14115 (unspec:SI
14116 [(match_dup 2)
14117 (match_operand:SI 1 "tls_symbolic_operand" "")
14118 (match_dup 3)]
14119 UNSPEC_TLS_GD))
14120 (clobber (match_scratch:SI 4 ""))
14121 (clobber (match_scratch:SI 5 ""))
14122 (clobber (reg:CC 17))])]
14123 ""
14124 {
14125 if (flag_pic)
14126 operands[2] = pic_offset_table_rtx;
14127 else
14128 {
14129 operands[2] = gen_reg_rtx (Pmode);
14130 emit_insn (gen_set_got (operands[2]));
14131 }
14132 operands[3] = ix86_tls_get_addr ();
14133 })
14134
14135 (define_insn "*tls_global_dynamic_64"
14136 [(set (match_operand:DI 0 "register_operand" "=a")
14137 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14138 (match_operand:DI 3 "" "")))
14139 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14140 UNSPEC_TLS_GD)]
14141 "TARGET_64BIT"
14142 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14143 [(set_attr "type" "multi")
14144 (set_attr "length" "16")])
14145
14146 (define_expand "tls_global_dynamic_64"
14147 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14148 (call (mem:QI (match_dup 2)) (const_int 0)))
14149 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14150 UNSPEC_TLS_GD)])]
14151 ""
14152 {
14153 operands[2] = ix86_tls_get_addr ();
14154 })
14155
14156 (define_insn "*tls_local_dynamic_base_32_gnu"
14157 [(set (match_operand:SI 0 "register_operand" "=a")
14158 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14159 (match_operand:SI 2 "call_insn_operand" "")]
14160 UNSPEC_TLS_LD_BASE))
14161 (clobber (match_scratch:SI 3 "=d"))
14162 (clobber (match_scratch:SI 4 "=c"))
14163 (clobber (reg:CC 17))]
14164 "!TARGET_64BIT && TARGET_GNU_TLS"
14165 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14166 [(set_attr "type" "multi")
14167 (set_attr "length" "11")])
14168
14169 (define_insn "*tls_local_dynamic_base_32_sun"
14170 [(set (match_operand:SI 0 "register_operand" "=a")
14171 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14172 (match_operand:SI 2 "call_insn_operand" "")]
14173 UNSPEC_TLS_LD_BASE))
14174 (clobber (match_scratch:SI 3 "=d"))
14175 (clobber (match_scratch:SI 4 "=c"))
14176 (clobber (reg:CC 17))]
14177 "!TARGET_64BIT && TARGET_SUN_TLS"
14178 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14179 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14180 [(set_attr "type" "multi")
14181 (set_attr "length" "13")])
14182
14183 (define_expand "tls_local_dynamic_base_32"
14184 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14185 (unspec:SI [(match_dup 1) (match_dup 2)]
14186 UNSPEC_TLS_LD_BASE))
14187 (clobber (match_scratch:SI 3 ""))
14188 (clobber (match_scratch:SI 4 ""))
14189 (clobber (reg:CC 17))])]
14190 ""
14191 {
14192 if (flag_pic)
14193 operands[1] = pic_offset_table_rtx;
14194 else
14195 {
14196 operands[1] = gen_reg_rtx (Pmode);
14197 emit_insn (gen_set_got (operands[1]));
14198 }
14199 operands[2] = ix86_tls_get_addr ();
14200 })
14201
14202 (define_insn "*tls_local_dynamic_base_64"
14203 [(set (match_operand:DI 0 "register_operand" "=a")
14204 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14205 (match_operand:DI 2 "" "")))
14206 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14207 "TARGET_64BIT"
14208 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14209 [(set_attr "type" "multi")
14210 (set_attr "length" "12")])
14211
14212 (define_expand "tls_local_dynamic_base_64"
14213 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14214 (call (mem:QI (match_dup 1)) (const_int 0)))
14215 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14216 ""
14217 {
14218 operands[1] = ix86_tls_get_addr ();
14219 })
14220
14221 ;; Local dynamic of a single variable is a lose. Show combine how
14222 ;; to convert that back to global dynamic.
14223
14224 (define_insn_and_split "*tls_local_dynamic_32_once"
14225 [(set (match_operand:SI 0 "register_operand" "=a")
14226 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14227 (match_operand:SI 2 "call_insn_operand" "")]
14228 UNSPEC_TLS_LD_BASE)
14229 (const:SI (unspec:SI
14230 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14231 UNSPEC_DTPOFF))))
14232 (clobber (match_scratch:SI 4 "=d"))
14233 (clobber (match_scratch:SI 5 "=c"))
14234 (clobber (reg:CC 17))]
14235 ""
14236 "#"
14237 ""
14238 [(parallel [(set (match_dup 0)
14239 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14240 UNSPEC_TLS_GD))
14241 (clobber (match_dup 4))
14242 (clobber (match_dup 5))
14243 (clobber (reg:CC 17))])]
14244 "")
14245 \f
14246 ;; These patterns match the binary 387 instructions for addM3, subM3,
14247 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14248 ;; SFmode. The first is the normal insn, the second the same insn but
14249 ;; with one operand a conversion, and the third the same insn but with
14250 ;; the other operand a conversion. The conversion may be SFmode or
14251 ;; SImode if the target mode DFmode, but only SImode if the target mode
14252 ;; is SFmode.
14253
14254 ;; Gcc is slightly more smart about handling normal two address instructions
14255 ;; so use special patterns for add and mull.
14256 (define_insn "*fop_sf_comm_nosse"
14257 [(set (match_operand:SF 0 "register_operand" "=f")
14258 (match_operator:SF 3 "binary_fp_operator"
14259 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14260 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14261 "TARGET_80387 && !TARGET_SSE_MATH
14262 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14264 "* return output_387_binary_op (insn, operands);"
14265 [(set (attr "type")
14266 (if_then_else (match_operand:SF 3 "mult_operator" "")
14267 (const_string "fmul")
14268 (const_string "fop")))
14269 (set_attr "mode" "SF")])
14270
14271 (define_insn "*fop_sf_comm"
14272 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14273 (match_operator:SF 3 "binary_fp_operator"
14274 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14275 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14276 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14277 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14278 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14279 "* return output_387_binary_op (insn, operands);"
14280 [(set (attr "type")
14281 (if_then_else (eq_attr "alternative" "1")
14282 (if_then_else (match_operand:SF 3 "mult_operator" "")
14283 (const_string "ssemul")
14284 (const_string "sseadd"))
14285 (if_then_else (match_operand:SF 3 "mult_operator" "")
14286 (const_string "fmul")
14287 (const_string "fop"))))
14288 (set_attr "mode" "SF")])
14289
14290 (define_insn "*fop_sf_comm_sse"
14291 [(set (match_operand:SF 0 "register_operand" "=x")
14292 (match_operator:SF 3 "binary_fp_operator"
14293 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14294 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14295 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14296 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14297 "* return output_387_binary_op (insn, operands);"
14298 [(set (attr "type")
14299 (if_then_else (match_operand:SF 3 "mult_operator" "")
14300 (const_string "ssemul")
14301 (const_string "sseadd")))
14302 (set_attr "mode" "SF")])
14303
14304 (define_insn "*fop_df_comm_nosse"
14305 [(set (match_operand:DF 0 "register_operand" "=f")
14306 (match_operator:DF 3 "binary_fp_operator"
14307 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14308 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14309 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14310 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14311 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14312 "* return output_387_binary_op (insn, operands);"
14313 [(set (attr "type")
14314 (if_then_else (match_operand:SF 3 "mult_operator" "")
14315 (const_string "fmul")
14316 (const_string "fop")))
14317 (set_attr "mode" "DF")])
14318
14319 (define_insn "*fop_df_comm"
14320 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14321 (match_operator:DF 3 "binary_fp_operator"
14322 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14323 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14324 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14325 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14326 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14327 "* return output_387_binary_op (insn, operands);"
14328 [(set (attr "type")
14329 (if_then_else (eq_attr "alternative" "1")
14330 (if_then_else (match_operand:SF 3 "mult_operator" "")
14331 (const_string "ssemul")
14332 (const_string "sseadd"))
14333 (if_then_else (match_operand:SF 3 "mult_operator" "")
14334 (const_string "fmul")
14335 (const_string "fop"))))
14336 (set_attr "mode" "DF")])
14337
14338 (define_insn "*fop_df_comm_sse"
14339 [(set (match_operand:DF 0 "register_operand" "=Y")
14340 (match_operator:DF 3 "binary_fp_operator"
14341 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14342 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14343 "TARGET_SSE2 && TARGET_SSE_MATH
14344 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14345 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14346 "* return output_387_binary_op (insn, operands);"
14347 [(set (attr "type")
14348 (if_then_else (match_operand:SF 3 "mult_operator" "")
14349 (const_string "ssemul")
14350 (const_string "sseadd")))
14351 (set_attr "mode" "DF")])
14352
14353 (define_insn "*fop_xf_comm"
14354 [(set (match_operand:XF 0 "register_operand" "=f")
14355 (match_operator:XF 3 "binary_fp_operator"
14356 [(match_operand:XF 1 "register_operand" "%0")
14357 (match_operand:XF 2 "register_operand" "f")]))]
14358 "!TARGET_64BIT && TARGET_80387
14359 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14360 "* return output_387_binary_op (insn, operands);"
14361 [(set (attr "type")
14362 (if_then_else (match_operand:XF 3 "mult_operator" "")
14363 (const_string "fmul")
14364 (const_string "fop")))
14365 (set_attr "mode" "XF")])
14366
14367 (define_insn "*fop_tf_comm"
14368 [(set (match_operand:TF 0 "register_operand" "=f")
14369 (match_operator:TF 3 "binary_fp_operator"
14370 [(match_operand:TF 1 "register_operand" "%0")
14371 (match_operand:TF 2 "register_operand" "f")]))]
14372 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14373 "* return output_387_binary_op (insn, operands);"
14374 [(set (attr "type")
14375 (if_then_else (match_operand:TF 3 "mult_operator" "")
14376 (const_string "fmul")
14377 (const_string "fop")))
14378 (set_attr "mode" "XF")])
14379
14380 (define_insn "*fop_sf_1_nosse"
14381 [(set (match_operand:SF 0 "register_operand" "=f,f")
14382 (match_operator:SF 3 "binary_fp_operator"
14383 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14384 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14385 "TARGET_80387 && !TARGET_SSE_MATH
14386 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14387 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14388 "* return output_387_binary_op (insn, operands);"
14389 [(set (attr "type")
14390 (cond [(match_operand:SF 3 "mult_operator" "")
14391 (const_string "fmul")
14392 (match_operand:SF 3 "div_operator" "")
14393 (const_string "fdiv")
14394 ]
14395 (const_string "fop")))
14396 (set_attr "mode" "SF")])
14397
14398 (define_insn "*fop_sf_1"
14399 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14400 (match_operator:SF 3 "binary_fp_operator"
14401 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14402 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14403 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14404 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14405 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14406 "* return output_387_binary_op (insn, operands);"
14407 [(set (attr "type")
14408 (cond [(and (eq_attr "alternative" "2")
14409 (match_operand:SF 3 "mult_operator" ""))
14410 (const_string "ssemul")
14411 (and (eq_attr "alternative" "2")
14412 (match_operand:SF 3 "div_operator" ""))
14413 (const_string "ssediv")
14414 (eq_attr "alternative" "2")
14415 (const_string "sseadd")
14416 (match_operand:SF 3 "mult_operator" "")
14417 (const_string "fmul")
14418 (match_operand:SF 3 "div_operator" "")
14419 (const_string "fdiv")
14420 ]
14421 (const_string "fop")))
14422 (set_attr "mode" "SF")])
14423
14424 (define_insn "*fop_sf_1_sse"
14425 [(set (match_operand:SF 0 "register_operand" "=x")
14426 (match_operator:SF 3 "binary_fp_operator"
14427 [(match_operand:SF 1 "register_operand" "0")
14428 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14429 "TARGET_SSE_MATH
14430 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14431 "* return output_387_binary_op (insn, operands);"
14432 [(set (attr "type")
14433 (cond [(match_operand:SF 3 "mult_operator" "")
14434 (const_string "ssemul")
14435 (match_operand:SF 3 "div_operator" "")
14436 (const_string "ssediv")
14437 ]
14438 (const_string "sseadd")))
14439 (set_attr "mode" "SF")])
14440
14441 ;; ??? Add SSE splitters for these!
14442 (define_insn "*fop_sf_2"
14443 [(set (match_operand:SF 0 "register_operand" "=f,f")
14444 (match_operator:SF 3 "binary_fp_operator"
14445 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14446 (match_operand:SF 2 "register_operand" "0,0")]))]
14447 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14448 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14449 [(set (attr "type")
14450 (cond [(match_operand:SF 3 "mult_operator" "")
14451 (const_string "fmul")
14452 (match_operand:SF 3 "div_operator" "")
14453 (const_string "fdiv")
14454 ]
14455 (const_string "fop")))
14456 (set_attr "fp_int_src" "true")
14457 (set_attr "ppro_uops" "many")
14458 (set_attr "mode" "SI")])
14459
14460 (define_insn "*fop_sf_3"
14461 [(set (match_operand:SF 0 "register_operand" "=f,f")
14462 (match_operator:SF 3 "binary_fp_operator"
14463 [(match_operand:SF 1 "register_operand" "0,0")
14464 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14465 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14466 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14467 [(set (attr "type")
14468 (cond [(match_operand:SF 3 "mult_operator" "")
14469 (const_string "fmul")
14470 (match_operand:SF 3 "div_operator" "")
14471 (const_string "fdiv")
14472 ]
14473 (const_string "fop")))
14474 (set_attr "fp_int_src" "true")
14475 (set_attr "ppro_uops" "many")
14476 (set_attr "mode" "SI")])
14477
14478 (define_insn "*fop_df_1_nosse"
14479 [(set (match_operand:DF 0 "register_operand" "=f,f")
14480 (match_operator:DF 3 "binary_fp_operator"
14481 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14482 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14483 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14484 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14485 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14486 "* return output_387_binary_op (insn, operands);"
14487 [(set (attr "type")
14488 (cond [(match_operand:DF 3 "mult_operator" "")
14489 (const_string "fmul")
14490 (match_operand:DF 3 "div_operator" "")
14491 (const_string "fdiv")
14492 ]
14493 (const_string "fop")))
14494 (set_attr "mode" "DF")])
14495
14496
14497 (define_insn "*fop_df_1"
14498 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14499 (match_operator:DF 3 "binary_fp_operator"
14500 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14501 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14502 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14503 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14504 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14505 "* return output_387_binary_op (insn, operands);"
14506 [(set (attr "type")
14507 (cond [(and (eq_attr "alternative" "2")
14508 (match_operand:SF 3 "mult_operator" ""))
14509 (const_string "ssemul")
14510 (and (eq_attr "alternative" "2")
14511 (match_operand:SF 3 "div_operator" ""))
14512 (const_string "ssediv")
14513 (eq_attr "alternative" "2")
14514 (const_string "sseadd")
14515 (match_operand:DF 3 "mult_operator" "")
14516 (const_string "fmul")
14517 (match_operand:DF 3 "div_operator" "")
14518 (const_string "fdiv")
14519 ]
14520 (const_string "fop")))
14521 (set_attr "mode" "DF")])
14522
14523 (define_insn "*fop_df_1_sse"
14524 [(set (match_operand:DF 0 "register_operand" "=Y")
14525 (match_operator:DF 3 "binary_fp_operator"
14526 [(match_operand:DF 1 "register_operand" "0")
14527 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14528 "TARGET_SSE2 && TARGET_SSE_MATH
14529 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14530 "* return output_387_binary_op (insn, operands);"
14531 [(set_attr "mode" "DF")
14532 (set (attr "type")
14533 (cond [(match_operand:SF 3 "mult_operator" "")
14534 (const_string "ssemul")
14535 (match_operand:SF 3 "div_operator" "")
14536 (const_string "ssediv")
14537 ]
14538 (const_string "sseadd")))])
14539
14540 ;; ??? Add SSE splitters for these!
14541 (define_insn "*fop_df_2"
14542 [(set (match_operand:DF 0 "register_operand" "=f,f")
14543 (match_operator:DF 3 "binary_fp_operator"
14544 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14545 (match_operand:DF 2 "register_operand" "0,0")]))]
14546 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14547 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14548 [(set (attr "type")
14549 (cond [(match_operand:DF 3 "mult_operator" "")
14550 (const_string "fmul")
14551 (match_operand:DF 3 "div_operator" "")
14552 (const_string "fdiv")
14553 ]
14554 (const_string "fop")))
14555 (set_attr "fp_int_src" "true")
14556 (set_attr "ppro_uops" "many")
14557 (set_attr "mode" "SI")])
14558
14559 (define_insn "*fop_df_3"
14560 [(set (match_operand:DF 0 "register_operand" "=f,f")
14561 (match_operator:DF 3 "binary_fp_operator"
14562 [(match_operand:DF 1 "register_operand" "0,0")
14563 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14564 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14565 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14566 [(set (attr "type")
14567 (cond [(match_operand:DF 3 "mult_operator" "")
14568 (const_string "fmul")
14569 (match_operand:DF 3 "div_operator" "")
14570 (const_string "fdiv")
14571 ]
14572 (const_string "fop")))
14573 (set_attr "fp_int_src" "true")
14574 (set_attr "ppro_uops" "many")
14575 (set_attr "mode" "SI")])
14576
14577 (define_insn "*fop_df_4"
14578 [(set (match_operand:DF 0 "register_operand" "=f,f")
14579 (match_operator:DF 3 "binary_fp_operator"
14580 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14581 (match_operand:DF 2 "register_operand" "0,f")]))]
14582 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14583 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14584 "* return output_387_binary_op (insn, operands);"
14585 [(set (attr "type")
14586 (cond [(match_operand:DF 3 "mult_operator" "")
14587 (const_string "fmul")
14588 (match_operand:DF 3 "div_operator" "")
14589 (const_string "fdiv")
14590 ]
14591 (const_string "fop")))
14592 (set_attr "mode" "SF")])
14593
14594 (define_insn "*fop_df_5"
14595 [(set (match_operand:DF 0 "register_operand" "=f,f")
14596 (match_operator:DF 3 "binary_fp_operator"
14597 [(match_operand:DF 1 "register_operand" "0,f")
14598 (float_extend:DF
14599 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14600 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14601 "* return output_387_binary_op (insn, operands);"
14602 [(set (attr "type")
14603 (cond [(match_operand:DF 3 "mult_operator" "")
14604 (const_string "fmul")
14605 (match_operand:DF 3 "div_operator" "")
14606 (const_string "fdiv")
14607 ]
14608 (const_string "fop")))
14609 (set_attr "mode" "SF")])
14610
14611 (define_insn "*fop_df_6"
14612 [(set (match_operand:DF 0 "register_operand" "=f,f")
14613 (match_operator:DF 3 "binary_fp_operator"
14614 [(float_extend:DF
14615 (match_operand:SF 1 "register_operand" "0,f"))
14616 (float_extend:DF
14617 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14618 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14619 "* return output_387_binary_op (insn, operands);"
14620 [(set (attr "type")
14621 (cond [(match_operand:DF 3 "mult_operator" "")
14622 (const_string "fmul")
14623 (match_operand:DF 3 "div_operator" "")
14624 (const_string "fdiv")
14625 ]
14626 (const_string "fop")))
14627 (set_attr "mode" "SF")])
14628
14629 (define_insn "*fop_xf_1"
14630 [(set (match_operand:XF 0 "register_operand" "=f,f")
14631 (match_operator:XF 3 "binary_fp_operator"
14632 [(match_operand:XF 1 "register_operand" "0,f")
14633 (match_operand:XF 2 "register_operand" "f,0")]))]
14634 "!TARGET_64BIT && TARGET_80387
14635 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14636 "* return output_387_binary_op (insn, operands);"
14637 [(set (attr "type")
14638 (cond [(match_operand:XF 3 "mult_operator" "")
14639 (const_string "fmul")
14640 (match_operand:XF 3 "div_operator" "")
14641 (const_string "fdiv")
14642 ]
14643 (const_string "fop")))
14644 (set_attr "mode" "XF")])
14645
14646 (define_insn "*fop_tf_1"
14647 [(set (match_operand:TF 0 "register_operand" "=f,f")
14648 (match_operator:TF 3 "binary_fp_operator"
14649 [(match_operand:TF 1 "register_operand" "0,f")
14650 (match_operand:TF 2 "register_operand" "f,0")]))]
14651 "TARGET_80387
14652 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14653 "* return output_387_binary_op (insn, operands);"
14654 [(set (attr "type")
14655 (cond [(match_operand:TF 3 "mult_operator" "")
14656 (const_string "fmul")
14657 (match_operand:TF 3 "div_operator" "")
14658 (const_string "fdiv")
14659 ]
14660 (const_string "fop")))
14661 (set_attr "mode" "XF")])
14662
14663 (define_insn "*fop_xf_2"
14664 [(set (match_operand:XF 0 "register_operand" "=f,f")
14665 (match_operator:XF 3 "binary_fp_operator"
14666 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14667 (match_operand:XF 2 "register_operand" "0,0")]))]
14668 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14669 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14670 [(set (attr "type")
14671 (cond [(match_operand:XF 3 "mult_operator" "")
14672 (const_string "fmul")
14673 (match_operand:XF 3 "div_operator" "")
14674 (const_string "fdiv")
14675 ]
14676 (const_string "fop")))
14677 (set_attr "fp_int_src" "true")
14678 (set_attr "mode" "SI")
14679 (set_attr "ppro_uops" "many")])
14680
14681 (define_insn "*fop_tf_2"
14682 [(set (match_operand:TF 0 "register_operand" "=f,f")
14683 (match_operator:TF 3 "binary_fp_operator"
14684 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14685 (match_operand:TF 2 "register_operand" "0,0")]))]
14686 "TARGET_80387 && TARGET_USE_FIOP"
14687 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14688 [(set (attr "type")
14689 (cond [(match_operand:TF 3 "mult_operator" "")
14690 (const_string "fmul")
14691 (match_operand:TF 3 "div_operator" "")
14692 (const_string "fdiv")
14693 ]
14694 (const_string "fop")))
14695 (set_attr "fp_int_src" "true")
14696 (set_attr "mode" "SI")
14697 (set_attr "ppro_uops" "many")])
14698
14699 (define_insn "*fop_xf_3"
14700 [(set (match_operand:XF 0 "register_operand" "=f,f")
14701 (match_operator:XF 3 "binary_fp_operator"
14702 [(match_operand:XF 1 "register_operand" "0,0")
14703 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14704 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14705 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14706 [(set (attr "type")
14707 (cond [(match_operand:XF 3 "mult_operator" "")
14708 (const_string "fmul")
14709 (match_operand:XF 3 "div_operator" "")
14710 (const_string "fdiv")
14711 ]
14712 (const_string "fop")))
14713 (set_attr "fp_int_src" "true")
14714 (set_attr "mode" "SI")
14715 (set_attr "ppro_uops" "many")])
14716
14717 (define_insn "*fop_tf_3"
14718 [(set (match_operand:TF 0 "register_operand" "=f,f")
14719 (match_operator:TF 3 "binary_fp_operator"
14720 [(match_operand:TF 1 "register_operand" "0,0")
14721 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14722 "TARGET_80387 && TARGET_USE_FIOP"
14723 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14724 [(set (attr "type")
14725 (cond [(match_operand:TF 3 "mult_operator" "")
14726 (const_string "fmul")
14727 (match_operand:TF 3 "div_operator" "")
14728 (const_string "fdiv")
14729 ]
14730 (const_string "fop")))
14731 (set_attr "fp_int_src" "true")
14732 (set_attr "mode" "SI")
14733 (set_attr "ppro_uops" "many")])
14734
14735 (define_insn "*fop_xf_4"
14736 [(set (match_operand:XF 0 "register_operand" "=f,f")
14737 (match_operator:XF 3 "binary_fp_operator"
14738 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14739 (match_operand:XF 2 "register_operand" "0,f")]))]
14740 "!TARGET_64BIT && TARGET_80387"
14741 "* return output_387_binary_op (insn, operands);"
14742 [(set (attr "type")
14743 (cond [(match_operand:XF 3 "mult_operator" "")
14744 (const_string "fmul")
14745 (match_operand:XF 3 "div_operator" "")
14746 (const_string "fdiv")
14747 ]
14748 (const_string "fop")))
14749 (set_attr "mode" "SF")])
14750
14751 (define_insn "*fop_tf_4"
14752 [(set (match_operand:TF 0 "register_operand" "=f,f")
14753 (match_operator:TF 3 "binary_fp_operator"
14754 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
14755 (match_operand:TF 2 "register_operand" "0,f")]))]
14756 "TARGET_80387"
14757 "* return output_387_binary_op (insn, operands);"
14758 [(set (attr "type")
14759 (cond [(match_operand:TF 3 "mult_operator" "")
14760 (const_string "fmul")
14761 (match_operand:TF 3 "div_operator" "")
14762 (const_string "fdiv")
14763 ]
14764 (const_string "fop")))
14765 (set_attr "mode" "SF")])
14766
14767 (define_insn "*fop_xf_5"
14768 [(set (match_operand:XF 0 "register_operand" "=f,f")
14769 (match_operator:XF 3 "binary_fp_operator"
14770 [(match_operand:XF 1 "register_operand" "0,f")
14771 (float_extend:XF
14772 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14773 "!TARGET_64BIT && TARGET_80387"
14774 "* return output_387_binary_op (insn, operands);"
14775 [(set (attr "type")
14776 (cond [(match_operand:XF 3 "mult_operator" "")
14777 (const_string "fmul")
14778 (match_operand:XF 3 "div_operator" "")
14779 (const_string "fdiv")
14780 ]
14781 (const_string "fop")))
14782 (set_attr "mode" "SF")])
14783
14784 (define_insn "*fop_tf_5"
14785 [(set (match_operand:TF 0 "register_operand" "=f,f")
14786 (match_operator:TF 3 "binary_fp_operator"
14787 [(match_operand:TF 1 "register_operand" "0,f")
14788 (float_extend:TF
14789 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14790 "TARGET_80387"
14791 "* return output_387_binary_op (insn, operands);"
14792 [(set (attr "type")
14793 (cond [(match_operand:TF 3 "mult_operator" "")
14794 (const_string "fmul")
14795 (match_operand:TF 3 "div_operator" "")
14796 (const_string "fdiv")
14797 ]
14798 (const_string "fop")))
14799 (set_attr "mode" "SF")])
14800
14801 (define_insn "*fop_xf_6"
14802 [(set (match_operand:XF 0 "register_operand" "=f,f")
14803 (match_operator:XF 3 "binary_fp_operator"
14804 [(float_extend:XF
14805 (match_operand 1 "register_operand" "0,f"))
14806 (float_extend:XF
14807 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14808 "!TARGET_64BIT && TARGET_80387"
14809 "* return output_387_binary_op (insn, operands);"
14810 [(set (attr "type")
14811 (cond [(match_operand:XF 3 "mult_operator" "")
14812 (const_string "fmul")
14813 (match_operand:XF 3 "div_operator" "")
14814 (const_string "fdiv")
14815 ]
14816 (const_string "fop")))
14817 (set_attr "mode" "SF")])
14818
14819 (define_insn "*fop_tf_6"
14820 [(set (match_operand:TF 0 "register_operand" "=f,f")
14821 (match_operator:TF 3 "binary_fp_operator"
14822 [(float_extend:TF
14823 (match_operand 1 "register_operand" "0,f"))
14824 (float_extend:TF
14825 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14826 "TARGET_80387"
14827 "* return output_387_binary_op (insn, operands);"
14828 [(set (attr "type")
14829 (cond [(match_operand:TF 3 "mult_operator" "")
14830 (const_string "fmul")
14831 (match_operand:TF 3 "div_operator" "")
14832 (const_string "fdiv")
14833 ]
14834 (const_string "fop")))
14835 (set_attr "mode" "SF")])
14836
14837 (define_split
14838 [(set (match_operand 0 "register_operand" "")
14839 (match_operator 3 "binary_fp_operator"
14840 [(float (match_operand:SI 1 "register_operand" ""))
14841 (match_operand 2 "register_operand" "")]))]
14842 "TARGET_80387 && reload_completed
14843 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14844 [(const_int 0)]
14845 {
14846 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14847 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14848 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14849 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14850 GET_MODE (operands[3]),
14851 operands[4],
14852 operands[2])));
14853 ix86_free_from_memory (GET_MODE (operands[1]));
14854 DONE;
14855 })
14856
14857 (define_split
14858 [(set (match_operand 0 "register_operand" "")
14859 (match_operator 3 "binary_fp_operator"
14860 [(match_operand 1 "register_operand" "")
14861 (float (match_operand:SI 2 "register_operand" ""))]))]
14862 "TARGET_80387 && reload_completed
14863 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14864 [(const_int 0)]
14865 {
14866 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14867 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14868 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14869 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14870 GET_MODE (operands[3]),
14871 operands[1],
14872 operands[4])));
14873 ix86_free_from_memory (GET_MODE (operands[2]));
14874 DONE;
14875 })
14876 \f
14877 ;; FPU special functions.
14878
14879 (define_expand "sqrtsf2"
14880 [(set (match_operand:SF 0 "register_operand" "")
14881 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14882 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14883 {
14884 if (!TARGET_SSE_MATH)
14885 operands[1] = force_reg (SFmode, operands[1]);
14886 })
14887
14888 (define_insn "sqrtsf2_1"
14889 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14890 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14891 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14892 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14893 "@
14894 fsqrt
14895 sqrtss\t{%1, %0|%0, %1}"
14896 [(set_attr "type" "fpspc,sse")
14897 (set_attr "mode" "SF,SF")
14898 (set_attr "athlon_decode" "direct,*")])
14899
14900 (define_insn "sqrtsf2_1_sse_only"
14901 [(set (match_operand:SF 0 "register_operand" "=x")
14902 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14903 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14904 "sqrtss\t{%1, %0|%0, %1}"
14905 [(set_attr "type" "sse")
14906 (set_attr "mode" "SF")
14907 (set_attr "athlon_decode" "*")])
14908
14909 (define_insn "sqrtsf2_i387"
14910 [(set (match_operand:SF 0 "register_operand" "=f")
14911 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14912 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14913 && !TARGET_SSE_MATH"
14914 "fsqrt"
14915 [(set_attr "type" "fpspc")
14916 (set_attr "mode" "SF")
14917 (set_attr "athlon_decode" "direct")])
14918
14919 (define_expand "sqrtdf2"
14920 [(set (match_operand:DF 0 "register_operand" "")
14921 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14922 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14923 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14924 {
14925 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14926 operands[1] = force_reg (DFmode, operands[1]);
14927 })
14928
14929 (define_insn "sqrtdf2_1"
14930 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14931 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14932 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14933 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14934 "@
14935 fsqrt
14936 sqrtsd\t{%1, %0|%0, %1}"
14937 [(set_attr "type" "fpspc,sse")
14938 (set_attr "mode" "DF,DF")
14939 (set_attr "athlon_decode" "direct,*")])
14940
14941 (define_insn "sqrtdf2_1_sse_only"
14942 [(set (match_operand:DF 0 "register_operand" "=Y")
14943 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14944 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14945 "sqrtsd\t{%1, %0|%0, %1}"
14946 [(set_attr "type" "sse")
14947 (set_attr "mode" "DF")
14948 (set_attr "athlon_decode" "*")])
14949
14950 (define_insn "sqrtdf2_i387"
14951 [(set (match_operand:DF 0 "register_operand" "=f")
14952 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14953 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14954 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14955 "fsqrt"
14956 [(set_attr "type" "fpspc")
14957 (set_attr "mode" "DF")
14958 (set_attr "athlon_decode" "direct")])
14959
14960 (define_insn "*sqrtextendsfdf2"
14961 [(set (match_operand:DF 0 "register_operand" "=f")
14962 (sqrt:DF (float_extend:DF
14963 (match_operand:SF 1 "register_operand" "0"))))]
14964 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14965 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14966 "fsqrt"
14967 [(set_attr "type" "fpspc")
14968 (set_attr "mode" "DF")
14969 (set_attr "athlon_decode" "direct")])
14970
14971 (define_insn "sqrtxf2"
14972 [(set (match_operand:XF 0 "register_operand" "=f")
14973 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14974 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14975 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14976 "fsqrt"
14977 [(set_attr "type" "fpspc")
14978 (set_attr "mode" "XF")
14979 (set_attr "athlon_decode" "direct")])
14980
14981 (define_insn "sqrttf2"
14982 [(set (match_operand:TF 0 "register_operand" "=f")
14983 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14984 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14985 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14986 "fsqrt"
14987 [(set_attr "type" "fpspc")
14988 (set_attr "mode" "XF")
14989 (set_attr "athlon_decode" "direct")])
14990
14991 (define_insn "*sqrtextenddfxf2"
14992 [(set (match_operand:XF 0 "register_operand" "=f")
14993 (sqrt:XF (float_extend:XF
14994 (match_operand:DF 1 "register_operand" "0"))))]
14995 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14996 "fsqrt"
14997 [(set_attr "type" "fpspc")
14998 (set_attr "mode" "XF")
14999 (set_attr "athlon_decode" "direct")])
15000
15001 (define_insn "*sqrtextenddftf2"
15002 [(set (match_operand:TF 0 "register_operand" "=f")
15003 (sqrt:TF (float_extend:TF
15004 (match_operand:DF 1 "register_operand" "0"))))]
15005 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15006 "fsqrt"
15007 [(set_attr "type" "fpspc")
15008 (set_attr "mode" "XF")
15009 (set_attr "athlon_decode" "direct")])
15010
15011 (define_insn "*sqrtextendsfxf2"
15012 [(set (match_operand:XF 0 "register_operand" "=f")
15013 (sqrt:XF (float_extend:XF
15014 (match_operand:SF 1 "register_operand" "0"))))]
15015 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15016 "fsqrt"
15017 [(set_attr "type" "fpspc")
15018 (set_attr "mode" "XF")
15019 (set_attr "athlon_decode" "direct")])
15020
15021 (define_insn "*sqrtextendsftf2"
15022 [(set (match_operand:TF 0 "register_operand" "=f")
15023 (sqrt:TF (float_extend:TF
15024 (match_operand:SF 1 "register_operand" "0"))))]
15025 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15026 "fsqrt"
15027 [(set_attr "type" "fpspc")
15028 (set_attr "mode" "XF")
15029 (set_attr "athlon_decode" "direct")])
15030
15031 (define_insn "sindf2"
15032 [(set (match_operand:DF 0 "register_operand" "=f")
15033 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15034 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15035 && flag_unsafe_math_optimizations"
15036 "fsin"
15037 [(set_attr "type" "fpspc")
15038 (set_attr "mode" "DF")])
15039
15040 (define_insn "sinsf2"
15041 [(set (match_operand:SF 0 "register_operand" "=f")
15042 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15043 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15044 && flag_unsafe_math_optimizations"
15045 "fsin"
15046 [(set_attr "type" "fpspc")
15047 (set_attr "mode" "SF")])
15048
15049 (define_insn "*sinextendsfdf2"
15050 [(set (match_operand:DF 0 "register_operand" "=f")
15051 (unspec:DF [(float_extend:DF
15052 (match_operand:SF 1 "register_operand" "0"))]
15053 UNSPEC_SIN))]
15054 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15055 && flag_unsafe_math_optimizations"
15056 "fsin"
15057 [(set_attr "type" "fpspc")
15058 (set_attr "mode" "DF")])
15059
15060 (define_insn "sinxf2"
15061 [(set (match_operand:XF 0 "register_operand" "=f")
15062 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15063 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15064 && flag_unsafe_math_optimizations"
15065 "fsin"
15066 [(set_attr "type" "fpspc")
15067 (set_attr "mode" "XF")])
15068
15069 (define_insn "sintf2"
15070 [(set (match_operand:TF 0 "register_operand" "=f")
15071 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15072 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15073 && flag_unsafe_math_optimizations"
15074 "fsin"
15075 [(set_attr "type" "fpspc")
15076 (set_attr "mode" "XF")])
15077
15078 (define_insn "cosdf2"
15079 [(set (match_operand:DF 0 "register_operand" "=f")
15080 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15081 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15082 && flag_unsafe_math_optimizations"
15083 "fcos"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "mode" "DF")])
15086
15087 (define_insn "cossf2"
15088 [(set (match_operand:SF 0 "register_operand" "=f")
15089 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15090 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15091 && flag_unsafe_math_optimizations"
15092 "fcos"
15093 [(set_attr "type" "fpspc")
15094 (set_attr "mode" "SF")])
15095
15096 (define_insn "*cosextendsfdf2"
15097 [(set (match_operand:DF 0 "register_operand" "=f")
15098 (unspec:DF [(float_extend:DF
15099 (match_operand:SF 1 "register_operand" "0"))]
15100 UNSPEC_COS))]
15101 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15102 && flag_unsafe_math_optimizations"
15103 "fcos"
15104 [(set_attr "type" "fpspc")
15105 (set_attr "mode" "DF")])
15106
15107 (define_insn "cosxf2"
15108 [(set (match_operand:XF 0 "register_operand" "=f")
15109 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15110 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15111 && flag_unsafe_math_optimizations"
15112 "fcos"
15113 [(set_attr "type" "fpspc")
15114 (set_attr "mode" "XF")])
15115
15116 (define_insn "costf2"
15117 [(set (match_operand:TF 0 "register_operand" "=f")
15118 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15119 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15120 && flag_unsafe_math_optimizations"
15121 "fcos"
15122 [(set_attr "type" "fpspc")
15123 (set_attr "mode" "XF")])
15124 \f
15125 ;; Block operation instructions
15126
15127 (define_insn "cld"
15128 [(set (reg:SI 19) (const_int 0))]
15129 ""
15130 "cld"
15131 [(set_attr "type" "cld")])
15132
15133 (define_expand "movstrsi"
15134 [(use (match_operand:BLK 0 "memory_operand" ""))
15135 (use (match_operand:BLK 1 "memory_operand" ""))
15136 (use (match_operand:SI 2 "nonmemory_operand" ""))
15137 (use (match_operand:SI 3 "const_int_operand" ""))]
15138 ""
15139 {
15140 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15141 DONE;
15142 else
15143 FAIL;
15144 })
15145
15146 (define_expand "movstrdi"
15147 [(use (match_operand:BLK 0 "memory_operand" ""))
15148 (use (match_operand:BLK 1 "memory_operand" ""))
15149 (use (match_operand:DI 2 "nonmemory_operand" ""))
15150 (use (match_operand:DI 3 "const_int_operand" ""))]
15151 "TARGET_64BIT"
15152 {
15153 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15154 DONE;
15155 else
15156 FAIL;
15157 })
15158
15159 ;; Most CPUs don't like single string operations
15160 ;; Handle this case here to simplify previous expander.
15161
15162 (define_expand "strmovdi_rex64"
15163 [(set (match_dup 2)
15164 (mem:DI (match_operand:DI 1 "register_operand" "")))
15165 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15166 (match_dup 2))
15167 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15168 (clobber (reg:CC 17))])
15169 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15170 (clobber (reg:CC 17))])]
15171 "TARGET_64BIT"
15172 {
15173 if (TARGET_SINGLE_STRINGOP || optimize_size)
15174 {
15175 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15176 operands[1]));
15177 DONE;
15178 }
15179 else
15180 operands[2] = gen_reg_rtx (DImode);
15181 })
15182
15183
15184 (define_expand "strmovsi"
15185 [(set (match_dup 2)
15186 (mem:SI (match_operand:SI 1 "register_operand" "")))
15187 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15188 (match_dup 2))
15189 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15190 (clobber (reg:CC 17))])
15191 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15192 (clobber (reg:CC 17))])]
15193 ""
15194 {
15195 if (TARGET_64BIT)
15196 {
15197 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15198 DONE;
15199 }
15200 if (TARGET_SINGLE_STRINGOP || optimize_size)
15201 {
15202 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15203 operands[1]));
15204 DONE;
15205 }
15206 else
15207 operands[2] = gen_reg_rtx (SImode);
15208 })
15209
15210 (define_expand "strmovsi_rex64"
15211 [(set (match_dup 2)
15212 (mem:SI (match_operand:DI 1 "register_operand" "")))
15213 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15214 (match_dup 2))
15215 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15216 (clobber (reg:CC 17))])
15217 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15218 (clobber (reg:CC 17))])]
15219 "TARGET_64BIT"
15220 {
15221 if (TARGET_SINGLE_STRINGOP || optimize_size)
15222 {
15223 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15224 operands[1]));
15225 DONE;
15226 }
15227 else
15228 operands[2] = gen_reg_rtx (SImode);
15229 })
15230
15231 (define_expand "strmovhi"
15232 [(set (match_dup 2)
15233 (mem:HI (match_operand:SI 1 "register_operand" "")))
15234 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15235 (match_dup 2))
15236 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15237 (clobber (reg:CC 17))])
15238 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15239 (clobber (reg:CC 17))])]
15240 ""
15241 {
15242 if (TARGET_64BIT)
15243 {
15244 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15245 DONE;
15246 }
15247 if (TARGET_SINGLE_STRINGOP || optimize_size)
15248 {
15249 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15250 operands[1]));
15251 DONE;
15252 }
15253 else
15254 operands[2] = gen_reg_rtx (HImode);
15255 })
15256
15257 (define_expand "strmovhi_rex64"
15258 [(set (match_dup 2)
15259 (mem:HI (match_operand:DI 1 "register_operand" "")))
15260 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15261 (match_dup 2))
15262 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15263 (clobber (reg:CC 17))])
15264 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15265 (clobber (reg:CC 17))])]
15266 "TARGET_64BIT"
15267 {
15268 if (TARGET_SINGLE_STRINGOP || optimize_size)
15269 {
15270 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15271 operands[1]));
15272 DONE;
15273 }
15274 else
15275 operands[2] = gen_reg_rtx (HImode);
15276 })
15277
15278 (define_expand "strmovqi"
15279 [(set (match_dup 2)
15280 (mem:QI (match_operand:SI 1 "register_operand" "")))
15281 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15282 (match_dup 2))
15283 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15284 (clobber (reg:CC 17))])
15285 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15286 (clobber (reg:CC 17))])]
15287 ""
15288 {
15289 if (TARGET_64BIT)
15290 {
15291 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15292 DONE;
15293 }
15294 if (TARGET_SINGLE_STRINGOP || optimize_size)
15295 {
15296 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15297 operands[1]));
15298 DONE;
15299 }
15300 else
15301 operands[2] = gen_reg_rtx (QImode);
15302 })
15303
15304 (define_expand "strmovqi_rex64"
15305 [(set (match_dup 2)
15306 (mem:QI (match_operand:DI 1 "register_operand" "")))
15307 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15308 (match_dup 2))
15309 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15310 (clobber (reg:CC 17))])
15311 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15312 (clobber (reg:CC 17))])]
15313 "TARGET_64BIT"
15314 {
15315 if (TARGET_SINGLE_STRINGOP || optimize_size)
15316 {
15317 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15318 operands[1]));
15319 DONE;
15320 }
15321 else
15322 operands[2] = gen_reg_rtx (QImode);
15323 })
15324
15325 (define_insn "strmovdi_rex_1"
15326 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15327 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15328 (set (match_operand:DI 0 "register_operand" "=D")
15329 (plus:DI (match_dup 2)
15330 (const_int 8)))
15331 (set (match_operand:DI 1 "register_operand" "=S")
15332 (plus:DI (match_dup 3)
15333 (const_int 8)))
15334 (use (reg:SI 19))]
15335 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15336 "movsq"
15337 [(set_attr "type" "str")
15338 (set_attr "mode" "DI")
15339 (set_attr "memory" "both")])
15340
15341 (define_insn "strmovsi_1"
15342 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15343 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15344 (set (match_operand:SI 0 "register_operand" "=D")
15345 (plus:SI (match_dup 2)
15346 (const_int 4)))
15347 (set (match_operand:SI 1 "register_operand" "=S")
15348 (plus:SI (match_dup 3)
15349 (const_int 4)))
15350 (use (reg:SI 19))]
15351 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15352 "{movsl|movsd}"
15353 [(set_attr "type" "str")
15354 (set_attr "mode" "SI")
15355 (set_attr "memory" "both")])
15356
15357 (define_insn "strmovsi_rex_1"
15358 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15359 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15360 (set (match_operand:DI 0 "register_operand" "=D")
15361 (plus:DI (match_dup 2)
15362 (const_int 4)))
15363 (set (match_operand:DI 1 "register_operand" "=S")
15364 (plus:DI (match_dup 3)
15365 (const_int 4)))
15366 (use (reg:SI 19))]
15367 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15368 "{movsl|movsd}"
15369 [(set_attr "type" "str")
15370 (set_attr "mode" "SI")
15371 (set_attr "memory" "both")])
15372
15373 (define_insn "strmovhi_1"
15374 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15375 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15376 (set (match_operand:SI 0 "register_operand" "=D")
15377 (plus:SI (match_dup 2)
15378 (const_int 2)))
15379 (set (match_operand:SI 1 "register_operand" "=S")
15380 (plus:SI (match_dup 3)
15381 (const_int 2)))
15382 (use (reg:SI 19))]
15383 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15384 "movsw"
15385 [(set_attr "type" "str")
15386 (set_attr "memory" "both")
15387 (set_attr "mode" "HI")])
15388
15389 (define_insn "strmovhi_rex_1"
15390 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15391 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15392 (set (match_operand:DI 0 "register_operand" "=D")
15393 (plus:DI (match_dup 2)
15394 (const_int 2)))
15395 (set (match_operand:DI 1 "register_operand" "=S")
15396 (plus:DI (match_dup 3)
15397 (const_int 2)))
15398 (use (reg:SI 19))]
15399 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15400 "movsw"
15401 [(set_attr "type" "str")
15402 (set_attr "memory" "both")
15403 (set_attr "mode" "HI")])
15404
15405 (define_insn "strmovqi_1"
15406 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15407 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15408 (set (match_operand:SI 0 "register_operand" "=D")
15409 (plus:SI (match_dup 2)
15410 (const_int 1)))
15411 (set (match_operand:SI 1 "register_operand" "=S")
15412 (plus:SI (match_dup 3)
15413 (const_int 1)))
15414 (use (reg:SI 19))]
15415 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15416 "movsb"
15417 [(set_attr "type" "str")
15418 (set_attr "memory" "both")
15419 (set_attr "mode" "QI")])
15420
15421 (define_insn "strmovqi_rex_1"
15422 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15423 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15424 (set (match_operand:DI 0 "register_operand" "=D")
15425 (plus:DI (match_dup 2)
15426 (const_int 1)))
15427 (set (match_operand:DI 1 "register_operand" "=S")
15428 (plus:DI (match_dup 3)
15429 (const_int 1)))
15430 (use (reg:SI 19))]
15431 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15432 "movsb"
15433 [(set_attr "type" "str")
15434 (set_attr "memory" "both")
15435 (set_attr "mode" "QI")])
15436
15437 (define_insn "rep_movdi_rex64"
15438 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15439 (set (match_operand:DI 0 "register_operand" "=D")
15440 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15441 (const_int 3))
15442 (match_operand:DI 3 "register_operand" "0")))
15443 (set (match_operand:DI 1 "register_operand" "=S")
15444 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15445 (match_operand:DI 4 "register_operand" "1")))
15446 (set (mem:BLK (match_dup 3))
15447 (mem:BLK (match_dup 4)))
15448 (use (match_dup 5))
15449 (use (reg:SI 19))]
15450 "TARGET_64BIT"
15451 "{rep\;movsq|rep movsq}"
15452 [(set_attr "type" "str")
15453 (set_attr "prefix_rep" "1")
15454 (set_attr "memory" "both")
15455 (set_attr "mode" "DI")])
15456
15457 (define_insn "rep_movsi"
15458 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15459 (set (match_operand:SI 0 "register_operand" "=D")
15460 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15461 (const_int 2))
15462 (match_operand:SI 3 "register_operand" "0")))
15463 (set (match_operand:SI 1 "register_operand" "=S")
15464 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15465 (match_operand:SI 4 "register_operand" "1")))
15466 (set (mem:BLK (match_dup 3))
15467 (mem:BLK (match_dup 4)))
15468 (use (match_dup 5))
15469 (use (reg:SI 19))]
15470 "!TARGET_64BIT"
15471 "{rep\;movsl|rep movsd}"
15472 [(set_attr "type" "str")
15473 (set_attr "prefix_rep" "1")
15474 (set_attr "memory" "both")
15475 (set_attr "mode" "SI")])
15476
15477 (define_insn "rep_movsi_rex64"
15478 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15479 (set (match_operand:DI 0 "register_operand" "=D")
15480 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15481 (const_int 2))
15482 (match_operand:DI 3 "register_operand" "0")))
15483 (set (match_operand:DI 1 "register_operand" "=S")
15484 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15485 (match_operand:DI 4 "register_operand" "1")))
15486 (set (mem:BLK (match_dup 3))
15487 (mem:BLK (match_dup 4)))
15488 (use (match_dup 5))
15489 (use (reg:SI 19))]
15490 "TARGET_64BIT"
15491 "{rep\;movsl|rep movsd}"
15492 [(set_attr "type" "str")
15493 (set_attr "prefix_rep" "1")
15494 (set_attr "memory" "both")
15495 (set_attr "mode" "SI")])
15496
15497 (define_insn "rep_movqi"
15498 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15499 (set (match_operand:SI 0 "register_operand" "=D")
15500 (plus:SI (match_operand:SI 3 "register_operand" "0")
15501 (match_operand:SI 5 "register_operand" "2")))
15502 (set (match_operand:SI 1 "register_operand" "=S")
15503 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15504 (set (mem:BLK (match_dup 3))
15505 (mem:BLK (match_dup 4)))
15506 (use (match_dup 5))
15507 (use (reg:SI 19))]
15508 "!TARGET_64BIT"
15509 "{rep\;movsb|rep movsb}"
15510 [(set_attr "type" "str")
15511 (set_attr "prefix_rep" "1")
15512 (set_attr "memory" "both")
15513 (set_attr "mode" "SI")])
15514
15515 (define_insn "rep_movqi_rex64"
15516 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15517 (set (match_operand:DI 0 "register_operand" "=D")
15518 (plus:DI (match_operand:DI 3 "register_operand" "0")
15519 (match_operand:DI 5 "register_operand" "2")))
15520 (set (match_operand:DI 1 "register_operand" "=S")
15521 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15522 (set (mem:BLK (match_dup 3))
15523 (mem:BLK (match_dup 4)))
15524 (use (match_dup 5))
15525 (use (reg:SI 19))]
15526 "TARGET_64BIT"
15527 "{rep\;movsb|rep movsb}"
15528 [(set_attr "type" "str")
15529 (set_attr "prefix_rep" "1")
15530 (set_attr "memory" "both")
15531 (set_attr "mode" "SI")])
15532
15533 (define_expand "clrstrsi"
15534 [(use (match_operand:BLK 0 "memory_operand" ""))
15535 (use (match_operand:SI 1 "nonmemory_operand" ""))
15536 (use (match_operand 2 "const_int_operand" ""))]
15537 ""
15538 {
15539 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15540 DONE;
15541 else
15542 FAIL;
15543 })
15544
15545 (define_expand "clrstrdi"
15546 [(use (match_operand:BLK 0 "memory_operand" ""))
15547 (use (match_operand:DI 1 "nonmemory_operand" ""))
15548 (use (match_operand 2 "const_int_operand" ""))]
15549 "TARGET_64BIT"
15550 {
15551 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15552 DONE;
15553 else
15554 FAIL;
15555 })
15556
15557 ;; Most CPUs don't like single string operations
15558 ;; Handle this case here to simplify previous expander.
15559
15560 (define_expand "strsetdi_rex64"
15561 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15562 (match_operand:DI 1 "register_operand" ""))
15563 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15564 (clobber (reg:CC 17))])]
15565 "TARGET_64BIT"
15566 {
15567 if (TARGET_SINGLE_STRINGOP || optimize_size)
15568 {
15569 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15570 DONE;
15571 }
15572 })
15573
15574 (define_expand "strsetsi"
15575 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15576 (match_operand:SI 1 "register_operand" ""))
15577 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15578 (clobber (reg:CC 17))])]
15579 ""
15580 {
15581 if (TARGET_64BIT)
15582 {
15583 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15584 DONE;
15585 }
15586 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15587 {
15588 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15589 DONE;
15590 }
15591 })
15592
15593 (define_expand "strsetsi_rex64"
15594 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15595 (match_operand:SI 1 "register_operand" ""))
15596 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15597 (clobber (reg:CC 17))])]
15598 "TARGET_64BIT"
15599 {
15600 if (TARGET_SINGLE_STRINGOP || optimize_size)
15601 {
15602 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15603 DONE;
15604 }
15605 })
15606
15607 (define_expand "strsethi"
15608 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15609 (match_operand:HI 1 "register_operand" ""))
15610 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15611 (clobber (reg:CC 17))])]
15612 ""
15613 {
15614 if (TARGET_64BIT)
15615 {
15616 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15617 DONE;
15618 }
15619 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15620 {
15621 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15622 DONE;
15623 }
15624 })
15625
15626 (define_expand "strsethi_rex64"
15627 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15628 (match_operand:HI 1 "register_operand" ""))
15629 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15630 (clobber (reg:CC 17))])]
15631 "TARGET_64BIT"
15632 {
15633 if (TARGET_SINGLE_STRINGOP || optimize_size)
15634 {
15635 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15636 DONE;
15637 }
15638 })
15639
15640 (define_expand "strsetqi"
15641 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15642 (match_operand:QI 1 "register_operand" ""))
15643 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15644 (clobber (reg:CC 17))])]
15645 ""
15646 {
15647 if (TARGET_64BIT)
15648 {
15649 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
15650 DONE;
15651 }
15652 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15653 {
15654 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
15655 DONE;
15656 }
15657 })
15658
15659 (define_expand "strsetqi_rex64"
15660 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
15661 (match_operand:QI 1 "register_operand" ""))
15662 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15663 (clobber (reg:CC 17))])]
15664 "TARGET_64BIT"
15665 {
15666 if (TARGET_SINGLE_STRINGOP || optimize_size)
15667 {
15668 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15669 DONE;
15670 }
15671 })
15672
15673 (define_insn "strsetdi_rex_1"
15674 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15675 (match_operand:SI 2 "register_operand" "a"))
15676 (set (match_operand:DI 0 "register_operand" "=D")
15677 (plus:DI (match_dup 1)
15678 (const_int 8)))
15679 (use (reg:SI 19))]
15680 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15681 "stosq"
15682 [(set_attr "type" "str")
15683 (set_attr "memory" "store")
15684 (set_attr "mode" "DI")])
15685
15686 (define_insn "strsetsi_1"
15687 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15688 (match_operand:SI 2 "register_operand" "a"))
15689 (set (match_operand:SI 0 "register_operand" "=D")
15690 (plus:SI (match_dup 1)
15691 (const_int 4)))
15692 (use (reg:SI 19))]
15693 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15694 "{stosl|stosd}"
15695 [(set_attr "type" "str")
15696 (set_attr "memory" "store")
15697 (set_attr "mode" "SI")])
15698
15699 (define_insn "strsetsi_rex_1"
15700 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15701 (match_operand:SI 2 "register_operand" "a"))
15702 (set (match_operand:DI 0 "register_operand" "=D")
15703 (plus:DI (match_dup 1)
15704 (const_int 4)))
15705 (use (reg:SI 19))]
15706 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15707 "{stosl|stosd}"
15708 [(set_attr "type" "str")
15709 (set_attr "memory" "store")
15710 (set_attr "mode" "SI")])
15711
15712 (define_insn "strsethi_1"
15713 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15714 (match_operand:HI 2 "register_operand" "a"))
15715 (set (match_operand:SI 0 "register_operand" "=D")
15716 (plus:SI (match_dup 1)
15717 (const_int 2)))
15718 (use (reg:SI 19))]
15719 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15720 "stosw"
15721 [(set_attr "type" "str")
15722 (set_attr "memory" "store")
15723 (set_attr "mode" "HI")])
15724
15725 (define_insn "strsethi_rex_1"
15726 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15727 (match_operand:HI 2 "register_operand" "a"))
15728 (set (match_operand:DI 0 "register_operand" "=D")
15729 (plus:DI (match_dup 1)
15730 (const_int 2)))
15731 (use (reg:SI 19))]
15732 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15733 "stosw"
15734 [(set_attr "type" "str")
15735 (set_attr "memory" "store")
15736 (set_attr "mode" "HI")])
15737
15738 (define_insn "strsetqi_1"
15739 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15740 (match_operand:QI 2 "register_operand" "a"))
15741 (set (match_operand:SI 0 "register_operand" "=D")
15742 (plus:SI (match_dup 1)
15743 (const_int 1)))
15744 (use (reg:SI 19))]
15745 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15746 "stosb"
15747 [(set_attr "type" "str")
15748 (set_attr "memory" "store")
15749 (set_attr "mode" "QI")])
15750
15751 (define_insn "strsetqi_rex_1"
15752 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15753 (match_operand:QI 2 "register_operand" "a"))
15754 (set (match_operand:DI 0 "register_operand" "=D")
15755 (plus:DI (match_dup 1)
15756 (const_int 1)))
15757 (use (reg:SI 19))]
15758 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15759 "stosb"
15760 [(set_attr "type" "str")
15761 (set_attr "memory" "store")
15762 (set_attr "mode" "QI")])
15763
15764 (define_insn "rep_stosdi_rex64"
15765 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15766 (set (match_operand:DI 0 "register_operand" "=D")
15767 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15768 (const_int 3))
15769 (match_operand:DI 3 "register_operand" "0")))
15770 (set (mem:BLK (match_dup 3))
15771 (const_int 0))
15772 (use (match_operand:DI 2 "register_operand" "a"))
15773 (use (match_dup 4))
15774 (use (reg:SI 19))]
15775 "TARGET_64BIT"
15776 "{rep\;stosq|rep stosq}"
15777 [(set_attr "type" "str")
15778 (set_attr "prefix_rep" "1")
15779 (set_attr "memory" "store")
15780 (set_attr "mode" "DI")])
15781
15782 (define_insn "rep_stossi"
15783 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15784 (set (match_operand:SI 0 "register_operand" "=D")
15785 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15786 (const_int 2))
15787 (match_operand:SI 3 "register_operand" "0")))
15788 (set (mem:BLK (match_dup 3))
15789 (const_int 0))
15790 (use (match_operand:SI 2 "register_operand" "a"))
15791 (use (match_dup 4))
15792 (use (reg:SI 19))]
15793 "!TARGET_64BIT"
15794 "{rep\;stosl|rep stosd}"
15795 [(set_attr "type" "str")
15796 (set_attr "prefix_rep" "1")
15797 (set_attr "memory" "store")
15798 (set_attr "mode" "SI")])
15799
15800 (define_insn "rep_stossi_rex64"
15801 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15802 (set (match_operand:DI 0 "register_operand" "=D")
15803 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15804 (const_int 2))
15805 (match_operand:DI 3 "register_operand" "0")))
15806 (set (mem:BLK (match_dup 3))
15807 (const_int 0))
15808 (use (match_operand:SI 2 "register_operand" "a"))
15809 (use (match_dup 4))
15810 (use (reg:SI 19))]
15811 "TARGET_64BIT"
15812 "{rep\;stosl|rep stosd}"
15813 [(set_attr "type" "str")
15814 (set_attr "prefix_rep" "1")
15815 (set_attr "memory" "store")
15816 (set_attr "mode" "SI")])
15817
15818 (define_insn "rep_stosqi"
15819 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15820 (set (match_operand:SI 0 "register_operand" "=D")
15821 (plus:SI (match_operand:SI 3 "register_operand" "0")
15822 (match_operand:SI 4 "register_operand" "1")))
15823 (set (mem:BLK (match_dup 3))
15824 (const_int 0))
15825 (use (match_operand:QI 2 "register_operand" "a"))
15826 (use (match_dup 4))
15827 (use (reg:SI 19))]
15828 "!TARGET_64BIT"
15829 "{rep\;stosb|rep stosb}"
15830 [(set_attr "type" "str")
15831 (set_attr "prefix_rep" "1")
15832 (set_attr "memory" "store")
15833 (set_attr "mode" "QI")])
15834
15835 (define_insn "rep_stosqi_rex64"
15836 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15837 (set (match_operand:DI 0 "register_operand" "=D")
15838 (plus:DI (match_operand:DI 3 "register_operand" "0")
15839 (match_operand:DI 4 "register_operand" "1")))
15840 (set (mem:BLK (match_dup 3))
15841 (const_int 0))
15842 (use (match_operand:QI 2 "register_operand" "a"))
15843 (use (match_dup 4))
15844 (use (reg:DI 19))]
15845 "TARGET_64BIT"
15846 "{rep\;stosb|rep stosb}"
15847 [(set_attr "type" "str")
15848 (set_attr "prefix_rep" "1")
15849 (set_attr "memory" "store")
15850 (set_attr "mode" "QI")])
15851
15852 (define_expand "cmpstrsi"
15853 [(set (match_operand:SI 0 "register_operand" "")
15854 (compare:SI (match_operand:BLK 1 "general_operand" "")
15855 (match_operand:BLK 2 "general_operand" "")))
15856 (use (match_operand 3 "general_operand" ""))
15857 (use (match_operand 4 "immediate_operand" ""))]
15858 ""
15859 {
15860 rtx addr1, addr2, out, outlow, count, countreg, align;
15861
15862 out = operands[0];
15863 if (GET_CODE (out) != REG)
15864 out = gen_reg_rtx (SImode);
15865
15866 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15867 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15868
15869 count = operands[3];
15870 countreg = ix86_zero_extend_to_Pmode (count);
15871
15872 /* %%% Iff we are testing strict equality, we can use known alignment
15873 to good advantage. This may be possible with combine, particularly
15874 once cc0 is dead. */
15875 align = operands[4];
15876
15877 emit_insn (gen_cld ());
15878 if (GET_CODE (count) == CONST_INT)
15879 {
15880 if (INTVAL (count) == 0)
15881 {
15882 emit_move_insn (operands[0], const0_rtx);
15883 DONE;
15884 }
15885 if (TARGET_64BIT)
15886 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15887 addr1, addr2, countreg));
15888 else
15889 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15890 addr1, addr2, countreg));
15891 }
15892 else
15893 {
15894 if (TARGET_64BIT)
15895 {
15896 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15897 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15898 addr1, addr2, countreg));
15899 }
15900 else
15901 {
15902 emit_insn (gen_cmpsi_1 (countreg, countreg));
15903 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15904 addr1, addr2, countreg));
15905 }
15906 }
15907
15908 outlow = gen_lowpart (QImode, out);
15909 emit_insn (gen_cmpintqi (outlow));
15910 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15911
15912 if (operands[0] != out)
15913 emit_move_insn (operands[0], out);
15914
15915 DONE;
15916 })
15917
15918 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15919
15920 (define_expand "cmpintqi"
15921 [(set (match_dup 1)
15922 (gtu:QI (reg:CC 17) (const_int 0)))
15923 (set (match_dup 2)
15924 (ltu:QI (reg:CC 17) (const_int 0)))
15925 (parallel [(set (match_operand:QI 0 "register_operand" "")
15926 (minus:QI (match_dup 1)
15927 (match_dup 2)))
15928 (clobber (reg:CC 17))])]
15929 ""
15930 "operands[1] = gen_reg_rtx (QImode);
15931 operands[2] = gen_reg_rtx (QImode);")
15932
15933 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15934 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15935
15936 (define_insn "cmpstrqi_nz_1"
15937 [(set (reg:CC 17)
15938 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15939 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15940 (use (match_operand:SI 6 "register_operand" "2"))
15941 (use (match_operand:SI 3 "immediate_operand" "i"))
15942 (use (reg:SI 19))
15943 (clobber (match_operand:SI 0 "register_operand" "=S"))
15944 (clobber (match_operand:SI 1 "register_operand" "=D"))
15945 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15946 "!TARGET_64BIT"
15947 "repz{\;| }cmpsb"
15948 [(set_attr "type" "str")
15949 (set_attr "mode" "QI")
15950 (set_attr "prefix_rep" "1")])
15951
15952 (define_insn "cmpstrqi_nz_rex_1"
15953 [(set (reg:CC 17)
15954 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15955 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15956 (use (match_operand:DI 6 "register_operand" "2"))
15957 (use (match_operand:SI 3 "immediate_operand" "i"))
15958 (use (reg:SI 19))
15959 (clobber (match_operand:DI 0 "register_operand" "=S"))
15960 (clobber (match_operand:DI 1 "register_operand" "=D"))
15961 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15962 "TARGET_64BIT"
15963 "repz{\;| }cmpsb"
15964 [(set_attr "type" "str")
15965 (set_attr "mode" "QI")
15966 (set_attr "prefix_rep" "1")])
15967
15968 ;; The same, but the count is not known to not be zero.
15969
15970 (define_insn "cmpstrqi_1"
15971 [(set (reg:CC 17)
15972 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15973 (const_int 0))
15974 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15975 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15976 (const_int 0)))
15977 (use (match_operand:SI 3 "immediate_operand" "i"))
15978 (use (reg:CC 17))
15979 (use (reg:SI 19))
15980 (clobber (match_operand:SI 0 "register_operand" "=S"))
15981 (clobber (match_operand:SI 1 "register_operand" "=D"))
15982 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15983 "!TARGET_64BIT"
15984 "repz{\;| }cmpsb"
15985 [(set_attr "type" "str")
15986 (set_attr "mode" "QI")
15987 (set_attr "prefix_rep" "1")])
15988
15989 (define_insn "cmpstrqi_rex_1"
15990 [(set (reg:CC 17)
15991 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15992 (const_int 0))
15993 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15994 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15995 (const_int 0)))
15996 (use (match_operand:SI 3 "immediate_operand" "i"))
15997 (use (reg:CC 17))
15998 (use (reg:SI 19))
15999 (clobber (match_operand:DI 0 "register_operand" "=S"))
16000 (clobber (match_operand:DI 1 "register_operand" "=D"))
16001 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16002 "TARGET_64BIT"
16003 "repz{\;| }cmpsb"
16004 [(set_attr "type" "str")
16005 (set_attr "mode" "QI")
16006 (set_attr "prefix_rep" "1")])
16007
16008 (define_expand "strlensi"
16009 [(set (match_operand:SI 0 "register_operand" "")
16010 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16011 (match_operand:QI 2 "immediate_operand" "")
16012 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16013 ""
16014 {
16015 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16016 DONE;
16017 else
16018 FAIL;
16019 })
16020
16021 (define_expand "strlendi"
16022 [(set (match_operand:DI 0 "register_operand" "")
16023 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16024 (match_operand:QI 2 "immediate_operand" "")
16025 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16026 ""
16027 {
16028 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16029 DONE;
16030 else
16031 FAIL;
16032 })
16033
16034 (define_insn "strlenqi_1"
16035 [(set (match_operand:SI 0 "register_operand" "=&c")
16036 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16037 (match_operand:QI 2 "register_operand" "a")
16038 (match_operand:SI 3 "immediate_operand" "i")
16039 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16040 (use (reg:SI 19))
16041 (clobber (match_operand:SI 1 "register_operand" "=D"))
16042 (clobber (reg:CC 17))]
16043 "!TARGET_64BIT"
16044 "repnz{\;| }scasb"
16045 [(set_attr "type" "str")
16046 (set_attr "mode" "QI")
16047 (set_attr "prefix_rep" "1")])
16048
16049 (define_insn "strlenqi_rex_1"
16050 [(set (match_operand:DI 0 "register_operand" "=&c")
16051 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16052 (match_operand:QI 2 "register_operand" "a")
16053 (match_operand:DI 3 "immediate_operand" "i")
16054 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16055 (use (reg:SI 19))
16056 (clobber (match_operand:DI 1 "register_operand" "=D"))
16057 (clobber (reg:CC 17))]
16058 "TARGET_64BIT"
16059 "repnz{\;| }scasb"
16060 [(set_attr "type" "str")
16061 (set_attr "mode" "QI")
16062 (set_attr "prefix_rep" "1")])
16063
16064 ;; Peephole optimizations to clean up after cmpstr*. This should be
16065 ;; handled in combine, but it is not currently up to the task.
16066 ;; When used for their truth value, the cmpstr* expanders generate
16067 ;; code like this:
16068 ;;
16069 ;; repz cmpsb
16070 ;; seta %al
16071 ;; setb %dl
16072 ;; cmpb %al, %dl
16073 ;; jcc label
16074 ;;
16075 ;; The intermediate three instructions are unnecessary.
16076
16077 ;; This one handles cmpstr*_nz_1...
16078 (define_peephole2
16079 [(parallel[
16080 (set (reg:CC 17)
16081 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16082 (mem:BLK (match_operand 5 "register_operand" ""))))
16083 (use (match_operand 6 "register_operand" ""))
16084 (use (match_operand:SI 3 "immediate_operand" ""))
16085 (use (reg:SI 19))
16086 (clobber (match_operand 0 "register_operand" ""))
16087 (clobber (match_operand 1 "register_operand" ""))
16088 (clobber (match_operand 2 "register_operand" ""))])
16089 (set (match_operand:QI 7 "register_operand" "")
16090 (gtu:QI (reg:CC 17) (const_int 0)))
16091 (set (match_operand:QI 8 "register_operand" "")
16092 (ltu:QI (reg:CC 17) (const_int 0)))
16093 (set (reg 17)
16094 (compare (match_dup 7) (match_dup 8)))
16095 ]
16096 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16097 [(parallel[
16098 (set (reg:CC 17)
16099 (compare:CC (mem:BLK (match_dup 4))
16100 (mem:BLK (match_dup 5))))
16101 (use (match_dup 6))
16102 (use (match_dup 3))
16103 (use (reg:SI 19))
16104 (clobber (match_dup 0))
16105 (clobber (match_dup 1))
16106 (clobber (match_dup 2))])]
16107 "")
16108
16109 ;; ...and this one handles cmpstr*_1.
16110 (define_peephole2
16111 [(parallel[
16112 (set (reg:CC 17)
16113 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16114 (const_int 0))
16115 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16116 (mem:BLK (match_operand 5 "register_operand" "")))
16117 (const_int 0)))
16118 (use (match_operand:SI 3 "immediate_operand" ""))
16119 (use (reg:CC 17))
16120 (use (reg:SI 19))
16121 (clobber (match_operand 0 "register_operand" ""))
16122 (clobber (match_operand 1 "register_operand" ""))
16123 (clobber (match_operand 2 "register_operand" ""))])
16124 (set (match_operand:QI 7 "register_operand" "")
16125 (gtu:QI (reg:CC 17) (const_int 0)))
16126 (set (match_operand:QI 8 "register_operand" "")
16127 (ltu:QI (reg:CC 17) (const_int 0)))
16128 (set (reg 17)
16129 (compare (match_dup 7) (match_dup 8)))
16130 ]
16131 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16132 [(parallel[
16133 (set (reg:CC 17)
16134 (if_then_else:CC (ne (match_dup 6)
16135 (const_int 0))
16136 (compare:CC (mem:BLK (match_dup 4))
16137 (mem:BLK (match_dup 5)))
16138 (const_int 0)))
16139 (use (match_dup 3))
16140 (use (reg:CC 17))
16141 (use (reg:SI 19))
16142 (clobber (match_dup 0))
16143 (clobber (match_dup 1))
16144 (clobber (match_dup 2))])]
16145 "")
16146
16147
16148 \f
16149 ;; Conditional move instructions.
16150
16151 (define_expand "movdicc"
16152 [(set (match_operand:DI 0 "register_operand" "")
16153 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16154 (match_operand:DI 2 "general_operand" "")
16155 (match_operand:DI 3 "general_operand" "")))]
16156 "TARGET_64BIT"
16157 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16158
16159 (define_insn "x86_movdicc_0_m1_rex64"
16160 [(set (match_operand:DI 0 "register_operand" "=r")
16161 (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
16162 (const_int -1)
16163 (const_int 0)))
16164 (clobber (reg:CC 17))]
16165 "TARGET_64BIT"
16166 "sbb{q}\t%0, %0"
16167 ; Since we don't have the proper number of operands for an alu insn,
16168 ; fill in all the blanks.
16169 [(set_attr "type" "alu")
16170 (set_attr "pent_pair" "pu")
16171 (set_attr "memory" "none")
16172 (set_attr "imm_disp" "false")
16173 (set_attr "mode" "DI")
16174 (set_attr "length_immediate" "0")])
16175
16176 (define_insn "*movdicc_c_rex64"
16177 [(set (match_operand:DI 0 "register_operand" "=r,r")
16178 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16179 [(reg 17) (const_int 0)])
16180 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16181 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16182 "TARGET_64BIT && TARGET_CMOVE
16183 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16184 "@
16185 cmov%O2%C1\t{%2, %0|%0, %2}
16186 cmov%O2%c1\t{%3, %0|%0, %3}"
16187 [(set_attr "type" "icmov")
16188 (set_attr "mode" "DI")])
16189
16190 (define_expand "movsicc"
16191 [(set (match_operand:SI 0 "register_operand" "")
16192 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16193 (match_operand:SI 2 "general_operand" "")
16194 (match_operand:SI 3 "general_operand" "")))]
16195 ""
16196 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16197
16198 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16199 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16200 ;; So just document what we're doing explicitly.
16201
16202 (define_insn "x86_movsicc_0_m1"
16203 [(set (match_operand:SI 0 "register_operand" "=r")
16204 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
16205 (const_int -1)
16206 (const_int 0)))
16207 (clobber (reg:CC 17))]
16208 ""
16209 "sbb{l}\t%0, %0"
16210 ; Since we don't have the proper number of operands for an alu insn,
16211 ; fill in all the blanks.
16212 [(set_attr "type" "alu")
16213 (set_attr "pent_pair" "pu")
16214 (set_attr "memory" "none")
16215 (set_attr "imm_disp" "false")
16216 (set_attr "mode" "SI")
16217 (set_attr "length_immediate" "0")])
16218
16219 (define_insn "*movsicc_noc"
16220 [(set (match_operand:SI 0 "register_operand" "=r,r")
16221 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16222 [(reg 17) (const_int 0)])
16223 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16224 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16225 "TARGET_CMOVE
16226 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16227 "@
16228 cmov%O2%C1\t{%2, %0|%0, %2}
16229 cmov%O2%c1\t{%3, %0|%0, %3}"
16230 [(set_attr "type" "icmov")
16231 (set_attr "mode" "SI")])
16232
16233 (define_expand "movhicc"
16234 [(set (match_operand:HI 0 "register_operand" "")
16235 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16236 (match_operand:HI 2 "general_operand" "")
16237 (match_operand:HI 3 "general_operand" "")))]
16238 "TARGET_HIMODE_MATH"
16239 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16240
16241 (define_insn "*movhicc_noc"
16242 [(set (match_operand:HI 0 "register_operand" "=r,r")
16243 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16244 [(reg 17) (const_int 0)])
16245 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16246 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16247 "TARGET_CMOVE
16248 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16249 "@
16250 cmov%O2%C1\t{%2, %0|%0, %2}
16251 cmov%O2%c1\t{%3, %0|%0, %3}"
16252 [(set_attr "type" "icmov")
16253 (set_attr "mode" "HI")])
16254
16255 (define_expand "movqicc"
16256 [(set (match_operand:QI 0 "register_operand" "")
16257 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16258 (match_operand:QI 2 "general_operand" "")
16259 (match_operand:QI 3 "general_operand" "")))]
16260 "TARGET_QIMODE_MATH"
16261 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16262
16263 (define_insn_and_split "*movqicc_noc"
16264 [(set (match_operand:QI 0 "register_operand" "=r,r")
16265 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16266 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16267 (match_operand:QI 2 "register_operand" "r,0")
16268 (match_operand:QI 3 "register_operand" "0,r")))]
16269 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16270 "#"
16271 "&& reload_completed"
16272 [(set (match_dup 0)
16273 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16274 (match_dup 2)
16275 (match_dup 3)))]
16276 "operands[0] = gen_lowpart (SImode, operands[0]);
16277 operands[2] = gen_lowpart (SImode, operands[2]);
16278 operands[3] = gen_lowpart (SImode, operands[3]);"
16279 [(set_attr "type" "icmov")
16280 (set_attr "mode" "SI")])
16281
16282 (define_expand "movsfcc"
16283 [(set (match_operand:SF 0 "register_operand" "")
16284 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16285 (match_operand:SF 2 "register_operand" "")
16286 (match_operand:SF 3 "register_operand" "")))]
16287 "TARGET_CMOVE"
16288 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16289
16290 (define_insn "*movsfcc_1"
16291 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16292 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16293 [(reg 17) (const_int 0)])
16294 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16295 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16296 "TARGET_CMOVE
16297 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16298 "@
16299 fcmov%F1\t{%2, %0|%0, %2}
16300 fcmov%f1\t{%3, %0|%0, %3}
16301 cmov%O2%C1\t{%2, %0|%0, %2}
16302 cmov%O2%c1\t{%3, %0|%0, %3}"
16303 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16304 (set_attr "mode" "SF,SF,SI,SI")])
16305
16306 (define_expand "movdfcc"
16307 [(set (match_operand:DF 0 "register_operand" "")
16308 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16309 (match_operand:DF 2 "register_operand" "")
16310 (match_operand:DF 3 "register_operand" "")))]
16311 "TARGET_CMOVE"
16312 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16313
16314 (define_insn "*movdfcc_1"
16315 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16316 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16317 [(reg 17) (const_int 0)])
16318 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16319 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16320 "!TARGET_64BIT && TARGET_CMOVE
16321 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16322 "@
16323 fcmov%F1\t{%2, %0|%0, %2}
16324 fcmov%f1\t{%3, %0|%0, %3}
16325 #
16326 #"
16327 [(set_attr "type" "fcmov,fcmov,multi,multi")
16328 (set_attr "mode" "DF")])
16329
16330 (define_insn "*movdfcc_1_rex64"
16331 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16332 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16333 [(reg 17) (const_int 0)])
16334 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16335 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16336 "TARGET_64BIT && TARGET_CMOVE
16337 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16338 "@
16339 fcmov%F1\t{%2, %0|%0, %2}
16340 fcmov%f1\t{%3, %0|%0, %3}
16341 cmov%O2%C1\t{%2, %0|%0, %2}
16342 cmov%O2%c1\t{%3, %0|%0, %3}"
16343 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16344 (set_attr "mode" "DF")])
16345
16346 (define_split
16347 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16348 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16349 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16350 (match_operand:DF 2 "nonimmediate_operand" "")
16351 (match_operand:DF 3 "nonimmediate_operand" "")))]
16352 "!TARGET_64BIT && reload_completed"
16353 [(set (match_dup 2)
16354 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16355 (match_dup 5)
16356 (match_dup 7)))
16357 (set (match_dup 3)
16358 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16359 (match_dup 6)
16360 (match_dup 8)))]
16361 "split_di (operands+2, 1, operands+5, operands+6);
16362 split_di (operands+3, 1, operands+7, operands+8);
16363 split_di (operands, 1, operands+2, operands+3);")
16364
16365 (define_expand "movxfcc"
16366 [(set (match_operand:XF 0 "register_operand" "")
16367 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16368 (match_operand:XF 2 "register_operand" "")
16369 (match_operand:XF 3 "register_operand" "")))]
16370 "!TARGET_64BIT && TARGET_CMOVE"
16371 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16372
16373 (define_expand "movtfcc"
16374 [(set (match_operand:TF 0 "register_operand" "")
16375 (if_then_else:TF (match_operand 1 "comparison_operator" "")
16376 (match_operand:TF 2 "register_operand" "")
16377 (match_operand:TF 3 "register_operand" "")))]
16378 "TARGET_CMOVE"
16379 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16380
16381 (define_insn "*movxfcc_1"
16382 [(set (match_operand:XF 0 "register_operand" "=f,f")
16383 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16384 [(reg 17) (const_int 0)])
16385 (match_operand:XF 2 "register_operand" "f,0")
16386 (match_operand:XF 3 "register_operand" "0,f")))]
16387 "!TARGET_64BIT && TARGET_CMOVE"
16388 "@
16389 fcmov%F1\t{%2, %0|%0, %2}
16390 fcmov%f1\t{%3, %0|%0, %3}"
16391 [(set_attr "type" "fcmov")
16392 (set_attr "mode" "XF")])
16393
16394 (define_insn "*movtfcc_1"
16395 [(set (match_operand:TF 0 "register_operand" "=f,f")
16396 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
16397 [(reg 17) (const_int 0)])
16398 (match_operand:TF 2 "register_operand" "f,0")
16399 (match_operand:TF 3 "register_operand" "0,f")))]
16400 "TARGET_CMOVE"
16401 "@
16402 fcmov%F1\t{%2, %0|%0, %2}
16403 fcmov%f1\t{%3, %0|%0, %3}"
16404 [(set_attr "type" "fcmov")
16405 (set_attr "mode" "XF")])
16406
16407 (define_expand "minsf3"
16408 [(parallel [
16409 (set (match_operand:SF 0 "register_operand" "")
16410 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16411 (match_operand:SF 2 "nonimmediate_operand" ""))
16412 (match_dup 1)
16413 (match_dup 2)))
16414 (clobber (reg:CC 17))])]
16415 "TARGET_SSE"
16416 "")
16417
16418 (define_insn "*minsf"
16419 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16420 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16421 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16422 (match_dup 1)
16423 (match_dup 2)))
16424 (clobber (reg:CC 17))]
16425 "TARGET_SSE && TARGET_IEEE_FP"
16426 "#")
16427
16428 (define_insn "*minsf_nonieee"
16429 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16430 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16431 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16432 (match_dup 1)
16433 (match_dup 2)))
16434 (clobber (reg:CC 17))]
16435 "TARGET_SSE && !TARGET_IEEE_FP
16436 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16437 "#")
16438
16439 (define_split
16440 [(set (match_operand:SF 0 "register_operand" "")
16441 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16442 (match_operand:SF 2 "nonimmediate_operand" ""))
16443 (match_operand:SF 3 "register_operand" "")
16444 (match_operand:SF 4 "nonimmediate_operand" "")))
16445 (clobber (reg:CC 17))]
16446 "SSE_REG_P (operands[0]) && reload_completed
16447 && ((operands_match_p (operands[1], operands[3])
16448 && operands_match_p (operands[2], operands[4]))
16449 || (operands_match_p (operands[1], operands[4])
16450 && operands_match_p (operands[2], operands[3])))"
16451 [(set (match_dup 0)
16452 (if_then_else:SF (lt (match_dup 1)
16453 (match_dup 2))
16454 (match_dup 1)
16455 (match_dup 2)))])
16456
16457 ;; We can't represent the LT test directly. Do this by swapping the operands.
16458
16459 (define_split
16460 [(set (match_operand:SF 0 "fp_register_operand" "")
16461 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16462 (match_operand:SF 2 "register_operand" ""))
16463 (match_operand:SF 3 "register_operand" "")
16464 (match_operand:SF 4 "register_operand" "")))
16465 (clobber (reg:CC 17))]
16466 "reload_completed
16467 && ((operands_match_p (operands[1], operands[3])
16468 && operands_match_p (operands[2], operands[4]))
16469 || (operands_match_p (operands[1], operands[4])
16470 && operands_match_p (operands[2], operands[3])))"
16471 [(set (reg:CCFP 17)
16472 (compare:CCFP (match_dup 2)
16473 (match_dup 1)))
16474 (set (match_dup 0)
16475 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16476 (match_dup 1)
16477 (match_dup 2)))])
16478
16479 (define_insn "*minsf_sse"
16480 [(set (match_operand:SF 0 "register_operand" "=x")
16481 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16482 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16483 (match_dup 1)
16484 (match_dup 2)))]
16485 "TARGET_SSE && reload_completed"
16486 "minss\t{%2, %0|%0, %2}"
16487 [(set_attr "type" "sse")
16488 (set_attr "mode" "SF")])
16489
16490 (define_expand "mindf3"
16491 [(parallel [
16492 (set (match_operand:DF 0 "register_operand" "")
16493 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16494 (match_operand:DF 2 "nonimmediate_operand" ""))
16495 (match_dup 1)
16496 (match_dup 2)))
16497 (clobber (reg:CC 17))])]
16498 "TARGET_SSE2 && TARGET_SSE_MATH"
16499 "#")
16500
16501 (define_insn "*mindf"
16502 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16503 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16504 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16505 (match_dup 1)
16506 (match_dup 2)))
16507 (clobber (reg:CC 17))]
16508 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16509 "#")
16510
16511 (define_insn "*mindf_nonieee"
16512 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16513 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16514 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16515 (match_dup 1)
16516 (match_dup 2)))
16517 (clobber (reg:CC 17))]
16518 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16519 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16520 "#")
16521
16522 (define_split
16523 [(set (match_operand:DF 0 "register_operand" "")
16524 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16525 (match_operand:DF 2 "nonimmediate_operand" ""))
16526 (match_operand:DF 3 "register_operand" "")
16527 (match_operand:DF 4 "nonimmediate_operand" "")))
16528 (clobber (reg:CC 17))]
16529 "SSE_REG_P (operands[0]) && reload_completed
16530 && ((operands_match_p (operands[1], operands[3])
16531 && operands_match_p (operands[2], operands[4]))
16532 || (operands_match_p (operands[1], operands[4])
16533 && operands_match_p (operands[2], operands[3])))"
16534 [(set (match_dup 0)
16535 (if_then_else:DF (lt (match_dup 1)
16536 (match_dup 2))
16537 (match_dup 1)
16538 (match_dup 2)))])
16539
16540 ;; We can't represent the LT test directly. Do this by swapping the operands.
16541 (define_split
16542 [(set (match_operand:DF 0 "fp_register_operand" "")
16543 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16544 (match_operand:DF 2 "register_operand" ""))
16545 (match_operand:DF 3 "register_operand" "")
16546 (match_operand:DF 4 "register_operand" "")))
16547 (clobber (reg:CC 17))]
16548 "reload_completed
16549 && ((operands_match_p (operands[1], operands[3])
16550 && operands_match_p (operands[2], operands[4]))
16551 || (operands_match_p (operands[1], operands[4])
16552 && operands_match_p (operands[2], operands[3])))"
16553 [(set (reg:CCFP 17)
16554 (compare:CCFP (match_dup 2)
16555 (match_dup 2)))
16556 (set (match_dup 0)
16557 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16558 (match_dup 1)
16559 (match_dup 2)))])
16560
16561 (define_insn "*mindf_sse"
16562 [(set (match_operand:DF 0 "register_operand" "=Y")
16563 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16564 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16565 (match_dup 1)
16566 (match_dup 2)))]
16567 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16568 "minsd\t{%2, %0|%0, %2}"
16569 [(set_attr "type" "sse")
16570 (set_attr "mode" "DF")])
16571
16572 (define_expand "maxsf3"
16573 [(parallel [
16574 (set (match_operand:SF 0 "register_operand" "")
16575 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16576 (match_operand:SF 2 "nonimmediate_operand" ""))
16577 (match_dup 1)
16578 (match_dup 2)))
16579 (clobber (reg:CC 17))])]
16580 "TARGET_SSE"
16581 "#")
16582
16583 (define_insn "*maxsf"
16584 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16585 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16586 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16587 (match_dup 1)
16588 (match_dup 2)))
16589 (clobber (reg:CC 17))]
16590 "TARGET_SSE && TARGET_IEEE_FP"
16591 "#")
16592
16593 (define_insn "*maxsf_nonieee"
16594 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16595 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16596 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16597 (match_dup 1)
16598 (match_dup 2)))
16599 (clobber (reg:CC 17))]
16600 "TARGET_SSE && !TARGET_IEEE_FP
16601 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16602 "#")
16603
16604 (define_split
16605 [(set (match_operand:SF 0 "register_operand" "")
16606 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16607 (match_operand:SF 2 "nonimmediate_operand" ""))
16608 (match_operand:SF 3 "register_operand" "")
16609 (match_operand:SF 4 "nonimmediate_operand" "")))
16610 (clobber (reg:CC 17))]
16611 "SSE_REG_P (operands[0]) && reload_completed
16612 && ((operands_match_p (operands[1], operands[3])
16613 && operands_match_p (operands[2], operands[4]))
16614 || (operands_match_p (operands[1], operands[4])
16615 && operands_match_p (operands[2], operands[3])))"
16616 [(set (match_dup 0)
16617 (if_then_else:SF (gt (match_dup 1)
16618 (match_dup 2))
16619 (match_dup 1)
16620 (match_dup 2)))])
16621
16622 (define_split
16623 [(set (match_operand:SF 0 "fp_register_operand" "")
16624 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16625 (match_operand:SF 2 "register_operand" ""))
16626 (match_operand:SF 3 "register_operand" "")
16627 (match_operand:SF 4 "register_operand" "")))
16628 (clobber (reg:CC 17))]
16629 "reload_completed
16630 && ((operands_match_p (operands[1], operands[3])
16631 && operands_match_p (operands[2], operands[4]))
16632 || (operands_match_p (operands[1], operands[4])
16633 && operands_match_p (operands[2], operands[3])))"
16634 [(set (reg:CCFP 17)
16635 (compare:CCFP (match_dup 1)
16636 (match_dup 2)))
16637 (set (match_dup 0)
16638 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16639 (match_dup 1)
16640 (match_dup 2)))])
16641
16642 (define_insn "*maxsf_sse"
16643 [(set (match_operand:SF 0 "register_operand" "=x")
16644 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16645 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16646 (match_dup 1)
16647 (match_dup 2)))]
16648 "TARGET_SSE && reload_completed"
16649 "maxss\t{%2, %0|%0, %2}"
16650 [(set_attr "type" "sse")
16651 (set_attr "mode" "SF")])
16652
16653 (define_expand "maxdf3"
16654 [(parallel [
16655 (set (match_operand:DF 0 "register_operand" "")
16656 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16657 (match_operand:DF 2 "nonimmediate_operand" ""))
16658 (match_dup 1)
16659 (match_dup 2)))
16660 (clobber (reg:CC 17))])]
16661 "TARGET_SSE2 && TARGET_SSE_MATH"
16662 "#")
16663
16664 (define_insn "*maxdf"
16665 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16666 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16667 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16668 (match_dup 1)
16669 (match_dup 2)))
16670 (clobber (reg:CC 17))]
16671 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16672 "#")
16673
16674 (define_insn "*maxdf_nonieee"
16675 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16676 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16677 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16678 (match_dup 1)
16679 (match_dup 2)))
16680 (clobber (reg:CC 17))]
16681 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16682 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16683 "#")
16684
16685 (define_split
16686 [(set (match_operand:DF 0 "register_operand" "")
16687 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16688 (match_operand:DF 2 "nonimmediate_operand" ""))
16689 (match_operand:DF 3 "register_operand" "")
16690 (match_operand:DF 4 "nonimmediate_operand" "")))
16691 (clobber (reg:CC 17))]
16692 "SSE_REG_P (operands[0]) && reload_completed
16693 && ((operands_match_p (operands[1], operands[3])
16694 && operands_match_p (operands[2], operands[4]))
16695 || (operands_match_p (operands[1], operands[4])
16696 && operands_match_p (operands[2], operands[3])))"
16697 [(set (match_dup 0)
16698 (if_then_else:DF (gt (match_dup 1)
16699 (match_dup 2))
16700 (match_dup 1)
16701 (match_dup 2)))])
16702
16703 (define_split
16704 [(set (match_operand:DF 0 "fp_register_operand" "")
16705 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16706 (match_operand:DF 2 "register_operand" ""))
16707 (match_operand:DF 3 "register_operand" "")
16708 (match_operand:DF 4 "register_operand" "")))
16709 (clobber (reg:CC 17))]
16710 "reload_completed
16711 && ((operands_match_p (operands[1], operands[3])
16712 && operands_match_p (operands[2], operands[4]))
16713 || (operands_match_p (operands[1], operands[4])
16714 && operands_match_p (operands[2], operands[3])))"
16715 [(set (reg:CCFP 17)
16716 (compare:CCFP (match_dup 1)
16717 (match_dup 2)))
16718 (set (match_dup 0)
16719 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16720 (match_dup 1)
16721 (match_dup 2)))])
16722
16723 (define_insn "*maxdf_sse"
16724 [(set (match_operand:DF 0 "register_operand" "=Y")
16725 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16726 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16727 (match_dup 1)
16728 (match_dup 2)))]
16729 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16730 "maxsd\t{%2, %0|%0, %2}"
16731 [(set_attr "type" "sse")
16732 (set_attr "mode" "DF")])
16733 \f
16734 ;; Misc patterns (?)
16735
16736 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16737 ;; Otherwise there will be nothing to keep
16738 ;;
16739 ;; [(set (reg ebp) (reg esp))]
16740 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16741 ;; (clobber (eflags)]
16742 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16743 ;;
16744 ;; in proper program order.
16745 (define_expand "pro_epilogue_adjust_stack"
16746 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
16747 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16748 (match_operand:SI 2 "immediate_operand" "i,i")))
16749 (clobber (reg:CC 17))
16750 (clobber (mem:BLK (scratch)))])]
16751 ""
16752 {
16753 if (TARGET_64BIT)
16754 {
16755 emit_insn (gen_pro_epilogue_adjust_stack_rex64
16756 (operands[0], operands[1], operands[2]));
16757 DONE;
16758 }
16759 })
16760
16761 (define_insn "*pro_epilogue_adjust_stack_1"
16762 [(set (match_operand:SI 0 "register_operand" "=r,r")
16763 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16764 (match_operand:SI 2 "immediate_operand" "i,i")))
16765 (clobber (reg:CC 17))
16766 (clobber (mem:BLK (scratch)))]
16767 "!TARGET_64BIT"
16768 {
16769 switch (get_attr_type (insn))
16770 {
16771 case TYPE_IMOV:
16772 return "mov{l}\t{%1, %0|%0, %1}";
16773
16774 case TYPE_ALU:
16775 if (GET_CODE (operands[2]) == CONST_INT
16776 && (INTVAL (operands[2]) == 128
16777 || (INTVAL (operands[2]) < 0
16778 && INTVAL (operands[2]) != -128)))
16779 {
16780 operands[2] = GEN_INT (-INTVAL (operands[2]));
16781 return "sub{l}\t{%2, %0|%0, %2}";
16782 }
16783 return "add{l}\t{%2, %0|%0, %2}";
16784
16785 case TYPE_LEA:
16786 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16787 return "lea{l}\t{%a2, %0|%0, %a2}";
16788
16789 default:
16790 abort ();
16791 }
16792 }
16793 [(set (attr "type")
16794 (cond [(eq_attr "alternative" "0")
16795 (const_string "alu")
16796 (match_operand:SI 2 "const0_operand" "")
16797 (const_string "imov")
16798 ]
16799 (const_string "lea")))
16800 (set_attr "mode" "SI")])
16801
16802 (define_insn "pro_epilogue_adjust_stack_rex64"
16803 [(set (match_operand:DI 0 "register_operand" "=r,r")
16804 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16805 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16806 (clobber (reg:CC 17))
16807 (clobber (mem:BLK (scratch)))]
16808 "TARGET_64BIT"
16809 {
16810 switch (get_attr_type (insn))
16811 {
16812 case TYPE_IMOV:
16813 return "mov{q}\t{%1, %0|%0, %1}";
16814
16815 case TYPE_ALU:
16816 if (GET_CODE (operands[2]) == CONST_INT
16817 && (INTVAL (operands[2]) == 128
16818 || (INTVAL (operands[2]) < 0
16819 && INTVAL (operands[2]) != -128)))
16820 {
16821 operands[2] = GEN_INT (-INTVAL (operands[2]));
16822 return "sub{q}\t{%2, %0|%0, %2}";
16823 }
16824 return "add{q}\t{%2, %0|%0, %2}";
16825
16826 case TYPE_LEA:
16827 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16828 return "lea{q}\t{%a2, %0|%0, %a2}";
16829
16830 default:
16831 abort ();
16832 }
16833 }
16834 [(set (attr "type")
16835 (cond [(eq_attr "alternative" "0")
16836 (const_string "alu")
16837 (match_operand:DI 2 "const0_operand" "")
16838 (const_string "imov")
16839 ]
16840 (const_string "lea")))
16841 (set_attr "mode" "DI")])
16842
16843
16844 ;; Placeholder for the conditional moves. This one is split either to SSE
16845 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16846 ;; fact is that compares supported by the cmp??ss instructions are exactly
16847 ;; swapped of those supported by cmove sequence.
16848 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16849 ;; supported by i387 comparisons and we do need to emit two conditional moves
16850 ;; in tandem.
16851
16852 (define_insn "sse_movsfcc"
16853 [(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")
16854 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16855 [(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")
16856 (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")])
16857 (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")
16858 (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")))
16859 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16860 (clobber (reg:CC 17))]
16861 "TARGET_SSE
16862 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16863 /* Avoid combine from being smart and converting min/max
16864 instruction patterns into conditional moves. */
16865 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16866 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16867 || !rtx_equal_p (operands[4], operands[2])
16868 || !rtx_equal_p (operands[5], operands[3]))
16869 && (!TARGET_IEEE_FP
16870 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16871 "#")
16872
16873 (define_insn "sse_movsfcc_eq"
16874 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16875 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16876 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16877 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16878 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16879 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16880 (clobber (reg:CC 17))]
16881 "TARGET_SSE
16882 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16883 "#")
16884
16885 (define_insn "sse_movdfcc"
16886 [(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")
16887 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16888 [(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")
16889 (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")])
16890 (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")
16891 (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")))
16892 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16893 (clobber (reg:CC 17))]
16894 "TARGET_SSE2
16895 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16896 /* Avoid combine from being smart and converting min/max
16897 instruction patterns into conditional moves. */
16898 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16899 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16900 || !rtx_equal_p (operands[4], operands[2])
16901 || !rtx_equal_p (operands[5], operands[3]))
16902 && (!TARGET_IEEE_FP
16903 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16904 "#")
16905
16906 (define_insn "sse_movdfcc_eq"
16907 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16908 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16909 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16910 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16911 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
16912 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16913 (clobber (reg:CC 17))]
16914 "TARGET_SSE
16915 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16916 "#")
16917
16918 ;; For non-sse moves just expand the usual cmove sequence.
16919 (define_split
16920 [(set (match_operand 0 "register_operand" "")
16921 (if_then_else (match_operator 1 "comparison_operator"
16922 [(match_operand 4 "nonimmediate_operand" "")
16923 (match_operand 5 "register_operand" "")])
16924 (match_operand 2 "nonimmediate_operand" "")
16925 (match_operand 3 "nonimmediate_operand" "")))
16926 (clobber (match_operand 6 "" ""))
16927 (clobber (reg:CC 17))]
16928 "!SSE_REG_P (operands[0]) && reload_completed
16929 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16930 [(const_int 0)]
16931 {
16932 ix86_compare_op0 = operands[5];
16933 ix86_compare_op1 = operands[4];
16934 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16935 VOIDmode, operands[5], operands[4]);
16936 ix86_expand_fp_movcc (operands);
16937 DONE;
16938 })
16939
16940 ;; Split SSE based conditional move into seqence:
16941 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
16942 ;; and op2, op0 - zero op2 if comparison was false
16943 ;; nand op0, op3 - load op3 to op0 if comparison was false
16944 ;; or op2, op0 - get the nonzero one into the result.
16945 (define_split
16946 [(set (match_operand 0 "register_operand" "")
16947 (if_then_else (match_operator 1 "sse_comparison_operator"
16948 [(match_operand 4 "register_operand" "")
16949 (match_operand 5 "nonimmediate_operand" "")])
16950 (match_operand 2 "register_operand" "")
16951 (match_operand 3 "register_operand" "")))
16952 (clobber (match_operand 6 "" ""))
16953 (clobber (reg:CC 17))]
16954 "SSE_REG_P (operands[0]) && reload_completed"
16955 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16956 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
16957 (subreg:TI (match_dup 4) 0)))
16958 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
16959 (subreg:TI (match_dup 3) 0)))
16960 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16961 (subreg:TI (match_dup 7) 0)))]
16962 {
16963 if (GET_MODE (operands[2]) == DFmode
16964 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
16965 {
16966 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
16967 emit_insn (gen_sse2_unpcklpd (op, op, op));
16968 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
16969 emit_insn (gen_sse2_unpcklpd (op, op, op));
16970 }
16971 /* If op2 == op3, op3 will be clobbered before it is used.
16972 This should be optimized out though. */
16973 if (operands_match_p (operands[2], operands[3]))
16974 abort ();
16975 PUT_MODE (operands[1], GET_MODE (operands[0]));
16976 if (operands_match_p (operands[0], operands[4]))
16977 operands[6] = operands[4], operands[7] = operands[2];
16978 else
16979 operands[6] = operands[2], operands[7] = operands[4];
16980 })
16981
16982 ;; Special case of conditional move we can handle effectivly.
16983 ;; Do not brother with the integer/floating point case, since these are
16984 ;; bot considerably slower, unlike in the generic case.
16985 (define_insn "*sse_movsfcc_const0_1"
16986 [(set (match_operand:SF 0 "register_operand" "=&x")
16987 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16988 [(match_operand:SF 4 "register_operand" "0")
16989 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16990 (match_operand:SF 2 "register_operand" "x")
16991 (match_operand:SF 3 "const0_operand" "X")))]
16992 "TARGET_SSE"
16993 "#")
16994
16995 (define_insn "*sse_movsfcc_const0_2"
16996 [(set (match_operand:SF 0 "register_operand" "=&x")
16997 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16998 [(match_operand:SF 4 "register_operand" "0")
16999 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17000 (match_operand:SF 2 "const0_operand" "X")
17001 (match_operand:SF 3 "register_operand" "x")))]
17002 "TARGET_SSE"
17003 "#")
17004
17005 (define_insn "*sse_movsfcc_const0_3"
17006 [(set (match_operand:SF 0 "register_operand" "=&x")
17007 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17008 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17009 (match_operand:SF 5 "register_operand" "0")])
17010 (match_operand:SF 2 "register_operand" "x")
17011 (match_operand:SF 3 "const0_operand" "X")))]
17012 "TARGET_SSE"
17013 "#")
17014
17015 (define_insn "*sse_movsfcc_const0_4"
17016 [(set (match_operand:SF 0 "register_operand" "=&x")
17017 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17018 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17019 (match_operand:SF 5 "register_operand" "0")])
17020 (match_operand:SF 2 "const0_operand" "X")
17021 (match_operand:SF 3 "register_operand" "x")))]
17022 "TARGET_SSE"
17023 "#")
17024
17025 (define_insn "*sse_movdfcc_const0_1"
17026 [(set (match_operand:DF 0 "register_operand" "=&Y")
17027 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17028 [(match_operand:DF 4 "register_operand" "0")
17029 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17030 (match_operand:DF 2 "register_operand" "Y")
17031 (match_operand:DF 3 "const0_operand" "X")))]
17032 "TARGET_SSE2"
17033 "#")
17034
17035 (define_insn "*sse_movdfcc_const0_2"
17036 [(set (match_operand:DF 0 "register_operand" "=&Y")
17037 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17038 [(match_operand:DF 4 "register_operand" "0")
17039 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17040 (match_operand:DF 2 "const0_operand" "X")
17041 (match_operand:DF 3 "register_operand" "Y")))]
17042 "TARGET_SSE2"
17043 "#")
17044
17045 (define_insn "*sse_movdfcc_const0_3"
17046 [(set (match_operand:DF 0 "register_operand" "=&Y")
17047 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17048 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17049 (match_operand:DF 5 "register_operand" "0")])
17050 (match_operand:DF 2 "register_operand" "Y")
17051 (match_operand:DF 3 "const0_operand" "X")))]
17052 "TARGET_SSE2"
17053 "#")
17054
17055 (define_insn "*sse_movdfcc_const0_4"
17056 [(set (match_operand:DF 0 "register_operand" "=&Y")
17057 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17058 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17059 (match_operand:DF 5 "register_operand" "0")])
17060 (match_operand:DF 2 "const0_operand" "X")
17061 (match_operand:DF 3 "register_operand" "Y")))]
17062 "TARGET_SSE2"
17063 "#")
17064
17065 (define_split
17066 [(set (match_operand 0 "register_operand" "")
17067 (if_then_else (match_operator 1 "comparison_operator"
17068 [(match_operand 4 "register_operand" "")
17069 (match_operand 5 "nonimmediate_operand" "")])
17070 (match_operand 2 "nonmemory_operand" "")
17071 (match_operand 3 "nonmemory_operand" "")))]
17072 "SSE_REG_P (operands[0]) && reload_completed
17073 && (const0_operand (operands[2], GET_MODE (operands[0]))
17074 || const0_operand (operands[3], GET_MODE (operands[0])))"
17075 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17076 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17077 (match_dup 7)))]
17078 {
17079 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17080 && GET_MODE (operands[2]) == DFmode)
17081 {
17082 if (REG_P (operands[2]))
17083 {
17084 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17085 emit_insn (gen_sse2_unpcklpd (op, op, op));
17086 }
17087 if (REG_P (operands[3]))
17088 {
17089 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17090 emit_insn (gen_sse2_unpcklpd (op, op, op));
17091 }
17092 }
17093 PUT_MODE (operands[1], GET_MODE (operands[0]));
17094 if (!sse_comparison_operator (operands[1], VOIDmode))
17095 {
17096 rtx tmp = operands[5];
17097 operands[5] = operands[4];
17098 operands[4] = tmp;
17099 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17100 }
17101 if (const0_operand (operands[2], GET_MODE (operands[0])))
17102 {
17103 operands[7] = operands[3];
17104 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17105 0));
17106 }
17107 else
17108 {
17109 operands[7] = operands[2];
17110 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17111 }
17112 operands[7] = simplify_gen_subreg (TImode, operands[7],
17113 GET_MODE (operands[7]), 0);
17114 })
17115
17116 (define_expand "allocate_stack_worker"
17117 [(match_operand:SI 0 "register_operand" "")]
17118 "TARGET_STACK_PROBE"
17119 {
17120 if (TARGET_64BIT)
17121 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17122 else
17123 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17124 DONE;
17125 })
17126
17127 (define_insn "allocate_stack_worker_1"
17128 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17129 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17130 (clobber (match_dup 0))
17131 (clobber (reg:CC 17))]
17132 "!TARGET_64BIT && TARGET_STACK_PROBE"
17133 "call\t__alloca"
17134 [(set_attr "type" "multi")
17135 (set_attr "length" "5")])
17136
17137 (define_insn "allocate_stack_worker_rex64"
17138 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17139 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17140 (clobber (match_dup 0))
17141 (clobber (reg:CC 17))]
17142 "TARGET_64BIT && TARGET_STACK_PROBE"
17143 "call\t__alloca"
17144 [(set_attr "type" "multi")
17145 (set_attr "length" "5")])
17146
17147 (define_expand "allocate_stack"
17148 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17149 (minus:SI (reg:SI 7)
17150 (match_operand:SI 1 "general_operand" "")))
17151 (clobber (reg:CC 17))])
17152 (parallel [(set (reg:SI 7)
17153 (minus:SI (reg:SI 7) (match_dup 1)))
17154 (clobber (reg:CC 17))])]
17155 "TARGET_STACK_PROBE"
17156 {
17157 #ifdef CHECK_STACK_LIMIT
17158 if (GET_CODE (operands[1]) == CONST_INT
17159 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17160 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17161 operands[1]));
17162 else
17163 #endif
17164 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17165 operands[1])));
17166
17167 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17168 DONE;
17169 })
17170
17171 (define_expand "builtin_setjmp_receiver"
17172 [(label_ref (match_operand 0 "" ""))]
17173 "!TARGET_64BIT && flag_pic"
17174 {
17175 emit_insn (gen_set_got (pic_offset_table_rtx));
17176 DONE;
17177 })
17178 \f
17179 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17180
17181 (define_split
17182 [(set (match_operand 0 "register_operand" "")
17183 (match_operator 3 "promotable_binary_operator"
17184 [(match_operand 1 "register_operand" "")
17185 (match_operand 2 "aligned_operand" "")]))
17186 (clobber (reg:CC 17))]
17187 "! TARGET_PARTIAL_REG_STALL && reload_completed
17188 && ((GET_MODE (operands[0]) == HImode
17189 && ((!optimize_size && !TARGET_FAST_PREFIX)
17190 || GET_CODE (operands[2]) != CONST_INT
17191 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17192 || (GET_MODE (operands[0]) == QImode
17193 && (TARGET_PROMOTE_QImode || optimize_size)))"
17194 [(parallel [(set (match_dup 0)
17195 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17196 (clobber (reg:CC 17))])]
17197 "operands[0] = gen_lowpart (SImode, operands[0]);
17198 operands[1] = gen_lowpart (SImode, operands[1]);
17199 if (GET_CODE (operands[3]) != ASHIFT)
17200 operands[2] = gen_lowpart (SImode, operands[2]);
17201 PUT_MODE (operands[3], SImode);")
17202
17203 (define_split
17204 [(set (reg 17)
17205 (compare (and (match_operand 1 "aligned_operand" "")
17206 (match_operand 2 "const_int_operand" ""))
17207 (const_int 0)))
17208 (set (match_operand 0 "register_operand" "")
17209 (and (match_dup 1) (match_dup 2)))]
17210 "! TARGET_PARTIAL_REG_STALL && reload_completed
17211 && ix86_match_ccmode (insn, CCNOmode)
17212 && (GET_MODE (operands[0]) == HImode
17213 || (GET_MODE (operands[0]) == QImode
17214 /* Ensure that the operand will remain sign extended immediate. */
17215 && INTVAL (operands[2]) >= 0
17216 && (TARGET_PROMOTE_QImode || optimize_size)))"
17217 [(parallel [(set (reg:CCNO 17)
17218 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17219 (const_int 0)))
17220 (set (match_dup 0)
17221 (and:SI (match_dup 1) (match_dup 2)))])]
17222 "operands[2]
17223 = gen_int_mode (INTVAL (operands[2])
17224 & GET_MODE_MASK (GET_MODE (operands[0])),
17225 SImode);
17226 operands[0] = gen_lowpart (SImode, operands[0]);
17227 operands[1] = gen_lowpart (SImode, operands[1]);")
17228
17229 ; Don't promote the QImode tests, as i386 don't have encoding of
17230 ; the test instruction with 32bit sign extended immediate and thus
17231 ; the code grows.
17232 (define_split
17233 [(set (reg 17)
17234 (compare (and (match_operand:HI 0 "aligned_operand" "")
17235 (match_operand:HI 1 "const_int_operand" ""))
17236 (const_int 0)))]
17237 "! TARGET_PARTIAL_REG_STALL && reload_completed
17238 && ix86_match_ccmode (insn, CCNOmode)
17239 && GET_MODE (operands[0]) == HImode"
17240 [(set (reg:CCNO 17)
17241 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17242 (const_int 0)))]
17243 "operands[1]
17244 = gen_int_mode (INTVAL (operands[1])
17245 & GET_MODE_MASK (GET_MODE (operands[0])),
17246 SImode);
17247 operands[0] = gen_lowpart (SImode, operands[0]);")
17248
17249 (define_split
17250 [(set (match_operand 0 "register_operand" "")
17251 (neg (match_operand 1 "register_operand" "")))
17252 (clobber (reg:CC 17))]
17253 "! TARGET_PARTIAL_REG_STALL && reload_completed
17254 && (GET_MODE (operands[0]) == HImode
17255 || (GET_MODE (operands[0]) == QImode
17256 && (TARGET_PROMOTE_QImode || optimize_size)))"
17257 [(parallel [(set (match_dup 0)
17258 (neg:SI (match_dup 1)))
17259 (clobber (reg:CC 17))])]
17260 "operands[0] = gen_lowpart (SImode, operands[0]);
17261 operands[1] = gen_lowpart (SImode, operands[1]);")
17262
17263 (define_split
17264 [(set (match_operand 0 "register_operand" "")
17265 (not (match_operand 1 "register_operand" "")))]
17266 "! TARGET_PARTIAL_REG_STALL && reload_completed
17267 && (GET_MODE (operands[0]) == HImode
17268 || (GET_MODE (operands[0]) == QImode
17269 && (TARGET_PROMOTE_QImode || optimize_size)))"
17270 [(set (match_dup 0)
17271 (not:SI (match_dup 1)))]
17272 "operands[0] = gen_lowpart (SImode, operands[0]);
17273 operands[1] = gen_lowpart (SImode, operands[1]);")
17274
17275 (define_split
17276 [(set (match_operand 0 "register_operand" "")
17277 (if_then_else (match_operator 1 "comparison_operator"
17278 [(reg 17) (const_int 0)])
17279 (match_operand 2 "register_operand" "")
17280 (match_operand 3 "register_operand" "")))]
17281 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17282 && (GET_MODE (operands[0]) == HImode
17283 || (GET_MODE (operands[0]) == QImode
17284 && (TARGET_PROMOTE_QImode || optimize_size)))"
17285 [(set (match_dup 0)
17286 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17287 "operands[0] = gen_lowpart (SImode, operands[0]);
17288 operands[2] = gen_lowpart (SImode, operands[2]);
17289 operands[3] = gen_lowpart (SImode, operands[3]);")
17290
17291 \f
17292 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17293 ;; transform a complex memory operation into two memory to register operations.
17294
17295 ;; Don't push memory operands
17296 (define_peephole2
17297 [(set (match_operand:SI 0 "push_operand" "")
17298 (match_operand:SI 1 "memory_operand" ""))
17299 (match_scratch:SI 2 "r")]
17300 "! optimize_size && ! TARGET_PUSH_MEMORY"
17301 [(set (match_dup 2) (match_dup 1))
17302 (set (match_dup 0) (match_dup 2))]
17303 "")
17304
17305 (define_peephole2
17306 [(set (match_operand:DI 0 "push_operand" "")
17307 (match_operand:DI 1 "memory_operand" ""))
17308 (match_scratch:DI 2 "r")]
17309 "! optimize_size && ! TARGET_PUSH_MEMORY"
17310 [(set (match_dup 2) (match_dup 1))
17311 (set (match_dup 0) (match_dup 2))]
17312 "")
17313
17314 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17315 ;; SImode pushes.
17316 (define_peephole2
17317 [(set (match_operand:SF 0 "push_operand" "")
17318 (match_operand:SF 1 "memory_operand" ""))
17319 (match_scratch:SF 2 "r")]
17320 "! optimize_size && ! TARGET_PUSH_MEMORY"
17321 [(set (match_dup 2) (match_dup 1))
17322 (set (match_dup 0) (match_dup 2))]
17323 "")
17324
17325 (define_peephole2
17326 [(set (match_operand:HI 0 "push_operand" "")
17327 (match_operand:HI 1 "memory_operand" ""))
17328 (match_scratch:HI 2 "r")]
17329 "! optimize_size && ! TARGET_PUSH_MEMORY"
17330 [(set (match_dup 2) (match_dup 1))
17331 (set (match_dup 0) (match_dup 2))]
17332 "")
17333
17334 (define_peephole2
17335 [(set (match_operand:QI 0 "push_operand" "")
17336 (match_operand:QI 1 "memory_operand" ""))
17337 (match_scratch:QI 2 "q")]
17338 "! optimize_size && ! TARGET_PUSH_MEMORY"
17339 [(set (match_dup 2) (match_dup 1))
17340 (set (match_dup 0) (match_dup 2))]
17341 "")
17342
17343 ;; Don't move an immediate directly to memory when the instruction
17344 ;; gets too big.
17345 (define_peephole2
17346 [(match_scratch:SI 1 "r")
17347 (set (match_operand:SI 0 "memory_operand" "")
17348 (const_int 0))]
17349 "! optimize_size
17350 && ! TARGET_USE_MOV0
17351 && TARGET_SPLIT_LONG_MOVES
17352 && get_attr_length (insn) >= ix86_cost->large_insn
17353 && peep2_regno_dead_p (0, FLAGS_REG)"
17354 [(parallel [(set (match_dup 1) (const_int 0))
17355 (clobber (reg:CC 17))])
17356 (set (match_dup 0) (match_dup 1))]
17357 "")
17358
17359 (define_peephole2
17360 [(match_scratch:HI 1 "r")
17361 (set (match_operand:HI 0 "memory_operand" "")
17362 (const_int 0))]
17363 "! optimize_size
17364 && ! TARGET_USE_MOV0
17365 && TARGET_SPLIT_LONG_MOVES
17366 && get_attr_length (insn) >= ix86_cost->large_insn
17367 && peep2_regno_dead_p (0, FLAGS_REG)"
17368 [(parallel [(set (match_dup 2) (const_int 0))
17369 (clobber (reg:CC 17))])
17370 (set (match_dup 0) (match_dup 1))]
17371 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
17372
17373 (define_peephole2
17374 [(match_scratch:QI 1 "q")
17375 (set (match_operand:QI 0 "memory_operand" "")
17376 (const_int 0))]
17377 "! optimize_size
17378 && ! TARGET_USE_MOV0
17379 && TARGET_SPLIT_LONG_MOVES
17380 && get_attr_length (insn) >= ix86_cost->large_insn
17381 && peep2_regno_dead_p (0, FLAGS_REG)"
17382 [(parallel [(set (match_dup 2) (const_int 0))
17383 (clobber (reg:CC 17))])
17384 (set (match_dup 0) (match_dup 1))]
17385 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
17386
17387 (define_peephole2
17388 [(match_scratch:SI 2 "r")
17389 (set (match_operand:SI 0 "memory_operand" "")
17390 (match_operand:SI 1 "immediate_operand" ""))]
17391 "! optimize_size
17392 && get_attr_length (insn) >= ix86_cost->large_insn
17393 && TARGET_SPLIT_LONG_MOVES"
17394 [(set (match_dup 2) (match_dup 1))
17395 (set (match_dup 0) (match_dup 2))]
17396 "")
17397
17398 (define_peephole2
17399 [(match_scratch:HI 2 "r")
17400 (set (match_operand:HI 0 "memory_operand" "")
17401 (match_operand:HI 1 "immediate_operand" ""))]
17402 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17403 && TARGET_SPLIT_LONG_MOVES"
17404 [(set (match_dup 2) (match_dup 1))
17405 (set (match_dup 0) (match_dup 2))]
17406 "")
17407
17408 (define_peephole2
17409 [(match_scratch:QI 2 "q")
17410 (set (match_operand:QI 0 "memory_operand" "")
17411 (match_operand:QI 1 "immediate_operand" ""))]
17412 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17413 && TARGET_SPLIT_LONG_MOVES"
17414 [(set (match_dup 2) (match_dup 1))
17415 (set (match_dup 0) (match_dup 2))]
17416 "")
17417
17418 ;; Don't compare memory with zero, load and use a test instead.
17419 (define_peephole2
17420 [(set (reg 17)
17421 (compare (match_operand:SI 0 "memory_operand" "")
17422 (const_int 0)))
17423 (match_scratch:SI 3 "r")]
17424 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17425 [(set (match_dup 3) (match_dup 0))
17426 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17427 "")
17428
17429 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17430 ;; Don't split NOTs with a displacement operand, because resulting XOR
17431 ;; will not be pariable anyway.
17432 ;;
17433 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17434 ;; represented using a modRM byte. The XOR replacement is long decoded,
17435 ;; so this split helps here as well.
17436 ;;
17437 ;; Note: Can't do this as a regular split because we can't get proper
17438 ;; lifetime information then.
17439
17440 (define_peephole2
17441 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17442 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17443 "!optimize_size
17444 && peep2_regno_dead_p (0, FLAGS_REG)
17445 && ((TARGET_PENTIUM
17446 && (GET_CODE (operands[0]) != MEM
17447 || !memory_displacement_operand (operands[0], SImode)))
17448 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17449 [(parallel [(set (match_dup 0)
17450 (xor:SI (match_dup 1) (const_int -1)))
17451 (clobber (reg:CC 17))])]
17452 "")
17453
17454 (define_peephole2
17455 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17456 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17457 "!optimize_size
17458 && peep2_regno_dead_p (0, FLAGS_REG)
17459 && ((TARGET_PENTIUM
17460 && (GET_CODE (operands[0]) != MEM
17461 || !memory_displacement_operand (operands[0], HImode)))
17462 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17463 [(parallel [(set (match_dup 0)
17464 (xor:HI (match_dup 1) (const_int -1)))
17465 (clobber (reg:CC 17))])]
17466 "")
17467
17468 (define_peephole2
17469 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17470 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17471 "!optimize_size
17472 && peep2_regno_dead_p (0, FLAGS_REG)
17473 && ((TARGET_PENTIUM
17474 && (GET_CODE (operands[0]) != MEM
17475 || !memory_displacement_operand (operands[0], QImode)))
17476 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17477 [(parallel [(set (match_dup 0)
17478 (xor:QI (match_dup 1) (const_int -1)))
17479 (clobber (reg:CC 17))])]
17480 "")
17481
17482 ;; Non pairable "test imm, reg" instructions can be translated to
17483 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17484 ;; byte opcode instead of two, have a short form for byte operands),
17485 ;; so do it for other CPUs as well. Given that the value was dead,
17486 ;; this should not create any new dependencies. Pass on the sub-word
17487 ;; versions if we're concerned about partial register stalls.
17488
17489 (define_peephole2
17490 [(set (reg 17)
17491 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17492 (match_operand:SI 1 "immediate_operand" ""))
17493 (const_int 0)))]
17494 "ix86_match_ccmode (insn, CCNOmode)
17495 && (true_regnum (operands[0]) != 0
17496 || (GET_CODE (operands[1]) == CONST_INT
17497 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17498 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17499 [(parallel
17500 [(set (reg:CCNO 17)
17501 (compare:CCNO (and:SI (match_dup 0)
17502 (match_dup 1))
17503 (const_int 0)))
17504 (set (match_dup 0)
17505 (and:SI (match_dup 0) (match_dup 1)))])]
17506 "")
17507
17508 ;; We don't need to handle HImode case, because it will be promoted to SImode
17509 ;; on ! TARGET_PARTIAL_REG_STALL
17510
17511 (define_peephole2
17512 [(set (reg 17)
17513 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17514 (match_operand:QI 1 "immediate_operand" ""))
17515 (const_int 0)))]
17516 "! TARGET_PARTIAL_REG_STALL
17517 && ix86_match_ccmode (insn, CCNOmode)
17518 && true_regnum (operands[0]) != 0
17519 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17520 [(parallel
17521 [(set (reg:CCNO 17)
17522 (compare:CCNO (and:QI (match_dup 0)
17523 (match_dup 1))
17524 (const_int 0)))
17525 (set (match_dup 0)
17526 (and:QI (match_dup 0) (match_dup 1)))])]
17527 "")
17528
17529 (define_peephole2
17530 [(set (reg 17)
17531 (compare
17532 (and:SI
17533 (zero_extract:SI
17534 (match_operand 0 "ext_register_operand" "")
17535 (const_int 8)
17536 (const_int 8))
17537 (match_operand 1 "const_int_operand" ""))
17538 (const_int 0)))]
17539 "! TARGET_PARTIAL_REG_STALL
17540 && ix86_match_ccmode (insn, CCNOmode)
17541 && true_regnum (operands[0]) != 0
17542 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17543 [(parallel [(set (reg:CCNO 17)
17544 (compare:CCNO
17545 (and:SI
17546 (zero_extract:SI
17547 (match_dup 0)
17548 (const_int 8)
17549 (const_int 8))
17550 (match_dup 1))
17551 (const_int 0)))
17552 (set (zero_extract:SI (match_dup 0)
17553 (const_int 8)
17554 (const_int 8))
17555 (and:SI
17556 (zero_extract:SI
17557 (match_dup 0)
17558 (const_int 8)
17559 (const_int 8))
17560 (match_dup 1)))])]
17561 "")
17562
17563 ;; Don't do logical operations with memory inputs.
17564 (define_peephole2
17565 [(match_scratch:SI 2 "r")
17566 (parallel [(set (match_operand:SI 0 "register_operand" "")
17567 (match_operator:SI 3 "arith_or_logical_operator"
17568 [(match_dup 0)
17569 (match_operand:SI 1 "memory_operand" "")]))
17570 (clobber (reg:CC 17))])]
17571 "! optimize_size && ! TARGET_READ_MODIFY"
17572 [(set (match_dup 2) (match_dup 1))
17573 (parallel [(set (match_dup 0)
17574 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17575 (clobber (reg:CC 17))])]
17576 "")
17577
17578 (define_peephole2
17579 [(match_scratch:SI 2 "r")
17580 (parallel [(set (match_operand:SI 0 "register_operand" "")
17581 (match_operator:SI 3 "arith_or_logical_operator"
17582 [(match_operand:SI 1 "memory_operand" "")
17583 (match_dup 0)]))
17584 (clobber (reg:CC 17))])]
17585 "! optimize_size && ! TARGET_READ_MODIFY"
17586 [(set (match_dup 2) (match_dup 1))
17587 (parallel [(set (match_dup 0)
17588 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17589 (clobber (reg:CC 17))])]
17590 "")
17591
17592 ; Don't do logical operations with memory outputs
17593 ;
17594 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17595 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17596 ; the same decoder scheduling characteristics as the original.
17597
17598 (define_peephole2
17599 [(match_scratch:SI 2 "r")
17600 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17601 (match_operator:SI 3 "arith_or_logical_operator"
17602 [(match_dup 0)
17603 (match_operand:SI 1 "nonmemory_operand" "")]))
17604 (clobber (reg:CC 17))])]
17605 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17606 [(set (match_dup 2) (match_dup 0))
17607 (parallel [(set (match_dup 2)
17608 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17609 (clobber (reg:CC 17))])
17610 (set (match_dup 0) (match_dup 2))]
17611 "")
17612
17613 (define_peephole2
17614 [(match_scratch:SI 2 "r")
17615 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17616 (match_operator:SI 3 "arith_or_logical_operator"
17617 [(match_operand:SI 1 "nonmemory_operand" "")
17618 (match_dup 0)]))
17619 (clobber (reg:CC 17))])]
17620 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17621 [(set (match_dup 2) (match_dup 0))
17622 (parallel [(set (match_dup 2)
17623 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17624 (clobber (reg:CC 17))])
17625 (set (match_dup 0) (match_dup 2))]
17626 "")
17627
17628 ;; Attempt to always use XOR for zeroing registers.
17629 (define_peephole2
17630 [(set (match_operand 0 "register_operand" "")
17631 (const_int 0))]
17632 "(GET_MODE (operands[0]) == QImode
17633 || GET_MODE (operands[0]) == HImode
17634 || GET_MODE (operands[0]) == SImode
17635 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17636 && (! TARGET_USE_MOV0 || optimize_size)
17637 && peep2_regno_dead_p (0, FLAGS_REG)"
17638 [(parallel [(set (match_dup 0) (const_int 0))
17639 (clobber (reg:CC 17))])]
17640 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17641 true_regnum (operands[0]));")
17642
17643 (define_peephole2
17644 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17645 (const_int 0))]
17646 "(GET_MODE (operands[0]) == QImode
17647 || GET_MODE (operands[0]) == HImode)
17648 && (! TARGET_USE_MOV0 || optimize_size)
17649 && peep2_regno_dead_p (0, FLAGS_REG)"
17650 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17651 (clobber (reg:CC 17))])])
17652
17653 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17654 (define_peephole2
17655 [(set (match_operand 0 "register_operand" "")
17656 (const_int -1))]
17657 "(GET_MODE (operands[0]) == HImode
17658 || GET_MODE (operands[0]) == SImode
17659 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17660 && (optimize_size || TARGET_PENTIUM)
17661 && peep2_regno_dead_p (0, FLAGS_REG)"
17662 [(parallel [(set (match_dup 0) (const_int -1))
17663 (clobber (reg:CC 17))])]
17664 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17665 true_regnum (operands[0]));")
17666
17667 ;; Attempt to convert simple leas to adds. These can be created by
17668 ;; move expanders.
17669 (define_peephole2
17670 [(set (match_operand:SI 0 "register_operand" "")
17671 (plus:SI (match_dup 0)
17672 (match_operand:SI 1 "nonmemory_operand" "")))]
17673 "peep2_regno_dead_p (0, FLAGS_REG)"
17674 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17675 (clobber (reg:CC 17))])]
17676 "")
17677
17678 (define_peephole2
17679 [(set (match_operand:SI 0 "register_operand" "")
17680 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17681 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17682 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17683 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17684 (clobber (reg:CC 17))])]
17685 "operands[2] = gen_lowpart (SImode, operands[2]);")
17686
17687 (define_peephole2
17688 [(set (match_operand:DI 0 "register_operand" "")
17689 (plus:DI (match_dup 0)
17690 (match_operand:DI 1 "x86_64_general_operand" "")))]
17691 "peep2_regno_dead_p (0, FLAGS_REG)"
17692 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17693 (clobber (reg:CC 17))])]
17694 "")
17695
17696 (define_peephole2
17697 [(set (match_operand:SI 0 "register_operand" "")
17698 (mult:SI (match_dup 0)
17699 (match_operand:SI 1 "const_int_operand" "")))]
17700 "exact_log2 (INTVAL (operands[1])) >= 0
17701 && peep2_regno_dead_p (0, FLAGS_REG)"
17702 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17703 (clobber (reg:CC 17))])]
17704 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17705
17706 (define_peephole2
17707 [(set (match_operand:DI 0 "register_operand" "")
17708 (mult:DI (match_dup 0)
17709 (match_operand:DI 1 "const_int_operand" "")))]
17710 "exact_log2 (INTVAL (operands[1])) >= 0
17711 && peep2_regno_dead_p (0, FLAGS_REG)"
17712 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17713 (clobber (reg:CC 17))])]
17714 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17715
17716 (define_peephole2
17717 [(set (match_operand:SI 0 "register_operand" "")
17718 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17719 (match_operand:DI 2 "const_int_operand" "")) 0))]
17720 "exact_log2 (INTVAL (operands[2])) >= 0
17721 && REGNO (operands[0]) == REGNO (operands[1])
17722 && peep2_regno_dead_p (0, FLAGS_REG)"
17723 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17724 (clobber (reg:CC 17))])]
17725 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17726
17727 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17728 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17729 ;; many CPUs it is also faster, since special hardware to avoid esp
17730 ;; dependencies is present.
17731
17732 ;; While some of these conversions may be done using splitters, we use peepholes
17733 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17734
17735 ;; Convert prologue esp subtractions to push.
17736 ;; We need register to push. In order to keep verify_flow_info happy we have
17737 ;; two choices
17738 ;; - use scratch and clobber it in order to avoid dependencies
17739 ;; - use already live register
17740 ;; We can't use the second way right now, since there is no reliable way how to
17741 ;; verify that given register is live. First choice will also most likely in
17742 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17743 ;; call clobbered registers are dead. We may want to use base pointer as an
17744 ;; alternative when no register is available later.
17745
17746 (define_peephole2
17747 [(match_scratch:SI 0 "r")
17748 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17749 (clobber (reg:CC 17))
17750 (clobber (mem:BLK (scratch)))])]
17751 "optimize_size || !TARGET_SUB_ESP_4"
17752 [(clobber (match_dup 0))
17753 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17754 (clobber (mem:BLK (scratch)))])])
17755
17756 (define_peephole2
17757 [(match_scratch:SI 0 "r")
17758 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17759 (clobber (reg:CC 17))
17760 (clobber (mem:BLK (scratch)))])]
17761 "optimize_size || !TARGET_SUB_ESP_8"
17762 [(clobber (match_dup 0))
17763 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17764 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17765 (clobber (mem:BLK (scratch)))])])
17766
17767 ;; Convert esp subtractions to push.
17768 (define_peephole2
17769 [(match_scratch:SI 0 "r")
17770 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17771 (clobber (reg:CC 17))])]
17772 "optimize_size || !TARGET_SUB_ESP_4"
17773 [(clobber (match_dup 0))
17774 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17775
17776 (define_peephole2
17777 [(match_scratch:SI 0 "r")
17778 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17779 (clobber (reg:CC 17))])]
17780 "optimize_size || !TARGET_SUB_ESP_8"
17781 [(clobber (match_dup 0))
17782 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17783 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17784
17785 ;; Convert epilogue deallocator to pop.
17786 (define_peephole2
17787 [(match_scratch:SI 0 "r")
17788 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17789 (clobber (reg:CC 17))
17790 (clobber (mem:BLK (scratch)))])]
17791 "optimize_size || !TARGET_ADD_ESP_4"
17792 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17793 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17794 (clobber (mem:BLK (scratch)))])]
17795 "")
17796
17797 ;; Two pops case is tricky, since pop causes dependency on destination register.
17798 ;; We use two registers if available.
17799 (define_peephole2
17800 [(match_scratch:SI 0 "r")
17801 (match_scratch:SI 1 "r")
17802 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17803 (clobber (reg:CC 17))
17804 (clobber (mem:BLK (scratch)))])]
17805 "optimize_size || !TARGET_ADD_ESP_8"
17806 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17807 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17808 (clobber (mem:BLK (scratch)))])
17809 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17810 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17811 "")
17812
17813 (define_peephole2
17814 [(match_scratch:SI 0 "r")
17815 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17816 (clobber (reg:CC 17))
17817 (clobber (mem:BLK (scratch)))])]
17818 "optimize_size"
17819 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17820 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17821 (clobber (mem:BLK (scratch)))])
17822 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17823 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17824 "")
17825
17826 ;; Convert esp additions to pop.
17827 (define_peephole2
17828 [(match_scratch:SI 0 "r")
17829 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17830 (clobber (reg:CC 17))])]
17831 ""
17832 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17833 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17834 "")
17835
17836 ;; Two pops case is tricky, since pop causes dependency on destination register.
17837 ;; We use two registers if available.
17838 (define_peephole2
17839 [(match_scratch:SI 0 "r")
17840 (match_scratch:SI 1 "r")
17841 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17842 (clobber (reg:CC 17))])]
17843 ""
17844 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17845 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17846 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17847 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17848 "")
17849
17850 (define_peephole2
17851 [(match_scratch:SI 0 "r")
17852 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17853 (clobber (reg:CC 17))])]
17854 "optimize_size"
17855 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17856 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17857 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17858 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17859 "")
17860 \f
17861 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17862 ;; required and register dies.
17863 (define_peephole2
17864 [(set (reg 17)
17865 (compare (match_operand:SI 0 "register_operand" "")
17866 (match_operand:SI 1 "incdec_operand" "")))]
17867 "ix86_match_ccmode (insn, CCGCmode)
17868 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17869 [(parallel [(set (reg:CCGC 17)
17870 (compare:CCGC (match_dup 0)
17871 (match_dup 1)))
17872 (clobber (match_dup 0))])]
17873 "")
17874
17875 (define_peephole2
17876 [(set (reg 17)
17877 (compare (match_operand:HI 0 "register_operand" "")
17878 (match_operand:HI 1 "incdec_operand" "")))]
17879 "ix86_match_ccmode (insn, CCGCmode)
17880 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17881 [(parallel [(set (reg:CCGC 17)
17882 (compare:CCGC (match_dup 0)
17883 (match_dup 1)))
17884 (clobber (match_dup 0))])]
17885 "")
17886
17887 (define_peephole2
17888 [(set (reg 17)
17889 (compare (match_operand:QI 0 "register_operand" "")
17890 (match_operand:QI 1 "incdec_operand" "")))]
17891 "ix86_match_ccmode (insn, CCGCmode)
17892 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17893 [(parallel [(set (reg:CCGC 17)
17894 (compare:CCGC (match_dup 0)
17895 (match_dup 1)))
17896 (clobber (match_dup 0))])]
17897 "")
17898
17899 ;; Convert compares with 128 to shorter add -128
17900 (define_peephole2
17901 [(set (reg 17)
17902 (compare (match_operand:SI 0 "register_operand" "")
17903 (const_int 128)))]
17904 "ix86_match_ccmode (insn, CCGCmode)
17905 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17906 [(parallel [(set (reg:CCGC 17)
17907 (compare:CCGC (match_dup 0)
17908 (const_int 128)))
17909 (clobber (match_dup 0))])]
17910 "")
17911
17912 (define_peephole2
17913 [(set (reg 17)
17914 (compare (match_operand:HI 0 "register_operand" "")
17915 (const_int 128)))]
17916 "ix86_match_ccmode (insn, CCGCmode)
17917 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17918 [(parallel [(set (reg:CCGC 17)
17919 (compare:CCGC (match_dup 0)
17920 (const_int 128)))
17921 (clobber (match_dup 0))])]
17922 "")
17923 \f
17924 (define_peephole2
17925 [(match_scratch:DI 0 "r")
17926 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17927 (clobber (reg:CC 17))
17928 (clobber (mem:BLK (scratch)))])]
17929 "optimize_size || !TARGET_SUB_ESP_4"
17930 [(clobber (match_dup 0))
17931 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17932 (clobber (mem:BLK (scratch)))])])
17933
17934 (define_peephole2
17935 [(match_scratch:DI 0 "r")
17936 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17937 (clobber (reg:CC 17))
17938 (clobber (mem:BLK (scratch)))])]
17939 "optimize_size || !TARGET_SUB_ESP_8"
17940 [(clobber (match_dup 0))
17941 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17942 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17943 (clobber (mem:BLK (scratch)))])])
17944
17945 ;; Convert esp subtractions to push.
17946 (define_peephole2
17947 [(match_scratch:DI 0 "r")
17948 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17949 (clobber (reg:CC 17))])]
17950 "optimize_size || !TARGET_SUB_ESP_4"
17951 [(clobber (match_dup 0))
17952 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17953
17954 (define_peephole2
17955 [(match_scratch:DI 0 "r")
17956 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17957 (clobber (reg:CC 17))])]
17958 "optimize_size || !TARGET_SUB_ESP_8"
17959 [(clobber (match_dup 0))
17960 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17961 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17962
17963 ;; Convert epilogue deallocator to pop.
17964 (define_peephole2
17965 [(match_scratch:DI 0 "r")
17966 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17967 (clobber (reg:CC 17))
17968 (clobber (mem:BLK (scratch)))])]
17969 "optimize_size || !TARGET_ADD_ESP_4"
17970 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17971 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17972 (clobber (mem:BLK (scratch)))])]
17973 "")
17974
17975 ;; Two pops case is tricky, since pop causes dependency on destination register.
17976 ;; We use two registers if available.
17977 (define_peephole2
17978 [(match_scratch:DI 0 "r")
17979 (match_scratch:DI 1 "r")
17980 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17981 (clobber (reg:CC 17))
17982 (clobber (mem:BLK (scratch)))])]
17983 "optimize_size || !TARGET_ADD_ESP_8"
17984 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17985 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17986 (clobber (mem:BLK (scratch)))])
17987 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17988 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17989 "")
17990
17991 (define_peephole2
17992 [(match_scratch:DI 0 "r")
17993 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17994 (clobber (reg:CC 17))
17995 (clobber (mem:BLK (scratch)))])]
17996 "optimize_size"
17997 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17998 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17999 (clobber (mem:BLK (scratch)))])
18000 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18001 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18002 "")
18003
18004 ;; Convert esp additions to pop.
18005 (define_peephole2
18006 [(match_scratch:DI 0 "r")
18007 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18008 (clobber (reg:CC 17))])]
18009 ""
18010 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18011 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18012 "")
18013
18014 ;; Two pops case is tricky, since pop causes dependency on destination register.
18015 ;; We use two registers if available.
18016 (define_peephole2
18017 [(match_scratch:DI 0 "r")
18018 (match_scratch:DI 1 "r")
18019 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18020 (clobber (reg:CC 17))])]
18021 ""
18022 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18023 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18024 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18025 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18026 "")
18027
18028 (define_peephole2
18029 [(match_scratch:DI 0 "r")
18030 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18031 (clobber (reg:CC 17))])]
18032 "optimize_size"
18033 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18034 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18035 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18036 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18037 "")
18038 \f
18039 ;; Call-value patterns last so that the wildcard operand does not
18040 ;; disrupt insn-recog's switch tables.
18041
18042 (define_insn "*call_value_pop_0"
18043 [(set (match_operand 0 "" "")
18044 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18045 (match_operand:SI 2 "" "")))
18046 (set (reg:SI 7) (plus:SI (reg:SI 7)
18047 (match_operand:SI 3 "immediate_operand" "")))]
18048 "!TARGET_64BIT"
18049 {
18050 if (SIBLING_CALL_P (insn))
18051 return "jmp\t%P1";
18052 else
18053 return "call\t%P1";
18054 }
18055 [(set_attr "type" "callv")])
18056
18057 (define_insn "*call_value_pop_1"
18058 [(set (match_operand 0 "" "")
18059 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18060 (match_operand:SI 2 "" "")))
18061 (set (reg:SI 7) (plus:SI (reg:SI 7)
18062 (match_operand:SI 3 "immediate_operand" "i")))]
18063 "!TARGET_64BIT"
18064 {
18065 if (constant_call_address_operand (operands[1], QImode))
18066 {
18067 if (SIBLING_CALL_P (insn))
18068 return "jmp\t%P1";
18069 else
18070 return "call\t%P1";
18071 }
18072 if (SIBLING_CALL_P (insn))
18073 return "jmp\t%A1";
18074 else
18075 return "call\t%A1";
18076 }
18077 [(set_attr "type" "callv")])
18078
18079 (define_insn "*call_value_0"
18080 [(set (match_operand 0 "" "")
18081 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18082 (match_operand:SI 2 "" "")))]
18083 "!TARGET_64BIT"
18084 {
18085 if (SIBLING_CALL_P (insn))
18086 return "jmp\t%P1";
18087 else
18088 return "call\t%P1";
18089 }
18090 [(set_attr "type" "callv")])
18091
18092 (define_insn "*call_value_0_rex64"
18093 [(set (match_operand 0 "" "")
18094 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18095 (match_operand:DI 2 "const_int_operand" "")))]
18096 "TARGET_64BIT"
18097 {
18098 if (SIBLING_CALL_P (insn))
18099 return "jmp\t%P1";
18100 else
18101 return "call\t%P1";
18102 }
18103 [(set_attr "type" "callv")])
18104
18105 (define_insn "*call_value_1"
18106 [(set (match_operand 0 "" "")
18107 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18108 (match_operand:SI 2 "" "")))]
18109 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18110 {
18111 if (constant_call_address_operand (operands[1], QImode))
18112 return "call\t%P1";
18113 return "call\t%*%1";
18114 }
18115 [(set_attr "type" "callv")])
18116
18117 (define_insn "*sibcall_value_1"
18118 [(set (match_operand 0 "" "")
18119 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18120 (match_operand:SI 2 "" "")))]
18121 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18122 {
18123 if (constant_call_address_operand (operands[1], QImode))
18124 return "jmp\t%P1";
18125 return "jmp\t%*%1";
18126 }
18127 [(set_attr "type" "callv")])
18128
18129 (define_insn "*call_value_1_rex64"
18130 [(set (match_operand 0 "" "")
18131 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18132 (match_operand:DI 2 "" "")))]
18133 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18134 {
18135 if (constant_call_address_operand (operands[1], QImode))
18136 return "call\t%P1";
18137 return "call\t%A1";
18138 }
18139 [(set_attr "type" "callv")])
18140
18141 (define_insn "*sibcall_value_1_rex64"
18142 [(set (match_operand 0 "" "")
18143 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18144 (match_operand:DI 2 "" "")))]
18145 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18146 "jmp\t%P1"
18147 [(set_attr "type" "callv")])
18148
18149 (define_insn "*sibcall_value_1_rex64_v"
18150 [(set (match_operand 0 "" "")
18151 (call (mem:QI (reg:DI 40))
18152 (match_operand:DI 1 "" "")))]
18153 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18154 "jmp\t*%%r11"
18155 [(set_attr "type" "callv")])
18156 \f
18157 (define_insn "trap"
18158 [(trap_if (const_int 1) (const_int 5))]
18159 ""
18160 "int\t$5")
18161
18162 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18163 ;;; for the sake of bounds checking. By emitting bounds checks as
18164 ;;; conditional traps rather than as conditional jumps around
18165 ;;; unconditional traps we avoid introducing spurious basic-block
18166 ;;; boundaries and facilitate elimination of redundant checks. In
18167 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18168 ;;; interrupt 5.
18169 ;;;
18170 ;;; FIXME: Static branch prediction rules for ix86 are such that
18171 ;;; forward conditional branches predict as untaken. As implemented
18172 ;;; below, pseudo conditional traps violate that rule. We should use
18173 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18174 ;;; section loaded at the end of the text segment and branch forward
18175 ;;; there on bounds-failure, and then jump back immediately (in case
18176 ;;; the system chooses to ignore bounds violations, or to report
18177 ;;; violations and continue execution).
18178
18179 (define_expand "conditional_trap"
18180 [(trap_if (match_operator 0 "comparison_operator"
18181 [(match_dup 2) (const_int 0)])
18182 (match_operand 1 "const_int_operand" ""))]
18183 ""
18184 {
18185 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18186 ix86_expand_compare (GET_CODE (operands[0]),
18187 NULL, NULL),
18188 operands[1]));
18189 DONE;
18190 })
18191
18192 (define_insn "*conditional_trap_1"
18193 [(trap_if (match_operator 0 "comparison_operator"
18194 [(reg 17) (const_int 0)])
18195 (match_operand 1 "const_int_operand" ""))]
18196 ""
18197 {
18198 operands[2] = gen_label_rtx ();
18199 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18200 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18201 CODE_LABEL_NUMBER (operands[2]));
18202 RET;
18203 })
18204
18205 ;; Pentium III SIMD instructions.
18206
18207 ;; Moves for SSE/MMX regs.
18208
18209 (define_insn "movv4sf_internal"
18210 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18211 (match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
18212 "TARGET_SSE"
18213 "movaps\t{%1, %0|%0, %1}"
18214 [(set_attr "type" "ssemov")
18215 (set_attr "mode" "V4SF")])
18216
18217 (define_split
18218 [(set (match_operand:V4SF 0 "register_operand" "")
18219 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18220 "TARGET_SSE"
18221 [(set (match_dup 0)
18222 (vec_merge:V4SF
18223 (vec_duplicate:V4SF (match_dup 1))
18224 (match_dup 2)
18225 (const_int 1)))]
18226 {
18227 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18228 operands[2] = CONST0_RTX (V4SFmode);
18229 })
18230
18231 (define_insn "movv4si_internal"
18232 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
18233 (match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
18234 "TARGET_SSE"
18235 {
18236 if (get_attr_mode (insn) == MODE_V4SF)
18237 return "movaps\t{%1, %0|%0, %1}";
18238 else
18239 return "movdqa\t{%1, %0|%0, %1}";
18240 }
18241 [(set_attr "type" "ssemov")
18242 (set (attr "mode")
18243 (cond [(eq_attr "alternative" "0")
18244 (if_then_else
18245 (ne (symbol_ref "optimize_size")
18246 (const_int 0))
18247 (const_string "V4SF")
18248 (const_string "TI"))
18249 (eq_attr "alternative" "1")
18250 (if_then_else
18251 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18252 (const_int 0))
18253 (ne (symbol_ref "optimize_size")
18254 (const_int 0)))
18255 (const_string "V4SF")
18256 (const_string "TI"))]
18257 (const_string "TI")))])
18258
18259 (define_insn "movv2di_internal"
18260 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,m")
18261 (match_operand:V2DI 1 "nonimmediate_operand" "xm,x"))]
18262 "TARGET_SSE2"
18263 {
18264 if (get_attr_mode (insn) == MODE_V4SF)
18265 return "movaps\t{%1, %0|%0, %1}";
18266 else
18267 return "movdqa\t{%1, %0|%0, %1}";
18268 }
18269 [(set_attr "type" "ssemov")
18270 (set (attr "mode")
18271 (cond [(eq_attr "alternative" "0")
18272 (if_then_else
18273 (ne (symbol_ref "optimize_size")
18274 (const_int 0))
18275 (const_string "V4SF")
18276 (const_string "TI"))
18277 (eq_attr "alternative" "1")
18278 (if_then_else
18279 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18280 (const_int 0))
18281 (ne (symbol_ref "optimize_size")
18282 (const_int 0)))
18283 (const_string "V4SF")
18284 (const_string "TI"))]
18285 (const_string "TI")))])
18286
18287 (define_split
18288 [(set (match_operand:V2DF 0 "register_operand" "")
18289 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18290 "TARGET_SSE2"
18291 [(set (match_dup 0)
18292 (vec_merge:V2DF
18293 (vec_duplicate:V2DF (match_dup 1))
18294 (match_dup 2)
18295 (const_int 1)))]
18296 {
18297 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18298 operands[2] = CONST0_RTX (V2DFmode);
18299 })
18300
18301 (define_insn "movv8qi_internal"
18302 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
18303 (match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
18304 "TARGET_MMX"
18305 "movq\t{%1, %0|%0, %1}"
18306 [(set_attr "type" "mmxmov")
18307 (set_attr "mode" "DI")])
18308
18309 (define_insn "movv4hi_internal"
18310 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
18311 (match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
18312 "TARGET_MMX"
18313 "movq\t{%1, %0|%0, %1}"
18314 [(set_attr "type" "mmxmov")
18315 (set_attr "mode" "DI")])
18316
18317 (define_insn "movv2si_internal"
18318 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
18319 (match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
18320 "TARGET_MMX"
18321 "movq\t{%1, %0|%0, %1}"
18322 [(set_attr "type" "mmxcvt")
18323 (set_attr "mode" "DI")])
18324
18325 (define_insn "movv2sf_internal"
18326 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
18327 (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
18328 "TARGET_3DNOW"
18329 "movq\\t{%1, %0|%0, %1}"
18330 [(set_attr "type" "mmxcvt")
18331 (set_attr "mode" "DI")])
18332
18333 (define_expand "movti"
18334 [(set (match_operand:TI 0 "general_operand" "")
18335 (match_operand:TI 1 "general_operand" ""))]
18336 "TARGET_SSE || TARGET_64BIT"
18337 {
18338 if (TARGET_64BIT)
18339 ix86_expand_move (TImode, operands);
18340 else
18341 ix86_expand_vector_move (TImode, operands);
18342 DONE;
18343 })
18344
18345 (define_insn "movv2df_internal"
18346 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
18347 (match_operand:V2DF 1 "nonimmediate_operand" "xm,x"))]
18348 "TARGET_SSE2"
18349 {
18350 if (get_attr_mode (insn) == MODE_V4SF)
18351 return "movaps\t{%1, %0|%0, %1}";
18352 else
18353 return "movapd\t{%1, %0|%0, %1}";
18354 }
18355 [(set_attr "type" "ssemov")
18356 (set (attr "mode")
18357 (cond [(eq_attr "alternative" "0")
18358 (if_then_else
18359 (ne (symbol_ref "optimize_size")
18360 (const_int 0))
18361 (const_string "V4SF")
18362 (const_string "V2DF"))
18363 (eq_attr "alternative" "1")
18364 (if_then_else
18365 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18366 (const_int 0))
18367 (ne (symbol_ref "optimize_size")
18368 (const_int 0)))
18369 (const_string "V4SF")
18370 (const_string "V2DF"))]
18371 (const_string "V2DF")))])
18372
18373 (define_insn "movv8hi_internal"
18374 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
18375 (match_operand:V8HI 1 "nonimmediate_operand" "xm,x"))]
18376 "TARGET_SSE2"
18377 {
18378 if (get_attr_mode (insn) == MODE_V4SF)
18379 return "movaps\t{%1, %0|%0, %1}";
18380 else
18381 return "movdqa\t{%1, %0|%0, %1}";
18382 }
18383 [(set_attr "type" "ssemov")
18384 (set (attr "mode")
18385 (cond [(eq_attr "alternative" "0")
18386 (if_then_else
18387 (ne (symbol_ref "optimize_size")
18388 (const_int 0))
18389 (const_string "V4SF")
18390 (const_string "TI"))
18391 (eq_attr "alternative" "1")
18392 (if_then_else
18393 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18394 (const_int 0))
18395 (ne (symbol_ref "optimize_size")
18396 (const_int 0)))
18397 (const_string "V4SF")
18398 (const_string "TI"))]
18399 (const_string "TI")))])
18400
18401 (define_insn "movv16qi_internal"
18402 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
18403 (match_operand:V16QI 1 "nonimmediate_operand" "xm,x"))]
18404 "TARGET_SSE2"
18405 {
18406 if (get_attr_mode (insn) == MODE_V4SF)
18407 return "movaps\t{%1, %0|%0, %1}";
18408 else
18409 return "movdqa\t{%1, %0|%0, %1}";
18410 }
18411 [(set_attr "type" "ssemov")
18412 (set (attr "mode")
18413 (cond [(eq_attr "alternative" "0")
18414 (if_then_else
18415 (ne (symbol_ref "optimize_size")
18416 (const_int 0))
18417 (const_string "V4SF")
18418 (const_string "TI"))
18419 (eq_attr "alternative" "1")
18420 (if_then_else
18421 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18422 (const_int 0))
18423 (ne (symbol_ref "optimize_size")
18424 (const_int 0)))
18425 (const_string "V4SF")
18426 (const_string "TI"))]
18427 (const_string "TI")))])
18428
18429 (define_expand "movv2df"
18430 [(set (match_operand:V2DF 0 "general_operand" "")
18431 (match_operand:V2DF 1 "general_operand" ""))]
18432 "TARGET_SSE2"
18433 {
18434 ix86_expand_vector_move (V2DFmode, operands);
18435 DONE;
18436 })
18437
18438 (define_expand "movv8hi"
18439 [(set (match_operand:V8HI 0 "general_operand" "")
18440 (match_operand:V8HI 1 "general_operand" ""))]
18441 "TARGET_SSE2"
18442 {
18443 ix86_expand_vector_move (V8HImode, operands);
18444 DONE;
18445 })
18446
18447 (define_expand "movv16qi"
18448 [(set (match_operand:V16QI 0 "general_operand" "")
18449 (match_operand:V16QI 1 "general_operand" ""))]
18450 "TARGET_SSE2"
18451 {
18452 ix86_expand_vector_move (V16QImode, operands);
18453 DONE;
18454 })
18455
18456 (define_expand "movv4sf"
18457 [(set (match_operand:V4SF 0 "general_operand" "")
18458 (match_operand:V4SF 1 "general_operand" ""))]
18459 "TARGET_SSE"
18460 {
18461 ix86_expand_vector_move (V4SFmode, operands);
18462 DONE;
18463 })
18464
18465 (define_expand "movv4si"
18466 [(set (match_operand:V4SI 0 "general_operand" "")
18467 (match_operand:V4SI 1 "general_operand" ""))]
18468 "TARGET_SSE"
18469 {
18470 ix86_expand_vector_move (V4SImode, operands);
18471 DONE;
18472 })
18473
18474 (define_expand "movv2di"
18475 [(set (match_operand:V2DI 0 "general_operand" "")
18476 (match_operand:V2DI 1 "general_operand" ""))]
18477 "TARGET_SSE"
18478 {
18479 ix86_expand_vector_move (V2DImode, operands);
18480 DONE;
18481 })
18482
18483 (define_expand "movv2si"
18484 [(set (match_operand:V2SI 0 "general_operand" "")
18485 (match_operand:V2SI 1 "general_operand" ""))]
18486 "TARGET_MMX"
18487 {
18488 ix86_expand_vector_move (V2SImode, operands);
18489 DONE;
18490 })
18491
18492 (define_expand "movv4hi"
18493 [(set (match_operand:V4HI 0 "general_operand" "")
18494 (match_operand:V4HI 1 "general_operand" ""))]
18495 "TARGET_MMX"
18496 {
18497 ix86_expand_vector_move (V4HImode, operands);
18498 DONE;
18499 })
18500
18501 (define_expand "movv8qi"
18502 [(set (match_operand:V8QI 0 "general_operand" "")
18503 (match_operand:V8QI 1 "general_operand" ""))]
18504 "TARGET_MMX"
18505 {
18506 ix86_expand_vector_move (V8QImode, operands);
18507 DONE;
18508 })
18509
18510 (define_expand "movv2sf"
18511 [(set (match_operand:V2SF 0 "general_operand" "")
18512 (match_operand:V2SF 1 "general_operand" ""))]
18513 "TARGET_3DNOW"
18514 {
18515 ix86_expand_vector_move (V2SFmode, operands);
18516 DONE;
18517 })
18518
18519 (define_insn_and_split "*pushti"
18520 [(set (match_operand:TI 0 "push_operand" "=<")
18521 (match_operand:TI 1 "nonmemory_operand" "x"))]
18522 "TARGET_SSE"
18523 "#"
18524 ""
18525 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18526 (set (mem:TI (reg:SI 7)) (match_dup 1))]
18527 ""
18528 [(set_attr "type" "multi")])
18529
18530 (define_insn_and_split "*pushv2df"
18531 [(set (match_operand:V2DF 0 "push_operand" "=<")
18532 (match_operand:V2DF 1 "nonmemory_operand" "x"))]
18533 "TARGET_SSE2"
18534 "#"
18535 ""
18536 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18537 (set (mem:V2DF (reg:SI 7)) (match_dup 1))]
18538 ""
18539 [(set_attr "type" "multi")])
18540
18541 (define_insn_and_split "*pushv2di"
18542 [(set (match_operand:V2DI 0 "push_operand" "=<")
18543 (match_operand:V2DI 1 "nonmemory_operand" "x"))]
18544 "TARGET_SSE2"
18545 "#"
18546 ""
18547 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18548 (set (mem:V2DI (reg:SI 7)) (match_dup 1))]
18549 ""
18550 [(set_attr "type" "multi")])
18551
18552 (define_insn_and_split "*pushv8hi"
18553 [(set (match_operand:V8HI 0 "push_operand" "=<")
18554 (match_operand:V8HI 1 "nonmemory_operand" "x"))]
18555 "TARGET_SSE2"
18556 "#"
18557 ""
18558 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18559 (set (mem:V8HI (reg:SI 7)) (match_dup 1))]
18560 ""
18561 [(set_attr "type" "multi")])
18562
18563 (define_insn_and_split "*pushv16qi"
18564 [(set (match_operand:V16QI 0 "push_operand" "=<")
18565 (match_operand:V16QI 1 "nonmemory_operand" "x"))]
18566 "TARGET_SSE2"
18567 "#"
18568 ""
18569 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18570 (set (mem:V16QI (reg:SI 7)) (match_dup 1))]
18571 ""
18572 [(set_attr "type" "multi")])
18573
18574 (define_insn_and_split "*pushv4sf"
18575 [(set (match_operand:V4SF 0 "push_operand" "=<")
18576 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
18577 "TARGET_SSE"
18578 "#"
18579 ""
18580 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18581 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
18582 ""
18583 [(set_attr "type" "multi")])
18584
18585 (define_insn_and_split "*pushv4si"
18586 [(set (match_operand:V4SI 0 "push_operand" "=<")
18587 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
18588 "TARGET_SSE"
18589 "#"
18590 ""
18591 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18592 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
18593 ""
18594 [(set_attr "type" "multi")])
18595
18596 (define_insn_and_split "*pushv2si"
18597 [(set (match_operand:V2SI 0 "push_operand" "=<")
18598 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
18599 "TARGET_MMX"
18600 "#"
18601 ""
18602 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18603 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
18604 ""
18605 [(set_attr "type" "mmx")])
18606
18607 (define_insn_and_split "*pushv4hi"
18608 [(set (match_operand:V4HI 0 "push_operand" "=<")
18609 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
18610 "TARGET_MMX"
18611 "#"
18612 ""
18613 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18614 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
18615 ""
18616 [(set_attr "type" "mmx")])
18617
18618 (define_insn_and_split "*pushv8qi"
18619 [(set (match_operand:V8QI 0 "push_operand" "=<")
18620 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
18621 "TARGET_MMX"
18622 "#"
18623 ""
18624 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18625 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
18626 ""
18627 [(set_attr "type" "mmx")])
18628
18629 (define_insn_and_split "*pushv2sf"
18630 [(set (match_operand:V2SF 0 "push_operand" "=<")
18631 (match_operand:V2SF 1 "nonmemory_operand" "y"))]
18632 "TARGET_3DNOW"
18633 "#"
18634 ""
18635 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18636 (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
18637 ""
18638 [(set_attr "type" "mmx")])
18639
18640 (define_insn "movti_internal"
18641 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18642 (match_operand:TI 1 "general_operand" "C,xm,x"))]
18643 "TARGET_SSE && !TARGET_64BIT"
18644 {
18645 switch (which_alternative)
18646 {
18647 case 0:
18648 if (get_attr_mode (insn) == MODE_V4SF)
18649 return "xorps\t%0, %0";
18650 else
18651 return "pxor\t%0, %0";
18652 case 1:
18653 case 2:
18654 if (get_attr_mode (insn) == MODE_V4SF)
18655 return "movaps\t{%1, %0|%0, %1}";
18656 else
18657 return "movdqa\t{%1, %0|%0, %1}";
18658 default:
18659 abort ();
18660 }
18661 }
18662 [(set_attr "type" "ssemov,ssemov,ssemov")
18663 (set (attr "mode")
18664 (cond [(eq_attr "alternative" "0,1")
18665 (if_then_else
18666 (ne (symbol_ref "optimize_size")
18667 (const_int 0))
18668 (const_string "V4SF")
18669 (const_string "TI"))
18670 (eq_attr "alternative" "2")
18671 (if_then_else
18672 (ne (symbol_ref "optimize_size")
18673 (const_int 0))
18674 (const_string "V4SF")
18675 (const_string "TI"))]
18676 (const_string "TI")))])
18677
18678 (define_insn "*movti_rex64"
18679 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
18680 (match_operand:TI 1 "general_operand" "riFo,riF,O,xm,x"))]
18681 "TARGET_64BIT
18682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18683 {
18684 switch (which_alternative)
18685 {
18686 case 0:
18687 case 1:
18688 return "#";
18689 case 2:
18690 if (get_attr_mode (insn) == MODE_V4SF)
18691 return "xorps\t%0, %0";
18692 else
18693 return "pxor\t%0, %0";
18694 case 3:
18695 case 4:
18696 if (get_attr_mode (insn) == MODE_V4SF)
18697 return "movaps\t{%1, %0|%0, %1}";
18698 else
18699 return "movdqa\t{%1, %0|%0, %1}";
18700 default:
18701 abort ();
18702 }
18703 }
18704 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18705 (set (attr "mode")
18706 (cond [(eq_attr "alternative" "2,3")
18707 (if_then_else
18708 (ne (symbol_ref "optimize_size")
18709 (const_int 0))
18710 (const_string "V4SF")
18711 (const_string "TI"))
18712 (eq_attr "alternative" "4")
18713 (if_then_else
18714 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18715 (const_int 0))
18716 (ne (symbol_ref "optimize_size")
18717 (const_int 0)))
18718 (const_string "V4SF")
18719 (const_string "TI"))]
18720 (const_string "DI")))])
18721
18722 (define_split
18723 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18724 (match_operand:TI 1 "general_operand" ""))]
18725 "reload_completed && !SSE_REG_P (operands[0])
18726 && !SSE_REG_P (operands[1])"
18727 [(const_int 0)]
18728 "ix86_split_long_move (operands); DONE;")
18729
18730 ;; These two patterns are useful for specifying exactly whether to use
18731 ;; movaps or movups
18732 (define_insn "sse_movaps"
18733 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18734 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
18735 UNSPEC_MOVA))]
18736 "TARGET_SSE"
18737 "@
18738 movaps\t{%1, %0|%0, %1}
18739 movaps\t{%1, %0|%0, %1}"
18740 [(set_attr "type" "ssemov,ssemov")
18741 (set_attr "mode" "V4SF")])
18742
18743 (define_insn "sse_movups"
18744 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18745 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
18746 UNSPEC_MOVU))]
18747 "TARGET_SSE"
18748 "@
18749 movups\t{%1, %0|%0, %1}
18750 movups\t{%1, %0|%0, %1}"
18751 [(set_attr "type" "ssecvt,ssecvt")
18752 (set_attr "mode" "V4SF")])
18753
18754
18755 ;; SSE Strange Moves.
18756
18757 (define_insn "sse_movmskps"
18758 [(set (match_operand:SI 0 "register_operand" "=r")
18759 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
18760 UNSPEC_MOVMSK))]
18761 "TARGET_SSE"
18762 "movmskps\t{%1, %0|%0, %1}"
18763 [(set_attr "type" "ssecvt")
18764 (set_attr "mode" "V4SF")])
18765
18766 (define_insn "mmx_pmovmskb"
18767 [(set (match_operand:SI 0 "register_operand" "=r")
18768 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
18769 UNSPEC_MOVMSK))]
18770 "TARGET_SSE || TARGET_3DNOW_A"
18771 "pmovmskb\t{%1, %0|%0, %1}"
18772 [(set_attr "type" "ssecvt")
18773 (set_attr "mode" "V4SF")])
18774
18775
18776 (define_insn "mmx_maskmovq"
18777 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
18778 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18779 (match_operand:V8QI 2 "register_operand" "y")]
18780 UNSPEC_MASKMOV))]
18781 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
18782 ;; @@@ check ordering of operands in intel/nonintel syntax
18783 "maskmovq\t{%2, %1|%1, %2}"
18784 [(set_attr "type" "mmxcvt")
18785 (set_attr "mode" "DI")])
18786
18787 (define_insn "mmx_maskmovq_rex"
18788 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
18789 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18790 (match_operand:V8QI 2 "register_operand" "y")]
18791 UNSPEC_MASKMOV))]
18792 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
18793 ;; @@@ check ordering of operands in intel/nonintel syntax
18794 "maskmovq\t{%2, %1|%1, %2}"
18795 [(set_attr "type" "mmxcvt")
18796 (set_attr "mode" "DI")])
18797
18798 (define_insn "sse_movntv4sf"
18799 [(set (match_operand:V4SF 0 "memory_operand" "=m")
18800 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
18801 UNSPEC_MOVNT))]
18802 "TARGET_SSE"
18803 "movntps\t{%1, %0|%0, %1}"
18804 [(set_attr "type" "ssemov")
18805 (set_attr "mode" "V4SF")])
18806
18807 (define_insn "sse_movntdi"
18808 [(set (match_operand:DI 0 "memory_operand" "=m")
18809 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
18810 UNSPEC_MOVNT))]
18811 "TARGET_SSE || TARGET_3DNOW_A"
18812 "movntq\t{%1, %0|%0, %1}"
18813 [(set_attr "type" "mmxmov")
18814 (set_attr "mode" "DI")])
18815
18816 (define_insn "sse_movhlps"
18817 [(set (match_operand:V4SF 0 "register_operand" "=x")
18818 (vec_merge:V4SF
18819 (match_operand:V4SF 1 "register_operand" "0")
18820 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18821 (parallel [(const_int 2)
18822 (const_int 3)
18823 (const_int 0)
18824 (const_int 1)]))
18825 (const_int 3)))]
18826 "TARGET_SSE"
18827 "movhlps\t{%2, %0|%0, %2}"
18828 [(set_attr "type" "ssecvt")
18829 (set_attr "mode" "V4SF")])
18830
18831 (define_insn "sse_movlhps"
18832 [(set (match_operand:V4SF 0 "register_operand" "=x")
18833 (vec_merge:V4SF
18834 (match_operand:V4SF 1 "register_operand" "0")
18835 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18836 (parallel [(const_int 2)
18837 (const_int 3)
18838 (const_int 0)
18839 (const_int 1)]))
18840 (const_int 12)))]
18841 "TARGET_SSE"
18842 "movlhps\t{%2, %0|%0, %2}"
18843 [(set_attr "type" "ssecvt")
18844 (set_attr "mode" "V4SF")])
18845
18846 (define_insn "sse_movhps"
18847 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18848 (vec_merge:V4SF
18849 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18850 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18851 (const_int 12)))]
18852 "TARGET_SSE
18853 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18854 "movhps\t{%2, %0|%0, %2}"
18855 [(set_attr "type" "ssecvt")
18856 (set_attr "mode" "V4SF")])
18857
18858 (define_insn "sse_movlps"
18859 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18860 (vec_merge:V4SF
18861 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18862 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18863 (const_int 3)))]
18864 "TARGET_SSE
18865 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18866 "movlps\t{%2, %0|%0, %2}"
18867 [(set_attr "type" "ssecvt")
18868 (set_attr "mode" "V4SF")])
18869
18870 (define_expand "sse_loadss"
18871 [(match_operand:V4SF 0 "register_operand" "")
18872 (match_operand:SF 1 "memory_operand" "")]
18873 "TARGET_SSE"
18874 {
18875 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
18876 CONST0_RTX (V4SFmode)));
18877 DONE;
18878 })
18879
18880 (define_insn "sse_loadss_1"
18881 [(set (match_operand:V4SF 0 "register_operand" "=x")
18882 (vec_merge:V4SF
18883 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
18884 (match_operand:V4SF 2 "const0_operand" "X")
18885 (const_int 1)))]
18886 "TARGET_SSE"
18887 "movss\t{%1, %0|%0, %1}"
18888 [(set_attr "type" "ssemov")
18889 (set_attr "mode" "SF")])
18890
18891 (define_insn "sse_movss"
18892 [(set (match_operand:V4SF 0 "register_operand" "=x")
18893 (vec_merge:V4SF
18894 (match_operand:V4SF 1 "register_operand" "0")
18895 (match_operand:V4SF 2 "register_operand" "x")
18896 (const_int 1)))]
18897 "TARGET_SSE"
18898 "movss\t{%2, %0|%0, %2}"
18899 [(set_attr "type" "ssemov")
18900 (set_attr "mode" "SF")])
18901
18902 (define_insn "sse_storess"
18903 [(set (match_operand:SF 0 "memory_operand" "=m")
18904 (vec_select:SF
18905 (match_operand:V4SF 1 "register_operand" "x")
18906 (parallel [(const_int 0)])))]
18907 "TARGET_SSE"
18908 "movss\t{%1, %0|%0, %1}"
18909 [(set_attr "type" "ssemov")
18910 (set_attr "mode" "SF")])
18911
18912 (define_insn "sse_shufps"
18913 [(set (match_operand:V4SF 0 "register_operand" "=x")
18914 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
18915 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
18916 (match_operand:SI 3 "immediate_operand" "i")]
18917 UNSPEC_SHUFFLE))]
18918 "TARGET_SSE"
18919 ;; @@@ check operand order for intel/nonintel syntax
18920 "shufps\t{%3, %2, %0|%0, %2, %3}"
18921 [(set_attr "type" "ssecvt")
18922 (set_attr "mode" "V4SF")])
18923
18924
18925 ;; SSE arithmetic
18926
18927 (define_insn "addv4sf3"
18928 [(set (match_operand:V4SF 0 "register_operand" "=x")
18929 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18930 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18931 "TARGET_SSE"
18932 "addps\t{%2, %0|%0, %2}"
18933 [(set_attr "type" "sseadd")
18934 (set_attr "mode" "V4SF")])
18935
18936 (define_insn "vmaddv4sf3"
18937 [(set (match_operand:V4SF 0 "register_operand" "=x")
18938 (vec_merge:V4SF
18939 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18940 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18941 (match_dup 1)
18942 (const_int 1)))]
18943 "TARGET_SSE"
18944 "addss\t{%2, %0|%0, %2}"
18945 [(set_attr "type" "sseadd")
18946 (set_attr "mode" "SF")])
18947
18948 (define_insn "subv4sf3"
18949 [(set (match_operand:V4SF 0 "register_operand" "=x")
18950 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18951 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18952 "TARGET_SSE"
18953 "subps\t{%2, %0|%0, %2}"
18954 [(set_attr "type" "sseadd")
18955 (set_attr "mode" "V4SF")])
18956
18957 (define_insn "vmsubv4sf3"
18958 [(set (match_operand:V4SF 0 "register_operand" "=x")
18959 (vec_merge:V4SF
18960 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18961 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18962 (match_dup 1)
18963 (const_int 1)))]
18964 "TARGET_SSE"
18965 "subss\t{%2, %0|%0, %2}"
18966 [(set_attr "type" "sseadd")
18967 (set_attr "mode" "SF")])
18968
18969 (define_insn "mulv4sf3"
18970 [(set (match_operand:V4SF 0 "register_operand" "=x")
18971 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18972 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18973 "TARGET_SSE"
18974 "mulps\t{%2, %0|%0, %2}"
18975 [(set_attr "type" "ssemul")
18976 (set_attr "mode" "V4SF")])
18977
18978 (define_insn "vmmulv4sf3"
18979 [(set (match_operand:V4SF 0 "register_operand" "=x")
18980 (vec_merge:V4SF
18981 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18982 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18983 (match_dup 1)
18984 (const_int 1)))]
18985 "TARGET_SSE"
18986 "mulss\t{%2, %0|%0, %2}"
18987 [(set_attr "type" "ssemul")
18988 (set_attr "mode" "SF")])
18989
18990 (define_insn "divv4sf3"
18991 [(set (match_operand:V4SF 0 "register_operand" "=x")
18992 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18993 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18994 "TARGET_SSE"
18995 "divps\t{%2, %0|%0, %2}"
18996 [(set_attr "type" "ssediv")
18997 (set_attr "mode" "V4SF")])
18998
18999 (define_insn "vmdivv4sf3"
19000 [(set (match_operand:V4SF 0 "register_operand" "=x")
19001 (vec_merge:V4SF
19002 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19003 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19004 (match_dup 1)
19005 (const_int 1)))]
19006 "TARGET_SSE"
19007 "divss\t{%2, %0|%0, %2}"
19008 [(set_attr "type" "ssediv")
19009 (set_attr "mode" "SF")])
19010
19011
19012 ;; SSE square root/reciprocal
19013
19014 (define_insn "rcpv4sf2"
19015 [(set (match_operand:V4SF 0 "register_operand" "=x")
19016 (unspec:V4SF
19017 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19018 "TARGET_SSE"
19019 "rcpps\t{%1, %0|%0, %1}"
19020 [(set_attr "type" "sse")
19021 (set_attr "mode" "V4SF")])
19022
19023 (define_insn "vmrcpv4sf2"
19024 [(set (match_operand:V4SF 0 "register_operand" "=x")
19025 (vec_merge:V4SF
19026 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19027 UNSPEC_RCP)
19028 (match_operand:V4SF 2 "register_operand" "0")
19029 (const_int 1)))]
19030 "TARGET_SSE"
19031 "rcpss\t{%1, %0|%0, %1}"
19032 [(set_attr "type" "sse")
19033 (set_attr "mode" "SF")])
19034
19035 (define_insn "rsqrtv4sf2"
19036 [(set (match_operand:V4SF 0 "register_operand" "=x")
19037 (unspec:V4SF
19038 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19039 "TARGET_SSE"
19040 "rsqrtps\t{%1, %0|%0, %1}"
19041 [(set_attr "type" "sse")
19042 (set_attr "mode" "V4SF")])
19043
19044 (define_insn "vmrsqrtv4sf2"
19045 [(set (match_operand:V4SF 0 "register_operand" "=x")
19046 (vec_merge:V4SF
19047 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19048 UNSPEC_RSQRT)
19049 (match_operand:V4SF 2 "register_operand" "0")
19050 (const_int 1)))]
19051 "TARGET_SSE"
19052 "rsqrtss\t{%1, %0|%0, %1}"
19053 [(set_attr "type" "sse")
19054 (set_attr "mode" "SF")])
19055
19056 (define_insn "sqrtv4sf2"
19057 [(set (match_operand:V4SF 0 "register_operand" "=x")
19058 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19059 "TARGET_SSE"
19060 "sqrtps\t{%1, %0|%0, %1}"
19061 [(set_attr "type" "sse")
19062 (set_attr "mode" "V4SF")])
19063
19064 (define_insn "vmsqrtv4sf2"
19065 [(set (match_operand:V4SF 0 "register_operand" "=x")
19066 (vec_merge:V4SF
19067 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19068 (match_operand:V4SF 2 "register_operand" "0")
19069 (const_int 1)))]
19070 "TARGET_SSE"
19071 "sqrtss\t{%1, %0|%0, %1}"
19072 [(set_attr "type" "sse")
19073 (set_attr "mode" "SF")])
19074
19075 ;; SSE logical operations.
19076
19077 ;; SSE defines logical operations on floating point values. This brings
19078 ;; interesting challenge to RTL representation where logicals are only valid
19079 ;; on integral types. We deal with this by representing the floating point
19080 ;; logical as logical on arguments casted to TImode as this is what hardware
19081 ;; really does. Unfortunately hardware requires the type information to be
19082 ;; present and thus we must avoid subregs from being simplified and elliminated
19083 ;; in later compilation phases.
19084 ;;
19085 ;; We have following variants from each instruction:
19086 ;; sse_andsf3 - the operation taking V4SF vector operands
19087 ;; and doing TImode cast on them
19088 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19089 ;; TImode, since backend insist on elliminating casts
19090 ;; on memory operands
19091 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19092 ;; We can not accept memory operand here as instruction reads
19093 ;; whole scalar. This is generated only post reload by GCC
19094 ;; scalar float operations that expands to logicals (fabs)
19095 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19096 ;; memory operand. Eventually combine can be able
19097 ;; to synthetize these using splitter.
19098 ;; sse2_anddf3, *sse2_anddf3_memory
19099 ;;
19100 ;;
19101 ;; These are not called andti3 etc. because we really really don't want
19102 ;; the compiler to widen DImode ands to TImode ands and then try to move
19103 ;; into DImode subregs of SSE registers, and them together, and move out
19104 ;; of DImode subregs again!
19105 ;; SSE1 single precision floating point logical operation
19106 (define_expand "sse_andv4sf3"
19107 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19108 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19109 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19110 "TARGET_SSE"
19111 "")
19112
19113 (define_insn "*sse_andv4sf3"
19114 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19115 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19116 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19117 "TARGET_SSE
19118 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19119 "andps\t{%2, %0|%0, %2}"
19120 [(set_attr "type" "sselog")
19121 (set_attr "mode" "V4SF")])
19122
19123 (define_insn "*sse_andsf3"
19124 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19125 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19126 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19127 "TARGET_SSE
19128 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19129 "andps\t{%2, %0|%0, %2}"
19130 [(set_attr "type" "sselog")
19131 (set_attr "mode" "V4SF")])
19132
19133 (define_expand "sse_nandv4sf3"
19134 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19135 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19136 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19137 "TARGET_SSE"
19138 "")
19139
19140 (define_insn "*sse_nandv4sf3"
19141 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19142 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19143 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19144 "TARGET_SSE"
19145 "andnps\t{%2, %0|%0, %2}"
19146 [(set_attr "type" "sselog")
19147 (set_attr "mode" "V4SF")])
19148
19149 (define_insn "*sse_nandsf3"
19150 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19151 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19152 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19153 "TARGET_SSE"
19154 "andnps\t{%2, %0|%0, %2}"
19155 [(set_attr "type" "sselog")
19156 (set_attr "mode" "V4SF")])
19157
19158 (define_expand "sse_iorv4sf3"
19159 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19160 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19161 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19162 "TARGET_SSE"
19163 "")
19164
19165 (define_insn "*sse_iorv4sf3"
19166 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19167 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19168 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19169 "TARGET_SSE
19170 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19171 "orps\t{%2, %0|%0, %2}"
19172 [(set_attr "type" "sselog")
19173 (set_attr "mode" "V4SF")])
19174
19175 (define_insn "*sse_iorsf3"
19176 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19177 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19178 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19179 "TARGET_SSE
19180 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19181 "orps\t{%2, %0|%0, %2}"
19182 [(set_attr "type" "sselog")
19183 (set_attr "mode" "V4SF")])
19184
19185 (define_expand "sse_xorv4sf3"
19186 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19187 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19188 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19189 "TARGET_SSE
19190 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19191 "")
19192
19193 (define_insn "*sse_xorv4sf3"
19194 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19195 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19196 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19197 "TARGET_SSE
19198 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19199 "xorps\t{%2, %0|%0, %2}"
19200 [(set_attr "type" "sselog")
19201 (set_attr "mode" "V4SF")])
19202
19203 (define_insn "*sse_xorsf3"
19204 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19205 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19206 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19207 "TARGET_SSE
19208 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19209 "xorps\t{%2, %0|%0, %2}"
19210 [(set_attr "type" "sselog")
19211 (set_attr "mode" "V4SF")])
19212
19213 ;; SSE2 double precision floating point logical operation
19214
19215 (define_expand "sse2_andv2df3"
19216 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19217 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19218 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19219 "TARGET_SSE2"
19220 "")
19221
19222 (define_insn "*sse2_andv2df3"
19223 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19224 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19225 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19226 "TARGET_SSE2
19227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19228 "andpd\t{%2, %0|%0, %2}"
19229 [(set_attr "type" "sselog")
19230 (set_attr "mode" "V2DF")])
19231
19232 (define_insn "*sse2_andv2df3"
19233 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19234 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19235 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19236 "TARGET_SSE2
19237 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19238 "andpd\t{%2, %0|%0, %2}"
19239 [(set_attr "type" "sselog")
19240 (set_attr "mode" "V2DF")])
19241
19242 (define_expand "sse2_nandv2df3"
19243 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19244 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19245 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19246 "TARGET_SSE2"
19247 "")
19248
19249 (define_insn "*sse2_nandv2df3"
19250 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19251 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19252 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19253 "TARGET_SSE2"
19254 "andnpd\t{%2, %0|%0, %2}"
19255 [(set_attr "type" "sselog")
19256 (set_attr "mode" "V2DF")])
19257
19258 (define_insn "*sse_nandti3_df"
19259 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19260 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19261 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19262 "TARGET_SSE2"
19263 "andnpd\t{%2, %0|%0, %2}"
19264 [(set_attr "type" "sselog")
19265 (set_attr "mode" "V2DF")])
19266
19267 (define_expand "sse2_iorv2df3"
19268 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19269 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19270 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19271 "TARGET_SSE2"
19272 "")
19273
19274 (define_insn "*sse2_iorv2df3"
19275 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19276 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19277 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19278 "TARGET_SSE2
19279 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19280 "orpd\t{%2, %0|%0, %2}"
19281 [(set_attr "type" "sselog")
19282 (set_attr "mode" "V2DF")])
19283
19284 (define_insn "*sse2_iordf3"
19285 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19286 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19287 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19288 "TARGET_SSE2
19289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19290 "orpd\t{%2, %0|%0, %2}"
19291 [(set_attr "type" "sselog")
19292 (set_attr "mode" "V2DF")])
19293
19294 (define_expand "sse2_xorv2df3"
19295 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19296 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19297 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19298 "TARGET_SSE2"
19299 "")
19300
19301 (define_insn "*sse2_xorv2df3"
19302 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19303 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19304 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19305 "TARGET_SSE2
19306 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19307 "xorpd\t{%2, %0|%0, %2}"
19308 [(set_attr "type" "sselog")
19309 (set_attr "mode" "V2DF")])
19310
19311 (define_insn "*sse2_xordf3"
19312 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19313 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19314 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19315 "TARGET_SSE2
19316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19317 "xorpd\t{%2, %0|%0, %2}"
19318 [(set_attr "type" "sselog")
19319 (set_attr "mode" "V2DF")])
19320
19321 ;; SSE2 integral logicals. These patterns must always come after floating
19322 ;; point ones since we don't want compiler to use integer opcodes on floating
19323 ;; point SSE values to avoid matching of subregs in the match_operand.
19324 (define_insn "*sse2_andti3"
19325 [(set (match_operand:TI 0 "register_operand" "=x")
19326 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19327 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19328 "TARGET_SSE2
19329 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19330 "pand\t{%2, %0|%0, %2}"
19331 [(set_attr "type" "sselog")
19332 (set_attr "mode" "TI")])
19333
19334 (define_insn "sse2_andv2di3"
19335 [(set (match_operand:V2DI 0 "register_operand" "=x")
19336 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19337 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19338 "TARGET_SSE2
19339 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19340 "pand\t{%2, %0|%0, %2}"
19341 [(set_attr "type" "sselog")
19342 (set_attr "mode" "TI")])
19343
19344 (define_insn "*sse2_nandti3"
19345 [(set (match_operand:TI 0 "register_operand" "=x")
19346 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19347 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19348 "TARGET_SSE2"
19349 "pandn\t{%2, %0|%0, %2}"
19350 [(set_attr "type" "sselog")
19351 (set_attr "mode" "TI")])
19352
19353 (define_insn "sse2_nandv2di3"
19354 [(set (match_operand:V2DI 0 "register_operand" "=x")
19355 (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0"))
19356 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19357 "TARGET_SSE2
19358 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19359 "pandn\t{%2, %0|%0, %2}"
19360 [(set_attr "type" "sselog")
19361 (set_attr "mode" "TI")])
19362
19363 (define_insn "*sse2_iorti3"
19364 [(set (match_operand:TI 0 "register_operand" "=x")
19365 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19366 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19367 "TARGET_SSE2
19368 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19369 "por\t{%2, %0|%0, %2}"
19370 [(set_attr "type" "sselog")
19371 (set_attr "mode" "TI")])
19372
19373 (define_insn "sse2_iorv2di3"
19374 [(set (match_operand:V2DI 0 "register_operand" "=x")
19375 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19376 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19377 "TARGET_SSE2
19378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19379 "por\t{%2, %0|%0, %2}"
19380 [(set_attr "type" "sselog")
19381 (set_attr "mode" "TI")])
19382
19383 (define_insn "*sse2_xorti3"
19384 [(set (match_operand:TI 0 "register_operand" "=x")
19385 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19386 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19387 "TARGET_SSE2
19388 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19389 "pxor\t{%2, %0|%0, %2}"
19390 [(set_attr "type" "sselog")
19391 (set_attr "mode" "TI")])
19392
19393 (define_insn "sse2_xorv2di3"
19394 [(set (match_operand:V2DI 0 "register_operand" "=x")
19395 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19396 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19397 "TARGET_SSE2
19398 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19399 "pxor\t{%2, %0|%0, %2}"
19400 [(set_attr "type" "sselog")
19401 (set_attr "mode" "TI")])
19402
19403 ;; Use xor, but don't show input operands so they aren't live before
19404 ;; this insn.
19405 (define_insn "sse_clrv4sf"
19406 [(set (match_operand:V4SF 0 "register_operand" "=x")
19407 (match_operand:V4SF 1 "const0_operand" "X"))]
19408 "TARGET_SSE"
19409 {
19410 if (get_attr_mode (insn) == MODE_TI)
19411 return "pxor\t{%0, %0|%0, %0}";
19412 else
19413 return "xorps\t{%0, %0|%0, %0}";
19414 }
19415 [(set_attr "type" "sselog")
19416 (set_attr "memory" "none")
19417 (set (attr "mode")
19418 (if_then_else
19419 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19420 (const_int 0))
19421 (ne (symbol_ref "TARGET_SSE2")
19422 (const_int 0)))
19423 (eq (symbol_ref "optimize_size")
19424 (const_int 0)))
19425 (const_string "TI")
19426 (const_string "V4SF")))])
19427
19428 ;; Use xor, but don't show input operands so they aren't live before
19429 ;; this insn.
19430 (define_insn "sse_clrv2df"
19431 [(set (match_operand:V2DF 0 "register_operand" "=x")
19432 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19433 "TARGET_SSE2"
19434 "xorpd\t{%0, %0|%0, %0}"
19435 [(set_attr "type" "sselog")
19436 (set_attr "memory" "none")
19437 (set_attr "mode" "V4SF")])
19438
19439 ;; SSE mask-generating compares
19440
19441 (define_insn "maskcmpv4sf3"
19442 [(set (match_operand:V4SI 0 "register_operand" "=x")
19443 (match_operator:V4SI 3 "sse_comparison_operator"
19444 [(match_operand:V4SF 1 "register_operand" "0")
19445 (match_operand:V4SF 2 "register_operand" "x")]))]
19446 "TARGET_SSE"
19447 "cmp%D3ps\t{%2, %0|%0, %2}"
19448 [(set_attr "type" "ssecmp")
19449 (set_attr "mode" "V4SF")])
19450
19451 (define_insn "maskncmpv4sf3"
19452 [(set (match_operand:V4SI 0 "register_operand" "=x")
19453 (not:V4SI
19454 (match_operator:V4SI 3 "sse_comparison_operator"
19455 [(match_operand:V4SF 1 "register_operand" "0")
19456 (match_operand:V4SF 2 "register_operand" "x")])))]
19457 "TARGET_SSE"
19458 {
19459 if (GET_CODE (operands[3]) == UNORDERED)
19460 return "cmpordps\t{%2, %0|%0, %2}";
19461 else
19462 return "cmpn%D3ps\t{%2, %0|%0, %2}";
19463 }
19464 [(set_attr "type" "ssecmp")
19465 (set_attr "mode" "V4SF")])
19466
19467 (define_insn "vmmaskcmpv4sf3"
19468 [(set (match_operand:V4SI 0 "register_operand" "=x")
19469 (vec_merge:V4SI
19470 (match_operator:V4SI 3 "sse_comparison_operator"
19471 [(match_operand:V4SF 1 "register_operand" "0")
19472 (match_operand:V4SF 2 "register_operand" "x")])
19473 (match_dup 1)
19474 (const_int 1)))]
19475 "TARGET_SSE"
19476 "cmp%D3ss\t{%2, %0|%0, %2}"
19477 [(set_attr "type" "ssecmp")
19478 (set_attr "mode" "SF")])
19479
19480 (define_insn "vmmaskncmpv4sf3"
19481 [(set (match_operand:V4SI 0 "register_operand" "=x")
19482 (vec_merge:V4SI
19483 (not:V4SI
19484 (match_operator:V4SI 3 "sse_comparison_operator"
19485 [(match_operand:V4SF 1 "register_operand" "0")
19486 (match_operand:V4SF 2 "register_operand" "x")]))
19487 (subreg:V4SI (match_dup 1) 0)
19488 (const_int 1)))]
19489 "TARGET_SSE"
19490 {
19491 if (GET_CODE (operands[3]) == UNORDERED)
19492 return "cmpordss\t{%2, %0|%0, %2}";
19493 else
19494 return "cmpn%D3ss\t{%2, %0|%0, %2}";
19495 }
19496 [(set_attr "type" "ssecmp")
19497 (set_attr "mode" "SF")])
19498
19499 (define_insn "sse_comi"
19500 [(set (reg:CCFP 17)
19501 (compare:CCFP (vec_select:SF
19502 (match_operand:V4SF 0 "register_operand" "x")
19503 (parallel [(const_int 0)]))
19504 (vec_select:SF
19505 (match_operand:V4SF 1 "register_operand" "x")
19506 (parallel [(const_int 0)]))))]
19507 "TARGET_SSE"
19508 "comiss\t{%1, %0|%0, %1}"
19509 [(set_attr "type" "ssecmp")
19510 (set_attr "mode" "SF")])
19511
19512 (define_insn "sse_ucomi"
19513 [(set (reg:CCFPU 17)
19514 (compare:CCFPU (vec_select:SF
19515 (match_operand:V4SF 0 "register_operand" "x")
19516 (parallel [(const_int 0)]))
19517 (vec_select:SF
19518 (match_operand:V4SF 1 "register_operand" "x")
19519 (parallel [(const_int 0)]))))]
19520 "TARGET_SSE"
19521 "ucomiss\t{%1, %0|%0, %1}"
19522 [(set_attr "type" "ssecmp")
19523 (set_attr "mode" "SF")])
19524
19525
19526 ;; SSE unpack
19527
19528 (define_insn "sse_unpckhps"
19529 [(set (match_operand:V4SF 0 "register_operand" "=x")
19530 (vec_merge:V4SF
19531 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19532 (parallel [(const_int 2)
19533 (const_int 0)
19534 (const_int 3)
19535 (const_int 1)]))
19536 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19537 (parallel [(const_int 0)
19538 (const_int 2)
19539 (const_int 1)
19540 (const_int 3)]))
19541 (const_int 5)))]
19542 "TARGET_SSE"
19543 "unpckhps\t{%2, %0|%0, %2}"
19544 [(set_attr "type" "ssecvt")
19545 (set_attr "mode" "V4SF")])
19546
19547 (define_insn "sse_unpcklps"
19548 [(set (match_operand:V4SF 0 "register_operand" "=x")
19549 (vec_merge:V4SF
19550 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19551 (parallel [(const_int 0)
19552 (const_int 2)
19553 (const_int 1)
19554 (const_int 3)]))
19555 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19556 (parallel [(const_int 2)
19557 (const_int 0)
19558 (const_int 3)
19559 (const_int 1)]))
19560 (const_int 5)))]
19561 "TARGET_SSE"
19562 "unpcklps\t{%2, %0|%0, %2}"
19563 [(set_attr "type" "ssecvt")
19564 (set_attr "mode" "V4SF")])
19565
19566
19567 ;; SSE min/max
19568
19569 (define_insn "smaxv4sf3"
19570 [(set (match_operand:V4SF 0 "register_operand" "=x")
19571 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19572 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19573 "TARGET_SSE"
19574 "maxps\t{%2, %0|%0, %2}"
19575 [(set_attr "type" "sse")
19576 (set_attr "mode" "V4SF")])
19577
19578 (define_insn "vmsmaxv4sf3"
19579 [(set (match_operand:V4SF 0 "register_operand" "=x")
19580 (vec_merge:V4SF
19581 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19582 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19583 (match_dup 1)
19584 (const_int 1)))]
19585 "TARGET_SSE"
19586 "maxss\t{%2, %0|%0, %2}"
19587 [(set_attr "type" "sse")
19588 (set_attr "mode" "SF")])
19589
19590 (define_insn "sminv4sf3"
19591 [(set (match_operand:V4SF 0 "register_operand" "=x")
19592 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19593 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19594 "TARGET_SSE"
19595 "minps\t{%2, %0|%0, %2}"
19596 [(set_attr "type" "sse")
19597 (set_attr "mode" "V4SF")])
19598
19599 (define_insn "vmsminv4sf3"
19600 [(set (match_operand:V4SF 0 "register_operand" "=x")
19601 (vec_merge:V4SF
19602 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19603 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19604 (match_dup 1)
19605 (const_int 1)))]
19606 "TARGET_SSE"
19607 "minss\t{%2, %0|%0, %2}"
19608 [(set_attr "type" "sse")
19609 (set_attr "mode" "SF")])
19610
19611 ;; SSE <-> integer/MMX conversions
19612
19613 (define_insn "cvtpi2ps"
19614 [(set (match_operand:V4SF 0 "register_operand" "=x")
19615 (vec_merge:V4SF
19616 (match_operand:V4SF 1 "register_operand" "0")
19617 (vec_duplicate:V4SF
19618 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
19619 (const_int 12)))]
19620 "TARGET_SSE"
19621 "cvtpi2ps\t{%2, %0|%0, %2}"
19622 [(set_attr "type" "ssecvt")
19623 (set_attr "mode" "V4SF")])
19624
19625 (define_insn "cvtps2pi"
19626 [(set (match_operand:V2SI 0 "register_operand" "=y")
19627 (vec_select:V2SI
19628 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19629 (parallel [(const_int 0) (const_int 1)])))]
19630 "TARGET_SSE"
19631 "cvtps2pi\t{%1, %0|%0, %1}"
19632 [(set_attr "type" "ssecvt")
19633 (set_attr "mode" "V4SF")])
19634
19635 (define_insn "cvttps2pi"
19636 [(set (match_operand:V2SI 0 "register_operand" "=y")
19637 (vec_select:V2SI
19638 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19639 UNSPEC_FIX)
19640 (parallel [(const_int 0) (const_int 1)])))]
19641 "TARGET_SSE"
19642 "cvttps2pi\t{%1, %0|%0, %1}"
19643 [(set_attr "type" "ssecvt")
19644 (set_attr "mode" "SF")])
19645
19646 (define_insn "cvtsi2ss"
19647 [(set (match_operand:V4SF 0 "register_operand" "=x")
19648 (vec_merge:V4SF
19649 (match_operand:V4SF 1 "register_operand" "0")
19650 (vec_duplicate:V4SF
19651 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
19652 (const_int 14)))]
19653 "TARGET_SSE"
19654 "cvtsi2ss\t{%2, %0|%0, %2}"
19655 [(set_attr "type" "ssecvt")
19656 (set_attr "mode" "SF")])
19657
19658 (define_insn "cvtsi2ssq"
19659 [(set (match_operand:V4SF 0 "register_operand" "=x")
19660 (vec_merge:V4SF
19661 (match_operand:V4SF 1 "register_operand" "0")
19662 (vec_duplicate:V4SF
19663 (float:SF (match_operand:DI 2 "nonimmediate_operand" "rm")))
19664 (const_int 14)))]
19665 "TARGET_SSE && TARGET_64BIT"
19666 "cvtsi2ssq\t{%2, %0|%0, %2}"
19667 [(set_attr "type" "ssecvt")
19668 (set_attr "mode" "SF")])
19669
19670 (define_insn "cvtss2si"
19671 [(set (match_operand:SI 0 "register_operand" "=r")
19672 (vec_select:SI
19673 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19674 (parallel [(const_int 0)])))]
19675 "TARGET_SSE"
19676 "cvtss2si\t{%1, %0|%0, %1}"
19677 [(set_attr "type" "ssecvt")
19678 (set_attr "mode" "SF")])
19679
19680 (define_insn "cvttss2si"
19681 [(set (match_operand:SI 0 "register_operand" "=r")
19682 (vec_select:SI
19683 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19684 UNSPEC_FIX)
19685 (parallel [(const_int 0)])))]
19686 "TARGET_SSE"
19687 "cvttss2si\t{%1, %0|%0, %1}"
19688 [(set_attr "type" "ssecvt")
19689 (set_attr "mode" "SF")])
19690
19691
19692 ;; MMX insns
19693
19694 ;; MMX arithmetic
19695
19696 (define_insn "addv8qi3"
19697 [(set (match_operand:V8QI 0 "register_operand" "=y")
19698 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19699 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19700 "TARGET_MMX"
19701 "paddb\t{%2, %0|%0, %2}"
19702 [(set_attr "type" "mmxadd")
19703 (set_attr "mode" "DI")])
19704
19705 (define_insn "addv4hi3"
19706 [(set (match_operand:V4HI 0 "register_operand" "=y")
19707 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
19708 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19709 "TARGET_MMX"
19710 "paddw\t{%2, %0|%0, %2}"
19711 [(set_attr "type" "mmxadd")
19712 (set_attr "mode" "DI")])
19713
19714 (define_insn "addv2si3"
19715 [(set (match_operand:V2SI 0 "register_operand" "=y")
19716 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
19717 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19718 "TARGET_MMX"
19719 "paddd\t{%2, %0|%0, %2}"
19720 [(set_attr "type" "mmxadd")
19721 (set_attr "mode" "DI")])
19722
19723 (define_insn "ssaddv8qi3"
19724 [(set (match_operand:V8QI 0 "register_operand" "=y")
19725 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19726 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19727 "TARGET_MMX"
19728 "paddsb\t{%2, %0|%0, %2}"
19729 [(set_attr "type" "mmxadd")
19730 (set_attr "mode" "DI")])
19731
19732 (define_insn "ssaddv4hi3"
19733 [(set (match_operand:V4HI 0 "register_operand" "=y")
19734 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
19735 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19736 "TARGET_MMX"
19737 "paddsw\t{%2, %0|%0, %2}"
19738 [(set_attr "type" "mmxadd")
19739 (set_attr "mode" "DI")])
19740
19741 (define_insn "usaddv8qi3"
19742 [(set (match_operand:V8QI 0 "register_operand" "=y")
19743 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19744 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19745 "TARGET_MMX"
19746 "paddusb\t{%2, %0|%0, %2}"
19747 [(set_attr "type" "mmxadd")
19748 (set_attr "mode" "DI")])
19749
19750 (define_insn "usaddv4hi3"
19751 [(set (match_operand:V4HI 0 "register_operand" "=y")
19752 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
19753 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19754 "TARGET_MMX"
19755 "paddusw\t{%2, %0|%0, %2}"
19756 [(set_attr "type" "mmxadd")
19757 (set_attr "mode" "DI")])
19758
19759 (define_insn "subv8qi3"
19760 [(set (match_operand:V8QI 0 "register_operand" "=y")
19761 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19762 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19763 "TARGET_MMX"
19764 "psubb\t{%2, %0|%0, %2}"
19765 [(set_attr "type" "mmxadd")
19766 (set_attr "mode" "DI")])
19767
19768 (define_insn "subv4hi3"
19769 [(set (match_operand:V4HI 0 "register_operand" "=y")
19770 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
19771 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19772 "TARGET_MMX"
19773 "psubw\t{%2, %0|%0, %2}"
19774 [(set_attr "type" "mmxadd")
19775 (set_attr "mode" "DI")])
19776
19777 (define_insn "subv2si3"
19778 [(set (match_operand:V2SI 0 "register_operand" "=y")
19779 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
19780 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19781 "TARGET_MMX"
19782 "psubd\t{%2, %0|%0, %2}"
19783 [(set_attr "type" "mmxadd")
19784 (set_attr "mode" "DI")])
19785
19786 (define_insn "sssubv8qi3"
19787 [(set (match_operand:V8QI 0 "register_operand" "=y")
19788 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19789 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19790 "TARGET_MMX"
19791 "psubsb\t{%2, %0|%0, %2}"
19792 [(set_attr "type" "mmxadd")
19793 (set_attr "mode" "DI")])
19794
19795 (define_insn "sssubv4hi3"
19796 [(set (match_operand:V4HI 0 "register_operand" "=y")
19797 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
19798 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19799 "TARGET_MMX"
19800 "psubsw\t{%2, %0|%0, %2}"
19801 [(set_attr "type" "mmxadd")
19802 (set_attr "mode" "DI")])
19803
19804 (define_insn "ussubv8qi3"
19805 [(set (match_operand:V8QI 0 "register_operand" "=y")
19806 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19807 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19808 "TARGET_MMX"
19809 "psubusb\t{%2, %0|%0, %2}"
19810 [(set_attr "type" "mmxadd")
19811 (set_attr "mode" "DI")])
19812
19813 (define_insn "ussubv4hi3"
19814 [(set (match_operand:V4HI 0 "register_operand" "=y")
19815 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
19816 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19817 "TARGET_MMX"
19818 "psubusw\t{%2, %0|%0, %2}"
19819 [(set_attr "type" "mmxadd")
19820 (set_attr "mode" "DI")])
19821
19822 (define_insn "mulv4hi3"
19823 [(set (match_operand:V4HI 0 "register_operand" "=y")
19824 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
19825 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19826 "TARGET_MMX"
19827 "pmullw\t{%2, %0|%0, %2}"
19828 [(set_attr "type" "mmxmul")
19829 (set_attr "mode" "DI")])
19830
19831 (define_insn "smulv4hi3_highpart"
19832 [(set (match_operand:V4HI 0 "register_operand" "=y")
19833 (truncate:V4HI
19834 (lshiftrt:V4SI
19835 (mult:V4SI (sign_extend:V4SI
19836 (match_operand:V4HI 1 "register_operand" "0"))
19837 (sign_extend:V4SI
19838 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19839 (const_int 16))))]
19840 "TARGET_MMX"
19841 "pmulhw\t{%2, %0|%0, %2}"
19842 [(set_attr "type" "mmxmul")
19843 (set_attr "mode" "DI")])
19844
19845 (define_insn "umulv4hi3_highpart"
19846 [(set (match_operand:V4HI 0 "register_operand" "=y")
19847 (truncate:V4HI
19848 (lshiftrt:V4SI
19849 (mult:V4SI (zero_extend:V4SI
19850 (match_operand:V4HI 1 "register_operand" "0"))
19851 (zero_extend:V4SI
19852 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19853 (const_int 16))))]
19854 "TARGET_SSE || TARGET_3DNOW_A"
19855 "pmulhuw\t{%2, %0|%0, %2}"
19856 [(set_attr "type" "mmxmul")
19857 (set_attr "mode" "DI")])
19858
19859 (define_insn "mmx_pmaddwd"
19860 [(set (match_operand:V2SI 0 "register_operand" "=y")
19861 (plus:V2SI
19862 (mult:V2SI
19863 (sign_extend:V2SI
19864 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
19865 (parallel [(const_int 0) (const_int 2)])))
19866 (sign_extend:V2SI
19867 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
19868 (parallel [(const_int 0) (const_int 2)]))))
19869 (mult:V2SI
19870 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
19871 (parallel [(const_int 1)
19872 (const_int 3)])))
19873 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
19874 (parallel [(const_int 1)
19875 (const_int 3)]))))))]
19876 "TARGET_MMX"
19877 "pmaddwd\t{%2, %0|%0, %2}"
19878 [(set_attr "type" "mmxmul")
19879 (set_attr "mode" "DI")])
19880
19881
19882 ;; MMX logical operations
19883 ;; Note we don't want to declare these as regular iordi3 insns to prevent
19884 ;; normal code that also wants to use the FPU from getting broken.
19885 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
19886 (define_insn "mmx_iordi3"
19887 [(set (match_operand:DI 0 "register_operand" "=y")
19888 (unspec:DI
19889 [(ior:DI (match_operand:DI 1 "register_operand" "0")
19890 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19891 UNSPEC_NOP))]
19892 "TARGET_MMX"
19893 "por\t{%2, %0|%0, %2}"
19894 [(set_attr "type" "mmxadd")
19895 (set_attr "mode" "DI")])
19896
19897 (define_insn "mmx_xordi3"
19898 [(set (match_operand:DI 0 "register_operand" "=y")
19899 (unspec:DI
19900 [(xor:DI (match_operand:DI 1 "register_operand" "0")
19901 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19902 UNSPEC_NOP))]
19903 "TARGET_MMX"
19904 "pxor\t{%2, %0|%0, %2}"
19905 [(set_attr "type" "mmxadd")
19906 (set_attr "mode" "DI")
19907 (set_attr "memory" "none")])
19908
19909 ;; Same as pxor, but don't show input operands so that we don't think
19910 ;; they are live.
19911 (define_insn "mmx_clrdi"
19912 [(set (match_operand:DI 0 "register_operand" "=y")
19913 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
19914 "TARGET_MMX"
19915 "pxor\t{%0, %0|%0, %0}"
19916 [(set_attr "type" "mmxadd")
19917 (set_attr "mode" "DI")
19918 (set_attr "memory" "none")])
19919
19920 (define_insn "mmx_anddi3"
19921 [(set (match_operand:DI 0 "register_operand" "=y")
19922 (unspec:DI
19923 [(and:DI (match_operand:DI 1 "register_operand" "0")
19924 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19925 UNSPEC_NOP))]
19926 "TARGET_MMX"
19927 "pand\t{%2, %0|%0, %2}"
19928 [(set_attr "type" "mmxadd")
19929 (set_attr "mode" "DI")])
19930
19931 (define_insn "mmx_nanddi3"
19932 [(set (match_operand:DI 0 "register_operand" "=y")
19933 (unspec:DI
19934 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
19935 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19936 UNSPEC_NOP))]
19937 "TARGET_MMX"
19938 "pandn\t{%2, %0|%0, %2}"
19939 [(set_attr "type" "mmxadd")
19940 (set_attr "mode" "DI")])
19941
19942
19943 ;; MMX unsigned averages/sum of absolute differences
19944
19945 (define_insn "mmx_uavgv8qi3"
19946 [(set (match_operand:V8QI 0 "register_operand" "=y")
19947 (ashiftrt:V8QI
19948 (plus:V8QI (plus:V8QI
19949 (match_operand:V8QI 1 "register_operand" "0")
19950 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
19951 (const_vector:V8QI [(const_int 1)
19952 (const_int 1)
19953 (const_int 1)
19954 (const_int 1)
19955 (const_int 1)
19956 (const_int 1)
19957 (const_int 1)
19958 (const_int 1)]))
19959 (const_int 1)))]
19960 "TARGET_SSE || TARGET_3DNOW_A"
19961 "pavgb\t{%2, %0|%0, %2}"
19962 [(set_attr "type" "mmxshft")
19963 (set_attr "mode" "DI")])
19964
19965 (define_insn "mmx_uavgv4hi3"
19966 [(set (match_operand:V4HI 0 "register_operand" "=y")
19967 (ashiftrt:V4HI
19968 (plus:V4HI (plus:V4HI
19969 (match_operand:V4HI 1 "register_operand" "0")
19970 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
19971 (const_vector:V4HI [(const_int 1)
19972 (const_int 1)
19973 (const_int 1)
19974 (const_int 1)]))
19975 (const_int 1)))]
19976 "TARGET_SSE || TARGET_3DNOW_A"
19977 "pavgw\t{%2, %0|%0, %2}"
19978 [(set_attr "type" "mmxshft")
19979 (set_attr "mode" "DI")])
19980
19981 (define_insn "mmx_psadbw"
19982 [(set (match_operand:DI 0 "register_operand" "=y")
19983 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
19984 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
19985 UNSPEC_PSADBW))]
19986 "TARGET_SSE || TARGET_3DNOW_A"
19987 "psadbw\t{%2, %0|%0, %2}"
19988 [(set_attr "type" "mmxshft")
19989 (set_attr "mode" "DI")])
19990
19991
19992 ;; MMX insert/extract/shuffle
19993
19994 (define_insn "mmx_pinsrw"
19995 [(set (match_operand:V4HI 0 "register_operand" "=y")
19996 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
19997 (vec_duplicate:V4HI
19998 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
19999 (match_operand:SI 3 "immediate_operand" "i")))]
20000 "TARGET_SSE || TARGET_3DNOW_A"
20001 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20002 [(set_attr "type" "mmxcvt")
20003 (set_attr "mode" "DI")])
20004
20005 (define_insn "mmx_pextrw"
20006 [(set (match_operand:SI 0 "register_operand" "=r")
20007 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20008 (parallel
20009 [(match_operand:SI 2 "immediate_operand" "i")]))))]
20010 "TARGET_SSE || TARGET_3DNOW_A"
20011 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20012 [(set_attr "type" "mmxcvt")
20013 (set_attr "mode" "DI")])
20014
20015 (define_insn "mmx_pshufw"
20016 [(set (match_operand:V4HI 0 "register_operand" "=y")
20017 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20018 (match_operand:SI 2 "immediate_operand" "i")]
20019 UNSPEC_SHUFFLE))]
20020 "TARGET_SSE || TARGET_3DNOW_A"
20021 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20022 [(set_attr "type" "mmxcvt")
20023 (set_attr "mode" "DI")])
20024
20025
20026 ;; MMX mask-generating comparisons
20027
20028 (define_insn "eqv8qi3"
20029 [(set (match_operand:V8QI 0 "register_operand" "=y")
20030 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20031 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20032 "TARGET_MMX"
20033 "pcmpeqb\t{%2, %0|%0, %2}"
20034 [(set_attr "type" "mmxcmp")
20035 (set_attr "mode" "DI")])
20036
20037 (define_insn "eqv4hi3"
20038 [(set (match_operand:V4HI 0 "register_operand" "=y")
20039 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20040 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20041 "TARGET_MMX"
20042 "pcmpeqw\t{%2, %0|%0, %2}"
20043 [(set_attr "type" "mmxcmp")
20044 (set_attr "mode" "DI")])
20045
20046 (define_insn "eqv2si3"
20047 [(set (match_operand:V2SI 0 "register_operand" "=y")
20048 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20049 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20050 "TARGET_MMX"
20051 "pcmpeqd\t{%2, %0|%0, %2}"
20052 [(set_attr "type" "mmxcmp")
20053 (set_attr "mode" "DI")])
20054
20055 (define_insn "gtv8qi3"
20056 [(set (match_operand:V8QI 0 "register_operand" "=y")
20057 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20058 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20059 "TARGET_MMX"
20060 "pcmpgtb\t{%2, %0|%0, %2}"
20061 [(set_attr "type" "mmxcmp")
20062 (set_attr "mode" "DI")])
20063
20064 (define_insn "gtv4hi3"
20065 [(set (match_operand:V4HI 0 "register_operand" "=y")
20066 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20067 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20068 "TARGET_MMX"
20069 "pcmpgtw\t{%2, %0|%0, %2}"
20070 [(set_attr "type" "mmxcmp")
20071 (set_attr "mode" "DI")])
20072
20073 (define_insn "gtv2si3"
20074 [(set (match_operand:V2SI 0 "register_operand" "=y")
20075 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20076 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20077 "TARGET_MMX"
20078 "pcmpgtd\t{%2, %0|%0, %2}"
20079 [(set_attr "type" "mmxcmp")
20080 (set_attr "mode" "DI")])
20081
20082
20083 ;; MMX max/min insns
20084
20085 (define_insn "umaxv8qi3"
20086 [(set (match_operand:V8QI 0 "register_operand" "=y")
20087 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20088 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20089 "TARGET_SSE || TARGET_3DNOW_A"
20090 "pmaxub\t{%2, %0|%0, %2}"
20091 [(set_attr "type" "mmxadd")
20092 (set_attr "mode" "DI")])
20093
20094 (define_insn "smaxv4hi3"
20095 [(set (match_operand:V4HI 0 "register_operand" "=y")
20096 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20097 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20098 "TARGET_SSE || TARGET_3DNOW_A"
20099 "pmaxsw\t{%2, %0|%0, %2}"
20100 [(set_attr "type" "mmxadd")
20101 (set_attr "mode" "DI")])
20102
20103 (define_insn "uminv8qi3"
20104 [(set (match_operand:V8QI 0 "register_operand" "=y")
20105 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20106 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20107 "TARGET_SSE || TARGET_3DNOW_A"
20108 "pminub\t{%2, %0|%0, %2}"
20109 [(set_attr "type" "mmxadd")
20110 (set_attr "mode" "DI")])
20111
20112 (define_insn "sminv4hi3"
20113 [(set (match_operand:V4HI 0 "register_operand" "=y")
20114 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20115 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20116 "TARGET_SSE || TARGET_3DNOW_A"
20117 "pminsw\t{%2, %0|%0, %2}"
20118 [(set_attr "type" "mmxadd")
20119 (set_attr "mode" "DI")])
20120
20121
20122 ;; MMX shifts
20123
20124 (define_insn "ashrv4hi3"
20125 [(set (match_operand:V4HI 0 "register_operand" "=y")
20126 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20127 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20128 "TARGET_MMX"
20129 "psraw\t{%2, %0|%0, %2}"
20130 [(set_attr "type" "mmxshft")
20131 (set_attr "mode" "DI")])
20132
20133 (define_insn "ashrv2si3"
20134 [(set (match_operand:V2SI 0 "register_operand" "=y")
20135 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20136 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20137 "TARGET_MMX"
20138 "psrad\t{%2, %0|%0, %2}"
20139 [(set_attr "type" "mmxshft")
20140 (set_attr "mode" "DI")])
20141
20142 (define_insn "lshrv4hi3"
20143 [(set (match_operand:V4HI 0 "register_operand" "=y")
20144 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20145 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20146 "TARGET_MMX"
20147 "psrlw\t{%2, %0|%0, %2}"
20148 [(set_attr "type" "mmxshft")
20149 (set_attr "mode" "DI")])
20150
20151 (define_insn "lshrv2si3"
20152 [(set (match_operand:V2SI 0 "register_operand" "=y")
20153 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20154 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20155 "TARGET_MMX"
20156 "psrld\t{%2, %0|%0, %2}"
20157 [(set_attr "type" "mmxshft")
20158 (set_attr "mode" "DI")])
20159
20160 ;; See logical MMX insns.
20161 (define_insn "mmx_lshrdi3"
20162 [(set (match_operand:DI 0 "register_operand" "=y")
20163 (unspec:DI
20164 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20165 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20166 UNSPEC_NOP))]
20167 "TARGET_MMX"
20168 "psrlq\t{%2, %0|%0, %2}"
20169 [(set_attr "type" "mmxshft")
20170 (set_attr "mode" "DI")])
20171
20172 (define_insn "ashlv4hi3"
20173 [(set (match_operand:V4HI 0 "register_operand" "=y")
20174 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20175 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20176 "TARGET_MMX"
20177 "psllw\t{%2, %0|%0, %2}"
20178 [(set_attr "type" "mmxshft")
20179 (set_attr "mode" "DI")])
20180
20181 (define_insn "ashlv2si3"
20182 [(set (match_operand:V2SI 0 "register_operand" "=y")
20183 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20184 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20185 "TARGET_MMX"
20186 "pslld\t{%2, %0|%0, %2}"
20187 [(set_attr "type" "mmxshft")
20188 (set_attr "mode" "DI")])
20189
20190 ;; See logical MMX insns.
20191 (define_insn "mmx_ashldi3"
20192 [(set (match_operand:DI 0 "register_operand" "=y")
20193 (unspec:DI
20194 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20195 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20196 UNSPEC_NOP))]
20197 "TARGET_MMX"
20198 "psllq\t{%2, %0|%0, %2}"
20199 [(set_attr "type" "mmxshft")
20200 (set_attr "mode" "DI")])
20201
20202
20203 ;; MMX pack/unpack insns.
20204
20205 (define_insn "mmx_packsswb"
20206 [(set (match_operand:V8QI 0 "register_operand" "=y")
20207 (vec_concat:V8QI
20208 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20209 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20210 "TARGET_MMX"
20211 "packsswb\t{%2, %0|%0, %2}"
20212 [(set_attr "type" "mmxshft")
20213 (set_attr "mode" "DI")])
20214
20215 (define_insn "mmx_packssdw"
20216 [(set (match_operand:V4HI 0 "register_operand" "=y")
20217 (vec_concat:V4HI
20218 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20219 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20220 "TARGET_MMX"
20221 "packssdw\t{%2, %0|%0, %2}"
20222 [(set_attr "type" "mmxshft")
20223 (set_attr "mode" "DI")])
20224
20225 (define_insn "mmx_packuswb"
20226 [(set (match_operand:V8QI 0 "register_operand" "=y")
20227 (vec_concat:V8QI
20228 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20229 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20230 "TARGET_MMX"
20231 "packuswb\t{%2, %0|%0, %2}"
20232 [(set_attr "type" "mmxshft")
20233 (set_attr "mode" "DI")])
20234
20235 (define_insn "mmx_punpckhbw"
20236 [(set (match_operand:V8QI 0 "register_operand" "=y")
20237 (vec_merge:V8QI
20238 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20239 (parallel [(const_int 4)
20240 (const_int 0)
20241 (const_int 5)
20242 (const_int 1)
20243 (const_int 6)
20244 (const_int 2)
20245 (const_int 7)
20246 (const_int 3)]))
20247 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20248 (parallel [(const_int 0)
20249 (const_int 4)
20250 (const_int 1)
20251 (const_int 5)
20252 (const_int 2)
20253 (const_int 6)
20254 (const_int 3)
20255 (const_int 7)]))
20256 (const_int 85)))]
20257 "TARGET_MMX"
20258 "punpckhbw\t{%2, %0|%0, %2}"
20259 [(set_attr "type" "mmxcvt")
20260 (set_attr "mode" "DI")])
20261
20262 (define_insn "mmx_punpckhwd"
20263 [(set (match_operand:V4HI 0 "register_operand" "=y")
20264 (vec_merge:V4HI
20265 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20266 (parallel [(const_int 0)
20267 (const_int 2)
20268 (const_int 1)
20269 (const_int 3)]))
20270 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20271 (parallel [(const_int 2)
20272 (const_int 0)
20273 (const_int 3)
20274 (const_int 1)]))
20275 (const_int 5)))]
20276 "TARGET_MMX"
20277 "punpckhwd\t{%2, %0|%0, %2}"
20278 [(set_attr "type" "mmxcvt")
20279 (set_attr "mode" "DI")])
20280
20281 (define_insn "mmx_punpckhdq"
20282 [(set (match_operand:V2SI 0 "register_operand" "=y")
20283 (vec_merge:V2SI
20284 (match_operand:V2SI 1 "register_operand" "0")
20285 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20286 (parallel [(const_int 1)
20287 (const_int 0)]))
20288 (const_int 1)))]
20289 "TARGET_MMX"
20290 "punpckhdq\t{%2, %0|%0, %2}"
20291 [(set_attr "type" "mmxcvt")
20292 (set_attr "mode" "DI")])
20293
20294 (define_insn "mmx_punpcklbw"
20295 [(set (match_operand:V8QI 0 "register_operand" "=y")
20296 (vec_merge:V8QI
20297 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20298 (parallel [(const_int 0)
20299 (const_int 4)
20300 (const_int 1)
20301 (const_int 5)
20302 (const_int 2)
20303 (const_int 6)
20304 (const_int 3)
20305 (const_int 7)]))
20306 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20307 (parallel [(const_int 4)
20308 (const_int 0)
20309 (const_int 5)
20310 (const_int 1)
20311 (const_int 6)
20312 (const_int 2)
20313 (const_int 7)
20314 (const_int 3)]))
20315 (const_int 85)))]
20316 "TARGET_MMX"
20317 "punpcklbw\t{%2, %0|%0, %2}"
20318 [(set_attr "type" "mmxcvt")
20319 (set_attr "mode" "DI")])
20320
20321 (define_insn "mmx_punpcklwd"
20322 [(set (match_operand:V4HI 0 "register_operand" "=y")
20323 (vec_merge:V4HI
20324 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20325 (parallel [(const_int 2)
20326 (const_int 0)
20327 (const_int 3)
20328 (const_int 1)]))
20329 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20330 (parallel [(const_int 0)
20331 (const_int 2)
20332 (const_int 1)
20333 (const_int 3)]))
20334 (const_int 5)))]
20335 "TARGET_MMX"
20336 "punpcklwd\t{%2, %0|%0, %2}"
20337 [(set_attr "type" "mmxcvt")
20338 (set_attr "mode" "DI")])
20339
20340 (define_insn "mmx_punpckldq"
20341 [(set (match_operand:V2SI 0 "register_operand" "=y")
20342 (vec_merge:V2SI
20343 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20344 (parallel [(const_int 1)
20345 (const_int 0)]))
20346 (match_operand:V2SI 2 "register_operand" "y")
20347 (const_int 1)))]
20348 "TARGET_MMX"
20349 "punpckldq\t{%2, %0|%0, %2}"
20350 [(set_attr "type" "mmxcvt")
20351 (set_attr "mode" "DI")])
20352
20353
20354 ;; Miscellaneous stuff
20355
20356 (define_insn "emms"
20357 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20358 (clobber (reg:XF 8))
20359 (clobber (reg:XF 9))
20360 (clobber (reg:XF 10))
20361 (clobber (reg:XF 11))
20362 (clobber (reg:XF 12))
20363 (clobber (reg:XF 13))
20364 (clobber (reg:XF 14))
20365 (clobber (reg:XF 15))
20366 (clobber (reg:DI 29))
20367 (clobber (reg:DI 30))
20368 (clobber (reg:DI 31))
20369 (clobber (reg:DI 32))
20370 (clobber (reg:DI 33))
20371 (clobber (reg:DI 34))
20372 (clobber (reg:DI 35))
20373 (clobber (reg:DI 36))]
20374 "TARGET_MMX"
20375 "emms"
20376 [(set_attr "type" "mmx")
20377 (set_attr "memory" "unknown")])
20378
20379 (define_insn "ldmxcsr"
20380 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20381 UNSPECV_LDMXCSR)]
20382 "TARGET_MMX"
20383 "ldmxcsr\t%0"
20384 [(set_attr "type" "mmx")
20385 (set_attr "memory" "load")])
20386
20387 (define_insn "stmxcsr"
20388 [(set (match_operand:SI 0 "memory_operand" "=m")
20389 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20390 "TARGET_MMX"
20391 "stmxcsr\t%0"
20392 [(set_attr "type" "mmx")
20393 (set_attr "memory" "store")])
20394
20395 (define_expand "sfence"
20396 [(set (match_dup 0)
20397 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20398 "TARGET_SSE || TARGET_3DNOW_A"
20399 {
20400 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20401 MEM_VOLATILE_P (operands[0]) = 1;
20402 })
20403
20404 (define_insn "*sfence_insn"
20405 [(set (match_operand:BLK 0 "" "")
20406 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20407 "TARGET_SSE || TARGET_3DNOW_A"
20408 "sfence"
20409 [(set_attr "type" "sse")
20410 (set_attr "memory" "unknown")])
20411
20412 (define_expand "sse_prologue_save"
20413 [(parallel [(set (match_operand:BLK 0 "" "")
20414 (unspec:BLK [(reg:DI 21)
20415 (reg:DI 22)
20416 (reg:DI 23)
20417 (reg:DI 24)
20418 (reg:DI 25)
20419 (reg:DI 26)
20420 (reg:DI 27)
20421 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20422 (use (match_operand:DI 1 "register_operand" ""))
20423 (use (match_operand:DI 2 "immediate_operand" ""))
20424 (use (label_ref:DI (match_operand 3 "" "")))])]
20425 "TARGET_64BIT"
20426 "")
20427
20428 (define_insn "*sse_prologue_save_insn"
20429 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20430 (match_operand:DI 4 "const_int_operand" "n")))
20431 (unspec:BLK [(reg:DI 21)
20432 (reg:DI 22)
20433 (reg:DI 23)
20434 (reg:DI 24)
20435 (reg:DI 25)
20436 (reg:DI 26)
20437 (reg:DI 27)
20438 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20439 (use (match_operand:DI 1 "register_operand" "r"))
20440 (use (match_operand:DI 2 "const_int_operand" "i"))
20441 (use (label_ref:DI (match_operand 3 "" "X")))]
20442 "TARGET_64BIT
20443 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20444 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20445 "*
20446 {
20447 int i;
20448 operands[0] = gen_rtx_MEM (Pmode,
20449 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20450 output_asm_insn (\"jmp\\t%A1\", operands);
20451 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20452 {
20453 operands[4] = adjust_address (operands[0], DImode, i*16);
20454 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20455 PUT_MODE (operands[4], TImode);
20456 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20457 output_asm_insn (\"rex\", operands);
20458 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20459 }
20460 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20461 CODE_LABEL_NUMBER (operands[3]));
20462 RET;
20463 }
20464 "
20465 [(set_attr "type" "other")
20466 (set_attr "length_immediate" "0")
20467 (set_attr "length_address" "0")
20468 (set_attr "length" "135")
20469 (set_attr "memory" "store")
20470 (set_attr "modrm" "0")
20471 (set_attr "mode" "DI")])
20472
20473 ;; 3Dnow! instructions
20474
20475 (define_insn "addv2sf3"
20476 [(set (match_operand:V2SF 0 "register_operand" "=y")
20477 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20478 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20479 "TARGET_3DNOW"
20480 "pfadd\\t{%2, %0|%0, %2}"
20481 [(set_attr "type" "mmxadd")
20482 (set_attr "mode" "V2SF")])
20483
20484 (define_insn "subv2sf3"
20485 [(set (match_operand:V2SF 0 "register_operand" "=y")
20486 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20487 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20488 "TARGET_3DNOW"
20489 "pfsub\\t{%2, %0|%0, %2}"
20490 [(set_attr "type" "mmxadd")
20491 (set_attr "mode" "V2SF")])
20492
20493 (define_insn "subrv2sf3"
20494 [(set (match_operand:V2SF 0 "register_operand" "=y")
20495 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20496 (match_operand:V2SF 1 "register_operand" "0")))]
20497 "TARGET_3DNOW"
20498 "pfsubr\\t{%2, %0|%0, %2}"
20499 [(set_attr "type" "mmxadd")
20500 (set_attr "mode" "V2SF")])
20501
20502 (define_insn "gtv2sf3"
20503 [(set (match_operand:V2SI 0 "register_operand" "=y")
20504 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20505 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20506 "TARGET_3DNOW"
20507 "pfcmpgt\\t{%2, %0|%0, %2}"
20508 [(set_attr "type" "mmxcmp")
20509 (set_attr "mode" "V2SF")])
20510
20511 (define_insn "gev2sf3"
20512 [(set (match_operand:V2SI 0 "register_operand" "=y")
20513 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20514 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20515 "TARGET_3DNOW"
20516 "pfcmpge\\t{%2, %0|%0, %2}"
20517 [(set_attr "type" "mmxcmp")
20518 (set_attr "mode" "V2SF")])
20519
20520 (define_insn "eqv2sf3"
20521 [(set (match_operand:V2SI 0 "register_operand" "=y")
20522 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20523 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20524 "TARGET_3DNOW"
20525 "pfcmpeq\\t{%2, %0|%0, %2}"
20526 [(set_attr "type" "mmxcmp")
20527 (set_attr "mode" "V2SF")])
20528
20529 (define_insn "pfmaxv2sf3"
20530 [(set (match_operand:V2SF 0 "register_operand" "=y")
20531 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20532 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20533 "TARGET_3DNOW"
20534 "pfmax\\t{%2, %0|%0, %2}"
20535 [(set_attr "type" "mmxadd")
20536 (set_attr "mode" "V2SF")])
20537
20538 (define_insn "pfminv2sf3"
20539 [(set (match_operand:V2SF 0 "register_operand" "=y")
20540 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20541 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20542 "TARGET_3DNOW"
20543 "pfmin\\t{%2, %0|%0, %2}"
20544 [(set_attr "type" "mmxadd")
20545 (set_attr "mode" "V2SF")])
20546
20547 (define_insn "mulv2sf3"
20548 [(set (match_operand:V2SF 0 "register_operand" "=y")
20549 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20550 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20551 "TARGET_3DNOW"
20552 "pfmul\\t{%2, %0|%0, %2}"
20553 [(set_attr "type" "mmxmul")
20554 (set_attr "mode" "V2SF")])
20555
20556 (define_insn "femms"
20557 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
20558 (clobber (reg:XF 8))
20559 (clobber (reg:XF 9))
20560 (clobber (reg:XF 10))
20561 (clobber (reg:XF 11))
20562 (clobber (reg:XF 12))
20563 (clobber (reg:XF 13))
20564 (clobber (reg:XF 14))
20565 (clobber (reg:XF 15))
20566 (clobber (reg:DI 29))
20567 (clobber (reg:DI 30))
20568 (clobber (reg:DI 31))
20569 (clobber (reg:DI 32))
20570 (clobber (reg:DI 33))
20571 (clobber (reg:DI 34))
20572 (clobber (reg:DI 35))
20573 (clobber (reg:DI 36))]
20574 "TARGET_3DNOW"
20575 "femms"
20576 [(set_attr "type" "mmx")
20577 (set_attr "memory" "none")])
20578
20579 (define_insn "pf2id"
20580 [(set (match_operand:V2SI 0 "register_operand" "=y")
20581 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
20582 "TARGET_3DNOW"
20583 "pf2id\\t{%1, %0|%0, %1}"
20584 [(set_attr "type" "mmxcvt")
20585 (set_attr "mode" "V2SF")])
20586
20587 (define_insn "pf2iw"
20588 [(set (match_operand:V2SI 0 "register_operand" "=y")
20589 (sign_extend:V2SI
20590 (ss_truncate:V2HI
20591 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
20592 "TARGET_3DNOW_A"
20593 "pf2iw\\t{%1, %0|%0, %1}"
20594 [(set_attr "type" "mmxcvt")
20595 (set_attr "mode" "V2SF")])
20596
20597 (define_insn "pfacc"
20598 [(set (match_operand:V2SF 0 "register_operand" "=y")
20599 (vec_concat:V2SF
20600 (plus:SF
20601 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20602 (parallel [(const_int 0)]))
20603 (vec_select:SF (match_dup 1)
20604 (parallel [(const_int 1)])))
20605 (plus:SF
20606 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20607 (parallel [(const_int 0)]))
20608 (vec_select:SF (match_dup 2)
20609 (parallel [(const_int 1)])))))]
20610 "TARGET_3DNOW"
20611 "pfacc\\t{%2, %0|%0, %2}"
20612 [(set_attr "type" "mmxadd")
20613 (set_attr "mode" "V2SF")])
20614
20615 (define_insn "pfnacc"
20616 [(set (match_operand:V2SF 0 "register_operand" "=y")
20617 (vec_concat:V2SF
20618 (minus:SF
20619 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20620 (parallel [(const_int 0)]))
20621 (vec_select:SF (match_dup 1)
20622 (parallel [(const_int 1)])))
20623 (minus:SF
20624 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20625 (parallel [(const_int 0)]))
20626 (vec_select:SF (match_dup 2)
20627 (parallel [(const_int 1)])))))]
20628 "TARGET_3DNOW_A"
20629 "pfnacc\\t{%2, %0|%0, %2}"
20630 [(set_attr "type" "mmxadd")
20631 (set_attr "mode" "V2SF")])
20632
20633 (define_insn "pfpnacc"
20634 [(set (match_operand:V2SF 0 "register_operand" "=y")
20635 (vec_concat:V2SF
20636 (minus:SF
20637 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20638 (parallel [(const_int 0)]))
20639 (vec_select:SF (match_dup 1)
20640 (parallel [(const_int 1)])))
20641 (plus:SF
20642 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20643 (parallel [(const_int 0)]))
20644 (vec_select:SF (match_dup 2)
20645 (parallel [(const_int 1)])))))]
20646 "TARGET_3DNOW_A"
20647 "pfpnacc\\t{%2, %0|%0, %2}"
20648 [(set_attr "type" "mmxadd")
20649 (set_attr "mode" "V2SF")])
20650
20651 (define_insn "pi2fw"
20652 [(set (match_operand:V2SF 0 "register_operand" "=y")
20653 (float:V2SF
20654 (vec_concat:V2SI
20655 (sign_extend:SI
20656 (truncate:HI
20657 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
20658 (parallel [(const_int 0)]))))
20659 (sign_extend:SI
20660 (truncate:HI
20661 (vec_select:SI (match_dup 1)
20662 (parallel [(const_int 1)])))))))]
20663 "TARGET_3DNOW_A"
20664 "pi2fw\\t{%1, %0|%0, %1}"
20665 [(set_attr "type" "mmxcvt")
20666 (set_attr "mode" "V2SF")])
20667
20668 (define_insn "floatv2si2"
20669 [(set (match_operand:V2SF 0 "register_operand" "=y")
20670 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
20671 "TARGET_3DNOW"
20672 "pi2fd\\t{%1, %0|%0, %1}"
20673 [(set_attr "type" "mmxcvt")
20674 (set_attr "mode" "V2SF")])
20675
20676 ;; This insn is identical to pavgb in operation, but the opcode is
20677 ;; different. To avoid accidentally matching pavgb, use an unspec.
20678
20679 (define_insn "pavgusb"
20680 [(set (match_operand:V8QI 0 "register_operand" "=y")
20681 (unspec:V8QI
20682 [(match_operand:V8QI 1 "register_operand" "0")
20683 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20684 UNSPEC_PAVGUSB))]
20685 "TARGET_3DNOW"
20686 "pavgusb\\t{%2, %0|%0, %2}"
20687 [(set_attr "type" "mmxshft")
20688 (set_attr "mode" "TI")])
20689
20690 ;; 3DNow reciprical and sqrt
20691
20692 (define_insn "pfrcpv2sf2"
20693 [(set (match_operand:V2SF 0 "register_operand" "=y")
20694 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
20695 UNSPEC_PFRCP))]
20696 "TARGET_3DNOW"
20697 "pfrcp\\t{%1, %0|%0, %1}"
20698 [(set_attr "type" "mmx")
20699 (set_attr "mode" "TI")])
20700
20701 (define_insn "pfrcpit1v2sf3"
20702 [(set (match_operand:V2SF 0 "register_operand" "=y")
20703 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20704 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20705 UNSPEC_PFRCPIT1))]
20706 "TARGET_3DNOW"
20707 "pfrcpit1\\t{%2, %0|%0, %2}"
20708 [(set_attr "type" "mmx")
20709 (set_attr "mode" "TI")])
20710
20711 (define_insn "pfrcpit2v2sf3"
20712 [(set (match_operand:V2SF 0 "register_operand" "=y")
20713 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20714 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20715 UNSPEC_PFRCPIT2))]
20716 "TARGET_3DNOW"
20717 "pfrcpit2\\t{%2, %0|%0, %2}"
20718 [(set_attr "type" "mmx")
20719 (set_attr "mode" "TI")])
20720
20721 (define_insn "pfrsqrtv2sf2"
20722 [(set (match_operand:V2SF 0 "register_operand" "=y")
20723 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
20724 UNSPEC_PFRSQRT))]
20725 "TARGET_3DNOW"
20726 "pfrsqrt\\t{%1, %0|%0, %1}"
20727 [(set_attr "type" "mmx")
20728 (set_attr "mode" "TI")])
20729
20730 (define_insn "pfrsqit1v2sf3"
20731 [(set (match_operand:V2SF 0 "register_operand" "=y")
20732 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20733 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20734 UNSPEC_PFRSQIT1))]
20735 "TARGET_3DNOW"
20736 "pfrsqit1\\t{%2, %0|%0, %2}"
20737 [(set_attr "type" "mmx")
20738 (set_attr "mode" "TI")])
20739
20740 (define_insn "pmulhrwv4hi3"
20741 [(set (match_operand:V4HI 0 "register_operand" "=y")
20742 (truncate:V4HI
20743 (lshiftrt:V4SI
20744 (plus:V4SI
20745 (mult:V4SI
20746 (sign_extend:V4SI
20747 (match_operand:V4HI 1 "register_operand" "0"))
20748 (sign_extend:V4SI
20749 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20750 (const_vector:V4SI [(const_int 32768)
20751 (const_int 32768)
20752 (const_int 32768)
20753 (const_int 32768)]))
20754 (const_int 16))))]
20755 "TARGET_3DNOW"
20756 "pmulhrw\\t{%2, %0|%0, %2}"
20757 [(set_attr "type" "mmxmul")
20758 (set_attr "mode" "TI")])
20759
20760 (define_insn "pswapdv2si2"
20761 [(set (match_operand:V2SI 0 "register_operand" "=y")
20762 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
20763 (parallel [(const_int 1) (const_int 0)])))]
20764 "TARGET_3DNOW_A"
20765 "pswapd\\t{%1, %0|%0, %1}"
20766 [(set_attr "type" "mmxcvt")
20767 (set_attr "mode" "TI")])
20768
20769 (define_insn "pswapdv2sf2"
20770 [(set (match_operand:V2SF 0 "register_operand" "=y")
20771 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
20772 (parallel [(const_int 1) (const_int 0)])))]
20773 "TARGET_3DNOW_A"
20774 "pswapd\\t{%1, %0|%0, %1}"
20775 [(set_attr "type" "mmxcvt")
20776 (set_attr "mode" "TI")])
20777
20778 (define_expand "prefetch"
20779 [(prefetch (match_operand 0 "address_operand" "")
20780 (match_operand:SI 1 "const_int_operand" "")
20781 (match_operand:SI 2 "const_int_operand" ""))]
20782 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20783 {
20784 int rw = INTVAL (operands[1]);
20785 int locality = INTVAL (operands[2]);
20786
20787 if (rw != 0 && rw != 1)
20788 abort ();
20789 if (locality < 0 || locality > 3)
20790 abort ();
20791 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
20792 abort ();
20793
20794 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20795 suported by SSE counterpart or the SSE prefetch is not available
20796 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20797 of locality. */
20798 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20799 operands[2] = GEN_INT (3);
20800 else
20801 operands[1] = const0_rtx;
20802 })
20803
20804 (define_insn "*prefetch_sse"
20805 [(prefetch (match_operand:SI 0 "address_operand" "p")
20806 (const_int 0)
20807 (match_operand:SI 1 "const_int_operand" ""))]
20808 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20809 {
20810 static const char * const patterns[4] = {
20811 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20812 };
20813
20814 int locality = INTVAL (operands[1]);
20815 if (locality < 0 || locality > 3)
20816 abort ();
20817
20818 return patterns[locality];
20819 }
20820 [(set_attr "type" "sse")
20821 (set_attr "memory" "none")])
20822
20823 (define_insn "*prefetch_sse_rex"
20824 [(prefetch (match_operand:DI 0 "address_operand" "p")
20825 (const_int 0)
20826 (match_operand:SI 1 "const_int_operand" ""))]
20827 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20828 {
20829 static const char * const patterns[4] = {
20830 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20831 };
20832
20833 int locality = INTVAL (operands[1]);
20834 if (locality < 0 || locality > 3)
20835 abort ();
20836
20837 return patterns[locality];
20838 }
20839 [(set_attr "type" "sse")
20840 (set_attr "memory" "none")])
20841
20842 (define_insn "*prefetch_3dnow"
20843 [(prefetch (match_operand:SI 0 "address_operand" "p")
20844 (match_operand:SI 1 "const_int_operand" "n")
20845 (const_int 3))]
20846 "TARGET_3DNOW && !TARGET_64BIT"
20847 {
20848 if (INTVAL (operands[1]) == 0)
20849 return "prefetch\t%a0";
20850 else
20851 return "prefetchw\t%a0";
20852 }
20853 [(set_attr "type" "mmx")
20854 (set_attr "memory" "none")])
20855
20856 (define_insn "*prefetch_3dnow_rex"
20857 [(prefetch (match_operand:DI 0 "address_operand" "p")
20858 (match_operand:SI 1 "const_int_operand" "n")
20859 (const_int 3))]
20860 "TARGET_3DNOW && TARGET_64BIT"
20861 {
20862 if (INTVAL (operands[1]) == 0)
20863 return "prefetch\t%a0";
20864 else
20865 return "prefetchw\t%a0";
20866 }
20867 [(set_attr "type" "mmx")
20868 (set_attr "memory" "none")])
20869
20870 ;; SSE2 support
20871
20872 (define_insn "addv2df3"
20873 [(set (match_operand:V2DF 0 "register_operand" "=x")
20874 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
20875 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20876 "TARGET_SSE2"
20877 "addpd\t{%2, %0|%0, %2}"
20878 [(set_attr "type" "sseadd")
20879 (set_attr "mode" "V2DF")])
20880
20881 (define_insn "vmaddv2df3"
20882 [(set (match_operand:V2DF 0 "register_operand" "=x")
20883 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
20884 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20885 (match_dup 1)
20886 (const_int 1)))]
20887 "TARGET_SSE2"
20888 "addsd\t{%2, %0|%0, %2}"
20889 [(set_attr "type" "sseadd")
20890 (set_attr "mode" "DF")])
20891
20892 (define_insn "subv2df3"
20893 [(set (match_operand:V2DF 0 "register_operand" "=x")
20894 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
20895 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20896 "TARGET_SSE2"
20897 "subpd\t{%2, %0|%0, %2}"
20898 [(set_attr "type" "sseadd")
20899 (set_attr "mode" "V2DF")])
20900
20901 (define_insn "vmsubv2df3"
20902 [(set (match_operand:V2DF 0 "register_operand" "=x")
20903 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
20904 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20905 (match_dup 1)
20906 (const_int 1)))]
20907 "TARGET_SSE2"
20908 "subsd\t{%2, %0|%0, %2}"
20909 [(set_attr "type" "sseadd")
20910 (set_attr "mode" "DF")])
20911
20912 (define_insn "mulv2df3"
20913 [(set (match_operand:V2DF 0 "register_operand" "=x")
20914 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
20915 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20916 "TARGET_SSE2"
20917 "mulpd\t{%2, %0|%0, %2}"
20918 [(set_attr "type" "ssemul")
20919 (set_attr "mode" "V2DF")])
20920
20921 (define_insn "vmmulv2df3"
20922 [(set (match_operand:V2DF 0 "register_operand" "=x")
20923 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
20924 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20925 (match_dup 1)
20926 (const_int 1)))]
20927 "TARGET_SSE2"
20928 "mulsd\t{%2, %0|%0, %2}"
20929 [(set_attr "type" "ssemul")
20930 (set_attr "mode" "DF")])
20931
20932 (define_insn "divv2df3"
20933 [(set (match_operand:V2DF 0 "register_operand" "=x")
20934 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
20935 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20936 "TARGET_SSE2"
20937 "divpd\t{%2, %0|%0, %2}"
20938 [(set_attr "type" "ssediv")
20939 (set_attr "mode" "V2DF")])
20940
20941 (define_insn "vmdivv2df3"
20942 [(set (match_operand:V2DF 0 "register_operand" "=x")
20943 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
20944 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20945 (match_dup 1)
20946 (const_int 1)))]
20947 "TARGET_SSE2"
20948 "divsd\t{%2, %0|%0, %2}"
20949 [(set_attr "type" "ssediv")
20950 (set_attr "mode" "DF")])
20951
20952 ;; SSE min/max
20953
20954 (define_insn "smaxv2df3"
20955 [(set (match_operand:V2DF 0 "register_operand" "=x")
20956 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
20957 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20958 "TARGET_SSE2"
20959 "maxpd\t{%2, %0|%0, %2}"
20960 [(set_attr "type" "sseadd")
20961 (set_attr "mode" "V2DF")])
20962
20963 (define_insn "vmsmaxv2df3"
20964 [(set (match_operand:V2DF 0 "register_operand" "=x")
20965 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
20966 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20967 (match_dup 1)
20968 (const_int 1)))]
20969 "TARGET_SSE2"
20970 "maxsd\t{%2, %0|%0, %2}"
20971 [(set_attr "type" "sseadd")
20972 (set_attr "mode" "DF")])
20973
20974 (define_insn "sminv2df3"
20975 [(set (match_operand:V2DF 0 "register_operand" "=x")
20976 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
20977 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20978 "TARGET_SSE2"
20979 "minpd\t{%2, %0|%0, %2}"
20980 [(set_attr "type" "sseadd")
20981 (set_attr "mode" "V2DF")])
20982
20983 (define_insn "vmsminv2df3"
20984 [(set (match_operand:V2DF 0 "register_operand" "=x")
20985 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
20986 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20987 (match_dup 1)
20988 (const_int 1)))]
20989 "TARGET_SSE2"
20990 "minsd\t{%2, %0|%0, %2}"
20991 [(set_attr "type" "sseadd")
20992 (set_attr "mode" "DF")])
20993 ;; SSE2 square root. There doesn't appear to be an extension for the
20994 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
20995
20996 (define_insn "sqrtv2df2"
20997 [(set (match_operand:V2DF 0 "register_operand" "=x")
20998 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
20999 "TARGET_SSE2"
21000 "sqrtpd\t{%1, %0|%0, %1}"
21001 [(set_attr "type" "sse")
21002 (set_attr "mode" "V2DF")])
21003
21004 (define_insn "vmsqrtv2df2"
21005 [(set (match_operand:V2DF 0 "register_operand" "=x")
21006 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21007 (match_operand:V2DF 2 "register_operand" "0")
21008 (const_int 1)))]
21009 "TARGET_SSE2"
21010 "sqrtsd\t{%1, %0|%0, %1}"
21011 [(set_attr "type" "sse")
21012 (set_attr "mode" "SF")])
21013
21014 ;; SSE mask-generating compares
21015
21016 (define_insn "maskcmpv2df3"
21017 [(set (match_operand:V2DI 0 "register_operand" "=x")
21018 (match_operator:V2DI 3 "sse_comparison_operator"
21019 [(match_operand:V2DF 1 "register_operand" "0")
21020 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21021 "TARGET_SSE2"
21022 "cmp%D3pd\t{%2, %0|%0, %2}"
21023 [(set_attr "type" "ssecmp")
21024 (set_attr "mode" "V2DF")])
21025
21026 (define_insn "maskncmpv2df3"
21027 [(set (match_operand:V2DI 0 "register_operand" "=x")
21028 (not:V2DI
21029 (match_operator:V2DI 3 "sse_comparison_operator"
21030 [(match_operand:V2DF 1 "register_operand" "0")
21031 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21032 "TARGET_SSE2"
21033 {
21034 if (GET_CODE (operands[3]) == UNORDERED)
21035 return "cmpordps\t{%2, %0|%0, %2}";
21036 else
21037 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21038 }
21039 [(set_attr "type" "ssecmp")
21040 (set_attr "mode" "V2DF")])
21041
21042 (define_insn "vmmaskcmpv2df3"
21043 [(set (match_operand:V2DI 0 "register_operand" "=x")
21044 (vec_merge:V2DI
21045 (match_operator:V2DI 3 "sse_comparison_operator"
21046 [(match_operand:V2DF 1 "register_operand" "0")
21047 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21048 (match_dup 1)
21049 (const_int 1)))]
21050 "TARGET_SSE2"
21051 "cmp%D3sd\t{%2, %0|%0, %2}"
21052 [(set_attr "type" "ssecmp")
21053 (set_attr "mode" "DF")])
21054
21055 (define_insn "vmmaskncmpv2df3"
21056 [(set (match_operand:V2DI 0 "register_operand" "=x")
21057 (vec_merge:V2DI
21058 (not:V2DI
21059 (match_operator:V2DI 3 "sse_comparison_operator"
21060 [(match_operand:V2DF 1 "register_operand" "0")
21061 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21062 (subreg:V2DI (match_dup 1) 0)
21063 (const_int 1)))]
21064 "TARGET_SSE2"
21065 {
21066 if (GET_CODE (operands[3]) == UNORDERED)
21067 return "cmpordsd\t{%2, %0|%0, %2}";
21068 else
21069 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21070 }
21071 [(set_attr "type" "ssecmp")
21072 (set_attr "mode" "DF")])
21073
21074 (define_insn "sse2_comi"
21075 [(set (reg:CCFP 17)
21076 (compare:CCFP (vec_select:DF
21077 (match_operand:V2DF 0 "register_operand" "x")
21078 (parallel [(const_int 0)]))
21079 (vec_select:DF
21080 (match_operand:V2DF 1 "register_operand" "x")
21081 (parallel [(const_int 0)]))))]
21082 "TARGET_SSE2"
21083 "comisd\t{%1, %0|%0, %1}"
21084 [(set_attr "type" "ssecmp")
21085 (set_attr "mode" "DF")])
21086
21087 (define_insn "sse2_ucomi"
21088 [(set (reg:CCFPU 17)
21089 (compare:CCFPU (vec_select:DF
21090 (match_operand:V2DF 0 "register_operand" "x")
21091 (parallel [(const_int 0)]))
21092 (vec_select:DF
21093 (match_operand:V2DF 1 "register_operand" "x")
21094 (parallel [(const_int 0)]))))]
21095 "TARGET_SSE2"
21096 "ucomisd\t{%1, %0|%0, %1}"
21097 [(set_attr "type" "ssecmp")
21098 (set_attr "mode" "DF")])
21099
21100 ;; SSE Strange Moves.
21101
21102 (define_insn "sse2_movmskpd"
21103 [(set (match_operand:SI 0 "register_operand" "=r")
21104 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21105 UNSPEC_MOVMSK))]
21106 "TARGET_SSE2"
21107 "movmskpd\t{%1, %0|%0, %1}"
21108 [(set_attr "type" "ssecvt")
21109 (set_attr "mode" "V2DF")])
21110
21111 (define_insn "sse2_pmovmskb"
21112 [(set (match_operand:SI 0 "register_operand" "=r")
21113 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21114 UNSPEC_MOVMSK))]
21115 "TARGET_SSE2"
21116 "pmovmskb\t{%1, %0|%0, %1}"
21117 [(set_attr "type" "ssecvt")
21118 (set_attr "mode" "V2DF")])
21119
21120 (define_insn "sse2_maskmovdqu"
21121 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21122 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21123 (match_operand:V16QI 2 "register_operand" "x")]
21124 UNSPEC_MASKMOV))]
21125 "TARGET_SSE2"
21126 ;; @@@ check ordering of operands in intel/nonintel syntax
21127 "maskmovdqu\t{%2, %1|%1, %2}"
21128 [(set_attr "type" "ssecvt")
21129 (set_attr "mode" "TI")])
21130
21131 (define_insn "sse2_maskmovdqu_rex64"
21132 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21133 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21134 (match_operand:V16QI 2 "register_operand" "x")]
21135 UNSPEC_MASKMOV))]
21136 "TARGET_SSE2"
21137 ;; @@@ check ordering of operands in intel/nonintel syntax
21138 "maskmovdqu\t{%2, %1|%1, %2}"
21139 [(set_attr "type" "ssecvt")
21140 (set_attr "mode" "TI")])
21141
21142 (define_insn "sse2_movntv2df"
21143 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21144 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21145 UNSPEC_MOVNT))]
21146 "TARGET_SSE2"
21147 "movntpd\t{%1, %0|%0, %1}"
21148 [(set_attr "type" "ssecvt")
21149 (set_attr "mode" "V2DF")])
21150
21151 (define_insn "sse2_movntv2di"
21152 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21153 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21154 UNSPEC_MOVNT))]
21155 "TARGET_SSE2"
21156 "movntdq\t{%1, %0|%0, %1}"
21157 [(set_attr "type" "ssecvt")
21158 (set_attr "mode" "TI")])
21159
21160 (define_insn "sse2_movntsi"
21161 [(set (match_operand:SI 0 "memory_operand" "=m")
21162 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21163 UNSPEC_MOVNT))]
21164 "TARGET_SSE2"
21165 "movnti\t{%1, %0|%0, %1}"
21166 [(set_attr "type" "ssecvt")
21167 (set_attr "mode" "V2DF")])
21168
21169 ;; SSE <-> integer/MMX conversions
21170
21171 ;; Conversions between SI and SF
21172
21173 (define_insn "cvtdq2ps"
21174 [(set (match_operand:V4SF 0 "register_operand" "=x")
21175 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21176 "TARGET_SSE2"
21177 "cvtdq2ps\t{%1, %0|%0, %1}"
21178 [(set_attr "type" "ssecvt")
21179 (set_attr "mode" "V2DF")])
21180
21181 (define_insn "cvtps2dq"
21182 [(set (match_operand:V4SI 0 "register_operand" "=x")
21183 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21184 "TARGET_SSE2"
21185 "cvtps2dq\t{%1, %0|%0, %1}"
21186 [(set_attr "type" "ssecvt")
21187 (set_attr "mode" "TI")])
21188
21189 (define_insn "cvttps2dq"
21190 [(set (match_operand:V4SI 0 "register_operand" "=x")
21191 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21192 UNSPEC_FIX))]
21193 "TARGET_SSE2"
21194 "cvttps2dq\t{%1, %0|%0, %1}"
21195 [(set_attr "type" "ssecvt")
21196 (set_attr "mode" "TI")])
21197
21198 ;; Conversions between SI and DF
21199
21200 (define_insn "cvtdq2pd"
21201 [(set (match_operand:V2DF 0 "register_operand" "=x")
21202 (float:V2DF (vec_select:V2SI
21203 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21204 (parallel
21205 [(const_int 0)
21206 (const_int 1)]))))]
21207 "TARGET_SSE2"
21208 "cvtdq2pd\t{%1, %0|%0, %1}"
21209 [(set_attr "type" "ssecvt")
21210 (set_attr "mode" "V2DF")])
21211
21212 (define_insn "cvtpd2dq"
21213 [(set (match_operand:V4SI 0 "register_operand" "=x")
21214 (vec_concat:V4SI
21215 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21216 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21217 "TARGET_SSE2"
21218 "cvtpd2dq\t{%1, %0|%0, %1}"
21219 [(set_attr "type" "ssecvt")
21220 (set_attr "mode" "TI")])
21221
21222 (define_insn "cvttpd2dq"
21223 [(set (match_operand:V4SI 0 "register_operand" "=x")
21224 (vec_concat:V4SI
21225 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21226 UNSPEC_FIX)
21227 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21228 "TARGET_SSE2"
21229 "cvttpd2dq\t{%1, %0|%0, %1}"
21230 [(set_attr "type" "ssecvt")
21231 (set_attr "mode" "TI")])
21232
21233 (define_insn "cvtpd2pi"
21234 [(set (match_operand:V2SI 0 "register_operand" "=y")
21235 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21236 "TARGET_SSE2"
21237 "cvtpd2pi\t{%1, %0|%0, %1}"
21238 [(set_attr "type" "ssecvt")
21239 (set_attr "mode" "TI")])
21240
21241 (define_insn "cvttpd2pi"
21242 [(set (match_operand:V2SI 0 "register_operand" "=y")
21243 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21244 UNSPEC_FIX))]
21245 "TARGET_SSE2"
21246 "cvttpd2pi\t{%1, %0|%0, %1}"
21247 [(set_attr "type" "ssecvt")
21248 (set_attr "mode" "TI")])
21249
21250 (define_insn "cvtpi2pd"
21251 [(set (match_operand:V2DF 0 "register_operand" "=x")
21252 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21253 "TARGET_SSE2"
21254 "cvtpi2pd\t{%1, %0|%0, %1}"
21255 [(set_attr "type" "ssecvt")
21256 (set_attr "mode" "TI")])
21257
21258 ;; Conversions between SI and DF
21259
21260 (define_insn "cvtsd2si"
21261 [(set (match_operand:SI 0 "register_operand" "=r")
21262 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
21263 (parallel [(const_int 0)]))))]
21264 "TARGET_SSE2"
21265 "cvtsd2si\t{%1, %0|%0, %1}"
21266 [(set_attr "type" "ssecvt")
21267 (set_attr "mode" "SI")])
21268
21269 (define_insn "cvttsd2si"
21270 [(set (match_operand:SI 0 "register_operand" "=r")
21271 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
21272 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21273 "TARGET_SSE2"
21274 "cvttsd2si\t{%1, %0|%0, %1}"
21275 [(set_attr "type" "ssecvt")
21276 (set_attr "mode" "SI")])
21277
21278 (define_insn "cvtsi2sd"
21279 [(set (match_operand:V2DF 0 "register_operand" "=x")
21280 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21281 (vec_duplicate:V2DF
21282 (float:DF
21283 (match_operand:SI 2 "nonimmediate_operand" "rm")))
21284 (const_int 2)))]
21285 "TARGET_SSE2"
21286 "cvtsi2sd\t{%2, %0|%0, %2}"
21287 [(set_attr "type" "ssecvt")
21288 (set_attr "mode" "DF")])
21289
21290 ;; Conversions between SF and DF
21291
21292 (define_insn "cvtsd2ss"
21293 [(set (match_operand:V4SF 0 "register_operand" "=x")
21294 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
21295 (vec_duplicate:V4SF
21296 (float_truncate:V2SF
21297 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))
21298 (const_int 14)))]
21299 "TARGET_SSE2"
21300 "cvtsd2ss\t{%2, %0|%0, %2}"
21301 [(set_attr "type" "ssecvt")
21302 (set_attr "mode" "SF")])
21303
21304 (define_insn "cvtss2sd"
21305 [(set (match_operand:V2DF 0 "register_operand" "=x")
21306 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21307 (float_extend:V2DF
21308 (vec_select:V2SF
21309 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21310 (parallel [(const_int 0)
21311 (const_int 1)])))
21312 (const_int 2)))]
21313 "TARGET_SSE2"
21314 "cvtss2sd\t{%2, %0|%0, %2}"
21315 [(set_attr "type" "ssecvt")
21316 (set_attr "mode" "DF")])
21317
21318 (define_insn "cvtpd2ps"
21319 [(set (match_operand:V4SF 0 "register_operand" "=x")
21320 (subreg:V4SF
21321 (vec_concat:V4SI
21322 (subreg:V2SI (float_truncate:V2SF
21323 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21324 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21325 "TARGET_SSE2"
21326 "cvtpd2ps\t{%1, %0|%0, %1}"
21327 [(set_attr "type" "ssecvt")
21328 (set_attr "mode" "V4SF")])
21329
21330 (define_insn "cvtps2pd"
21331 [(set (match_operand:V2DF 0 "register_operand" "=x")
21332 (float_extend:V2DF
21333 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21334 (parallel [(const_int 0)
21335 (const_int 1)]))))]
21336 "TARGET_SSE2"
21337 "cvtps2pd\t{%1, %0|%0, %1}"
21338 [(set_attr "type" "ssecvt")
21339 (set_attr "mode" "V2DF")])
21340
21341 ;; SSE2 variants of MMX insns
21342
21343 ;; MMX arithmetic
21344
21345 (define_insn "addv16qi3"
21346 [(set (match_operand:V16QI 0 "register_operand" "=x")
21347 (plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21348 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21349 "TARGET_SSE2"
21350 "paddb\t{%2, %0|%0, %2}"
21351 [(set_attr "type" "sseiadd")
21352 (set_attr "mode" "TI")])
21353
21354 (define_insn "addv8hi3"
21355 [(set (match_operand:V8HI 0 "register_operand" "=x")
21356 (plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21357 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21358 "TARGET_SSE2"
21359 "paddw\t{%2, %0|%0, %2}"
21360 [(set_attr "type" "sseiadd")
21361 (set_attr "mode" "TI")])
21362
21363 (define_insn "addv4si3"
21364 [(set (match_operand:V4SI 0 "register_operand" "=x")
21365 (plus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21366 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21367 "TARGET_SSE2"
21368 "paddd\t{%2, %0|%0, %2}"
21369 [(set_attr "type" "sseiadd")
21370 (set_attr "mode" "TI")])
21371
21372 (define_insn "addv2di3"
21373 [(set (match_operand:V2DI 0 "register_operand" "=x")
21374 (plus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21375 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21376 "TARGET_SSE2"
21377 "paddq\t{%2, %0|%0, %2}"
21378 [(set_attr "type" "sseiadd")
21379 (set_attr "mode" "TI")])
21380
21381 (define_insn "ssaddv16qi3"
21382 [(set (match_operand:V16QI 0 "register_operand" "=x")
21383 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21384 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21385 "TARGET_SSE2"
21386 "paddsb\t{%2, %0|%0, %2}"
21387 [(set_attr "type" "sseiadd")
21388 (set_attr "mode" "TI")])
21389
21390 (define_insn "ssaddv8hi3"
21391 [(set (match_operand:V8HI 0 "register_operand" "=x")
21392 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21393 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21394 "TARGET_SSE2"
21395 "paddsw\t{%2, %0|%0, %2}"
21396 [(set_attr "type" "sseiadd")
21397 (set_attr "mode" "TI")])
21398
21399 (define_insn "usaddv16qi3"
21400 [(set (match_operand:V16QI 0 "register_operand" "=x")
21401 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21402 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21403 "TARGET_SSE2"
21404 "paddusb\t{%2, %0|%0, %2}"
21405 [(set_attr "type" "sseiadd")
21406 (set_attr "mode" "TI")])
21407
21408 (define_insn "usaddv8hi3"
21409 [(set (match_operand:V8HI 0 "register_operand" "=x")
21410 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21411 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21412 "TARGET_SSE2"
21413 "paddusw\t{%2, %0|%0, %2}"
21414 [(set_attr "type" "sseiadd")
21415 (set_attr "mode" "TI")])
21416
21417 (define_insn "subv16qi3"
21418 [(set (match_operand:V16QI 0 "register_operand" "=x")
21419 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21420 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21421 "TARGET_SSE2"
21422 "psubb\t{%2, %0|%0, %2}"
21423 [(set_attr "type" "sseiadd")
21424 (set_attr "mode" "TI")])
21425
21426 (define_insn "subv8hi3"
21427 [(set (match_operand:V8HI 0 "register_operand" "=x")
21428 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21429 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21430 "TARGET_SSE2"
21431 "psubw\t{%2, %0|%0, %2}"
21432 [(set_attr "type" "sseiadd")
21433 (set_attr "mode" "TI")])
21434
21435 (define_insn "subv4si3"
21436 [(set (match_operand:V4SI 0 "register_operand" "=x")
21437 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21438 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21439 "TARGET_SSE2"
21440 "psubd\t{%2, %0|%0, %2}"
21441 [(set_attr "type" "sseiadd")
21442 (set_attr "mode" "TI")])
21443
21444 (define_insn "subv2di3"
21445 [(set (match_operand:V2DI 0 "register_operand" "=x")
21446 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21447 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21448 "TARGET_SSE2"
21449 "psubq\t{%2, %0|%0, %2}"
21450 [(set_attr "type" "sseiadd")
21451 (set_attr "mode" "TI")])
21452
21453 (define_insn "sssubv16qi3"
21454 [(set (match_operand:V16QI 0 "register_operand" "=x")
21455 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21456 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21457 "TARGET_SSE2"
21458 "psubsb\t{%2, %0|%0, %2}"
21459 [(set_attr "type" "sseiadd")
21460 (set_attr "mode" "TI")])
21461
21462 (define_insn "sssubv8hi3"
21463 [(set (match_operand:V8HI 0 "register_operand" "=x")
21464 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21465 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21466 "TARGET_SSE2"
21467 "psubsw\t{%2, %0|%0, %2}"
21468 [(set_attr "type" "sseiadd")
21469 (set_attr "mode" "TI")])
21470
21471 (define_insn "ussubv16qi3"
21472 [(set (match_operand:V16QI 0 "register_operand" "=x")
21473 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21474 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21475 "TARGET_SSE2"
21476 "psubusb\t{%2, %0|%0, %2}"
21477 [(set_attr "type" "sseiadd")
21478 (set_attr "mode" "TI")])
21479
21480 (define_insn "ussubv8hi3"
21481 [(set (match_operand:V8HI 0 "register_operand" "=x")
21482 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21483 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21484 "TARGET_SSE2"
21485 "psubusw\t{%2, %0|%0, %2}"
21486 [(set_attr "type" "sseiadd")
21487 (set_attr "mode" "TI")])
21488
21489 (define_insn "mulv8hi3"
21490 [(set (match_operand:V8HI 0 "register_operand" "=x")
21491 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21492 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21493 "TARGET_SSE2"
21494 "pmullw\t{%2, %0|%0, %2}"
21495 [(set_attr "type" "sseimul")
21496 (set_attr "mode" "TI")])
21497
21498 (define_insn "smulv8hi3_highpart"
21499 [(set (match_operand:V8HI 0 "register_operand" "=x")
21500 (truncate:V8HI
21501 (lshiftrt:V8SI
21502 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21503 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21504 (const_int 16))))]
21505 "TARGET_SSE2"
21506 "pmulhw\t{%2, %0|%0, %2}"
21507 [(set_attr "type" "sseimul")
21508 (set_attr "mode" "TI")])
21509
21510 (define_insn "umulv8hi3_highpart"
21511 [(set (match_operand:V8HI 0 "register_operand" "=x")
21512 (truncate:V8HI
21513 (lshiftrt:V8SI
21514 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21515 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21516 (const_int 16))))]
21517 "TARGET_SSE2"
21518 "pmulhuw\t{%2, %0|%0, %2}"
21519 [(set_attr "type" "sseimul")
21520 (set_attr "mode" "TI")])
21521
21522 (define_insn "sse2_umulsidi3"
21523 [(set (match_operand:DI 0 "register_operand" "=y")
21524 (mult:DI (zero_extend:DI (vec_select:SI
21525 (match_operand:V2SI 1 "register_operand" "0")
21526 (parallel [(const_int 0)])))
21527 (zero_extend:DI (vec_select:SI
21528 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
21529 (parallel [(const_int 0)])))))]
21530 "TARGET_SSE2"
21531 "pmuludq\t{%2, %0|%0, %2}"
21532 [(set_attr "type" "sseimul")
21533 (set_attr "mode" "TI")])
21534
21535 (define_insn "sse2_umulv2siv2di3"
21536 [(set (match_operand:V2DI 0 "register_operand" "=x")
21537 (mult:V2DI (zero_extend:V2DI
21538 (vec_select:V2SI
21539 (match_operand:V4SI 1 "register_operand" "0")
21540 (parallel [(const_int 0) (const_int 2)])))
21541 (zero_extend:V2DI
21542 (vec_select:V2SI
21543 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
21544 (parallel [(const_int 0) (const_int 2)])))))]
21545 "TARGET_SSE2"
21546 "pmuludq\t{%2, %0|%0, %2}"
21547 [(set_attr "type" "sseimul")
21548 (set_attr "mode" "TI")])
21549
21550 (define_insn "sse2_pmaddwd"
21551 [(set (match_operand:V4SI 0 "register_operand" "=x")
21552 (plus:V4SI
21553 (mult:V4SI
21554 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
21555 (parallel [(const_int 0)
21556 (const_int 2)
21557 (const_int 4)
21558 (const_int 6)])))
21559 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
21560 (parallel [(const_int 0)
21561 (const_int 2)
21562 (const_int 4)
21563 (const_int 6)]))))
21564 (mult:V4SI
21565 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
21566 (parallel [(const_int 1)
21567 (const_int 3)
21568 (const_int 5)
21569 (const_int 7)])))
21570 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
21571 (parallel [(const_int 1)
21572 (const_int 3)
21573 (const_int 5)
21574 (const_int 7)]))))))]
21575 "TARGET_SSE2"
21576 "pmaddwd\t{%2, %0|%0, %2}"
21577 [(set_attr "type" "sseiadd")
21578 (set_attr "mode" "TI")])
21579
21580 ;; Same as pxor, but don't show input operands so that we don't think
21581 ;; they are live.
21582 (define_insn "sse2_clrti"
21583 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
21584 "TARGET_SSE2"
21585 {
21586 if (get_attr_mode (insn) == MODE_TI)
21587 return "pxor\t%0, %0";
21588 else
21589 return "xorps\t%0, %0";
21590 }
21591 [(set_attr "type" "ssemov")
21592 (set_attr "memory" "none")
21593 (set (attr "mode")
21594 (if_then_else
21595 (ne (symbol_ref "optimize_size")
21596 (const_int 0))
21597 (const_string "V4SF")
21598 (const_string "TI")))])
21599
21600 ;; MMX unsigned averages/sum of absolute differences
21601
21602 (define_insn "sse2_uavgv16qi3"
21603 [(set (match_operand:V16QI 0 "register_operand" "=x")
21604 (ashiftrt:V16QI
21605 (plus:V16QI (plus:V16QI
21606 (match_operand:V16QI 1 "register_operand" "0")
21607 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
21608 (const_vector:V16QI [(const_int 1) (const_int 1)
21609 (const_int 1) (const_int 1)
21610 (const_int 1) (const_int 1)
21611 (const_int 1) (const_int 1)
21612 (const_int 1) (const_int 1)
21613 (const_int 1) (const_int 1)
21614 (const_int 1) (const_int 1)
21615 (const_int 1) (const_int 1)]))
21616 (const_int 1)))]
21617 "TARGET_SSE2"
21618 "pavgb\t{%2, %0|%0, %2}"
21619 [(set_attr "type" "sseiadd")
21620 (set_attr "mode" "TI")])
21621
21622 (define_insn "sse2_uavgv8hi3"
21623 [(set (match_operand:V8HI 0 "register_operand" "=x")
21624 (ashiftrt:V8HI
21625 (plus:V8HI (plus:V8HI
21626 (match_operand:V8HI 1 "register_operand" "0")
21627 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
21628 (const_vector:V8HI [(const_int 1) (const_int 1)
21629 (const_int 1) (const_int 1)
21630 (const_int 1) (const_int 1)
21631 (const_int 1) (const_int 1)]))
21632 (const_int 1)))]
21633 "TARGET_SSE2"
21634 "pavgw\t{%2, %0|%0, %2}"
21635 [(set_attr "type" "sseiadd")
21636 (set_attr "mode" "TI")])
21637
21638 ;; @@@ this isn't the right representation.
21639 (define_insn "sse2_psadbw"
21640 [(set (match_operand:V2DI 0 "register_operand" "=x")
21641 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
21642 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
21643 UNSPEC_PSADBW))]
21644 "TARGET_SSE2"
21645 "psadbw\t{%2, %0|%0, %2}"
21646 [(set_attr "type" "sseiadd")
21647 (set_attr "mode" "TI")])
21648
21649
21650 ;; MMX insert/extract/shuffle
21651
21652 (define_insn "sse2_pinsrw"
21653 [(set (match_operand:V8HI 0 "register_operand" "=x")
21654 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
21655 (vec_duplicate:V8HI
21656 (match_operand:SI 2 "nonimmediate_operand" "rm"))
21657 (match_operand:SI 3 "immediate_operand" "i")))]
21658 "TARGET_SSE2"
21659 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21660 [(set_attr "type" "ssecvt")
21661 (set_attr "mode" "TI")])
21662
21663 (define_insn "sse2_pextrw"
21664 [(set (match_operand:SI 0 "register_operand" "=r")
21665 (zero_extend:SI
21666 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
21667 (parallel
21668 [(match_operand:SI 2 "immediate_operand" "i")]))))]
21669 "TARGET_SSE2"
21670 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21671 [(set_attr "type" "ssecvt")
21672 (set_attr "mode" "TI")])
21673
21674 (define_insn "sse2_pshufd"
21675 [(set (match_operand:V4SI 0 "register_operand" "=x")
21676 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
21677 (match_operand:SI 2 "immediate_operand" "i")]
21678 UNSPEC_SHUFFLE))]
21679 "TARGET_SSE2"
21680 "pshufd\t{%2, %1, %0|%0, %1, %2}"
21681 [(set_attr "type" "ssecvt")
21682 (set_attr "mode" "TI")])
21683
21684 (define_insn "sse2_pshuflw"
21685 [(set (match_operand:V8HI 0 "register_operand" "=x")
21686 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
21687 (match_operand:SI 2 "immediate_operand" "i")]
21688 UNSPEC_PSHUFLW))]
21689 "TARGET_SSE2"
21690 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
21691 [(set_attr "type" "ssecvt")
21692 (set_attr "mode" "TI")])
21693
21694 (define_insn "sse2_pshufhw"
21695 [(set (match_operand:V8HI 0 "register_operand" "=x")
21696 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
21697 (match_operand:SI 2 "immediate_operand" "i")]
21698 UNSPEC_PSHUFHW))]
21699 "TARGET_SSE2"
21700 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
21701 [(set_attr "type" "ssecvt")
21702 (set_attr "mode" "TI")])
21703
21704 ;; MMX mask-generating comparisons
21705
21706 (define_insn "eqv16qi3"
21707 [(set (match_operand:V16QI 0 "register_operand" "=x")
21708 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
21709 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21710 "TARGET_SSE2"
21711 "pcmpeqb\t{%2, %0|%0, %2}"
21712 [(set_attr "type" "ssecmp")
21713 (set_attr "mode" "TI")])
21714
21715 (define_insn "eqv8hi3"
21716 [(set (match_operand:V8HI 0 "register_operand" "=x")
21717 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
21718 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21719 "TARGET_SSE2"
21720 "pcmpeqw\t{%2, %0|%0, %2}"
21721 [(set_attr "type" "ssecmp")
21722 (set_attr "mode" "TI")])
21723
21724 (define_insn "eqv4si3"
21725 [(set (match_operand:V4SI 0 "register_operand" "=x")
21726 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
21727 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21728 "TARGET_SSE2"
21729 "pcmpeqd\t{%2, %0|%0, %2}"
21730 [(set_attr "type" "ssecmp")
21731 (set_attr "mode" "TI")])
21732
21733 (define_insn "gtv16qi3"
21734 [(set (match_operand:V16QI 0 "register_operand" "=x")
21735 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
21736 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21737 "TARGET_SSE2"
21738 "pcmpgtb\t{%2, %0|%0, %2}"
21739 [(set_attr "type" "ssecmp")
21740 (set_attr "mode" "TI")])
21741
21742 (define_insn "gtv8hi3"
21743 [(set (match_operand:V8HI 0 "register_operand" "=x")
21744 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21745 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21746 "TARGET_SSE2"
21747 "pcmpgtw\t{%2, %0|%0, %2}"
21748 [(set_attr "type" "ssecmp")
21749 (set_attr "mode" "TI")])
21750
21751 (define_insn "gtv4si3"
21752 [(set (match_operand:V4SI 0 "register_operand" "=x")
21753 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21754 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21755 "TARGET_SSE2"
21756 "pcmpgtd\t{%2, %0|%0, %2}"
21757 [(set_attr "type" "ssecmp")
21758 (set_attr "mode" "TI")])
21759
21760
21761 ;; MMX max/min insns
21762
21763 (define_insn "umaxv16qi3"
21764 [(set (match_operand:V16QI 0 "register_operand" "=x")
21765 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
21766 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21767 "TARGET_SSE2"
21768 "pmaxub\t{%2, %0|%0, %2}"
21769 [(set_attr "type" "sseiadd")
21770 (set_attr "mode" "TI")])
21771
21772 (define_insn "smaxv8hi3"
21773 [(set (match_operand:V8HI 0 "register_operand" "=x")
21774 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
21775 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21776 "TARGET_SSE2"
21777 "pmaxsw\t{%2, %0|%0, %2}"
21778 [(set_attr "type" "sseiadd")
21779 (set_attr "mode" "TI")])
21780
21781 (define_insn "uminv16qi3"
21782 [(set (match_operand:V16QI 0 "register_operand" "=x")
21783 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
21784 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21785 "TARGET_SSE2"
21786 "pminub\t{%2, %0|%0, %2}"
21787 [(set_attr "type" "sseiadd")
21788 (set_attr "mode" "TI")])
21789
21790 (define_insn "sminv8hi3"
21791 [(set (match_operand:V8HI 0 "register_operand" "=x")
21792 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
21793 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21794 "TARGET_SSE2"
21795 "pminsw\t{%2, %0|%0, %2}"
21796 [(set_attr "type" "sseiadd")
21797 (set_attr "mode" "TI")])
21798
21799
21800 ;; MMX shifts
21801
21802 (define_insn "ashrv8hi3"
21803 [(set (match_operand:V8HI 0 "register_operand" "=x")
21804 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21805 (match_operand:SI 2 "nonmemory_operand" "xi")))]
21806 "TARGET_SSE2"
21807 "psraw\t{%2, %0|%0, %2}"
21808 [(set_attr "type" "sseishft")
21809 (set_attr "mode" "TI")])
21810
21811 (define_insn "ashrv4si3"
21812 [(set (match_operand:V4SI 0 "register_operand" "=x")
21813 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21814 (match_operand:SI 2 "nonmemory_operand" "xi")))]
21815 "TARGET_SSE2"
21816 "psrad\t{%2, %0|%0, %2}"
21817 [(set_attr "type" "sseishft")
21818 (set_attr "mode" "TI")])
21819
21820 (define_insn "lshrv8hi3"
21821 [(set (match_operand:V8HI 0 "register_operand" "=x")
21822 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21823 (match_operand:SI 2 "nonmemory_operand" "xi")))]
21824 "TARGET_SSE2"
21825 "psrlw\t{%2, %0|%0, %2}"
21826 [(set_attr "type" "sseishft")
21827 (set_attr "mode" "TI")])
21828
21829 (define_insn "lshrv4si3"
21830 [(set (match_operand:V4SI 0 "register_operand" "=x")
21831 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21832 (match_operand:SI 2 "nonmemory_operand" "xi")))]
21833 "TARGET_SSE2"
21834 "psrld\t{%2, %0|%0, %2}"
21835 [(set_attr "type" "sseishft")
21836 (set_attr "mode" "TI")])
21837
21838 (define_insn "lshrv2di3"
21839 [(set (match_operand:V2DI 0 "register_operand" "=x")
21840 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
21841 (match_operand:SI 2 "nonmemory_operand" "xi")))]
21842 "TARGET_SSE2"
21843 "psrlq\t{%2, %0|%0, %2}"
21844 [(set_attr "type" "sseishft")
21845 (set_attr "mode" "TI")])
21846
21847 (define_insn "ashlv8hi3"
21848 [(set (match_operand:V8HI 0 "register_operand" "=x")
21849 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
21850 (match_operand:SI 2 "nonmemory_operand" "xi")))]
21851 "TARGET_SSE2"
21852 "psllw\t{%2, %0|%0, %2}"
21853 [(set_attr "type" "sseishft")
21854 (set_attr "mode" "TI")])
21855
21856 (define_insn "ashlv4si3"
21857 [(set (match_operand:V4SI 0 "register_operand" "=x")
21858 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
21859 (match_operand:SI 2 "nonmemory_operand" "xi")))]
21860 "TARGET_SSE2"
21861 "pslld\t{%2, %0|%0, %2}"
21862 [(set_attr "type" "sseishft")
21863 (set_attr "mode" "TI")])
21864
21865 (define_insn "ashlv2di3"
21866 [(set (match_operand:V2DI 0 "register_operand" "=x")
21867 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
21868 (match_operand:SI 2 "nonmemory_operand" "xi")))]
21869 "TARGET_SSE2"
21870 "psllq\t{%2, %0|%0, %2}"
21871 [(set_attr "type" "sseishft")
21872 (set_attr "mode" "TI")])
21873
21874 (define_insn "ashrv8hi3_ti"
21875 [(set (match_operand:V8HI 0 "register_operand" "=x")
21876 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21877 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21878 "TARGET_SSE2"
21879 "psraw\t{%2, %0|%0, %2}"
21880 [(set_attr "type" "sseishft")
21881 (set_attr "mode" "TI")])
21882
21883 (define_insn "ashrv4si3_ti"
21884 [(set (match_operand:V4SI 0 "register_operand" "=x")
21885 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21886 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21887 "TARGET_SSE2"
21888 "psrad\t{%2, %0|%0, %2}"
21889 [(set_attr "type" "sseishft")
21890 (set_attr "mode" "TI")])
21891
21892 (define_insn "lshrv8hi3_ti"
21893 [(set (match_operand:V8HI 0 "register_operand" "=x")
21894 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21895 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21896 "TARGET_SSE2"
21897 "psrlw\t{%2, %0|%0, %2}"
21898 [(set_attr "type" "sseishft")
21899 (set_attr "mode" "TI")])
21900
21901 (define_insn "lshrv4si3_ti"
21902 [(set (match_operand:V4SI 0 "register_operand" "=x")
21903 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21904 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21905 "TARGET_SSE2"
21906 "psrld\t{%2, %0|%0, %2}"
21907 [(set_attr "type" "sseishft")
21908 (set_attr "mode" "TI")])
21909
21910 (define_insn "lshrv2di3_ti"
21911 [(set (match_operand:V2DI 0 "register_operand" "=x")
21912 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
21913 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21914 "TARGET_SSE2"
21915 "psrlq\t{%2, %0|%0, %2}"
21916 [(set_attr "type" "sseishft")
21917 (set_attr "mode" "TI")])
21918
21919 (define_insn "ashlv8hi3_ti"
21920 [(set (match_operand:V8HI 0 "register_operand" "=x")
21921 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
21922 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21923 "TARGET_SSE2"
21924 "psllw\t{%2, %0|%0, %2}"
21925 [(set_attr "type" "sseishft")
21926 (set_attr "mode" "TI")])
21927
21928 (define_insn "ashlv4si3_ti"
21929 [(set (match_operand:V4SI 0 "register_operand" "=x")
21930 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
21931 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21932 "TARGET_SSE2"
21933 "pslld\t{%2, %0|%0, %2}"
21934 [(set_attr "type" "sseishft")
21935 (set_attr "mode" "TI")])
21936
21937 (define_insn "ashlv2di3_ti"
21938 [(set (match_operand:V2DI 0 "register_operand" "=x")
21939 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
21940 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21941 "TARGET_SSE2"
21942 "psllq\t{%2, %0|%0, %2}"
21943 [(set_attr "type" "sseishft")
21944 (set_attr "mode" "TI")])
21945
21946 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
21947 ;; we wouldn't need here it since we never generate TImode arithmetic.
21948
21949 ;; There has to be some kind of prize for the weirdest new instruction...
21950 (define_insn "sse2_ashlti3"
21951 [(set (match_operand:TI 0 "register_operand" "=x")
21952 (unspec:TI
21953 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
21954 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
21955 (const_int 8)))] UNSPEC_NOP))]
21956 "TARGET_SSE2"
21957 "pslldq\t{%2, %0|%0, %2}"
21958 [(set_attr "type" "sseishft")
21959 (set_attr "mode" "TI")])
21960
21961 (define_insn "sse2_lshrti3"
21962 [(set (match_operand:TI 0 "register_operand" "=x")
21963 (unspec:TI
21964 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
21965 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
21966 (const_int 8)))] UNSPEC_NOP))]
21967 "TARGET_SSE2"
21968 "psrldq\t{%2, %0|%0, %2}"
21969 [(set_attr "type" "sseishft")
21970 (set_attr "mode" "TI")])
21971
21972 ;; SSE unpack
21973
21974 (define_insn "sse2_unpckhpd"
21975 [(set (match_operand:V2DF 0 "register_operand" "=x")
21976 (vec_concat:V2DF
21977 (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
21978 (parallel [(const_int 1)]))
21979 (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
21980 (parallel [(const_int 0)]))))]
21981 "TARGET_SSE2"
21982 "unpckhpd\t{%2, %0|%0, %2}"
21983 [(set_attr "type" "ssecvt")
21984 (set_attr "mode" "TI")])
21985
21986 (define_insn "sse2_unpcklpd"
21987 [(set (match_operand:V2DF 0 "register_operand" "=x")
21988 (vec_concat:V2DF
21989 (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
21990 (parallel [(const_int 0)]))
21991 (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
21992 (parallel [(const_int 1)]))))]
21993 "TARGET_SSE2"
21994 "unpcklpd\t{%2, %0|%0, %2}"
21995 [(set_attr "type" "ssecvt")
21996 (set_attr "mode" "TI")])
21997
21998 ;; MMX pack/unpack insns.
21999
22000 (define_insn "sse2_packsswb"
22001 [(set (match_operand:V16QI 0 "register_operand" "=x")
22002 (vec_concat:V16QI
22003 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22004 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22005 "TARGET_SSE2"
22006 "packsswb\t{%2, %0|%0, %2}"
22007 [(set_attr "type" "ssecvt")
22008 (set_attr "mode" "TI")])
22009
22010 (define_insn "sse2_packssdw"
22011 [(set (match_operand:V8HI 0 "register_operand" "=x")
22012 (vec_concat:V8HI
22013 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22014 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22015 "TARGET_SSE2"
22016 "packssdw\t{%2, %0|%0, %2}"
22017 [(set_attr "type" "ssecvt")
22018 (set_attr "mode" "TI")])
22019
22020 (define_insn "sse2_packuswb"
22021 [(set (match_operand:V16QI 0 "register_operand" "=x")
22022 (vec_concat:V16QI
22023 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22024 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22025 "TARGET_SSE2"
22026 "packuswb\t{%2, %0|%0, %2}"
22027 [(set_attr "type" "ssecvt")
22028 (set_attr "mode" "TI")])
22029
22030 (define_insn "sse2_punpckhbw"
22031 [(set (match_operand:V16QI 0 "register_operand" "=x")
22032 (vec_merge:V16QI
22033 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22034 (parallel [(const_int 8) (const_int 0)
22035 (const_int 9) (const_int 1)
22036 (const_int 10) (const_int 2)
22037 (const_int 11) (const_int 3)
22038 (const_int 12) (const_int 4)
22039 (const_int 13) (const_int 5)
22040 (const_int 14) (const_int 6)
22041 (const_int 15) (const_int 7)]))
22042 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22043 (parallel [(const_int 0) (const_int 8)
22044 (const_int 1) (const_int 9)
22045 (const_int 2) (const_int 10)
22046 (const_int 3) (const_int 11)
22047 (const_int 4) (const_int 12)
22048 (const_int 5) (const_int 13)
22049 (const_int 6) (const_int 14)
22050 (const_int 7) (const_int 15)]))
22051 (const_int 21845)))]
22052 "TARGET_SSE2"
22053 "punpckhbw\t{%2, %0|%0, %2}"
22054 [(set_attr "type" "ssecvt")
22055 (set_attr "mode" "TI")])
22056
22057 (define_insn "sse2_punpckhwd"
22058 [(set (match_operand:V8HI 0 "register_operand" "=x")
22059 (vec_merge:V8HI
22060 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22061 (parallel [(const_int 4) (const_int 0)
22062 (const_int 5) (const_int 1)
22063 (const_int 6) (const_int 2)
22064 (const_int 7) (const_int 3)]))
22065 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22066 (parallel [(const_int 0) (const_int 4)
22067 (const_int 1) (const_int 5)
22068 (const_int 2) (const_int 6)
22069 (const_int 3) (const_int 7)]))
22070 (const_int 85)))]
22071 "TARGET_SSE2"
22072 "punpckhwd\t{%2, %0|%0, %2}"
22073 [(set_attr "type" "ssecvt")
22074 (set_attr "mode" "TI")])
22075
22076 (define_insn "sse2_punpckhdq"
22077 [(set (match_operand:V4SI 0 "register_operand" "=x")
22078 (vec_merge:V4SI
22079 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22080 (parallel [(const_int 2) (const_int 0)
22081 (const_int 3) (const_int 1)]))
22082 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22083 (parallel [(const_int 0) (const_int 2)
22084 (const_int 1) (const_int 3)]))
22085 (const_int 5)))]
22086 "TARGET_SSE2"
22087 "punpckhdq\t{%2, %0|%0, %2}"
22088 [(set_attr "type" "ssecvt")
22089 (set_attr "mode" "TI")])
22090
22091 (define_insn "sse2_punpcklbw"
22092 [(set (match_operand:V16QI 0 "register_operand" "=x")
22093 (vec_merge:V16QI
22094 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22095 (parallel [(const_int 0) (const_int 8)
22096 (const_int 1) (const_int 9)
22097 (const_int 2) (const_int 10)
22098 (const_int 3) (const_int 11)
22099 (const_int 4) (const_int 12)
22100 (const_int 5) (const_int 13)
22101 (const_int 6) (const_int 14)
22102 (const_int 7) (const_int 15)]))
22103 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22104 (parallel [(const_int 8) (const_int 0)
22105 (const_int 9) (const_int 1)
22106 (const_int 10) (const_int 2)
22107 (const_int 11) (const_int 3)
22108 (const_int 12) (const_int 4)
22109 (const_int 13) (const_int 5)
22110 (const_int 14) (const_int 6)
22111 (const_int 15) (const_int 7)]))
22112 (const_int 21845)))]
22113 "TARGET_SSE2"
22114 "punpcklbw\t{%2, %0|%0, %2}"
22115 [(set_attr "type" "ssecvt")
22116 (set_attr "mode" "TI")])
22117
22118 (define_insn "sse2_punpcklwd"
22119 [(set (match_operand:V8HI 0 "register_operand" "=x")
22120 (vec_merge:V8HI
22121 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22122 (parallel [(const_int 0) (const_int 4)
22123 (const_int 1) (const_int 5)
22124 (const_int 2) (const_int 6)
22125 (const_int 3) (const_int 7)]))
22126 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22127 (parallel [(const_int 4) (const_int 0)
22128 (const_int 5) (const_int 1)
22129 (const_int 6) (const_int 2)
22130 (const_int 7) (const_int 3)]))
22131 (const_int 85)))]
22132 "TARGET_SSE2"
22133 "punpcklwd\t{%2, %0|%0, %2}"
22134 [(set_attr "type" "ssecvt")
22135 (set_attr "mode" "TI")])
22136
22137 (define_insn "sse2_punpckldq"
22138 [(set (match_operand:V4SI 0 "register_operand" "=x")
22139 (vec_merge:V4SI
22140 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22141 (parallel [(const_int 0) (const_int 2)
22142 (const_int 1) (const_int 3)]))
22143 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22144 (parallel [(const_int 2) (const_int 0)
22145 (const_int 3) (const_int 1)]))
22146 (const_int 5)))]
22147 "TARGET_SSE2"
22148 "punpckldq\t{%2, %0|%0, %2}"
22149 [(set_attr "type" "ssecvt")
22150 (set_attr "mode" "TI")])
22151
22152 (define_insn "sse2_punpcklqdq"
22153 [(set (match_operand:V2DI 0 "register_operand" "=x")
22154 (vec_merge:V2DI
22155 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22156 (parallel [(const_int 1)
22157 (const_int 0)]))
22158 (match_operand:V2DI 1 "register_operand" "0")
22159 (const_int 1)))]
22160 "TARGET_SSE2"
22161 "punpcklqdq\t{%2, %0|%0, %2}"
22162 [(set_attr "type" "ssecvt")
22163 (set_attr "mode" "TI")])
22164
22165 (define_insn "sse2_punpckhqdq"
22166 [(set (match_operand:V2DI 0 "register_operand" "=x")
22167 (vec_merge:V2DI
22168 (match_operand:V2DI 1 "register_operand" "0")
22169 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22170 (parallel [(const_int 1)
22171 (const_int 0)]))
22172 (const_int 1)))]
22173 "TARGET_SSE2"
22174 "punpckhqdq\t{%2, %0|%0, %2}"
22175 [(set_attr "type" "ssecvt")
22176 (set_attr "mode" "TI")])
22177
22178 ;; SSE2 moves
22179
22180 (define_insn "sse2_movapd"
22181 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22182 (unspec:V2DF [(match_operand:V2DF 1 "general_operand" "xm,x")]
22183 UNSPEC_MOVA))]
22184 "TARGET_SSE2"
22185 "@
22186 movapd\t{%1, %0|%0, %1}
22187 movapd\t{%1, %0|%0, %1}"
22188 [(set_attr "type" "ssemov")
22189 (set_attr "mode" "V2DF")])
22190
22191 (define_insn "sse2_movupd"
22192 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22193 (unspec:V2DF [(match_operand:V2DF 1 "general_operand" "xm,x")]
22194 UNSPEC_MOVU))]
22195 "TARGET_SSE2"
22196 "@
22197 movupd\t{%1, %0|%0, %1}
22198 movupd\t{%1, %0|%0, %1}"
22199 [(set_attr "type" "ssecvt")
22200 (set_attr "mode" "V2DF")])
22201
22202 (define_insn "sse2_movdqa"
22203 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22204 (unspec:V16QI [(match_operand:V16QI 1 "general_operand" "xm,x")]
22205 UNSPEC_MOVA))]
22206 "TARGET_SSE2"
22207 "@
22208 movdqa\t{%1, %0|%0, %1}
22209 movdqa\t{%1, %0|%0, %1}"
22210 [(set_attr "type" "ssemov")
22211 (set_attr "mode" "TI")])
22212
22213 (define_insn "sse2_movdqu"
22214 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22215 (unspec:V16QI [(match_operand:V16QI 1 "general_operand" "xm,x")]
22216 UNSPEC_MOVU))]
22217 "TARGET_SSE2"
22218 "@
22219 movdqu\t{%1, %0|%0, %1}
22220 movdqu\t{%1, %0|%0, %1}"
22221 [(set_attr "type" "ssecvt")
22222 (set_attr "mode" "TI")])
22223
22224 (define_insn "sse2_movdq2q"
22225 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22226 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22227 (parallel [(const_int 0)])))]
22228 "TARGET_SSE2"
22229 "@
22230 movq\t{%1, %0|%0, %1}
22231 movdq2q\t{%1, %0|%0, %1}"
22232 [(set_attr "type" "ssecvt")
22233 (set_attr "mode" "TI")])
22234
22235 (define_insn "sse2_movq2dq"
22236 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22237 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22238 (const_int 0)))]
22239 "TARGET_SSE2"
22240 "@
22241 movq\t{%1, %0|%0, %1}
22242 movq2dq\t{%1, %0|%0, %1}"
22243 [(set_attr "type" "ssecvt,ssemov")
22244 (set_attr "mode" "TI")])
22245
22246 (define_insn "sse2_movq"
22247 [(set (match_operand:V2DI 0 "register_operand" "=x")
22248 (vec_concat:V2DI (vec_select:DI
22249 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22250 (parallel [(const_int 0)]))
22251 (const_int 0)))]
22252 "TARGET_SSE2"
22253 "movq\t{%1, %0|%0, %1}"
22254 [(set_attr "type" "ssemov")
22255 (set_attr "mode" "TI")])
22256
22257 (define_insn "sse2_loadd"
22258 [(set (match_operand:V4SI 0 "register_operand" "=x")
22259 (vec_merge:V4SI
22260 (vec_duplicate:V4HI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22261 (const_vector:V4SI [(const_int 0)
22262 (const_int 0)
22263 (const_int 0)
22264 (const_int 0)])
22265 (const_int 1)))]
22266 "TARGET_SSE2"
22267 "movd\t{%1, %0|%0, %1}"
22268 [(set_attr "type" "ssemov")
22269 (set_attr "mode" "TI")])
22270
22271 (define_insn "sse2_stored"
22272 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22273 (vec_select:SI
22274 (match_operand:V4SI 1 "register_operand" "x")
22275 (parallel [(const_int 0)])))]
22276 "TARGET_SSE2"
22277 "movd\t{%1, %0|%0, %1}"
22278 [(set_attr "type" "ssemov")
22279 (set_attr "mode" "TI")])
22280
22281 (define_insn "sse2_movhpd"
22282 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22283 (vec_merge:V2DF
22284 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22285 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22286 (const_int 2)))]
22287 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22288 "movhpd\t{%2, %0|%0, %2}"
22289 [(set_attr "type" "ssecvt")
22290 (set_attr "mode" "V2DF")])
22291
22292 (define_insn "sse2_movlpd"
22293 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22294 (vec_merge:V2DF
22295 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22296 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22297 (const_int 1)))]
22298 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22299 "movlpd\t{%2, %0|%0, %2}"
22300 [(set_attr "type" "ssecvt")
22301 (set_attr "mode" "V2DF")])
22302
22303 (define_expand "sse2_loadsd"
22304 [(match_operand:V2DF 0 "register_operand" "")
22305 (match_operand:DF 1 "memory_operand" "")]
22306 "TARGET_SSE2"
22307 {
22308 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22309 CONST0_RTX (V2DFmode)));
22310 DONE;
22311 })
22312
22313 (define_insn "sse2_loadsd_1"
22314 [(set (match_operand:V2DF 0 "register_operand" "=x")
22315 (vec_merge:V2DF
22316 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22317 (match_operand:V2DF 2 "const0_operand" "X")
22318 (const_int 1)))]
22319 "TARGET_SSE2"
22320 "movsd\t{%1, %0|%0, %1}"
22321 [(set_attr "type" "ssecvt")
22322 (set_attr "mode" "DF")])
22323
22324 (define_insn "sse2_movsd"
22325 [(set (match_operand:V2DF 0 "register_operand" "=x")
22326 (vec_merge:V2DF
22327 (match_operand:V2DF 1 "register_operand" "0")
22328 (match_operand:V2DF 2 "register_operand" "x")
22329 (const_int 1)))]
22330 "TARGET_SSE2"
22331 "movsd\t{%2, %0|%0, %2}"
22332 [(set_attr "type" "ssecvt")
22333 (set_attr "mode" "DF")])
22334
22335 (define_insn "sse2_storesd"
22336 [(set (match_operand:DF 0 "memory_operand" "=m")
22337 (vec_select:DF
22338 (match_operand:V2DF 1 "register_operand" "x")
22339 (parallel [(const_int 0)])))]
22340 "TARGET_SSE2"
22341 "movsd\t{%1, %0|%0, %1}"
22342 [(set_attr "type" "ssecvt")
22343 (set_attr "mode" "DF")])
22344
22345 (define_insn "sse2_shufpd"
22346 [(set (match_operand:V2DF 0 "register_operand" "=x")
22347 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22348 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22349 (match_operand:SI 3 "immediate_operand" "i")]
22350 UNSPEC_SHUFFLE))]
22351 "TARGET_SSE2"
22352 ;; @@@ check operand order for intel/nonintel syntax
22353 "shufpd\t{%3, %2, %0|%0, %2, %3}"
22354 [(set_attr "type" "ssecvt")
22355 (set_attr "mode" "V2DF")])
22356
22357 (define_insn "sse2_clflush"
22358 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22359 UNSPECV_CLFLUSH)]
22360 "TARGET_SSE2"
22361 "clflush %0"
22362 [(set_attr "type" "sse")
22363 (set_attr "memory" "unknown")])
22364
22365 (define_expand "sse2_mfence"
22366 [(set (match_dup 0)
22367 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22368 "TARGET_SSE2"
22369 {
22370 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22371 MEM_VOLATILE_P (operands[0]) = 1;
22372 })
22373
22374 (define_insn "*mfence_insn"
22375 [(set (match_operand:BLK 0 "" "")
22376 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22377 "TARGET_SSE2"
22378 "mfence"
22379 [(set_attr "type" "sse")
22380 (set_attr "memory" "unknown")])
22381
22382 (define_expand "sse2_lfence"
22383 [(set (match_dup 0)
22384 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22385 "TARGET_SSE2"
22386 {
22387 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22388 MEM_VOLATILE_P (operands[0]) = 1;
22389 })
22390
22391 (define_insn "*lfence_insn"
22392 [(set (match_operand:BLK 0 "" "")
22393 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22394 "TARGET_SSE2"
22395 "lfence"
22396 [(set_attr "type" "sse")
22397 (set_attr "memory" "unknown")])