]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
optabs.h (enum optab_index): Add new OTI_log1p.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_PROBE 10)
67 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SET_GOT 12)
69 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70
71 ; TLS support
72 (UNSPEC_TP 15)
73 (UNSPEC_TLS_GD 16)
74 (UNSPEC_TLS_LD_BASE 17)
75
76 ; Other random patterns
77 (UNSPEC_SCAS 20)
78 (UNSPEC_SIN 21)
79 (UNSPEC_COS 22)
80 (UNSPEC_FNSTSW 24)
81 (UNSPEC_SAHF 25)
82 (UNSPEC_FSTCW 26)
83 (UNSPEC_ADD_CARRY 27)
84 (UNSPEC_FLDCW 28)
85
86 ; For SSE/MMX support:
87 (UNSPEC_FIX 30)
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
119 (UNSPEC_FYL2X 66)
120 (UNSPEC_FYL2XP1 67)
121 (UNSPEC_FRNDINT 68)
122 (UNSPEC_F2XM1 69)
123
124 ; x87 Double output FP
125 (UNSPEC_SINCOS_COS 80)
126 (UNSPEC_SINCOS_SIN 81)
127 (UNSPEC_TAN_ONE 82)
128 (UNSPEC_TAN_TAN 83)
129 (UNSPEC_XTRACT_FRACT 84)
130 (UNSPEC_XTRACT_EXP 85)
131 (UNSPEC_FSCALE_FRACT 86)
132 (UNSPEC_FSCALE_EXP 87)
133 (UNSPEC_FPREM_F 88)
134 (UNSPEC_FPREM_U 89)
135 (UNSPEC_FPREM1_F 90)
136 (UNSPEC_FPREM1_U 91)
137
138 ; REP instruction
139 (UNSPEC_REP 75)
140 ])
141
142 (define_constants
143 [(UNSPECV_BLOCKAGE 0)
144 (UNSPECV_EH_RETURN 13)
145 (UNSPECV_EMMS 31)
146 (UNSPECV_LDMXCSR 37)
147 (UNSPECV_STMXCSR 40)
148 (UNSPECV_FEMMS 46)
149 (UNSPECV_CLFLUSH 57)
150 (UNSPECV_ALIGN 68)
151 (UNSPECV_MONITOR 69)
152 (UNSPECV_MWAIT 70)
153 ])
154
155 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
156 ;; from i386.c.
157
158 ;; In C guard expressions, put expressions which may be compile-time
159 ;; constants first. This allows for better optimization. For
160 ;; example, write "TARGET_64BIT && reload_completed", not
161 ;; "reload_completed && TARGET_64BIT".
162
163 \f
164 ;; Processor type. This attribute must exactly match the processor_type
165 ;; enumeration in i386.h.
166 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
167 (const (symbol_ref "ix86_tune")))
168
169 ;; A basic instruction type. Refinements due to arguments to be
170 ;; provided in other attributes.
171 (define_attr "type"
172 "other,multi,
173 alu,alu1,negnot,imov,imovx,lea,
174 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
175 icmp,test,ibr,setcc,icmov,
176 push,pop,call,callv,leave,
177 str,cld,
178 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
179 sselog,sseiadd,sseishft,sseimul,
180 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
181 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
182 (const_string "other"))
183
184 ;; Main data type used by the insn
185 (define_attr "mode"
186 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
187 (const_string "unknown"))
188
189 ;; The CPU unit operations uses.
190 (define_attr "unit" "integer,i387,sse,mmx,unknown"
191 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
192 (const_string "i387")
193 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
194 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
195 (const_string "sse")
196 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
197 (const_string "mmx")
198 (eq_attr "type" "other")
199 (const_string "unknown")]
200 (const_string "integer")))
201
202 ;; The (bounding maximum) length of an instruction immediate.
203 (define_attr "length_immediate" ""
204 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
205 (const_int 0)
206 (eq_attr "unit" "i387,sse,mmx")
207 (const_int 0)
208 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
209 imul,icmp,push,pop")
210 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
211 (eq_attr "type" "imov,test")
212 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
213 (eq_attr "type" "call")
214 (if_then_else (match_operand 0 "constant_call_address_operand" "")
215 (const_int 4)
216 (const_int 0))
217 (eq_attr "type" "callv")
218 (if_then_else (match_operand 1 "constant_call_address_operand" "")
219 (const_int 4)
220 (const_int 0))
221 ;; We don't know the size before shorten_branches. Expect
222 ;; the instruction to fit for better scheduling.
223 (eq_attr "type" "ibr")
224 (const_int 1)
225 ]
226 (symbol_ref "/* Update immediate_length and other attributes! */
227 abort(),1")))
228
229 ;; The (bounding maximum) length of an instruction address.
230 (define_attr "length_address" ""
231 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
232 (const_int 0)
233 (and (eq_attr "type" "call")
234 (match_operand 0 "constant_call_address_operand" ""))
235 (const_int 0)
236 (and (eq_attr "type" "callv")
237 (match_operand 1 "constant_call_address_operand" ""))
238 (const_int 0)
239 ]
240 (symbol_ref "ix86_attr_length_address_default (insn)")))
241
242 ;; Set when length prefix is used.
243 (define_attr "prefix_data16" ""
244 (if_then_else (ior (eq_attr "mode" "HI")
245 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
246 (const_int 1)
247 (const_int 0)))
248
249 ;; Set when string REP prefix is used.
250 (define_attr "prefix_rep" ""
251 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
252 (const_int 1)
253 (const_int 0)))
254
255 ;; Set when 0f opcode prefix is used.
256 (define_attr "prefix_0f" ""
257 (if_then_else
258 (ior (eq_attr "type" "imovx,setcc,icmov")
259 (eq_attr "unit" "sse,mmx"))
260 (const_int 1)
261 (const_int 0)))
262
263 ;; Set when REX opcode prefix is used.
264 (define_attr "prefix_rex" ""
265 (cond [(and (eq_attr "mode" "DI")
266 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
267 (const_int 1)
268 (and (eq_attr "mode" "QI")
269 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
270 (const_int 0)))
271 (const_int 1)
272 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
273 (const_int 0))
274 (const_int 1)
275 ]
276 (const_int 0)))
277
278 ;; Set when modrm byte is used.
279 (define_attr "modrm" ""
280 (cond [(eq_attr "type" "str,cld,leave")
281 (const_int 0)
282 (eq_attr "unit" "i387")
283 (const_int 0)
284 (and (eq_attr "type" "incdec")
285 (ior (match_operand:SI 1 "register_operand" "")
286 (match_operand:HI 1 "register_operand" "")))
287 (const_int 0)
288 (and (eq_attr "type" "push")
289 (not (match_operand 1 "memory_operand" "")))
290 (const_int 0)
291 (and (eq_attr "type" "pop")
292 (not (match_operand 0 "memory_operand" "")))
293 (const_int 0)
294 (and (eq_attr "type" "imov")
295 (and (match_operand 0 "register_operand" "")
296 (match_operand 1 "immediate_operand" "")))
297 (const_int 0)
298 (and (eq_attr "type" "call")
299 (match_operand 0 "constant_call_address_operand" ""))
300 (const_int 0)
301 (and (eq_attr "type" "callv")
302 (match_operand 1 "constant_call_address_operand" ""))
303 (const_int 0)
304 ]
305 (const_int 1)))
306
307 ;; The (bounding maximum) length of an instruction in bytes.
308 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
309 ;; to split it and compute proper length as for other insns.
310 (define_attr "length" ""
311 (cond [(eq_attr "type" "other,multi,fistp")
312 (const_int 16)
313 (eq_attr "type" "fcmp")
314 (const_int 4)
315 (eq_attr "unit" "i387")
316 (plus (const_int 2)
317 (plus (attr "prefix_data16")
318 (attr "length_address")))]
319 (plus (plus (attr "modrm")
320 (plus (attr "prefix_0f")
321 (plus (attr "prefix_rex")
322 (const_int 1))))
323 (plus (attr "prefix_rep")
324 (plus (attr "prefix_data16")
325 (plus (attr "length_immediate")
326 (attr "length_address")))))))
327
328 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
329 ;; `store' if there is a simple memory reference therein, or `unknown'
330 ;; if the instruction is complex.
331
332 (define_attr "memory" "none,load,store,both,unknown"
333 (cond [(eq_attr "type" "other,multi,str")
334 (const_string "unknown")
335 (eq_attr "type" "lea,fcmov,fpspc,cld")
336 (const_string "none")
337 (eq_attr "type" "fistp,leave")
338 (const_string "both")
339 (eq_attr "type" "push")
340 (if_then_else (match_operand 1 "memory_operand" "")
341 (const_string "both")
342 (const_string "store"))
343 (eq_attr "type" "pop")
344 (if_then_else (match_operand 0 "memory_operand" "")
345 (const_string "both")
346 (const_string "load"))
347 (eq_attr "type" "setcc")
348 (if_then_else (match_operand 0 "memory_operand" "")
349 (const_string "store")
350 (const_string "none"))
351 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
352 (if_then_else (ior (match_operand 0 "memory_operand" "")
353 (match_operand 1 "memory_operand" ""))
354 (const_string "load")
355 (const_string "none"))
356 (eq_attr "type" "ibr")
357 (if_then_else (match_operand 0 "memory_operand" "")
358 (const_string "load")
359 (const_string "none"))
360 (eq_attr "type" "call")
361 (if_then_else (match_operand 0 "constant_call_address_operand" "")
362 (const_string "none")
363 (const_string "load"))
364 (eq_attr "type" "callv")
365 (if_then_else (match_operand 1 "constant_call_address_operand" "")
366 (const_string "none")
367 (const_string "load"))
368 (and (eq_attr "type" "alu1,negnot,ishift1")
369 (match_operand 1 "memory_operand" ""))
370 (const_string "both")
371 (and (match_operand 0 "memory_operand" "")
372 (match_operand 1 "memory_operand" ""))
373 (const_string "both")
374 (match_operand 0 "memory_operand" "")
375 (const_string "store")
376 (match_operand 1 "memory_operand" "")
377 (const_string "load")
378 (and (eq_attr "type"
379 "!alu1,negnot,ishift1,
380 imov,imovx,icmp,test,
381 fmov,fcmp,fsgn,
382 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
383 mmx,mmxmov,mmxcmp,mmxcvt")
384 (match_operand 2 "memory_operand" ""))
385 (const_string "load")
386 (and (eq_attr "type" "icmov")
387 (match_operand 3 "memory_operand" ""))
388 (const_string "load")
389 ]
390 (const_string "none")))
391
392 ;; Indicates if an instruction has both an immediate and a displacement.
393
394 (define_attr "imm_disp" "false,true,unknown"
395 (cond [(eq_attr "type" "other,multi")
396 (const_string "unknown")
397 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
398 (and (match_operand 0 "memory_displacement_operand" "")
399 (match_operand 1 "immediate_operand" "")))
400 (const_string "true")
401 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
402 (and (match_operand 0 "memory_displacement_operand" "")
403 (match_operand 2 "immediate_operand" "")))
404 (const_string "true")
405 ]
406 (const_string "false")))
407
408 ;; Indicates if an FP operation has an integer source.
409
410 (define_attr "fp_int_src" "false,true"
411 (const_string "false"))
412
413 ;; Describe a user's asm statement.
414 (define_asm_attributes
415 [(set_attr "length" "128")
416 (set_attr "type" "multi")])
417 \f
418 (include "pentium.md")
419 (include "ppro.md")
420 (include "k6.md")
421 (include "athlon.md")
422 \f
423 ;; Compare instructions.
424
425 ;; All compare insns have expanders that save the operands away without
426 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
427 ;; after the cmp) will actually emit the cmpM.
428
429 (define_expand "cmpdi"
430 [(set (reg:CC 17)
431 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
432 (match_operand:DI 1 "x86_64_general_operand" "")))]
433 ""
434 {
435 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
436 operands[0] = force_reg (DImode, operands[0]);
437 ix86_compare_op0 = operands[0];
438 ix86_compare_op1 = operands[1];
439 DONE;
440 })
441
442 (define_expand "cmpsi"
443 [(set (reg:CC 17)
444 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
445 (match_operand:SI 1 "general_operand" "")))]
446 ""
447 {
448 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
449 operands[0] = force_reg (SImode, operands[0]);
450 ix86_compare_op0 = operands[0];
451 ix86_compare_op1 = operands[1];
452 DONE;
453 })
454
455 (define_expand "cmphi"
456 [(set (reg:CC 17)
457 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
458 (match_operand:HI 1 "general_operand" "")))]
459 ""
460 {
461 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
462 operands[0] = force_reg (HImode, operands[0]);
463 ix86_compare_op0 = operands[0];
464 ix86_compare_op1 = operands[1];
465 DONE;
466 })
467
468 (define_expand "cmpqi"
469 [(set (reg:CC 17)
470 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
471 (match_operand:QI 1 "general_operand" "")))]
472 "TARGET_QIMODE_MATH"
473 {
474 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
475 operands[0] = force_reg (QImode, operands[0]);
476 ix86_compare_op0 = operands[0];
477 ix86_compare_op1 = operands[1];
478 DONE;
479 })
480
481 (define_insn "cmpdi_ccno_1_rex64"
482 [(set (reg 17)
483 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
484 (match_operand:DI 1 "const0_operand" "n,n")))]
485 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
486 "@
487 test{q}\t{%0, %0|%0, %0}
488 cmp{q}\t{%1, %0|%0, %1}"
489 [(set_attr "type" "test,icmp")
490 (set_attr "length_immediate" "0,1")
491 (set_attr "mode" "DI")])
492
493 (define_insn "*cmpdi_minus_1_rex64"
494 [(set (reg 17)
495 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
496 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
497 (const_int 0)))]
498 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
499 "cmp{q}\t{%1, %0|%0, %1}"
500 [(set_attr "type" "icmp")
501 (set_attr "mode" "DI")])
502
503 (define_expand "cmpdi_1_rex64"
504 [(set (reg:CC 17)
505 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506 (match_operand:DI 1 "general_operand" "")))]
507 "TARGET_64BIT"
508 "")
509
510 (define_insn "cmpdi_1_insn_rex64"
511 [(set (reg 17)
512 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
513 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
514 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
515 "cmp{q}\t{%1, %0|%0, %1}"
516 [(set_attr "type" "icmp")
517 (set_attr "mode" "DI")])
518
519
520 (define_insn "*cmpsi_ccno_1"
521 [(set (reg 17)
522 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
523 (match_operand:SI 1 "const0_operand" "n,n")))]
524 "ix86_match_ccmode (insn, CCNOmode)"
525 "@
526 test{l}\t{%0, %0|%0, %0}
527 cmp{l}\t{%1, %0|%0, %1}"
528 [(set_attr "type" "test,icmp")
529 (set_attr "length_immediate" "0,1")
530 (set_attr "mode" "SI")])
531
532 (define_insn "*cmpsi_minus_1"
533 [(set (reg 17)
534 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
535 (match_operand:SI 1 "general_operand" "ri,mr"))
536 (const_int 0)))]
537 "ix86_match_ccmode (insn, CCGOCmode)"
538 "cmp{l}\t{%1, %0|%0, %1}"
539 [(set_attr "type" "icmp")
540 (set_attr "mode" "SI")])
541
542 (define_expand "cmpsi_1"
543 [(set (reg:CC 17)
544 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
545 (match_operand:SI 1 "general_operand" "ri,mr")))]
546 ""
547 "")
548
549 (define_insn "*cmpsi_1_insn"
550 [(set (reg 17)
551 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
552 (match_operand:SI 1 "general_operand" "ri,mr")))]
553 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
554 && ix86_match_ccmode (insn, CCmode)"
555 "cmp{l}\t{%1, %0|%0, %1}"
556 [(set_attr "type" "icmp")
557 (set_attr "mode" "SI")])
558
559 (define_insn "*cmphi_ccno_1"
560 [(set (reg 17)
561 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
562 (match_operand:HI 1 "const0_operand" "n,n")))]
563 "ix86_match_ccmode (insn, CCNOmode)"
564 "@
565 test{w}\t{%0, %0|%0, %0}
566 cmp{w}\t{%1, %0|%0, %1}"
567 [(set_attr "type" "test,icmp")
568 (set_attr "length_immediate" "0,1")
569 (set_attr "mode" "HI")])
570
571 (define_insn "*cmphi_minus_1"
572 [(set (reg 17)
573 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
574 (match_operand:HI 1 "general_operand" "ri,mr"))
575 (const_int 0)))]
576 "ix86_match_ccmode (insn, CCGOCmode)"
577 "cmp{w}\t{%1, %0|%0, %1}"
578 [(set_attr "type" "icmp")
579 (set_attr "mode" "HI")])
580
581 (define_insn "*cmphi_1"
582 [(set (reg 17)
583 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:HI 1 "general_operand" "ri,mr")))]
585 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586 && ix86_match_ccmode (insn, CCmode)"
587 "cmp{w}\t{%1, %0|%0, %1}"
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "HI")])
590
591 (define_insn "*cmpqi_ccno_1"
592 [(set (reg 17)
593 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
594 (match_operand:QI 1 "const0_operand" "n,n")))]
595 "ix86_match_ccmode (insn, CCNOmode)"
596 "@
597 test{b}\t{%0, %0|%0, %0}
598 cmp{b}\t{$0, %0|%0, 0}"
599 [(set_attr "type" "test,icmp")
600 (set_attr "length_immediate" "0,1")
601 (set_attr "mode" "QI")])
602
603 (define_insn "*cmpqi_1"
604 [(set (reg 17)
605 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
606 (match_operand:QI 1 "general_operand" "qi,mq")))]
607 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
608 && ix86_match_ccmode (insn, CCmode)"
609 "cmp{b}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "icmp")
611 (set_attr "mode" "QI")])
612
613 (define_insn "*cmpqi_minus_1"
614 [(set (reg 17)
615 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
616 (match_operand:QI 1 "general_operand" "qi,mq"))
617 (const_int 0)))]
618 "ix86_match_ccmode (insn, CCGOCmode)"
619 "cmp{b}\t{%1, %0|%0, %1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "QI")])
622
623 (define_insn "*cmpqi_ext_1"
624 [(set (reg 17)
625 (compare
626 (match_operand:QI 0 "general_operand" "Qm")
627 (subreg:QI
628 (zero_extract:SI
629 (match_operand 1 "ext_register_operand" "Q")
630 (const_int 8)
631 (const_int 8)) 0)))]
632 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633 "cmp{b}\t{%h1, %0|%0, %h1}"
634 [(set_attr "type" "icmp")
635 (set_attr "mode" "QI")])
636
637 (define_insn "*cmpqi_ext_1_rex64"
638 [(set (reg 17)
639 (compare
640 (match_operand:QI 0 "register_operand" "Q")
641 (subreg:QI
642 (zero_extract:SI
643 (match_operand 1 "ext_register_operand" "Q")
644 (const_int 8)
645 (const_int 8)) 0)))]
646 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
647 "cmp{b}\t{%h1, %0|%0, %h1}"
648 [(set_attr "type" "icmp")
649 (set_attr "mode" "QI")])
650
651 (define_insn "*cmpqi_ext_2"
652 [(set (reg 17)
653 (compare
654 (subreg:QI
655 (zero_extract:SI
656 (match_operand 0 "ext_register_operand" "Q")
657 (const_int 8)
658 (const_int 8)) 0)
659 (match_operand:QI 1 "const0_operand" "n")))]
660 "ix86_match_ccmode (insn, CCNOmode)"
661 "test{b}\t%h0, %h0"
662 [(set_attr "type" "test")
663 (set_attr "length_immediate" "0")
664 (set_attr "mode" "QI")])
665
666 (define_expand "cmpqi_ext_3"
667 [(set (reg:CC 17)
668 (compare:CC
669 (subreg:QI
670 (zero_extract:SI
671 (match_operand 0 "ext_register_operand" "")
672 (const_int 8)
673 (const_int 8)) 0)
674 (match_operand:QI 1 "general_operand" "")))]
675 ""
676 "")
677
678 (define_insn "cmpqi_ext_3_insn"
679 [(set (reg 17)
680 (compare
681 (subreg:QI
682 (zero_extract:SI
683 (match_operand 0 "ext_register_operand" "Q")
684 (const_int 8)
685 (const_int 8)) 0)
686 (match_operand:QI 1 "general_operand" "Qmn")))]
687 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{b}\t{%1, %h0|%h0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "QI")])
691
692 (define_insn "cmpqi_ext_3_insn_rex64"
693 [(set (reg 17)
694 (compare
695 (subreg:QI
696 (zero_extract:SI
697 (match_operand 0 "ext_register_operand" "Q")
698 (const_int 8)
699 (const_int 8)) 0)
700 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
701 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
702 "cmp{b}\t{%1, %h0|%h0, %1}"
703 [(set_attr "type" "icmp")
704 (set_attr "mode" "QI")])
705
706 (define_insn "*cmpqi_ext_4"
707 [(set (reg 17)
708 (compare
709 (subreg:QI
710 (zero_extract:SI
711 (match_operand 0 "ext_register_operand" "Q")
712 (const_int 8)
713 (const_int 8)) 0)
714 (subreg:QI
715 (zero_extract:SI
716 (match_operand 1 "ext_register_operand" "Q")
717 (const_int 8)
718 (const_int 8)) 0)))]
719 "ix86_match_ccmode (insn, CCmode)"
720 "cmp{b}\t{%h1, %h0|%h0, %h1}"
721 [(set_attr "type" "icmp")
722 (set_attr "mode" "QI")])
723
724 ;; These implement float point compares.
725 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
726 ;; which would allow mix and match FP modes on the compares. Which is what
727 ;; the old patterns did, but with many more of them.
728
729 (define_expand "cmpxf"
730 [(set (reg:CC 17)
731 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
732 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
733 "TARGET_80387"
734 {
735 ix86_compare_op0 = operands[0];
736 ix86_compare_op1 = operands[1];
737 DONE;
738 })
739
740 (define_expand "cmpdf"
741 [(set (reg:CC 17)
742 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
743 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
744 "TARGET_80387 || TARGET_SSE2"
745 {
746 ix86_compare_op0 = operands[0];
747 ix86_compare_op1 = operands[1];
748 DONE;
749 })
750
751 (define_expand "cmpsf"
752 [(set (reg:CC 17)
753 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
754 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
755 "TARGET_80387 || TARGET_SSE"
756 {
757 ix86_compare_op0 = operands[0];
758 ix86_compare_op1 = operands[1];
759 DONE;
760 })
761
762 ;; FP compares, step 1:
763 ;; Set the FP condition codes.
764 ;;
765 ;; CCFPmode compare with exceptions
766 ;; CCFPUmode compare with no exceptions
767
768 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
769 ;; and that fp moves clobber the condition codes, and that there is
770 ;; currently no way to describe this fact to reg-stack. So there are
771 ;; no splitters yet for this.
772
773 ;; %%% YIKES! This scheme does not retain a strong connection between
774 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
775 ;; work! Only allow tos/mem with tos in op 0.
776 ;;
777 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
778 ;; things aren't as bad as they sound...
779
780 (define_insn "*cmpfp_0"
781 [(set (match_operand:HI 0 "register_operand" "=a")
782 (unspec:HI
783 [(compare:CCFP (match_operand 1 "register_operand" "f")
784 (match_operand 2 "const0_operand" "X"))]
785 UNSPEC_FNSTSW))]
786 "TARGET_80387
787 && FLOAT_MODE_P (GET_MODE (operands[1]))
788 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
789 {
790 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
791 return "ftst\;fnstsw\t%0\;fstp\t%y0";
792 else
793 return "ftst\;fnstsw\t%0";
794 }
795 [(set_attr "type" "multi")
796 (set (attr "mode")
797 (cond [(match_operand:SF 1 "" "")
798 (const_string "SF")
799 (match_operand:DF 1 "" "")
800 (const_string "DF")
801 ]
802 (const_string "XF")))])
803
804 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
805 ;; used to manage the reg stack popping would not be preserved.
806
807 (define_insn "*cmpfp_2_sf"
808 [(set (reg:CCFP 18)
809 (compare:CCFP
810 (match_operand:SF 0 "register_operand" "f")
811 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
812 "TARGET_80387"
813 "* return output_fp_compare (insn, operands, 0, 0);"
814 [(set_attr "type" "fcmp")
815 (set_attr "mode" "SF")])
816
817 (define_insn "*cmpfp_2_sf_1"
818 [(set (match_operand:HI 0 "register_operand" "=a")
819 (unspec:HI
820 [(compare:CCFP
821 (match_operand:SF 1 "register_operand" "f")
822 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
823 UNSPEC_FNSTSW))]
824 "TARGET_80387"
825 "* return output_fp_compare (insn, operands, 2, 0);"
826 [(set_attr "type" "fcmp")
827 (set_attr "mode" "SF")])
828
829 (define_insn "*cmpfp_2_df"
830 [(set (reg:CCFP 18)
831 (compare:CCFP
832 (match_operand:DF 0 "register_operand" "f")
833 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
834 "TARGET_80387"
835 "* return output_fp_compare (insn, operands, 0, 0);"
836 [(set_attr "type" "fcmp")
837 (set_attr "mode" "DF")])
838
839 (define_insn "*cmpfp_2_df_1"
840 [(set (match_operand:HI 0 "register_operand" "=a")
841 (unspec:HI
842 [(compare:CCFP
843 (match_operand:DF 1 "register_operand" "f")
844 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
845 UNSPEC_FNSTSW))]
846 "TARGET_80387"
847 "* return output_fp_compare (insn, operands, 2, 0);"
848 [(set_attr "type" "multi")
849 (set_attr "mode" "DF")])
850
851 (define_insn "*cmpfp_2_xf"
852 [(set (reg:CCFP 18)
853 (compare:CCFP
854 (match_operand:XF 0 "register_operand" "f")
855 (match_operand:XF 1 "register_operand" "f")))]
856 "TARGET_80387"
857 "* return output_fp_compare (insn, operands, 0, 0);"
858 [(set_attr "type" "fcmp")
859 (set_attr "mode" "XF")])
860
861 (define_insn "*cmpfp_2_xf_1"
862 [(set (match_operand:HI 0 "register_operand" "=a")
863 (unspec:HI
864 [(compare:CCFP
865 (match_operand:XF 1 "register_operand" "f")
866 (match_operand:XF 2 "register_operand" "f"))]
867 UNSPEC_FNSTSW))]
868 "TARGET_80387"
869 "* return output_fp_compare (insn, operands, 2, 0);"
870 [(set_attr "type" "multi")
871 (set_attr "mode" "XF")])
872
873 (define_insn "*cmpfp_2u"
874 [(set (reg:CCFPU 18)
875 (compare:CCFPU
876 (match_operand 0 "register_operand" "f")
877 (match_operand 1 "register_operand" "f")))]
878 "TARGET_80387
879 && FLOAT_MODE_P (GET_MODE (operands[0]))
880 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
881 "* return output_fp_compare (insn, operands, 0, 1);"
882 [(set_attr "type" "fcmp")
883 (set (attr "mode")
884 (cond [(match_operand:SF 1 "" "")
885 (const_string "SF")
886 (match_operand:DF 1 "" "")
887 (const_string "DF")
888 ]
889 (const_string "XF")))])
890
891 (define_insn "*cmpfp_2u_1"
892 [(set (match_operand:HI 0 "register_operand" "=a")
893 (unspec:HI
894 [(compare:CCFPU
895 (match_operand 1 "register_operand" "f")
896 (match_operand 2 "register_operand" "f"))]
897 UNSPEC_FNSTSW))]
898 "TARGET_80387
899 && FLOAT_MODE_P (GET_MODE (operands[1]))
900 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
901 "* return output_fp_compare (insn, operands, 2, 1);"
902 [(set_attr "type" "multi")
903 (set (attr "mode")
904 (cond [(match_operand:SF 1 "" "")
905 (const_string "SF")
906 (match_operand:DF 1 "" "")
907 (const_string "DF")
908 ]
909 (const_string "XF")))])
910
911 ;; Patterns to match the SImode-in-memory ficom instructions.
912 ;;
913 ;; %%% Play games with accepting gp registers, as otherwise we have to
914 ;; force them to memory during rtl generation, which is no good. We
915 ;; can get rid of this once we teach reload to do memory input reloads
916 ;; via pushes.
917
918 (define_insn "*ficom_1"
919 [(set (reg:CCFP 18)
920 (compare:CCFP
921 (match_operand 0 "register_operand" "f,f")
922 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
923 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
924 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
925 "#")
926
927 ;; Split the not-really-implemented gp register case into a
928 ;; push-op-pop sequence.
929 ;;
930 ;; %%% This is most efficient, but am I gonna get in trouble
931 ;; for separating cc0_setter and cc0_user?
932
933 (define_split
934 [(set (reg:CCFP 18)
935 (compare:CCFP
936 (match_operand:SF 0 "register_operand" "")
937 (float (match_operand:SI 1 "register_operand" ""))))]
938 "0 && TARGET_80387 && reload_completed"
939 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
940 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
941 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
942 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
943 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
944 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
945
946 ;; FP compares, step 2
947 ;; Move the fpsw to ax.
948
949 (define_insn "x86_fnstsw_1"
950 [(set (match_operand:HI 0 "register_operand" "=a")
951 (unspec:HI [(reg:CCFP 18)] UNSPEC_FNSTSW))]
952 "TARGET_80387"
953 "fnstsw\t%0"
954 [(set_attr "length" "2")
955 (set_attr "mode" "SI")
956 (set_attr "unit" "i387")])
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
970 ;; Pentium Pro can do steps 1 through 3 in one go.
971
972 (define_insn "*cmpfp_i"
973 [(set (reg:CCFP 17)
974 (compare:CCFP (match_operand 0 "register_operand" "f")
975 (match_operand 1 "register_operand" "f")))]
976 "TARGET_80387 && TARGET_CMOVE
977 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
978 && FLOAT_MODE_P (GET_MODE (operands[0]))
979 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
980 "* return output_fp_compare (insn, operands, 1, 0);"
981 [(set_attr "type" "fcmp")
982 (set (attr "mode")
983 (cond [(match_operand:SF 1 "" "")
984 (const_string "SF")
985 (match_operand:DF 1 "" "")
986 (const_string "DF")
987 ]
988 (const_string "XF")))
989 (set_attr "athlon_decode" "vector")])
990
991 (define_insn "*cmpfp_i_sse"
992 [(set (reg:CCFP 17)
993 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
994 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
995 "TARGET_80387
996 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
997 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
998 "* return output_fp_compare (insn, operands, 1, 0);"
999 [(set_attr "type" "fcmp,ssecomi")
1000 (set (attr "mode")
1001 (if_then_else (match_operand:SF 1 "" "")
1002 (const_string "SF")
1003 (const_string "DF")))
1004 (set_attr "athlon_decode" "vector")])
1005
1006 (define_insn "*cmpfp_i_sse_only"
1007 [(set (reg:CCFP 17)
1008 (compare:CCFP (match_operand 0 "register_operand" "x")
1009 (match_operand 1 "nonimmediate_operand" "xm")))]
1010 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1011 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1012 "* return output_fp_compare (insn, operands, 1, 0);"
1013 [(set_attr "type" "ssecomi")
1014 (set (attr "mode")
1015 (if_then_else (match_operand:SF 1 "" "")
1016 (const_string "SF")
1017 (const_string "DF")))
1018 (set_attr "athlon_decode" "vector")])
1019
1020 (define_insn "*cmpfp_iu"
1021 [(set (reg:CCFPU 17)
1022 (compare:CCFPU (match_operand 0 "register_operand" "f")
1023 (match_operand 1 "register_operand" "f")))]
1024 "TARGET_80387 && TARGET_CMOVE
1025 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1026 && FLOAT_MODE_P (GET_MODE (operands[0]))
1027 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1028 "* return output_fp_compare (insn, operands, 1, 1);"
1029 [(set_attr "type" "fcmp")
1030 (set (attr "mode")
1031 (cond [(match_operand:SF 1 "" "")
1032 (const_string "SF")
1033 (match_operand:DF 1 "" "")
1034 (const_string "DF")
1035 ]
1036 (const_string "XF")))
1037 (set_attr "athlon_decode" "vector")])
1038
1039 (define_insn "*cmpfp_iu_sse"
1040 [(set (reg:CCFPU 17)
1041 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1042 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1043 "TARGET_80387
1044 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1045 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1046 "* return output_fp_compare (insn, operands, 1, 1);"
1047 [(set_attr "type" "fcmp,ssecomi")
1048 (set (attr "mode")
1049 (if_then_else (match_operand:SF 1 "" "")
1050 (const_string "SF")
1051 (const_string "DF")))
1052 (set_attr "athlon_decode" "vector")])
1053
1054 (define_insn "*cmpfp_iu_sse_only"
1055 [(set (reg:CCFPU 17)
1056 (compare:CCFPU (match_operand 0 "register_operand" "x")
1057 (match_operand 1 "nonimmediate_operand" "xm")))]
1058 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1059 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1060 "* return output_fp_compare (insn, operands, 1, 1);"
1061 [(set_attr "type" "ssecomi")
1062 (set (attr "mode")
1063 (if_then_else (match_operand:SF 1 "" "")
1064 (const_string "SF")
1065 (const_string "DF")))
1066 (set_attr "athlon_decode" "vector")])
1067 \f
1068 ;; Move instructions.
1069
1070 ;; General case of fullword move.
1071
1072 (define_expand "movsi"
1073 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1074 (match_operand:SI 1 "general_operand" ""))]
1075 ""
1076 "ix86_expand_move (SImode, operands); DONE;")
1077
1078 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1079 ;; general_operand.
1080 ;;
1081 ;; %%% We don't use a post-inc memory reference because x86 is not a
1082 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1083 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1084 ;; targets without our curiosities, and it is just as easy to represent
1085 ;; this differently.
1086
1087 (define_insn "*pushsi2"
1088 [(set (match_operand:SI 0 "push_operand" "=<")
1089 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1090 "!TARGET_64BIT"
1091 "push{l}\t%1"
1092 [(set_attr "type" "push")
1093 (set_attr "mode" "SI")])
1094
1095 ;; For 64BIT abi we always round up to 8 bytes.
1096 (define_insn "*pushsi2_rex64"
1097 [(set (match_operand:SI 0 "push_operand" "=X")
1098 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1099 "TARGET_64BIT"
1100 "push{q}\t%q1"
1101 [(set_attr "type" "push")
1102 (set_attr "mode" "SI")])
1103
1104 (define_insn "*pushsi2_prologue"
1105 [(set (match_operand:SI 0 "push_operand" "=<")
1106 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1107 (clobber (mem:BLK (scratch)))]
1108 "!TARGET_64BIT"
1109 "push{l}\t%1"
1110 [(set_attr "type" "push")
1111 (set_attr "mode" "SI")])
1112
1113 (define_insn "*popsi1_epilogue"
1114 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1115 (mem:SI (reg:SI 7)))
1116 (set (reg:SI 7)
1117 (plus:SI (reg:SI 7) (const_int 4)))
1118 (clobber (mem:BLK (scratch)))]
1119 "!TARGET_64BIT"
1120 "pop{l}\t%0"
1121 [(set_attr "type" "pop")
1122 (set_attr "mode" "SI")])
1123
1124 (define_insn "popsi1"
1125 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1126 (mem:SI (reg:SI 7)))
1127 (set (reg:SI 7)
1128 (plus:SI (reg:SI 7) (const_int 4)))]
1129 "!TARGET_64BIT"
1130 "pop{l}\t%0"
1131 [(set_attr "type" "pop")
1132 (set_attr "mode" "SI")])
1133
1134 (define_insn "*movsi_xor"
1135 [(set (match_operand:SI 0 "register_operand" "=r")
1136 (match_operand:SI 1 "const0_operand" "i"))
1137 (clobber (reg:CC 17))]
1138 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1139 "xor{l}\t{%0, %0|%0, %0}"
1140 [(set_attr "type" "alu1")
1141 (set_attr "mode" "SI")
1142 (set_attr "length_immediate" "0")])
1143
1144 (define_insn "*movsi_or"
1145 [(set (match_operand:SI 0 "register_operand" "=r")
1146 (match_operand:SI 1 "immediate_operand" "i"))
1147 (clobber (reg:CC 17))]
1148 "reload_completed
1149 && operands[1] == constm1_rtx
1150 && (TARGET_PENTIUM || optimize_size)"
1151 {
1152 operands[1] = constm1_rtx;
1153 return "or{l}\t{%1, %0|%0, %1}";
1154 }
1155 [(set_attr "type" "alu1")
1156 (set_attr "mode" "SI")
1157 (set_attr "length_immediate" "1")])
1158
1159 (define_insn "*movsi_1"
1160 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1161 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1162 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1163 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1164 {
1165 switch (get_attr_type (insn))
1166 {
1167 case TYPE_SSEMOV:
1168 if (get_attr_mode (insn) == MODE_TI)
1169 return "movdqa\t{%1, %0|%0, %1}";
1170 return "movd\t{%1, %0|%0, %1}";
1171
1172 case TYPE_MMXMOV:
1173 if (get_attr_mode (insn) == MODE_DI)
1174 return "movq\t{%1, %0|%0, %1}";
1175 return "movd\t{%1, %0|%0, %1}";
1176
1177 case TYPE_LEA:
1178 return "lea{l}\t{%1, %0|%0, %1}";
1179
1180 default:
1181 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1182 abort();
1183 return "mov{l}\t{%1, %0|%0, %1}";
1184 }
1185 }
1186 [(set (attr "type")
1187 (cond [(eq_attr "alternative" "2,3,4")
1188 (const_string "mmxmov")
1189 (eq_attr "alternative" "5,6,7")
1190 (const_string "ssemov")
1191 (and (ne (symbol_ref "flag_pic") (const_int 0))
1192 (match_operand:SI 1 "symbolic_operand" ""))
1193 (const_string "lea")
1194 ]
1195 (const_string "imov")))
1196 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1197
1198 (define_insn "*movsi_1_nointernunit"
1199 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1200 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1201 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1202 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1203 {
1204 switch (get_attr_type (insn))
1205 {
1206 case TYPE_SSEMOV:
1207 if (get_attr_mode (insn) == MODE_TI)
1208 return "movdqa\t{%1, %0|%0, %1}";
1209 return "movd\t{%1, %0|%0, %1}";
1210
1211 case TYPE_MMXMOV:
1212 if (get_attr_mode (insn) == MODE_DI)
1213 return "movq\t{%1, %0|%0, %1}";
1214 return "movd\t{%1, %0|%0, %1}";
1215
1216 case TYPE_LEA:
1217 return "lea{l}\t{%1, %0|%0, %1}";
1218
1219 default:
1220 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1221 abort();
1222 return "mov{l}\t{%1, %0|%0, %1}";
1223 }
1224 }
1225 [(set (attr "type")
1226 (cond [(eq_attr "alternative" "2,3,4")
1227 (const_string "mmxmov")
1228 (eq_attr "alternative" "5,6,7")
1229 (const_string "ssemov")
1230 (and (ne (symbol_ref "flag_pic") (const_int 0))
1231 (match_operand:SI 1 "symbolic_operand" ""))
1232 (const_string "lea")
1233 ]
1234 (const_string "imov")))
1235 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1236
1237 ;; Stores and loads of ax to arbitrary constant address.
1238 ;; We fake an second form of instruction to force reload to load address
1239 ;; into register when rax is not available
1240 (define_insn "*movabssi_1_rex64"
1241 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1242 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1243 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1244 "@
1245 movabs{l}\t{%1, %P0|%P0, %1}
1246 mov{l}\t{%1, %a0|%a0, %1}"
1247 [(set_attr "type" "imov")
1248 (set_attr "modrm" "0,*")
1249 (set_attr "length_address" "8,0")
1250 (set_attr "length_immediate" "0,*")
1251 (set_attr "memory" "store")
1252 (set_attr "mode" "SI")])
1253
1254 (define_insn "*movabssi_2_rex64"
1255 [(set (match_operand:SI 0 "register_operand" "=a,r")
1256 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1257 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1258 "@
1259 movabs{l}\t{%P1, %0|%0, %P1}
1260 mov{l}\t{%a1, %0|%0, %a1}"
1261 [(set_attr "type" "imov")
1262 (set_attr "modrm" "0,*")
1263 (set_attr "length_address" "8,0")
1264 (set_attr "length_immediate" "0")
1265 (set_attr "memory" "load")
1266 (set_attr "mode" "SI")])
1267
1268 (define_insn "*swapsi"
1269 [(set (match_operand:SI 0 "register_operand" "+r")
1270 (match_operand:SI 1 "register_operand" "+r"))
1271 (set (match_dup 1)
1272 (match_dup 0))]
1273 ""
1274 "xchg{l}\t%1, %0"
1275 [(set_attr "type" "imov")
1276 (set_attr "pent_pair" "np")
1277 (set_attr "athlon_decode" "vector")
1278 (set_attr "mode" "SI")
1279 (set_attr "modrm" "0")])
1280
1281 (define_expand "movhi"
1282 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1283 (match_operand:HI 1 "general_operand" ""))]
1284 ""
1285 "ix86_expand_move (HImode, operands); DONE;")
1286
1287 (define_insn "*pushhi2"
1288 [(set (match_operand:HI 0 "push_operand" "=<,<")
1289 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1290 "!TARGET_64BIT"
1291 "@
1292 push{w}\t{|WORD PTR }%1
1293 push{w}\t%1"
1294 [(set_attr "type" "push")
1295 (set_attr "mode" "HI")])
1296
1297 ;; For 64BIT abi we always round up to 8 bytes.
1298 (define_insn "*pushhi2_rex64"
1299 [(set (match_operand:HI 0 "push_operand" "=X")
1300 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1301 "TARGET_64BIT"
1302 "push{q}\t%q1"
1303 [(set_attr "type" "push")
1304 (set_attr "mode" "QI")])
1305
1306 (define_insn "*movhi_1"
1307 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1308 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1309 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1310 {
1311 switch (get_attr_type (insn))
1312 {
1313 case TYPE_IMOVX:
1314 /* movzwl is faster than movw on p2 due to partial word stalls,
1315 though not as fast as an aligned movl. */
1316 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1317 default:
1318 if (get_attr_mode (insn) == MODE_SI)
1319 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1320 else
1321 return "mov{w}\t{%1, %0|%0, %1}";
1322 }
1323 }
1324 [(set (attr "type")
1325 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1326 (const_string "imov")
1327 (and (eq_attr "alternative" "0")
1328 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1329 (const_int 0))
1330 (eq (symbol_ref "TARGET_HIMODE_MATH")
1331 (const_int 0))))
1332 (const_string "imov")
1333 (and (eq_attr "alternative" "1,2")
1334 (match_operand:HI 1 "aligned_operand" ""))
1335 (const_string "imov")
1336 (and (ne (symbol_ref "TARGET_MOVX")
1337 (const_int 0))
1338 (eq_attr "alternative" "0,2"))
1339 (const_string "imovx")
1340 ]
1341 (const_string "imov")))
1342 (set (attr "mode")
1343 (cond [(eq_attr "type" "imovx")
1344 (const_string "SI")
1345 (and (eq_attr "alternative" "1,2")
1346 (match_operand:HI 1 "aligned_operand" ""))
1347 (const_string "SI")
1348 (and (eq_attr "alternative" "0")
1349 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1350 (const_int 0))
1351 (eq (symbol_ref "TARGET_HIMODE_MATH")
1352 (const_int 0))))
1353 (const_string "SI")
1354 ]
1355 (const_string "HI")))])
1356
1357 ;; Stores and loads of ax to arbitrary constant address.
1358 ;; We fake an second form of instruction to force reload to load address
1359 ;; into register when rax is not available
1360 (define_insn "*movabshi_1_rex64"
1361 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1362 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1363 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1364 "@
1365 movabs{w}\t{%1, %P0|%P0, %1}
1366 mov{w}\t{%1, %a0|%a0, %1}"
1367 [(set_attr "type" "imov")
1368 (set_attr "modrm" "0,*")
1369 (set_attr "length_address" "8,0")
1370 (set_attr "length_immediate" "0,*")
1371 (set_attr "memory" "store")
1372 (set_attr "mode" "HI")])
1373
1374 (define_insn "*movabshi_2_rex64"
1375 [(set (match_operand:HI 0 "register_operand" "=a,r")
1376 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1377 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1378 "@
1379 movabs{w}\t{%P1, %0|%0, %P1}
1380 mov{w}\t{%a1, %0|%0, %a1}"
1381 [(set_attr "type" "imov")
1382 (set_attr "modrm" "0,*")
1383 (set_attr "length_address" "8,0")
1384 (set_attr "length_immediate" "0")
1385 (set_attr "memory" "load")
1386 (set_attr "mode" "HI")])
1387
1388 (define_insn "*swaphi_1"
1389 [(set (match_operand:HI 0 "register_operand" "+r")
1390 (match_operand:HI 1 "register_operand" "+r"))
1391 (set (match_dup 1)
1392 (match_dup 0))]
1393 "TARGET_PARTIAL_REG_STALL"
1394 "xchg{w}\t%1, %0"
1395 [(set_attr "type" "imov")
1396 (set_attr "pent_pair" "np")
1397 (set_attr "mode" "HI")
1398 (set_attr "modrm" "0")])
1399
1400 (define_insn "*swaphi_2"
1401 [(set (match_operand:HI 0 "register_operand" "+r")
1402 (match_operand:HI 1 "register_operand" "+r"))
1403 (set (match_dup 1)
1404 (match_dup 0))]
1405 "! TARGET_PARTIAL_REG_STALL"
1406 "xchg{l}\t%k1, %k0"
1407 [(set_attr "type" "imov")
1408 (set_attr "pent_pair" "np")
1409 (set_attr "mode" "SI")
1410 (set_attr "modrm" "0")])
1411
1412 (define_expand "movstricthi"
1413 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1414 (match_operand:HI 1 "general_operand" ""))]
1415 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1416 {
1417 /* Don't generate memory->memory moves, go through a register */
1418 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1419 operands[1] = force_reg (HImode, operands[1]);
1420 })
1421
1422 (define_insn "*movstricthi_1"
1423 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1424 (match_operand:HI 1 "general_operand" "rn,m"))]
1425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1426 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1427 "mov{w}\t{%1, %0|%0, %1}"
1428 [(set_attr "type" "imov")
1429 (set_attr "mode" "HI")])
1430
1431 (define_insn "*movstricthi_xor"
1432 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1433 (match_operand:HI 1 "const0_operand" "i"))
1434 (clobber (reg:CC 17))]
1435 "reload_completed
1436 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1437 "xor{w}\t{%0, %0|%0, %0}"
1438 [(set_attr "type" "alu1")
1439 (set_attr "mode" "HI")
1440 (set_attr "length_immediate" "0")])
1441
1442 (define_expand "movqi"
1443 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1444 (match_operand:QI 1 "general_operand" ""))]
1445 ""
1446 "ix86_expand_move (QImode, operands); DONE;")
1447
1448 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1449 ;; "push a byte". But actually we use pushw, which has the effect
1450 ;; of rounding the amount pushed up to a halfword.
1451
1452 (define_insn "*pushqi2"
1453 [(set (match_operand:QI 0 "push_operand" "=X,X")
1454 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1455 "!TARGET_64BIT"
1456 "@
1457 push{w}\t{|word ptr }%1
1458 push{w}\t%w1"
1459 [(set_attr "type" "push")
1460 (set_attr "mode" "HI")])
1461
1462 ;; For 64BIT abi we always round up to 8 bytes.
1463 (define_insn "*pushqi2_rex64"
1464 [(set (match_operand:QI 0 "push_operand" "=X")
1465 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1466 "TARGET_64BIT"
1467 "push{q}\t%q1"
1468 [(set_attr "type" "push")
1469 (set_attr "mode" "QI")])
1470
1471 ;; Situation is quite tricky about when to choose full sized (SImode) move
1472 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1473 ;; partial register dependency machines (such as AMD Athlon), where QImode
1474 ;; moves issue extra dependency and for partial register stalls machines
1475 ;; that don't use QImode patterns (and QImode move cause stall on the next
1476 ;; instruction).
1477 ;;
1478 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1479 ;; register stall machines with, where we use QImode instructions, since
1480 ;; partial register stall can be caused there. Then we use movzx.
1481 (define_insn "*movqi_1"
1482 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1483 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1484 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1485 {
1486 switch (get_attr_type (insn))
1487 {
1488 case TYPE_IMOVX:
1489 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1490 abort ();
1491 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1492 default:
1493 if (get_attr_mode (insn) == MODE_SI)
1494 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1495 else
1496 return "mov{b}\t{%1, %0|%0, %1}";
1497 }
1498 }
1499 [(set (attr "type")
1500 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1501 (const_string "imov")
1502 (and (eq_attr "alternative" "3")
1503 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1504 (const_int 0))
1505 (eq (symbol_ref "TARGET_QIMODE_MATH")
1506 (const_int 0))))
1507 (const_string "imov")
1508 (eq_attr "alternative" "3,5")
1509 (const_string "imovx")
1510 (and (ne (symbol_ref "TARGET_MOVX")
1511 (const_int 0))
1512 (eq_attr "alternative" "2"))
1513 (const_string "imovx")
1514 ]
1515 (const_string "imov")))
1516 (set (attr "mode")
1517 (cond [(eq_attr "alternative" "3,4,5")
1518 (const_string "SI")
1519 (eq_attr "alternative" "6")
1520 (const_string "QI")
1521 (eq_attr "type" "imovx")
1522 (const_string "SI")
1523 (and (eq_attr "type" "imov")
1524 (and (eq_attr "alternative" "0,1,2")
1525 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1526 (const_int 0))))
1527 (const_string "SI")
1528 ;; Avoid partial register stalls when not using QImode arithmetic
1529 (and (eq_attr "type" "imov")
1530 (and (eq_attr "alternative" "0,1,2")
1531 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532 (const_int 0))
1533 (eq (symbol_ref "TARGET_QIMODE_MATH")
1534 (const_int 0)))))
1535 (const_string "SI")
1536 ]
1537 (const_string "QI")))])
1538
1539 (define_expand "reload_outqi"
1540 [(parallel [(match_operand:QI 0 "" "=m")
1541 (match_operand:QI 1 "register_operand" "r")
1542 (match_operand:QI 2 "register_operand" "=&q")])]
1543 ""
1544 {
1545 rtx op0, op1, op2;
1546 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1547
1548 if (reg_overlap_mentioned_p (op2, op0))
1549 abort ();
1550 if (! q_regs_operand (op1, QImode))
1551 {
1552 emit_insn (gen_movqi (op2, op1));
1553 op1 = op2;
1554 }
1555 emit_insn (gen_movqi (op0, op1));
1556 DONE;
1557 })
1558
1559 (define_insn "*swapqi"
1560 [(set (match_operand:QI 0 "register_operand" "+r")
1561 (match_operand:QI 1 "register_operand" "+r"))
1562 (set (match_dup 1)
1563 (match_dup 0))]
1564 ""
1565 "xchg{b}\t%1, %0"
1566 [(set_attr "type" "imov")
1567 (set_attr "pent_pair" "np")
1568 (set_attr "mode" "QI")
1569 (set_attr "modrm" "0")])
1570
1571 (define_expand "movstrictqi"
1572 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1573 (match_operand:QI 1 "general_operand" ""))]
1574 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1575 {
1576 /* Don't generate memory->memory moves, go through a register. */
1577 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1578 operands[1] = force_reg (QImode, operands[1]);
1579 })
1580
1581 (define_insn "*movstrictqi_1"
1582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1583 (match_operand:QI 1 "general_operand" "*qn,m"))]
1584 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1585 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1586 "mov{b}\t{%1, %0|%0, %1}"
1587 [(set_attr "type" "imov")
1588 (set_attr "mode" "QI")])
1589
1590 (define_insn "*movstrictqi_xor"
1591 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1592 (match_operand:QI 1 "const0_operand" "i"))
1593 (clobber (reg:CC 17))]
1594 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1595 "xor{b}\t{%0, %0|%0, %0}"
1596 [(set_attr "type" "alu1")
1597 (set_attr "mode" "QI")
1598 (set_attr "length_immediate" "0")])
1599
1600 (define_insn "*movsi_extv_1"
1601 [(set (match_operand:SI 0 "register_operand" "=R")
1602 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1603 (const_int 8)
1604 (const_int 8)))]
1605 ""
1606 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1607 [(set_attr "type" "imovx")
1608 (set_attr "mode" "SI")])
1609
1610 (define_insn "*movhi_extv_1"
1611 [(set (match_operand:HI 0 "register_operand" "=R")
1612 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1613 (const_int 8)
1614 (const_int 8)))]
1615 ""
1616 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1617 [(set_attr "type" "imovx")
1618 (set_attr "mode" "SI")])
1619
1620 (define_insn "*movqi_extv_1"
1621 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1622 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1623 (const_int 8)
1624 (const_int 8)))]
1625 "!TARGET_64BIT"
1626 {
1627 switch (get_attr_type (insn))
1628 {
1629 case TYPE_IMOVX:
1630 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1631 default:
1632 return "mov{b}\t{%h1, %0|%0, %h1}";
1633 }
1634 }
1635 [(set (attr "type")
1636 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1637 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1638 (ne (symbol_ref "TARGET_MOVX")
1639 (const_int 0))))
1640 (const_string "imovx")
1641 (const_string "imov")))
1642 (set (attr "mode")
1643 (if_then_else (eq_attr "type" "imovx")
1644 (const_string "SI")
1645 (const_string "QI")))])
1646
1647 (define_insn "*movqi_extv_1_rex64"
1648 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1649 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1650 (const_int 8)
1651 (const_int 8)))]
1652 "TARGET_64BIT"
1653 {
1654 switch (get_attr_type (insn))
1655 {
1656 case TYPE_IMOVX:
1657 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1658 default:
1659 return "mov{b}\t{%h1, %0|%0, %h1}";
1660 }
1661 }
1662 [(set (attr "type")
1663 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1664 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1665 (ne (symbol_ref "TARGET_MOVX")
1666 (const_int 0))))
1667 (const_string "imovx")
1668 (const_string "imov")))
1669 (set (attr "mode")
1670 (if_then_else (eq_attr "type" "imovx")
1671 (const_string "SI")
1672 (const_string "QI")))])
1673
1674 ;; Stores and loads of ax to arbitrary constant address.
1675 ;; We fake an second form of instruction to force reload to load address
1676 ;; into register when rax is not available
1677 (define_insn "*movabsqi_1_rex64"
1678 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1679 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1680 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1681 "@
1682 movabs{b}\t{%1, %P0|%P0, %1}
1683 mov{b}\t{%1, %a0|%a0, %1}"
1684 [(set_attr "type" "imov")
1685 (set_attr "modrm" "0,*")
1686 (set_attr "length_address" "8,0")
1687 (set_attr "length_immediate" "0,*")
1688 (set_attr "memory" "store")
1689 (set_attr "mode" "QI")])
1690
1691 (define_insn "*movabsqi_2_rex64"
1692 [(set (match_operand:QI 0 "register_operand" "=a,r")
1693 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1694 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1695 "@
1696 movabs{b}\t{%P1, %0|%0, %P1}
1697 mov{b}\t{%a1, %0|%0, %a1}"
1698 [(set_attr "type" "imov")
1699 (set_attr "modrm" "0,*")
1700 (set_attr "length_address" "8,0")
1701 (set_attr "length_immediate" "0")
1702 (set_attr "memory" "load")
1703 (set_attr "mode" "QI")])
1704
1705 (define_insn "*movsi_extzv_1"
1706 [(set (match_operand:SI 0 "register_operand" "=R")
1707 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1708 (const_int 8)
1709 (const_int 8)))]
1710 ""
1711 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1712 [(set_attr "type" "imovx")
1713 (set_attr "mode" "SI")])
1714
1715 (define_insn "*movqi_extzv_2"
1716 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1717 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1718 (const_int 8)
1719 (const_int 8)) 0))]
1720 "!TARGET_64BIT"
1721 {
1722 switch (get_attr_type (insn))
1723 {
1724 case TYPE_IMOVX:
1725 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1726 default:
1727 return "mov{b}\t{%h1, %0|%0, %h1}";
1728 }
1729 }
1730 [(set (attr "type")
1731 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1732 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1733 (ne (symbol_ref "TARGET_MOVX")
1734 (const_int 0))))
1735 (const_string "imovx")
1736 (const_string "imov")))
1737 (set (attr "mode")
1738 (if_then_else (eq_attr "type" "imovx")
1739 (const_string "SI")
1740 (const_string "QI")))])
1741
1742 (define_insn "*movqi_extzv_2_rex64"
1743 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1744 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1745 (const_int 8)
1746 (const_int 8)) 0))]
1747 "TARGET_64BIT"
1748 {
1749 switch (get_attr_type (insn))
1750 {
1751 case TYPE_IMOVX:
1752 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1753 default:
1754 return "mov{b}\t{%h1, %0|%0, %h1}";
1755 }
1756 }
1757 [(set (attr "type")
1758 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1759 (ne (symbol_ref "TARGET_MOVX")
1760 (const_int 0)))
1761 (const_string "imovx")
1762 (const_string "imov")))
1763 (set (attr "mode")
1764 (if_then_else (eq_attr "type" "imovx")
1765 (const_string "SI")
1766 (const_string "QI")))])
1767
1768 (define_insn "movsi_insv_1"
1769 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770 (const_int 8)
1771 (const_int 8))
1772 (match_operand:SI 1 "general_operand" "Qmn"))]
1773 "!TARGET_64BIT"
1774 "mov{b}\t{%b1, %h0|%h0, %b1}"
1775 [(set_attr "type" "imov")
1776 (set_attr "mode" "QI")])
1777
1778 (define_insn "*movsi_insv_1_rex64"
1779 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1780 (const_int 8)
1781 (const_int 8))
1782 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1783 "TARGET_64BIT"
1784 "mov{b}\t{%b1, %h0|%h0, %b1}"
1785 [(set_attr "type" "imov")
1786 (set_attr "mode" "QI")])
1787
1788 (define_insn "*movqi_insv_2"
1789 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1790 (const_int 8)
1791 (const_int 8))
1792 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1793 (const_int 8)))]
1794 ""
1795 "mov{b}\t{%h1, %h0|%h0, %h1}"
1796 [(set_attr "type" "imov")
1797 (set_attr "mode" "QI")])
1798
1799 (define_expand "movdi"
1800 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1801 (match_operand:DI 1 "general_operand" ""))]
1802 ""
1803 "ix86_expand_move (DImode, operands); DONE;")
1804
1805 (define_insn "*pushdi"
1806 [(set (match_operand:DI 0 "push_operand" "=<")
1807 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1808 "!TARGET_64BIT"
1809 "#")
1810
1811 (define_insn "pushdi2_rex64"
1812 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1813 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1814 "TARGET_64BIT"
1815 "@
1816 push{q}\t%1
1817 #"
1818 [(set_attr "type" "push,multi")
1819 (set_attr "mode" "DI")])
1820
1821 ;; Convert impossible pushes of immediate to existing instructions.
1822 ;; First try to get scratch register and go through it. In case this
1823 ;; fails, push sign extended lower part first and then overwrite
1824 ;; upper part by 32bit move.
1825 (define_peephole2
1826 [(match_scratch:DI 2 "r")
1827 (set (match_operand:DI 0 "push_operand" "")
1828 (match_operand:DI 1 "immediate_operand" ""))]
1829 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1830 && !x86_64_immediate_operand (operands[1], DImode)"
1831 [(set (match_dup 2) (match_dup 1))
1832 (set (match_dup 0) (match_dup 2))]
1833 "")
1834
1835 ;; We need to define this as both peepholer and splitter for case
1836 ;; peephole2 pass is not run.
1837 (define_peephole2
1838 [(set (match_operand:DI 0 "push_operand" "")
1839 (match_operand:DI 1 "immediate_operand" ""))]
1840 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1842 [(set (match_dup 0) (match_dup 1))
1843 (set (match_dup 2) (match_dup 3))]
1844 "split_di (operands + 1, 1, operands + 2, operands + 3);
1845 operands[1] = gen_lowpart (DImode, operands[2]);
1846 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1847 GEN_INT (4)));
1848 ")
1849
1850 (define_split
1851 [(set (match_operand:DI 0 "push_operand" "")
1852 (match_operand:DI 1 "immediate_operand" ""))]
1853 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1854 && !symbolic_operand (operands[1], DImode)
1855 && !x86_64_immediate_operand (operands[1], DImode)"
1856 [(set (match_dup 0) (match_dup 1))
1857 (set (match_dup 2) (match_dup 3))]
1858 "split_di (operands + 1, 1, operands + 2, operands + 3);
1859 operands[1] = gen_lowpart (DImode, operands[2]);
1860 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1861 GEN_INT (4)));
1862 ")
1863
1864 (define_insn "*pushdi2_prologue_rex64"
1865 [(set (match_operand:DI 0 "push_operand" "=<")
1866 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1867 (clobber (mem:BLK (scratch)))]
1868 "TARGET_64BIT"
1869 "push{q}\t%1"
1870 [(set_attr "type" "push")
1871 (set_attr "mode" "DI")])
1872
1873 (define_insn "*popdi1_epilogue_rex64"
1874 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1875 (mem:DI (reg:DI 7)))
1876 (set (reg:DI 7)
1877 (plus:DI (reg:DI 7) (const_int 8)))
1878 (clobber (mem:BLK (scratch)))]
1879 "TARGET_64BIT"
1880 "pop{q}\t%0"
1881 [(set_attr "type" "pop")
1882 (set_attr "mode" "DI")])
1883
1884 (define_insn "popdi1"
1885 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1886 (mem:DI (reg:DI 7)))
1887 (set (reg:DI 7)
1888 (plus:DI (reg:DI 7) (const_int 8)))]
1889 "TARGET_64BIT"
1890 "pop{q}\t%0"
1891 [(set_attr "type" "pop")
1892 (set_attr "mode" "DI")])
1893
1894 (define_insn "*movdi_xor_rex64"
1895 [(set (match_operand:DI 0 "register_operand" "=r")
1896 (match_operand:DI 1 "const0_operand" "i"))
1897 (clobber (reg:CC 17))]
1898 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1899 && reload_completed"
1900 "xor{l}\t{%k0, %k0|%k0, %k0}"
1901 [(set_attr "type" "alu1")
1902 (set_attr "mode" "SI")
1903 (set_attr "length_immediate" "0")])
1904
1905 (define_insn "*movdi_or_rex64"
1906 [(set (match_operand:DI 0 "register_operand" "=r")
1907 (match_operand:DI 1 "const_int_operand" "i"))
1908 (clobber (reg:CC 17))]
1909 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1910 && reload_completed
1911 && operands[1] == constm1_rtx"
1912 {
1913 operands[1] = constm1_rtx;
1914 return "or{q}\t{%1, %0|%0, %1}";
1915 }
1916 [(set_attr "type" "alu1")
1917 (set_attr "mode" "DI")
1918 (set_attr "length_immediate" "1")])
1919
1920 (define_insn "*movdi_2"
1921 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1922 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1923 "!TARGET_64BIT
1924 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1925 "@
1926 #
1927 #
1928 movq\t{%1, %0|%0, %1}
1929 movq\t{%1, %0|%0, %1}
1930 movq\t{%1, %0|%0, %1}
1931 movdqa\t{%1, %0|%0, %1}
1932 movq\t{%1, %0|%0, %1}"
1933 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1934 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1935
1936 (define_split
1937 [(set (match_operand:DI 0 "push_operand" "")
1938 (match_operand:DI 1 "general_operand" ""))]
1939 "!TARGET_64BIT && reload_completed
1940 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1941 [(const_int 0)]
1942 "ix86_split_long_move (operands); DONE;")
1943
1944 ;; %%% This multiword shite has got to go.
1945 (define_split
1946 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1947 (match_operand:DI 1 "general_operand" ""))]
1948 "!TARGET_64BIT && reload_completed
1949 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1950 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1951 [(const_int 0)]
1952 "ix86_split_long_move (operands); DONE;")
1953
1954 (define_insn "*movdi_1_rex64"
1955 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1956 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1957 "TARGET_64BIT
1958 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1959 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1960 {
1961 switch (get_attr_type (insn))
1962 {
1963 case TYPE_SSEMOV:
1964 if (get_attr_mode (insn) == MODE_TI)
1965 return "movdqa\t{%1, %0|%0, %1}";
1966 /* FALLTHRU */
1967 case TYPE_MMXMOV:
1968 /* Moves from and into integer register is done using movd opcode with
1969 REX prefix. */
1970 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1971 return "movd\t{%1, %0|%0, %1}";
1972 return "movq\t{%1, %0|%0, %1}";
1973 case TYPE_MULTI:
1974 return "#";
1975 case TYPE_LEA:
1976 return "lea{q}\t{%a1, %0|%0, %a1}";
1977 default:
1978 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1979 abort ();
1980 if (get_attr_mode (insn) == MODE_SI)
1981 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1982 else if (which_alternative == 2)
1983 return "movabs{q}\t{%1, %0|%0, %1}";
1984 else
1985 return "mov{q}\t{%1, %0|%0, %1}";
1986 }
1987 }
1988 [(set (attr "type")
1989 (cond [(eq_attr "alternative" "5,6,7")
1990 (const_string "mmxmov")
1991 (eq_attr "alternative" "8,9,10")
1992 (const_string "ssemov")
1993 (eq_attr "alternative" "4")
1994 (const_string "multi")
1995 (and (ne (symbol_ref "flag_pic") (const_int 0))
1996 (match_operand:DI 1 "symbolic_operand" ""))
1997 (const_string "lea")
1998 ]
1999 (const_string "imov")))
2000 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2001 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2002 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2003
2004 (define_insn "*movdi_1_rex64_nointerunit"
2005 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2006 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2007 "TARGET_64BIT
2008 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2009 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2010 {
2011 switch (get_attr_type (insn))
2012 {
2013 case TYPE_SSEMOV:
2014 if (get_attr_mode (insn) == MODE_TI)
2015 return "movdqa\t{%1, %0|%0, %1}";
2016 /* FALLTHRU */
2017 case TYPE_MMXMOV:
2018 return "movq\t{%1, %0|%0, %1}";
2019 case TYPE_MULTI:
2020 return "#";
2021 case TYPE_LEA:
2022 return "lea{q}\t{%a1, %0|%0, %a1}";
2023 default:
2024 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2025 abort ();
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 2)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2030 else
2031 return "mov{q}\t{%1, %0|%0, %1}";
2032 }
2033 }
2034 [(set (attr "type")
2035 (cond [(eq_attr "alternative" "5,6,7")
2036 (const_string "mmxmov")
2037 (eq_attr "alternative" "8,9,10")
2038 (const_string "ssemov")
2039 (eq_attr "alternative" "4")
2040 (const_string "multi")
2041 (and (ne (symbol_ref "flag_pic") (const_int 0))
2042 (match_operand:DI 1 "symbolic_operand" ""))
2043 (const_string "lea")
2044 ]
2045 (const_string "imov")))
2046 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2047 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2048 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2049
2050 ;; Stores and loads of ax to arbitrary constant address.
2051 ;; We fake an second form of instruction to force reload to load address
2052 ;; into register when rax is not available
2053 (define_insn "*movabsdi_1_rex64"
2054 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2055 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2056 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2057 "@
2058 movabs{q}\t{%1, %P0|%P0, %1}
2059 mov{q}\t{%1, %a0|%a0, %1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "modrm" "0,*")
2062 (set_attr "length_address" "8,0")
2063 (set_attr "length_immediate" "0,*")
2064 (set_attr "memory" "store")
2065 (set_attr "mode" "DI")])
2066
2067 (define_insn "*movabsdi_2_rex64"
2068 [(set (match_operand:DI 0 "register_operand" "=a,r")
2069 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2070 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2071 "@
2072 movabs{q}\t{%P1, %0|%0, %P1}
2073 mov{q}\t{%a1, %0|%0, %a1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "modrm" "0,*")
2076 (set_attr "length_address" "8,0")
2077 (set_attr "length_immediate" "0")
2078 (set_attr "memory" "load")
2079 (set_attr "mode" "DI")])
2080
2081 ;; Convert impossible stores of immediate to existing instructions.
2082 ;; First try to get scratch register and go through it. In case this
2083 ;; fails, move by 32bit parts.
2084 (define_peephole2
2085 [(match_scratch:DI 2 "r")
2086 (set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode)"
2090 [(set (match_dup 2) (match_dup 1))
2091 (set (match_dup 0) (match_dup 2))]
2092 "")
2093
2094 ;; We need to define this as both peepholer and splitter for case
2095 ;; peephole2 pass is not run.
2096 (define_peephole2
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_di (operands, 2, operands + 2, operands + 4);")
2104
2105 (define_split
2106 [(set (match_operand:DI 0 "memory_operand" "")
2107 (match_operand:DI 1 "immediate_operand" ""))]
2108 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2109 && !symbolic_operand (operands[1], DImode)
2110 && !x86_64_immediate_operand (operands[1], DImode)"
2111 [(set (match_dup 2) (match_dup 3))
2112 (set (match_dup 4) (match_dup 5))]
2113 "split_di (operands, 2, operands + 2, operands + 4);")
2114
2115 (define_insn "*swapdi_rex64"
2116 [(set (match_operand:DI 0 "register_operand" "+r")
2117 (match_operand:DI 1 "register_operand" "+r"))
2118 (set (match_dup 1)
2119 (match_dup 0))]
2120 "TARGET_64BIT"
2121 "xchg{q}\t%1, %0"
2122 [(set_attr "type" "imov")
2123 (set_attr "pent_pair" "np")
2124 (set_attr "athlon_decode" "vector")
2125 (set_attr "mode" "DI")
2126 (set_attr "modrm" "0")])
2127
2128
2129 (define_expand "movsf"
2130 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2131 (match_operand:SF 1 "general_operand" ""))]
2132 ""
2133 "ix86_expand_move (SFmode, operands); DONE;")
2134
2135 (define_insn "*pushsf"
2136 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2137 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2138 "!TARGET_64BIT"
2139 {
2140 switch (which_alternative)
2141 {
2142 case 1:
2143 return "push{l}\t%1";
2144
2145 default:
2146 /* This insn should be already split before reg-stack. */
2147 abort ();
2148 }
2149 }
2150 [(set_attr "type" "multi,push,multi")
2151 (set_attr "mode" "SF,SI,SF")])
2152
2153 (define_insn "*pushsf_rex64"
2154 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2155 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2156 "TARGET_64BIT"
2157 {
2158 switch (which_alternative)
2159 {
2160 case 1:
2161 return "push{q}\t%q1";
2162
2163 default:
2164 /* This insn should be already split before reg-stack. */
2165 abort ();
2166 }
2167 }
2168 [(set_attr "type" "multi,push,multi")
2169 (set_attr "mode" "SF,DI,SF")])
2170
2171 (define_split
2172 [(set (match_operand:SF 0 "push_operand" "")
2173 (match_operand:SF 1 "memory_operand" ""))]
2174 "reload_completed
2175 && GET_CODE (operands[1]) == MEM
2176 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2177 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2178 [(set (match_dup 0)
2179 (match_dup 1))]
2180 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2181
2182
2183 ;; %%% Kill this when call knows how to work this out.
2184 (define_split
2185 [(set (match_operand:SF 0 "push_operand" "")
2186 (match_operand:SF 1 "any_fp_register_operand" ""))]
2187 "!TARGET_64BIT"
2188 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2189 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2190
2191 (define_split
2192 [(set (match_operand:SF 0 "push_operand" "")
2193 (match_operand:SF 1 "any_fp_register_operand" ""))]
2194 "TARGET_64BIT"
2195 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2196 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2197
2198 (define_insn "*movsf_1"
2199 [(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")
2200 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2201 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2202 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2203 && (reload_in_progress || reload_completed
2204 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2205 || GET_CODE (operands[1]) != CONST_DOUBLE
2206 || memory_operand (operands[0], SFmode))"
2207 {
2208 switch (which_alternative)
2209 {
2210 case 0:
2211 return output_387_reg_move (insn, operands);
2212
2213 case 1:
2214 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2215 return "fstp%z0\t%y0";
2216 else
2217 return "fst%z0\t%y0";
2218
2219 case 2:
2220 return standard_80387_constant_opcode (operands[1]);
2221
2222 case 3:
2223 case 4:
2224 return "mov{l}\t{%1, %0|%0, %1}";
2225 case 5:
2226 if (get_attr_mode (insn) == MODE_TI)
2227 return "pxor\t%0, %0";
2228 else
2229 return "xorps\t%0, %0";
2230 case 6:
2231 if (get_attr_mode (insn) == MODE_V4SF)
2232 return "movaps\t{%1, %0|%0, %1}";
2233 else
2234 return "movss\t{%1, %0|%0, %1}";
2235 case 7:
2236 case 8:
2237 return "movss\t{%1, %0|%0, %1}";
2238
2239 case 9:
2240 case 10:
2241 return "movd\t{%1, %0|%0, %1}";
2242
2243 case 11:
2244 return "movq\t{%1, %0|%0, %1}";
2245
2246 default:
2247 abort();
2248 }
2249 }
2250 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2251 (set (attr "mode")
2252 (cond [(eq_attr "alternative" "3,4,9,10")
2253 (const_string "SI")
2254 (eq_attr "alternative" "5")
2255 (if_then_else
2256 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2257 (const_int 0))
2258 (ne (symbol_ref "TARGET_SSE2")
2259 (const_int 0)))
2260 (eq (symbol_ref "optimize_size")
2261 (const_int 0)))
2262 (const_string "TI")
2263 (const_string "V4SF"))
2264 /* For architectures resolving dependencies on
2265 whole SSE registers use APS move to break dependency
2266 chains, otherwise use short move to avoid extra work.
2267
2268 Do the same for architectures resolving dependencies on
2269 the parts. While in DF mode it is better to always handle
2270 just register parts, the SF mode is different due to lack
2271 of instructions to load just part of the register. It is
2272 better to maintain the whole registers in single format
2273 to avoid problems on using packed logical operations. */
2274 (eq_attr "alternative" "6")
2275 (if_then_else
2276 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2277 (const_int 0))
2278 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2279 (const_int 0)))
2280 (const_string "V4SF")
2281 (const_string "SF"))
2282 (eq_attr "alternative" "11")
2283 (const_string "DI")]
2284 (const_string "SF")))])
2285
2286 (define_insn "*movsf_1_nointerunit"
2287 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2288 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2289 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2290 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2291 && (reload_in_progress || reload_completed
2292 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2293 || GET_CODE (operands[1]) != CONST_DOUBLE
2294 || memory_operand (operands[0], SFmode))"
2295 {
2296 switch (which_alternative)
2297 {
2298 case 0:
2299 return output_387_reg_move (insn, operands);
2300
2301 case 1:
2302 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2303 return "fstp%z0\t%y0";
2304 else
2305 return "fst%z0\t%y0";
2306
2307 case 2:
2308 return standard_80387_constant_opcode (operands[1]);
2309
2310 case 3:
2311 case 4:
2312 return "mov{l}\t{%1, %0|%0, %1}";
2313 case 5:
2314 if (get_attr_mode (insn) == MODE_TI)
2315 return "pxor\t%0, %0";
2316 else
2317 return "xorps\t%0, %0";
2318 case 6:
2319 if (get_attr_mode (insn) == MODE_V4SF)
2320 return "movaps\t{%1, %0|%0, %1}";
2321 else
2322 return "movss\t{%1, %0|%0, %1}";
2323 case 7:
2324 case 8:
2325 return "movss\t{%1, %0|%0, %1}";
2326
2327 case 9:
2328 case 10:
2329 return "movd\t{%1, %0|%0, %1}";
2330
2331 case 11:
2332 return "movq\t{%1, %0|%0, %1}";
2333
2334 default:
2335 abort();
2336 }
2337 }
2338 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2339 (set (attr "mode")
2340 (cond [(eq_attr "alternative" "3,4,9,10")
2341 (const_string "SI")
2342 (eq_attr "alternative" "5")
2343 (if_then_else
2344 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2345 (const_int 0))
2346 (ne (symbol_ref "TARGET_SSE2")
2347 (const_int 0)))
2348 (eq (symbol_ref "optimize_size")
2349 (const_int 0)))
2350 (const_string "TI")
2351 (const_string "V4SF"))
2352 /* For architectures resolving dependencies on
2353 whole SSE registers use APS move to break dependency
2354 chains, otherwise use short move to avoid extra work.
2355
2356 Do the same for architectures resolving dependencies on
2357 the parts. While in DF mode it is better to always handle
2358 just register parts, the SF mode is different due to lack
2359 of instructions to load just part of the register. It is
2360 better to maintain the whole registers in single format
2361 to avoid problems on using packed logical operations. */
2362 (eq_attr "alternative" "6")
2363 (if_then_else
2364 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2365 (const_int 0))
2366 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2367 (const_int 0)))
2368 (const_string "V4SF")
2369 (const_string "SF"))
2370 (eq_attr "alternative" "11")
2371 (const_string "DI")]
2372 (const_string "SF")))])
2373
2374 (define_insn "*swapsf"
2375 [(set (match_operand:SF 0 "register_operand" "+f")
2376 (match_operand:SF 1 "register_operand" "+f"))
2377 (set (match_dup 1)
2378 (match_dup 0))]
2379 "reload_completed || !TARGET_SSE"
2380 {
2381 if (STACK_TOP_P (operands[0]))
2382 return "fxch\t%1";
2383 else
2384 return "fxch\t%0";
2385 }
2386 [(set_attr "type" "fxch")
2387 (set_attr "mode" "SF")])
2388
2389 (define_expand "movdf"
2390 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2391 (match_operand:DF 1 "general_operand" ""))]
2392 ""
2393 "ix86_expand_move (DFmode, operands); DONE;")
2394
2395 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2396 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2397 ;; On the average, pushdf using integers can be still shorter. Allow this
2398 ;; pattern for optimize_size too.
2399
2400 (define_insn "*pushdf_nointeger"
2401 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2402 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2403 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2404 {
2405 /* This insn should be already split before reg-stack. */
2406 abort ();
2407 }
2408 [(set_attr "type" "multi")
2409 (set_attr "mode" "DF,SI,SI,DF")])
2410
2411 (define_insn "*pushdf_integer"
2412 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2413 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2414 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2415 {
2416 /* This insn should be already split before reg-stack. */
2417 abort ();
2418 }
2419 [(set_attr "type" "multi")
2420 (set_attr "mode" "DF,SI,DF")])
2421
2422 ;; %%% Kill this when call knows how to work this out.
2423 (define_split
2424 [(set (match_operand:DF 0 "push_operand" "")
2425 (match_operand:DF 1 "any_fp_register_operand" ""))]
2426 "!TARGET_64BIT && reload_completed"
2427 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2428 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2429 "")
2430
2431 (define_split
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "any_fp_register_operand" ""))]
2434 "TARGET_64BIT && reload_completed"
2435 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2436 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2437 "")
2438
2439 (define_split
2440 [(set (match_operand:DF 0 "push_operand" "")
2441 (match_operand:DF 1 "general_operand" ""))]
2442 "reload_completed"
2443 [(const_int 0)]
2444 "ix86_split_long_move (operands); DONE;")
2445
2446 ;; Moving is usually shorter when only FP registers are used. This separate
2447 ;; movdf pattern avoids the use of integer registers for FP operations
2448 ;; when optimizing for size.
2449
2450 (define_insn "*movdf_nointeger"
2451 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2452 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2453 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2454 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2455 && (reload_in_progress || reload_completed
2456 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2457 || GET_CODE (operands[1]) != CONST_DOUBLE
2458 || memory_operand (operands[0], DFmode))"
2459 {
2460 switch (which_alternative)
2461 {
2462 case 0:
2463 return output_387_reg_move (insn, operands);
2464
2465 case 1:
2466 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2467 return "fstp%z0\t%y0";
2468 else
2469 return "fst%z0\t%y0";
2470
2471 case 2:
2472 return standard_80387_constant_opcode (operands[1]);
2473
2474 case 3:
2475 case 4:
2476 return "#";
2477 case 5:
2478 switch (get_attr_mode (insn))
2479 {
2480 case MODE_V4SF:
2481 return "xorps\t%0, %0";
2482 case MODE_V2DF:
2483 return "xorpd\t%0, %0";
2484 case MODE_TI:
2485 return "pxor\t%0, %0";
2486 default:
2487 abort ();
2488 }
2489 case 6:
2490 switch (get_attr_mode (insn))
2491 {
2492 case MODE_V4SF:
2493 return "movaps\t{%1, %0|%0, %1}";
2494 case MODE_V2DF:
2495 return "movapd\t{%1, %0|%0, %1}";
2496 case MODE_DF:
2497 return "movsd\t{%1, %0|%0, %1}";
2498 default:
2499 abort ();
2500 }
2501 case 7:
2502 if (get_attr_mode (insn) == MODE_V2DF)
2503 return "movlpd\t{%1, %0|%0, %1}";
2504 else
2505 return "movsd\t{%1, %0|%0, %1}";
2506 case 8:
2507 return "movsd\t{%1, %0|%0, %1}";
2508
2509 default:
2510 abort();
2511 }
2512 }
2513 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2514 (set (attr "mode")
2515 (cond [(eq_attr "alternative" "3,4")
2516 (const_string "SI")
2517 /* xorps is one byte shorter. */
2518 (eq_attr "alternative" "5")
2519 (cond [(ne (symbol_ref "optimize_size")
2520 (const_int 0))
2521 (const_string "V4SF")
2522 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2523 (const_int 0))
2524 (const_string "TI")]
2525 (const_string "V2DF"))
2526 /* For architectures resolving dependencies on
2527 whole SSE registers use APD move to break dependency
2528 chains, otherwise use short move to avoid extra work.
2529
2530 movaps encodes one byte shorter. */
2531 (eq_attr "alternative" "6")
2532 (cond
2533 [(ne (symbol_ref "optimize_size")
2534 (const_int 0))
2535 (const_string "V4SF")
2536 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2537 (const_int 0))
2538 (const_string "V2DF")]
2539 (const_string "DF"))
2540 /* For architectures resolving dependencies on register
2541 parts we may avoid extra work to zero out upper part
2542 of register. */
2543 (eq_attr "alternative" "7")
2544 (if_then_else
2545 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2546 (const_int 0))
2547 (const_string "V2DF")
2548 (const_string "DF"))]
2549 (const_string "DF")))])
2550
2551 (define_insn "*movdf_integer"
2552 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2553 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2554 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2555 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2556 && (reload_in_progress || reload_completed
2557 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2558 || GET_CODE (operands[1]) != CONST_DOUBLE
2559 || memory_operand (operands[0], DFmode))"
2560 {
2561 switch (which_alternative)
2562 {
2563 case 0:
2564 return output_387_reg_move (insn, operands);
2565
2566 case 1:
2567 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2568 return "fstp%z0\t%y0";
2569 else
2570 return "fst%z0\t%y0";
2571
2572 case 2:
2573 return standard_80387_constant_opcode (operands[1]);
2574
2575 case 3:
2576 case 4:
2577 return "#";
2578
2579 case 5:
2580 switch (get_attr_mode (insn))
2581 {
2582 case MODE_V4SF:
2583 return "xorps\t%0, %0";
2584 case MODE_V2DF:
2585 return "xorpd\t%0, %0";
2586 case MODE_TI:
2587 return "pxor\t%0, %0";
2588 default:
2589 abort ();
2590 }
2591 case 6:
2592 switch (get_attr_mode (insn))
2593 {
2594 case MODE_V4SF:
2595 return "movaps\t{%1, %0|%0, %1}";
2596 case MODE_V2DF:
2597 return "movapd\t{%1, %0|%0, %1}";
2598 case MODE_DF:
2599 return "movsd\t{%1, %0|%0, %1}";
2600 default:
2601 abort ();
2602 }
2603 case 7:
2604 if (get_attr_mode (insn) == MODE_V2DF)
2605 return "movlpd\t{%1, %0|%0, %1}";
2606 else
2607 return "movsd\t{%1, %0|%0, %1}";
2608 case 8:
2609 return "movsd\t{%1, %0|%0, %1}";
2610
2611 default:
2612 abort();
2613 }
2614 }
2615 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2616 (set (attr "mode")
2617 (cond [(eq_attr "alternative" "3,4")
2618 (const_string "SI")
2619 /* xorps is one byte shorter. */
2620 (eq_attr "alternative" "5")
2621 (cond [(ne (symbol_ref "optimize_size")
2622 (const_int 0))
2623 (const_string "V4SF")
2624 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2625 (const_int 0))
2626 (const_string "TI")]
2627 (const_string "V2DF"))
2628 /* For architectures resolving dependencies on
2629 whole SSE registers use APD move to break dependency
2630 chains, otherwise use short move to avoid extra work.
2631
2632 movaps encodes one byte shorter. */
2633 (eq_attr "alternative" "6")
2634 (cond
2635 [(ne (symbol_ref "optimize_size")
2636 (const_int 0))
2637 (const_string "V4SF")
2638 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2639 (const_int 0))
2640 (const_string "V2DF")]
2641 (const_string "DF"))
2642 /* For architectures resolving dependencies on register
2643 parts we may avoid extra work to zero out upper part
2644 of register. */
2645 (eq_attr "alternative" "7")
2646 (if_then_else
2647 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2648 (const_int 0))
2649 (const_string "V2DF")
2650 (const_string "DF"))]
2651 (const_string "DF")))])
2652
2653 (define_split
2654 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2655 (match_operand:DF 1 "general_operand" ""))]
2656 "reload_completed
2657 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2658 && ! (ANY_FP_REG_P (operands[0]) ||
2659 (GET_CODE (operands[0]) == SUBREG
2660 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2661 && ! (ANY_FP_REG_P (operands[1]) ||
2662 (GET_CODE (operands[1]) == SUBREG
2663 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2664 [(const_int 0)]
2665 "ix86_split_long_move (operands); DONE;")
2666
2667 (define_insn "*swapdf"
2668 [(set (match_operand:DF 0 "register_operand" "+f")
2669 (match_operand:DF 1 "register_operand" "+f"))
2670 (set (match_dup 1)
2671 (match_dup 0))]
2672 "reload_completed || !TARGET_SSE2"
2673 {
2674 if (STACK_TOP_P (operands[0]))
2675 return "fxch\t%1";
2676 else
2677 return "fxch\t%0";
2678 }
2679 [(set_attr "type" "fxch")
2680 (set_attr "mode" "DF")])
2681
2682 (define_expand "movxf"
2683 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2684 (match_operand:XF 1 "general_operand" ""))]
2685 ""
2686 "ix86_expand_move (XFmode, operands); DONE;")
2687
2688 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2689 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2690 ;; Pushing using integer instructions is longer except for constants
2691 ;; and direct memory references.
2692 ;; (assuming that any given constant is pushed only once, but this ought to be
2693 ;; handled elsewhere).
2694
2695 (define_insn "*pushxf_nointeger"
2696 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2697 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2698 "optimize_size"
2699 {
2700 /* This insn should be already split before reg-stack. */
2701 abort ();
2702 }
2703 [(set_attr "type" "multi")
2704 (set_attr "mode" "XF,SI,SI")])
2705
2706 (define_insn "*pushxf_integer"
2707 [(set (match_operand:XF 0 "push_operand" "=<,<")
2708 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2709 "!optimize_size"
2710 {
2711 /* This insn should be already split before reg-stack. */
2712 abort ();
2713 }
2714 [(set_attr "type" "multi")
2715 (set_attr "mode" "XF,SI")])
2716
2717 (define_split
2718 [(set (match_operand 0 "push_operand" "")
2719 (match_operand 1 "general_operand" ""))]
2720 "reload_completed
2721 && (GET_MODE (operands[0]) == XFmode
2722 || GET_MODE (operands[0]) == DFmode)
2723 && !ANY_FP_REG_P (operands[1])"
2724 [(const_int 0)]
2725 "ix86_split_long_move (operands); DONE;")
2726
2727 (define_split
2728 [(set (match_operand:XF 0 "push_operand" "")
2729 (match_operand:XF 1 "any_fp_register_operand" ""))]
2730 "!TARGET_64BIT"
2731 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2732 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2733 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2734
2735 (define_split
2736 [(set (match_operand:XF 0 "push_operand" "")
2737 (match_operand:XF 1 "any_fp_register_operand" ""))]
2738 "TARGET_64BIT"
2739 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2740 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2741 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2742
2743 ;; Do not use integer registers when optimizing for size
2744 (define_insn "*movxf_nointeger"
2745 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2746 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2747 "optimize_size
2748 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2749 && (reload_in_progress || reload_completed
2750 || GET_CODE (operands[1]) != CONST_DOUBLE
2751 || memory_operand (operands[0], XFmode))"
2752 {
2753 switch (which_alternative)
2754 {
2755 case 0:
2756 return output_387_reg_move (insn, operands);
2757
2758 case 1:
2759 /* There is no non-popping store to memory for XFmode. So if
2760 we need one, follow the store with a load. */
2761 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2762 return "fstp%z0\t%y0\;fld%z0\t%y0";
2763 else
2764 return "fstp%z0\t%y0";
2765
2766 case 2:
2767 return standard_80387_constant_opcode (operands[1]);
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 "!optimize_size
2781 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2782 && (reload_in_progress || reload_completed
2783 || GET_CODE (operands[1]) != CONST_DOUBLE
2784 || memory_operand (operands[0], XFmode))"
2785 {
2786 switch (which_alternative)
2787 {
2788 case 0:
2789 return output_387_reg_move (insn, operands);
2790
2791 case 1:
2792 /* There is no non-popping store to memory for XFmode. So if
2793 we need one, follow the store with a load. */
2794 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2795 return "fstp%z0\t%y0\;fld%z0\t%y0";
2796 else
2797 return "fstp%z0\t%y0";
2798
2799 case 2:
2800 return standard_80387_constant_opcode (operands[1]);
2801
2802 case 3: case 4:
2803 return "#";
2804 }
2805 abort();
2806 }
2807 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808 (set_attr "mode" "XF,XF,XF,SI,SI")])
2809
2810 (define_split
2811 [(set (match_operand 0 "nonimmediate_operand" "")
2812 (match_operand 1 "general_operand" ""))]
2813 "reload_completed
2814 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815 && GET_MODE (operands[0]) == XFmode
2816 && ! (ANY_FP_REG_P (operands[0]) ||
2817 (GET_CODE (operands[0]) == SUBREG
2818 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2819 && ! (ANY_FP_REG_P (operands[1]) ||
2820 (GET_CODE (operands[1]) == SUBREG
2821 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2822 [(const_int 0)]
2823 "ix86_split_long_move (operands); DONE;")
2824
2825 (define_split
2826 [(set (match_operand 0 "register_operand" "")
2827 (match_operand 1 "memory_operand" ""))]
2828 "reload_completed
2829 && GET_CODE (operands[1]) == MEM
2830 && (GET_MODE (operands[0]) == XFmode
2831 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2832 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2833 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2834 [(set (match_dup 0) (match_dup 1))]
2835 {
2836 rtx c = get_pool_constant (XEXP (operands[1], 0));
2837 rtx r = operands[0];
2838
2839 if (GET_CODE (r) == SUBREG)
2840 r = SUBREG_REG (r);
2841
2842 if (SSE_REG_P (r))
2843 {
2844 if (!standard_sse_constant_p (c))
2845 FAIL;
2846 }
2847 else if (FP_REG_P (r))
2848 {
2849 if (!standard_80387_constant_p (c))
2850 FAIL;
2851 }
2852 else if (MMX_REG_P (r))
2853 FAIL;
2854
2855 operands[1] = c;
2856 })
2857
2858 (define_insn "swapxf"
2859 [(set (match_operand:XF 0 "register_operand" "+f")
2860 (match_operand:XF 1 "register_operand" "+f"))
2861 (set (match_dup 1)
2862 (match_dup 0))]
2863 ""
2864 {
2865 if (STACK_TOP_P (operands[0]))
2866 return "fxch\t%1";
2867 else
2868 return "fxch\t%0";
2869 }
2870 [(set_attr "type" "fxch")
2871 (set_attr "mode" "XF")])
2872 \f
2873 ;; Zero extension instructions
2874
2875 (define_expand "zero_extendhisi2"
2876 [(set (match_operand:SI 0 "register_operand" "")
2877 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2878 ""
2879 {
2880 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2881 {
2882 operands[1] = force_reg (HImode, operands[1]);
2883 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2884 DONE;
2885 }
2886 })
2887
2888 (define_insn "zero_extendhisi2_and"
2889 [(set (match_operand:SI 0 "register_operand" "=r")
2890 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2891 (clobber (reg:CC 17))]
2892 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2893 "#"
2894 [(set_attr "type" "alu1")
2895 (set_attr "mode" "SI")])
2896
2897 (define_split
2898 [(set (match_operand:SI 0 "register_operand" "")
2899 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2900 (clobber (reg:CC 17))]
2901 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2902 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2903 (clobber (reg:CC 17))])]
2904 "")
2905
2906 (define_insn "*zero_extendhisi2_movzwl"
2907 [(set (match_operand:SI 0 "register_operand" "=r")
2908 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2909 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2910 "movz{wl|x}\t{%1, %0|%0, %1}"
2911 [(set_attr "type" "imovx")
2912 (set_attr "mode" "SI")])
2913
2914 (define_expand "zero_extendqihi2"
2915 [(parallel
2916 [(set (match_operand:HI 0 "register_operand" "")
2917 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2918 (clobber (reg:CC 17))])]
2919 ""
2920 "")
2921
2922 (define_insn "*zero_extendqihi2_and"
2923 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2924 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2925 (clobber (reg:CC 17))]
2926 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2927 "#"
2928 [(set_attr "type" "alu1")
2929 (set_attr "mode" "HI")])
2930
2931 (define_insn "*zero_extendqihi2_movzbw_and"
2932 [(set (match_operand:HI 0 "register_operand" "=r,r")
2933 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2934 (clobber (reg:CC 17))]
2935 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2936 "#"
2937 [(set_attr "type" "imovx,alu1")
2938 (set_attr "mode" "HI")])
2939
2940 (define_insn "*zero_extendqihi2_movzbw"
2941 [(set (match_operand:HI 0 "register_operand" "=r")
2942 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2943 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2944 "movz{bw|x}\t{%1, %0|%0, %1}"
2945 [(set_attr "type" "imovx")
2946 (set_attr "mode" "HI")])
2947
2948 ;; For the movzbw case strip only the clobber
2949 (define_split
2950 [(set (match_operand:HI 0 "register_operand" "")
2951 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2952 (clobber (reg:CC 17))]
2953 "reload_completed
2954 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2955 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2956 [(set (match_operand:HI 0 "register_operand" "")
2957 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2958
2959 ;; When source and destination does not overlap, clear destination
2960 ;; first and then do the movb
2961 (define_split
2962 [(set (match_operand:HI 0 "register_operand" "")
2963 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2964 (clobber (reg:CC 17))]
2965 "reload_completed
2966 && ANY_QI_REG_P (operands[0])
2967 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2968 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2969 [(set (match_dup 0) (const_int 0))
2970 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2971 "operands[2] = gen_lowpart (QImode, operands[0]);")
2972
2973 ;; Rest is handled by single and.
2974 (define_split
2975 [(set (match_operand:HI 0 "register_operand" "")
2976 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2977 (clobber (reg:CC 17))]
2978 "reload_completed
2979 && true_regnum (operands[0]) == true_regnum (operands[1])"
2980 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2981 (clobber (reg:CC 17))])]
2982 "")
2983
2984 (define_expand "zero_extendqisi2"
2985 [(parallel
2986 [(set (match_operand:SI 0 "register_operand" "")
2987 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2988 (clobber (reg:CC 17))])]
2989 ""
2990 "")
2991
2992 (define_insn "*zero_extendqisi2_and"
2993 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2994 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2995 (clobber (reg:CC 17))]
2996 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997 "#"
2998 [(set_attr "type" "alu1")
2999 (set_attr "mode" "SI")])
3000
3001 (define_insn "*zero_extendqisi2_movzbw_and"
3002 [(set (match_operand:SI 0 "register_operand" "=r,r")
3003 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3004 (clobber (reg:CC 17))]
3005 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3006 "#"
3007 [(set_attr "type" "imovx,alu1")
3008 (set_attr "mode" "SI")])
3009
3010 (define_insn "*zero_extendqisi2_movzbw"
3011 [(set (match_operand:SI 0 "register_operand" "=r")
3012 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3013 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3014 "movz{bl|x}\t{%1, %0|%0, %1}"
3015 [(set_attr "type" "imovx")
3016 (set_attr "mode" "SI")])
3017
3018 ;; For the movzbl case strip only the clobber
3019 (define_split
3020 [(set (match_operand:SI 0 "register_operand" "")
3021 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3022 (clobber (reg:CC 17))]
3023 "reload_completed
3024 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3025 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3026 [(set (match_dup 0)
3027 (zero_extend:SI (match_dup 1)))])
3028
3029 ;; When source and destination does not overlap, clear destination
3030 ;; first and then do the movb
3031 (define_split
3032 [(set (match_operand:SI 0 "register_operand" "")
3033 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3034 (clobber (reg:CC 17))]
3035 "reload_completed
3036 && ANY_QI_REG_P (operands[0])
3037 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3038 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3039 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3040 [(set (match_dup 0) (const_int 0))
3041 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3042 "operands[2] = gen_lowpart (QImode, operands[0]);")
3043
3044 ;; Rest is handled by single and.
3045 (define_split
3046 [(set (match_operand:SI 0 "register_operand" "")
3047 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3048 (clobber (reg:CC 17))]
3049 "reload_completed
3050 && true_regnum (operands[0]) == true_regnum (operands[1])"
3051 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3052 (clobber (reg:CC 17))])]
3053 "")
3054
3055 ;; %%% Kill me once multi-word ops are sane.
3056 (define_expand "zero_extendsidi2"
3057 [(set (match_operand:DI 0 "register_operand" "=r")
3058 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3059 ""
3060 "if (!TARGET_64BIT)
3061 {
3062 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3063 DONE;
3064 }
3065 ")
3066
3067 (define_insn "zero_extendsidi2_32"
3068 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3069 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3070 (clobber (reg:CC 17))]
3071 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3072 "@
3073 #
3074 #
3075 #
3076 movd\t{%1, %0|%0, %1}
3077 movd\t{%1, %0|%0, %1}"
3078 [(set_attr "mode" "SI,SI,SI,DI,TI")
3079 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3080
3081 (define_insn "*zero_extendsidi2_32_1"
3082 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3083 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3084 (clobber (reg:CC 17))]
3085 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3086 "@
3087 #
3088 #
3089 #
3090 movd\t{%1, %0|%0, %1}
3091 movd\t{%1, %0|%0, %1}"
3092 [(set_attr "mode" "SI,SI,SI,DI,TI")
3093 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3094
3095 (define_insn "zero_extendsidi2_rex64"
3096 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3097 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3098 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3099 "@
3100 mov\t{%k1, %k0|%k0, %k1}
3101 #
3102 movd\t{%1, %0|%0, %1}
3103 movd\t{%1, %0|%0, %1}"
3104 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3105 (set_attr "mode" "SI,DI,DI,TI")])
3106
3107 (define_insn "*zero_extendsidi2_rex64_1"
3108 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3109 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3110 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3111 "@
3112 mov\t{%k1, %k0|%k0, %k1}
3113 #
3114 movd\t{%1, %0|%0, %1}
3115 movd\t{%1, %0|%0, %1}"
3116 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3117 (set_attr "mode" "SI,DI,SI,SI")])
3118
3119 (define_split
3120 [(set (match_operand:DI 0 "memory_operand" "")
3121 (zero_extend:DI (match_dup 0)))]
3122 "TARGET_64BIT"
3123 [(set (match_dup 4) (const_int 0))]
3124 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3125
3126 (define_split
3127 [(set (match_operand:DI 0 "register_operand" "")
3128 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3129 (clobber (reg:CC 17))]
3130 "!TARGET_64BIT && reload_completed
3131 && true_regnum (operands[0]) == true_regnum (operands[1])"
3132 [(set (match_dup 4) (const_int 0))]
3133 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3134
3135 (define_split
3136 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3137 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3138 (clobber (reg:CC 17))]
3139 "!TARGET_64BIT && reload_completed
3140 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3141 [(set (match_dup 3) (match_dup 1))
3142 (set (match_dup 4) (const_int 0))]
3143 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3144
3145 (define_insn "zero_extendhidi2"
3146 [(set (match_operand:DI 0 "register_operand" "=r,r")
3147 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3148 "TARGET_64BIT"
3149 "@
3150 movz{wl|x}\t{%1, %k0|%k0, %1}
3151 movz{wq|x}\t{%1, %0|%0, %1}"
3152 [(set_attr "type" "imovx")
3153 (set_attr "mode" "SI,DI")])
3154
3155 (define_insn "zero_extendqidi2"
3156 [(set (match_operand:DI 0 "register_operand" "=r,r")
3157 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3158 "TARGET_64BIT"
3159 "@
3160 movz{bl|x}\t{%1, %k0|%k0, %1}
3161 movz{bq|x}\t{%1, %0|%0, %1}"
3162 [(set_attr "type" "imovx")
3163 (set_attr "mode" "SI,DI")])
3164 \f
3165 ;; Sign extension instructions
3166
3167 (define_expand "extendsidi2"
3168 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3169 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3170 (clobber (reg:CC 17))
3171 (clobber (match_scratch:SI 2 ""))])]
3172 ""
3173 {
3174 if (TARGET_64BIT)
3175 {
3176 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3177 DONE;
3178 }
3179 })
3180
3181 (define_insn "*extendsidi2_1"
3182 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3183 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3184 (clobber (reg:CC 17))
3185 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3186 "!TARGET_64BIT"
3187 "#")
3188
3189 (define_insn "extendsidi2_rex64"
3190 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3191 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3192 "TARGET_64BIT"
3193 "@
3194 {cltq|cdqe}
3195 movs{lq|x}\t{%1,%0|%0, %1}"
3196 [(set_attr "type" "imovx")
3197 (set_attr "mode" "DI")
3198 (set_attr "prefix_0f" "0")
3199 (set_attr "modrm" "0,1")])
3200
3201 (define_insn "extendhidi2"
3202 [(set (match_operand:DI 0 "register_operand" "=r")
3203 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3204 "TARGET_64BIT"
3205 "movs{wq|x}\t{%1,%0|%0, %1}"
3206 [(set_attr "type" "imovx")
3207 (set_attr "mode" "DI")])
3208
3209 (define_insn "extendqidi2"
3210 [(set (match_operand:DI 0 "register_operand" "=r")
3211 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3212 "TARGET_64BIT"
3213 "movs{bq|x}\t{%1,%0|%0, %1}"
3214 [(set_attr "type" "imovx")
3215 (set_attr "mode" "DI")])
3216
3217 ;; Extend to memory case when source register does die.
3218 (define_split
3219 [(set (match_operand:DI 0 "memory_operand" "")
3220 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3221 (clobber (reg:CC 17))
3222 (clobber (match_operand:SI 2 "register_operand" ""))]
3223 "(reload_completed
3224 && dead_or_set_p (insn, operands[1])
3225 && !reg_mentioned_p (operands[1], operands[0]))"
3226 [(set (match_dup 3) (match_dup 1))
3227 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3228 (clobber (reg:CC 17))])
3229 (set (match_dup 4) (match_dup 1))]
3230 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3231
3232 ;; Extend to memory case when source register does not die.
3233 (define_split
3234 [(set (match_operand:DI 0 "memory_operand" "")
3235 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236 (clobber (reg:CC 17))
3237 (clobber (match_operand:SI 2 "register_operand" ""))]
3238 "reload_completed"
3239 [(const_int 0)]
3240 {
3241 split_di (&operands[0], 1, &operands[3], &operands[4]);
3242
3243 emit_move_insn (operands[3], operands[1]);
3244
3245 /* Generate a cltd if possible and doing so it profitable. */
3246 if (true_regnum (operands[1]) == 0
3247 && true_regnum (operands[2]) == 1
3248 && (optimize_size || TARGET_USE_CLTD))
3249 {
3250 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3251 }
3252 else
3253 {
3254 emit_move_insn (operands[2], operands[1]);
3255 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3256 }
3257 emit_move_insn (operands[4], operands[2]);
3258 DONE;
3259 })
3260
3261 ;; Extend to register case. Optimize case where source and destination
3262 ;; registers match and cases where we can use cltd.
3263 (define_split
3264 [(set (match_operand:DI 0 "register_operand" "")
3265 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3266 (clobber (reg:CC 17))
3267 (clobber (match_scratch:SI 2 ""))]
3268 "reload_completed"
3269 [(const_int 0)]
3270 {
3271 split_di (&operands[0], 1, &operands[3], &operands[4]);
3272
3273 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3274 emit_move_insn (operands[3], operands[1]);
3275
3276 /* Generate a cltd if possible and doing so it profitable. */
3277 if (true_regnum (operands[3]) == 0
3278 && (optimize_size || TARGET_USE_CLTD))
3279 {
3280 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3281 DONE;
3282 }
3283
3284 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3285 emit_move_insn (operands[4], operands[1]);
3286
3287 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3288 DONE;
3289 })
3290
3291 (define_insn "extendhisi2"
3292 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3293 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3294 ""
3295 {
3296 switch (get_attr_prefix_0f (insn))
3297 {
3298 case 0:
3299 return "{cwtl|cwde}";
3300 default:
3301 return "movs{wl|x}\t{%1,%0|%0, %1}";
3302 }
3303 }
3304 [(set_attr "type" "imovx")
3305 (set_attr "mode" "SI")
3306 (set (attr "prefix_0f")
3307 ;; movsx is short decodable while cwtl is vector decoded.
3308 (if_then_else (and (eq_attr "cpu" "!k6")
3309 (eq_attr "alternative" "0"))
3310 (const_string "0")
3311 (const_string "1")))
3312 (set (attr "modrm")
3313 (if_then_else (eq_attr "prefix_0f" "0")
3314 (const_string "0")
3315 (const_string "1")))])
3316
3317 (define_insn "*extendhisi2_zext"
3318 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3319 (zero_extend:DI
3320 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3321 "TARGET_64BIT"
3322 {
3323 switch (get_attr_prefix_0f (insn))
3324 {
3325 case 0:
3326 return "{cwtl|cwde}";
3327 default:
3328 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3329 }
3330 }
3331 [(set_attr "type" "imovx")
3332 (set_attr "mode" "SI")
3333 (set (attr "prefix_0f")
3334 ;; movsx is short decodable while cwtl is vector decoded.
3335 (if_then_else (and (eq_attr "cpu" "!k6")
3336 (eq_attr "alternative" "0"))
3337 (const_string "0")
3338 (const_string "1")))
3339 (set (attr "modrm")
3340 (if_then_else (eq_attr "prefix_0f" "0")
3341 (const_string "0")
3342 (const_string "1")))])
3343
3344 (define_insn "extendqihi2"
3345 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3346 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3347 ""
3348 {
3349 switch (get_attr_prefix_0f (insn))
3350 {
3351 case 0:
3352 return "{cbtw|cbw}";
3353 default:
3354 return "movs{bw|x}\t{%1,%0|%0, %1}";
3355 }
3356 }
3357 [(set_attr "type" "imovx")
3358 (set_attr "mode" "HI")
3359 (set (attr "prefix_0f")
3360 ;; movsx is short decodable while cwtl is vector decoded.
3361 (if_then_else (and (eq_attr "cpu" "!k6")
3362 (eq_attr "alternative" "0"))
3363 (const_string "0")
3364 (const_string "1")))
3365 (set (attr "modrm")
3366 (if_then_else (eq_attr "prefix_0f" "0")
3367 (const_string "0")
3368 (const_string "1")))])
3369
3370 (define_insn "extendqisi2"
3371 [(set (match_operand:SI 0 "register_operand" "=r")
3372 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3373 ""
3374 "movs{bl|x}\t{%1,%0|%0, %1}"
3375 [(set_attr "type" "imovx")
3376 (set_attr "mode" "SI")])
3377
3378 (define_insn "*extendqisi2_zext"
3379 [(set (match_operand:DI 0 "register_operand" "=r")
3380 (zero_extend:DI
3381 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3382 "TARGET_64BIT"
3383 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3384 [(set_attr "type" "imovx")
3385 (set_attr "mode" "SI")])
3386 \f
3387 ;; Conversions between float and double.
3388
3389 ;; These are all no-ops in the model used for the 80387. So just
3390 ;; emit moves.
3391
3392 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3393 (define_insn "*dummy_extendsfdf2"
3394 [(set (match_operand:DF 0 "push_operand" "=<")
3395 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3396 "0"
3397 "#")
3398
3399 (define_split
3400 [(set (match_operand:DF 0 "push_operand" "")
3401 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3402 "!TARGET_64BIT"
3403 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3404 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3405
3406 (define_split
3407 [(set (match_operand:DF 0 "push_operand" "")
3408 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3409 "TARGET_64BIT"
3410 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3411 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3412
3413 (define_insn "*dummy_extendsfxf2"
3414 [(set (match_operand:XF 0 "push_operand" "=<")
3415 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3416 "0"
3417 "#")
3418
3419 (define_split
3420 [(set (match_operand:XF 0 "push_operand" "")
3421 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3422 ""
3423 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3424 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3425 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3426
3427 (define_split
3428 [(set (match_operand:XF 0 "push_operand" "")
3429 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3430 "TARGET_64BIT"
3431 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3432 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3433 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3434
3435 (define_split
3436 [(set (match_operand:XF 0 "push_operand" "")
3437 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3438 ""
3439 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3440 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3441 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3442
3443 (define_split
3444 [(set (match_operand:XF 0 "push_operand" "")
3445 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3446 "TARGET_64BIT"
3447 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3448 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3449 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3450
3451 (define_expand "extendsfdf2"
3452 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3453 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3454 "TARGET_80387 || TARGET_SSE2"
3455 {
3456 /* ??? Needed for compress_float_constant since all fp constants
3457 are LEGITIMATE_CONSTANT_P. */
3458 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3459 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3460 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3461 operands[1] = force_reg (SFmode, operands[1]);
3462 })
3463
3464 (define_insn "*extendsfdf2_1"
3465 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3466 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3467 "(TARGET_80387 || TARGET_SSE2)
3468 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3469 {
3470 switch (which_alternative)
3471 {
3472 case 0:
3473 return output_387_reg_move (insn, operands);
3474
3475 case 1:
3476 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3477 return "fstp%z0\t%y0";
3478 else
3479 return "fst%z0\t%y0";
3480
3481 case 2:
3482 return "cvtss2sd\t{%1, %0|%0, %1}";
3483
3484 default:
3485 abort ();
3486 }
3487 }
3488 [(set_attr "type" "fmov,fmov,ssecvt")
3489 (set_attr "mode" "SF,XF,DF")])
3490
3491 (define_insn "*extendsfdf2_1_sse_only"
3492 [(set (match_operand:DF 0 "register_operand" "=Y")
3493 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3494 "!TARGET_80387 && TARGET_SSE2
3495 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3496 "cvtss2sd\t{%1, %0|%0, %1}"
3497 [(set_attr "type" "ssecvt")
3498 (set_attr "mode" "DF")])
3499
3500 (define_expand "extendsfxf2"
3501 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3502 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3503 "TARGET_80387"
3504 {
3505 /* ??? Needed for compress_float_constant since all fp constants
3506 are LEGITIMATE_CONSTANT_P. */
3507 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3508 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3509 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3510 operands[1] = force_reg (SFmode, operands[1]);
3511 })
3512
3513 (define_insn "*extendsfxf2_1"
3514 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3515 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3516 "TARGET_80387
3517 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3518 {
3519 switch (which_alternative)
3520 {
3521 case 0:
3522 return output_387_reg_move (insn, operands);
3523
3524 case 1:
3525 /* There is no non-popping store to memory for XFmode. So if
3526 we need one, follow the store with a load. */
3527 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3528 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3529 else
3530 return "fstp%z0\t%y0";
3531
3532 default:
3533 abort ();
3534 }
3535 }
3536 [(set_attr "type" "fmov")
3537 (set_attr "mode" "SF,XF")])
3538
3539 (define_expand "extenddfxf2"
3540 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3541 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3542 "TARGET_80387"
3543 {
3544 /* ??? Needed for compress_float_constant since all fp constants
3545 are LEGITIMATE_CONSTANT_P. */
3546 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3547 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3548 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3549 operands[1] = force_reg (DFmode, operands[1]);
3550 })
3551
3552 (define_insn "*extenddfxf2_1"
3553 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3554 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3555 "TARGET_80387
3556 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557 {
3558 switch (which_alternative)
3559 {
3560 case 0:
3561 return output_387_reg_move (insn, operands);
3562
3563 case 1:
3564 /* There is no non-popping store to memory for XFmode. So if
3565 we need one, follow the store with a load. */
3566 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3567 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3568 else
3569 return "fstp%z0\t%y0";
3570
3571 default:
3572 abort ();
3573 }
3574 }
3575 [(set_attr "type" "fmov")
3576 (set_attr "mode" "DF,XF")])
3577
3578 ;; %%% This seems bad bad news.
3579 ;; This cannot output into an f-reg because there is no way to be sure
3580 ;; of truncating in that case. Otherwise this is just like a simple move
3581 ;; insn. So we pretend we can output to a reg in order to get better
3582 ;; register preferencing, but we really use a stack slot.
3583
3584 (define_expand "truncdfsf2"
3585 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3586 (float_truncate:SF
3587 (match_operand:DF 1 "register_operand" "")))
3588 (clobber (match_dup 2))])]
3589 "TARGET_80387 || TARGET_SSE2"
3590 "
3591 if (!TARGET_80387)
3592 {
3593 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3594 DONE;
3595 }
3596 else if (flag_unsafe_math_optimizations)
3597 {
3598 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3599 emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3600 if (reg != operands[0])
3601 emit_move_insn (operands[0], reg);
3602 DONE;
3603 }
3604 else
3605 operands[2] = assign_386_stack_local (SFmode, 0);
3606 ")
3607
3608 (define_insn "truncdfsf2_noop"
3609 [(set (match_operand:SF 0 "register_operand" "=f")
3610 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3611 "TARGET_80387 && flag_unsafe_math_optimizations"
3612 {
3613 return output_387_reg_move (insn, operands);
3614 }
3615 [(set_attr "type" "fmov")
3616 (set_attr "mode" "SF")])
3617
3618 (define_insn "*truncdfsf2_1"
3619 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3620 (float_truncate:SF
3621 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3622 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3623 "TARGET_80387 && !TARGET_SSE2"
3624 {
3625 switch (which_alternative)
3626 {
3627 case 0:
3628 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3629 return "fstp%z0\t%y0";
3630 else
3631 return "fst%z0\t%y0";
3632 default:
3633 abort ();
3634 }
3635 }
3636 [(set_attr "type" "fmov,multi,multi,multi")
3637 (set_attr "mode" "SF,SF,SF,SF")])
3638
3639 (define_insn "*truncdfsf2_1_sse"
3640 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3641 (float_truncate:SF
3642 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3643 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3644 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3645 {
3646 switch (which_alternative)
3647 {
3648 case 0:
3649 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3650 return "fstp%z0\t%y0";
3651 else
3652 return "fst%z0\t%y0";
3653 case 4:
3654 return "#";
3655 default:
3656 abort ();
3657 }
3658 }
3659 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3660 (set_attr "mode" "SF,SF,SF,SF,DF")])
3661
3662 (define_insn "*truncdfsf2_1_sse_nooverlap"
3663 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3664 (float_truncate:SF
3665 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3666 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3667 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3668 {
3669 switch (which_alternative)
3670 {
3671 case 0:
3672 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3673 return "fstp%z0\t%y0";
3674 else
3675 return "fst%z0\t%y0";
3676 case 4:
3677 return "#";
3678 default:
3679 abort ();
3680 }
3681 }
3682 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3683 (set_attr "mode" "SF,SF,SF,SF,DF")])
3684
3685 (define_insn "*truncdfsf2_2"
3686 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3687 (float_truncate:SF
3688 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3689 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3690 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3691 {
3692 switch (which_alternative)
3693 {
3694 case 0:
3695 case 1:
3696 return "cvtsd2ss\t{%1, %0|%0, %1}";
3697 case 2:
3698 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3699 return "fstp%z0\t%y0";
3700 else
3701 return "fst%z0\t%y0";
3702 default:
3703 abort ();
3704 }
3705 }
3706 [(set_attr "type" "ssecvt,ssecvt,fmov")
3707 (set_attr "athlon_decode" "vector,double,*")
3708 (set_attr "mode" "SF,SF,SF")])
3709
3710 (define_insn "*truncdfsf2_2_nooverlap"
3711 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3712 (float_truncate:SF
3713 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3714 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3715 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3716 {
3717 switch (which_alternative)
3718 {
3719 case 0:
3720 return "#";
3721 case 1:
3722 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3723 return "fstp%z0\t%y0";
3724 else
3725 return "fst%z0\t%y0";
3726 default:
3727 abort ();
3728 }
3729 }
3730 [(set_attr "type" "ssecvt,fmov")
3731 (set_attr "mode" "DF,SF")])
3732
3733 (define_insn "*truncdfsf2_3"
3734 [(set (match_operand:SF 0 "memory_operand" "=m")
3735 (float_truncate:SF
3736 (match_operand:DF 1 "register_operand" "f")))]
3737 "TARGET_80387"
3738 {
3739 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3740 return "fstp%z0\t%y0";
3741 else
3742 return "fst%z0\t%y0";
3743 }
3744 [(set_attr "type" "fmov")
3745 (set_attr "mode" "SF")])
3746
3747 (define_insn "truncdfsf2_sse_only"
3748 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3749 (float_truncate:SF
3750 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3751 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3752 "cvtsd2ss\t{%1, %0|%0, %1}"
3753 [(set_attr "type" "ssecvt")
3754 (set_attr "athlon_decode" "vector,double")
3755 (set_attr "mode" "SF")])
3756
3757 (define_insn "*truncdfsf2_sse_only_nooverlap"
3758 [(set (match_operand:SF 0 "register_operand" "=&Y")
3759 (float_truncate:SF
3760 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3761 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3762 "#"
3763 [(set_attr "type" "ssecvt")
3764 (set_attr "mode" "DF")])
3765
3766 (define_split
3767 [(set (match_operand:SF 0 "memory_operand" "")
3768 (float_truncate:SF
3769 (match_operand:DF 1 "register_operand" "")))
3770 (clobber (match_operand:SF 2 "memory_operand" ""))]
3771 "TARGET_80387"
3772 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3773 "")
3774
3775 ; Avoid possible reformatting penalty on the destination by first
3776 ; zeroing it out
3777 (define_split
3778 [(set (match_operand:SF 0 "register_operand" "")
3779 (float_truncate:SF
3780 (match_operand:DF 1 "nonimmediate_operand" "")))
3781 (clobber (match_operand 2 "" ""))]
3782 "TARGET_80387 && reload_completed
3783 && SSE_REG_P (operands[0])
3784 && !STACK_REG_P (operands[1])"
3785 [(const_int 0)]
3786 {
3787 rtx src, dest;
3788 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3789 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3790 else
3791 {
3792 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3793 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3794 /* simplify_gen_subreg refuses to widen memory references. */
3795 if (GET_CODE (src) == SUBREG)
3796 alter_subreg (&src);
3797 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3798 abort ();
3799 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3800 emit_insn (gen_cvtsd2ss (dest, dest, src));
3801 }
3802 DONE;
3803 })
3804
3805 (define_split
3806 [(set (match_operand:SF 0 "register_operand" "")
3807 (float_truncate:SF
3808 (match_operand:DF 1 "nonimmediate_operand" "")))]
3809 "TARGET_80387 && reload_completed
3810 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3811 [(const_int 0)]
3812 {
3813 rtx src, dest;
3814 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3815 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3816 /* simplify_gen_subreg refuses to widen memory references. */
3817 if (GET_CODE (src) == SUBREG)
3818 alter_subreg (&src);
3819 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3820 abort ();
3821 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3822 emit_insn (gen_cvtsd2ss (dest, dest, src));
3823 DONE;
3824 })
3825
3826 (define_split
3827 [(set (match_operand:SF 0 "register_operand" "")
3828 (float_truncate:SF
3829 (match_operand:DF 1 "fp_register_operand" "")))
3830 (clobber (match_operand:SF 2 "memory_operand" ""))]
3831 "TARGET_80387 && reload_completed"
3832 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3833 (set (match_dup 0) (match_dup 2))]
3834 "")
3835
3836 (define_expand "truncxfsf2"
3837 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3838 (float_truncate:SF
3839 (match_operand:XF 1 "register_operand" "")))
3840 (clobber (match_dup 2))])]
3841 "TARGET_80387"
3842 "
3843 if (flag_unsafe_math_optimizations)
3844 {
3845 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3846 emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3847 if (reg != operands[0])
3848 emit_move_insn (operands[0], reg);
3849 DONE;
3850 }
3851 else
3852 operands[2] = assign_386_stack_local (SFmode, 0);
3853 ")
3854
3855 (define_insn "truncxfsf2_noop"
3856 [(set (match_operand:SF 0 "register_operand" "=f")
3857 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3858 "TARGET_80387 && flag_unsafe_math_optimizations"
3859 {
3860 return output_387_reg_move (insn, operands);
3861 }
3862 [(set_attr "type" "fmov")
3863 (set_attr "mode" "SF")])
3864
3865 (define_insn "*truncxfsf2_1"
3866 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3867 (float_truncate:SF
3868 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3869 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3870 "TARGET_80387"
3871 {
3872 switch (which_alternative)
3873 {
3874 case 0:
3875 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876 return "fstp%z0\t%y0";
3877 else
3878 return "fst%z0\t%y0";
3879 default:
3880 abort();
3881 }
3882 }
3883 [(set_attr "type" "fmov,multi,multi,multi")
3884 (set_attr "mode" "SF")])
3885
3886 (define_insn "*truncxfsf2_2"
3887 [(set (match_operand:SF 0 "memory_operand" "=m")
3888 (float_truncate:SF
3889 (match_operand:XF 1 "register_operand" "f")))]
3890 "TARGET_80387"
3891 {
3892 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3893 return "fstp%z0\t%y0";
3894 else
3895 return "fst%z0\t%y0";
3896 }
3897 [(set_attr "type" "fmov")
3898 (set_attr "mode" "SF")])
3899
3900 (define_split
3901 [(set (match_operand:SF 0 "memory_operand" "")
3902 (float_truncate:SF
3903 (match_operand:XF 1 "register_operand" "")))
3904 (clobber (match_operand:SF 2 "memory_operand" ""))]
3905 "TARGET_80387"
3906 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3907 "")
3908
3909 (define_split
3910 [(set (match_operand:SF 0 "register_operand" "")
3911 (float_truncate:SF
3912 (match_operand:XF 1 "register_operand" "")))
3913 (clobber (match_operand:SF 2 "memory_operand" ""))]
3914 "TARGET_80387 && reload_completed"
3915 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3916 (set (match_dup 0) (match_dup 2))]
3917 "")
3918
3919 (define_expand "truncxfdf2"
3920 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3921 (float_truncate:DF
3922 (match_operand:XF 1 "register_operand" "")))
3923 (clobber (match_dup 2))])]
3924 "TARGET_80387"
3925 "
3926 if (flag_unsafe_math_optimizations)
3927 {
3928 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3929 emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3930 if (reg != operands[0])
3931 emit_move_insn (operands[0], reg);
3932 DONE;
3933 }
3934 else
3935 operands[2] = assign_386_stack_local (DFmode, 0);
3936 ")
3937
3938 (define_insn "truncxfdf2_noop"
3939 [(set (match_operand:DF 0 "register_operand" "=f")
3940 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3941 "TARGET_80387 && flag_unsafe_math_optimizations"
3942 {
3943 return output_387_reg_move (insn, operands);
3944 }
3945 [(set_attr "type" "fmov")
3946 (set_attr "mode" "DF")])
3947
3948 (define_insn "*truncxfdf2_1"
3949 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3950 (float_truncate:DF
3951 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3952 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3953 "TARGET_80387"
3954 {
3955 switch (which_alternative)
3956 {
3957 case 0:
3958 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3959 return "fstp%z0\t%y0";
3960 else
3961 return "fst%z0\t%y0";
3962 default:
3963 abort();
3964 }
3965 abort ();
3966 }
3967 [(set_attr "type" "fmov,multi,multi,multi")
3968 (set_attr "mode" "DF")])
3969
3970 (define_insn "*truncxfdf2_2"
3971 [(set (match_operand:DF 0 "memory_operand" "=m")
3972 (float_truncate:DF
3973 (match_operand:XF 1 "register_operand" "f")))]
3974 "TARGET_80387"
3975 {
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3978 else
3979 return "fst%z0\t%y0";
3980 }
3981 [(set_attr "type" "fmov")
3982 (set_attr "mode" "DF")])
3983
3984 (define_split
3985 [(set (match_operand:DF 0 "memory_operand" "")
3986 (float_truncate:DF
3987 (match_operand:XF 1 "register_operand" "")))
3988 (clobber (match_operand:DF 2 "memory_operand" ""))]
3989 "TARGET_80387"
3990 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3991 "")
3992
3993 (define_split
3994 [(set (match_operand:DF 0 "register_operand" "")
3995 (float_truncate:DF
3996 (match_operand:XF 1 "register_operand" "")))
3997 (clobber (match_operand:DF 2 "memory_operand" ""))]
3998 "TARGET_80387 && reload_completed"
3999 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4000 (set (match_dup 0) (match_dup 2))]
4001 "")
4002
4003 \f
4004 ;; %%% Break up all these bad boys.
4005
4006 ;; Signed conversion to DImode.
4007
4008 (define_expand "fix_truncxfdi2"
4009 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4010 (fix:DI (match_operand:XF 1 "register_operand" "")))
4011 (clobber (reg:CC 17))])]
4012 "TARGET_80387"
4013 "")
4014
4015 (define_expand "fix_truncdfdi2"
4016 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4017 (fix:DI (match_operand:DF 1 "register_operand" "")))
4018 (clobber (reg:CC 17))])]
4019 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4020 {
4021 if (TARGET_64BIT && TARGET_SSE2)
4022 {
4023 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4024 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4025 if (out != operands[0])
4026 emit_move_insn (operands[0], out);
4027 DONE;
4028 }
4029 })
4030
4031 (define_expand "fix_truncsfdi2"
4032 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4033 (fix:DI (match_operand:SF 1 "register_operand" "")))
4034 (clobber (reg:CC 17))])]
4035 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4036 {
4037 if (TARGET_SSE && TARGET_64BIT)
4038 {
4039 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4040 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4041 if (out != operands[0])
4042 emit_move_insn (operands[0], out);
4043 DONE;
4044 }
4045 })
4046
4047 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4048 ;; of the machinery.
4049 (define_insn_and_split "*fix_truncdi_1"
4050 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4051 (fix:DI (match_operand 1 "register_operand" "f,f")))
4052 (clobber (reg:CC 17))]
4053 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4054 && !reload_completed && !reload_in_progress
4055 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4056 "#"
4057 "&& 1"
4058 [(const_int 0)]
4059 {
4060 ix86_optimize_mode_switching = 1;
4061 operands[2] = assign_386_stack_local (HImode, 1);
4062 operands[3] = assign_386_stack_local (HImode, 2);
4063 if (memory_operand (operands[0], VOIDmode))
4064 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4065 operands[2], operands[3]));
4066 else
4067 {
4068 operands[4] = assign_386_stack_local (DImode, 0);
4069 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4070 operands[2], operands[3],
4071 operands[4]));
4072 }
4073 DONE;
4074 }
4075 [(set_attr "type" "fistp")
4076 (set_attr "mode" "DI")])
4077
4078 (define_insn "fix_truncdi_nomemory"
4079 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4080 (fix:DI (match_operand 1 "register_operand" "f,f")))
4081 (use (match_operand:HI 2 "memory_operand" "m,m"))
4082 (use (match_operand:HI 3 "memory_operand" "m,m"))
4083 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4084 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4085 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4086 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4087 "#"
4088 [(set_attr "type" "fistp")
4089 (set_attr "mode" "DI")])
4090
4091 (define_insn "fix_truncdi_memory"
4092 [(set (match_operand:DI 0 "memory_operand" "=m")
4093 (fix:DI (match_operand 1 "register_operand" "f")))
4094 (use (match_operand:HI 2 "memory_operand" "m"))
4095 (use (match_operand:HI 3 "memory_operand" "m"))
4096 (clobber (match_scratch:DF 4 "=&1f"))]
4097 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4098 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4099 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4100 [(set_attr "type" "fistp")
4101 (set_attr "mode" "DI")])
4102
4103 (define_split
4104 [(set (match_operand:DI 0 "register_operand" "")
4105 (fix:DI (match_operand 1 "register_operand" "")))
4106 (use (match_operand:HI 2 "memory_operand" ""))
4107 (use (match_operand:HI 3 "memory_operand" ""))
4108 (clobber (match_operand:DI 4 "memory_operand" ""))
4109 (clobber (match_scratch 5 ""))]
4110 "reload_completed"
4111 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4112 (use (match_dup 2))
4113 (use (match_dup 3))
4114 (clobber (match_dup 5))])
4115 (set (match_dup 0) (match_dup 4))]
4116 "")
4117
4118 (define_split
4119 [(set (match_operand:DI 0 "memory_operand" "")
4120 (fix:DI (match_operand 1 "register_operand" "")))
4121 (use (match_operand:HI 2 "memory_operand" ""))
4122 (use (match_operand:HI 3 "memory_operand" ""))
4123 (clobber (match_operand:DI 4 "memory_operand" ""))
4124 (clobber (match_scratch 5 ""))]
4125 "reload_completed"
4126 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4127 (use (match_dup 2))
4128 (use (match_dup 3))
4129 (clobber (match_dup 5))])]
4130 "")
4131
4132 ;; When SSE available, it is always faster to use it!
4133 (define_insn "fix_truncsfdi_sse"
4134 [(set (match_operand:DI 0 "register_operand" "=r,r")
4135 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4136 "TARGET_64BIT && TARGET_SSE"
4137 "cvttss2si{q}\t{%1, %0|%0, %1}"
4138 [(set_attr "type" "sseicvt")
4139 (set_attr "mode" "SF")
4140 (set_attr "athlon_decode" "double,vector")])
4141
4142 ;; Avoid vector decoded form of the instruction.
4143 (define_peephole2
4144 [(match_scratch:SF 2 "x")
4145 (set (match_operand:DI 0 "register_operand" "")
4146 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4147 "TARGET_K8 && !optimize_size"
4148 [(set (match_dup 2) (match_dup 1))
4149 (set (match_dup 0) (fix:DI (match_dup 2)))]
4150 "")
4151
4152 (define_insn "fix_truncdfdi_sse"
4153 [(set (match_operand:DI 0 "register_operand" "=r,r")
4154 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4155 "TARGET_64BIT && TARGET_SSE2"
4156 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4157 [(set_attr "type" "sseicvt,sseicvt")
4158 (set_attr "mode" "DF")
4159 (set_attr "athlon_decode" "double,vector")])
4160
4161 ;; Avoid vector decoded form of the instruction.
4162 (define_peephole2
4163 [(match_scratch:DF 2 "Y")
4164 (set (match_operand:DI 0 "register_operand" "")
4165 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4166 "TARGET_K8 && !optimize_size"
4167 [(set (match_dup 2) (match_dup 1))
4168 (set (match_dup 0) (fix:DI (match_dup 2)))]
4169 "")
4170
4171 ;; Signed conversion to SImode.
4172
4173 (define_expand "fix_truncxfsi2"
4174 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4175 (fix:SI (match_operand:XF 1 "register_operand" "")))
4176 (clobber (reg:CC 17))])]
4177 "TARGET_80387"
4178 "")
4179
4180 (define_expand "fix_truncdfsi2"
4181 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4182 (fix:SI (match_operand:DF 1 "register_operand" "")))
4183 (clobber (reg:CC 17))])]
4184 "TARGET_80387 || TARGET_SSE2"
4185 {
4186 if (TARGET_SSE2)
4187 {
4188 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4189 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4190 if (out != operands[0])
4191 emit_move_insn (operands[0], out);
4192 DONE;
4193 }
4194 })
4195
4196 (define_expand "fix_truncsfsi2"
4197 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4198 (fix:SI (match_operand:SF 1 "register_operand" "")))
4199 (clobber (reg:CC 17))])]
4200 "TARGET_80387 || TARGET_SSE"
4201 {
4202 if (TARGET_SSE)
4203 {
4204 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4205 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4206 if (out != operands[0])
4207 emit_move_insn (operands[0], out);
4208 DONE;
4209 }
4210 })
4211
4212 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4213 ;; of the machinery.
4214 (define_insn_and_split "*fix_truncsi_1"
4215 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4216 (fix:SI (match_operand 1 "register_operand" "f,f")))
4217 (clobber (reg:CC 17))]
4218 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4219 && !reload_completed && !reload_in_progress
4220 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4221 "#"
4222 "&& 1"
4223 [(const_int 0)]
4224 {
4225 ix86_optimize_mode_switching = 1;
4226 operands[2] = assign_386_stack_local (HImode, 1);
4227 operands[3] = assign_386_stack_local (HImode, 2);
4228 if (memory_operand (operands[0], VOIDmode))
4229 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4230 operands[2], operands[3]));
4231 else
4232 {
4233 operands[4] = assign_386_stack_local (SImode, 0);
4234 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4235 operands[2], operands[3],
4236 operands[4]));
4237 }
4238 DONE;
4239 }
4240 [(set_attr "type" "fistp")
4241 (set_attr "mode" "SI")])
4242
4243 (define_insn "fix_truncsi_nomemory"
4244 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4245 (fix:SI (match_operand 1 "register_operand" "f,f")))
4246 (use (match_operand:HI 2 "memory_operand" "m,m"))
4247 (use (match_operand:HI 3 "memory_operand" "m,m"))
4248 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4249 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4250 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4251 "#"
4252 [(set_attr "type" "fistp")
4253 (set_attr "mode" "SI")])
4254
4255 (define_insn "fix_truncsi_memory"
4256 [(set (match_operand:SI 0 "memory_operand" "=m")
4257 (fix:SI (match_operand 1 "register_operand" "f")))
4258 (use (match_operand:HI 2 "memory_operand" "m"))
4259 (use (match_operand:HI 3 "memory_operand" "m"))]
4260 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4261 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4262 "* return output_fix_trunc (insn, operands);"
4263 [(set_attr "type" "fistp")
4264 (set_attr "mode" "SI")])
4265
4266 ;; When SSE available, it is always faster to use it!
4267 (define_insn "fix_truncsfsi_sse"
4268 [(set (match_operand:SI 0 "register_operand" "=r,r")
4269 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4270 "TARGET_SSE"
4271 "cvttss2si\t{%1, %0|%0, %1}"
4272 [(set_attr "type" "sseicvt")
4273 (set_attr "mode" "DF")
4274 (set_attr "athlon_decode" "double,vector")])
4275
4276 ;; Avoid vector decoded form of the instruction.
4277 (define_peephole2
4278 [(match_scratch:SF 2 "x")
4279 (set (match_operand:SI 0 "register_operand" "")
4280 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4281 "TARGET_K8 && !optimize_size"
4282 [(set (match_dup 2) (match_dup 1))
4283 (set (match_dup 0) (fix:SI (match_dup 2)))]
4284 "")
4285
4286 (define_insn "fix_truncdfsi_sse"
4287 [(set (match_operand:SI 0 "register_operand" "=r,r")
4288 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4289 "TARGET_SSE2"
4290 "cvttsd2si\t{%1, %0|%0, %1}"
4291 [(set_attr "type" "sseicvt")
4292 (set_attr "mode" "DF")
4293 (set_attr "athlon_decode" "double,vector")])
4294
4295 ;; Avoid vector decoded form of the instruction.
4296 (define_peephole2
4297 [(match_scratch:DF 2 "Y")
4298 (set (match_operand:SI 0 "register_operand" "")
4299 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4300 "TARGET_K8 && !optimize_size"
4301 [(set (match_dup 2) (match_dup 1))
4302 (set (match_dup 0) (fix:SI (match_dup 2)))]
4303 "")
4304
4305 (define_split
4306 [(set (match_operand:SI 0 "register_operand" "")
4307 (fix:SI (match_operand 1 "register_operand" "")))
4308 (use (match_operand:HI 2 "memory_operand" ""))
4309 (use (match_operand:HI 3 "memory_operand" ""))
4310 (clobber (match_operand:SI 4 "memory_operand" ""))]
4311 "reload_completed"
4312 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4313 (use (match_dup 2))
4314 (use (match_dup 3))])
4315 (set (match_dup 0) (match_dup 4))]
4316 "")
4317
4318 (define_split
4319 [(set (match_operand:SI 0 "memory_operand" "")
4320 (fix:SI (match_operand 1 "register_operand" "")))
4321 (use (match_operand:HI 2 "memory_operand" ""))
4322 (use (match_operand:HI 3 "memory_operand" ""))
4323 (clobber (match_operand:SI 4 "memory_operand" ""))]
4324 "reload_completed"
4325 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4326 (use (match_dup 2))
4327 (use (match_dup 3))])]
4328 "")
4329
4330 ;; Signed conversion to HImode.
4331
4332 (define_expand "fix_truncxfhi2"
4333 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4334 (fix:HI (match_operand:XF 1 "register_operand" "")))
4335 (clobber (reg:CC 17))])]
4336 "TARGET_80387"
4337 "")
4338
4339 (define_expand "fix_truncdfhi2"
4340 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4341 (fix:HI (match_operand:DF 1 "register_operand" "")))
4342 (clobber (reg:CC 17))])]
4343 "TARGET_80387 && !TARGET_SSE2"
4344 "")
4345
4346 (define_expand "fix_truncsfhi2"
4347 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4348 (fix:HI (match_operand:SF 1 "register_operand" "")))
4349 (clobber (reg:CC 17))])]
4350 "TARGET_80387 && !TARGET_SSE"
4351 "")
4352
4353 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4354 ;; of the machinery.
4355 (define_insn_and_split "*fix_trunchi_1"
4356 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4357 (fix:HI (match_operand 1 "register_operand" "f,f")))
4358 (clobber (reg:CC 17))]
4359 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4360 && !reload_completed && !reload_in_progress
4361 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4362 "#"
4363 ""
4364 [(const_int 0)]
4365 {
4366 ix86_optimize_mode_switching = 1;
4367 operands[2] = assign_386_stack_local (HImode, 1);
4368 operands[3] = assign_386_stack_local (HImode, 2);
4369 if (memory_operand (operands[0], VOIDmode))
4370 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4371 operands[2], operands[3]));
4372 else
4373 {
4374 operands[4] = assign_386_stack_local (HImode, 0);
4375 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4376 operands[2], operands[3],
4377 operands[4]));
4378 }
4379 DONE;
4380 }
4381 [(set_attr "type" "fistp")
4382 (set_attr "mode" "HI")])
4383
4384 (define_insn "fix_trunchi_nomemory"
4385 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4386 (fix:HI (match_operand 1 "register_operand" "f,f")))
4387 (use (match_operand:HI 2 "memory_operand" "m,m"))
4388 (use (match_operand:HI 3 "memory_operand" "m,m"))
4389 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4390 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4391 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4392 "#"
4393 [(set_attr "type" "fistp")
4394 (set_attr "mode" "HI")])
4395
4396 (define_insn "fix_trunchi_memory"
4397 [(set (match_operand:HI 0 "memory_operand" "=m")
4398 (fix:HI (match_operand 1 "register_operand" "f")))
4399 (use (match_operand:HI 2 "memory_operand" "m"))
4400 (use (match_operand:HI 3 "memory_operand" "m"))]
4401 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4402 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4403 "* return output_fix_trunc (insn, operands);"
4404 [(set_attr "type" "fistp")
4405 (set_attr "mode" "HI")])
4406
4407 (define_split
4408 [(set (match_operand:HI 0 "memory_operand" "")
4409 (fix:HI (match_operand 1 "register_operand" "")))
4410 (use (match_operand:HI 2 "memory_operand" ""))
4411 (use (match_operand:HI 3 "memory_operand" ""))
4412 (clobber (match_operand:HI 4 "memory_operand" ""))]
4413 "reload_completed"
4414 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4415 (use (match_dup 2))
4416 (use (match_dup 3))])]
4417 "")
4418
4419 (define_split
4420 [(set (match_operand:HI 0 "register_operand" "")
4421 (fix:HI (match_operand 1 "register_operand" "")))
4422 (use (match_operand:HI 2 "memory_operand" ""))
4423 (use (match_operand:HI 3 "memory_operand" ""))
4424 (clobber (match_operand:HI 4 "memory_operand" ""))]
4425 "reload_completed"
4426 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4427 (use (match_dup 2))
4428 (use (match_dup 3))
4429 (clobber (match_dup 4))])
4430 (set (match_dup 0) (match_dup 4))]
4431 "")
4432
4433 ;; %% Not used yet.
4434 (define_insn "x86_fnstcw_1"
4435 [(set (match_operand:HI 0 "memory_operand" "=m")
4436 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4437 "TARGET_80387"
4438 "fnstcw\t%0"
4439 [(set_attr "length" "2")
4440 (set_attr "mode" "HI")
4441 (set_attr "unit" "i387")])
4442
4443 (define_insn "x86_fldcw_1"
4444 [(set (reg:HI 18)
4445 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4446 "TARGET_80387"
4447 "fldcw\t%0"
4448 [(set_attr "length" "2")
4449 (set_attr "mode" "HI")
4450 (set_attr "unit" "i387")
4451 (set_attr "athlon_decode" "vector")])
4452 \f
4453 ;; Conversion between fixed point and floating point.
4454
4455 ;; Even though we only accept memory inputs, the backend _really_
4456 ;; wants to be able to do this between registers.
4457
4458 (define_expand "floathisf2"
4459 [(set (match_operand:SF 0 "register_operand" "")
4460 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4461 "TARGET_SSE || TARGET_80387"
4462 {
4463 if (TARGET_SSE && TARGET_SSE_MATH)
4464 {
4465 emit_insn (gen_floatsisf2 (operands[0],
4466 convert_to_mode (SImode, operands[1], 0)));
4467 DONE;
4468 }
4469 })
4470
4471 (define_insn "*floathisf2_1"
4472 [(set (match_operand:SF 0 "register_operand" "=f,f")
4473 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4474 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4475 "@
4476 fild%z1\t%1
4477 #"
4478 [(set_attr "type" "fmov,multi")
4479 (set_attr "mode" "SF")
4480 (set_attr "fp_int_src" "true")])
4481
4482 (define_expand "floatsisf2"
4483 [(set (match_operand:SF 0 "register_operand" "")
4484 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4485 "TARGET_SSE || TARGET_80387"
4486 "")
4487
4488 (define_insn "*floatsisf2_i387"
4489 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4490 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4491 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4492 "@
4493 fild%z1\t%1
4494 #
4495 cvtsi2ss\t{%1, %0|%0, %1}
4496 cvtsi2ss\t{%1, %0|%0, %1}"
4497 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4498 (set_attr "mode" "SF")
4499 (set_attr "athlon_decode" "*,*,vector,double")
4500 (set_attr "fp_int_src" "true")])
4501
4502 (define_insn "*floatsisf2_sse"
4503 [(set (match_operand:SF 0 "register_operand" "=x,x")
4504 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4505 "TARGET_SSE"
4506 "cvtsi2ss\t{%1, %0|%0, %1}"
4507 [(set_attr "type" "sseicvt")
4508 (set_attr "mode" "SF")
4509 (set_attr "athlon_decode" "vector,double")
4510 (set_attr "fp_int_src" "true")])
4511
4512 ; Avoid possible reformatting penalty on the destination by first
4513 ; zeroing it out
4514 (define_split
4515 [(set (match_operand:SF 0 "register_operand" "")
4516 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4517 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4518 && SSE_REG_P (operands[0])"
4519 [(const_int 0)]
4520 {
4521 rtx dest;
4522 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4523 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4524 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4525 DONE;
4526 })
4527
4528 (define_expand "floatdisf2"
4529 [(set (match_operand:SF 0 "register_operand" "")
4530 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4531 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4532 "")
4533
4534 (define_insn "*floatdisf2_i387_only"
4535 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4536 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4537 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4538 "@
4539 fild%z1\t%1
4540 #"
4541 [(set_attr "type" "fmov,multi")
4542 (set_attr "mode" "SF")
4543 (set_attr "fp_int_src" "true")])
4544
4545 (define_insn "*floatdisf2_i387"
4546 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4547 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4548 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4549 "@
4550 fild%z1\t%1
4551 #
4552 cvtsi2ss{q}\t{%1, %0|%0, %1}
4553 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4554 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4555 (set_attr "mode" "SF")
4556 (set_attr "athlon_decode" "*,*,vector,double")
4557 (set_attr "fp_int_src" "true")])
4558
4559 (define_insn "*floatdisf2_sse"
4560 [(set (match_operand:SF 0 "register_operand" "=x,x")
4561 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4562 "TARGET_64BIT && TARGET_SSE"
4563 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "sseicvt")
4565 (set_attr "mode" "SF")
4566 (set_attr "athlon_decode" "vector,double")
4567 (set_attr "fp_int_src" "true")])
4568
4569 ; Avoid possible reformatting penalty on the destination by first
4570 ; zeroing it out
4571 (define_split
4572 [(set (match_operand:SF 0 "register_operand" "")
4573 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4574 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4575 && SSE_REG_P (operands[0])"
4576 [(const_int 0)]
4577 {
4578 rtx dest;
4579 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4580 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4581 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4582 DONE;
4583 })
4584
4585 (define_expand "floathidf2"
4586 [(set (match_operand:DF 0 "register_operand" "")
4587 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4588 "TARGET_SSE2 || TARGET_80387"
4589 {
4590 if (TARGET_SSE && TARGET_SSE_MATH)
4591 {
4592 emit_insn (gen_floatsidf2 (operands[0],
4593 convert_to_mode (SImode, operands[1], 0)));
4594 DONE;
4595 }
4596 })
4597
4598 (define_insn "*floathidf2_1"
4599 [(set (match_operand:DF 0 "register_operand" "=f,f")
4600 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4601 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4602 "@
4603 fild%z1\t%1
4604 #"
4605 [(set_attr "type" "fmov,multi")
4606 (set_attr "mode" "DF")
4607 (set_attr "fp_int_src" "true")])
4608
4609 (define_expand "floatsidf2"
4610 [(set (match_operand:DF 0 "register_operand" "")
4611 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4612 "TARGET_80387 || TARGET_SSE2"
4613 "")
4614
4615 (define_insn "*floatsidf2_i387"
4616 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4617 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4618 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4619 "@
4620 fild%z1\t%1
4621 #
4622 cvtsi2sd\t{%1, %0|%0, %1}
4623 cvtsi2sd\t{%1, %0|%0, %1}"
4624 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4625 (set_attr "mode" "DF")
4626 (set_attr "athlon_decode" "*,*,double,direct")
4627 (set_attr "fp_int_src" "true")])
4628
4629 (define_insn "*floatsidf2_sse"
4630 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4631 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4632 "TARGET_SSE2"
4633 "cvtsi2sd\t{%1, %0|%0, %1}"
4634 [(set_attr "type" "sseicvt")
4635 (set_attr "mode" "DF")
4636 (set_attr "athlon_decode" "double,direct")
4637 (set_attr "fp_int_src" "true")])
4638
4639 (define_expand "floatdidf2"
4640 [(set (match_operand:DF 0 "register_operand" "")
4641 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4642 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4643 "")
4644
4645 (define_insn "*floatdidf2_i387_only"
4646 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4647 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4648 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4649 "@
4650 fild%z1\t%1
4651 #"
4652 [(set_attr "type" "fmov,multi")
4653 (set_attr "mode" "DF")
4654 (set_attr "fp_int_src" "true")])
4655
4656 (define_insn "*floatdidf2_i387"
4657 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4658 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4659 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4660 "@
4661 fild%z1\t%1
4662 #
4663 cvtsi2sd{q}\t{%1, %0|%0, %1}
4664 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4665 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4666 (set_attr "mode" "DF")
4667 (set_attr "athlon_decode" "*,*,double,direct")
4668 (set_attr "fp_int_src" "true")])
4669
4670 (define_insn "*floatdidf2_sse"
4671 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4672 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4673 "TARGET_SSE2"
4674 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4675 [(set_attr "type" "sseicvt")
4676 (set_attr "mode" "DF")
4677 (set_attr "athlon_decode" "double,direct")
4678 (set_attr "fp_int_src" "true")])
4679
4680 (define_insn "floathixf2"
4681 [(set (match_operand:XF 0 "register_operand" "=f,f")
4682 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4683 "TARGET_80387"
4684 "@
4685 fild%z1\t%1
4686 #"
4687 [(set_attr "type" "fmov,multi")
4688 (set_attr "mode" "XF")
4689 (set_attr "fp_int_src" "true")])
4690
4691 (define_insn "floatsixf2"
4692 [(set (match_operand:XF 0 "register_operand" "=f,f")
4693 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4694 "TARGET_80387"
4695 "@
4696 fild%z1\t%1
4697 #"
4698 [(set_attr "type" "fmov,multi")
4699 (set_attr "mode" "XF")
4700 (set_attr "fp_int_src" "true")])
4701
4702 (define_insn "floatdixf2"
4703 [(set (match_operand:XF 0 "register_operand" "=f,f")
4704 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4705 "TARGET_80387"
4706 "@
4707 fild%z1\t%1
4708 #"
4709 [(set_attr "type" "fmov,multi")
4710 (set_attr "mode" "XF")
4711 (set_attr "fp_int_src" "true")])
4712
4713 ;; %%% Kill these when reload knows how to do it.
4714 (define_split
4715 [(set (match_operand 0 "fp_register_operand" "")
4716 (float (match_operand 1 "register_operand" "")))]
4717 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4718 [(const_int 0)]
4719 {
4720 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4721 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4722 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4723 ix86_free_from_memory (GET_MODE (operands[1]));
4724 DONE;
4725 })
4726
4727 (define_expand "floatunssisf2"
4728 [(use (match_operand:SF 0 "register_operand" ""))
4729 (use (match_operand:SI 1 "register_operand" ""))]
4730 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4731 "x86_emit_floatuns (operands); DONE;")
4732
4733 (define_expand "floatunsdisf2"
4734 [(use (match_operand:SF 0 "register_operand" ""))
4735 (use (match_operand:DI 1 "register_operand" ""))]
4736 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4737 "x86_emit_floatuns (operands); DONE;")
4738
4739 (define_expand "floatunsdidf2"
4740 [(use (match_operand:DF 0 "register_operand" ""))
4741 (use (match_operand:DI 1 "register_operand" ""))]
4742 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4743 "x86_emit_floatuns (operands); DONE;")
4744 \f
4745 ;; SSE extract/set expanders
4746
4747 (define_expand "vec_setv2df"
4748 [(match_operand:V2DF 0 "register_operand" "")
4749 (match_operand:DF 1 "register_operand" "")
4750 (match_operand 2 "const_int_operand" "")]
4751 "TARGET_SSE2"
4752 {
4753 switch (INTVAL (operands[2]))
4754 {
4755 case 0:
4756 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4757 simplify_gen_subreg (V2DFmode, operands[1],
4758 DFmode, 0)));
4759 break;
4760 case 1:
4761 {
4762 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4763
4764 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4765 }
4766 break;
4767 default:
4768 abort ();
4769 }
4770 DONE;
4771 })
4772
4773 (define_expand "vec_extractv2df"
4774 [(match_operand:DF 0 "register_operand" "")
4775 (match_operand:V2DF 1 "register_operand" "")
4776 (match_operand 2 "const_int_operand" "")]
4777 "TARGET_SSE2"
4778 {
4779 switch (INTVAL (operands[2]))
4780 {
4781 case 0:
4782 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4783 break;
4784 case 1:
4785 {
4786 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4787
4788 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4789 }
4790 break;
4791 default:
4792 abort ();
4793 }
4794 DONE;
4795 })
4796
4797 (define_expand "vec_initv2df"
4798 [(match_operand:V2DF 0 "register_operand" "")
4799 (match_operand 1 "" "")]
4800 "TARGET_SSE2"
4801 {
4802 ix86_expand_vector_init (operands[0], operands[1]);
4803 DONE;
4804 })
4805
4806 (define_expand "vec_setv4sf"
4807 [(match_operand:V4SF 0 "register_operand" "")
4808 (match_operand:SF 1 "register_operand" "")
4809 (match_operand 2 "const_int_operand" "")]
4810 "TARGET_SSE"
4811 {
4812 switch (INTVAL (operands[2]))
4813 {
4814 case 0:
4815 emit_insn (gen_sse_movss (operands[0], operands[0],
4816 simplify_gen_subreg (V4SFmode, operands[1],
4817 SFmode, 0)));
4818 break;
4819 case 1:
4820 {
4821 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4822 rtx tmp = gen_reg_rtx (V4SFmode);
4823
4824 emit_move_insn (tmp, operands[0]);
4825 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4826 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4827 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4828 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4829 }
4830 case 2:
4831 {
4832 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4833 rtx tmp = gen_reg_rtx (V4SFmode);
4834
4835 emit_move_insn (tmp, operands[0]);
4836 emit_insn (gen_sse_movss (tmp, tmp, op1));
4837 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4838 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4839 }
4840 break;
4841 case 3:
4842 {
4843 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4844 rtx tmp = gen_reg_rtx (V4SFmode);
4845
4846 emit_move_insn (tmp, operands[0]);
4847 emit_insn (gen_sse_movss (tmp, tmp, op1));
4848 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4849 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4850 }
4851 break;
4852 default:
4853 abort ();
4854 }
4855 DONE;
4856 })
4857
4858 (define_expand "vec_extractv4sf"
4859 [(match_operand:SF 0 "register_operand" "")
4860 (match_operand:V4SF 1 "register_operand" "")
4861 (match_operand 2 "const_int_operand" "")]
4862 "TARGET_SSE"
4863 {
4864 switch (INTVAL (operands[2]))
4865 {
4866 case 0:
4867 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4868 break;
4869 case 1:
4870 {
4871 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4872 rtx tmp = gen_reg_rtx (V4SFmode);
4873
4874 emit_move_insn (tmp, operands[1]);
4875 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4876 const1_rtx));
4877 }
4878 case 2:
4879 {
4880 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4881 rtx tmp = gen_reg_rtx (V4SFmode);
4882
4883 emit_move_insn (tmp, operands[1]);
4884 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4885 }
4886 case 3:
4887 {
4888 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4889 rtx tmp = gen_reg_rtx (V4SFmode);
4890
4891 emit_move_insn (tmp, operands[1]);
4892 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4893 GEN_INT (3)));
4894 }
4895 default:
4896 abort ();
4897 }
4898 DONE;
4899 })
4900
4901 (define_expand "vec_initv4sf"
4902 [(match_operand:V4SF 0 "register_operand" "")
4903 (match_operand 1 "" "")]
4904 "TARGET_SSE"
4905 {
4906 ix86_expand_vector_init (operands[0], operands[1]);
4907 DONE;
4908 })
4909 \f
4910 ;; Add instructions
4911
4912 ;; %%% splits for addsidi3
4913 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4914 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4915 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4916
4917 (define_expand "adddi3"
4918 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4919 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4920 (match_operand:DI 2 "x86_64_general_operand" "")))
4921 (clobber (reg:CC 17))]
4922 ""
4923 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4924
4925 (define_insn "*adddi3_1"
4926 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4927 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4928 (match_operand:DI 2 "general_operand" "roiF,riF")))
4929 (clobber (reg:CC 17))]
4930 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4931 "#")
4932
4933 (define_split
4934 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4935 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4936 (match_operand:DI 2 "general_operand" "")))
4937 (clobber (reg:CC 17))]
4938 "!TARGET_64BIT && reload_completed"
4939 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4940 UNSPEC_ADD_CARRY))
4941 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4942 (parallel [(set (match_dup 3)
4943 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4944 (match_dup 4))
4945 (match_dup 5)))
4946 (clobber (reg:CC 17))])]
4947 "split_di (operands+0, 1, operands+0, operands+3);
4948 split_di (operands+1, 1, operands+1, operands+4);
4949 split_di (operands+2, 1, operands+2, operands+5);")
4950
4951 (define_insn "adddi3_carry_rex64"
4952 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4953 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4954 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4955 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4956 (clobber (reg:CC 17))]
4957 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4958 "adc{q}\t{%2, %0|%0, %2}"
4959 [(set_attr "type" "alu")
4960 (set_attr "pent_pair" "pu")
4961 (set_attr "mode" "DI")])
4962
4963 (define_insn "*adddi3_cc_rex64"
4964 [(set (reg:CC 17)
4965 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4966 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4967 UNSPEC_ADD_CARRY))
4968 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4969 (plus:DI (match_dup 1) (match_dup 2)))]
4970 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4971 "add{q}\t{%2, %0|%0, %2}"
4972 [(set_attr "type" "alu")
4973 (set_attr "mode" "DI")])
4974
4975 (define_insn "addqi3_carry"
4976 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4977 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4978 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4979 (match_operand:QI 2 "general_operand" "qi,qm")))
4980 (clobber (reg:CC 17))]
4981 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4982 "adc{b}\t{%2, %0|%0, %2}"
4983 [(set_attr "type" "alu")
4984 (set_attr "pent_pair" "pu")
4985 (set_attr "mode" "QI")])
4986
4987 (define_insn "addhi3_carry"
4988 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4989 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4990 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4991 (match_operand:HI 2 "general_operand" "ri,rm")))
4992 (clobber (reg:CC 17))]
4993 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4994 "adc{w}\t{%2, %0|%0, %2}"
4995 [(set_attr "type" "alu")
4996 (set_attr "pent_pair" "pu")
4997 (set_attr "mode" "HI")])
4998
4999 (define_insn "addsi3_carry"
5000 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5001 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5002 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5003 (match_operand:SI 2 "general_operand" "ri,rm")))
5004 (clobber (reg:CC 17))]
5005 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5006 "adc{l}\t{%2, %0|%0, %2}"
5007 [(set_attr "type" "alu")
5008 (set_attr "pent_pair" "pu")
5009 (set_attr "mode" "SI")])
5010
5011 (define_insn "*addsi3_carry_zext"
5012 [(set (match_operand:DI 0 "register_operand" "=r")
5013 (zero_extend:DI
5014 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5015 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5016 (match_operand:SI 2 "general_operand" "rim"))))
5017 (clobber (reg:CC 17))]
5018 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5019 "adc{l}\t{%2, %k0|%k0, %2}"
5020 [(set_attr "type" "alu")
5021 (set_attr "pent_pair" "pu")
5022 (set_attr "mode" "SI")])
5023
5024 (define_insn "*addsi3_cc"
5025 [(set (reg:CC 17)
5026 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5027 (match_operand:SI 2 "general_operand" "ri,rm")]
5028 UNSPEC_ADD_CARRY))
5029 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5030 (plus:SI (match_dup 1) (match_dup 2)))]
5031 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5032 "add{l}\t{%2, %0|%0, %2}"
5033 [(set_attr "type" "alu")
5034 (set_attr "mode" "SI")])
5035
5036 (define_insn "addqi3_cc"
5037 [(set (reg:CC 17)
5038 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5039 (match_operand:QI 2 "general_operand" "qi,qm")]
5040 UNSPEC_ADD_CARRY))
5041 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5042 (plus:QI (match_dup 1) (match_dup 2)))]
5043 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5044 "add{b}\t{%2, %0|%0, %2}"
5045 [(set_attr "type" "alu")
5046 (set_attr "mode" "QI")])
5047
5048 (define_expand "addsi3"
5049 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5050 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5051 (match_operand:SI 2 "general_operand" "")))
5052 (clobber (reg:CC 17))])]
5053 ""
5054 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5055
5056 (define_insn "*lea_1"
5057 [(set (match_operand:SI 0 "register_operand" "=r")
5058 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5059 "!TARGET_64BIT"
5060 "lea{l}\t{%a1, %0|%0, %a1}"
5061 [(set_attr "type" "lea")
5062 (set_attr "mode" "SI")])
5063
5064 (define_insn "*lea_1_rex64"
5065 [(set (match_operand:SI 0 "register_operand" "=r")
5066 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5067 "TARGET_64BIT"
5068 "lea{l}\t{%a1, %0|%0, %a1}"
5069 [(set_attr "type" "lea")
5070 (set_attr "mode" "SI")])
5071
5072 (define_insn "*lea_1_zext"
5073 [(set (match_operand:DI 0 "register_operand" "=r")
5074 (zero_extend:DI
5075 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5076 "TARGET_64BIT"
5077 "lea{l}\t{%a1, %k0|%k0, %a1}"
5078 [(set_attr "type" "lea")
5079 (set_attr "mode" "SI")])
5080
5081 (define_insn "*lea_2_rex64"
5082 [(set (match_operand:DI 0 "register_operand" "=r")
5083 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5084 "TARGET_64BIT"
5085 "lea{q}\t{%a1, %0|%0, %a1}"
5086 [(set_attr "type" "lea")
5087 (set_attr "mode" "DI")])
5088
5089 ;; The lea patterns for non-Pmodes needs to be matched by several
5090 ;; insns converted to real lea by splitters.
5091
5092 (define_insn_and_split "*lea_general_1"
5093 [(set (match_operand 0 "register_operand" "=r")
5094 (plus (plus (match_operand 1 "index_register_operand" "r")
5095 (match_operand 2 "register_operand" "r"))
5096 (match_operand 3 "immediate_operand" "i")))]
5097 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5098 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5099 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5100 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5101 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5102 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5103 || GET_MODE (operands[3]) == VOIDmode)"
5104 "#"
5105 "&& reload_completed"
5106 [(const_int 0)]
5107 {
5108 rtx pat;
5109 operands[0] = gen_lowpart (SImode, operands[0]);
5110 operands[1] = gen_lowpart (Pmode, operands[1]);
5111 operands[2] = gen_lowpart (Pmode, operands[2]);
5112 operands[3] = gen_lowpart (Pmode, operands[3]);
5113 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5114 operands[3]);
5115 if (Pmode != SImode)
5116 pat = gen_rtx_SUBREG (SImode, pat, 0);
5117 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5118 DONE;
5119 }
5120 [(set_attr "type" "lea")
5121 (set_attr "mode" "SI")])
5122
5123 (define_insn_and_split "*lea_general_1_zext"
5124 [(set (match_operand:DI 0 "register_operand" "=r")
5125 (zero_extend:DI
5126 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5127 (match_operand:SI 2 "register_operand" "r"))
5128 (match_operand:SI 3 "immediate_operand" "i"))))]
5129 "TARGET_64BIT"
5130 "#"
5131 "&& reload_completed"
5132 [(set (match_dup 0)
5133 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5134 (match_dup 2))
5135 (match_dup 3)) 0)))]
5136 {
5137 operands[1] = gen_lowpart (Pmode, operands[1]);
5138 operands[2] = gen_lowpart (Pmode, operands[2]);
5139 operands[3] = gen_lowpart (Pmode, operands[3]);
5140 }
5141 [(set_attr "type" "lea")
5142 (set_attr "mode" "SI")])
5143
5144 (define_insn_and_split "*lea_general_2"
5145 [(set (match_operand 0 "register_operand" "=r")
5146 (plus (mult (match_operand 1 "index_register_operand" "r")
5147 (match_operand 2 "const248_operand" "i"))
5148 (match_operand 3 "nonmemory_operand" "ri")))]
5149 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5150 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5151 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5152 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5153 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5154 || GET_MODE (operands[3]) == VOIDmode)"
5155 "#"
5156 "&& reload_completed"
5157 [(const_int 0)]
5158 {
5159 rtx pat;
5160 operands[0] = gen_lowpart (SImode, operands[0]);
5161 operands[1] = gen_lowpart (Pmode, operands[1]);
5162 operands[3] = gen_lowpart (Pmode, operands[3]);
5163 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5164 operands[3]);
5165 if (Pmode != SImode)
5166 pat = gen_rtx_SUBREG (SImode, pat, 0);
5167 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5168 DONE;
5169 }
5170 [(set_attr "type" "lea")
5171 (set_attr "mode" "SI")])
5172
5173 (define_insn_and_split "*lea_general_2_zext"
5174 [(set (match_operand:DI 0 "register_operand" "=r")
5175 (zero_extend:DI
5176 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5177 (match_operand:SI 2 "const248_operand" "n"))
5178 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5179 "TARGET_64BIT"
5180 "#"
5181 "&& reload_completed"
5182 [(set (match_dup 0)
5183 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5184 (match_dup 2))
5185 (match_dup 3)) 0)))]
5186 {
5187 operands[1] = gen_lowpart (Pmode, operands[1]);
5188 operands[3] = gen_lowpart (Pmode, operands[3]);
5189 }
5190 [(set_attr "type" "lea")
5191 (set_attr "mode" "SI")])
5192
5193 (define_insn_and_split "*lea_general_3"
5194 [(set (match_operand 0 "register_operand" "=r")
5195 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5196 (match_operand 2 "const248_operand" "i"))
5197 (match_operand 3 "register_operand" "r"))
5198 (match_operand 4 "immediate_operand" "i")))]
5199 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5200 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5201 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5202 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5203 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5204 "#"
5205 "&& reload_completed"
5206 [(const_int 0)]
5207 {
5208 rtx pat;
5209 operands[0] = gen_lowpart (SImode, operands[0]);
5210 operands[1] = gen_lowpart (Pmode, operands[1]);
5211 operands[3] = gen_lowpart (Pmode, operands[3]);
5212 operands[4] = gen_lowpart (Pmode, operands[4]);
5213 pat = gen_rtx_PLUS (Pmode,
5214 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5215 operands[2]),
5216 operands[3]),
5217 operands[4]);
5218 if (Pmode != SImode)
5219 pat = gen_rtx_SUBREG (SImode, pat, 0);
5220 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5221 DONE;
5222 }
5223 [(set_attr "type" "lea")
5224 (set_attr "mode" "SI")])
5225
5226 (define_insn_and_split "*lea_general_3_zext"
5227 [(set (match_operand:DI 0 "register_operand" "=r")
5228 (zero_extend:DI
5229 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5230 (match_operand:SI 2 "const248_operand" "n"))
5231 (match_operand:SI 3 "register_operand" "r"))
5232 (match_operand:SI 4 "immediate_operand" "i"))))]
5233 "TARGET_64BIT"
5234 "#"
5235 "&& reload_completed"
5236 [(set (match_dup 0)
5237 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5238 (match_dup 2))
5239 (match_dup 3))
5240 (match_dup 4)) 0)))]
5241 {
5242 operands[1] = gen_lowpart (Pmode, operands[1]);
5243 operands[3] = gen_lowpart (Pmode, operands[3]);
5244 operands[4] = gen_lowpart (Pmode, operands[4]);
5245 }
5246 [(set_attr "type" "lea")
5247 (set_attr "mode" "SI")])
5248
5249 (define_insn "*adddi_1_rex64"
5250 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5251 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5252 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5253 (clobber (reg:CC 17))]
5254 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5255 {
5256 switch (get_attr_type (insn))
5257 {
5258 case TYPE_LEA:
5259 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5260 return "lea{q}\t{%a2, %0|%0, %a2}";
5261
5262 case TYPE_INCDEC:
5263 if (! rtx_equal_p (operands[0], operands[1]))
5264 abort ();
5265 if (operands[2] == const1_rtx)
5266 return "inc{q}\t%0";
5267 else if (operands[2] == constm1_rtx)
5268 return "dec{q}\t%0";
5269 else
5270 abort ();
5271
5272 default:
5273 if (! rtx_equal_p (operands[0], operands[1]))
5274 abort ();
5275
5276 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5277 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5278 if (GET_CODE (operands[2]) == CONST_INT
5279 /* Avoid overflows. */
5280 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5281 && (INTVAL (operands[2]) == 128
5282 || (INTVAL (operands[2]) < 0
5283 && INTVAL (operands[2]) != -128)))
5284 {
5285 operands[2] = GEN_INT (-INTVAL (operands[2]));
5286 return "sub{q}\t{%2, %0|%0, %2}";
5287 }
5288 return "add{q}\t{%2, %0|%0, %2}";
5289 }
5290 }
5291 [(set (attr "type")
5292 (cond [(eq_attr "alternative" "2")
5293 (const_string "lea")
5294 ; Current assemblers are broken and do not allow @GOTOFF in
5295 ; ought but a memory context.
5296 (match_operand:DI 2 "pic_symbolic_operand" "")
5297 (const_string "lea")
5298 (match_operand:DI 2 "incdec_operand" "")
5299 (const_string "incdec")
5300 ]
5301 (const_string "alu")))
5302 (set_attr "mode" "DI")])
5303
5304 ;; Convert lea to the lea pattern to avoid flags dependency.
5305 (define_split
5306 [(set (match_operand:DI 0 "register_operand" "")
5307 (plus:DI (match_operand:DI 1 "register_operand" "")
5308 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5309 (clobber (reg:CC 17))]
5310 "TARGET_64BIT && reload_completed
5311 && true_regnum (operands[0]) != true_regnum (operands[1])"
5312 [(set (match_dup 0)
5313 (plus:DI (match_dup 1)
5314 (match_dup 2)))]
5315 "")
5316
5317 (define_insn "*adddi_2_rex64"
5318 [(set (reg 17)
5319 (compare
5320 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5321 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5322 (const_int 0)))
5323 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5324 (plus:DI (match_dup 1) (match_dup 2)))]
5325 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5326 && ix86_binary_operator_ok (PLUS, DImode, operands)
5327 /* Current assemblers are broken and do not allow @GOTOFF in
5328 ought but a memory context. */
5329 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5330 {
5331 switch (get_attr_type (insn))
5332 {
5333 case TYPE_INCDEC:
5334 if (! rtx_equal_p (operands[0], operands[1]))
5335 abort ();
5336 if (operands[2] == const1_rtx)
5337 return "inc{q}\t%0";
5338 else if (operands[2] == constm1_rtx)
5339 return "dec{q}\t%0";
5340 else
5341 abort ();
5342
5343 default:
5344 if (! rtx_equal_p (operands[0], operands[1]))
5345 abort ();
5346 /* ???? We ought to handle there the 32bit case too
5347 - do we need new constraint? */
5348 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5349 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5350 if (GET_CODE (operands[2]) == CONST_INT
5351 /* Avoid overflows. */
5352 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5353 && (INTVAL (operands[2]) == 128
5354 || (INTVAL (operands[2]) < 0
5355 && INTVAL (operands[2]) != -128)))
5356 {
5357 operands[2] = GEN_INT (-INTVAL (operands[2]));
5358 return "sub{q}\t{%2, %0|%0, %2}";
5359 }
5360 return "add{q}\t{%2, %0|%0, %2}";
5361 }
5362 }
5363 [(set (attr "type")
5364 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5365 (const_string "incdec")
5366 (const_string "alu")))
5367 (set_attr "mode" "DI")])
5368
5369 (define_insn "*adddi_3_rex64"
5370 [(set (reg 17)
5371 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5372 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5373 (clobber (match_scratch:DI 0 "=r"))]
5374 "TARGET_64BIT
5375 && ix86_match_ccmode (insn, CCZmode)
5376 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5377 /* Current assemblers are broken and do not allow @GOTOFF in
5378 ought but a memory context. */
5379 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5380 {
5381 switch (get_attr_type (insn))
5382 {
5383 case TYPE_INCDEC:
5384 if (! rtx_equal_p (operands[0], operands[1]))
5385 abort ();
5386 if (operands[2] == const1_rtx)
5387 return "inc{q}\t%0";
5388 else if (operands[2] == constm1_rtx)
5389 return "dec{q}\t%0";
5390 else
5391 abort ();
5392
5393 default:
5394 if (! rtx_equal_p (operands[0], operands[1]))
5395 abort ();
5396 /* ???? We ought to handle there the 32bit case too
5397 - do we need new constraint? */
5398 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5399 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5400 if (GET_CODE (operands[2]) == CONST_INT
5401 /* Avoid overflows. */
5402 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5403 && (INTVAL (operands[2]) == 128
5404 || (INTVAL (operands[2]) < 0
5405 && INTVAL (operands[2]) != -128)))
5406 {
5407 operands[2] = GEN_INT (-INTVAL (operands[2]));
5408 return "sub{q}\t{%2, %0|%0, %2}";
5409 }
5410 return "add{q}\t{%2, %0|%0, %2}";
5411 }
5412 }
5413 [(set (attr "type")
5414 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5415 (const_string "incdec")
5416 (const_string "alu")))
5417 (set_attr "mode" "DI")])
5418
5419 ; For comparisons against 1, -1 and 128, we may generate better code
5420 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5421 ; is matched then. We can't accept general immediate, because for
5422 ; case of overflows, the result is messed up.
5423 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5424 ; when negated.
5425 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5426 ; only for comparisons not depending on it.
5427 (define_insn "*adddi_4_rex64"
5428 [(set (reg 17)
5429 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5430 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5431 (clobber (match_scratch:DI 0 "=rm"))]
5432 "TARGET_64BIT
5433 && ix86_match_ccmode (insn, CCGCmode)"
5434 {
5435 switch (get_attr_type (insn))
5436 {
5437 case TYPE_INCDEC:
5438 if (operands[2] == constm1_rtx)
5439 return "inc{q}\t%0";
5440 else if (operands[2] == const1_rtx)
5441 return "dec{q}\t%0";
5442 else
5443 abort();
5444
5445 default:
5446 if (! rtx_equal_p (operands[0], operands[1]))
5447 abort ();
5448 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5449 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5450 if ((INTVAL (operands[2]) == -128
5451 || (INTVAL (operands[2]) > 0
5452 && INTVAL (operands[2]) != 128))
5453 /* Avoid overflows. */
5454 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5455 return "sub{q}\t{%2, %0|%0, %2}";
5456 operands[2] = GEN_INT (-INTVAL (operands[2]));
5457 return "add{q}\t{%2, %0|%0, %2}";
5458 }
5459 }
5460 [(set (attr "type")
5461 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5462 (const_string "incdec")
5463 (const_string "alu")))
5464 (set_attr "mode" "DI")])
5465
5466 (define_insn "*adddi_5_rex64"
5467 [(set (reg 17)
5468 (compare
5469 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5470 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5471 (const_int 0)))
5472 (clobber (match_scratch:DI 0 "=r"))]
5473 "TARGET_64BIT
5474 && ix86_match_ccmode (insn, CCGOCmode)
5475 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5476 /* Current assemblers are broken and do not allow @GOTOFF in
5477 ought but a memory context. */
5478 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5479 {
5480 switch (get_attr_type (insn))
5481 {
5482 case TYPE_INCDEC:
5483 if (! rtx_equal_p (operands[0], operands[1]))
5484 abort ();
5485 if (operands[2] == const1_rtx)
5486 return "inc{q}\t%0";
5487 else if (operands[2] == constm1_rtx)
5488 return "dec{q}\t%0";
5489 else
5490 abort();
5491
5492 default:
5493 if (! rtx_equal_p (operands[0], operands[1]))
5494 abort ();
5495 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5496 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5497 if (GET_CODE (operands[2]) == CONST_INT
5498 /* Avoid overflows. */
5499 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5500 && (INTVAL (operands[2]) == 128
5501 || (INTVAL (operands[2]) < 0
5502 && INTVAL (operands[2]) != -128)))
5503 {
5504 operands[2] = GEN_INT (-INTVAL (operands[2]));
5505 return "sub{q}\t{%2, %0|%0, %2}";
5506 }
5507 return "add{q}\t{%2, %0|%0, %2}";
5508 }
5509 }
5510 [(set (attr "type")
5511 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5512 (const_string "incdec")
5513 (const_string "alu")))
5514 (set_attr "mode" "DI")])
5515
5516
5517 (define_insn "*addsi_1"
5518 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5519 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5520 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5521 (clobber (reg:CC 17))]
5522 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5523 {
5524 switch (get_attr_type (insn))
5525 {
5526 case TYPE_LEA:
5527 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5528 return "lea{l}\t{%a2, %0|%0, %a2}";
5529
5530 case TYPE_INCDEC:
5531 if (! rtx_equal_p (operands[0], operands[1]))
5532 abort ();
5533 if (operands[2] == const1_rtx)
5534 return "inc{l}\t%0";
5535 else if (operands[2] == constm1_rtx)
5536 return "dec{l}\t%0";
5537 else
5538 abort();
5539
5540 default:
5541 if (! rtx_equal_p (operands[0], operands[1]))
5542 abort ();
5543
5544 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5545 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5546 if (GET_CODE (operands[2]) == CONST_INT
5547 && (INTVAL (operands[2]) == 128
5548 || (INTVAL (operands[2]) < 0
5549 && INTVAL (operands[2]) != -128)))
5550 {
5551 operands[2] = GEN_INT (-INTVAL (operands[2]));
5552 return "sub{l}\t{%2, %0|%0, %2}";
5553 }
5554 return "add{l}\t{%2, %0|%0, %2}";
5555 }
5556 }
5557 [(set (attr "type")
5558 (cond [(eq_attr "alternative" "2")
5559 (const_string "lea")
5560 ; Current assemblers are broken and do not allow @GOTOFF in
5561 ; ought but a memory context.
5562 (match_operand:SI 2 "pic_symbolic_operand" "")
5563 (const_string "lea")
5564 (match_operand:SI 2 "incdec_operand" "")
5565 (const_string "incdec")
5566 ]
5567 (const_string "alu")))
5568 (set_attr "mode" "SI")])
5569
5570 ;; Convert lea to the lea pattern to avoid flags dependency.
5571 (define_split
5572 [(set (match_operand 0 "register_operand" "")
5573 (plus (match_operand 1 "register_operand" "")
5574 (match_operand 2 "nonmemory_operand" "")))
5575 (clobber (reg:CC 17))]
5576 "reload_completed
5577 && true_regnum (operands[0]) != true_regnum (operands[1])"
5578 [(const_int 0)]
5579 {
5580 rtx pat;
5581 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5582 may confuse gen_lowpart. */
5583 if (GET_MODE (operands[0]) != Pmode)
5584 {
5585 operands[1] = gen_lowpart (Pmode, operands[1]);
5586 operands[2] = gen_lowpart (Pmode, operands[2]);
5587 }
5588 operands[0] = gen_lowpart (SImode, operands[0]);
5589 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5590 if (Pmode != SImode)
5591 pat = gen_rtx_SUBREG (SImode, pat, 0);
5592 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5593 DONE;
5594 })
5595
5596 ;; It may seem that nonimmediate operand is proper one for operand 1.
5597 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5598 ;; we take care in ix86_binary_operator_ok to not allow two memory
5599 ;; operands so proper swapping will be done in reload. This allow
5600 ;; patterns constructed from addsi_1 to match.
5601 (define_insn "addsi_1_zext"
5602 [(set (match_operand:DI 0 "register_operand" "=r,r")
5603 (zero_extend:DI
5604 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5605 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5606 (clobber (reg:CC 17))]
5607 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5608 {
5609 switch (get_attr_type (insn))
5610 {
5611 case TYPE_LEA:
5612 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5613 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5614
5615 case TYPE_INCDEC:
5616 if (operands[2] == const1_rtx)
5617 return "inc{l}\t%k0";
5618 else if (operands[2] == constm1_rtx)
5619 return "dec{l}\t%k0";
5620 else
5621 abort();
5622
5623 default:
5624 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5625 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5626 if (GET_CODE (operands[2]) == CONST_INT
5627 && (INTVAL (operands[2]) == 128
5628 || (INTVAL (operands[2]) < 0
5629 && INTVAL (operands[2]) != -128)))
5630 {
5631 operands[2] = GEN_INT (-INTVAL (operands[2]));
5632 return "sub{l}\t{%2, %k0|%k0, %2}";
5633 }
5634 return "add{l}\t{%2, %k0|%k0, %2}";
5635 }
5636 }
5637 [(set (attr "type")
5638 (cond [(eq_attr "alternative" "1")
5639 (const_string "lea")
5640 ; Current assemblers are broken and do not allow @GOTOFF in
5641 ; ought but a memory context.
5642 (match_operand:SI 2 "pic_symbolic_operand" "")
5643 (const_string "lea")
5644 (match_operand:SI 2 "incdec_operand" "")
5645 (const_string "incdec")
5646 ]
5647 (const_string "alu")))
5648 (set_attr "mode" "SI")])
5649
5650 ;; Convert lea to the lea pattern to avoid flags dependency.
5651 (define_split
5652 [(set (match_operand:DI 0 "register_operand" "")
5653 (zero_extend:DI
5654 (plus:SI (match_operand:SI 1 "register_operand" "")
5655 (match_operand:SI 2 "nonmemory_operand" ""))))
5656 (clobber (reg:CC 17))]
5657 "TARGET_64BIT && reload_completed
5658 && true_regnum (operands[0]) != true_regnum (operands[1])"
5659 [(set (match_dup 0)
5660 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5661 {
5662 operands[1] = gen_lowpart (Pmode, operands[1]);
5663 operands[2] = gen_lowpart (Pmode, operands[2]);
5664 })
5665
5666 (define_insn "*addsi_2"
5667 [(set (reg 17)
5668 (compare
5669 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5670 (match_operand:SI 2 "general_operand" "rmni,rni"))
5671 (const_int 0)))
5672 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5673 (plus:SI (match_dup 1) (match_dup 2)))]
5674 "ix86_match_ccmode (insn, CCGOCmode)
5675 && ix86_binary_operator_ok (PLUS, SImode, operands)
5676 /* Current assemblers are broken and do not allow @GOTOFF in
5677 ought but a memory context. */
5678 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5679 {
5680 switch (get_attr_type (insn))
5681 {
5682 case TYPE_INCDEC:
5683 if (! rtx_equal_p (operands[0], operands[1]))
5684 abort ();
5685 if (operands[2] == const1_rtx)
5686 return "inc{l}\t%0";
5687 else if (operands[2] == constm1_rtx)
5688 return "dec{l}\t%0";
5689 else
5690 abort();
5691
5692 default:
5693 if (! rtx_equal_p (operands[0], operands[1]))
5694 abort ();
5695 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5696 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5697 if (GET_CODE (operands[2]) == CONST_INT
5698 && (INTVAL (operands[2]) == 128
5699 || (INTVAL (operands[2]) < 0
5700 && INTVAL (operands[2]) != -128)))
5701 {
5702 operands[2] = GEN_INT (-INTVAL (operands[2]));
5703 return "sub{l}\t{%2, %0|%0, %2}";
5704 }
5705 return "add{l}\t{%2, %0|%0, %2}";
5706 }
5707 }
5708 [(set (attr "type")
5709 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5710 (const_string "incdec")
5711 (const_string "alu")))
5712 (set_attr "mode" "SI")])
5713
5714 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5715 (define_insn "*addsi_2_zext"
5716 [(set (reg 17)
5717 (compare
5718 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5719 (match_operand:SI 2 "general_operand" "rmni"))
5720 (const_int 0)))
5721 (set (match_operand:DI 0 "register_operand" "=r")
5722 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5723 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5724 && ix86_binary_operator_ok (PLUS, SImode, operands)
5725 /* Current assemblers are broken and do not allow @GOTOFF in
5726 ought but a memory context. */
5727 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5728 {
5729 switch (get_attr_type (insn))
5730 {
5731 case TYPE_INCDEC:
5732 if (operands[2] == const1_rtx)
5733 return "inc{l}\t%k0";
5734 else if (operands[2] == constm1_rtx)
5735 return "dec{l}\t%k0";
5736 else
5737 abort();
5738
5739 default:
5740 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5741 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5742 if (GET_CODE (operands[2]) == CONST_INT
5743 && (INTVAL (operands[2]) == 128
5744 || (INTVAL (operands[2]) < 0
5745 && INTVAL (operands[2]) != -128)))
5746 {
5747 operands[2] = GEN_INT (-INTVAL (operands[2]));
5748 return "sub{l}\t{%2, %k0|%k0, %2}";
5749 }
5750 return "add{l}\t{%2, %k0|%k0, %2}";
5751 }
5752 }
5753 [(set (attr "type")
5754 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5755 (const_string "incdec")
5756 (const_string "alu")))
5757 (set_attr "mode" "SI")])
5758
5759 (define_insn "*addsi_3"
5760 [(set (reg 17)
5761 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5762 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5763 (clobber (match_scratch:SI 0 "=r"))]
5764 "ix86_match_ccmode (insn, CCZmode)
5765 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5766 /* Current assemblers are broken and do not allow @GOTOFF in
5767 ought but a memory context. */
5768 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5769 {
5770 switch (get_attr_type (insn))
5771 {
5772 case TYPE_INCDEC:
5773 if (! rtx_equal_p (operands[0], operands[1]))
5774 abort ();
5775 if (operands[2] == const1_rtx)
5776 return "inc{l}\t%0";
5777 else if (operands[2] == constm1_rtx)
5778 return "dec{l}\t%0";
5779 else
5780 abort();
5781
5782 default:
5783 if (! rtx_equal_p (operands[0], operands[1]))
5784 abort ();
5785 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5786 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5787 if (GET_CODE (operands[2]) == CONST_INT
5788 && (INTVAL (operands[2]) == 128
5789 || (INTVAL (operands[2]) < 0
5790 && INTVAL (operands[2]) != -128)))
5791 {
5792 operands[2] = GEN_INT (-INTVAL (operands[2]));
5793 return "sub{l}\t{%2, %0|%0, %2}";
5794 }
5795 return "add{l}\t{%2, %0|%0, %2}";
5796 }
5797 }
5798 [(set (attr "type")
5799 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5800 (const_string "incdec")
5801 (const_string "alu")))
5802 (set_attr "mode" "SI")])
5803
5804 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5805 (define_insn "*addsi_3_zext"
5806 [(set (reg 17)
5807 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5808 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5809 (set (match_operand:DI 0 "register_operand" "=r")
5810 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5811 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5812 && ix86_binary_operator_ok (PLUS, SImode, operands)
5813 /* Current assemblers are broken and do not allow @GOTOFF in
5814 ought but a memory context. */
5815 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5816 {
5817 switch (get_attr_type (insn))
5818 {
5819 case TYPE_INCDEC:
5820 if (operands[2] == const1_rtx)
5821 return "inc{l}\t%k0";
5822 else if (operands[2] == constm1_rtx)
5823 return "dec{l}\t%k0";
5824 else
5825 abort();
5826
5827 default:
5828 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5829 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5830 if (GET_CODE (operands[2]) == CONST_INT
5831 && (INTVAL (operands[2]) == 128
5832 || (INTVAL (operands[2]) < 0
5833 && INTVAL (operands[2]) != -128)))
5834 {
5835 operands[2] = GEN_INT (-INTVAL (operands[2]));
5836 return "sub{l}\t{%2, %k0|%k0, %2}";
5837 }
5838 return "add{l}\t{%2, %k0|%k0, %2}";
5839 }
5840 }
5841 [(set (attr "type")
5842 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5843 (const_string "incdec")
5844 (const_string "alu")))
5845 (set_attr "mode" "SI")])
5846
5847 ; For comparisons against 1, -1 and 128, we may generate better code
5848 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5849 ; is matched then. We can't accept general immediate, because for
5850 ; case of overflows, the result is messed up.
5851 ; This pattern also don't hold of 0x80000000, since the value overflows
5852 ; when negated.
5853 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5854 ; only for comparisons not depending on it.
5855 (define_insn "*addsi_4"
5856 [(set (reg 17)
5857 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5858 (match_operand:SI 2 "const_int_operand" "n")))
5859 (clobber (match_scratch:SI 0 "=rm"))]
5860 "ix86_match_ccmode (insn, CCGCmode)
5861 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5862 {
5863 switch (get_attr_type (insn))
5864 {
5865 case TYPE_INCDEC:
5866 if (operands[2] == constm1_rtx)
5867 return "inc{l}\t%0";
5868 else if (operands[2] == const1_rtx)
5869 return "dec{l}\t%0";
5870 else
5871 abort();
5872
5873 default:
5874 if (! rtx_equal_p (operands[0], operands[1]))
5875 abort ();
5876 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5877 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5878 if ((INTVAL (operands[2]) == -128
5879 || (INTVAL (operands[2]) > 0
5880 && INTVAL (operands[2]) != 128)))
5881 return "sub{l}\t{%2, %0|%0, %2}";
5882 operands[2] = GEN_INT (-INTVAL (operands[2]));
5883 return "add{l}\t{%2, %0|%0, %2}";
5884 }
5885 }
5886 [(set (attr "type")
5887 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5888 (const_string "incdec")
5889 (const_string "alu")))
5890 (set_attr "mode" "SI")])
5891
5892 (define_insn "*addsi_5"
5893 [(set (reg 17)
5894 (compare
5895 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5896 (match_operand:SI 2 "general_operand" "rmni"))
5897 (const_int 0)))
5898 (clobber (match_scratch:SI 0 "=r"))]
5899 "ix86_match_ccmode (insn, CCGOCmode)
5900 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5901 /* Current assemblers are broken and do not allow @GOTOFF in
5902 ought but a memory context. */
5903 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5904 {
5905 switch (get_attr_type (insn))
5906 {
5907 case TYPE_INCDEC:
5908 if (! rtx_equal_p (operands[0], operands[1]))
5909 abort ();
5910 if (operands[2] == const1_rtx)
5911 return "inc{l}\t%0";
5912 else if (operands[2] == constm1_rtx)
5913 return "dec{l}\t%0";
5914 else
5915 abort();
5916
5917 default:
5918 if (! rtx_equal_p (operands[0], operands[1]))
5919 abort ();
5920 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5921 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5922 if (GET_CODE (operands[2]) == CONST_INT
5923 && (INTVAL (operands[2]) == 128
5924 || (INTVAL (operands[2]) < 0
5925 && INTVAL (operands[2]) != -128)))
5926 {
5927 operands[2] = GEN_INT (-INTVAL (operands[2]));
5928 return "sub{l}\t{%2, %0|%0, %2}";
5929 }
5930 return "add{l}\t{%2, %0|%0, %2}";
5931 }
5932 }
5933 [(set (attr "type")
5934 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5935 (const_string "incdec")
5936 (const_string "alu")))
5937 (set_attr "mode" "SI")])
5938
5939 (define_expand "addhi3"
5940 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5941 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5942 (match_operand:HI 2 "general_operand" "")))
5943 (clobber (reg:CC 17))])]
5944 "TARGET_HIMODE_MATH"
5945 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5946
5947 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5948 ;; type optimizations enabled by define-splits. This is not important
5949 ;; for PII, and in fact harmful because of partial register stalls.
5950
5951 (define_insn "*addhi_1_lea"
5952 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5953 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5954 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5955 (clobber (reg:CC 17))]
5956 "!TARGET_PARTIAL_REG_STALL
5957 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5958 {
5959 switch (get_attr_type (insn))
5960 {
5961 case TYPE_LEA:
5962 return "#";
5963 case TYPE_INCDEC:
5964 if (operands[2] == const1_rtx)
5965 return "inc{w}\t%0";
5966 else if (operands[2] == constm1_rtx)
5967 return "dec{w}\t%0";
5968 abort();
5969
5970 default:
5971 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5972 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5973 if (GET_CODE (operands[2]) == CONST_INT
5974 && (INTVAL (operands[2]) == 128
5975 || (INTVAL (operands[2]) < 0
5976 && INTVAL (operands[2]) != -128)))
5977 {
5978 operands[2] = GEN_INT (-INTVAL (operands[2]));
5979 return "sub{w}\t{%2, %0|%0, %2}";
5980 }
5981 return "add{w}\t{%2, %0|%0, %2}";
5982 }
5983 }
5984 [(set (attr "type")
5985 (if_then_else (eq_attr "alternative" "2")
5986 (const_string "lea")
5987 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5988 (const_string "incdec")
5989 (const_string "alu"))))
5990 (set_attr "mode" "HI,HI,SI")])
5991
5992 (define_insn "*addhi_1"
5993 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5994 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5995 (match_operand:HI 2 "general_operand" "ri,rm")))
5996 (clobber (reg:CC 17))]
5997 "TARGET_PARTIAL_REG_STALL
5998 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5999 {
6000 switch (get_attr_type (insn))
6001 {
6002 case TYPE_INCDEC:
6003 if (operands[2] == const1_rtx)
6004 return "inc{w}\t%0";
6005 else if (operands[2] == constm1_rtx)
6006 return "dec{w}\t%0";
6007 abort();
6008
6009 default:
6010 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6012 if (GET_CODE (operands[2]) == CONST_INT
6013 && (INTVAL (operands[2]) == 128
6014 || (INTVAL (operands[2]) < 0
6015 && INTVAL (operands[2]) != -128)))
6016 {
6017 operands[2] = GEN_INT (-INTVAL (operands[2]));
6018 return "sub{w}\t{%2, %0|%0, %2}";
6019 }
6020 return "add{w}\t{%2, %0|%0, %2}";
6021 }
6022 }
6023 [(set (attr "type")
6024 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6025 (const_string "incdec")
6026 (const_string "alu")))
6027 (set_attr "mode" "HI")])
6028
6029 (define_insn "*addhi_2"
6030 [(set (reg 17)
6031 (compare
6032 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6033 (match_operand:HI 2 "general_operand" "rmni,rni"))
6034 (const_int 0)))
6035 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6036 (plus:HI (match_dup 1) (match_dup 2)))]
6037 "ix86_match_ccmode (insn, CCGOCmode)
6038 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6039 {
6040 switch (get_attr_type (insn))
6041 {
6042 case TYPE_INCDEC:
6043 if (operands[2] == const1_rtx)
6044 return "inc{w}\t%0";
6045 else if (operands[2] == constm1_rtx)
6046 return "dec{w}\t%0";
6047 abort();
6048
6049 default:
6050 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6052 if (GET_CODE (operands[2]) == CONST_INT
6053 && (INTVAL (operands[2]) == 128
6054 || (INTVAL (operands[2]) < 0
6055 && INTVAL (operands[2]) != -128)))
6056 {
6057 operands[2] = GEN_INT (-INTVAL (operands[2]));
6058 return "sub{w}\t{%2, %0|%0, %2}";
6059 }
6060 return "add{w}\t{%2, %0|%0, %2}";
6061 }
6062 }
6063 [(set (attr "type")
6064 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6065 (const_string "incdec")
6066 (const_string "alu")))
6067 (set_attr "mode" "HI")])
6068
6069 (define_insn "*addhi_3"
6070 [(set (reg 17)
6071 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6072 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6073 (clobber (match_scratch:HI 0 "=r"))]
6074 "ix86_match_ccmode (insn, CCZmode)
6075 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6076 {
6077 switch (get_attr_type (insn))
6078 {
6079 case TYPE_INCDEC:
6080 if (operands[2] == const1_rtx)
6081 return "inc{w}\t%0";
6082 else if (operands[2] == constm1_rtx)
6083 return "dec{w}\t%0";
6084 abort();
6085
6086 default:
6087 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6088 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6089 if (GET_CODE (operands[2]) == CONST_INT
6090 && (INTVAL (operands[2]) == 128
6091 || (INTVAL (operands[2]) < 0
6092 && INTVAL (operands[2]) != -128)))
6093 {
6094 operands[2] = GEN_INT (-INTVAL (operands[2]));
6095 return "sub{w}\t{%2, %0|%0, %2}";
6096 }
6097 return "add{w}\t{%2, %0|%0, %2}";
6098 }
6099 }
6100 [(set (attr "type")
6101 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6102 (const_string "incdec")
6103 (const_string "alu")))
6104 (set_attr "mode" "HI")])
6105
6106 ; See comments above addsi_3_imm for details.
6107 (define_insn "*addhi_4"
6108 [(set (reg 17)
6109 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6110 (match_operand:HI 2 "const_int_operand" "n")))
6111 (clobber (match_scratch:HI 0 "=rm"))]
6112 "ix86_match_ccmode (insn, CCGCmode)
6113 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6114 {
6115 switch (get_attr_type (insn))
6116 {
6117 case TYPE_INCDEC:
6118 if (operands[2] == constm1_rtx)
6119 return "inc{w}\t%0";
6120 else if (operands[2] == const1_rtx)
6121 return "dec{w}\t%0";
6122 else
6123 abort();
6124
6125 default:
6126 if (! rtx_equal_p (operands[0], operands[1]))
6127 abort ();
6128 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6129 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6130 if ((INTVAL (operands[2]) == -128
6131 || (INTVAL (operands[2]) > 0
6132 && INTVAL (operands[2]) != 128)))
6133 return "sub{w}\t{%2, %0|%0, %2}";
6134 operands[2] = GEN_INT (-INTVAL (operands[2]));
6135 return "add{w}\t{%2, %0|%0, %2}";
6136 }
6137 }
6138 [(set (attr "type")
6139 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6140 (const_string "incdec")
6141 (const_string "alu")))
6142 (set_attr "mode" "SI")])
6143
6144
6145 (define_insn "*addhi_5"
6146 [(set (reg 17)
6147 (compare
6148 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6149 (match_operand:HI 2 "general_operand" "rmni"))
6150 (const_int 0)))
6151 (clobber (match_scratch:HI 0 "=r"))]
6152 "ix86_match_ccmode (insn, CCGOCmode)
6153 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6154 {
6155 switch (get_attr_type (insn))
6156 {
6157 case TYPE_INCDEC:
6158 if (operands[2] == const1_rtx)
6159 return "inc{w}\t%0";
6160 else if (operands[2] == constm1_rtx)
6161 return "dec{w}\t%0";
6162 abort();
6163
6164 default:
6165 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6166 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6167 if (GET_CODE (operands[2]) == CONST_INT
6168 && (INTVAL (operands[2]) == 128
6169 || (INTVAL (operands[2]) < 0
6170 && INTVAL (operands[2]) != -128)))
6171 {
6172 operands[2] = GEN_INT (-INTVAL (operands[2]));
6173 return "sub{w}\t{%2, %0|%0, %2}";
6174 }
6175 return "add{w}\t{%2, %0|%0, %2}";
6176 }
6177 }
6178 [(set (attr "type")
6179 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6180 (const_string "incdec")
6181 (const_string "alu")))
6182 (set_attr "mode" "HI")])
6183
6184 (define_expand "addqi3"
6185 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6186 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6187 (match_operand:QI 2 "general_operand" "")))
6188 (clobber (reg:CC 17))])]
6189 "TARGET_QIMODE_MATH"
6190 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6191
6192 ;; %%% Potential partial reg stall on alternative 2. What to do?
6193 (define_insn "*addqi_1_lea"
6194 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6195 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6196 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6197 (clobber (reg:CC 17))]
6198 "!TARGET_PARTIAL_REG_STALL
6199 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6200 {
6201 int widen = (which_alternative == 2);
6202 switch (get_attr_type (insn))
6203 {
6204 case TYPE_LEA:
6205 return "#";
6206 case TYPE_INCDEC:
6207 if (operands[2] == const1_rtx)
6208 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6209 else if (operands[2] == constm1_rtx)
6210 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6211 abort();
6212
6213 default:
6214 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6215 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6216 if (GET_CODE (operands[2]) == CONST_INT
6217 && (INTVAL (operands[2]) == 128
6218 || (INTVAL (operands[2]) < 0
6219 && INTVAL (operands[2]) != -128)))
6220 {
6221 operands[2] = GEN_INT (-INTVAL (operands[2]));
6222 if (widen)
6223 return "sub{l}\t{%2, %k0|%k0, %2}";
6224 else
6225 return "sub{b}\t{%2, %0|%0, %2}";
6226 }
6227 if (widen)
6228 return "add{l}\t{%k2, %k0|%k0, %k2}";
6229 else
6230 return "add{b}\t{%2, %0|%0, %2}";
6231 }
6232 }
6233 [(set (attr "type")
6234 (if_then_else (eq_attr "alternative" "3")
6235 (const_string "lea")
6236 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6237 (const_string "incdec")
6238 (const_string "alu"))))
6239 (set_attr "mode" "QI,QI,SI,SI")])
6240
6241 (define_insn "*addqi_1"
6242 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6243 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6244 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6245 (clobber (reg:CC 17))]
6246 "TARGET_PARTIAL_REG_STALL
6247 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6248 {
6249 int widen = (which_alternative == 2);
6250 switch (get_attr_type (insn))
6251 {
6252 case TYPE_INCDEC:
6253 if (operands[2] == const1_rtx)
6254 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6255 else if (operands[2] == constm1_rtx)
6256 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6257 abort();
6258
6259 default:
6260 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6261 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6262 if (GET_CODE (operands[2]) == CONST_INT
6263 && (INTVAL (operands[2]) == 128
6264 || (INTVAL (operands[2]) < 0
6265 && INTVAL (operands[2]) != -128)))
6266 {
6267 operands[2] = GEN_INT (-INTVAL (operands[2]));
6268 if (widen)
6269 return "sub{l}\t{%2, %k0|%k0, %2}";
6270 else
6271 return "sub{b}\t{%2, %0|%0, %2}";
6272 }
6273 if (widen)
6274 return "add{l}\t{%k2, %k0|%k0, %k2}";
6275 else
6276 return "add{b}\t{%2, %0|%0, %2}";
6277 }
6278 }
6279 [(set (attr "type")
6280 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6281 (const_string "incdec")
6282 (const_string "alu")))
6283 (set_attr "mode" "QI,QI,SI")])
6284
6285 (define_insn "*addqi_1_slp"
6286 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6287 (plus:QI (match_dup 0)
6288 (match_operand:QI 1 "general_operand" "qn,qnm")))
6289 (clobber (reg:CC 17))]
6290 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6291 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6292 {
6293 switch (get_attr_type (insn))
6294 {
6295 case TYPE_INCDEC:
6296 if (operands[1] == const1_rtx)
6297 return "inc{b}\t%0";
6298 else if (operands[1] == constm1_rtx)
6299 return "dec{b}\t%0";
6300 abort();
6301
6302 default:
6303 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6304 if (GET_CODE (operands[1]) == CONST_INT
6305 && INTVAL (operands[1]) < 0)
6306 {
6307 operands[1] = GEN_INT (-INTVAL (operands[1]));
6308 return "sub{b}\t{%1, %0|%0, %1}";
6309 }
6310 return "add{b}\t{%1, %0|%0, %1}";
6311 }
6312 }
6313 [(set (attr "type")
6314 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6315 (const_string "incdec")
6316 (const_string "alu1")))
6317 (set_attr "mode" "QI")])
6318
6319 (define_insn "*addqi_2"
6320 [(set (reg 17)
6321 (compare
6322 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6323 (match_operand:QI 2 "general_operand" "qmni,qni"))
6324 (const_int 0)))
6325 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6326 (plus:QI (match_dup 1) (match_dup 2)))]
6327 "ix86_match_ccmode (insn, CCGOCmode)
6328 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6329 {
6330 switch (get_attr_type (insn))
6331 {
6332 case TYPE_INCDEC:
6333 if (operands[2] == const1_rtx)
6334 return "inc{b}\t%0";
6335 else if (operands[2] == constm1_rtx
6336 || (GET_CODE (operands[2]) == CONST_INT
6337 && INTVAL (operands[2]) == 255))
6338 return "dec{b}\t%0";
6339 abort();
6340
6341 default:
6342 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6343 if (GET_CODE (operands[2]) == CONST_INT
6344 && INTVAL (operands[2]) < 0)
6345 {
6346 operands[2] = GEN_INT (-INTVAL (operands[2]));
6347 return "sub{b}\t{%2, %0|%0, %2}";
6348 }
6349 return "add{b}\t{%2, %0|%0, %2}";
6350 }
6351 }
6352 [(set (attr "type")
6353 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6354 (const_string "incdec")
6355 (const_string "alu")))
6356 (set_attr "mode" "QI")])
6357
6358 (define_insn "*addqi_3"
6359 [(set (reg 17)
6360 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6361 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6362 (clobber (match_scratch:QI 0 "=q"))]
6363 "ix86_match_ccmode (insn, CCZmode)
6364 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6365 {
6366 switch (get_attr_type (insn))
6367 {
6368 case TYPE_INCDEC:
6369 if (operands[2] == const1_rtx)
6370 return "inc{b}\t%0";
6371 else if (operands[2] == constm1_rtx
6372 || (GET_CODE (operands[2]) == CONST_INT
6373 && INTVAL (operands[2]) == 255))
6374 return "dec{b}\t%0";
6375 abort();
6376
6377 default:
6378 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6379 if (GET_CODE (operands[2]) == CONST_INT
6380 && INTVAL (operands[2]) < 0)
6381 {
6382 operands[2] = GEN_INT (-INTVAL (operands[2]));
6383 return "sub{b}\t{%2, %0|%0, %2}";
6384 }
6385 return "add{b}\t{%2, %0|%0, %2}";
6386 }
6387 }
6388 [(set (attr "type")
6389 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6390 (const_string "incdec")
6391 (const_string "alu")))
6392 (set_attr "mode" "QI")])
6393
6394 ; See comments above addsi_3_imm for details.
6395 (define_insn "*addqi_4"
6396 [(set (reg 17)
6397 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6398 (match_operand:QI 2 "const_int_operand" "n")))
6399 (clobber (match_scratch:QI 0 "=qm"))]
6400 "ix86_match_ccmode (insn, CCGCmode)
6401 && (INTVAL (operands[2]) & 0xff) != 0x80"
6402 {
6403 switch (get_attr_type (insn))
6404 {
6405 case TYPE_INCDEC:
6406 if (operands[2] == constm1_rtx
6407 || (GET_CODE (operands[2]) == CONST_INT
6408 && INTVAL (operands[2]) == 255))
6409 return "inc{b}\t%0";
6410 else if (operands[2] == const1_rtx)
6411 return "dec{b}\t%0";
6412 else
6413 abort();
6414
6415 default:
6416 if (! rtx_equal_p (operands[0], operands[1]))
6417 abort ();
6418 if (INTVAL (operands[2]) < 0)
6419 {
6420 operands[2] = GEN_INT (-INTVAL (operands[2]));
6421 return "add{b}\t{%2, %0|%0, %2}";
6422 }
6423 return "sub{b}\t{%2, %0|%0, %2}";
6424 }
6425 }
6426 [(set (attr "type")
6427 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6428 (const_string "incdec")
6429 (const_string "alu")))
6430 (set_attr "mode" "QI")])
6431
6432
6433 (define_insn "*addqi_5"
6434 [(set (reg 17)
6435 (compare
6436 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6437 (match_operand:QI 2 "general_operand" "qmni"))
6438 (const_int 0)))
6439 (clobber (match_scratch:QI 0 "=q"))]
6440 "ix86_match_ccmode (insn, CCGOCmode)
6441 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6442 {
6443 switch (get_attr_type (insn))
6444 {
6445 case TYPE_INCDEC:
6446 if (operands[2] == const1_rtx)
6447 return "inc{b}\t%0";
6448 else if (operands[2] == constm1_rtx
6449 || (GET_CODE (operands[2]) == CONST_INT
6450 && INTVAL (operands[2]) == 255))
6451 return "dec{b}\t%0";
6452 abort();
6453
6454 default:
6455 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6456 if (GET_CODE (operands[2]) == CONST_INT
6457 && INTVAL (operands[2]) < 0)
6458 {
6459 operands[2] = GEN_INT (-INTVAL (operands[2]));
6460 return "sub{b}\t{%2, %0|%0, %2}";
6461 }
6462 return "add{b}\t{%2, %0|%0, %2}";
6463 }
6464 }
6465 [(set (attr "type")
6466 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6467 (const_string "incdec")
6468 (const_string "alu")))
6469 (set_attr "mode" "QI")])
6470
6471
6472 (define_insn "addqi_ext_1"
6473 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6474 (const_int 8)
6475 (const_int 8))
6476 (plus:SI
6477 (zero_extract:SI
6478 (match_operand 1 "ext_register_operand" "0")
6479 (const_int 8)
6480 (const_int 8))
6481 (match_operand:QI 2 "general_operand" "Qmn")))
6482 (clobber (reg:CC 17))]
6483 "!TARGET_64BIT"
6484 {
6485 switch (get_attr_type (insn))
6486 {
6487 case TYPE_INCDEC:
6488 if (operands[2] == const1_rtx)
6489 return "inc{b}\t%h0";
6490 else if (operands[2] == constm1_rtx
6491 || (GET_CODE (operands[2]) == CONST_INT
6492 && INTVAL (operands[2]) == 255))
6493 return "dec{b}\t%h0";
6494 abort();
6495
6496 default:
6497 return "add{b}\t{%2, %h0|%h0, %2}";
6498 }
6499 }
6500 [(set (attr "type")
6501 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6502 (const_string "incdec")
6503 (const_string "alu")))
6504 (set_attr "mode" "QI")])
6505
6506 (define_insn "*addqi_ext_1_rex64"
6507 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6508 (const_int 8)
6509 (const_int 8))
6510 (plus:SI
6511 (zero_extract:SI
6512 (match_operand 1 "ext_register_operand" "0")
6513 (const_int 8)
6514 (const_int 8))
6515 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6516 (clobber (reg:CC 17))]
6517 "TARGET_64BIT"
6518 {
6519 switch (get_attr_type (insn))
6520 {
6521 case TYPE_INCDEC:
6522 if (operands[2] == const1_rtx)
6523 return "inc{b}\t%h0";
6524 else if (operands[2] == constm1_rtx
6525 || (GET_CODE (operands[2]) == CONST_INT
6526 && INTVAL (operands[2]) == 255))
6527 return "dec{b}\t%h0";
6528 abort();
6529
6530 default:
6531 return "add{b}\t{%2, %h0|%h0, %2}";
6532 }
6533 }
6534 [(set (attr "type")
6535 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6536 (const_string "incdec")
6537 (const_string "alu")))
6538 (set_attr "mode" "QI")])
6539
6540 (define_insn "*addqi_ext_2"
6541 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6542 (const_int 8)
6543 (const_int 8))
6544 (plus:SI
6545 (zero_extract:SI
6546 (match_operand 1 "ext_register_operand" "%0")
6547 (const_int 8)
6548 (const_int 8))
6549 (zero_extract:SI
6550 (match_operand 2 "ext_register_operand" "Q")
6551 (const_int 8)
6552 (const_int 8))))
6553 (clobber (reg:CC 17))]
6554 ""
6555 "add{b}\t{%h2, %h0|%h0, %h2}"
6556 [(set_attr "type" "alu")
6557 (set_attr "mode" "QI")])
6558
6559 ;; The patterns that match these are at the end of this file.
6560
6561 (define_expand "addxf3"
6562 [(set (match_operand:XF 0 "register_operand" "")
6563 (plus:XF (match_operand:XF 1 "register_operand" "")
6564 (match_operand:XF 2 "register_operand" "")))]
6565 "TARGET_80387"
6566 "")
6567
6568 (define_expand "adddf3"
6569 [(set (match_operand:DF 0 "register_operand" "")
6570 (plus:DF (match_operand:DF 1 "register_operand" "")
6571 (match_operand:DF 2 "nonimmediate_operand" "")))]
6572 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6573 "")
6574
6575 (define_expand "addsf3"
6576 [(set (match_operand:SF 0 "register_operand" "")
6577 (plus:SF (match_operand:SF 1 "register_operand" "")
6578 (match_operand:SF 2 "nonimmediate_operand" "")))]
6579 "TARGET_80387 || TARGET_SSE_MATH"
6580 "")
6581 \f
6582 ;; Subtract instructions
6583
6584 ;; %%% splits for subsidi3
6585
6586 (define_expand "subdi3"
6587 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6588 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6589 (match_operand:DI 2 "x86_64_general_operand" "")))
6590 (clobber (reg:CC 17))])]
6591 ""
6592 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6593
6594 (define_insn "*subdi3_1"
6595 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6596 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6597 (match_operand:DI 2 "general_operand" "roiF,riF")))
6598 (clobber (reg:CC 17))]
6599 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6600 "#")
6601
6602 (define_split
6603 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6604 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6605 (match_operand:DI 2 "general_operand" "")))
6606 (clobber (reg:CC 17))]
6607 "!TARGET_64BIT && reload_completed"
6608 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6609 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6610 (parallel [(set (match_dup 3)
6611 (minus:SI (match_dup 4)
6612 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6613 (match_dup 5))))
6614 (clobber (reg:CC 17))])]
6615 "split_di (operands+0, 1, operands+0, operands+3);
6616 split_di (operands+1, 1, operands+1, operands+4);
6617 split_di (operands+2, 1, operands+2, operands+5);")
6618
6619 (define_insn "subdi3_carry_rex64"
6620 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6621 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6623 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6624 (clobber (reg:CC 17))]
6625 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6626 "sbb{q}\t{%2, %0|%0, %2}"
6627 [(set_attr "type" "alu")
6628 (set_attr "pent_pair" "pu")
6629 (set_attr "mode" "DI")])
6630
6631 (define_insn "*subdi_1_rex64"
6632 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6633 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6634 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6635 (clobber (reg:CC 17))]
6636 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6637 "sub{q}\t{%2, %0|%0, %2}"
6638 [(set_attr "type" "alu")
6639 (set_attr "mode" "DI")])
6640
6641 (define_insn "*subdi_2_rex64"
6642 [(set (reg 17)
6643 (compare
6644 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6645 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6646 (const_int 0)))
6647 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6648 (minus:DI (match_dup 1) (match_dup 2)))]
6649 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6650 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6651 "sub{q}\t{%2, %0|%0, %2}"
6652 [(set_attr "type" "alu")
6653 (set_attr "mode" "DI")])
6654
6655 (define_insn "*subdi_3_rex63"
6656 [(set (reg 17)
6657 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6658 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6659 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6660 (minus:DI (match_dup 1) (match_dup 2)))]
6661 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6662 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6663 "sub{q}\t{%2, %0|%0, %2}"
6664 [(set_attr "type" "alu")
6665 (set_attr "mode" "DI")])
6666
6667 (define_insn "subqi3_carry"
6668 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6669 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6670 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6671 (match_operand:QI 2 "general_operand" "qi,qm"))))
6672 (clobber (reg:CC 17))]
6673 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6674 "sbb{b}\t{%2, %0|%0, %2}"
6675 [(set_attr "type" "alu")
6676 (set_attr "pent_pair" "pu")
6677 (set_attr "mode" "QI")])
6678
6679 (define_insn "subhi3_carry"
6680 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6681 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6682 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6683 (match_operand:HI 2 "general_operand" "ri,rm"))))
6684 (clobber (reg:CC 17))]
6685 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6686 "sbb{w}\t{%2, %0|%0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "pent_pair" "pu")
6689 (set_attr "mode" "HI")])
6690
6691 (define_insn "subsi3_carry"
6692 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6693 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6694 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6695 (match_operand:SI 2 "general_operand" "ri,rm"))))
6696 (clobber (reg:CC 17))]
6697 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6698 "sbb{l}\t{%2, %0|%0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "pent_pair" "pu")
6701 (set_attr "mode" "SI")])
6702
6703 (define_insn "subsi3_carry_zext"
6704 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6705 (zero_extend:DI
6706 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6707 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6708 (match_operand:SI 2 "general_operand" "ri,rm")))))
6709 (clobber (reg:CC 17))]
6710 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6711 "sbb{l}\t{%2, %k0|%k0, %2}"
6712 [(set_attr "type" "alu")
6713 (set_attr "pent_pair" "pu")
6714 (set_attr "mode" "SI")])
6715
6716 (define_expand "subsi3"
6717 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6718 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6719 (match_operand:SI 2 "general_operand" "")))
6720 (clobber (reg:CC 17))])]
6721 ""
6722 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6723
6724 (define_insn "*subsi_1"
6725 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6726 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6727 (match_operand:SI 2 "general_operand" "ri,rm")))
6728 (clobber (reg:CC 17))]
6729 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6730 "sub{l}\t{%2, %0|%0, %2}"
6731 [(set_attr "type" "alu")
6732 (set_attr "mode" "SI")])
6733
6734 (define_insn "*subsi_1_zext"
6735 [(set (match_operand:DI 0 "register_operand" "=r")
6736 (zero_extend:DI
6737 (minus:SI (match_operand:SI 1 "register_operand" "0")
6738 (match_operand:SI 2 "general_operand" "rim"))))
6739 (clobber (reg:CC 17))]
6740 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6741 "sub{l}\t{%2, %k0|%k0, %2}"
6742 [(set_attr "type" "alu")
6743 (set_attr "mode" "SI")])
6744
6745 (define_insn "*subsi_2"
6746 [(set (reg 17)
6747 (compare
6748 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6749 (match_operand:SI 2 "general_operand" "ri,rm"))
6750 (const_int 0)))
6751 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6752 (minus:SI (match_dup 1) (match_dup 2)))]
6753 "ix86_match_ccmode (insn, CCGOCmode)
6754 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6755 "sub{l}\t{%2, %0|%0, %2}"
6756 [(set_attr "type" "alu")
6757 (set_attr "mode" "SI")])
6758
6759 (define_insn "*subsi_2_zext"
6760 [(set (reg 17)
6761 (compare
6762 (minus:SI (match_operand:SI 1 "register_operand" "0")
6763 (match_operand:SI 2 "general_operand" "rim"))
6764 (const_int 0)))
6765 (set (match_operand:DI 0 "register_operand" "=r")
6766 (zero_extend:DI
6767 (minus:SI (match_dup 1)
6768 (match_dup 2))))]
6769 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6770 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6771 "sub{l}\t{%2, %k0|%k0, %2}"
6772 [(set_attr "type" "alu")
6773 (set_attr "mode" "SI")])
6774
6775 (define_insn "*subsi_3"
6776 [(set (reg 17)
6777 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6778 (match_operand:SI 2 "general_operand" "ri,rm")))
6779 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6780 (minus:SI (match_dup 1) (match_dup 2)))]
6781 "ix86_match_ccmode (insn, CCmode)
6782 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6783 "sub{l}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "SI")])
6786
6787 (define_insn "*subsi_3_zext"
6788 [(set (reg 17)
6789 (compare (match_operand:SI 1 "register_operand" "0")
6790 (match_operand:SI 2 "general_operand" "rim")))
6791 (set (match_operand:DI 0 "register_operand" "=r")
6792 (zero_extend:DI
6793 (minus:SI (match_dup 1)
6794 (match_dup 2))))]
6795 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6796 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6797 "sub{q}\t{%2, %0|%0, %2}"
6798 [(set_attr "type" "alu")
6799 (set_attr "mode" "DI")])
6800
6801 (define_expand "subhi3"
6802 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6803 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6804 (match_operand:HI 2 "general_operand" "")))
6805 (clobber (reg:CC 17))])]
6806 "TARGET_HIMODE_MATH"
6807 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6808
6809 (define_insn "*subhi_1"
6810 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6811 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6812 (match_operand:HI 2 "general_operand" "ri,rm")))
6813 (clobber (reg:CC 17))]
6814 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6815 "sub{w}\t{%2, %0|%0, %2}"
6816 [(set_attr "type" "alu")
6817 (set_attr "mode" "HI")])
6818
6819 (define_insn "*subhi_2"
6820 [(set (reg 17)
6821 (compare
6822 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6823 (match_operand:HI 2 "general_operand" "ri,rm"))
6824 (const_int 0)))
6825 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6826 (minus:HI (match_dup 1) (match_dup 2)))]
6827 "ix86_match_ccmode (insn, CCGOCmode)
6828 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6829 "sub{w}\t{%2, %0|%0, %2}"
6830 [(set_attr "type" "alu")
6831 (set_attr "mode" "HI")])
6832
6833 (define_insn "*subhi_3"
6834 [(set (reg 17)
6835 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6836 (match_operand:HI 2 "general_operand" "ri,rm")))
6837 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6838 (minus:HI (match_dup 1) (match_dup 2)))]
6839 "ix86_match_ccmode (insn, CCmode)
6840 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6841 "sub{w}\t{%2, %0|%0, %2}"
6842 [(set_attr "type" "alu")
6843 (set_attr "mode" "HI")])
6844
6845 (define_expand "subqi3"
6846 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6847 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6848 (match_operand:QI 2 "general_operand" "")))
6849 (clobber (reg:CC 17))])]
6850 "TARGET_QIMODE_MATH"
6851 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6852
6853 (define_insn "*subqi_1"
6854 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6855 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6856 (match_operand:QI 2 "general_operand" "qn,qmn")))
6857 (clobber (reg:CC 17))]
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 (define_insn "*subqi_1_slp"
6864 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6865 (minus:QI (match_dup 0)
6866 (match_operand:QI 1 "general_operand" "qn,qmn")))
6867 (clobber (reg:CC 17))]
6868 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6869 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6870 "sub{b}\t{%1, %0|%0, %1}"
6871 [(set_attr "type" "alu1")
6872 (set_attr "mode" "QI")])
6873
6874 (define_insn "*subqi_2"
6875 [(set (reg 17)
6876 (compare
6877 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878 (match_operand:QI 2 "general_operand" "qi,qm"))
6879 (const_int 0)))
6880 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6881 (minus:HI (match_dup 1) (match_dup 2)))]
6882 "ix86_match_ccmode (insn, CCGOCmode)
6883 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6884 "sub{b}\t{%2, %0|%0, %2}"
6885 [(set_attr "type" "alu")
6886 (set_attr "mode" "QI")])
6887
6888 (define_insn "*subqi_3"
6889 [(set (reg 17)
6890 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6891 (match_operand:QI 2 "general_operand" "qi,qm")))
6892 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6893 (minus:HI (match_dup 1) (match_dup 2)))]
6894 "ix86_match_ccmode (insn, CCmode)
6895 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6896 "sub{b}\t{%2, %0|%0, %2}"
6897 [(set_attr "type" "alu")
6898 (set_attr "mode" "QI")])
6899
6900 ;; The patterns that match these are at the end of this file.
6901
6902 (define_expand "subxf3"
6903 [(set (match_operand:XF 0 "register_operand" "")
6904 (minus:XF (match_operand:XF 1 "register_operand" "")
6905 (match_operand:XF 2 "register_operand" "")))]
6906 "TARGET_80387"
6907 "")
6908
6909 (define_expand "subdf3"
6910 [(set (match_operand:DF 0 "register_operand" "")
6911 (minus:DF (match_operand:DF 1 "register_operand" "")
6912 (match_operand:DF 2 "nonimmediate_operand" "")))]
6913 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6914 "")
6915
6916 (define_expand "subsf3"
6917 [(set (match_operand:SF 0 "register_operand" "")
6918 (minus:SF (match_operand:SF 1 "register_operand" "")
6919 (match_operand:SF 2 "nonimmediate_operand" "")))]
6920 "TARGET_80387 || TARGET_SSE_MATH"
6921 "")
6922 \f
6923 ;; Multiply instructions
6924
6925 (define_expand "muldi3"
6926 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6927 (mult:DI (match_operand:DI 1 "register_operand" "")
6928 (match_operand:DI 2 "x86_64_general_operand" "")))
6929 (clobber (reg:CC 17))])]
6930 "TARGET_64BIT"
6931 "")
6932
6933 (define_insn "*muldi3_1_rex64"
6934 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6935 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6936 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6937 (clobber (reg:CC 17))]
6938 "TARGET_64BIT
6939 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6940 "@
6941 imul{q}\t{%2, %1, %0|%0, %1, %2}
6942 imul{q}\t{%2, %1, %0|%0, %1, %2}
6943 imul{q}\t{%2, %0|%0, %2}"
6944 [(set_attr "type" "imul")
6945 (set_attr "prefix_0f" "0,0,1")
6946 (set (attr "athlon_decode")
6947 (cond [(eq_attr "cpu" "athlon")
6948 (const_string "vector")
6949 (eq_attr "alternative" "1")
6950 (const_string "vector")
6951 (and (eq_attr "alternative" "2")
6952 (match_operand 1 "memory_operand" ""))
6953 (const_string "vector")]
6954 (const_string "direct")))
6955 (set_attr "mode" "DI")])
6956
6957 (define_expand "mulsi3"
6958 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6959 (mult:SI (match_operand:SI 1 "register_operand" "")
6960 (match_operand:SI 2 "general_operand" "")))
6961 (clobber (reg:CC 17))])]
6962 ""
6963 "")
6964
6965 (define_insn "*mulsi3_1"
6966 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6967 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6968 (match_operand:SI 2 "general_operand" "K,i,mr")))
6969 (clobber (reg:CC 17))]
6970 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6971 "@
6972 imul{l}\t{%2, %1, %0|%0, %1, %2}
6973 imul{l}\t{%2, %1, %0|%0, %1, %2}
6974 imul{l}\t{%2, %0|%0, %2}"
6975 [(set_attr "type" "imul")
6976 (set_attr "prefix_0f" "0,0,1")
6977 (set (attr "athlon_decode")
6978 (cond [(eq_attr "cpu" "athlon")
6979 (const_string "vector")
6980 (eq_attr "alternative" "1")
6981 (const_string "vector")
6982 (and (eq_attr "alternative" "2")
6983 (match_operand 1 "memory_operand" ""))
6984 (const_string "vector")]
6985 (const_string "direct")))
6986 (set_attr "mode" "SI")])
6987
6988 (define_insn "*mulsi3_1_zext"
6989 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6990 (zero_extend:DI
6991 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6992 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6993 (clobber (reg:CC 17))]
6994 "TARGET_64BIT
6995 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6996 "@
6997 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6998 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6999 imul{l}\t{%2, %k0|%k0, %2}"
7000 [(set_attr "type" "imul")
7001 (set_attr "prefix_0f" "0,0,1")
7002 (set (attr "athlon_decode")
7003 (cond [(eq_attr "cpu" "athlon")
7004 (const_string "vector")
7005 (eq_attr "alternative" "1")
7006 (const_string "vector")
7007 (and (eq_attr "alternative" "2")
7008 (match_operand 1 "memory_operand" ""))
7009 (const_string "vector")]
7010 (const_string "direct")))
7011 (set_attr "mode" "SI")])
7012
7013 (define_expand "mulhi3"
7014 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7015 (mult:HI (match_operand:HI 1 "register_operand" "")
7016 (match_operand:HI 2 "general_operand" "")))
7017 (clobber (reg:CC 17))])]
7018 "TARGET_HIMODE_MATH"
7019 "")
7020
7021 (define_insn "*mulhi3_1"
7022 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7023 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7024 (match_operand:HI 2 "general_operand" "K,i,mr")))
7025 (clobber (reg:CC 17))]
7026 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7027 "@
7028 imul{w}\t{%2, %1, %0|%0, %1, %2}
7029 imul{w}\t{%2, %1, %0|%0, %1, %2}
7030 imul{w}\t{%2, %0|%0, %2}"
7031 [(set_attr "type" "imul")
7032 (set_attr "prefix_0f" "0,0,1")
7033 (set (attr "athlon_decode")
7034 (cond [(eq_attr "cpu" "athlon")
7035 (const_string "vector")
7036 (eq_attr "alternative" "1,2")
7037 (const_string "vector")]
7038 (const_string "direct")))
7039 (set_attr "mode" "HI")])
7040
7041 (define_expand "mulqi3"
7042 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7043 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7044 (match_operand:QI 2 "register_operand" "")))
7045 (clobber (reg:CC 17))])]
7046 "TARGET_QIMODE_MATH"
7047 "")
7048
7049 (define_insn "*mulqi3_1"
7050 [(set (match_operand:QI 0 "register_operand" "=a")
7051 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7052 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7053 (clobber (reg:CC 17))]
7054 "TARGET_QIMODE_MATH
7055 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7056 "mul{b}\t%2"
7057 [(set_attr "type" "imul")
7058 (set_attr "length_immediate" "0")
7059 (set (attr "athlon_decode")
7060 (if_then_else (eq_attr "cpu" "athlon")
7061 (const_string "vector")
7062 (const_string "direct")))
7063 (set_attr "mode" "QI")])
7064
7065 (define_expand "umulqihi3"
7066 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7067 (mult:HI (zero_extend:HI
7068 (match_operand:QI 1 "nonimmediate_operand" ""))
7069 (zero_extend:HI
7070 (match_operand:QI 2 "register_operand" ""))))
7071 (clobber (reg:CC 17))])]
7072 "TARGET_QIMODE_MATH"
7073 "")
7074
7075 (define_insn "*umulqihi3_1"
7076 [(set (match_operand:HI 0 "register_operand" "=a")
7077 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7078 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7079 (clobber (reg:CC 17))]
7080 "TARGET_QIMODE_MATH
7081 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7082 "mul{b}\t%2"
7083 [(set_attr "type" "imul")
7084 (set_attr "length_immediate" "0")
7085 (set (attr "athlon_decode")
7086 (if_then_else (eq_attr "cpu" "athlon")
7087 (const_string "vector")
7088 (const_string "direct")))
7089 (set_attr "mode" "QI")])
7090
7091 (define_expand "mulqihi3"
7092 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7093 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7094 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7095 (clobber (reg:CC 17))])]
7096 "TARGET_QIMODE_MATH"
7097 "")
7098
7099 (define_insn "*mulqihi3_insn"
7100 [(set (match_operand:HI 0 "register_operand" "=a")
7101 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7102 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7103 (clobber (reg:CC 17))]
7104 "TARGET_QIMODE_MATH
7105 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7106 "imul{b}\t%2"
7107 [(set_attr "type" "imul")
7108 (set_attr "length_immediate" "0")
7109 (set (attr "athlon_decode")
7110 (if_then_else (eq_attr "cpu" "athlon")
7111 (const_string "vector")
7112 (const_string "direct")))
7113 (set_attr "mode" "QI")])
7114
7115 (define_expand "umulditi3"
7116 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7117 (mult:TI (zero_extend:TI
7118 (match_operand:DI 1 "nonimmediate_operand" ""))
7119 (zero_extend:TI
7120 (match_operand:DI 2 "register_operand" ""))))
7121 (clobber (reg:CC 17))])]
7122 "TARGET_64BIT"
7123 "")
7124
7125 (define_insn "*umulditi3_insn"
7126 [(set (match_operand:TI 0 "register_operand" "=A")
7127 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7128 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7129 (clobber (reg:CC 17))]
7130 "TARGET_64BIT
7131 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7132 "mul{q}\t%2"
7133 [(set_attr "type" "imul")
7134 (set_attr "length_immediate" "0")
7135 (set (attr "athlon_decode")
7136 (if_then_else (eq_attr "cpu" "athlon")
7137 (const_string "vector")
7138 (const_string "double")))
7139 (set_attr "mode" "DI")])
7140
7141 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7142 (define_expand "umulsidi3"
7143 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7144 (mult:DI (zero_extend:DI
7145 (match_operand:SI 1 "nonimmediate_operand" ""))
7146 (zero_extend:DI
7147 (match_operand:SI 2 "register_operand" ""))))
7148 (clobber (reg:CC 17))])]
7149 "!TARGET_64BIT"
7150 "")
7151
7152 (define_insn "*umulsidi3_insn"
7153 [(set (match_operand:DI 0 "register_operand" "=A")
7154 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7155 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7156 (clobber (reg:CC 17))]
7157 "!TARGET_64BIT
7158 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7159 "mul{l}\t%2"
7160 [(set_attr "type" "imul")
7161 (set_attr "length_immediate" "0")
7162 (set (attr "athlon_decode")
7163 (if_then_else (eq_attr "cpu" "athlon")
7164 (const_string "vector")
7165 (const_string "double")))
7166 (set_attr "mode" "SI")])
7167
7168 (define_expand "mulditi3"
7169 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7170 (mult:TI (sign_extend:TI
7171 (match_operand:DI 1 "nonimmediate_operand" ""))
7172 (sign_extend:TI
7173 (match_operand:DI 2 "register_operand" ""))))
7174 (clobber (reg:CC 17))])]
7175 "TARGET_64BIT"
7176 "")
7177
7178 (define_insn "*mulditi3_insn"
7179 [(set (match_operand:TI 0 "register_operand" "=A")
7180 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7181 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7182 (clobber (reg:CC 17))]
7183 "TARGET_64BIT
7184 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7185 "imul{q}\t%2"
7186 [(set_attr "type" "imul")
7187 (set_attr "length_immediate" "0")
7188 (set (attr "athlon_decode")
7189 (if_then_else (eq_attr "cpu" "athlon")
7190 (const_string "vector")
7191 (const_string "double")))
7192 (set_attr "mode" "DI")])
7193
7194 (define_expand "mulsidi3"
7195 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7196 (mult:DI (sign_extend:DI
7197 (match_operand:SI 1 "nonimmediate_operand" ""))
7198 (sign_extend:DI
7199 (match_operand:SI 2 "register_operand" ""))))
7200 (clobber (reg:CC 17))])]
7201 "!TARGET_64BIT"
7202 "")
7203
7204 (define_insn "*mulsidi3_insn"
7205 [(set (match_operand:DI 0 "register_operand" "=A")
7206 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7207 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7208 (clobber (reg:CC 17))]
7209 "!TARGET_64BIT
7210 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7211 "imul{l}\t%2"
7212 [(set_attr "type" "imul")
7213 (set_attr "length_immediate" "0")
7214 (set (attr "athlon_decode")
7215 (if_then_else (eq_attr "cpu" "athlon")
7216 (const_string "vector")
7217 (const_string "double")))
7218 (set_attr "mode" "SI")])
7219
7220 (define_expand "umuldi3_highpart"
7221 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7222 (truncate:DI
7223 (lshiftrt:TI
7224 (mult:TI (zero_extend:TI
7225 (match_operand:DI 1 "nonimmediate_operand" ""))
7226 (zero_extend:TI
7227 (match_operand:DI 2 "register_operand" "")))
7228 (const_int 64))))
7229 (clobber (match_scratch:DI 3 ""))
7230 (clobber (reg:CC 17))])]
7231 "TARGET_64BIT"
7232 "")
7233
7234 (define_insn "*umuldi3_highpart_rex64"
7235 [(set (match_operand:DI 0 "register_operand" "=d")
7236 (truncate:DI
7237 (lshiftrt:TI
7238 (mult:TI (zero_extend:TI
7239 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7240 (zero_extend:TI
7241 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7242 (const_int 64))))
7243 (clobber (match_scratch:DI 3 "=1"))
7244 (clobber (reg:CC 17))]
7245 "TARGET_64BIT
7246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7247 "mul{q}\t%2"
7248 [(set_attr "type" "imul")
7249 (set_attr "length_immediate" "0")
7250 (set (attr "athlon_decode")
7251 (if_then_else (eq_attr "cpu" "athlon")
7252 (const_string "vector")
7253 (const_string "double")))
7254 (set_attr "mode" "DI")])
7255
7256 (define_expand "umulsi3_highpart"
7257 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7258 (truncate:SI
7259 (lshiftrt:DI
7260 (mult:DI (zero_extend:DI
7261 (match_operand:SI 1 "nonimmediate_operand" ""))
7262 (zero_extend:DI
7263 (match_operand:SI 2 "register_operand" "")))
7264 (const_int 32))))
7265 (clobber (match_scratch:SI 3 ""))
7266 (clobber (reg:CC 17))])]
7267 ""
7268 "")
7269
7270 (define_insn "*umulsi3_highpart_insn"
7271 [(set (match_operand:SI 0 "register_operand" "=d")
7272 (truncate:SI
7273 (lshiftrt:DI
7274 (mult:DI (zero_extend:DI
7275 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7276 (zero_extend:DI
7277 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7278 (const_int 32))))
7279 (clobber (match_scratch:SI 3 "=1"))
7280 (clobber (reg:CC 17))]
7281 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7282 "mul{l}\t%2"
7283 [(set_attr "type" "imul")
7284 (set_attr "length_immediate" "0")
7285 (set (attr "athlon_decode")
7286 (if_then_else (eq_attr "cpu" "athlon")
7287 (const_string "vector")
7288 (const_string "double")))
7289 (set_attr "mode" "SI")])
7290
7291 (define_insn "*umulsi3_highpart_zext"
7292 [(set (match_operand:DI 0 "register_operand" "=d")
7293 (zero_extend:DI (truncate:SI
7294 (lshiftrt:DI
7295 (mult:DI (zero_extend:DI
7296 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7297 (zero_extend:DI
7298 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7299 (const_int 32)))))
7300 (clobber (match_scratch:SI 3 "=1"))
7301 (clobber (reg:CC 17))]
7302 "TARGET_64BIT
7303 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7304 "mul{l}\t%2"
7305 [(set_attr "type" "imul")
7306 (set_attr "length_immediate" "0")
7307 (set (attr "athlon_decode")
7308 (if_then_else (eq_attr "cpu" "athlon")
7309 (const_string "vector")
7310 (const_string "double")))
7311 (set_attr "mode" "SI")])
7312
7313 (define_expand "smuldi3_highpart"
7314 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7315 (truncate:DI
7316 (lshiftrt:TI
7317 (mult:TI (sign_extend:TI
7318 (match_operand:DI 1 "nonimmediate_operand" ""))
7319 (sign_extend:TI
7320 (match_operand:DI 2 "register_operand" "")))
7321 (const_int 64))))
7322 (clobber (match_scratch:DI 3 ""))
7323 (clobber (reg:CC 17))])]
7324 "TARGET_64BIT"
7325 "")
7326
7327 (define_insn "*smuldi3_highpart_rex64"
7328 [(set (match_operand:DI 0 "register_operand" "=d")
7329 (truncate:DI
7330 (lshiftrt:TI
7331 (mult:TI (sign_extend:TI
7332 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7333 (sign_extend:TI
7334 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7335 (const_int 64))))
7336 (clobber (match_scratch:DI 3 "=1"))
7337 (clobber (reg:CC 17))]
7338 "TARGET_64BIT
7339 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7340 "imul{q}\t%2"
7341 [(set_attr "type" "imul")
7342 (set (attr "athlon_decode")
7343 (if_then_else (eq_attr "cpu" "athlon")
7344 (const_string "vector")
7345 (const_string "double")))
7346 (set_attr "mode" "DI")])
7347
7348 (define_expand "smulsi3_highpart"
7349 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7350 (truncate:SI
7351 (lshiftrt:DI
7352 (mult:DI (sign_extend:DI
7353 (match_operand:SI 1 "nonimmediate_operand" ""))
7354 (sign_extend:DI
7355 (match_operand:SI 2 "register_operand" "")))
7356 (const_int 32))))
7357 (clobber (match_scratch:SI 3 ""))
7358 (clobber (reg:CC 17))])]
7359 ""
7360 "")
7361
7362 (define_insn "*smulsi3_highpart_insn"
7363 [(set (match_operand:SI 0 "register_operand" "=d")
7364 (truncate:SI
7365 (lshiftrt:DI
7366 (mult:DI (sign_extend:DI
7367 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7368 (sign_extend:DI
7369 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7370 (const_int 32))))
7371 (clobber (match_scratch:SI 3 "=1"))
7372 (clobber (reg:CC 17))]
7373 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7374 "imul{l}\t%2"
7375 [(set_attr "type" "imul")
7376 (set (attr "athlon_decode")
7377 (if_then_else (eq_attr "cpu" "athlon")
7378 (const_string "vector")
7379 (const_string "double")))
7380 (set_attr "mode" "SI")])
7381
7382 (define_insn "*smulsi3_highpart_zext"
7383 [(set (match_operand:DI 0 "register_operand" "=d")
7384 (zero_extend:DI (truncate:SI
7385 (lshiftrt:DI
7386 (mult:DI (sign_extend:DI
7387 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7388 (sign_extend:DI
7389 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7390 (const_int 32)))))
7391 (clobber (match_scratch:SI 3 "=1"))
7392 (clobber (reg:CC 17))]
7393 "TARGET_64BIT
7394 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7395 "imul{l}\t%2"
7396 [(set_attr "type" "imul")
7397 (set (attr "athlon_decode")
7398 (if_then_else (eq_attr "cpu" "athlon")
7399 (const_string "vector")
7400 (const_string "double")))
7401 (set_attr "mode" "SI")])
7402
7403 ;; The patterns that match these are at the end of this file.
7404
7405 (define_expand "mulxf3"
7406 [(set (match_operand:XF 0 "register_operand" "")
7407 (mult:XF (match_operand:XF 1 "register_operand" "")
7408 (match_operand:XF 2 "register_operand" "")))]
7409 "TARGET_80387"
7410 "")
7411
7412 (define_expand "muldf3"
7413 [(set (match_operand:DF 0 "register_operand" "")
7414 (mult:DF (match_operand:DF 1 "register_operand" "")
7415 (match_operand:DF 2 "nonimmediate_operand" "")))]
7416 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7417 "")
7418
7419 (define_expand "mulsf3"
7420 [(set (match_operand:SF 0 "register_operand" "")
7421 (mult:SF (match_operand:SF 1 "register_operand" "")
7422 (match_operand:SF 2 "nonimmediate_operand" "")))]
7423 "TARGET_80387 || TARGET_SSE_MATH"
7424 "")
7425 \f
7426 ;; Divide instructions
7427
7428 (define_insn "divqi3"
7429 [(set (match_operand:QI 0 "register_operand" "=a")
7430 (div:QI (match_operand:HI 1 "register_operand" "0")
7431 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7432 (clobber (reg:CC 17))]
7433 "TARGET_QIMODE_MATH"
7434 "idiv{b}\t%2"
7435 [(set_attr "type" "idiv")
7436 (set_attr "mode" "QI")])
7437
7438 (define_insn "udivqi3"
7439 [(set (match_operand:QI 0 "register_operand" "=a")
7440 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7441 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7442 (clobber (reg:CC 17))]
7443 "TARGET_QIMODE_MATH"
7444 "div{b}\t%2"
7445 [(set_attr "type" "idiv")
7446 (set_attr "mode" "QI")])
7447
7448 ;; The patterns that match these are at the end of this file.
7449
7450 (define_expand "divxf3"
7451 [(set (match_operand:XF 0 "register_operand" "")
7452 (div:XF (match_operand:XF 1 "register_operand" "")
7453 (match_operand:XF 2 "register_operand" "")))]
7454 "TARGET_80387"
7455 "")
7456
7457 (define_expand "divdf3"
7458 [(set (match_operand:DF 0 "register_operand" "")
7459 (div:DF (match_operand:DF 1 "register_operand" "")
7460 (match_operand:DF 2 "nonimmediate_operand" "")))]
7461 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7462 "")
7463
7464 (define_expand "divsf3"
7465 [(set (match_operand:SF 0 "register_operand" "")
7466 (div:SF (match_operand:SF 1 "register_operand" "")
7467 (match_operand:SF 2 "nonimmediate_operand" "")))]
7468 "TARGET_80387 || TARGET_SSE_MATH"
7469 "")
7470 \f
7471 ;; Remainder instructions.
7472
7473 (define_expand "divmoddi4"
7474 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7475 (div:DI (match_operand:DI 1 "register_operand" "")
7476 (match_operand:DI 2 "nonimmediate_operand" "")))
7477 (set (match_operand:DI 3 "register_operand" "")
7478 (mod:DI (match_dup 1) (match_dup 2)))
7479 (clobber (reg:CC 17))])]
7480 "TARGET_64BIT"
7481 "")
7482
7483 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7484 ;; Penalize eax case slightly because it results in worse scheduling
7485 ;; of code.
7486 (define_insn "*divmoddi4_nocltd_rex64"
7487 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7488 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7489 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7490 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7491 (mod:DI (match_dup 2) (match_dup 3)))
7492 (clobber (reg:CC 17))]
7493 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7494 "#"
7495 [(set_attr "type" "multi")])
7496
7497 (define_insn "*divmoddi4_cltd_rex64"
7498 [(set (match_operand:DI 0 "register_operand" "=a")
7499 (div:DI (match_operand:DI 2 "register_operand" "a")
7500 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7501 (set (match_operand:DI 1 "register_operand" "=&d")
7502 (mod:DI (match_dup 2) (match_dup 3)))
7503 (clobber (reg:CC 17))]
7504 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7505 "#"
7506 [(set_attr "type" "multi")])
7507
7508 (define_insn "*divmoddi_noext_rex64"
7509 [(set (match_operand:DI 0 "register_operand" "=a")
7510 (div:DI (match_operand:DI 1 "register_operand" "0")
7511 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7512 (set (match_operand:DI 3 "register_operand" "=d")
7513 (mod:DI (match_dup 1) (match_dup 2)))
7514 (use (match_operand:DI 4 "register_operand" "3"))
7515 (clobber (reg:CC 17))]
7516 "TARGET_64BIT"
7517 "idiv{q}\t%2"
7518 [(set_attr "type" "idiv")
7519 (set_attr "mode" "DI")])
7520
7521 (define_split
7522 [(set (match_operand:DI 0 "register_operand" "")
7523 (div:DI (match_operand:DI 1 "register_operand" "")
7524 (match_operand:DI 2 "nonimmediate_operand" "")))
7525 (set (match_operand:DI 3 "register_operand" "")
7526 (mod:DI (match_dup 1) (match_dup 2)))
7527 (clobber (reg:CC 17))]
7528 "TARGET_64BIT && reload_completed"
7529 [(parallel [(set (match_dup 3)
7530 (ashiftrt:DI (match_dup 4) (const_int 63)))
7531 (clobber (reg:CC 17))])
7532 (parallel [(set (match_dup 0)
7533 (div:DI (reg:DI 0) (match_dup 2)))
7534 (set (match_dup 3)
7535 (mod:DI (reg:DI 0) (match_dup 2)))
7536 (use (match_dup 3))
7537 (clobber (reg:CC 17))])]
7538 {
7539 /* Avoid use of cltd in favor of a mov+shift. */
7540 if (!TARGET_USE_CLTD && !optimize_size)
7541 {
7542 if (true_regnum (operands[1]))
7543 emit_move_insn (operands[0], operands[1]);
7544 else
7545 emit_move_insn (operands[3], operands[1]);
7546 operands[4] = operands[3];
7547 }
7548 else
7549 {
7550 if (true_regnum (operands[1]))
7551 abort();
7552 operands[4] = operands[1];
7553 }
7554 })
7555
7556
7557 (define_expand "divmodsi4"
7558 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7559 (div:SI (match_operand:SI 1 "register_operand" "")
7560 (match_operand:SI 2 "nonimmediate_operand" "")))
7561 (set (match_operand:SI 3 "register_operand" "")
7562 (mod:SI (match_dup 1) (match_dup 2)))
7563 (clobber (reg:CC 17))])]
7564 ""
7565 "")
7566
7567 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7568 ;; Penalize eax case slightly because it results in worse scheduling
7569 ;; of code.
7570 (define_insn "*divmodsi4_nocltd"
7571 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7572 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7573 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7574 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7575 (mod:SI (match_dup 2) (match_dup 3)))
7576 (clobber (reg:CC 17))]
7577 "!optimize_size && !TARGET_USE_CLTD"
7578 "#"
7579 [(set_attr "type" "multi")])
7580
7581 (define_insn "*divmodsi4_cltd"
7582 [(set (match_operand:SI 0 "register_operand" "=a")
7583 (div:SI (match_operand:SI 2 "register_operand" "a")
7584 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7585 (set (match_operand:SI 1 "register_operand" "=&d")
7586 (mod:SI (match_dup 2) (match_dup 3)))
7587 (clobber (reg:CC 17))]
7588 "optimize_size || TARGET_USE_CLTD"
7589 "#"
7590 [(set_attr "type" "multi")])
7591
7592 (define_insn "*divmodsi_noext"
7593 [(set (match_operand:SI 0 "register_operand" "=a")
7594 (div:SI (match_operand:SI 1 "register_operand" "0")
7595 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7596 (set (match_operand:SI 3 "register_operand" "=d")
7597 (mod:SI (match_dup 1) (match_dup 2)))
7598 (use (match_operand:SI 4 "register_operand" "3"))
7599 (clobber (reg:CC 17))]
7600 ""
7601 "idiv{l}\t%2"
7602 [(set_attr "type" "idiv")
7603 (set_attr "mode" "SI")])
7604
7605 (define_split
7606 [(set (match_operand:SI 0 "register_operand" "")
7607 (div:SI (match_operand:SI 1 "register_operand" "")
7608 (match_operand:SI 2 "nonimmediate_operand" "")))
7609 (set (match_operand:SI 3 "register_operand" "")
7610 (mod:SI (match_dup 1) (match_dup 2)))
7611 (clobber (reg:CC 17))]
7612 "reload_completed"
7613 [(parallel [(set (match_dup 3)
7614 (ashiftrt:SI (match_dup 4) (const_int 31)))
7615 (clobber (reg:CC 17))])
7616 (parallel [(set (match_dup 0)
7617 (div:SI (reg:SI 0) (match_dup 2)))
7618 (set (match_dup 3)
7619 (mod:SI (reg:SI 0) (match_dup 2)))
7620 (use (match_dup 3))
7621 (clobber (reg:CC 17))])]
7622 {
7623 /* Avoid use of cltd in favor of a mov+shift. */
7624 if (!TARGET_USE_CLTD && !optimize_size)
7625 {
7626 if (true_regnum (operands[1]))
7627 emit_move_insn (operands[0], operands[1]);
7628 else
7629 emit_move_insn (operands[3], operands[1]);
7630 operands[4] = operands[3];
7631 }
7632 else
7633 {
7634 if (true_regnum (operands[1]))
7635 abort();
7636 operands[4] = operands[1];
7637 }
7638 })
7639 ;; %%% Split me.
7640 (define_insn "divmodhi4"
7641 [(set (match_operand:HI 0 "register_operand" "=a")
7642 (div:HI (match_operand:HI 1 "register_operand" "0")
7643 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644 (set (match_operand:HI 3 "register_operand" "=&d")
7645 (mod:HI (match_dup 1) (match_dup 2)))
7646 (clobber (reg:CC 17))]
7647 "TARGET_HIMODE_MATH"
7648 "cwtd\;idiv{w}\t%2"
7649 [(set_attr "type" "multi")
7650 (set_attr "length_immediate" "0")
7651 (set_attr "mode" "SI")])
7652
7653 (define_insn "udivmoddi4"
7654 [(set (match_operand:DI 0 "register_operand" "=a")
7655 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7656 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7657 (set (match_operand:DI 3 "register_operand" "=&d")
7658 (umod:DI (match_dup 1) (match_dup 2)))
7659 (clobber (reg:CC 17))]
7660 "TARGET_64BIT"
7661 "xor{q}\t%3, %3\;div{q}\t%2"
7662 [(set_attr "type" "multi")
7663 (set_attr "length_immediate" "0")
7664 (set_attr "mode" "DI")])
7665
7666 (define_insn "*udivmoddi4_noext"
7667 [(set (match_operand:DI 0 "register_operand" "=a")
7668 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7669 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7670 (set (match_operand:DI 3 "register_operand" "=d")
7671 (umod:DI (match_dup 1) (match_dup 2)))
7672 (use (match_dup 3))
7673 (clobber (reg:CC 17))]
7674 "TARGET_64BIT"
7675 "div{q}\t%2"
7676 [(set_attr "type" "idiv")
7677 (set_attr "mode" "DI")])
7678
7679 (define_split
7680 [(set (match_operand:DI 0 "register_operand" "")
7681 (udiv:DI (match_operand:DI 1 "register_operand" "")
7682 (match_operand:DI 2 "nonimmediate_operand" "")))
7683 (set (match_operand:DI 3 "register_operand" "")
7684 (umod:DI (match_dup 1) (match_dup 2)))
7685 (clobber (reg:CC 17))]
7686 "TARGET_64BIT && reload_completed"
7687 [(set (match_dup 3) (const_int 0))
7688 (parallel [(set (match_dup 0)
7689 (udiv:DI (match_dup 1) (match_dup 2)))
7690 (set (match_dup 3)
7691 (umod:DI (match_dup 1) (match_dup 2)))
7692 (use (match_dup 3))
7693 (clobber (reg:CC 17))])]
7694 "")
7695
7696 (define_insn "udivmodsi4"
7697 [(set (match_operand:SI 0 "register_operand" "=a")
7698 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7699 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7700 (set (match_operand:SI 3 "register_operand" "=&d")
7701 (umod:SI (match_dup 1) (match_dup 2)))
7702 (clobber (reg:CC 17))]
7703 ""
7704 "xor{l}\t%3, %3\;div{l}\t%2"
7705 [(set_attr "type" "multi")
7706 (set_attr "length_immediate" "0")
7707 (set_attr "mode" "SI")])
7708
7709 (define_insn "*udivmodsi4_noext"
7710 [(set (match_operand:SI 0 "register_operand" "=a")
7711 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7712 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7713 (set (match_operand:SI 3 "register_operand" "=d")
7714 (umod:SI (match_dup 1) (match_dup 2)))
7715 (use (match_dup 3))
7716 (clobber (reg:CC 17))]
7717 ""
7718 "div{l}\t%2"
7719 [(set_attr "type" "idiv")
7720 (set_attr "mode" "SI")])
7721
7722 (define_split
7723 [(set (match_operand:SI 0 "register_operand" "")
7724 (udiv:SI (match_operand:SI 1 "register_operand" "")
7725 (match_operand:SI 2 "nonimmediate_operand" "")))
7726 (set (match_operand:SI 3 "register_operand" "")
7727 (umod:SI (match_dup 1) (match_dup 2)))
7728 (clobber (reg:CC 17))]
7729 "reload_completed"
7730 [(set (match_dup 3) (const_int 0))
7731 (parallel [(set (match_dup 0)
7732 (udiv:SI (match_dup 1) (match_dup 2)))
7733 (set (match_dup 3)
7734 (umod:SI (match_dup 1) (match_dup 2)))
7735 (use (match_dup 3))
7736 (clobber (reg:CC 17))])]
7737 "")
7738
7739 (define_expand "udivmodhi4"
7740 [(set (match_dup 4) (const_int 0))
7741 (parallel [(set (match_operand:HI 0 "register_operand" "")
7742 (udiv:HI (match_operand:HI 1 "register_operand" "")
7743 (match_operand:HI 2 "nonimmediate_operand" "")))
7744 (set (match_operand:HI 3 "register_operand" "")
7745 (umod:HI (match_dup 1) (match_dup 2)))
7746 (use (match_dup 4))
7747 (clobber (reg:CC 17))])]
7748 "TARGET_HIMODE_MATH"
7749 "operands[4] = gen_reg_rtx (HImode);")
7750
7751 (define_insn "*udivmodhi_noext"
7752 [(set (match_operand:HI 0 "register_operand" "=a")
7753 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7754 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7755 (set (match_operand:HI 3 "register_operand" "=d")
7756 (umod:HI (match_dup 1) (match_dup 2)))
7757 (use (match_operand:HI 4 "register_operand" "3"))
7758 (clobber (reg:CC 17))]
7759 ""
7760 "div{w}\t%2"
7761 [(set_attr "type" "idiv")
7762 (set_attr "mode" "HI")])
7763
7764 ;; We can not use div/idiv for double division, because it causes
7765 ;; "division by zero" on the overflow and that's not what we expect
7766 ;; from truncate. Because true (non truncating) double division is
7767 ;; never generated, we can't create this insn anyway.
7768 ;
7769 ;(define_insn ""
7770 ; [(set (match_operand:SI 0 "register_operand" "=a")
7771 ; (truncate:SI
7772 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7773 ; (zero_extend:DI
7774 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7775 ; (set (match_operand:SI 3 "register_operand" "=d")
7776 ; (truncate:SI
7777 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7778 ; (clobber (reg:CC 17))]
7779 ; ""
7780 ; "div{l}\t{%2, %0|%0, %2}"
7781 ; [(set_attr "type" "idiv")])
7782 \f
7783 ;;- Logical AND instructions
7784
7785 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7786 ;; Note that this excludes ah.
7787
7788 (define_insn "*testdi_1_rex64"
7789 [(set (reg 17)
7790 (compare
7791 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7792 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7793 (const_int 0)))]
7794 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7795 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7796 "@
7797 test{l}\t{%k1, %k0|%k0, %k1}
7798 test{l}\t{%k1, %k0|%k0, %k1}
7799 test{q}\t{%1, %0|%0, %1}
7800 test{q}\t{%1, %0|%0, %1}
7801 test{q}\t{%1, %0|%0, %1}"
7802 [(set_attr "type" "test")
7803 (set_attr "modrm" "0,1,0,1,1")
7804 (set_attr "mode" "SI,SI,DI,DI,DI")
7805 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7806
7807 (define_insn "testsi_1"
7808 [(set (reg 17)
7809 (compare
7810 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7811 (match_operand:SI 1 "general_operand" "in,in,rin"))
7812 (const_int 0)))]
7813 "ix86_match_ccmode (insn, CCNOmode)
7814 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7815 "test{l}\t{%1, %0|%0, %1}"
7816 [(set_attr "type" "test")
7817 (set_attr "modrm" "0,1,1")
7818 (set_attr "mode" "SI")
7819 (set_attr "pent_pair" "uv,np,uv")])
7820
7821 (define_expand "testsi_ccno_1"
7822 [(set (reg:CCNO 17)
7823 (compare:CCNO
7824 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7825 (match_operand:SI 1 "nonmemory_operand" ""))
7826 (const_int 0)))]
7827 ""
7828 "")
7829
7830 (define_insn "*testhi_1"
7831 [(set (reg 17)
7832 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7833 (match_operand:HI 1 "general_operand" "n,n,rn"))
7834 (const_int 0)))]
7835 "ix86_match_ccmode (insn, CCNOmode)
7836 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7837 "test{w}\t{%1, %0|%0, %1}"
7838 [(set_attr "type" "test")
7839 (set_attr "modrm" "0,1,1")
7840 (set_attr "mode" "HI")
7841 (set_attr "pent_pair" "uv,np,uv")])
7842
7843 (define_expand "testqi_ccz_1"
7844 [(set (reg:CCZ 17)
7845 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7846 (match_operand:QI 1 "nonmemory_operand" ""))
7847 (const_int 0)))]
7848 ""
7849 "")
7850
7851 (define_insn "*testqi_1"
7852 [(set (reg 17)
7853 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7854 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7855 (const_int 0)))]
7856 "ix86_match_ccmode (insn, CCNOmode)
7857 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7858 {
7859 if (which_alternative == 3)
7860 {
7861 if (GET_CODE (operands[1]) == CONST_INT
7862 && (INTVAL (operands[1]) & 0xffffff00))
7863 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7864 return "test{l}\t{%1, %k0|%k0, %1}";
7865 }
7866 return "test{b}\t{%1, %0|%0, %1}";
7867 }
7868 [(set_attr "type" "test")
7869 (set_attr "modrm" "0,1,1,1")
7870 (set_attr "mode" "QI,QI,QI,SI")
7871 (set_attr "pent_pair" "uv,np,uv,np")])
7872
7873 (define_expand "testqi_ext_ccno_0"
7874 [(set (reg:CCNO 17)
7875 (compare:CCNO
7876 (and:SI
7877 (zero_extract:SI
7878 (match_operand 0 "ext_register_operand" "")
7879 (const_int 8)
7880 (const_int 8))
7881 (match_operand 1 "const_int_operand" ""))
7882 (const_int 0)))]
7883 ""
7884 "")
7885
7886 (define_insn "*testqi_ext_0"
7887 [(set (reg 17)
7888 (compare
7889 (and:SI
7890 (zero_extract:SI
7891 (match_operand 0 "ext_register_operand" "Q")
7892 (const_int 8)
7893 (const_int 8))
7894 (match_operand 1 "const_int_operand" "n"))
7895 (const_int 0)))]
7896 "ix86_match_ccmode (insn, CCNOmode)"
7897 "test{b}\t{%1, %h0|%h0, %1}"
7898 [(set_attr "type" "test")
7899 (set_attr "mode" "QI")
7900 (set_attr "length_immediate" "1")
7901 (set_attr "pent_pair" "np")])
7902
7903 (define_insn "*testqi_ext_1"
7904 [(set (reg 17)
7905 (compare
7906 (and:SI
7907 (zero_extract:SI
7908 (match_operand 0 "ext_register_operand" "Q")
7909 (const_int 8)
7910 (const_int 8))
7911 (zero_extend:SI
7912 (match_operand:QI 1 "general_operand" "Qm")))
7913 (const_int 0)))]
7914 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7915 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7916 "test{b}\t{%1, %h0|%h0, %1}"
7917 [(set_attr "type" "test")
7918 (set_attr "mode" "QI")])
7919
7920 (define_insn "*testqi_ext_1_rex64"
7921 [(set (reg 17)
7922 (compare
7923 (and:SI
7924 (zero_extract:SI
7925 (match_operand 0 "ext_register_operand" "Q")
7926 (const_int 8)
7927 (const_int 8))
7928 (zero_extend:SI
7929 (match_operand:QI 1 "register_operand" "Q")))
7930 (const_int 0)))]
7931 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7932 "test{b}\t{%1, %h0|%h0, %1}"
7933 [(set_attr "type" "test")
7934 (set_attr "mode" "QI")])
7935
7936 (define_insn "*testqi_ext_2"
7937 [(set (reg 17)
7938 (compare
7939 (and:SI
7940 (zero_extract:SI
7941 (match_operand 0 "ext_register_operand" "Q")
7942 (const_int 8)
7943 (const_int 8))
7944 (zero_extract:SI
7945 (match_operand 1 "ext_register_operand" "Q")
7946 (const_int 8)
7947 (const_int 8)))
7948 (const_int 0)))]
7949 "ix86_match_ccmode (insn, CCNOmode)"
7950 "test{b}\t{%h1, %h0|%h0, %h1}"
7951 [(set_attr "type" "test")
7952 (set_attr "mode" "QI")])
7953
7954 ;; Combine likes to form bit extractions for some tests. Humor it.
7955 (define_insn "*testqi_ext_3"
7956 [(set (reg 17)
7957 (compare (zero_extract:SI
7958 (match_operand 0 "nonimmediate_operand" "rm")
7959 (match_operand:SI 1 "const_int_operand" "")
7960 (match_operand:SI 2 "const_int_operand" ""))
7961 (const_int 0)))]
7962 "ix86_match_ccmode (insn, CCNOmode)
7963 && (GET_MODE (operands[0]) == SImode
7964 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7965 || GET_MODE (operands[0]) == HImode
7966 || GET_MODE (operands[0]) == QImode)"
7967 "#")
7968
7969 (define_insn "*testqi_ext_3_rex64"
7970 [(set (reg 17)
7971 (compare (zero_extract:DI
7972 (match_operand 0 "nonimmediate_operand" "rm")
7973 (match_operand:DI 1 "const_int_operand" "")
7974 (match_operand:DI 2 "const_int_operand" ""))
7975 (const_int 0)))]
7976 "TARGET_64BIT
7977 && ix86_match_ccmode (insn, CCNOmode)
7978 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7979 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7980 /* Ensure that resulting mask is zero or sign extended operand. */
7981 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7982 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7983 && INTVAL (operands[1]) > 32))
7984 && (GET_MODE (operands[0]) == SImode
7985 || GET_MODE (operands[0]) == DImode
7986 || GET_MODE (operands[0]) == HImode
7987 || GET_MODE (operands[0]) == QImode)"
7988 "#")
7989
7990 (define_split
7991 [(set (reg 17)
7992 (compare (zero_extract
7993 (match_operand 0 "nonimmediate_operand" "")
7994 (match_operand 1 "const_int_operand" "")
7995 (match_operand 2 "const_int_operand" ""))
7996 (const_int 0)))]
7997 "ix86_match_ccmode (insn, CCNOmode)"
7998 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7999 {
8000 HOST_WIDE_INT len = INTVAL (operands[1]);
8001 HOST_WIDE_INT pos = INTVAL (operands[2]);
8002 HOST_WIDE_INT mask;
8003 enum machine_mode mode, submode;
8004
8005 mode = GET_MODE (operands[0]);
8006 if (GET_CODE (operands[0]) == MEM)
8007 {
8008 /* ??? Combine likes to put non-volatile mem extractions in QImode
8009 no matter the size of the test. So find a mode that works. */
8010 if (! MEM_VOLATILE_P (operands[0]))
8011 {
8012 mode = smallest_mode_for_size (pos + len, MODE_INT);
8013 operands[0] = adjust_address (operands[0], mode, 0);
8014 }
8015 }
8016 else if (GET_CODE (operands[0]) == SUBREG
8017 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8018 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8019 && pos + len <= GET_MODE_BITSIZE (submode))
8020 {
8021 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8022 mode = submode;
8023 operands[0] = SUBREG_REG (operands[0]);
8024 }
8025 else if (mode == HImode && pos + len <= 8)
8026 {
8027 /* Small HImode tests can be converted to QImode. */
8028 mode = QImode;
8029 operands[0] = gen_lowpart (QImode, operands[0]);
8030 }
8031
8032 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8033 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8034
8035 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8036 })
8037
8038 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8039 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8040 ;; this is relatively important trick.
8041 ;; Do the conversion only post-reload to avoid limiting of the register class
8042 ;; to QI regs.
8043 (define_split
8044 [(set (reg 17)
8045 (compare
8046 (and (match_operand 0 "register_operand" "")
8047 (match_operand 1 "const_int_operand" ""))
8048 (const_int 0)))]
8049 "reload_completed
8050 && QI_REG_P (operands[0])
8051 && ((ix86_match_ccmode (insn, CCZmode)
8052 && !(INTVAL (operands[1]) & ~(255 << 8)))
8053 || (ix86_match_ccmode (insn, CCNOmode)
8054 && !(INTVAL (operands[1]) & ~(127 << 8))))
8055 && GET_MODE (operands[0]) != QImode"
8056 [(set (reg:CCNO 17)
8057 (compare:CCNO
8058 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8059 (match_dup 1))
8060 (const_int 0)))]
8061 "operands[0] = gen_lowpart (SImode, operands[0]);
8062 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8063
8064 (define_split
8065 [(set (reg 17)
8066 (compare
8067 (and (match_operand 0 "nonimmediate_operand" "")
8068 (match_operand 1 "const_int_operand" ""))
8069 (const_int 0)))]
8070 "reload_completed
8071 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8072 && ((ix86_match_ccmode (insn, CCZmode)
8073 && !(INTVAL (operands[1]) & ~255))
8074 || (ix86_match_ccmode (insn, CCNOmode)
8075 && !(INTVAL (operands[1]) & ~127)))
8076 && GET_MODE (operands[0]) != QImode"
8077 [(set (reg:CCNO 17)
8078 (compare:CCNO
8079 (and:QI (match_dup 0)
8080 (match_dup 1))
8081 (const_int 0)))]
8082 "operands[0] = gen_lowpart (QImode, operands[0]);
8083 operands[1] = gen_lowpart (QImode, operands[1]);")
8084
8085
8086 ;; %%% This used to optimize known byte-wide and operations to memory,
8087 ;; and sometimes to QImode registers. If this is considered useful,
8088 ;; it should be done with splitters.
8089
8090 (define_expand "anddi3"
8091 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8092 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8093 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8094 (clobber (reg:CC 17))]
8095 "TARGET_64BIT"
8096 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8097
8098 (define_insn "*anddi_1_rex64"
8099 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8100 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8101 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8102 (clobber (reg:CC 17))]
8103 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8104 {
8105 switch (get_attr_type (insn))
8106 {
8107 case TYPE_IMOVX:
8108 {
8109 enum machine_mode mode;
8110
8111 if (GET_CODE (operands[2]) != CONST_INT)
8112 abort ();
8113 if (INTVAL (operands[2]) == 0xff)
8114 mode = QImode;
8115 else if (INTVAL (operands[2]) == 0xffff)
8116 mode = HImode;
8117 else
8118 abort ();
8119
8120 operands[1] = gen_lowpart (mode, operands[1]);
8121 if (mode == QImode)
8122 return "movz{bq|x}\t{%1,%0|%0, %1}";
8123 else
8124 return "movz{wq|x}\t{%1,%0|%0, %1}";
8125 }
8126
8127 default:
8128 if (! rtx_equal_p (operands[0], operands[1]))
8129 abort ();
8130 if (get_attr_mode (insn) == MODE_SI)
8131 return "and{l}\t{%k2, %k0|%k0, %k2}";
8132 else
8133 return "and{q}\t{%2, %0|%0, %2}";
8134 }
8135 }
8136 [(set_attr "type" "alu,alu,alu,imovx")
8137 (set_attr "length_immediate" "*,*,*,0")
8138 (set_attr "mode" "SI,DI,DI,DI")])
8139
8140 (define_insn "*anddi_2"
8141 [(set (reg 17)
8142 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8143 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8144 (const_int 0)))
8145 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8146 (and:DI (match_dup 1) (match_dup 2)))]
8147 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148 && ix86_binary_operator_ok (AND, DImode, operands)"
8149 "@
8150 and{l}\t{%k2, %k0|%k0, %k2}
8151 and{q}\t{%2, %0|%0, %2}
8152 and{q}\t{%2, %0|%0, %2}"
8153 [(set_attr "type" "alu")
8154 (set_attr "mode" "SI,DI,DI")])
8155
8156 (define_expand "andsi3"
8157 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8158 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8159 (match_operand:SI 2 "general_operand" "")))
8160 (clobber (reg:CC 17))]
8161 ""
8162 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8163
8164 (define_insn "*andsi_1"
8165 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8166 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8167 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8168 (clobber (reg:CC 17))]
8169 "ix86_binary_operator_ok (AND, SImode, operands)"
8170 {
8171 switch (get_attr_type (insn))
8172 {
8173 case TYPE_IMOVX:
8174 {
8175 enum machine_mode mode;
8176
8177 if (GET_CODE (operands[2]) != CONST_INT)
8178 abort ();
8179 if (INTVAL (operands[2]) == 0xff)
8180 mode = QImode;
8181 else if (INTVAL (operands[2]) == 0xffff)
8182 mode = HImode;
8183 else
8184 abort ();
8185
8186 operands[1] = gen_lowpart (mode, operands[1]);
8187 if (mode == QImode)
8188 return "movz{bl|x}\t{%1,%0|%0, %1}";
8189 else
8190 return "movz{wl|x}\t{%1,%0|%0, %1}";
8191 }
8192
8193 default:
8194 if (! rtx_equal_p (operands[0], operands[1]))
8195 abort ();
8196 return "and{l}\t{%2, %0|%0, %2}";
8197 }
8198 }
8199 [(set_attr "type" "alu,alu,imovx")
8200 (set_attr "length_immediate" "*,*,0")
8201 (set_attr "mode" "SI")])
8202
8203 (define_split
8204 [(set (match_operand 0 "register_operand" "")
8205 (and (match_dup 0)
8206 (const_int -65536)))
8207 (clobber (reg:CC 17))]
8208 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8209 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8210 "operands[1] = gen_lowpart (HImode, operands[0]);")
8211
8212 (define_split
8213 [(set (match_operand 0 "ext_register_operand" "")
8214 (and (match_dup 0)
8215 (const_int -256)))
8216 (clobber (reg:CC 17))]
8217 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8218 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8219 "operands[1] = gen_lowpart (QImode, operands[0]);")
8220
8221 (define_split
8222 [(set (match_operand 0 "ext_register_operand" "")
8223 (and (match_dup 0)
8224 (const_int -65281)))
8225 (clobber (reg:CC 17))]
8226 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8227 [(parallel [(set (zero_extract:SI (match_dup 0)
8228 (const_int 8)
8229 (const_int 8))
8230 (xor:SI
8231 (zero_extract:SI (match_dup 0)
8232 (const_int 8)
8233 (const_int 8))
8234 (zero_extract:SI (match_dup 0)
8235 (const_int 8)
8236 (const_int 8))))
8237 (clobber (reg:CC 17))])]
8238 "operands[0] = gen_lowpart (SImode, operands[0]);")
8239
8240 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8241 (define_insn "*andsi_1_zext"
8242 [(set (match_operand:DI 0 "register_operand" "=r")
8243 (zero_extend:DI
8244 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8245 (match_operand:SI 2 "general_operand" "rim"))))
8246 (clobber (reg:CC 17))]
8247 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8248 "and{l}\t{%2, %k0|%k0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "SI")])
8251
8252 (define_insn "*andsi_2"
8253 [(set (reg 17)
8254 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8255 (match_operand:SI 2 "general_operand" "rim,ri"))
8256 (const_int 0)))
8257 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8258 (and:SI (match_dup 1) (match_dup 2)))]
8259 "ix86_match_ccmode (insn, CCNOmode)
8260 && ix86_binary_operator_ok (AND, SImode, operands)"
8261 "and{l}\t{%2, %0|%0, %2}"
8262 [(set_attr "type" "alu")
8263 (set_attr "mode" "SI")])
8264
8265 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8266 (define_insn "*andsi_2_zext"
8267 [(set (reg 17)
8268 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8269 (match_operand:SI 2 "general_operand" "rim"))
8270 (const_int 0)))
8271 (set (match_operand:DI 0 "register_operand" "=r")
8272 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8273 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8274 && ix86_binary_operator_ok (AND, SImode, operands)"
8275 "and{l}\t{%2, %k0|%k0, %2}"
8276 [(set_attr "type" "alu")
8277 (set_attr "mode" "SI")])
8278
8279 (define_expand "andhi3"
8280 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8281 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8282 (match_operand:HI 2 "general_operand" "")))
8283 (clobber (reg:CC 17))]
8284 "TARGET_HIMODE_MATH"
8285 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8286
8287 (define_insn "*andhi_1"
8288 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8289 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8290 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8291 (clobber (reg:CC 17))]
8292 "ix86_binary_operator_ok (AND, HImode, operands)"
8293 {
8294 switch (get_attr_type (insn))
8295 {
8296 case TYPE_IMOVX:
8297 if (GET_CODE (operands[2]) != CONST_INT)
8298 abort ();
8299 if (INTVAL (operands[2]) == 0xff)
8300 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8301 abort ();
8302
8303 default:
8304 if (! rtx_equal_p (operands[0], operands[1]))
8305 abort ();
8306
8307 return "and{w}\t{%2, %0|%0, %2}";
8308 }
8309 }
8310 [(set_attr "type" "alu,alu,imovx")
8311 (set_attr "length_immediate" "*,*,0")
8312 (set_attr "mode" "HI,HI,SI")])
8313
8314 (define_insn "*andhi_2"
8315 [(set (reg 17)
8316 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8317 (match_operand:HI 2 "general_operand" "rim,ri"))
8318 (const_int 0)))
8319 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8320 (and:HI (match_dup 1) (match_dup 2)))]
8321 "ix86_match_ccmode (insn, CCNOmode)
8322 && ix86_binary_operator_ok (AND, HImode, operands)"
8323 "and{w}\t{%2, %0|%0, %2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "mode" "HI")])
8326
8327 (define_expand "andqi3"
8328 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8329 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8330 (match_operand:QI 2 "general_operand" "")))
8331 (clobber (reg:CC 17))]
8332 "TARGET_QIMODE_MATH"
8333 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8334
8335 ;; %%% Potential partial reg stall on alternative 2. What to do?
8336 (define_insn "*andqi_1"
8337 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8338 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8339 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8340 (clobber (reg:CC 17))]
8341 "ix86_binary_operator_ok (AND, QImode, operands)"
8342 "@
8343 and{b}\t{%2, %0|%0, %2}
8344 and{b}\t{%2, %0|%0, %2}
8345 and{l}\t{%k2, %k0|%k0, %k2}"
8346 [(set_attr "type" "alu")
8347 (set_attr "mode" "QI,QI,SI")])
8348
8349 (define_insn "*andqi_1_slp"
8350 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8351 (and:QI (match_dup 0)
8352 (match_operand:QI 1 "general_operand" "qi,qmi")))
8353 (clobber (reg:CC 17))]
8354 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8355 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8356 "and{b}\t{%1, %0|%0, %1}"
8357 [(set_attr "type" "alu1")
8358 (set_attr "mode" "QI")])
8359
8360 (define_insn "*andqi_2"
8361 [(set (reg 17)
8362 (compare (and:QI
8363 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8364 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8365 (const_int 0)))
8366 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8367 (and:QI (match_dup 1) (match_dup 2)))]
8368 "ix86_match_ccmode (insn, CCNOmode)
8369 && ix86_binary_operator_ok (AND, QImode, operands)"
8370 {
8371 if (which_alternative == 2)
8372 {
8373 if (GET_CODE (operands[2]) == CONST_INT
8374 && (INTVAL (operands[2]) & 0xffffff00))
8375 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8376 return "and{l}\t{%2, %k0|%k0, %2}";
8377 }
8378 return "and{b}\t{%2, %0|%0, %2}";
8379 }
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "QI,QI,SI")])
8382
8383 (define_insn "*andqi_2_slp"
8384 [(set (reg 17)
8385 (compare (and:QI
8386 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8387 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8388 (const_int 0)))
8389 (set (strict_low_part (match_dup 0))
8390 (and:QI (match_dup 0) (match_dup 1)))]
8391 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8392 && ix86_match_ccmode (insn, CCNOmode)
8393 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8394 "and{b}\t{%1, %0|%0, %1}"
8395 [(set_attr "type" "alu1")
8396 (set_attr "mode" "QI")])
8397
8398 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8399 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8400 ;; for a QImode operand, which of course failed.
8401
8402 (define_insn "andqi_ext_0"
8403 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404 (const_int 8)
8405 (const_int 8))
8406 (and:SI
8407 (zero_extract:SI
8408 (match_operand 1 "ext_register_operand" "0")
8409 (const_int 8)
8410 (const_int 8))
8411 (match_operand 2 "const_int_operand" "n")))
8412 (clobber (reg:CC 17))]
8413 ""
8414 "and{b}\t{%2, %h0|%h0, %2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "length_immediate" "1")
8417 (set_attr "mode" "QI")])
8418
8419 ;; Generated by peephole translating test to and. This shows up
8420 ;; often in fp comparisons.
8421
8422 (define_insn "*andqi_ext_0_cc"
8423 [(set (reg 17)
8424 (compare
8425 (and:SI
8426 (zero_extract:SI
8427 (match_operand 1 "ext_register_operand" "0")
8428 (const_int 8)
8429 (const_int 8))
8430 (match_operand 2 "const_int_operand" "n"))
8431 (const_int 0)))
8432 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8433 (const_int 8)
8434 (const_int 8))
8435 (and:SI
8436 (zero_extract:SI
8437 (match_dup 1)
8438 (const_int 8)
8439 (const_int 8))
8440 (match_dup 2)))]
8441 "ix86_match_ccmode (insn, CCNOmode)"
8442 "and{b}\t{%2, %h0|%h0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "length_immediate" "1")
8445 (set_attr "mode" "QI")])
8446
8447 (define_insn "*andqi_ext_1"
8448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8449 (const_int 8)
8450 (const_int 8))
8451 (and:SI
8452 (zero_extract:SI
8453 (match_operand 1 "ext_register_operand" "0")
8454 (const_int 8)
8455 (const_int 8))
8456 (zero_extend:SI
8457 (match_operand:QI 2 "general_operand" "Qm"))))
8458 (clobber (reg:CC 17))]
8459 "!TARGET_64BIT"
8460 "and{b}\t{%2, %h0|%h0, %2}"
8461 [(set_attr "type" "alu")
8462 (set_attr "length_immediate" "0")
8463 (set_attr "mode" "QI")])
8464
8465 (define_insn "*andqi_ext_1_rex64"
8466 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 (const_int 8)
8468 (const_int 8))
8469 (and:SI
8470 (zero_extract:SI
8471 (match_operand 1 "ext_register_operand" "0")
8472 (const_int 8)
8473 (const_int 8))
8474 (zero_extend:SI
8475 (match_operand 2 "ext_register_operand" "Q"))))
8476 (clobber (reg:CC 17))]
8477 "TARGET_64BIT"
8478 "and{b}\t{%2, %h0|%h0, %2}"
8479 [(set_attr "type" "alu")
8480 (set_attr "length_immediate" "0")
8481 (set_attr "mode" "QI")])
8482
8483 (define_insn "*andqi_ext_2"
8484 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8485 (const_int 8)
8486 (const_int 8))
8487 (and:SI
8488 (zero_extract:SI
8489 (match_operand 1 "ext_register_operand" "%0")
8490 (const_int 8)
8491 (const_int 8))
8492 (zero_extract:SI
8493 (match_operand 2 "ext_register_operand" "Q")
8494 (const_int 8)
8495 (const_int 8))))
8496 (clobber (reg:CC 17))]
8497 ""
8498 "and{b}\t{%h2, %h0|%h0, %h2}"
8499 [(set_attr "type" "alu")
8500 (set_attr "length_immediate" "0")
8501 (set_attr "mode" "QI")])
8502
8503 ;; Convert wide AND instructions with immediate operand to shorter QImode
8504 ;; equivalents when possible.
8505 ;; Don't do the splitting with memory operands, since it introduces risk
8506 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8507 ;; for size, but that can (should?) be handled by generic code instead.
8508 (define_split
8509 [(set (match_operand 0 "register_operand" "")
8510 (and (match_operand 1 "register_operand" "")
8511 (match_operand 2 "const_int_operand" "")))
8512 (clobber (reg:CC 17))]
8513 "reload_completed
8514 && QI_REG_P (operands[0])
8515 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8516 && !(~INTVAL (operands[2]) & ~(255 << 8))
8517 && GET_MODE (operands[0]) != QImode"
8518 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8519 (and:SI (zero_extract:SI (match_dup 1)
8520 (const_int 8) (const_int 8))
8521 (match_dup 2)))
8522 (clobber (reg:CC 17))])]
8523 "operands[0] = gen_lowpart (SImode, operands[0]);
8524 operands[1] = gen_lowpart (SImode, operands[1]);
8525 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8526
8527 ;; Since AND can be encoded with sign extended immediate, this is only
8528 ;; profitable when 7th bit is not set.
8529 (define_split
8530 [(set (match_operand 0 "register_operand" "")
8531 (and (match_operand 1 "general_operand" "")
8532 (match_operand 2 "const_int_operand" "")))
8533 (clobber (reg:CC 17))]
8534 "reload_completed
8535 && ANY_QI_REG_P (operands[0])
8536 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8537 && !(~INTVAL (operands[2]) & ~255)
8538 && !(INTVAL (operands[2]) & 128)
8539 && GET_MODE (operands[0]) != QImode"
8540 [(parallel [(set (strict_low_part (match_dup 0))
8541 (and:QI (match_dup 1)
8542 (match_dup 2)))
8543 (clobber (reg:CC 17))])]
8544 "operands[0] = gen_lowpart (QImode, operands[0]);
8545 operands[1] = gen_lowpart (QImode, operands[1]);
8546 operands[2] = gen_lowpart (QImode, operands[2]);")
8547 \f
8548 ;; Logical inclusive OR instructions
8549
8550 ;; %%% This used to optimize known byte-wide and operations to memory.
8551 ;; If this is considered useful, it should be done with splitters.
8552
8553 (define_expand "iordi3"
8554 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8555 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8556 (match_operand:DI 2 "x86_64_general_operand" "")))
8557 (clobber (reg:CC 17))]
8558 "TARGET_64BIT"
8559 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8560
8561 (define_insn "*iordi_1_rex64"
8562 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8563 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8564 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8565 (clobber (reg:CC 17))]
8566 "TARGET_64BIT
8567 && ix86_binary_operator_ok (IOR, DImode, operands)"
8568 "or{q}\t{%2, %0|%0, %2}"
8569 [(set_attr "type" "alu")
8570 (set_attr "mode" "DI")])
8571
8572 (define_insn "*iordi_2_rex64"
8573 [(set (reg 17)
8574 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8575 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8576 (const_int 0)))
8577 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8578 (ior:DI (match_dup 1) (match_dup 2)))]
8579 "TARGET_64BIT
8580 && ix86_match_ccmode (insn, CCNOmode)
8581 && ix86_binary_operator_ok (IOR, DImode, operands)"
8582 "or{q}\t{%2, %0|%0, %2}"
8583 [(set_attr "type" "alu")
8584 (set_attr "mode" "DI")])
8585
8586 (define_insn "*iordi_3_rex64"
8587 [(set (reg 17)
8588 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8589 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8590 (const_int 0)))
8591 (clobber (match_scratch:DI 0 "=r"))]
8592 "TARGET_64BIT
8593 && ix86_match_ccmode (insn, CCNOmode)
8594 && ix86_binary_operator_ok (IOR, DImode, operands)"
8595 "or{q}\t{%2, %0|%0, %2}"
8596 [(set_attr "type" "alu")
8597 (set_attr "mode" "DI")])
8598
8599
8600 (define_expand "iorsi3"
8601 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8602 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8603 (match_operand:SI 2 "general_operand" "")))
8604 (clobber (reg:CC 17))]
8605 ""
8606 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8607
8608 (define_insn "*iorsi_1"
8609 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8610 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8611 (match_operand:SI 2 "general_operand" "ri,rmi")))
8612 (clobber (reg:CC 17))]
8613 "ix86_binary_operator_ok (IOR, SImode, operands)"
8614 "or{l}\t{%2, %0|%0, %2}"
8615 [(set_attr "type" "alu")
8616 (set_attr "mode" "SI")])
8617
8618 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8619 (define_insn "*iorsi_1_zext"
8620 [(set (match_operand:DI 0 "register_operand" "=rm")
8621 (zero_extend:DI
8622 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8623 (match_operand:SI 2 "general_operand" "rim"))))
8624 (clobber (reg:CC 17))]
8625 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8626 "or{l}\t{%2, %k0|%k0, %2}"
8627 [(set_attr "type" "alu")
8628 (set_attr "mode" "SI")])
8629
8630 (define_insn "*iorsi_1_zext_imm"
8631 [(set (match_operand:DI 0 "register_operand" "=rm")
8632 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8633 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8634 (clobber (reg:CC 17))]
8635 "TARGET_64BIT"
8636 "or{l}\t{%2, %k0|%k0, %2}"
8637 [(set_attr "type" "alu")
8638 (set_attr "mode" "SI")])
8639
8640 (define_insn "*iorsi_2"
8641 [(set (reg 17)
8642 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8643 (match_operand:SI 2 "general_operand" "rim,ri"))
8644 (const_int 0)))
8645 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8646 (ior:SI (match_dup 1) (match_dup 2)))]
8647 "ix86_match_ccmode (insn, CCNOmode)
8648 && ix86_binary_operator_ok (IOR, SImode, operands)"
8649 "or{l}\t{%2, %0|%0, %2}"
8650 [(set_attr "type" "alu")
8651 (set_attr "mode" "SI")])
8652
8653 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8654 ;; ??? Special case for immediate operand is missing - it is tricky.
8655 (define_insn "*iorsi_2_zext"
8656 [(set (reg 17)
8657 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8658 (match_operand:SI 2 "general_operand" "rim"))
8659 (const_int 0)))
8660 (set (match_operand:DI 0 "register_operand" "=r")
8661 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8662 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8663 && ix86_binary_operator_ok (IOR, SImode, operands)"
8664 "or{l}\t{%2, %k0|%k0, %2}"
8665 [(set_attr "type" "alu")
8666 (set_attr "mode" "SI")])
8667
8668 (define_insn "*iorsi_2_zext_imm"
8669 [(set (reg 17)
8670 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8671 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8672 (const_int 0)))
8673 (set (match_operand:DI 0 "register_operand" "=r")
8674 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8675 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8676 && ix86_binary_operator_ok (IOR, SImode, operands)"
8677 "or{l}\t{%2, %k0|%k0, %2}"
8678 [(set_attr "type" "alu")
8679 (set_attr "mode" "SI")])
8680
8681 (define_insn "*iorsi_3"
8682 [(set (reg 17)
8683 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8684 (match_operand:SI 2 "general_operand" "rim"))
8685 (const_int 0)))
8686 (clobber (match_scratch:SI 0 "=r"))]
8687 "ix86_match_ccmode (insn, CCNOmode)
8688 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8689 "or{l}\t{%2, %0|%0, %2}"
8690 [(set_attr "type" "alu")
8691 (set_attr "mode" "SI")])
8692
8693 (define_expand "iorhi3"
8694 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8695 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8696 (match_operand:HI 2 "general_operand" "")))
8697 (clobber (reg:CC 17))]
8698 "TARGET_HIMODE_MATH"
8699 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8700
8701 (define_insn "*iorhi_1"
8702 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8703 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8704 (match_operand:HI 2 "general_operand" "rmi,ri")))
8705 (clobber (reg:CC 17))]
8706 "ix86_binary_operator_ok (IOR, HImode, operands)"
8707 "or{w}\t{%2, %0|%0, %2}"
8708 [(set_attr "type" "alu")
8709 (set_attr "mode" "HI")])
8710
8711 (define_insn "*iorhi_2"
8712 [(set (reg 17)
8713 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8714 (match_operand:HI 2 "general_operand" "rim,ri"))
8715 (const_int 0)))
8716 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8717 (ior:HI (match_dup 1) (match_dup 2)))]
8718 "ix86_match_ccmode (insn, CCNOmode)
8719 && ix86_binary_operator_ok (IOR, HImode, operands)"
8720 "or{w}\t{%2, %0|%0, %2}"
8721 [(set_attr "type" "alu")
8722 (set_attr "mode" "HI")])
8723
8724 (define_insn "*iorhi_3"
8725 [(set (reg 17)
8726 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8727 (match_operand:HI 2 "general_operand" "rim"))
8728 (const_int 0)))
8729 (clobber (match_scratch:HI 0 "=r"))]
8730 "ix86_match_ccmode (insn, CCNOmode)
8731 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8732 "or{w}\t{%2, %0|%0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "mode" "HI")])
8735
8736 (define_expand "iorqi3"
8737 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8738 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8739 (match_operand:QI 2 "general_operand" "")))
8740 (clobber (reg:CC 17))]
8741 "TARGET_QIMODE_MATH"
8742 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8743
8744 ;; %%% Potential partial reg stall on alternative 2. What to do?
8745 (define_insn "*iorqi_1"
8746 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8747 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8748 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8749 (clobber (reg:CC 17))]
8750 "ix86_binary_operator_ok (IOR, QImode, operands)"
8751 "@
8752 or{b}\t{%2, %0|%0, %2}
8753 or{b}\t{%2, %0|%0, %2}
8754 or{l}\t{%k2, %k0|%k0, %k2}"
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "QI,QI,SI")])
8757
8758 (define_insn "*iorqi_1_slp"
8759 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8760 (ior:QI (match_dup 0)
8761 (match_operand:QI 1 "general_operand" "qmi,qi")))
8762 (clobber (reg:CC 17))]
8763 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8765 "or{b}\t{%1, %0|%0, %1}"
8766 [(set_attr "type" "alu1")
8767 (set_attr "mode" "QI")])
8768
8769 (define_insn "*iorqi_2"
8770 [(set (reg 17)
8771 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8772 (match_operand:QI 2 "general_operand" "qim,qi"))
8773 (const_int 0)))
8774 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8775 (ior:QI (match_dup 1) (match_dup 2)))]
8776 "ix86_match_ccmode (insn, CCNOmode)
8777 && ix86_binary_operator_ok (IOR, QImode, operands)"
8778 "or{b}\t{%2, %0|%0, %2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "mode" "QI")])
8781
8782 (define_insn "*iorqi_2_slp"
8783 [(set (reg 17)
8784 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8785 (match_operand:QI 1 "general_operand" "qim,qi"))
8786 (const_int 0)))
8787 (set (strict_low_part (match_dup 0))
8788 (ior:QI (match_dup 0) (match_dup 1)))]
8789 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8790 && ix86_match_ccmode (insn, CCNOmode)
8791 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8792 "or{b}\t{%1, %0|%0, %1}"
8793 [(set_attr "type" "alu1")
8794 (set_attr "mode" "QI")])
8795
8796 (define_insn "*iorqi_3"
8797 [(set (reg 17)
8798 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8799 (match_operand:QI 2 "general_operand" "qim"))
8800 (const_int 0)))
8801 (clobber (match_scratch:QI 0 "=q"))]
8802 "ix86_match_ccmode (insn, CCNOmode)
8803 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8804 "or{b}\t{%2, %0|%0, %2}"
8805 [(set_attr "type" "alu")
8806 (set_attr "mode" "QI")])
8807
8808 (define_insn "iorqi_ext_0"
8809 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8810 (const_int 8)
8811 (const_int 8))
8812 (ior:SI
8813 (zero_extract:SI
8814 (match_operand 1 "ext_register_operand" "0")
8815 (const_int 8)
8816 (const_int 8))
8817 (match_operand 2 "const_int_operand" "n")))
8818 (clobber (reg:CC 17))]
8819 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8820 "or{b}\t{%2, %h0|%h0, %2}"
8821 [(set_attr "type" "alu")
8822 (set_attr "length_immediate" "1")
8823 (set_attr "mode" "QI")])
8824
8825 (define_insn "*iorqi_ext_1"
8826 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8827 (const_int 8)
8828 (const_int 8))
8829 (ior:SI
8830 (zero_extract:SI
8831 (match_operand 1 "ext_register_operand" "0")
8832 (const_int 8)
8833 (const_int 8))
8834 (zero_extend:SI
8835 (match_operand:QI 2 "general_operand" "Qm"))))
8836 (clobber (reg:CC 17))]
8837 "!TARGET_64BIT
8838 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8839 "or{b}\t{%2, %h0|%h0, %2}"
8840 [(set_attr "type" "alu")
8841 (set_attr "length_immediate" "0")
8842 (set_attr "mode" "QI")])
8843
8844 (define_insn "*iorqi_ext_1_rex64"
8845 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8846 (const_int 8)
8847 (const_int 8))
8848 (ior:SI
8849 (zero_extract:SI
8850 (match_operand 1 "ext_register_operand" "0")
8851 (const_int 8)
8852 (const_int 8))
8853 (zero_extend:SI
8854 (match_operand 2 "ext_register_operand" "Q"))))
8855 (clobber (reg:CC 17))]
8856 "TARGET_64BIT
8857 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8858 "or{b}\t{%2, %h0|%h0, %2}"
8859 [(set_attr "type" "alu")
8860 (set_attr "length_immediate" "0")
8861 (set_attr "mode" "QI")])
8862
8863 (define_insn "*iorqi_ext_2"
8864 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865 (const_int 8)
8866 (const_int 8))
8867 (ior:SI
8868 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8869 (const_int 8)
8870 (const_int 8))
8871 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8872 (const_int 8)
8873 (const_int 8))))
8874 (clobber (reg:CC 17))]
8875 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8876 "ior{b}\t{%h2, %h0|%h0, %h2}"
8877 [(set_attr "type" "alu")
8878 (set_attr "length_immediate" "0")
8879 (set_attr "mode" "QI")])
8880
8881 (define_split
8882 [(set (match_operand 0 "register_operand" "")
8883 (ior (match_operand 1 "register_operand" "")
8884 (match_operand 2 "const_int_operand" "")))
8885 (clobber (reg:CC 17))]
8886 "reload_completed
8887 && QI_REG_P (operands[0])
8888 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8889 && !(INTVAL (operands[2]) & ~(255 << 8))
8890 && GET_MODE (operands[0]) != QImode"
8891 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8892 (ior:SI (zero_extract:SI (match_dup 1)
8893 (const_int 8) (const_int 8))
8894 (match_dup 2)))
8895 (clobber (reg:CC 17))])]
8896 "operands[0] = gen_lowpart (SImode, operands[0]);
8897 operands[1] = gen_lowpart (SImode, operands[1]);
8898 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8899
8900 ;; Since OR can be encoded with sign extended immediate, this is only
8901 ;; profitable when 7th bit is set.
8902 (define_split
8903 [(set (match_operand 0 "register_operand" "")
8904 (ior (match_operand 1 "general_operand" "")
8905 (match_operand 2 "const_int_operand" "")))
8906 (clobber (reg:CC 17))]
8907 "reload_completed
8908 && ANY_QI_REG_P (operands[0])
8909 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8910 && !(INTVAL (operands[2]) & ~255)
8911 && (INTVAL (operands[2]) & 128)
8912 && GET_MODE (operands[0]) != QImode"
8913 [(parallel [(set (strict_low_part (match_dup 0))
8914 (ior:QI (match_dup 1)
8915 (match_dup 2)))
8916 (clobber (reg:CC 17))])]
8917 "operands[0] = gen_lowpart (QImode, operands[0]);
8918 operands[1] = gen_lowpart (QImode, operands[1]);
8919 operands[2] = gen_lowpart (QImode, operands[2]);")
8920 \f
8921 ;; Logical XOR instructions
8922
8923 ;; %%% This used to optimize known byte-wide and operations to memory.
8924 ;; If this is considered useful, it should be done with splitters.
8925
8926 (define_expand "xordi3"
8927 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8928 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8929 (match_operand:DI 2 "x86_64_general_operand" "")))
8930 (clobber (reg:CC 17))]
8931 "TARGET_64BIT"
8932 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8933
8934 (define_insn "*xordi_1_rex64"
8935 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8936 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8937 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8938 (clobber (reg:CC 17))]
8939 "TARGET_64BIT
8940 && ix86_binary_operator_ok (XOR, DImode, operands)"
8941 "@
8942 xor{q}\t{%2, %0|%0, %2}
8943 xor{q}\t{%2, %0|%0, %2}"
8944 [(set_attr "type" "alu")
8945 (set_attr "mode" "DI,DI")])
8946
8947 (define_insn "*xordi_2_rex64"
8948 [(set (reg 17)
8949 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8950 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8951 (const_int 0)))
8952 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8953 (xor:DI (match_dup 1) (match_dup 2)))]
8954 "TARGET_64BIT
8955 && ix86_match_ccmode (insn, CCNOmode)
8956 && ix86_binary_operator_ok (XOR, DImode, operands)"
8957 "@
8958 xor{q}\t{%2, %0|%0, %2}
8959 xor{q}\t{%2, %0|%0, %2}"
8960 [(set_attr "type" "alu")
8961 (set_attr "mode" "DI,DI")])
8962
8963 (define_insn "*xordi_3_rex64"
8964 [(set (reg 17)
8965 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8966 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8967 (const_int 0)))
8968 (clobber (match_scratch:DI 0 "=r"))]
8969 "TARGET_64BIT
8970 && ix86_match_ccmode (insn, CCNOmode)
8971 && ix86_binary_operator_ok (XOR, DImode, operands)"
8972 "xor{q}\t{%2, %0|%0, %2}"
8973 [(set_attr "type" "alu")
8974 (set_attr "mode" "DI")])
8975
8976 (define_expand "xorsi3"
8977 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8978 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8979 (match_operand:SI 2 "general_operand" "")))
8980 (clobber (reg:CC 17))]
8981 ""
8982 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8983
8984 (define_insn "*xorsi_1"
8985 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8986 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8987 (match_operand:SI 2 "general_operand" "ri,rm")))
8988 (clobber (reg:CC 17))]
8989 "ix86_binary_operator_ok (XOR, SImode, operands)"
8990 "xor{l}\t{%2, %0|%0, %2}"
8991 [(set_attr "type" "alu")
8992 (set_attr "mode" "SI")])
8993
8994 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8995 ;; Add speccase for immediates
8996 (define_insn "*xorsi_1_zext"
8997 [(set (match_operand:DI 0 "register_operand" "=r")
8998 (zero_extend:DI
8999 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9000 (match_operand:SI 2 "general_operand" "rim"))))
9001 (clobber (reg:CC 17))]
9002 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9003 "xor{l}\t{%2, %k0|%k0, %2}"
9004 [(set_attr "type" "alu")
9005 (set_attr "mode" "SI")])
9006
9007 (define_insn "*xorsi_1_zext_imm"
9008 [(set (match_operand:DI 0 "register_operand" "=r")
9009 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9010 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9011 (clobber (reg:CC 17))]
9012 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9013 "xor{l}\t{%2, %k0|%k0, %2}"
9014 [(set_attr "type" "alu")
9015 (set_attr "mode" "SI")])
9016
9017 (define_insn "*xorsi_2"
9018 [(set (reg 17)
9019 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9020 (match_operand:SI 2 "general_operand" "rim,ri"))
9021 (const_int 0)))
9022 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9023 (xor:SI (match_dup 1) (match_dup 2)))]
9024 "ix86_match_ccmode (insn, CCNOmode)
9025 && ix86_binary_operator_ok (XOR, SImode, operands)"
9026 "xor{l}\t{%2, %0|%0, %2}"
9027 [(set_attr "type" "alu")
9028 (set_attr "mode" "SI")])
9029
9030 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9031 ;; ??? Special case for immediate operand is missing - it is tricky.
9032 (define_insn "*xorsi_2_zext"
9033 [(set (reg 17)
9034 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9035 (match_operand:SI 2 "general_operand" "rim"))
9036 (const_int 0)))
9037 (set (match_operand:DI 0 "register_operand" "=r")
9038 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9039 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9040 && ix86_binary_operator_ok (XOR, SImode, operands)"
9041 "xor{l}\t{%2, %k0|%k0, %2}"
9042 [(set_attr "type" "alu")
9043 (set_attr "mode" "SI")])
9044
9045 (define_insn "*xorsi_2_zext_imm"
9046 [(set (reg 17)
9047 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9048 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9049 (const_int 0)))
9050 (set (match_operand:DI 0 "register_operand" "=r")
9051 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9052 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9053 && ix86_binary_operator_ok (XOR, SImode, operands)"
9054 "xor{l}\t{%2, %k0|%k0, %2}"
9055 [(set_attr "type" "alu")
9056 (set_attr "mode" "SI")])
9057
9058 (define_insn "*xorsi_3"
9059 [(set (reg 17)
9060 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9061 (match_operand:SI 2 "general_operand" "rim"))
9062 (const_int 0)))
9063 (clobber (match_scratch:SI 0 "=r"))]
9064 "ix86_match_ccmode (insn, CCNOmode)
9065 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9066 "xor{l}\t{%2, %0|%0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "SI")])
9069
9070 (define_expand "xorhi3"
9071 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9072 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9073 (match_operand:HI 2 "general_operand" "")))
9074 (clobber (reg:CC 17))]
9075 "TARGET_HIMODE_MATH"
9076 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9077
9078 (define_insn "*xorhi_1"
9079 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9080 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9081 (match_operand:HI 2 "general_operand" "rmi,ri")))
9082 (clobber (reg:CC 17))]
9083 "ix86_binary_operator_ok (XOR, HImode, operands)"
9084 "xor{w}\t{%2, %0|%0, %2}"
9085 [(set_attr "type" "alu")
9086 (set_attr "mode" "HI")])
9087
9088 (define_insn "*xorhi_2"
9089 [(set (reg 17)
9090 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9091 (match_operand:HI 2 "general_operand" "rim,ri"))
9092 (const_int 0)))
9093 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9094 (xor:HI (match_dup 1) (match_dup 2)))]
9095 "ix86_match_ccmode (insn, CCNOmode)
9096 && ix86_binary_operator_ok (XOR, HImode, operands)"
9097 "xor{w}\t{%2, %0|%0, %2}"
9098 [(set_attr "type" "alu")
9099 (set_attr "mode" "HI")])
9100
9101 (define_insn "*xorhi_3"
9102 [(set (reg 17)
9103 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9104 (match_operand:HI 2 "general_operand" "rim"))
9105 (const_int 0)))
9106 (clobber (match_scratch:HI 0 "=r"))]
9107 "ix86_match_ccmode (insn, CCNOmode)
9108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9109 "xor{w}\t{%2, %0|%0, %2}"
9110 [(set_attr "type" "alu")
9111 (set_attr "mode" "HI")])
9112
9113 (define_expand "xorqi3"
9114 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9115 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9116 (match_operand:QI 2 "general_operand" "")))
9117 (clobber (reg:CC 17))]
9118 "TARGET_QIMODE_MATH"
9119 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9120
9121 ;; %%% Potential partial reg stall on alternative 2. What to do?
9122 (define_insn "*xorqi_1"
9123 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9124 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9125 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9126 (clobber (reg:CC 17))]
9127 "ix86_binary_operator_ok (XOR, QImode, operands)"
9128 "@
9129 xor{b}\t{%2, %0|%0, %2}
9130 xor{b}\t{%2, %0|%0, %2}
9131 xor{l}\t{%k2, %k0|%k0, %k2}"
9132 [(set_attr "type" "alu")
9133 (set_attr "mode" "QI,QI,SI")])
9134
9135 (define_insn "*xorqi_1_slp"
9136 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9137 (xor:QI (match_dup 0)
9138 (match_operand:QI 1 "general_operand" "qi,qmi")))
9139 (clobber (reg:CC 17))]
9140 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9141 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9142 "xor{b}\t{%1, %0|%0, %1}"
9143 [(set_attr "type" "alu1")
9144 (set_attr "mode" "QI")])
9145
9146 (define_insn "xorqi_ext_0"
9147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9148 (const_int 8)
9149 (const_int 8))
9150 (xor:SI
9151 (zero_extract:SI
9152 (match_operand 1 "ext_register_operand" "0")
9153 (const_int 8)
9154 (const_int 8))
9155 (match_operand 2 "const_int_operand" "n")))
9156 (clobber (reg:CC 17))]
9157 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9158 "xor{b}\t{%2, %h0|%h0, %2}"
9159 [(set_attr "type" "alu")
9160 (set_attr "length_immediate" "1")
9161 (set_attr "mode" "QI")])
9162
9163 (define_insn "*xorqi_ext_1"
9164 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9165 (const_int 8)
9166 (const_int 8))
9167 (xor:SI
9168 (zero_extract:SI
9169 (match_operand 1 "ext_register_operand" "0")
9170 (const_int 8)
9171 (const_int 8))
9172 (zero_extend:SI
9173 (match_operand:QI 2 "general_operand" "Qm"))))
9174 (clobber (reg:CC 17))]
9175 "!TARGET_64BIT
9176 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177 "xor{b}\t{%2, %h0|%h0, %2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "length_immediate" "0")
9180 (set_attr "mode" "QI")])
9181
9182 (define_insn "*xorqi_ext_1_rex64"
9183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9184 (const_int 8)
9185 (const_int 8))
9186 (xor:SI
9187 (zero_extract:SI
9188 (match_operand 1 "ext_register_operand" "0")
9189 (const_int 8)
9190 (const_int 8))
9191 (zero_extend:SI
9192 (match_operand 2 "ext_register_operand" "Q"))))
9193 (clobber (reg:CC 17))]
9194 "TARGET_64BIT
9195 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9196 "xor{b}\t{%2, %h0|%h0, %2}"
9197 [(set_attr "type" "alu")
9198 (set_attr "length_immediate" "0")
9199 (set_attr "mode" "QI")])
9200
9201 (define_insn "*xorqi_ext_2"
9202 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203 (const_int 8)
9204 (const_int 8))
9205 (xor:SI
9206 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9207 (const_int 8)
9208 (const_int 8))
9209 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9210 (const_int 8)
9211 (const_int 8))))
9212 (clobber (reg:CC 17))]
9213 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9214 "xor{b}\t{%h2, %h0|%h0, %h2}"
9215 [(set_attr "type" "alu")
9216 (set_attr "length_immediate" "0")
9217 (set_attr "mode" "QI")])
9218
9219 (define_insn "*xorqi_cc_1"
9220 [(set (reg 17)
9221 (compare
9222 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9223 (match_operand:QI 2 "general_operand" "qim,qi"))
9224 (const_int 0)))
9225 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9226 (xor:QI (match_dup 1) (match_dup 2)))]
9227 "ix86_match_ccmode (insn, CCNOmode)
9228 && ix86_binary_operator_ok (XOR, QImode, operands)"
9229 "xor{b}\t{%2, %0|%0, %2}"
9230 [(set_attr "type" "alu")
9231 (set_attr "mode" "QI")])
9232
9233 (define_insn "*xorqi_2_slp"
9234 [(set (reg 17)
9235 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9236 (match_operand:QI 1 "general_operand" "qim,qi"))
9237 (const_int 0)))
9238 (set (strict_low_part (match_dup 0))
9239 (xor:QI (match_dup 0) (match_dup 1)))]
9240 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9241 && ix86_match_ccmode (insn, CCNOmode)
9242 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9243 "xor{b}\t{%1, %0|%0, %1}"
9244 [(set_attr "type" "alu1")
9245 (set_attr "mode" "QI")])
9246
9247 (define_insn "*xorqi_cc_2"
9248 [(set (reg 17)
9249 (compare
9250 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9251 (match_operand:QI 2 "general_operand" "qim"))
9252 (const_int 0)))
9253 (clobber (match_scratch:QI 0 "=q"))]
9254 "ix86_match_ccmode (insn, CCNOmode)
9255 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9256 "xor{b}\t{%2, %0|%0, %2}"
9257 [(set_attr "type" "alu")
9258 (set_attr "mode" "QI")])
9259
9260 (define_insn "*xorqi_cc_ext_1"
9261 [(set (reg 17)
9262 (compare
9263 (xor:SI
9264 (zero_extract:SI
9265 (match_operand 1 "ext_register_operand" "0")
9266 (const_int 8)
9267 (const_int 8))
9268 (match_operand:QI 2 "general_operand" "qmn"))
9269 (const_int 0)))
9270 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9271 (const_int 8)
9272 (const_int 8))
9273 (xor:SI
9274 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9275 (match_dup 2)))]
9276 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9277 "xor{b}\t{%2, %h0|%h0, %2}"
9278 [(set_attr "type" "alu")
9279 (set_attr "mode" "QI")])
9280
9281 (define_insn "*xorqi_cc_ext_1_rex64"
9282 [(set (reg 17)
9283 (compare
9284 (xor:SI
9285 (zero_extract:SI
9286 (match_operand 1 "ext_register_operand" "0")
9287 (const_int 8)
9288 (const_int 8))
9289 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9290 (const_int 0)))
9291 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9292 (const_int 8)
9293 (const_int 8))
9294 (xor:SI
9295 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9296 (match_dup 2)))]
9297 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9298 "xor{b}\t{%2, %h0|%h0, %2}"
9299 [(set_attr "type" "alu")
9300 (set_attr "mode" "QI")])
9301
9302 (define_expand "xorqi_cc_ext_1"
9303 [(parallel [
9304 (set (reg:CCNO 17)
9305 (compare:CCNO
9306 (xor:SI
9307 (zero_extract:SI
9308 (match_operand 1 "ext_register_operand" "")
9309 (const_int 8)
9310 (const_int 8))
9311 (match_operand:QI 2 "general_operand" ""))
9312 (const_int 0)))
9313 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9314 (const_int 8)
9315 (const_int 8))
9316 (xor:SI
9317 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9318 (match_dup 2)))])]
9319 ""
9320 "")
9321
9322 (define_split
9323 [(set (match_operand 0 "register_operand" "")
9324 (xor (match_operand 1 "register_operand" "")
9325 (match_operand 2 "const_int_operand" "")))
9326 (clobber (reg:CC 17))]
9327 "reload_completed
9328 && QI_REG_P (operands[0])
9329 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9330 && !(INTVAL (operands[2]) & ~(255 << 8))
9331 && GET_MODE (operands[0]) != QImode"
9332 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9333 (xor:SI (zero_extract:SI (match_dup 1)
9334 (const_int 8) (const_int 8))
9335 (match_dup 2)))
9336 (clobber (reg:CC 17))])]
9337 "operands[0] = gen_lowpart (SImode, operands[0]);
9338 operands[1] = gen_lowpart (SImode, operands[1]);
9339 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9340
9341 ;; Since XOR can be encoded with sign extended immediate, this is only
9342 ;; profitable when 7th bit is set.
9343 (define_split
9344 [(set (match_operand 0 "register_operand" "")
9345 (xor (match_operand 1 "general_operand" "")
9346 (match_operand 2 "const_int_operand" "")))
9347 (clobber (reg:CC 17))]
9348 "reload_completed
9349 && ANY_QI_REG_P (operands[0])
9350 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9351 && !(INTVAL (operands[2]) & ~255)
9352 && (INTVAL (operands[2]) & 128)
9353 && GET_MODE (operands[0]) != QImode"
9354 [(parallel [(set (strict_low_part (match_dup 0))
9355 (xor:QI (match_dup 1)
9356 (match_dup 2)))
9357 (clobber (reg:CC 17))])]
9358 "operands[0] = gen_lowpart (QImode, operands[0]);
9359 operands[1] = gen_lowpart (QImode, operands[1]);
9360 operands[2] = gen_lowpart (QImode, operands[2]);")
9361 \f
9362 ;; Negation instructions
9363
9364 (define_expand "negdi2"
9365 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9366 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9367 (clobber (reg:CC 17))])]
9368 ""
9369 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9370
9371 (define_insn "*negdi2_1"
9372 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9373 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9374 (clobber (reg:CC 17))]
9375 "!TARGET_64BIT
9376 && ix86_unary_operator_ok (NEG, DImode, operands)"
9377 "#")
9378
9379 (define_split
9380 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9381 (neg:DI (match_operand:DI 1 "general_operand" "")))
9382 (clobber (reg:CC 17))]
9383 "!TARGET_64BIT && reload_completed"
9384 [(parallel
9385 [(set (reg:CCZ 17)
9386 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9387 (set (match_dup 0) (neg:SI (match_dup 2)))])
9388 (parallel
9389 [(set (match_dup 1)
9390 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9391 (match_dup 3))
9392 (const_int 0)))
9393 (clobber (reg:CC 17))])
9394 (parallel
9395 [(set (match_dup 1)
9396 (neg:SI (match_dup 1)))
9397 (clobber (reg:CC 17))])]
9398 "split_di (operands+1, 1, operands+2, operands+3);
9399 split_di (operands+0, 1, operands+0, operands+1);")
9400
9401 (define_insn "*negdi2_1_rex64"
9402 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9403 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9404 (clobber (reg:CC 17))]
9405 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9406 "neg{q}\t%0"
9407 [(set_attr "type" "negnot")
9408 (set_attr "mode" "DI")])
9409
9410 ;; The problem with neg is that it does not perform (compare x 0),
9411 ;; it really performs (compare 0 x), which leaves us with the zero
9412 ;; flag being the only useful item.
9413
9414 (define_insn "*negdi2_cmpz_rex64"
9415 [(set (reg:CCZ 17)
9416 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9417 (const_int 0)))
9418 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9419 (neg:DI (match_dup 1)))]
9420 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9421 "neg{q}\t%0"
9422 [(set_attr "type" "negnot")
9423 (set_attr "mode" "DI")])
9424
9425
9426 (define_expand "negsi2"
9427 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9428 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9429 (clobber (reg:CC 17))])]
9430 ""
9431 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9432
9433 (define_insn "*negsi2_1"
9434 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9435 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9436 (clobber (reg:CC 17))]
9437 "ix86_unary_operator_ok (NEG, SImode, operands)"
9438 "neg{l}\t%0"
9439 [(set_attr "type" "negnot")
9440 (set_attr "mode" "SI")])
9441
9442 ;; Combine is quite creative about this pattern.
9443 (define_insn "*negsi2_1_zext"
9444 [(set (match_operand:DI 0 "register_operand" "=r")
9445 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9446 (const_int 32)))
9447 (const_int 32)))
9448 (clobber (reg:CC 17))]
9449 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9450 "neg{l}\t%k0"
9451 [(set_attr "type" "negnot")
9452 (set_attr "mode" "SI")])
9453
9454 ;; The problem with neg is that it does not perform (compare x 0),
9455 ;; it really performs (compare 0 x), which leaves us with the zero
9456 ;; flag being the only useful item.
9457
9458 (define_insn "*negsi2_cmpz"
9459 [(set (reg:CCZ 17)
9460 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9461 (const_int 0)))
9462 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9463 (neg:SI (match_dup 1)))]
9464 "ix86_unary_operator_ok (NEG, SImode, operands)"
9465 "neg{l}\t%0"
9466 [(set_attr "type" "negnot")
9467 (set_attr "mode" "SI")])
9468
9469 (define_insn "*negsi2_cmpz_zext"
9470 [(set (reg:CCZ 17)
9471 (compare:CCZ (lshiftrt:DI
9472 (neg:DI (ashift:DI
9473 (match_operand:DI 1 "register_operand" "0")
9474 (const_int 32)))
9475 (const_int 32))
9476 (const_int 0)))
9477 (set (match_operand:DI 0 "register_operand" "=r")
9478 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9479 (const_int 32)))
9480 (const_int 32)))]
9481 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9482 "neg{l}\t%k0"
9483 [(set_attr "type" "negnot")
9484 (set_attr "mode" "SI")])
9485
9486 (define_expand "neghi2"
9487 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9488 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9489 (clobber (reg:CC 17))])]
9490 "TARGET_HIMODE_MATH"
9491 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9492
9493 (define_insn "*neghi2_1"
9494 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9495 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9496 (clobber (reg:CC 17))]
9497 "ix86_unary_operator_ok (NEG, HImode, operands)"
9498 "neg{w}\t%0"
9499 [(set_attr "type" "negnot")
9500 (set_attr "mode" "HI")])
9501
9502 (define_insn "*neghi2_cmpz"
9503 [(set (reg:CCZ 17)
9504 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9505 (const_int 0)))
9506 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9507 (neg:HI (match_dup 1)))]
9508 "ix86_unary_operator_ok (NEG, HImode, operands)"
9509 "neg{w}\t%0"
9510 [(set_attr "type" "negnot")
9511 (set_attr "mode" "HI")])
9512
9513 (define_expand "negqi2"
9514 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9515 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9516 (clobber (reg:CC 17))])]
9517 "TARGET_QIMODE_MATH"
9518 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9519
9520 (define_insn "*negqi2_1"
9521 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9522 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9523 (clobber (reg:CC 17))]
9524 "ix86_unary_operator_ok (NEG, QImode, operands)"
9525 "neg{b}\t%0"
9526 [(set_attr "type" "negnot")
9527 (set_attr "mode" "QI")])
9528
9529 (define_insn "*negqi2_cmpz"
9530 [(set (reg:CCZ 17)
9531 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9532 (const_int 0)))
9533 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9534 (neg:QI (match_dup 1)))]
9535 "ix86_unary_operator_ok (NEG, QImode, operands)"
9536 "neg{b}\t%0"
9537 [(set_attr "type" "negnot")
9538 (set_attr "mode" "QI")])
9539
9540 ;; Changing of sign for FP values is doable using integer unit too.
9541
9542 (define_expand "negsf2"
9543 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9544 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9545 (clobber (reg:CC 17))])]
9546 "TARGET_80387"
9547 "if (TARGET_SSE)
9548 {
9549 /* In case operand is in memory, we will not use SSE. */
9550 if (memory_operand (operands[0], VOIDmode)
9551 && rtx_equal_p (operands[0], operands[1]))
9552 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9553 else
9554 {
9555 /* Using SSE is tricky, since we need bitwise negation of -0
9556 in register. */
9557 rtx reg = gen_reg_rtx (SFmode);
9558 rtx dest = operands[0];
9559 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9560
9561 operands[1] = force_reg (SFmode, operands[1]);
9562 operands[0] = force_reg (SFmode, operands[0]);
9563 reg = force_reg (V4SFmode,
9564 gen_rtx_CONST_VECTOR (V4SFmode,
9565 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9566 CONST0_RTX (SFmode),
9567 CONST0_RTX (SFmode))));
9568 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9569 if (dest != operands[0])
9570 emit_move_insn (dest, operands[0]);
9571 }
9572 DONE;
9573 }
9574 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9575
9576 (define_insn "negsf2_memory"
9577 [(set (match_operand:SF 0 "memory_operand" "=m")
9578 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9579 (clobber (reg:CC 17))]
9580 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9581 "#")
9582
9583 (define_insn "negsf2_ifs"
9584 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9585 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9586 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9587 (clobber (reg:CC 17))]
9588 "TARGET_SSE
9589 && (reload_in_progress || reload_completed
9590 || (register_operand (operands[0], VOIDmode)
9591 && register_operand (operands[1], VOIDmode)))"
9592 "#")
9593
9594 (define_split
9595 [(set (match_operand:SF 0 "memory_operand" "")
9596 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9597 (use (match_operand:SF 2 "" ""))
9598 (clobber (reg:CC 17))]
9599 ""
9600 [(parallel [(set (match_dup 0)
9601 (neg:SF (match_dup 1)))
9602 (clobber (reg:CC 17))])])
9603
9604 (define_split
9605 [(set (match_operand:SF 0 "register_operand" "")
9606 (neg:SF (match_operand:SF 1 "register_operand" "")))
9607 (use (match_operand:V4SF 2 "" ""))
9608 (clobber (reg:CC 17))]
9609 "reload_completed && !SSE_REG_P (operands[0])"
9610 [(parallel [(set (match_dup 0)
9611 (neg:SF (match_dup 1)))
9612 (clobber (reg:CC 17))])])
9613
9614 (define_split
9615 [(set (match_operand:SF 0 "register_operand" "")
9616 (neg:SF (match_operand:SF 1 "register_operand" "")))
9617 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9618 (clobber (reg:CC 17))]
9619 "reload_completed && SSE_REG_P (operands[0])"
9620 [(set (match_dup 0)
9621 (xor:V4SF (match_dup 1)
9622 (match_dup 2)))]
9623 {
9624 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9625 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9626 if (operands_match_p (operands[0], operands[2]))
9627 {
9628 rtx tmp;
9629 tmp = operands[1];
9630 operands[1] = operands[2];
9631 operands[2] = tmp;
9632 }
9633 })
9634
9635
9636 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9637 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9638 ;; to itself.
9639 (define_insn "*negsf2_if"
9640 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9641 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9642 (clobber (reg:CC 17))]
9643 "TARGET_80387 && !TARGET_SSE
9644 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9645 "#")
9646
9647 (define_split
9648 [(set (match_operand:SF 0 "fp_register_operand" "")
9649 (neg:SF (match_operand:SF 1 "register_operand" "")))
9650 (clobber (reg:CC 17))]
9651 "TARGET_80387 && reload_completed"
9652 [(set (match_dup 0)
9653 (neg:SF (match_dup 1)))]
9654 "")
9655
9656 (define_split
9657 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9658 (neg:SF (match_operand:SF 1 "register_operand" "")))
9659 (clobber (reg:CC 17))]
9660 "TARGET_80387 && reload_completed"
9661 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9662 (clobber (reg:CC 17))])]
9663 "operands[1] = gen_int_mode (0x80000000, SImode);
9664 operands[0] = gen_lowpart (SImode, operands[0]);")
9665
9666 (define_split
9667 [(set (match_operand 0 "memory_operand" "")
9668 (neg (match_operand 1 "memory_operand" "")))
9669 (clobber (reg:CC 17))]
9670 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9671 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9672 (clobber (reg:CC 17))])]
9673 {
9674 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9675
9676 if (GET_MODE (operands[1]) == XFmode)
9677 size = 10;
9678 operands[0] = adjust_address (operands[0], QImode, size - 1);
9679 operands[1] = gen_int_mode (0x80, QImode);
9680 })
9681
9682 (define_expand "negdf2"
9683 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9684 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9685 (clobber (reg:CC 17))])]
9686 "TARGET_80387"
9687 "if (TARGET_SSE2)
9688 {
9689 /* In case operand is in memory, we will not use SSE. */
9690 if (memory_operand (operands[0], VOIDmode)
9691 && rtx_equal_p (operands[0], operands[1]))
9692 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9693 else
9694 {
9695 /* Using SSE is tricky, since we need bitwise negation of -0
9696 in register. */
9697 rtx reg;
9698 #if HOST_BITS_PER_WIDE_INT >= 64
9699 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9700 #else
9701 rtx imm = immed_double_const (0, 0x80000000, DImode);
9702 #endif
9703 rtx dest = operands[0];
9704
9705 operands[1] = force_reg (DFmode, operands[1]);
9706 operands[0] = force_reg (DFmode, operands[0]);
9707 imm = gen_lowpart (DFmode, imm);
9708 reg = force_reg (V2DFmode,
9709 gen_rtx_CONST_VECTOR (V2DFmode,
9710 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9711 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9712 if (dest != operands[0])
9713 emit_move_insn (dest, operands[0]);
9714 }
9715 DONE;
9716 }
9717 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9718
9719 (define_insn "negdf2_memory"
9720 [(set (match_operand:DF 0 "memory_operand" "=m")
9721 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9722 (clobber (reg:CC 17))]
9723 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9724 "#")
9725
9726 (define_insn "negdf2_ifs"
9727 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9728 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9729 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9730 (clobber (reg:CC 17))]
9731 "!TARGET_64BIT && TARGET_SSE2
9732 && (reload_in_progress || reload_completed
9733 || (register_operand (operands[0], VOIDmode)
9734 && register_operand (operands[1], VOIDmode)))"
9735 "#")
9736
9737 (define_insn "*negdf2_ifs_rex64"
9738 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9739 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9740 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9741 (clobber (reg:CC 17))]
9742 "TARGET_64BIT && TARGET_SSE2
9743 && (reload_in_progress || reload_completed
9744 || (register_operand (operands[0], VOIDmode)
9745 && register_operand (operands[1], VOIDmode)))"
9746 "#")
9747
9748 (define_split
9749 [(set (match_operand:DF 0 "memory_operand" "")
9750 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9751 (use (match_operand:V2DF 2 "" ""))
9752 (clobber (reg:CC 17))]
9753 ""
9754 [(parallel [(set (match_dup 0)
9755 (neg:DF (match_dup 1)))
9756 (clobber (reg:CC 17))])])
9757
9758 (define_split
9759 [(set (match_operand:DF 0 "register_operand" "")
9760 (neg:DF (match_operand:DF 1 "register_operand" "")))
9761 (use (match_operand:V2DF 2 "" ""))
9762 (clobber (reg:CC 17))]
9763 "reload_completed && !SSE_REG_P (operands[0])
9764 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9765 [(parallel [(set (match_dup 0)
9766 (neg:DF (match_dup 1)))
9767 (clobber (reg:CC 17))])])
9768
9769 (define_split
9770 [(set (match_operand:DF 0 "register_operand" "")
9771 (neg:DF (match_operand:DF 1 "register_operand" "")))
9772 (use (match_operand:V2DF 2 "" ""))
9773 (clobber (reg:CC 17))]
9774 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9775 [(parallel [(set (match_dup 0)
9776 (xor:DI (match_dup 1) (match_dup 2)))
9777 (clobber (reg:CC 17))])]
9778 "operands[0] = gen_lowpart (DImode, operands[0]);
9779 operands[1] = gen_lowpart (DImode, operands[1]);
9780 operands[2] = gen_lowpart (DImode, operands[2]);")
9781
9782 (define_split
9783 [(set (match_operand:DF 0 "register_operand" "")
9784 (neg:DF (match_operand:DF 1 "register_operand" "")))
9785 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9786 (clobber (reg:CC 17))]
9787 "reload_completed && SSE_REG_P (operands[0])"
9788 [(set (match_dup 0)
9789 (xor:V2DF (match_dup 1)
9790 (match_dup 2)))]
9791 {
9792 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9793 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9794 /* Avoid possible reformatting on the operands. */
9795 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9796 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9797 if (operands_match_p (operands[0], operands[2]))
9798 {
9799 rtx tmp;
9800 tmp = operands[1];
9801 operands[1] = operands[2];
9802 operands[2] = tmp;
9803 }
9804 })
9805
9806 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9807 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9808 ;; to itself.
9809 (define_insn "*negdf2_if"
9810 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9811 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9812 (clobber (reg:CC 17))]
9813 "!TARGET_64BIT && TARGET_80387
9814 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9815 "#")
9816
9817 ;; FIXME: We should to allow integer registers here. Problem is that
9818 ;; we need another scratch register to get constant from.
9819 ;; Forcing constant to mem if no register available in peep2 should be
9820 ;; safe even for PIC mode, because of RIP relative addressing.
9821 (define_insn "*negdf2_if_rex64"
9822 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9823 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9824 (clobber (reg:CC 17))]
9825 "TARGET_64BIT && TARGET_80387
9826 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9827 "#")
9828
9829 (define_split
9830 [(set (match_operand:DF 0 "fp_register_operand" "")
9831 (neg:DF (match_operand:DF 1 "register_operand" "")))
9832 (clobber (reg:CC 17))]
9833 "TARGET_80387 && reload_completed"
9834 [(set (match_dup 0)
9835 (neg:DF (match_dup 1)))]
9836 "")
9837
9838 (define_split
9839 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9840 (neg:DF (match_operand:DF 1 "register_operand" "")))
9841 (clobber (reg:CC 17))]
9842 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9843 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9844 (clobber (reg:CC 17))])]
9845 "operands[4] = gen_int_mode (0x80000000, SImode);
9846 split_di (operands+0, 1, operands+2, operands+3);")
9847
9848 (define_expand "negxf2"
9849 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9850 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9851 (clobber (reg:CC 17))])]
9852 "TARGET_80387"
9853 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9854
9855 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9856 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9857 ;; to itself.
9858 (define_insn "*negxf2_if"
9859 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9860 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9861 (clobber (reg:CC 17))]
9862 "TARGET_80387
9863 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9864 "#")
9865
9866 (define_split
9867 [(set (match_operand:XF 0 "fp_register_operand" "")
9868 (neg:XF (match_operand:XF 1 "register_operand" "")))
9869 (clobber (reg:CC 17))]
9870 "TARGET_80387 && reload_completed"
9871 [(set (match_dup 0)
9872 (neg:XF (match_dup 1)))]
9873 "")
9874
9875 (define_split
9876 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9877 (neg:XF (match_operand:XF 1 "register_operand" "")))
9878 (clobber (reg:CC 17))]
9879 "TARGET_80387 && reload_completed"
9880 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9881 (clobber (reg:CC 17))])]
9882 "operands[1] = GEN_INT (0x8000);
9883 operands[0] = gen_rtx_REG (SImode,
9884 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9885
9886 ;; Conditionalize these after reload. If they matches before reload, we
9887 ;; lose the clobber and ability to use integer instructions.
9888
9889 (define_insn "*negsf2_1"
9890 [(set (match_operand:SF 0 "register_operand" "=f")
9891 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9892 "TARGET_80387 && reload_completed"
9893 "fchs"
9894 [(set_attr "type" "fsgn")
9895 (set_attr "mode" "SF")])
9896
9897 (define_insn "*negdf2_1"
9898 [(set (match_operand:DF 0 "register_operand" "=f")
9899 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9900 "TARGET_80387 && reload_completed"
9901 "fchs"
9902 [(set_attr "type" "fsgn")
9903 (set_attr "mode" "DF")])
9904
9905 (define_insn "*negextendsfdf2"
9906 [(set (match_operand:DF 0 "register_operand" "=f")
9907 (neg:DF (float_extend:DF
9908 (match_operand:SF 1 "register_operand" "0"))))]
9909 "TARGET_80387"
9910 "fchs"
9911 [(set_attr "type" "fsgn")
9912 (set_attr "mode" "DF")])
9913
9914 (define_insn "*negxf2_1"
9915 [(set (match_operand:XF 0 "register_operand" "=f")
9916 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9917 "TARGET_80387 && reload_completed"
9918 "fchs"
9919 [(set_attr "type" "fsgn")
9920 (set_attr "mode" "XF")])
9921
9922 (define_insn "*negextenddfxf2"
9923 [(set (match_operand:XF 0 "register_operand" "=f")
9924 (neg:XF (float_extend:XF
9925 (match_operand:DF 1 "register_operand" "0"))))]
9926 "TARGET_80387"
9927 "fchs"
9928 [(set_attr "type" "fsgn")
9929 (set_attr "mode" "XF")])
9930
9931 (define_insn "*negextendsfxf2"
9932 [(set (match_operand:XF 0 "register_operand" "=f")
9933 (neg:XF (float_extend:XF
9934 (match_operand:SF 1 "register_operand" "0"))))]
9935 "TARGET_80387"
9936 "fchs"
9937 [(set_attr "type" "fsgn")
9938 (set_attr "mode" "XF")])
9939 \f
9940 ;; Absolute value instructions
9941
9942 (define_expand "abssf2"
9943 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9944 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9945 (clobber (reg:CC 17))])]
9946 "TARGET_80387"
9947 "if (TARGET_SSE)
9948 {
9949 /* In case operand is in memory, we will not use SSE. */
9950 if (memory_operand (operands[0], VOIDmode)
9951 && rtx_equal_p (operands[0], operands[1]))
9952 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9953 else
9954 {
9955 /* Using SSE is tricky, since we need bitwise negation of -0
9956 in register. */
9957 rtx reg = gen_reg_rtx (V4SFmode);
9958 rtx dest = operands[0];
9959 rtx imm;
9960
9961 operands[1] = force_reg (SFmode, operands[1]);
9962 operands[0] = force_reg (SFmode, operands[0]);
9963 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9964 reg = force_reg (V4SFmode,
9965 gen_rtx_CONST_VECTOR (V4SFmode,
9966 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9967 CONST0_RTX (SFmode),
9968 CONST0_RTX (SFmode))));
9969 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9970 if (dest != operands[0])
9971 emit_move_insn (dest, operands[0]);
9972 }
9973 DONE;
9974 }
9975 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9976
9977 (define_insn "abssf2_memory"
9978 [(set (match_operand:SF 0 "memory_operand" "=m")
9979 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9980 (clobber (reg:CC 17))]
9981 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9982 "#")
9983
9984 (define_insn "abssf2_ifs"
9985 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9986 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9987 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9988 (clobber (reg:CC 17))]
9989 "TARGET_SSE
9990 && (reload_in_progress || reload_completed
9991 || (register_operand (operands[0], VOIDmode)
9992 && register_operand (operands[1], VOIDmode)))"
9993 "#")
9994
9995 (define_split
9996 [(set (match_operand:SF 0 "memory_operand" "")
9997 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9998 (use (match_operand:V4SF 2 "" ""))
9999 (clobber (reg:CC 17))]
10000 ""
10001 [(parallel [(set (match_dup 0)
10002 (abs:SF (match_dup 1)))
10003 (clobber (reg:CC 17))])])
10004
10005 (define_split
10006 [(set (match_operand:SF 0 "register_operand" "")
10007 (abs:SF (match_operand:SF 1 "register_operand" "")))
10008 (use (match_operand:V4SF 2 "" ""))
10009 (clobber (reg:CC 17))]
10010 "reload_completed && !SSE_REG_P (operands[0])"
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 "nonimmediate_operand" ""))
10019 (clobber (reg:CC 17))]
10020 "reload_completed && SSE_REG_P (operands[0])"
10021 [(set (match_dup 0)
10022 (and:V4SF (match_dup 1)
10023 (match_dup 2)))]
10024 {
10025 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10026 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10027 if (operands_match_p (operands[0], operands[2]))
10028 {
10029 rtx tmp;
10030 tmp = operands[1];
10031 operands[1] = operands[2];
10032 operands[2] = tmp;
10033 }
10034 })
10035
10036 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10037 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10038 ;; to itself.
10039 (define_insn "*abssf2_if"
10040 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10041 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10042 (clobber (reg:CC 17))]
10043 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10044 "#")
10045
10046 (define_split
10047 [(set (match_operand:SF 0 "fp_register_operand" "")
10048 (abs:SF (match_operand:SF 1 "register_operand" "")))
10049 (clobber (reg:CC 17))]
10050 "TARGET_80387 && reload_completed"
10051 [(set (match_dup 0)
10052 (abs:SF (match_dup 1)))]
10053 "")
10054
10055 (define_split
10056 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10057 (abs:SF (match_operand:SF 1 "register_operand" "")))
10058 (clobber (reg:CC 17))]
10059 "TARGET_80387 && reload_completed"
10060 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10061 (clobber (reg:CC 17))])]
10062 "operands[1] = gen_int_mode (~0x80000000, SImode);
10063 operands[0] = gen_lowpart (SImode, operands[0]);")
10064
10065 (define_split
10066 [(set (match_operand 0 "memory_operand" "")
10067 (abs (match_operand 1 "memory_operand" "")))
10068 (clobber (reg:CC 17))]
10069 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10070 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10071 (clobber (reg:CC 17))])]
10072 {
10073 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10074
10075 if (GET_MODE (operands[1]) == XFmode)
10076 size = 10;
10077 operands[0] = adjust_address (operands[0], QImode, size - 1);
10078 operands[1] = gen_int_mode (~0x80, QImode);
10079 })
10080
10081 (define_expand "absdf2"
10082 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10083 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10084 (clobber (reg:CC 17))])]
10085 "TARGET_80387"
10086 "if (TARGET_SSE2)
10087 {
10088 /* In case operand is in memory, we will not use SSE. */
10089 if (memory_operand (operands[0], VOIDmode)
10090 && rtx_equal_p (operands[0], operands[1]))
10091 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10092 else
10093 {
10094 /* Using SSE is tricky, since we need bitwise negation of -0
10095 in register. */
10096 rtx reg = gen_reg_rtx (V2DFmode);
10097 #if HOST_BITS_PER_WIDE_INT >= 64
10098 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10099 #else
10100 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10101 #endif
10102 rtx dest = operands[0];
10103
10104 operands[1] = force_reg (DFmode, operands[1]);
10105 operands[0] = force_reg (DFmode, operands[0]);
10106
10107 /* Produce LONG_DOUBLE with the proper immediate argument. */
10108 imm = gen_lowpart (DFmode, imm);
10109 reg = force_reg (V2DFmode,
10110 gen_rtx_CONST_VECTOR (V2DFmode,
10111 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10112 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10113 if (dest != operands[0])
10114 emit_move_insn (dest, operands[0]);
10115 }
10116 DONE;
10117 }
10118 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10119
10120 (define_insn "absdf2_memory"
10121 [(set (match_operand:DF 0 "memory_operand" "=m")
10122 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10123 (clobber (reg:CC 17))]
10124 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10125 "#")
10126
10127 (define_insn "absdf2_ifs"
10128 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10129 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10130 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10131 (clobber (reg:CC 17))]
10132 "!TARGET_64BIT && TARGET_SSE2
10133 && (reload_in_progress || reload_completed
10134 || (register_operand (operands[0], VOIDmode)
10135 && register_operand (operands[1], VOIDmode)))"
10136 "#")
10137
10138 (define_insn "*absdf2_ifs_rex64"
10139 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10140 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10141 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,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_split
10150 [(set (match_operand:DF 0 "memory_operand" "")
10151 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10152 (use (match_operand:V2DF 2 "" ""))
10153 (clobber (reg:CC 17))]
10154 ""
10155 [(parallel [(set (match_dup 0)
10156 (abs:DF (match_dup 1)))
10157 (clobber (reg:CC 17))])])
10158
10159 (define_split
10160 [(set (match_operand:DF 0 "register_operand" "")
10161 (abs:DF (match_operand:DF 1 "register_operand" "")))
10162 (use (match_operand:V2DF 2 "" ""))
10163 (clobber (reg:CC 17))]
10164 "reload_completed && !SSE_REG_P (operands[0])"
10165 [(parallel [(set (match_dup 0)
10166 (abs:DF (match_dup 1)))
10167 (clobber (reg:CC 17))])])
10168
10169 (define_split
10170 [(set (match_operand:DF 0 "register_operand" "")
10171 (abs:DF (match_operand:DF 1 "register_operand" "")))
10172 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10173 (clobber (reg:CC 17))]
10174 "reload_completed && SSE_REG_P (operands[0])"
10175 [(set (match_dup 0)
10176 (and:V2DF (match_dup 1)
10177 (match_dup 2)))]
10178 {
10179 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10180 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10181 /* Avoid possible reformatting on the operands. */
10182 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10183 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10184 if (operands_match_p (operands[0], operands[2]))
10185 {
10186 rtx tmp;
10187 tmp = operands[1];
10188 operands[1] = operands[2];
10189 operands[2] = tmp;
10190 }
10191 })
10192
10193
10194 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10195 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10196 ;; to itself.
10197 (define_insn "*absdf2_if"
10198 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10199 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10200 (clobber (reg:CC 17))]
10201 "!TARGET_64BIT && TARGET_80387
10202 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10203 "#")
10204
10205 ;; FIXME: We should to allow integer registers here. Problem is that
10206 ;; we need another scratch register to get constant from.
10207 ;; Forcing constant to mem if no register available in peep2 should be
10208 ;; safe even for PIC mode, because of RIP relative addressing.
10209 (define_insn "*absdf2_if_rex64"
10210 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
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 (define_split
10218 [(set (match_operand:DF 0 "fp_register_operand" "")
10219 (abs:DF (match_operand:DF 1 "register_operand" "")))
10220 (clobber (reg:CC 17))]
10221 "TARGET_80387 && reload_completed"
10222 [(set (match_dup 0)
10223 (abs:DF (match_dup 1)))]
10224 "")
10225
10226 (define_split
10227 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10228 (abs:DF (match_operand:DF 1 "register_operand" "")))
10229 (clobber (reg:CC 17))]
10230 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10231 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10232 (clobber (reg:CC 17))])]
10233 "operands[4] = gen_int_mode (~0x80000000, SImode);
10234 split_di (operands+0, 1, operands+2, operands+3);")
10235
10236 (define_expand "absxf2"
10237 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10238 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10239 (clobber (reg:CC 17))])]
10240 "TARGET_80387"
10241 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10242
10243 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10244 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10245 ;; to itself.
10246 (define_insn "*absxf2_if"
10247 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10248 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10249 (clobber (reg:CC 17))]
10250 "TARGET_80387
10251 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10252 "#")
10253
10254 (define_split
10255 [(set (match_operand:XF 0 "fp_register_operand" "")
10256 (abs:XF (match_operand:XF 1 "register_operand" "")))
10257 (clobber (reg:CC 17))]
10258 "TARGET_80387 && reload_completed"
10259 [(set (match_dup 0)
10260 (abs:XF (match_dup 1)))]
10261 "")
10262
10263 (define_split
10264 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10265 (abs:XF (match_operand:XF 1 "register_operand" "")))
10266 (clobber (reg:CC 17))]
10267 "TARGET_80387 && reload_completed"
10268 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10269 (clobber (reg:CC 17))])]
10270 "operands[1] = GEN_INT (~0x8000);
10271 operands[0] = gen_rtx_REG (SImode,
10272 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10273
10274 (define_insn "*abssf2_1"
10275 [(set (match_operand:SF 0 "register_operand" "=f")
10276 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10277 "TARGET_80387 && reload_completed"
10278 "fabs"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "SF")])
10281
10282 (define_insn "*absdf2_1"
10283 [(set (match_operand:DF 0 "register_operand" "=f")
10284 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10285 "TARGET_80387 && reload_completed"
10286 "fabs"
10287 [(set_attr "type" "fsgn")
10288 (set_attr "mode" "DF")])
10289
10290 (define_insn "*absextendsfdf2"
10291 [(set (match_operand:DF 0 "register_operand" "=f")
10292 (abs:DF (float_extend:DF
10293 (match_operand:SF 1 "register_operand" "0"))))]
10294 "TARGET_80387"
10295 "fabs"
10296 [(set_attr "type" "fsgn")
10297 (set_attr "mode" "DF")])
10298
10299 (define_insn "*absxf2_1"
10300 [(set (match_operand:XF 0 "register_operand" "=f")
10301 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10302 "TARGET_80387 && reload_completed"
10303 "fabs"
10304 [(set_attr "type" "fsgn")
10305 (set_attr "mode" "DF")])
10306
10307 (define_insn "*absextenddfxf2"
10308 [(set (match_operand:XF 0 "register_operand" "=f")
10309 (abs:XF (float_extend:XF
10310 (match_operand:DF 1 "register_operand" "0"))))]
10311 "TARGET_80387"
10312 "fabs"
10313 [(set_attr "type" "fsgn")
10314 (set_attr "mode" "XF")])
10315
10316 (define_insn "*absextendsfxf2"
10317 [(set (match_operand:XF 0 "register_operand" "=f")
10318 (abs:XF (float_extend:XF
10319 (match_operand:SF 1 "register_operand" "0"))))]
10320 "TARGET_80387"
10321 "fabs"
10322 [(set_attr "type" "fsgn")
10323 (set_attr "mode" "XF")])
10324 \f
10325 ;; One complement instructions
10326
10327 (define_expand "one_cmpldi2"
10328 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10329 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10330 "TARGET_64BIT"
10331 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10332
10333 (define_insn "*one_cmpldi2_1_rex64"
10334 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10335 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10336 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10337 "not{q}\t%0"
10338 [(set_attr "type" "negnot")
10339 (set_attr "mode" "DI")])
10340
10341 (define_insn "*one_cmpldi2_2_rex64"
10342 [(set (reg 17)
10343 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10344 (const_int 0)))
10345 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10346 (not:DI (match_dup 1)))]
10347 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10348 && ix86_unary_operator_ok (NOT, DImode, operands)"
10349 "#"
10350 [(set_attr "type" "alu1")
10351 (set_attr "mode" "DI")])
10352
10353 (define_split
10354 [(set (reg 17)
10355 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10356 (const_int 0)))
10357 (set (match_operand:DI 0 "nonimmediate_operand" "")
10358 (not:DI (match_dup 1)))]
10359 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10360 [(parallel [(set (reg:CCNO 17)
10361 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10362 (const_int 0)))
10363 (set (match_dup 0)
10364 (xor:DI (match_dup 1) (const_int -1)))])]
10365 "")
10366
10367 (define_expand "one_cmplsi2"
10368 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10369 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10370 ""
10371 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10372
10373 (define_insn "*one_cmplsi2_1"
10374 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10375 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10376 "ix86_unary_operator_ok (NOT, SImode, operands)"
10377 "not{l}\t%0"
10378 [(set_attr "type" "negnot")
10379 (set_attr "mode" "SI")])
10380
10381 ;; ??? Currently never generated - xor is used instead.
10382 (define_insn "*one_cmplsi2_1_zext"
10383 [(set (match_operand:DI 0 "register_operand" "=r")
10384 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10385 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10386 "not{l}\t%k0"
10387 [(set_attr "type" "negnot")
10388 (set_attr "mode" "SI")])
10389
10390 (define_insn "*one_cmplsi2_2"
10391 [(set (reg 17)
10392 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10393 (const_int 0)))
10394 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10395 (not:SI (match_dup 1)))]
10396 "ix86_match_ccmode (insn, CCNOmode)
10397 && ix86_unary_operator_ok (NOT, SImode, operands)"
10398 "#"
10399 [(set_attr "type" "alu1")
10400 (set_attr "mode" "SI")])
10401
10402 (define_split
10403 [(set (reg 17)
10404 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10405 (const_int 0)))
10406 (set (match_operand:SI 0 "nonimmediate_operand" "")
10407 (not:SI (match_dup 1)))]
10408 "ix86_match_ccmode (insn, CCNOmode)"
10409 [(parallel [(set (reg:CCNO 17)
10410 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10411 (const_int 0)))
10412 (set (match_dup 0)
10413 (xor:SI (match_dup 1) (const_int -1)))])]
10414 "")
10415
10416 ;; ??? Currently never generated - xor is used instead.
10417 (define_insn "*one_cmplsi2_2_zext"
10418 [(set (reg 17)
10419 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10420 (const_int 0)))
10421 (set (match_operand:DI 0 "register_operand" "=r")
10422 (zero_extend:DI (not:SI (match_dup 1))))]
10423 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10424 && ix86_unary_operator_ok (NOT, SImode, operands)"
10425 "#"
10426 [(set_attr "type" "alu1")
10427 (set_attr "mode" "SI")])
10428
10429 (define_split
10430 [(set (reg 17)
10431 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10432 (const_int 0)))
10433 (set (match_operand:DI 0 "register_operand" "")
10434 (zero_extend:DI (not:SI (match_dup 1))))]
10435 "ix86_match_ccmode (insn, CCNOmode)"
10436 [(parallel [(set (reg:CCNO 17)
10437 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10438 (const_int 0)))
10439 (set (match_dup 0)
10440 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10441 "")
10442
10443 (define_expand "one_cmplhi2"
10444 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10445 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10446 "TARGET_HIMODE_MATH"
10447 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10448
10449 (define_insn "*one_cmplhi2_1"
10450 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10451 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10452 "ix86_unary_operator_ok (NOT, HImode, operands)"
10453 "not{w}\t%0"
10454 [(set_attr "type" "negnot")
10455 (set_attr "mode" "HI")])
10456
10457 (define_insn "*one_cmplhi2_2"
10458 [(set (reg 17)
10459 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10460 (const_int 0)))
10461 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10462 (not:HI (match_dup 1)))]
10463 "ix86_match_ccmode (insn, CCNOmode)
10464 && ix86_unary_operator_ok (NEG, HImode, operands)"
10465 "#"
10466 [(set_attr "type" "alu1")
10467 (set_attr "mode" "HI")])
10468
10469 (define_split
10470 [(set (reg 17)
10471 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10472 (const_int 0)))
10473 (set (match_operand:HI 0 "nonimmediate_operand" "")
10474 (not:HI (match_dup 1)))]
10475 "ix86_match_ccmode (insn, CCNOmode)"
10476 [(parallel [(set (reg:CCNO 17)
10477 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10478 (const_int 0)))
10479 (set (match_dup 0)
10480 (xor:HI (match_dup 1) (const_int -1)))])]
10481 "")
10482
10483 ;; %%% Potential partial reg stall on alternative 1. What to do?
10484 (define_expand "one_cmplqi2"
10485 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10486 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10487 "TARGET_QIMODE_MATH"
10488 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10489
10490 (define_insn "*one_cmplqi2_1"
10491 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10492 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10493 "ix86_unary_operator_ok (NOT, QImode, operands)"
10494 "@
10495 not{b}\t%0
10496 not{l}\t%k0"
10497 [(set_attr "type" "negnot")
10498 (set_attr "mode" "QI,SI")])
10499
10500 (define_insn "*one_cmplqi2_2"
10501 [(set (reg 17)
10502 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10503 (const_int 0)))
10504 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10505 (not:QI (match_dup 1)))]
10506 "ix86_match_ccmode (insn, CCNOmode)
10507 && ix86_unary_operator_ok (NOT, QImode, operands)"
10508 "#"
10509 [(set_attr "type" "alu1")
10510 (set_attr "mode" "QI")])
10511
10512 (define_split
10513 [(set (reg 17)
10514 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10515 (const_int 0)))
10516 (set (match_operand:QI 0 "nonimmediate_operand" "")
10517 (not:QI (match_dup 1)))]
10518 "ix86_match_ccmode (insn, CCNOmode)"
10519 [(parallel [(set (reg:CCNO 17)
10520 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10521 (const_int 0)))
10522 (set (match_dup 0)
10523 (xor:QI (match_dup 1) (const_int -1)))])]
10524 "")
10525 \f
10526 ;; Arithmetic shift instructions
10527
10528 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10529 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10530 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10531 ;; from the assembler input.
10532 ;;
10533 ;; This instruction shifts the target reg/mem as usual, but instead of
10534 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10535 ;; is a left shift double, bits are taken from the high order bits of
10536 ;; reg, else if the insn is a shift right double, bits are taken from the
10537 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10538 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10539 ;;
10540 ;; Since sh[lr]d does not change the `reg' operand, that is done
10541 ;; separately, making all shifts emit pairs of shift double and normal
10542 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10543 ;; support a 63 bit shift, each shift where the count is in a reg expands
10544 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10545 ;;
10546 ;; If the shift count is a constant, we need never emit more than one
10547 ;; shift pair, instead using moves and sign extension for counts greater
10548 ;; than 31.
10549
10550 (define_expand "ashldi3"
10551 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10552 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10553 (match_operand:QI 2 "nonmemory_operand" "")))
10554 (clobber (reg:CC 17))])]
10555 ""
10556 {
10557 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10558 {
10559 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10560 DONE;
10561 }
10562 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10563 DONE;
10564 })
10565
10566 (define_insn "*ashldi3_1_rex64"
10567 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10568 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10569 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10570 (clobber (reg:CC 17))]
10571 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10572 {
10573 switch (get_attr_type (insn))
10574 {
10575 case TYPE_ALU:
10576 if (operands[2] != const1_rtx)
10577 abort ();
10578 if (!rtx_equal_p (operands[0], operands[1]))
10579 abort ();
10580 return "add{q}\t{%0, %0|%0, %0}";
10581
10582 case TYPE_LEA:
10583 if (GET_CODE (operands[2]) != CONST_INT
10584 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10585 abort ();
10586 operands[1] = gen_rtx_MULT (DImode, operands[1],
10587 GEN_INT (1 << INTVAL (operands[2])));
10588 return "lea{q}\t{%a1, %0|%0, %a1}";
10589
10590 default:
10591 if (REG_P (operands[2]))
10592 return "sal{q}\t{%b2, %0|%0, %b2}";
10593 else if (operands[2] == const1_rtx
10594 && (TARGET_SHIFT1 || optimize_size))
10595 return "sal{q}\t%0";
10596 else
10597 return "sal{q}\t{%2, %0|%0, %2}";
10598 }
10599 }
10600 [(set (attr "type")
10601 (cond [(eq_attr "alternative" "1")
10602 (const_string "lea")
10603 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10604 (const_int 0))
10605 (match_operand 0 "register_operand" ""))
10606 (match_operand 2 "const1_operand" ""))
10607 (const_string "alu")
10608 ]
10609 (const_string "ishift")))
10610 (set_attr "mode" "DI")])
10611
10612 ;; Convert lea to the lea pattern to avoid flags dependency.
10613 (define_split
10614 [(set (match_operand:DI 0 "register_operand" "")
10615 (ashift:DI (match_operand:DI 1 "register_operand" "")
10616 (match_operand:QI 2 "immediate_operand" "")))
10617 (clobber (reg:CC 17))]
10618 "TARGET_64BIT && reload_completed
10619 && true_regnum (operands[0]) != true_regnum (operands[1])"
10620 [(set (match_dup 0)
10621 (mult:DI (match_dup 1)
10622 (match_dup 2)))]
10623 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10624
10625 ;; This pattern can't accept a variable shift count, since shifts by
10626 ;; zero don't affect the flags. We assume that shifts by constant
10627 ;; zero are optimized away.
10628 (define_insn "*ashldi3_cmp_rex64"
10629 [(set (reg 17)
10630 (compare
10631 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10632 (match_operand:QI 2 "immediate_operand" "e"))
10633 (const_int 0)))
10634 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10635 (ashift:DI (match_dup 1) (match_dup 2)))]
10636 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10637 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10638 {
10639 switch (get_attr_type (insn))
10640 {
10641 case TYPE_ALU:
10642 if (operands[2] != const1_rtx)
10643 abort ();
10644 return "add{q}\t{%0, %0|%0, %0}";
10645
10646 default:
10647 if (REG_P (operands[2]))
10648 return "sal{q}\t{%b2, %0|%0, %b2}";
10649 else if (operands[2] == const1_rtx
10650 && (TARGET_SHIFT1 || optimize_size))
10651 return "sal{q}\t%0";
10652 else
10653 return "sal{q}\t{%2, %0|%0, %2}";
10654 }
10655 }
10656 [(set (attr "type")
10657 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10658 (const_int 0))
10659 (match_operand 0 "register_operand" ""))
10660 (match_operand 2 "const1_operand" ""))
10661 (const_string "alu")
10662 ]
10663 (const_string "ishift")))
10664 (set_attr "mode" "DI")])
10665
10666 (define_insn "ashldi3_1"
10667 [(set (match_operand:DI 0 "register_operand" "=r")
10668 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10669 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10670 (clobber (match_scratch:SI 3 "=&r"))
10671 (clobber (reg:CC 17))]
10672 "!TARGET_64BIT && TARGET_CMOVE"
10673 "#"
10674 [(set_attr "type" "multi")])
10675
10676 (define_insn "*ashldi3_2"
10677 [(set (match_operand:DI 0 "register_operand" "=r")
10678 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10679 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10680 (clobber (reg:CC 17))]
10681 "!TARGET_64BIT"
10682 "#"
10683 [(set_attr "type" "multi")])
10684
10685 (define_split
10686 [(set (match_operand:DI 0 "register_operand" "")
10687 (ashift:DI (match_operand:DI 1 "register_operand" "")
10688 (match_operand:QI 2 "nonmemory_operand" "")))
10689 (clobber (match_scratch:SI 3 ""))
10690 (clobber (reg:CC 17))]
10691 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10692 [(const_int 0)]
10693 "ix86_split_ashldi (operands, operands[3]); DONE;")
10694
10695 (define_split
10696 [(set (match_operand:DI 0 "register_operand" "")
10697 (ashift:DI (match_operand:DI 1 "register_operand" "")
10698 (match_operand:QI 2 "nonmemory_operand" "")))
10699 (clobber (reg:CC 17))]
10700 "!TARGET_64BIT && reload_completed"
10701 [(const_int 0)]
10702 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10703
10704 (define_insn "x86_shld_1"
10705 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10706 (ior:SI (ashift:SI (match_dup 0)
10707 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10708 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10709 (minus:QI (const_int 32) (match_dup 2)))))
10710 (clobber (reg:CC 17))]
10711 ""
10712 "@
10713 shld{l}\t{%2, %1, %0|%0, %1, %2}
10714 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10715 [(set_attr "type" "ishift")
10716 (set_attr "prefix_0f" "1")
10717 (set_attr "mode" "SI")
10718 (set_attr "pent_pair" "np")
10719 (set_attr "athlon_decode" "vector")])
10720
10721 (define_expand "x86_shift_adj_1"
10722 [(set (reg:CCZ 17)
10723 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10724 (const_int 32))
10725 (const_int 0)))
10726 (set (match_operand:SI 0 "register_operand" "")
10727 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10728 (match_operand:SI 1 "register_operand" "")
10729 (match_dup 0)))
10730 (set (match_dup 1)
10731 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10732 (match_operand:SI 3 "register_operand" "r")
10733 (match_dup 1)))]
10734 "TARGET_CMOVE"
10735 "")
10736
10737 (define_expand "x86_shift_adj_2"
10738 [(use (match_operand:SI 0 "register_operand" ""))
10739 (use (match_operand:SI 1 "register_operand" ""))
10740 (use (match_operand:QI 2 "register_operand" ""))]
10741 ""
10742 {
10743 rtx label = gen_label_rtx ();
10744 rtx tmp;
10745
10746 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10747
10748 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10749 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10750 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10751 gen_rtx_LABEL_REF (VOIDmode, label),
10752 pc_rtx);
10753 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10754 JUMP_LABEL (tmp) = label;
10755
10756 emit_move_insn (operands[0], operands[1]);
10757 emit_move_insn (operands[1], const0_rtx);
10758
10759 emit_label (label);
10760 LABEL_NUSES (label) = 1;
10761
10762 DONE;
10763 })
10764
10765 (define_expand "ashlsi3"
10766 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10767 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10768 (match_operand:QI 2 "nonmemory_operand" "")))
10769 (clobber (reg:CC 17))]
10770 ""
10771 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10772
10773 (define_insn "*ashlsi3_1"
10774 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10775 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10776 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10777 (clobber (reg:CC 17))]
10778 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10779 {
10780 switch (get_attr_type (insn))
10781 {
10782 case TYPE_ALU:
10783 if (operands[2] != const1_rtx)
10784 abort ();
10785 if (!rtx_equal_p (operands[0], operands[1]))
10786 abort ();
10787 return "add{l}\t{%0, %0|%0, %0}";
10788
10789 case TYPE_LEA:
10790 return "#";
10791
10792 default:
10793 if (REG_P (operands[2]))
10794 return "sal{l}\t{%b2, %0|%0, %b2}";
10795 else if (operands[2] == const1_rtx
10796 && (TARGET_SHIFT1 || optimize_size))
10797 return "sal{l}\t%0";
10798 else
10799 return "sal{l}\t{%2, %0|%0, %2}";
10800 }
10801 }
10802 [(set (attr "type")
10803 (cond [(eq_attr "alternative" "1")
10804 (const_string "lea")
10805 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10806 (const_int 0))
10807 (match_operand 0 "register_operand" ""))
10808 (match_operand 2 "const1_operand" ""))
10809 (const_string "alu")
10810 ]
10811 (const_string "ishift")))
10812 (set_attr "mode" "SI")])
10813
10814 ;; Convert lea to the lea pattern to avoid flags dependency.
10815 (define_split
10816 [(set (match_operand 0 "register_operand" "")
10817 (ashift (match_operand 1 "index_register_operand" "")
10818 (match_operand:QI 2 "const_int_operand" "")))
10819 (clobber (reg:CC 17))]
10820 "reload_completed
10821 && true_regnum (operands[0]) != true_regnum (operands[1])"
10822 [(const_int 0)]
10823 {
10824 rtx pat;
10825 operands[0] = gen_lowpart (SImode, operands[0]);
10826 operands[1] = gen_lowpart (Pmode, operands[1]);
10827 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10828 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10829 if (Pmode != SImode)
10830 pat = gen_rtx_SUBREG (SImode, pat, 0);
10831 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10832 DONE;
10833 })
10834
10835 ;; Rare case of shifting RSP is handled by generating move and shift
10836 (define_split
10837 [(set (match_operand 0 "register_operand" "")
10838 (ashift (match_operand 1 "register_operand" "")
10839 (match_operand:QI 2 "const_int_operand" "")))
10840 (clobber (reg:CC 17))]
10841 "reload_completed
10842 && true_regnum (operands[0]) != true_regnum (operands[1])"
10843 [(const_int 0)]
10844 {
10845 rtx pat, clob;
10846 emit_move_insn (operands[1], operands[0]);
10847 pat = gen_rtx_SET (VOIDmode, operands[0],
10848 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10849 operands[0], operands[2]));
10850 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10851 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10852 DONE;
10853 })
10854
10855 (define_insn "*ashlsi3_1_zext"
10856 [(set (match_operand:DI 0 "register_operand" "=r,r")
10857 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10858 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10859 (clobber (reg:CC 17))]
10860 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10861 {
10862 switch (get_attr_type (insn))
10863 {
10864 case TYPE_ALU:
10865 if (operands[2] != const1_rtx)
10866 abort ();
10867 return "add{l}\t{%k0, %k0|%k0, %k0}";
10868
10869 case TYPE_LEA:
10870 return "#";
10871
10872 default:
10873 if (REG_P (operands[2]))
10874 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10875 else if (operands[2] == const1_rtx
10876 && (TARGET_SHIFT1 || optimize_size))
10877 return "sal{l}\t%k0";
10878 else
10879 return "sal{l}\t{%2, %k0|%k0, %2}";
10880 }
10881 }
10882 [(set (attr "type")
10883 (cond [(eq_attr "alternative" "1")
10884 (const_string "lea")
10885 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10886 (const_int 0))
10887 (match_operand 2 "const1_operand" ""))
10888 (const_string "alu")
10889 ]
10890 (const_string "ishift")))
10891 (set_attr "mode" "SI")])
10892
10893 ;; Convert lea to the lea pattern to avoid flags dependency.
10894 (define_split
10895 [(set (match_operand:DI 0 "register_operand" "")
10896 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10897 (match_operand:QI 2 "const_int_operand" ""))))
10898 (clobber (reg:CC 17))]
10899 "TARGET_64BIT && reload_completed
10900 && true_regnum (operands[0]) != true_regnum (operands[1])"
10901 [(set (match_dup 0) (zero_extend:DI
10902 (subreg:SI (mult:SI (match_dup 1)
10903 (match_dup 2)) 0)))]
10904 {
10905 operands[1] = gen_lowpart (Pmode, operands[1]);
10906 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10907 })
10908
10909 ;; This pattern can't accept a variable shift count, since shifts by
10910 ;; zero don't affect the flags. We assume that shifts by constant
10911 ;; zero are optimized away.
10912 (define_insn "*ashlsi3_cmp"
10913 [(set (reg 17)
10914 (compare
10915 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10916 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10917 (const_int 0)))
10918 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10919 (ashift:SI (match_dup 1) (match_dup 2)))]
10920 "ix86_match_ccmode (insn, CCGOCmode)
10921 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10922 {
10923 switch (get_attr_type (insn))
10924 {
10925 case TYPE_ALU:
10926 if (operands[2] != const1_rtx)
10927 abort ();
10928 return "add{l}\t{%0, %0|%0, %0}";
10929
10930 default:
10931 if (REG_P (operands[2]))
10932 return "sal{l}\t{%b2, %0|%0, %b2}";
10933 else if (operands[2] == const1_rtx
10934 && (TARGET_SHIFT1 || optimize_size))
10935 return "sal{l}\t%0";
10936 else
10937 return "sal{l}\t{%2, %0|%0, %2}";
10938 }
10939 }
10940 [(set (attr "type")
10941 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10942 (const_int 0))
10943 (match_operand 0 "register_operand" ""))
10944 (match_operand 2 "const1_operand" ""))
10945 (const_string "alu")
10946 ]
10947 (const_string "ishift")))
10948 (set_attr "mode" "SI")])
10949
10950 (define_insn "*ashlsi3_cmp_zext"
10951 [(set (reg 17)
10952 (compare
10953 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10954 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10955 (const_int 0)))
10956 (set (match_operand:DI 0 "register_operand" "=r")
10957 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10958 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10959 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10960 {
10961 switch (get_attr_type (insn))
10962 {
10963 case TYPE_ALU:
10964 if (operands[2] != const1_rtx)
10965 abort ();
10966 return "add{l}\t{%k0, %k0|%k0, %k0}";
10967
10968 default:
10969 if (REG_P (operands[2]))
10970 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10971 else if (operands[2] == const1_rtx
10972 && (TARGET_SHIFT1 || optimize_size))
10973 return "sal{l}\t%k0";
10974 else
10975 return "sal{l}\t{%2, %k0|%k0, %2}";
10976 }
10977 }
10978 [(set (attr "type")
10979 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980 (const_int 0))
10981 (match_operand 2 "const1_operand" ""))
10982 (const_string "alu")
10983 ]
10984 (const_string "ishift")))
10985 (set_attr "mode" "SI")])
10986
10987 (define_expand "ashlhi3"
10988 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10989 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10990 (match_operand:QI 2 "nonmemory_operand" "")))
10991 (clobber (reg:CC 17))]
10992 "TARGET_HIMODE_MATH"
10993 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10994
10995 (define_insn "*ashlhi3_1_lea"
10996 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10997 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10998 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10999 (clobber (reg:CC 17))]
11000 "!TARGET_PARTIAL_REG_STALL
11001 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11002 {
11003 switch (get_attr_type (insn))
11004 {
11005 case TYPE_LEA:
11006 return "#";
11007 case TYPE_ALU:
11008 if (operands[2] != const1_rtx)
11009 abort ();
11010 return "add{w}\t{%0, %0|%0, %0}";
11011
11012 default:
11013 if (REG_P (operands[2]))
11014 return "sal{w}\t{%b2, %0|%0, %b2}";
11015 else if (operands[2] == const1_rtx
11016 && (TARGET_SHIFT1 || optimize_size))
11017 return "sal{w}\t%0";
11018 else
11019 return "sal{w}\t{%2, %0|%0, %2}";
11020 }
11021 }
11022 [(set (attr "type")
11023 (cond [(eq_attr "alternative" "1")
11024 (const_string "lea")
11025 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11026 (const_int 0))
11027 (match_operand 0 "register_operand" ""))
11028 (match_operand 2 "const1_operand" ""))
11029 (const_string "alu")
11030 ]
11031 (const_string "ishift")))
11032 (set_attr "mode" "HI,SI")])
11033
11034 (define_insn "*ashlhi3_1"
11035 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11036 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11037 (match_operand:QI 2 "nonmemory_operand" "cI")))
11038 (clobber (reg:CC 17))]
11039 "TARGET_PARTIAL_REG_STALL
11040 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11041 {
11042 switch (get_attr_type (insn))
11043 {
11044 case TYPE_ALU:
11045 if (operands[2] != const1_rtx)
11046 abort ();
11047 return "add{w}\t{%0, %0|%0, %0}";
11048
11049 default:
11050 if (REG_P (operands[2]))
11051 return "sal{w}\t{%b2, %0|%0, %b2}";
11052 else if (operands[2] == const1_rtx
11053 && (TARGET_SHIFT1 || optimize_size))
11054 return "sal{w}\t%0";
11055 else
11056 return "sal{w}\t{%2, %0|%0, %2}";
11057 }
11058 }
11059 [(set (attr "type")
11060 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11061 (const_int 0))
11062 (match_operand 0 "register_operand" ""))
11063 (match_operand 2 "const1_operand" ""))
11064 (const_string "alu")
11065 ]
11066 (const_string "ishift")))
11067 (set_attr "mode" "HI")])
11068
11069 ;; This pattern can't accept a variable shift count, since shifts by
11070 ;; zero don't affect the flags. We assume that shifts by constant
11071 ;; zero are optimized away.
11072 (define_insn "*ashlhi3_cmp"
11073 [(set (reg 17)
11074 (compare
11075 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11076 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11077 (const_int 0)))
11078 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11079 (ashift:HI (match_dup 1) (match_dup 2)))]
11080 "ix86_match_ccmode (insn, CCGOCmode)
11081 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11082 {
11083 switch (get_attr_type (insn))
11084 {
11085 case TYPE_ALU:
11086 if (operands[2] != const1_rtx)
11087 abort ();
11088 return "add{w}\t{%0, %0|%0, %0}";
11089
11090 default:
11091 if (REG_P (operands[2]))
11092 return "sal{w}\t{%b2, %0|%0, %b2}";
11093 else if (operands[2] == const1_rtx
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 [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11102 (const_int 0))
11103 (match_operand 0 "register_operand" ""))
11104 (match_operand 2 "const1_operand" ""))
11105 (const_string "alu")
11106 ]
11107 (const_string "ishift")))
11108 (set_attr "mode" "HI")])
11109
11110 (define_expand "ashlqi3"
11111 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11112 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11113 (match_operand:QI 2 "nonmemory_operand" "")))
11114 (clobber (reg:CC 17))]
11115 "TARGET_QIMODE_MATH"
11116 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11117
11118 ;; %%% Potential partial reg stall on alternative 2. What to do?
11119
11120 (define_insn "*ashlqi3_1_lea"
11121 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11122 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11123 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11124 (clobber (reg:CC 17))]
11125 "!TARGET_PARTIAL_REG_STALL
11126 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11127 {
11128 switch (get_attr_type (insn))
11129 {
11130 case TYPE_LEA:
11131 return "#";
11132 case TYPE_ALU:
11133 if (operands[2] != const1_rtx)
11134 abort ();
11135 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11136 return "add{l}\t{%k0, %k0|%k0, %k0}";
11137 else
11138 return "add{b}\t{%0, %0|%0, %0}";
11139
11140 default:
11141 if (REG_P (operands[2]))
11142 {
11143 if (get_attr_mode (insn) == MODE_SI)
11144 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11145 else
11146 return "sal{b}\t{%b2, %0|%0, %b2}";
11147 }
11148 else if (operands[2] == const1_rtx
11149 && (TARGET_SHIFT1 || optimize_size))
11150 {
11151 if (get_attr_mode (insn) == MODE_SI)
11152 return "sal{l}\t%0";
11153 else
11154 return "sal{b}\t%0";
11155 }
11156 else
11157 {
11158 if (get_attr_mode (insn) == MODE_SI)
11159 return "sal{l}\t{%2, %k0|%k0, %2}";
11160 else
11161 return "sal{b}\t{%2, %0|%0, %2}";
11162 }
11163 }
11164 }
11165 [(set (attr "type")
11166 (cond [(eq_attr "alternative" "2")
11167 (const_string "lea")
11168 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11169 (const_int 0))
11170 (match_operand 0 "register_operand" ""))
11171 (match_operand 2 "const1_operand" ""))
11172 (const_string "alu")
11173 ]
11174 (const_string "ishift")))
11175 (set_attr "mode" "QI,SI,SI")])
11176
11177 (define_insn "*ashlqi3_1"
11178 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11179 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11180 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11181 (clobber (reg:CC 17))]
11182 "TARGET_PARTIAL_REG_STALL
11183 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11184 {
11185 switch (get_attr_type (insn))
11186 {
11187 case TYPE_ALU:
11188 if (operands[2] != const1_rtx)
11189 abort ();
11190 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11191 return "add{l}\t{%k0, %k0|%k0, %k0}";
11192 else
11193 return "add{b}\t{%0, %0|%0, %0}";
11194
11195 default:
11196 if (REG_P (operands[2]))
11197 {
11198 if (get_attr_mode (insn) == MODE_SI)
11199 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11200 else
11201 return "sal{b}\t{%b2, %0|%0, %b2}";
11202 }
11203 else if (operands[2] == const1_rtx
11204 && (TARGET_SHIFT1 || optimize_size))
11205 {
11206 if (get_attr_mode (insn) == MODE_SI)
11207 return "sal{l}\t%0";
11208 else
11209 return "sal{b}\t%0";
11210 }
11211 else
11212 {
11213 if (get_attr_mode (insn) == MODE_SI)
11214 return "sal{l}\t{%2, %k0|%k0, %2}";
11215 else
11216 return "sal{b}\t{%2, %0|%0, %2}";
11217 }
11218 }
11219 }
11220 [(set (attr "type")
11221 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11222 (const_int 0))
11223 (match_operand 0 "register_operand" ""))
11224 (match_operand 2 "const1_operand" ""))
11225 (const_string "alu")
11226 ]
11227 (const_string "ishift")))
11228 (set_attr "mode" "QI,SI")])
11229
11230 ;; This pattern can't accept a variable shift count, since shifts by
11231 ;; zero don't affect the flags. We assume that shifts by constant
11232 ;; zero are optimized away.
11233 (define_insn "*ashlqi3_cmp"
11234 [(set (reg 17)
11235 (compare
11236 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11237 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11238 (const_int 0)))
11239 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11240 (ashift:QI (match_dup 1) (match_dup 2)))]
11241 "ix86_match_ccmode (insn, CCGOCmode)
11242 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11243 {
11244 switch (get_attr_type (insn))
11245 {
11246 case TYPE_ALU:
11247 if (operands[2] != const1_rtx)
11248 abort ();
11249 return "add{b}\t{%0, %0|%0, %0}";
11250
11251 default:
11252 if (REG_P (operands[2]))
11253 return "sal{b}\t{%b2, %0|%0, %b2}";
11254 else if (operands[2] == const1_rtx
11255 && (TARGET_SHIFT1 || optimize_size))
11256 return "sal{b}\t%0";
11257 else
11258 return "sal{b}\t{%2, %0|%0, %2}";
11259 }
11260 }
11261 [(set (attr "type")
11262 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11263 (const_int 0))
11264 (match_operand 0 "register_operand" ""))
11265 (match_operand 2 "const1_operand" ""))
11266 (const_string "alu")
11267 ]
11268 (const_string "ishift")))
11269 (set_attr "mode" "QI")])
11270
11271 ;; See comment above `ashldi3' about how this works.
11272
11273 (define_expand "ashrdi3"
11274 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11275 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11276 (match_operand:QI 2 "nonmemory_operand" "")))
11277 (clobber (reg:CC 17))])]
11278 ""
11279 {
11280 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11281 {
11282 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11283 DONE;
11284 }
11285 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11286 DONE;
11287 })
11288
11289 (define_insn "ashrdi3_63_rex64"
11290 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11291 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11292 (match_operand:DI 2 "const_int_operand" "i,i")))
11293 (clobber (reg:CC 17))]
11294 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11295 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11296 "@
11297 {cqto|cqo}
11298 sar{q}\t{%2, %0|%0, %2}"
11299 [(set_attr "type" "imovx,ishift")
11300 (set_attr "prefix_0f" "0,*")
11301 (set_attr "length_immediate" "0,*")
11302 (set_attr "modrm" "0,1")
11303 (set_attr "mode" "DI")])
11304
11305 (define_insn "*ashrdi3_1_one_bit_rex64"
11306 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11307 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11308 (match_operand:QI 2 "const1_operand" "")))
11309 (clobber (reg:CC 17))]
11310 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11311 && (TARGET_SHIFT1 || optimize_size)"
11312 "sar{q}\t%0"
11313 [(set_attr "type" "ishift")
11314 (set (attr "length")
11315 (if_then_else (match_operand:DI 0 "register_operand" "")
11316 (const_string "2")
11317 (const_string "*")))])
11318
11319 (define_insn "*ashrdi3_1_rex64"
11320 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11321 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11322 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11323 (clobber (reg:CC 17))]
11324 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11325 "@
11326 sar{q}\t{%2, %0|%0, %2}
11327 sar{q}\t{%b2, %0|%0, %b2}"
11328 [(set_attr "type" "ishift")
11329 (set_attr "mode" "DI")])
11330
11331 ;; This pattern can't accept a variable shift count, since shifts by
11332 ;; zero don't affect the flags. We assume that shifts by constant
11333 ;; zero are optimized away.
11334 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11335 [(set (reg 17)
11336 (compare
11337 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11338 (match_operand:QI 2 "const1_operand" ""))
11339 (const_int 0)))
11340 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11341 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11342 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11343 && (TARGET_SHIFT1 || optimize_size)
11344 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11345 "sar{q}\t%0"
11346 [(set_attr "type" "ishift")
11347 (set (attr "length")
11348 (if_then_else (match_operand:DI 0 "register_operand" "")
11349 (const_string "2")
11350 (const_string "*")))])
11351
11352 ;; This pattern can't accept a variable shift count, since shifts by
11353 ;; zero don't affect the flags. We assume that shifts by constant
11354 ;; zero are optimized away.
11355 (define_insn "*ashrdi3_cmp_rex64"
11356 [(set (reg 17)
11357 (compare
11358 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11359 (match_operand:QI 2 "const_int_operand" "n"))
11360 (const_int 0)))
11361 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11362 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11363 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11364 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11365 "sar{q}\t{%2, %0|%0, %2}"
11366 [(set_attr "type" "ishift")
11367 (set_attr "mode" "DI")])
11368
11369
11370 (define_insn "ashrdi3_1"
11371 [(set (match_operand:DI 0 "register_operand" "=r")
11372 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11373 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11374 (clobber (match_scratch:SI 3 "=&r"))
11375 (clobber (reg:CC 17))]
11376 "!TARGET_64BIT && TARGET_CMOVE"
11377 "#"
11378 [(set_attr "type" "multi")])
11379
11380 (define_insn "*ashrdi3_2"
11381 [(set (match_operand:DI 0 "register_operand" "=r")
11382 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11383 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11384 (clobber (reg:CC 17))]
11385 "!TARGET_64BIT"
11386 "#"
11387 [(set_attr "type" "multi")])
11388
11389 (define_split
11390 [(set (match_operand:DI 0 "register_operand" "")
11391 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11392 (match_operand:QI 2 "nonmemory_operand" "")))
11393 (clobber (match_scratch:SI 3 ""))
11394 (clobber (reg:CC 17))]
11395 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11396 [(const_int 0)]
11397 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11398
11399 (define_split
11400 [(set (match_operand:DI 0 "register_operand" "")
11401 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11402 (match_operand:QI 2 "nonmemory_operand" "")))
11403 (clobber (reg:CC 17))]
11404 "!TARGET_64BIT && reload_completed"
11405 [(const_int 0)]
11406 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11407
11408 (define_insn "x86_shrd_1"
11409 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11410 (ior:SI (ashiftrt:SI (match_dup 0)
11411 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11412 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11413 (minus:QI (const_int 32) (match_dup 2)))))
11414 (clobber (reg:CC 17))]
11415 ""
11416 "@
11417 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11418 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11419 [(set_attr "type" "ishift")
11420 (set_attr "prefix_0f" "1")
11421 (set_attr "pent_pair" "np")
11422 (set_attr "mode" "SI")])
11423
11424 (define_expand "x86_shift_adj_3"
11425 [(use (match_operand:SI 0 "register_operand" ""))
11426 (use (match_operand:SI 1 "register_operand" ""))
11427 (use (match_operand:QI 2 "register_operand" ""))]
11428 ""
11429 {
11430 rtx label = gen_label_rtx ();
11431 rtx tmp;
11432
11433 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11434
11435 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11436 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11437 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11438 gen_rtx_LABEL_REF (VOIDmode, label),
11439 pc_rtx);
11440 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11441 JUMP_LABEL (tmp) = label;
11442
11443 emit_move_insn (operands[0], operands[1]);
11444 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11445
11446 emit_label (label);
11447 LABEL_NUSES (label) = 1;
11448
11449 DONE;
11450 })
11451
11452 (define_insn "ashrsi3_31"
11453 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11454 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11455 (match_operand:SI 2 "const_int_operand" "i,i")))
11456 (clobber (reg:CC 17))]
11457 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11458 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11459 "@
11460 {cltd|cdq}
11461 sar{l}\t{%2, %0|%0, %2}"
11462 [(set_attr "type" "imovx,ishift")
11463 (set_attr "prefix_0f" "0,*")
11464 (set_attr "length_immediate" "0,*")
11465 (set_attr "modrm" "0,1")
11466 (set_attr "mode" "SI")])
11467
11468 (define_insn "*ashrsi3_31_zext"
11469 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11470 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11471 (match_operand:SI 2 "const_int_operand" "i,i"))))
11472 (clobber (reg:CC 17))]
11473 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11474 && INTVAL (operands[2]) == 31
11475 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11476 "@
11477 {cltd|cdq}
11478 sar{l}\t{%2, %k0|%k0, %2}"
11479 [(set_attr "type" "imovx,ishift")
11480 (set_attr "prefix_0f" "0,*")
11481 (set_attr "length_immediate" "0,*")
11482 (set_attr "modrm" "0,1")
11483 (set_attr "mode" "SI")])
11484
11485 (define_expand "ashrsi3"
11486 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11487 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11488 (match_operand:QI 2 "nonmemory_operand" "")))
11489 (clobber (reg:CC 17))]
11490 ""
11491 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11492
11493 (define_insn "*ashrsi3_1_one_bit"
11494 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11495 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11496 (match_operand:QI 2 "const1_operand" "")))
11497 (clobber (reg:CC 17))]
11498 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11499 && (TARGET_SHIFT1 || optimize_size)"
11500 "sar{l}\t%0"
11501 [(set_attr "type" "ishift")
11502 (set (attr "length")
11503 (if_then_else (match_operand:SI 0 "register_operand" "")
11504 (const_string "2")
11505 (const_string "*")))])
11506
11507 (define_insn "*ashrsi3_1_one_bit_zext"
11508 [(set (match_operand:DI 0 "register_operand" "=r")
11509 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11510 (match_operand:QI 2 "const1_operand" ""))))
11511 (clobber (reg:CC 17))]
11512 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11513 && (TARGET_SHIFT1 || optimize_size)"
11514 "sar{l}\t%k0"
11515 [(set_attr "type" "ishift")
11516 (set_attr "length" "2")])
11517
11518 (define_insn "*ashrsi3_1"
11519 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11520 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11521 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11522 (clobber (reg:CC 17))]
11523 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11524 "@
11525 sar{l}\t{%2, %0|%0, %2}
11526 sar{l}\t{%b2, %0|%0, %b2}"
11527 [(set_attr "type" "ishift")
11528 (set_attr "mode" "SI")])
11529
11530 (define_insn "*ashrsi3_1_zext"
11531 [(set (match_operand:DI 0 "register_operand" "=r,r")
11532 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11533 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11534 (clobber (reg:CC 17))]
11535 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11536 "@
11537 sar{l}\t{%2, %k0|%k0, %2}
11538 sar{l}\t{%b2, %k0|%k0, %b2}"
11539 [(set_attr "type" "ishift")
11540 (set_attr "mode" "SI")])
11541
11542 ;; This pattern can't accept a variable shift count, since shifts by
11543 ;; zero don't affect the flags. We assume that shifts by constant
11544 ;; zero are optimized away.
11545 (define_insn "*ashrsi3_one_bit_cmp"
11546 [(set (reg 17)
11547 (compare
11548 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11549 (match_operand:QI 2 "const1_operand" ""))
11550 (const_int 0)))
11551 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11552 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11553 "ix86_match_ccmode (insn, CCGOCmode)
11554 && (TARGET_SHIFT1 || optimize_size)
11555 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11556 "sar{l}\t%0"
11557 [(set_attr "type" "ishift")
11558 (set (attr "length")
11559 (if_then_else (match_operand:SI 0 "register_operand" "")
11560 (const_string "2")
11561 (const_string "*")))])
11562
11563 (define_insn "*ashrsi3_one_bit_cmp_zext"
11564 [(set (reg 17)
11565 (compare
11566 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11567 (match_operand:QI 2 "const1_operand" ""))
11568 (const_int 0)))
11569 (set (match_operand:DI 0 "register_operand" "=r")
11570 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11571 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11572 && (TARGET_SHIFT1 || optimize_size)
11573 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11574 "sar{l}\t%k0"
11575 [(set_attr "type" "ishift")
11576 (set_attr "length" "2")])
11577
11578 ;; This pattern can't accept a variable shift count, since shifts by
11579 ;; zero don't affect the flags. We assume that shifts by constant
11580 ;; zero are optimized away.
11581 (define_insn "*ashrsi3_cmp"
11582 [(set (reg 17)
11583 (compare
11584 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11585 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11586 (const_int 0)))
11587 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11588 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11589 "ix86_match_ccmode (insn, CCGOCmode)
11590 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11591 "sar{l}\t{%2, %0|%0, %2}"
11592 [(set_attr "type" "ishift")
11593 (set_attr "mode" "SI")])
11594
11595 (define_insn "*ashrsi3_cmp_zext"
11596 [(set (reg 17)
11597 (compare
11598 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11599 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11600 (const_int 0)))
11601 (set (match_operand:DI 0 "register_operand" "=r")
11602 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11603 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11604 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11605 "sar{l}\t{%2, %k0|%k0, %2}"
11606 [(set_attr "type" "ishift")
11607 (set_attr "mode" "SI")])
11608
11609 (define_expand "ashrhi3"
11610 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11611 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11612 (match_operand:QI 2 "nonmemory_operand" "")))
11613 (clobber (reg:CC 17))]
11614 "TARGET_HIMODE_MATH"
11615 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11616
11617 (define_insn "*ashrhi3_1_one_bit"
11618 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11619 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11620 (match_operand:QI 2 "const1_operand" "")))
11621 (clobber (reg:CC 17))]
11622 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11623 && (TARGET_SHIFT1 || optimize_size)"
11624 "sar{w}\t%0"
11625 [(set_attr "type" "ishift")
11626 (set (attr "length")
11627 (if_then_else (match_operand 0 "register_operand" "")
11628 (const_string "2")
11629 (const_string "*")))])
11630
11631 (define_insn "*ashrhi3_1"
11632 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11633 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11634 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11635 (clobber (reg:CC 17))]
11636 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11637 "@
11638 sar{w}\t{%2, %0|%0, %2}
11639 sar{w}\t{%b2, %0|%0, %b2}"
11640 [(set_attr "type" "ishift")
11641 (set_attr "mode" "HI")])
11642
11643 ;; This pattern can't accept a variable shift count, since shifts by
11644 ;; zero don't affect the flags. We assume that shifts by constant
11645 ;; zero are optimized away.
11646 (define_insn "*ashrhi3_one_bit_cmp"
11647 [(set (reg 17)
11648 (compare
11649 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11650 (match_operand:QI 2 "const1_operand" ""))
11651 (const_int 0)))
11652 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11653 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11654 "ix86_match_ccmode (insn, CCGOCmode)
11655 && (TARGET_SHIFT1 || optimize_size)
11656 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11657 "sar{w}\t%0"
11658 [(set_attr "type" "ishift")
11659 (set (attr "length")
11660 (if_then_else (match_operand 0 "register_operand" "")
11661 (const_string "2")
11662 (const_string "*")))])
11663
11664 ;; This pattern can't accept a variable shift count, since shifts by
11665 ;; zero don't affect the flags. We assume that shifts by constant
11666 ;; zero are optimized away.
11667 (define_insn "*ashrhi3_cmp"
11668 [(set (reg 17)
11669 (compare
11670 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11671 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11672 (const_int 0)))
11673 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11674 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11675 "ix86_match_ccmode (insn, CCGOCmode)
11676 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11677 "sar{w}\t{%2, %0|%0, %2}"
11678 [(set_attr "type" "ishift")
11679 (set_attr "mode" "HI")])
11680
11681 (define_expand "ashrqi3"
11682 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11683 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11684 (match_operand:QI 2 "nonmemory_operand" "")))
11685 (clobber (reg:CC 17))]
11686 "TARGET_QIMODE_MATH"
11687 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11688
11689 (define_insn "*ashrqi3_1_one_bit"
11690 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11691 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11692 (match_operand:QI 2 "const1_operand" "")))
11693 (clobber (reg:CC 17))]
11694 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11695 && (TARGET_SHIFT1 || optimize_size)"
11696 "sar{b}\t%0"
11697 [(set_attr "type" "ishift")
11698 (set (attr "length")
11699 (if_then_else (match_operand 0 "register_operand" "")
11700 (const_string "2")
11701 (const_string "*")))])
11702
11703 (define_insn "*ashrqi3_1_one_bit_slp"
11704 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11705 (ashiftrt:QI (match_dup 0)
11706 (match_operand:QI 1 "const1_operand" "")))
11707 (clobber (reg:CC 17))]
11708 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11709 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11710 && (TARGET_SHIFT1 || optimize_size)"
11711 "sar{b}\t%0"
11712 [(set_attr "type" "ishift1")
11713 (set (attr "length")
11714 (if_then_else (match_operand 0 "register_operand" "")
11715 (const_string "2")
11716 (const_string "*")))])
11717
11718 (define_insn "*ashrqi3_1"
11719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11720 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11721 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11722 (clobber (reg:CC 17))]
11723 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11724 "@
11725 sar{b}\t{%2, %0|%0, %2}
11726 sar{b}\t{%b2, %0|%0, %b2}"
11727 [(set_attr "type" "ishift")
11728 (set_attr "mode" "QI")])
11729
11730 (define_insn "*ashrqi3_1_slp"
11731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11732 (ashiftrt:QI (match_dup 0)
11733 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11734 (clobber (reg:CC 17))]
11735 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11737 "@
11738 sar{b}\t{%1, %0|%0, %1}
11739 sar{b}\t{%b1, %0|%0, %b1}"
11740 [(set_attr "type" "ishift1")
11741 (set_attr "mode" "QI")])
11742
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags. We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*ashrqi3_one_bit_cmp"
11747 [(set (reg 17)
11748 (compare
11749 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11750 (match_operand:QI 2 "const1_operand" "I"))
11751 (const_int 0)))
11752 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11753 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11754 "ix86_match_ccmode (insn, CCGOCmode)
11755 && (TARGET_SHIFT1 || optimize_size)
11756 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11757 "sar{b}\t%0"
11758 [(set_attr "type" "ishift")
11759 (set (attr "length")
11760 (if_then_else (match_operand 0 "register_operand" "")
11761 (const_string "2")
11762 (const_string "*")))])
11763
11764 ;; This pattern can't accept a variable shift count, since shifts by
11765 ;; zero don't affect the flags. We assume that shifts by constant
11766 ;; zero are optimized away.
11767 (define_insn "*ashrqi3_cmp"
11768 [(set (reg 17)
11769 (compare
11770 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11771 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11772 (const_int 0)))
11773 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11774 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11775 "ix86_match_ccmode (insn, CCGOCmode)
11776 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11777 "sar{b}\t{%2, %0|%0, %2}"
11778 [(set_attr "type" "ishift")
11779 (set_attr "mode" "QI")])
11780 \f
11781 ;; Logical shift instructions
11782
11783 ;; See comment above `ashldi3' about how this works.
11784
11785 (define_expand "lshrdi3"
11786 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11787 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11788 (match_operand:QI 2 "nonmemory_operand" "")))
11789 (clobber (reg:CC 17))])]
11790 ""
11791 {
11792 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11793 {
11794 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11795 DONE;
11796 }
11797 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11798 DONE;
11799 })
11800
11801 (define_insn "*lshrdi3_1_one_bit_rex64"
11802 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11803 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11804 (match_operand:QI 2 "const1_operand" "")))
11805 (clobber (reg:CC 17))]
11806 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11807 && (TARGET_SHIFT1 || optimize_size)"
11808 "shr{q}\t%0"
11809 [(set_attr "type" "ishift")
11810 (set (attr "length")
11811 (if_then_else (match_operand:DI 0 "register_operand" "")
11812 (const_string "2")
11813 (const_string "*")))])
11814
11815 (define_insn "*lshrdi3_1_rex64"
11816 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11817 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11818 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11819 (clobber (reg:CC 17))]
11820 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11821 "@
11822 shr{q}\t{%2, %0|%0, %2}
11823 shr{q}\t{%b2, %0|%0, %b2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "DI")])
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 "*lshrdi3_cmp_one_bit_rex64"
11831 [(set (reg 17)
11832 (compare
11833 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11834 (match_operand:QI 2 "const1_operand" ""))
11835 (const_int 0)))
11836 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11837 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11838 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11839 && (TARGET_SHIFT1 || optimize_size)
11840 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11841 "shr{q}\t%0"
11842 [(set_attr "type" "ishift")
11843 (set (attr "length")
11844 (if_then_else (match_operand:DI 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 "*lshrdi3_cmp_rex64"
11852 [(set (reg 17)
11853 (compare
11854 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11855 (match_operand:QI 2 "const_int_operand" "e"))
11856 (const_int 0)))
11857 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11858 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11859 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11860 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11861 "shr{q}\t{%2, %0|%0, %2}"
11862 [(set_attr "type" "ishift")
11863 (set_attr "mode" "DI")])
11864
11865 (define_insn "lshrdi3_1"
11866 [(set (match_operand:DI 0 "register_operand" "=r")
11867 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11868 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11869 (clobber (match_scratch:SI 3 "=&r"))
11870 (clobber (reg:CC 17))]
11871 "!TARGET_64BIT && TARGET_CMOVE"
11872 "#"
11873 [(set_attr "type" "multi")])
11874
11875 (define_insn "*lshrdi3_2"
11876 [(set (match_operand:DI 0 "register_operand" "=r")
11877 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11878 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11879 (clobber (reg:CC 17))]
11880 "!TARGET_64BIT"
11881 "#"
11882 [(set_attr "type" "multi")])
11883
11884 (define_split
11885 [(set (match_operand:DI 0 "register_operand" "")
11886 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11887 (match_operand:QI 2 "nonmemory_operand" "")))
11888 (clobber (match_scratch:SI 3 ""))
11889 (clobber (reg:CC 17))]
11890 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11891 [(const_int 0)]
11892 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11893
11894 (define_split
11895 [(set (match_operand:DI 0 "register_operand" "")
11896 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11897 (match_operand:QI 2 "nonmemory_operand" "")))
11898 (clobber (reg:CC 17))]
11899 "!TARGET_64BIT && reload_completed"
11900 [(const_int 0)]
11901 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11902
11903 (define_expand "lshrsi3"
11904 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11905 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11906 (match_operand:QI 2 "nonmemory_operand" "")))
11907 (clobber (reg:CC 17))]
11908 ""
11909 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11910
11911 (define_insn "*lshrsi3_1_one_bit"
11912 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11913 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11914 (match_operand:QI 2 "const1_operand" "")))
11915 (clobber (reg:CC 17))]
11916 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11917 && (TARGET_SHIFT1 || optimize_size)"
11918 "shr{l}\t%0"
11919 [(set_attr "type" "ishift")
11920 (set (attr "length")
11921 (if_then_else (match_operand:SI 0 "register_operand" "")
11922 (const_string "2")
11923 (const_string "*")))])
11924
11925 (define_insn "*lshrsi3_1_one_bit_zext"
11926 [(set (match_operand:DI 0 "register_operand" "=r")
11927 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11928 (match_operand:QI 2 "const1_operand" "")))
11929 (clobber (reg:CC 17))]
11930 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11931 && (TARGET_SHIFT1 || optimize_size)"
11932 "shr{l}\t%k0"
11933 [(set_attr "type" "ishift")
11934 (set_attr "length" "2")])
11935
11936 (define_insn "*lshrsi3_1"
11937 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11938 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11939 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11940 (clobber (reg:CC 17))]
11941 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11942 "@
11943 shr{l}\t{%2, %0|%0, %2}
11944 shr{l}\t{%b2, %0|%0, %b2}"
11945 [(set_attr "type" "ishift")
11946 (set_attr "mode" "SI")])
11947
11948 (define_insn "*lshrsi3_1_zext"
11949 [(set (match_operand:DI 0 "register_operand" "=r,r")
11950 (zero_extend:DI
11951 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11952 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11953 (clobber (reg:CC 17))]
11954 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11955 "@
11956 shr{l}\t{%2, %k0|%k0, %2}
11957 shr{l}\t{%b2, %k0|%k0, %b2}"
11958 [(set_attr "type" "ishift")
11959 (set_attr "mode" "SI")])
11960
11961 ;; This pattern can't accept a variable shift count, since shifts by
11962 ;; zero don't affect the flags. We assume that shifts by constant
11963 ;; zero are optimized away.
11964 (define_insn "*lshrsi3_one_bit_cmp"
11965 [(set (reg 17)
11966 (compare
11967 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11968 (match_operand:QI 2 "const1_operand" ""))
11969 (const_int 0)))
11970 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11971 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11972 "ix86_match_ccmode (insn, CCGOCmode)
11973 && (TARGET_SHIFT1 || optimize_size)
11974 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11975 "shr{l}\t%0"
11976 [(set_attr "type" "ishift")
11977 (set (attr "length")
11978 (if_then_else (match_operand:SI 0 "register_operand" "")
11979 (const_string "2")
11980 (const_string "*")))])
11981
11982 (define_insn "*lshrsi3_cmp_one_bit_zext"
11983 [(set (reg 17)
11984 (compare
11985 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11986 (match_operand:QI 2 "const1_operand" ""))
11987 (const_int 0)))
11988 (set (match_operand:DI 0 "register_operand" "=r")
11989 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11990 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11991 && (TARGET_SHIFT1 || optimize_size)
11992 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11993 "shr{l}\t%k0"
11994 [(set_attr "type" "ishift")
11995 (set_attr "length" "2")])
11996
11997 ;; This pattern can't accept a variable shift count, since shifts by
11998 ;; zero don't affect the flags. We assume that shifts by constant
11999 ;; zero are optimized away.
12000 (define_insn "*lshrsi3_cmp"
12001 [(set (reg 17)
12002 (compare
12003 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12004 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12005 (const_int 0)))
12006 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12007 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12008 "ix86_match_ccmode (insn, CCGOCmode)
12009 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12010 "shr{l}\t{%2, %0|%0, %2}"
12011 [(set_attr "type" "ishift")
12012 (set_attr "mode" "SI")])
12013
12014 (define_insn "*lshrsi3_cmp_zext"
12015 [(set (reg 17)
12016 (compare
12017 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12018 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12019 (const_int 0)))
12020 (set (match_operand:DI 0 "register_operand" "=r")
12021 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12022 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12023 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12024 "shr{l}\t{%2, %k0|%k0, %2}"
12025 [(set_attr "type" "ishift")
12026 (set_attr "mode" "SI")])
12027
12028 (define_expand "lshrhi3"
12029 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12030 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12031 (match_operand:QI 2 "nonmemory_operand" "")))
12032 (clobber (reg:CC 17))]
12033 "TARGET_HIMODE_MATH"
12034 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12035
12036 (define_insn "*lshrhi3_1_one_bit"
12037 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12038 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12039 (match_operand:QI 2 "const1_operand" "")))
12040 (clobber (reg:CC 17))]
12041 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12042 && (TARGET_SHIFT1 || optimize_size)"
12043 "shr{w}\t%0"
12044 [(set_attr "type" "ishift")
12045 (set (attr "length")
12046 (if_then_else (match_operand 0 "register_operand" "")
12047 (const_string "2")
12048 (const_string "*")))])
12049
12050 (define_insn "*lshrhi3_1"
12051 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12052 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12053 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12054 (clobber (reg:CC 17))]
12055 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12056 "@
12057 shr{w}\t{%2, %0|%0, %2}
12058 shr{w}\t{%b2, %0|%0, %b2}"
12059 [(set_attr "type" "ishift")
12060 (set_attr "mode" "HI")])
12061
12062 ;; This pattern can't accept a variable shift count, since shifts by
12063 ;; zero don't affect the flags. We assume that shifts by constant
12064 ;; zero are optimized away.
12065 (define_insn "*lshrhi3_one_bit_cmp"
12066 [(set (reg 17)
12067 (compare
12068 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12069 (match_operand:QI 2 "const1_operand" ""))
12070 (const_int 0)))
12071 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12072 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12073 "ix86_match_ccmode (insn, CCGOCmode)
12074 && (TARGET_SHIFT1 || optimize_size)
12075 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12076 "shr{w}\t%0"
12077 [(set_attr "type" "ishift")
12078 (set (attr "length")
12079 (if_then_else (match_operand:SI 0 "register_operand" "")
12080 (const_string "2")
12081 (const_string "*")))])
12082
12083 ;; This pattern can't accept a variable shift count, since shifts by
12084 ;; zero don't affect the flags. We assume that shifts by constant
12085 ;; zero are optimized away.
12086 (define_insn "*lshrhi3_cmp"
12087 [(set (reg 17)
12088 (compare
12089 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12090 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12091 (const_int 0)))
12092 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12093 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12094 "ix86_match_ccmode (insn, CCGOCmode)
12095 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12096 "shr{w}\t{%2, %0|%0, %2}"
12097 [(set_attr "type" "ishift")
12098 (set_attr "mode" "HI")])
12099
12100 (define_expand "lshrqi3"
12101 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12102 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12103 (match_operand:QI 2 "nonmemory_operand" "")))
12104 (clobber (reg:CC 17))]
12105 "TARGET_QIMODE_MATH"
12106 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12107
12108 (define_insn "*lshrqi3_1_one_bit"
12109 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12110 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12111 (match_operand:QI 2 "const1_operand" "")))
12112 (clobber (reg:CC 17))]
12113 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12114 && (TARGET_SHIFT1 || optimize_size)"
12115 "shr{b}\t%0"
12116 [(set_attr "type" "ishift")
12117 (set (attr "length")
12118 (if_then_else (match_operand 0 "register_operand" "")
12119 (const_string "2")
12120 (const_string "*")))])
12121
12122 (define_insn "*lshrqi3_1_one_bit_slp"
12123 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12124 (lshiftrt:QI (match_dup 0)
12125 (match_operand:QI 1 "const1_operand" "")))
12126 (clobber (reg:CC 17))]
12127 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12128 && (TARGET_SHIFT1 || optimize_size)"
12129 "shr{b}\t%0"
12130 [(set_attr "type" "ishift1")
12131 (set (attr "length")
12132 (if_then_else (match_operand 0 "register_operand" "")
12133 (const_string "2")
12134 (const_string "*")))])
12135
12136 (define_insn "*lshrqi3_1"
12137 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12138 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12140 (clobber (reg:CC 17))]
12141 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12142 "@
12143 shr{b}\t{%2, %0|%0, %2}
12144 shr{b}\t{%b2, %0|%0, %b2}"
12145 [(set_attr "type" "ishift")
12146 (set_attr "mode" "QI")])
12147
12148 (define_insn "*lshrqi3_1_slp"
12149 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12150 (lshiftrt:QI (match_dup 0)
12151 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12152 (clobber (reg:CC 17))]
12153 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12154 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12155 "@
12156 shr{b}\t{%1, %0|%0, %1}
12157 shr{b}\t{%b1, %0|%0, %b1}"
12158 [(set_attr "type" "ishift1")
12159 (set_attr "mode" "QI")])
12160
12161 ;; This pattern can't accept a variable shift count, since shifts by
12162 ;; zero don't affect the flags. We assume that shifts by constant
12163 ;; zero are optimized away.
12164 (define_insn "*lshrqi2_one_bit_cmp"
12165 [(set (reg 17)
12166 (compare
12167 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12168 (match_operand:QI 2 "const1_operand" ""))
12169 (const_int 0)))
12170 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12171 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12172 "ix86_match_ccmode (insn, CCGOCmode)
12173 && (TARGET_SHIFT1 || optimize_size)
12174 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12175 "shr{b}\t%0"
12176 [(set_attr "type" "ishift")
12177 (set (attr "length")
12178 (if_then_else (match_operand:SI 0 "register_operand" "")
12179 (const_string "2")
12180 (const_string "*")))])
12181
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags. We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*lshrqi2_cmp"
12186 [(set (reg 17)
12187 (compare
12188 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12190 (const_int 0)))
12191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12192 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12193 "ix86_match_ccmode (insn, CCGOCmode)
12194 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12195 "shr{b}\t{%2, %0|%0, %2}"
12196 [(set_attr "type" "ishift")
12197 (set_attr "mode" "QI")])
12198 \f
12199 ;; Rotate instructions
12200
12201 (define_expand "rotldi3"
12202 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12203 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12204 (match_operand:QI 2 "nonmemory_operand" "")))
12205 (clobber (reg:CC 17))]
12206 "TARGET_64BIT"
12207 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12208
12209 (define_insn "*rotlsi3_1_one_bit_rex64"
12210 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12211 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12212 (match_operand:QI 2 "const1_operand" "")))
12213 (clobber (reg:CC 17))]
12214 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12215 && (TARGET_SHIFT1 || optimize_size)"
12216 "rol{q}\t%0"
12217 [(set_attr "type" "rotate")
12218 (set (attr "length")
12219 (if_then_else (match_operand:DI 0 "register_operand" "")
12220 (const_string "2")
12221 (const_string "*")))])
12222
12223 (define_insn "*rotldi3_1_rex64"
12224 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12225 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12226 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12227 (clobber (reg:CC 17))]
12228 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12229 "@
12230 rol{q}\t{%2, %0|%0, %2}
12231 rol{q}\t{%b2, %0|%0, %b2}"
12232 [(set_attr "type" "rotate")
12233 (set_attr "mode" "DI")])
12234
12235 (define_expand "rotlsi3"
12236 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12237 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12238 (match_operand:QI 2 "nonmemory_operand" "")))
12239 (clobber (reg:CC 17))]
12240 ""
12241 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12242
12243 (define_insn "*rotlsi3_1_one_bit"
12244 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12245 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12246 (match_operand:QI 2 "const1_operand" "")))
12247 (clobber (reg:CC 17))]
12248 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12249 && (TARGET_SHIFT1 || optimize_size)"
12250 "rol{l}\t%0"
12251 [(set_attr "type" "rotate")
12252 (set (attr "length")
12253 (if_then_else (match_operand:SI 0 "register_operand" "")
12254 (const_string "2")
12255 (const_string "*")))])
12256
12257 (define_insn "*rotlsi3_1_one_bit_zext"
12258 [(set (match_operand:DI 0 "register_operand" "=r")
12259 (zero_extend:DI
12260 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12261 (match_operand:QI 2 "const1_operand" ""))))
12262 (clobber (reg:CC 17))]
12263 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12264 && (TARGET_SHIFT1 || optimize_size)"
12265 "rol{l}\t%k0"
12266 [(set_attr "type" "rotate")
12267 (set_attr "length" "2")])
12268
12269 (define_insn "*rotlsi3_1"
12270 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12271 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12272 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12273 (clobber (reg:CC 17))]
12274 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12275 "@
12276 rol{l}\t{%2, %0|%0, %2}
12277 rol{l}\t{%b2, %0|%0, %b2}"
12278 [(set_attr "type" "rotate")
12279 (set_attr "mode" "SI")])
12280
12281 (define_insn "*rotlsi3_1_zext"
12282 [(set (match_operand:DI 0 "register_operand" "=r,r")
12283 (zero_extend:DI
12284 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12285 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12286 (clobber (reg:CC 17))]
12287 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12288 "@
12289 rol{l}\t{%2, %k0|%k0, %2}
12290 rol{l}\t{%b2, %k0|%k0, %b2}"
12291 [(set_attr "type" "rotate")
12292 (set_attr "mode" "SI")])
12293
12294 (define_expand "rotlhi3"
12295 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12296 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12297 (match_operand:QI 2 "nonmemory_operand" "")))
12298 (clobber (reg:CC 17))]
12299 "TARGET_HIMODE_MATH"
12300 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12301
12302 (define_insn "*rotlhi3_1_one_bit"
12303 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12304 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12305 (match_operand:QI 2 "const1_operand" "")))
12306 (clobber (reg:CC 17))]
12307 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12308 && (TARGET_SHIFT1 || optimize_size)"
12309 "rol{w}\t%0"
12310 [(set_attr "type" "rotate")
12311 (set (attr "length")
12312 (if_then_else (match_operand 0 "register_operand" "")
12313 (const_string "2")
12314 (const_string "*")))])
12315
12316 (define_insn "*rotlhi3_1"
12317 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12318 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12319 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12320 (clobber (reg:CC 17))]
12321 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12322 "@
12323 rol{w}\t{%2, %0|%0, %2}
12324 rol{w}\t{%b2, %0|%0, %b2}"
12325 [(set_attr "type" "rotate")
12326 (set_attr "mode" "HI")])
12327
12328 (define_expand "rotlqi3"
12329 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12330 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12331 (match_operand:QI 2 "nonmemory_operand" "")))
12332 (clobber (reg:CC 17))]
12333 "TARGET_QIMODE_MATH"
12334 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12335
12336 (define_insn "*rotlqi3_1_one_bit_slp"
12337 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12338 (rotate:QI (match_dup 0)
12339 (match_operand:QI 1 "const1_operand" "")))
12340 (clobber (reg:CC 17))]
12341 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12342 && (TARGET_SHIFT1 || optimize_size)"
12343 "rol{b}\t%0"
12344 [(set_attr "type" "rotate1")
12345 (set (attr "length")
12346 (if_then_else (match_operand 0 "register_operand" "")
12347 (const_string "2")
12348 (const_string "*")))])
12349
12350 (define_insn "*rotlqi3_1_one_bit"
12351 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12352 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const1_operand" "")))
12354 (clobber (reg:CC 17))]
12355 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12356 && (TARGET_SHIFT1 || optimize_size)"
12357 "rol{b}\t%0"
12358 [(set_attr "type" "rotate")
12359 (set (attr "length")
12360 (if_then_else (match_operand 0 "register_operand" "")
12361 (const_string "2")
12362 (const_string "*")))])
12363
12364 (define_insn "*rotlqi3_1_slp"
12365 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12366 (rotate:QI (match_dup 0)
12367 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12368 (clobber (reg:CC 17))]
12369 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12370 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12371 "@
12372 rol{b}\t{%1, %0|%0, %1}
12373 rol{b}\t{%b1, %0|%0, %b1}"
12374 [(set_attr "type" "rotate1")
12375 (set_attr "mode" "QI")])
12376
12377 (define_insn "*rotlqi3_1"
12378 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12379 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12380 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12381 (clobber (reg:CC 17))]
12382 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12383 "@
12384 rol{b}\t{%2, %0|%0, %2}
12385 rol{b}\t{%b2, %0|%0, %b2}"
12386 [(set_attr "type" "rotate")
12387 (set_attr "mode" "QI")])
12388
12389 (define_expand "rotrdi3"
12390 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12391 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12392 (match_operand:QI 2 "nonmemory_operand" "")))
12393 (clobber (reg:CC 17))]
12394 "TARGET_64BIT"
12395 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12396
12397 (define_insn "*rotrdi3_1_one_bit_rex64"
12398 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12399 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12400 (match_operand:QI 2 "const1_operand" "")))
12401 (clobber (reg:CC 17))]
12402 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12403 && (TARGET_SHIFT1 || optimize_size)"
12404 "ror{q}\t%0"
12405 [(set_attr "type" "rotate")
12406 (set (attr "length")
12407 (if_then_else (match_operand:DI 0 "register_operand" "")
12408 (const_string "2")
12409 (const_string "*")))])
12410
12411 (define_insn "*rotrdi3_1_rex64"
12412 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12413 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12414 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12415 (clobber (reg:CC 17))]
12416 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12417 "@
12418 ror{q}\t{%2, %0|%0, %2}
12419 ror{q}\t{%b2, %0|%0, %b2}"
12420 [(set_attr "type" "rotate")
12421 (set_attr "mode" "DI")])
12422
12423 (define_expand "rotrsi3"
12424 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12425 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12426 (match_operand:QI 2 "nonmemory_operand" "")))
12427 (clobber (reg:CC 17))]
12428 ""
12429 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12430
12431 (define_insn "*rotrsi3_1_one_bit"
12432 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12433 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12434 (match_operand:QI 2 "const1_operand" "")))
12435 (clobber (reg:CC 17))]
12436 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12437 && (TARGET_SHIFT1 || optimize_size)"
12438 "ror{l}\t%0"
12439 [(set_attr "type" "rotate")
12440 (set (attr "length")
12441 (if_then_else (match_operand:SI 0 "register_operand" "")
12442 (const_string "2")
12443 (const_string "*")))])
12444
12445 (define_insn "*rotrsi3_1_one_bit_zext"
12446 [(set (match_operand:DI 0 "register_operand" "=r")
12447 (zero_extend:DI
12448 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12449 (match_operand:QI 2 "const1_operand" ""))))
12450 (clobber (reg:CC 17))]
12451 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12452 && (TARGET_SHIFT1 || optimize_size)"
12453 "ror{l}\t%k0"
12454 [(set_attr "type" "rotate")
12455 (set (attr "length")
12456 (if_then_else (match_operand:SI 0 "register_operand" "")
12457 (const_string "2")
12458 (const_string "*")))])
12459
12460 (define_insn "*rotrsi3_1"
12461 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12462 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12463 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12464 (clobber (reg:CC 17))]
12465 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12466 "@
12467 ror{l}\t{%2, %0|%0, %2}
12468 ror{l}\t{%b2, %0|%0, %b2}"
12469 [(set_attr "type" "rotate")
12470 (set_attr "mode" "SI")])
12471
12472 (define_insn "*rotrsi3_1_zext"
12473 [(set (match_operand:DI 0 "register_operand" "=r,r")
12474 (zero_extend:DI
12475 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12476 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12477 (clobber (reg:CC 17))]
12478 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12479 "@
12480 ror{l}\t{%2, %k0|%k0, %2}
12481 ror{l}\t{%b2, %k0|%k0, %b2}"
12482 [(set_attr "type" "rotate")
12483 (set_attr "mode" "SI")])
12484
12485 (define_expand "rotrhi3"
12486 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12487 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12488 (match_operand:QI 2 "nonmemory_operand" "")))
12489 (clobber (reg:CC 17))]
12490 "TARGET_HIMODE_MATH"
12491 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12492
12493 (define_insn "*rotrhi3_one_bit"
12494 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12495 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12496 (match_operand:QI 2 "const1_operand" "")))
12497 (clobber (reg:CC 17))]
12498 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12499 && (TARGET_SHIFT1 || optimize_size)"
12500 "ror{w}\t%0"
12501 [(set_attr "type" "rotate")
12502 (set (attr "length")
12503 (if_then_else (match_operand 0 "register_operand" "")
12504 (const_string "2")
12505 (const_string "*")))])
12506
12507 (define_insn "*rotrhi3"
12508 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12509 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12510 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12511 (clobber (reg:CC 17))]
12512 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12513 "@
12514 ror{w}\t{%2, %0|%0, %2}
12515 ror{w}\t{%b2, %0|%0, %b2}"
12516 [(set_attr "type" "rotate")
12517 (set_attr "mode" "HI")])
12518
12519 (define_expand "rotrqi3"
12520 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12521 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12522 (match_operand:QI 2 "nonmemory_operand" "")))
12523 (clobber (reg:CC 17))]
12524 "TARGET_QIMODE_MATH"
12525 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12526
12527 (define_insn "*rotrqi3_1_one_bit"
12528 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12529 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12530 (match_operand:QI 2 "const1_operand" "")))
12531 (clobber (reg:CC 17))]
12532 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12533 && (TARGET_SHIFT1 || optimize_size)"
12534 "ror{b}\t%0"
12535 [(set_attr "type" "rotate")
12536 (set (attr "length")
12537 (if_then_else (match_operand 0 "register_operand" "")
12538 (const_string "2")
12539 (const_string "*")))])
12540
12541 (define_insn "*rotrqi3_1_one_bit_slp"
12542 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12543 (rotatert:QI (match_dup 0)
12544 (match_operand:QI 1 "const1_operand" "")))
12545 (clobber (reg:CC 17))]
12546 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12547 && (TARGET_SHIFT1 || optimize_size)"
12548 "ror{b}\t%0"
12549 [(set_attr "type" "rotate1")
12550 (set (attr "length")
12551 (if_then_else (match_operand 0 "register_operand" "")
12552 (const_string "2")
12553 (const_string "*")))])
12554
12555 (define_insn "*rotrqi3_1"
12556 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12557 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12558 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12559 (clobber (reg:CC 17))]
12560 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12561 "@
12562 ror{b}\t{%2, %0|%0, %2}
12563 ror{b}\t{%b2, %0|%0, %b2}"
12564 [(set_attr "type" "rotate")
12565 (set_attr "mode" "QI")])
12566
12567 (define_insn "*rotrqi3_1_slp"
12568 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12569 (rotatert:QI (match_dup 0)
12570 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12571 (clobber (reg:CC 17))]
12572 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12573 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12574 "@
12575 ror{b}\t{%1, %0|%0, %1}
12576 ror{b}\t{%b1, %0|%0, %b1}"
12577 [(set_attr "type" "rotate1")
12578 (set_attr "mode" "QI")])
12579 \f
12580 ;; Bit set / bit test instructions
12581
12582 (define_expand "extv"
12583 [(set (match_operand:SI 0 "register_operand" "")
12584 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12585 (match_operand:SI 2 "immediate_operand" "")
12586 (match_operand:SI 3 "immediate_operand" "")))]
12587 ""
12588 {
12589 /* Handle extractions from %ah et al. */
12590 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12591 FAIL;
12592
12593 /* From mips.md: extract_bit_field doesn't verify that our source
12594 matches the predicate, so check it again here. */
12595 if (! register_operand (operands[1], VOIDmode))
12596 FAIL;
12597 })
12598
12599 (define_expand "extzv"
12600 [(set (match_operand:SI 0 "register_operand" "")
12601 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12602 (match_operand:SI 2 "immediate_operand" "")
12603 (match_operand:SI 3 "immediate_operand" "")))]
12604 ""
12605 {
12606 /* Handle extractions from %ah et al. */
12607 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12608 FAIL;
12609
12610 /* From mips.md: extract_bit_field doesn't verify that our source
12611 matches the predicate, so check it again here. */
12612 if (! register_operand (operands[1], VOIDmode))
12613 FAIL;
12614 })
12615
12616 (define_expand "insv"
12617 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12618 (match_operand:SI 1 "immediate_operand" "")
12619 (match_operand:SI 2 "immediate_operand" ""))
12620 (match_operand:SI 3 "register_operand" ""))]
12621 ""
12622 {
12623 /* Handle extractions from %ah et al. */
12624 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12625 FAIL;
12626
12627 /* From mips.md: insert_bit_field doesn't verify that our source
12628 matches the predicate, so check it again here. */
12629 if (! register_operand (operands[0], VOIDmode))
12630 FAIL;
12631 })
12632
12633 ;; %%% bts, btr, btc, bt.
12634 \f
12635 ;; Store-flag instructions.
12636
12637 ;; For all sCOND expanders, also expand the compare or test insn that
12638 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12639
12640 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12641 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12642 ;; way, which can later delete the movzx if only QImode is needed.
12643
12644 (define_expand "seq"
12645 [(set (match_operand:QI 0 "register_operand" "")
12646 (eq:QI (reg:CC 17) (const_int 0)))]
12647 ""
12648 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12649
12650 (define_expand "sne"
12651 [(set (match_operand:QI 0 "register_operand" "")
12652 (ne:QI (reg:CC 17) (const_int 0)))]
12653 ""
12654 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12655
12656 (define_expand "sgt"
12657 [(set (match_operand:QI 0 "register_operand" "")
12658 (gt:QI (reg:CC 17) (const_int 0)))]
12659 ""
12660 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12661
12662 (define_expand "sgtu"
12663 [(set (match_operand:QI 0 "register_operand" "")
12664 (gtu:QI (reg:CC 17) (const_int 0)))]
12665 ""
12666 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12667
12668 (define_expand "slt"
12669 [(set (match_operand:QI 0 "register_operand" "")
12670 (lt:QI (reg:CC 17) (const_int 0)))]
12671 ""
12672 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12673
12674 (define_expand "sltu"
12675 [(set (match_operand:QI 0 "register_operand" "")
12676 (ltu:QI (reg:CC 17) (const_int 0)))]
12677 ""
12678 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12679
12680 (define_expand "sge"
12681 [(set (match_operand:QI 0 "register_operand" "")
12682 (ge:QI (reg:CC 17) (const_int 0)))]
12683 ""
12684 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12685
12686 (define_expand "sgeu"
12687 [(set (match_operand:QI 0 "register_operand" "")
12688 (geu:QI (reg:CC 17) (const_int 0)))]
12689 ""
12690 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12691
12692 (define_expand "sle"
12693 [(set (match_operand:QI 0 "register_operand" "")
12694 (le:QI (reg:CC 17) (const_int 0)))]
12695 ""
12696 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12697
12698 (define_expand "sleu"
12699 [(set (match_operand:QI 0 "register_operand" "")
12700 (leu:QI (reg:CC 17) (const_int 0)))]
12701 ""
12702 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12703
12704 (define_expand "sunordered"
12705 [(set (match_operand:QI 0 "register_operand" "")
12706 (unordered:QI (reg:CC 17) (const_int 0)))]
12707 "TARGET_80387 || TARGET_SSE"
12708 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12709
12710 (define_expand "sordered"
12711 [(set (match_operand:QI 0 "register_operand" "")
12712 (ordered:QI (reg:CC 17) (const_int 0)))]
12713 "TARGET_80387"
12714 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "suneq"
12717 [(set (match_operand:QI 0 "register_operand" "")
12718 (uneq:QI (reg:CC 17) (const_int 0)))]
12719 "TARGET_80387 || TARGET_SSE"
12720 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sunge"
12723 [(set (match_operand:QI 0 "register_operand" "")
12724 (unge:QI (reg:CC 17) (const_int 0)))]
12725 "TARGET_80387 || TARGET_SSE"
12726 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sungt"
12729 [(set (match_operand:QI 0 "register_operand" "")
12730 (ungt:QI (reg:CC 17) (const_int 0)))]
12731 "TARGET_80387 || TARGET_SSE"
12732 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "sunle"
12735 [(set (match_operand:QI 0 "register_operand" "")
12736 (unle:QI (reg:CC 17) (const_int 0)))]
12737 "TARGET_80387 || TARGET_SSE"
12738 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sunlt"
12741 [(set (match_operand:QI 0 "register_operand" "")
12742 (unlt:QI (reg:CC 17) (const_int 0)))]
12743 "TARGET_80387 || TARGET_SSE"
12744 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sltgt"
12747 [(set (match_operand:QI 0 "register_operand" "")
12748 (ltgt:QI (reg:CC 17) (const_int 0)))]
12749 "TARGET_80387 || TARGET_SSE"
12750 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12751
12752 (define_insn "*setcc_1"
12753 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12754 (match_operator:QI 1 "ix86_comparison_operator"
12755 [(reg 17) (const_int 0)]))]
12756 ""
12757 "set%C1\t%0"
12758 [(set_attr "type" "setcc")
12759 (set_attr "mode" "QI")])
12760
12761 (define_insn "setcc_2"
12762 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12763 (match_operator:QI 1 "ix86_comparison_operator"
12764 [(reg 17) (const_int 0)]))]
12765 ""
12766 "set%C1\t%0"
12767 [(set_attr "type" "setcc")
12768 (set_attr "mode" "QI")])
12769
12770 ;; In general it is not safe to assume too much about CCmode registers,
12771 ;; so simplify-rtx stops when it sees a second one. Under certain
12772 ;; conditions this is safe on x86, so help combine not create
12773 ;;
12774 ;; seta %al
12775 ;; testb %al, %al
12776 ;; sete %al
12777
12778 (define_split
12779 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12780 (ne:QI (match_operator 1 "ix86_comparison_operator"
12781 [(reg 17) (const_int 0)])
12782 (const_int 0)))]
12783 ""
12784 [(set (match_dup 0) (match_dup 1))]
12785 {
12786 PUT_MODE (operands[1], QImode);
12787 })
12788
12789 (define_split
12790 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12791 (ne:QI (match_operator 1 "ix86_comparison_operator"
12792 [(reg 17) (const_int 0)])
12793 (const_int 0)))]
12794 ""
12795 [(set (match_dup 0) (match_dup 1))]
12796 {
12797 PUT_MODE (operands[1], QImode);
12798 })
12799
12800 (define_split
12801 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12802 (eq:QI (match_operator 1 "ix86_comparison_operator"
12803 [(reg 17) (const_int 0)])
12804 (const_int 0)))]
12805 ""
12806 [(set (match_dup 0) (match_dup 1))]
12807 {
12808 rtx new_op1 = copy_rtx (operands[1]);
12809 operands[1] = new_op1;
12810 PUT_MODE (new_op1, QImode);
12811 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12812 GET_MODE (XEXP (new_op1, 0))));
12813
12814 /* Make sure that (a) the CCmode we have for the flags is strong
12815 enough for the reversed compare or (b) we have a valid FP compare. */
12816 if (! ix86_comparison_operator (new_op1, VOIDmode))
12817 FAIL;
12818 })
12819
12820 (define_split
12821 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12822 (eq:QI (match_operator 1 "ix86_comparison_operator"
12823 [(reg 17) (const_int 0)])
12824 (const_int 0)))]
12825 ""
12826 [(set (match_dup 0) (match_dup 1))]
12827 {
12828 rtx new_op1 = copy_rtx (operands[1]);
12829 operands[1] = new_op1;
12830 PUT_MODE (new_op1, QImode);
12831 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12832 GET_MODE (XEXP (new_op1, 0))));
12833
12834 /* Make sure that (a) the CCmode we have for the flags is strong
12835 enough for the reversed compare or (b) we have a valid FP compare. */
12836 if (! ix86_comparison_operator (new_op1, VOIDmode))
12837 FAIL;
12838 })
12839
12840 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12841 ;; subsequent logical operations are used to imitate conditional moves.
12842 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12843 ;; it directly. Further holding this value in pseudo register might bring
12844 ;; problem in implicit normalization in spill code.
12845 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12846 ;; instructions after reload by splitting the conditional move patterns.
12847
12848 (define_insn "*sse_setccsf"
12849 [(set (match_operand:SF 0 "register_operand" "=x")
12850 (match_operator:SF 1 "sse_comparison_operator"
12851 [(match_operand:SF 2 "register_operand" "0")
12852 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12853 "TARGET_SSE && reload_completed"
12854 "cmp%D1ss\t{%3, %0|%0, %3}"
12855 [(set_attr "type" "ssecmp")
12856 (set_attr "mode" "SF")])
12857
12858 (define_insn "*sse_setccdf"
12859 [(set (match_operand:DF 0 "register_operand" "=Y")
12860 (match_operator:DF 1 "sse_comparison_operator"
12861 [(match_operand:DF 2 "register_operand" "0")
12862 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12863 "TARGET_SSE2 && reload_completed"
12864 "cmp%D1sd\t{%3, %0|%0, %3}"
12865 [(set_attr "type" "ssecmp")
12866 (set_attr "mode" "DF")])
12867 \f
12868 ;; Basic conditional jump instructions.
12869 ;; We ignore the overflow flag for signed branch instructions.
12870
12871 ;; For all bCOND expanders, also expand the compare or test insn that
12872 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12873
12874 (define_expand "beq"
12875 [(set (pc)
12876 (if_then_else (match_dup 1)
12877 (label_ref (match_operand 0 "" ""))
12878 (pc)))]
12879 ""
12880 "ix86_expand_branch (EQ, operands[0]); DONE;")
12881
12882 (define_expand "bne"
12883 [(set (pc)
12884 (if_then_else (match_dup 1)
12885 (label_ref (match_operand 0 "" ""))
12886 (pc)))]
12887 ""
12888 "ix86_expand_branch (NE, operands[0]); DONE;")
12889
12890 (define_expand "bgt"
12891 [(set (pc)
12892 (if_then_else (match_dup 1)
12893 (label_ref (match_operand 0 "" ""))
12894 (pc)))]
12895 ""
12896 "ix86_expand_branch (GT, operands[0]); DONE;")
12897
12898 (define_expand "bgtu"
12899 [(set (pc)
12900 (if_then_else (match_dup 1)
12901 (label_ref (match_operand 0 "" ""))
12902 (pc)))]
12903 ""
12904 "ix86_expand_branch (GTU, operands[0]); DONE;")
12905
12906 (define_expand "blt"
12907 [(set (pc)
12908 (if_then_else (match_dup 1)
12909 (label_ref (match_operand 0 "" ""))
12910 (pc)))]
12911 ""
12912 "ix86_expand_branch (LT, operands[0]); DONE;")
12913
12914 (define_expand "bltu"
12915 [(set (pc)
12916 (if_then_else (match_dup 1)
12917 (label_ref (match_operand 0 "" ""))
12918 (pc)))]
12919 ""
12920 "ix86_expand_branch (LTU, operands[0]); DONE;")
12921
12922 (define_expand "bge"
12923 [(set (pc)
12924 (if_then_else (match_dup 1)
12925 (label_ref (match_operand 0 "" ""))
12926 (pc)))]
12927 ""
12928 "ix86_expand_branch (GE, operands[0]); DONE;")
12929
12930 (define_expand "bgeu"
12931 [(set (pc)
12932 (if_then_else (match_dup 1)
12933 (label_ref (match_operand 0 "" ""))
12934 (pc)))]
12935 ""
12936 "ix86_expand_branch (GEU, operands[0]); DONE;")
12937
12938 (define_expand "ble"
12939 [(set (pc)
12940 (if_then_else (match_dup 1)
12941 (label_ref (match_operand 0 "" ""))
12942 (pc)))]
12943 ""
12944 "ix86_expand_branch (LE, operands[0]); DONE;")
12945
12946 (define_expand "bleu"
12947 [(set (pc)
12948 (if_then_else (match_dup 1)
12949 (label_ref (match_operand 0 "" ""))
12950 (pc)))]
12951 ""
12952 "ix86_expand_branch (LEU, operands[0]); DONE;")
12953
12954 (define_expand "bunordered"
12955 [(set (pc)
12956 (if_then_else (match_dup 1)
12957 (label_ref (match_operand 0 "" ""))
12958 (pc)))]
12959 "TARGET_80387 || TARGET_SSE"
12960 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12961
12962 (define_expand "bordered"
12963 [(set (pc)
12964 (if_then_else (match_dup 1)
12965 (label_ref (match_operand 0 "" ""))
12966 (pc)))]
12967 "TARGET_80387 || TARGET_SSE"
12968 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12969
12970 (define_expand "buneq"
12971 [(set (pc)
12972 (if_then_else (match_dup 1)
12973 (label_ref (match_operand 0 "" ""))
12974 (pc)))]
12975 "TARGET_80387 || TARGET_SSE"
12976 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12977
12978 (define_expand "bunge"
12979 [(set (pc)
12980 (if_then_else (match_dup 1)
12981 (label_ref (match_operand 0 "" ""))
12982 (pc)))]
12983 "TARGET_80387 || TARGET_SSE"
12984 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12985
12986 (define_expand "bungt"
12987 [(set (pc)
12988 (if_then_else (match_dup 1)
12989 (label_ref (match_operand 0 "" ""))
12990 (pc)))]
12991 "TARGET_80387 || TARGET_SSE"
12992 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12993
12994 (define_expand "bunle"
12995 [(set (pc)
12996 (if_then_else (match_dup 1)
12997 (label_ref (match_operand 0 "" ""))
12998 (pc)))]
12999 "TARGET_80387 || TARGET_SSE"
13000 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13001
13002 (define_expand "bunlt"
13003 [(set (pc)
13004 (if_then_else (match_dup 1)
13005 (label_ref (match_operand 0 "" ""))
13006 (pc)))]
13007 "TARGET_80387 || TARGET_SSE"
13008 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13009
13010 (define_expand "bltgt"
13011 [(set (pc)
13012 (if_then_else (match_dup 1)
13013 (label_ref (match_operand 0 "" ""))
13014 (pc)))]
13015 "TARGET_80387 || TARGET_SSE"
13016 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13017
13018 (define_insn "*jcc_1"
13019 [(set (pc)
13020 (if_then_else (match_operator 1 "ix86_comparison_operator"
13021 [(reg 17) (const_int 0)])
13022 (label_ref (match_operand 0 "" ""))
13023 (pc)))]
13024 ""
13025 "%+j%C1\t%l0"
13026 [(set_attr "type" "ibr")
13027 (set_attr "modrm" "0")
13028 (set (attr "length")
13029 (if_then_else (and (ge (minus (match_dup 0) (pc))
13030 (const_int -126))
13031 (lt (minus (match_dup 0) (pc))
13032 (const_int 128)))
13033 (const_int 2)
13034 (const_int 6)))])
13035
13036 (define_insn "*jcc_2"
13037 [(set (pc)
13038 (if_then_else (match_operator 1 "ix86_comparison_operator"
13039 [(reg 17) (const_int 0)])
13040 (pc)
13041 (label_ref (match_operand 0 "" ""))))]
13042 ""
13043 "%+j%c1\t%l0"
13044 [(set_attr "type" "ibr")
13045 (set_attr "modrm" "0")
13046 (set (attr "length")
13047 (if_then_else (and (ge (minus (match_dup 0) (pc))
13048 (const_int -126))
13049 (lt (minus (match_dup 0) (pc))
13050 (const_int 128)))
13051 (const_int 2)
13052 (const_int 6)))])
13053
13054 ;; In general it is not safe to assume too much about CCmode registers,
13055 ;; so simplify-rtx stops when it sees a second one. Under certain
13056 ;; conditions this is safe on x86, so help combine not create
13057 ;;
13058 ;; seta %al
13059 ;; testb %al, %al
13060 ;; je Lfoo
13061
13062 (define_split
13063 [(set (pc)
13064 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13065 [(reg 17) (const_int 0)])
13066 (const_int 0))
13067 (label_ref (match_operand 1 "" ""))
13068 (pc)))]
13069 ""
13070 [(set (pc)
13071 (if_then_else (match_dup 0)
13072 (label_ref (match_dup 1))
13073 (pc)))]
13074 {
13075 PUT_MODE (operands[0], VOIDmode);
13076 })
13077
13078 (define_split
13079 [(set (pc)
13080 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13081 [(reg 17) (const_int 0)])
13082 (const_int 0))
13083 (label_ref (match_operand 1 "" ""))
13084 (pc)))]
13085 ""
13086 [(set (pc)
13087 (if_then_else (match_dup 0)
13088 (label_ref (match_dup 1))
13089 (pc)))]
13090 {
13091 rtx new_op0 = copy_rtx (operands[0]);
13092 operands[0] = new_op0;
13093 PUT_MODE (new_op0, VOIDmode);
13094 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13095 GET_MODE (XEXP (new_op0, 0))));
13096
13097 /* Make sure that (a) the CCmode we have for the flags is strong
13098 enough for the reversed compare or (b) we have a valid FP compare. */
13099 if (! ix86_comparison_operator (new_op0, VOIDmode))
13100 FAIL;
13101 })
13102
13103 ;; Define combination compare-and-branch fp compare instructions to use
13104 ;; during early optimization. Splitting the operation apart early makes
13105 ;; for bad code when we want to reverse the operation.
13106
13107 (define_insn "*fp_jcc_1"
13108 [(set (pc)
13109 (if_then_else (match_operator 0 "comparison_operator"
13110 [(match_operand 1 "register_operand" "f")
13111 (match_operand 2 "register_operand" "f")])
13112 (label_ref (match_operand 3 "" ""))
13113 (pc)))
13114 (clobber (reg:CCFP 18))
13115 (clobber (reg:CCFP 17))]
13116 "TARGET_CMOVE && TARGET_80387
13117 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13118 && FLOAT_MODE_P (GET_MODE (operands[1]))
13119 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13120 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13121 "#")
13122
13123 (define_insn "*fp_jcc_1_sse"
13124 [(set (pc)
13125 (if_then_else (match_operator 0 "comparison_operator"
13126 [(match_operand 1 "register_operand" "f#x,x#f")
13127 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13128 (label_ref (match_operand 3 "" ""))
13129 (pc)))
13130 (clobber (reg:CCFP 18))
13131 (clobber (reg:CCFP 17))]
13132 "TARGET_80387
13133 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13134 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13135 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13136 "#")
13137
13138 (define_insn "*fp_jcc_1_sse_only"
13139 [(set (pc)
13140 (if_then_else (match_operator 0 "comparison_operator"
13141 [(match_operand 1 "register_operand" "x")
13142 (match_operand 2 "nonimmediate_operand" "xm")])
13143 (label_ref (match_operand 3 "" ""))
13144 (pc)))
13145 (clobber (reg:CCFP 18))
13146 (clobber (reg:CCFP 17))]
13147 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13148 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13149 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13150 "#")
13151
13152 (define_insn "*fp_jcc_2"
13153 [(set (pc)
13154 (if_then_else (match_operator 0 "comparison_operator"
13155 [(match_operand 1 "register_operand" "f")
13156 (match_operand 2 "register_operand" "f")])
13157 (pc)
13158 (label_ref (match_operand 3 "" ""))))
13159 (clobber (reg:CCFP 18))
13160 (clobber (reg:CCFP 17))]
13161 "TARGET_CMOVE && TARGET_80387
13162 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13163 && FLOAT_MODE_P (GET_MODE (operands[1]))
13164 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13165 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13166 "#")
13167
13168 (define_insn "*fp_jcc_2_sse"
13169 [(set (pc)
13170 (if_then_else (match_operator 0 "comparison_operator"
13171 [(match_operand 1 "register_operand" "f#x,x#f")
13172 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13173 (pc)
13174 (label_ref (match_operand 3 "" ""))))
13175 (clobber (reg:CCFP 18))
13176 (clobber (reg:CCFP 17))]
13177 "TARGET_80387
13178 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13179 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13180 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13181 "#")
13182
13183 (define_insn "*fp_jcc_2_sse_only"
13184 [(set (pc)
13185 (if_then_else (match_operator 0 "comparison_operator"
13186 [(match_operand 1 "register_operand" "x")
13187 (match_operand 2 "nonimmediate_operand" "xm")])
13188 (pc)
13189 (label_ref (match_operand 3 "" ""))))
13190 (clobber (reg:CCFP 18))
13191 (clobber (reg:CCFP 17))]
13192 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13193 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13194 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13195 "#")
13196
13197 (define_insn "*fp_jcc_3"
13198 [(set (pc)
13199 (if_then_else (match_operator 0 "comparison_operator"
13200 [(match_operand 1 "register_operand" "f")
13201 (match_operand 2 "nonimmediate_operand" "fm")])
13202 (label_ref (match_operand 3 "" ""))
13203 (pc)))
13204 (clobber (reg:CCFP 18))
13205 (clobber (reg:CCFP 17))
13206 (clobber (match_scratch:HI 4 "=a"))]
13207 "TARGET_80387
13208 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13209 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13210 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13211 && SELECT_CC_MODE (GET_CODE (operands[0]),
13212 operands[1], operands[2]) == CCFPmode
13213 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13214 "#")
13215
13216 (define_insn "*fp_jcc_4"
13217 [(set (pc)
13218 (if_then_else (match_operator 0 "comparison_operator"
13219 [(match_operand 1 "register_operand" "f")
13220 (match_operand 2 "nonimmediate_operand" "fm")])
13221 (pc)
13222 (label_ref (match_operand 3 "" ""))))
13223 (clobber (reg:CCFP 18))
13224 (clobber (reg:CCFP 17))
13225 (clobber (match_scratch:HI 4 "=a"))]
13226 "TARGET_80387
13227 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13228 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13229 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13230 && SELECT_CC_MODE (GET_CODE (operands[0]),
13231 operands[1], operands[2]) == CCFPmode
13232 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13233 "#")
13234
13235 (define_insn "*fp_jcc_5"
13236 [(set (pc)
13237 (if_then_else (match_operator 0 "comparison_operator"
13238 [(match_operand 1 "register_operand" "f")
13239 (match_operand 2 "register_operand" "f")])
13240 (label_ref (match_operand 3 "" ""))
13241 (pc)))
13242 (clobber (reg:CCFP 18))
13243 (clobber (reg:CCFP 17))
13244 (clobber (match_scratch:HI 4 "=a"))]
13245 "TARGET_80387
13246 && FLOAT_MODE_P (GET_MODE (operands[1]))
13247 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13248 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13249 "#")
13250
13251 (define_insn "*fp_jcc_6"
13252 [(set (pc)
13253 (if_then_else (match_operator 0 "comparison_operator"
13254 [(match_operand 1 "register_operand" "f")
13255 (match_operand 2 "register_operand" "f")])
13256 (pc)
13257 (label_ref (match_operand 3 "" ""))))
13258 (clobber (reg:CCFP 18))
13259 (clobber (reg:CCFP 17))
13260 (clobber (match_scratch:HI 4 "=a"))]
13261 "TARGET_80387
13262 && 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_split
13268 [(set (pc)
13269 (if_then_else (match_operator 0 "comparison_operator"
13270 [(match_operand 1 "register_operand" "")
13271 (match_operand 2 "nonimmediate_operand" "")])
13272 (match_operand 3 "" "")
13273 (match_operand 4 "" "")))
13274 (clobber (reg:CCFP 18))
13275 (clobber (reg:CCFP 17))]
13276 "reload_completed"
13277 [(const_int 0)]
13278 {
13279 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13280 operands[3], operands[4], NULL_RTX);
13281 DONE;
13282 })
13283
13284 (define_split
13285 [(set (pc)
13286 (if_then_else (match_operator 0 "comparison_operator"
13287 [(match_operand 1 "register_operand" "")
13288 (match_operand 2 "nonimmediate_operand" "")])
13289 (match_operand 3 "" "")
13290 (match_operand 4 "" "")))
13291 (clobber (reg:CCFP 18))
13292 (clobber (reg:CCFP 17))
13293 (clobber (match_scratch:HI 5 "=a"))]
13294 "reload_completed"
13295 [(set (pc)
13296 (if_then_else (match_dup 6)
13297 (match_dup 3)
13298 (match_dup 4)))]
13299 {
13300 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13301 operands[3], operands[4], operands[5]);
13302 DONE;
13303 })
13304 \f
13305 ;; Unconditional and other jump instructions
13306
13307 (define_insn "jump"
13308 [(set (pc)
13309 (label_ref (match_operand 0 "" "")))]
13310 ""
13311 "jmp\t%l0"
13312 [(set_attr "type" "ibr")
13313 (set (attr "length")
13314 (if_then_else (and (ge (minus (match_dup 0) (pc))
13315 (const_int -126))
13316 (lt (minus (match_dup 0) (pc))
13317 (const_int 128)))
13318 (const_int 2)
13319 (const_int 5)))
13320 (set_attr "modrm" "0")])
13321
13322 (define_expand "indirect_jump"
13323 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13324 ""
13325 "")
13326
13327 (define_insn "*indirect_jump"
13328 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13329 "!TARGET_64BIT"
13330 "jmp\t%A0"
13331 [(set_attr "type" "ibr")
13332 (set_attr "length_immediate" "0")])
13333
13334 (define_insn "*indirect_jump_rtx64"
13335 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13336 "TARGET_64BIT"
13337 "jmp\t%A0"
13338 [(set_attr "type" "ibr")
13339 (set_attr "length_immediate" "0")])
13340
13341 (define_expand "tablejump"
13342 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13343 (use (label_ref (match_operand 1 "" "")))])]
13344 ""
13345 {
13346 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13347 relative. Convert the relative address to an absolute address. */
13348 if (flag_pic)
13349 {
13350 rtx op0, op1;
13351 enum rtx_code code;
13352
13353 if (TARGET_64BIT)
13354 {
13355 code = PLUS;
13356 op0 = operands[0];
13357 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13358 }
13359 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13360 {
13361 code = PLUS;
13362 op0 = operands[0];
13363 op1 = pic_offset_table_rtx;
13364 }
13365 else
13366 {
13367 code = MINUS;
13368 op0 = pic_offset_table_rtx;
13369 op1 = operands[0];
13370 }
13371
13372 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13373 OPTAB_DIRECT);
13374 }
13375 })
13376
13377 (define_insn "*tablejump_1"
13378 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13379 (use (label_ref (match_operand 1 "" "")))]
13380 "!TARGET_64BIT"
13381 "jmp\t%A0"
13382 [(set_attr "type" "ibr")
13383 (set_attr "length_immediate" "0")])
13384
13385 (define_insn "*tablejump_1_rtx64"
13386 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13387 (use (label_ref (match_operand 1 "" "")))]
13388 "TARGET_64BIT"
13389 "jmp\t%A0"
13390 [(set_attr "type" "ibr")
13391 (set_attr "length_immediate" "0")])
13392 \f
13393 ;; Loop instruction
13394 ;;
13395 ;; This is all complicated by the fact that since this is a jump insn
13396 ;; we must handle our own reloads.
13397
13398 (define_expand "doloop_end"
13399 [(use (match_operand 0 "" "")) ; loop pseudo
13400 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13401 (use (match_operand 2 "" "")) ; max iterations
13402 (use (match_operand 3 "" "")) ; loop level
13403 (use (match_operand 4 "" ""))] ; label
13404 "!TARGET_64BIT && TARGET_USE_LOOP"
13405 "
13406 {
13407 /* Only use cloop on innermost loops. */
13408 if (INTVAL (operands[3]) > 1)
13409 FAIL;
13410 if (GET_MODE (operands[0]) != SImode)
13411 FAIL;
13412 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13413 operands[0]));
13414 DONE;
13415 }")
13416
13417 (define_insn "doloop_end_internal"
13418 [(set (pc)
13419 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13420 (const_int 1))
13421 (label_ref (match_operand 0 "" ""))
13422 (pc)))
13423 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13424 (plus:SI (match_dup 1)
13425 (const_int -1)))
13426 (clobber (match_scratch:SI 3 "=X,X,r"))
13427 (clobber (reg:CC 17))]
13428 "!TARGET_64BIT && TARGET_USE_LOOP
13429 && (reload_in_progress || reload_completed
13430 || register_operand (operands[2], VOIDmode))"
13431 {
13432 if (which_alternative != 0)
13433 return "#";
13434 if (get_attr_length (insn) == 2)
13435 return "%+loop\t%l0";
13436 else
13437 return "dec{l}\t%1\;%+jne\t%l0";
13438 }
13439 [(set (attr "length")
13440 (if_then_else (and (eq_attr "alternative" "0")
13441 (and (ge (minus (match_dup 0) (pc))
13442 (const_int -126))
13443 (lt (minus (match_dup 0) (pc))
13444 (const_int 128))))
13445 (const_int 2)
13446 (const_int 16)))
13447 ;; We don't know the type before shorten branches. Optimistically expect
13448 ;; the loop instruction to match.
13449 (set (attr "type") (const_string "ibr"))])
13450
13451 (define_split
13452 [(set (pc)
13453 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13454 (const_int 1))
13455 (match_operand 0 "" "")
13456 (pc)))
13457 (set (match_dup 1)
13458 (plus:SI (match_dup 1)
13459 (const_int -1)))
13460 (clobber (match_scratch:SI 2 ""))
13461 (clobber (reg:CC 17))]
13462 "!TARGET_64BIT && TARGET_USE_LOOP
13463 && reload_completed
13464 && REGNO (operands[1]) != 2"
13465 [(parallel [(set (reg:CCZ 17)
13466 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13467 (const_int 0)))
13468 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13469 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13470 (match_dup 0)
13471 (pc)))]
13472 "")
13473
13474 (define_split
13475 [(set (pc)
13476 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13477 (const_int 1))
13478 (match_operand 0 "" "")
13479 (pc)))
13480 (set (match_operand:SI 2 "nonimmediate_operand" "")
13481 (plus:SI (match_dup 1)
13482 (const_int -1)))
13483 (clobber (match_scratch:SI 3 ""))
13484 (clobber (reg:CC 17))]
13485 "!TARGET_64BIT && TARGET_USE_LOOP
13486 && reload_completed
13487 && (! REG_P (operands[2])
13488 || ! rtx_equal_p (operands[1], operands[2]))"
13489 [(set (match_dup 3) (match_dup 1))
13490 (parallel [(set (reg:CCZ 17)
13491 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13492 (const_int 0)))
13493 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13494 (set (match_dup 2) (match_dup 3))
13495 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13496 (match_dup 0)
13497 (pc)))]
13498 "")
13499
13500 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13501
13502 (define_peephole2
13503 [(set (reg 17) (match_operand 0 "" ""))
13504 (set (match_operand:QI 1 "register_operand" "")
13505 (match_operator:QI 2 "ix86_comparison_operator"
13506 [(reg 17) (const_int 0)]))
13507 (set (match_operand 3 "q_regs_operand" "")
13508 (zero_extend (match_dup 1)))]
13509 "(peep2_reg_dead_p (3, operands[1])
13510 || operands_match_p (operands[1], operands[3]))
13511 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13512 [(set (match_dup 4) (match_dup 0))
13513 (set (strict_low_part (match_dup 5))
13514 (match_dup 2))]
13515 {
13516 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13517 operands[5] = gen_lowpart (QImode, operands[3]);
13518 ix86_expand_clear (operands[3]);
13519 })
13520
13521 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13522
13523 (define_peephole2
13524 [(set (reg 17) (match_operand 0 "" ""))
13525 (set (match_operand:QI 1 "register_operand" "")
13526 (match_operator:QI 2 "ix86_comparison_operator"
13527 [(reg 17) (const_int 0)]))
13528 (parallel [(set (match_operand 3 "q_regs_operand" "")
13529 (zero_extend (match_dup 1)))
13530 (clobber (reg:CC 17))])]
13531 "(peep2_reg_dead_p (3, operands[1])
13532 || operands_match_p (operands[1], operands[3]))
13533 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13534 [(set (match_dup 4) (match_dup 0))
13535 (set (strict_low_part (match_dup 5))
13536 (match_dup 2))]
13537 {
13538 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13539 operands[5] = gen_lowpart (QImode, operands[3]);
13540 ix86_expand_clear (operands[3]);
13541 })
13542 \f
13543 ;; Call instructions.
13544
13545 ;; The predicates normally associated with named expanders are not properly
13546 ;; checked for calls. This is a bug in the generic code, but it isn't that
13547 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13548
13549 ;; Call subroutine returning no value.
13550
13551 (define_expand "call_pop"
13552 [(parallel [(call (match_operand:QI 0 "" "")
13553 (match_operand:SI 1 "" ""))
13554 (set (reg:SI 7)
13555 (plus:SI (reg:SI 7)
13556 (match_operand:SI 3 "" "")))])]
13557 "!TARGET_64BIT"
13558 {
13559 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13560 DONE;
13561 })
13562
13563 (define_insn "*call_pop_0"
13564 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13565 (match_operand:SI 1 "" ""))
13566 (set (reg:SI 7) (plus:SI (reg:SI 7)
13567 (match_operand:SI 2 "immediate_operand" "")))]
13568 "!TARGET_64BIT"
13569 {
13570 if (SIBLING_CALL_P (insn))
13571 return "jmp\t%P0";
13572 else
13573 return "call\t%P0";
13574 }
13575 [(set_attr "type" "call")])
13576
13577 (define_insn "*call_pop_1"
13578 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13579 (match_operand:SI 1 "" ""))
13580 (set (reg:SI 7) (plus:SI (reg:SI 7)
13581 (match_operand:SI 2 "immediate_operand" "i")))]
13582 "!TARGET_64BIT"
13583 {
13584 if (constant_call_address_operand (operands[0], Pmode))
13585 {
13586 if (SIBLING_CALL_P (insn))
13587 return "jmp\t%P0";
13588 else
13589 return "call\t%P0";
13590 }
13591 if (SIBLING_CALL_P (insn))
13592 return "jmp\t%A0";
13593 else
13594 return "call\t%A0";
13595 }
13596 [(set_attr "type" "call")])
13597
13598 (define_expand "call"
13599 [(call (match_operand:QI 0 "" "")
13600 (match_operand 1 "" ""))
13601 (use (match_operand 2 "" ""))]
13602 ""
13603 {
13604 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13605 DONE;
13606 })
13607
13608 (define_expand "sibcall"
13609 [(call (match_operand:QI 0 "" "")
13610 (match_operand 1 "" ""))
13611 (use (match_operand 2 "" ""))]
13612 ""
13613 {
13614 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13615 DONE;
13616 })
13617
13618 (define_insn "*call_0"
13619 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13620 (match_operand 1 "" ""))]
13621 ""
13622 {
13623 if (SIBLING_CALL_P (insn))
13624 return "jmp\t%P0";
13625 else
13626 return "call\t%P0";
13627 }
13628 [(set_attr "type" "call")])
13629
13630 (define_insn "*call_1"
13631 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13632 (match_operand 1 "" ""))]
13633 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13634 {
13635 if (constant_call_address_operand (operands[0], QImode))
13636 return "call\t%P0";
13637 return "call\t%A0";
13638 }
13639 [(set_attr "type" "call")])
13640
13641 (define_insn "*sibcall_1"
13642 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13643 (match_operand 1 "" ""))]
13644 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13645 {
13646 if (constant_call_address_operand (operands[0], QImode))
13647 return "jmp\t%P0";
13648 return "jmp\t%A0";
13649 }
13650 [(set_attr "type" "call")])
13651
13652 (define_insn "*call_1_rex64"
13653 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13654 (match_operand 1 "" ""))]
13655 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13656 {
13657 if (constant_call_address_operand (operands[0], QImode))
13658 return "call\t%P0";
13659 return "call\t%A0";
13660 }
13661 [(set_attr "type" "call")])
13662
13663 (define_insn "*sibcall_1_rex64"
13664 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13665 (match_operand 1 "" ""))]
13666 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13667 "jmp\t%P0"
13668 [(set_attr "type" "call")])
13669
13670 (define_insn "*sibcall_1_rex64_v"
13671 [(call (mem:QI (reg:DI 40))
13672 (match_operand 0 "" ""))]
13673 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13674 "jmp\t*%%r11"
13675 [(set_attr "type" "call")])
13676
13677
13678 ;; Call subroutine, returning value in operand 0
13679
13680 (define_expand "call_value_pop"
13681 [(parallel [(set (match_operand 0 "" "")
13682 (call (match_operand:QI 1 "" "")
13683 (match_operand:SI 2 "" "")))
13684 (set (reg:SI 7)
13685 (plus:SI (reg:SI 7)
13686 (match_operand:SI 4 "" "")))])]
13687 "!TARGET_64BIT"
13688 {
13689 ix86_expand_call (operands[0], operands[1], operands[2],
13690 operands[3], operands[4], 0);
13691 DONE;
13692 })
13693
13694 (define_expand "call_value"
13695 [(set (match_operand 0 "" "")
13696 (call (match_operand:QI 1 "" "")
13697 (match_operand:SI 2 "" "")))
13698 (use (match_operand:SI 3 "" ""))]
13699 ;; Operand 2 not used on the i386.
13700 ""
13701 {
13702 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13703 DONE;
13704 })
13705
13706 (define_expand "sibcall_value"
13707 [(set (match_operand 0 "" "")
13708 (call (match_operand:QI 1 "" "")
13709 (match_operand:SI 2 "" "")))
13710 (use (match_operand:SI 3 "" ""))]
13711 ;; Operand 2 not used on the i386.
13712 ""
13713 {
13714 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13715 DONE;
13716 })
13717
13718 ;; Call subroutine returning any type.
13719
13720 (define_expand "untyped_call"
13721 [(parallel [(call (match_operand 0 "" "")
13722 (const_int 0))
13723 (match_operand 1 "" "")
13724 (match_operand 2 "" "")])]
13725 ""
13726 {
13727 int i;
13728
13729 /* In order to give reg-stack an easier job in validating two
13730 coprocessor registers as containing a possible return value,
13731 simply pretend the untyped call returns a complex long double
13732 value. */
13733
13734 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13735 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13736 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13737 NULL, 0);
13738
13739 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13740 {
13741 rtx set = XVECEXP (operands[2], 0, i);
13742 emit_move_insn (SET_DEST (set), SET_SRC (set));
13743 }
13744
13745 /* The optimizer does not know that the call sets the function value
13746 registers we stored in the result block. We avoid problems by
13747 claiming that all hard registers are used and clobbered at this
13748 point. */
13749 emit_insn (gen_blockage (const0_rtx));
13750
13751 DONE;
13752 })
13753 \f
13754 ;; Prologue and epilogue instructions
13755
13756 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13757 ;; all of memory. This blocks insns from being moved across this point.
13758
13759 (define_insn "blockage"
13760 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13761 ""
13762 ""
13763 [(set_attr "length" "0")])
13764
13765 ;; Insn emitted into the body of a function to return from a function.
13766 ;; This is only done if the function's epilogue is known to be simple.
13767 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13768
13769 (define_expand "return"
13770 [(return)]
13771 "ix86_can_use_return_insn_p ()"
13772 {
13773 if (current_function_pops_args)
13774 {
13775 rtx popc = GEN_INT (current_function_pops_args);
13776 emit_jump_insn (gen_return_pop_internal (popc));
13777 DONE;
13778 }
13779 })
13780
13781 (define_insn "return_internal"
13782 [(return)]
13783 "reload_completed"
13784 "ret"
13785 [(set_attr "length" "1")
13786 (set_attr "length_immediate" "0")
13787 (set_attr "modrm" "0")])
13788
13789 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13790 ;; instruction Athlon and K8 have.
13791
13792 (define_insn "return_internal_long"
13793 [(return)
13794 (unspec [(const_int 0)] UNSPEC_REP)]
13795 "reload_completed"
13796 "rep {;} ret"
13797 [(set_attr "length" "1")
13798 (set_attr "length_immediate" "0")
13799 (set_attr "prefix_rep" "1")
13800 (set_attr "modrm" "0")])
13801
13802 (define_insn "return_pop_internal"
13803 [(return)
13804 (use (match_operand:SI 0 "const_int_operand" ""))]
13805 "reload_completed"
13806 "ret\t%0"
13807 [(set_attr "length" "3")
13808 (set_attr "length_immediate" "2")
13809 (set_attr "modrm" "0")])
13810
13811 (define_insn "return_indirect_internal"
13812 [(return)
13813 (use (match_operand:SI 0 "register_operand" "r"))]
13814 "reload_completed"
13815 "jmp\t%A0"
13816 [(set_attr "type" "ibr")
13817 (set_attr "length_immediate" "0")])
13818
13819 (define_insn "nop"
13820 [(const_int 0)]
13821 ""
13822 "nop"
13823 [(set_attr "length" "1")
13824 (set_attr "length_immediate" "0")
13825 (set_attr "modrm" "0")])
13826
13827 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13828 ;; branch prediction penalty for the third jump in a 16-byte
13829 ;; block on K8.
13830
13831 (define_insn "align"
13832 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13833 ""
13834 {
13835 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13836 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13837 #else
13838 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13839 The align insn is used to avoid 3 jump instructions in the row to improve
13840 branch prediction and the benefits hardly outweight the cost of extra 8
13841 nops on the average inserted by full alignment pseudo operation. */
13842 #endif
13843 return "";
13844 }
13845 [(set_attr "length" "16")])
13846
13847 (define_expand "prologue"
13848 [(const_int 1)]
13849 ""
13850 "ix86_expand_prologue (); DONE;")
13851
13852 (define_insn "set_got"
13853 [(set (match_operand:SI 0 "register_operand" "=r")
13854 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13855 (clobber (reg:CC 17))]
13856 "!TARGET_64BIT"
13857 { return output_set_got (operands[0]); }
13858 [(set_attr "type" "multi")
13859 (set_attr "length" "12")])
13860
13861 (define_expand "epilogue"
13862 [(const_int 1)]
13863 ""
13864 "ix86_expand_epilogue (1); DONE;")
13865
13866 (define_expand "sibcall_epilogue"
13867 [(const_int 1)]
13868 ""
13869 "ix86_expand_epilogue (0); DONE;")
13870
13871 (define_expand "eh_return"
13872 [(use (match_operand 0 "register_operand" ""))]
13873 ""
13874 {
13875 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13876
13877 /* Tricky bit: we write the address of the handler to which we will
13878 be returning into someone else's stack frame, one word below the
13879 stack address we wish to restore. */
13880 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13881 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13882 tmp = gen_rtx_MEM (Pmode, tmp);
13883 emit_move_insn (tmp, ra);
13884
13885 if (Pmode == SImode)
13886 emit_insn (gen_eh_return_si (sa));
13887 else
13888 emit_insn (gen_eh_return_di (sa));
13889 emit_barrier ();
13890 DONE;
13891 })
13892
13893 (define_insn_and_split "eh_return_si"
13894 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13895 UNSPECV_EH_RETURN)]
13896 "!TARGET_64BIT"
13897 "#"
13898 "reload_completed"
13899 [(const_int 1)]
13900 "ix86_expand_epilogue (2); DONE;")
13901
13902 (define_insn_and_split "eh_return_di"
13903 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13904 UNSPECV_EH_RETURN)]
13905 "TARGET_64BIT"
13906 "#"
13907 "reload_completed"
13908 [(const_int 1)]
13909 "ix86_expand_epilogue (2); DONE;")
13910
13911 (define_insn "leave"
13912 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13913 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13914 (clobber (mem:BLK (scratch)))]
13915 "!TARGET_64BIT"
13916 "leave"
13917 [(set_attr "type" "leave")])
13918
13919 (define_insn "leave_rex64"
13920 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13921 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13922 (clobber (mem:BLK (scratch)))]
13923 "TARGET_64BIT"
13924 "leave"
13925 [(set_attr "type" "leave")])
13926 \f
13927 (define_expand "ffssi2"
13928 [(parallel
13929 [(set (match_operand:SI 0 "register_operand" "")
13930 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13931 (clobber (match_scratch:SI 2 ""))
13932 (clobber (reg:CC 17))])]
13933 ""
13934 "")
13935
13936 (define_insn_and_split "*ffs_cmove"
13937 [(set (match_operand:SI 0 "register_operand" "=r")
13938 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13939 (clobber (match_scratch:SI 2 "=&r"))
13940 (clobber (reg:CC 17))]
13941 "TARGET_CMOVE"
13942 "#"
13943 "&& reload_completed"
13944 [(set (match_dup 2) (const_int -1))
13945 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13946 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13947 (set (match_dup 0) (if_then_else:SI
13948 (eq (reg:CCZ 17) (const_int 0))
13949 (match_dup 2)
13950 (match_dup 0)))
13951 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13952 (clobber (reg:CC 17))])]
13953 "")
13954
13955 (define_insn_and_split "*ffs_no_cmove"
13956 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13957 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13958 (clobber (match_scratch:SI 2 "=&q"))
13959 (clobber (reg:CC 17))]
13960 ""
13961 "#"
13962 "reload_completed"
13963 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13964 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13965 (set (strict_low_part (match_dup 3))
13966 (eq:QI (reg:CCZ 17) (const_int 0)))
13967 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13968 (clobber (reg:CC 17))])
13969 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13970 (clobber (reg:CC 17))])
13971 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13972 (clobber (reg:CC 17))])]
13973 {
13974 operands[3] = gen_lowpart (QImode, operands[2]);
13975 ix86_expand_clear (operands[2]);
13976 })
13977
13978 (define_insn "*ffssi_1"
13979 [(set (reg:CCZ 17)
13980 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13981 (const_int 0)))
13982 (set (match_operand:SI 0 "register_operand" "=r")
13983 (ctz:SI (match_dup 1)))]
13984 ""
13985 "bsf{l}\t{%1, %0|%0, %1}"
13986 [(set_attr "prefix_0f" "1")])
13987
13988 (define_insn "ctzsi2"
13989 [(set (match_operand:SI 0 "register_operand" "=r")
13990 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13991 (clobber (reg:CC 17))]
13992 ""
13993 "bsf{l}\t{%1, %0|%0, %1}"
13994 [(set_attr "prefix_0f" "1")])
13995
13996 (define_expand "clzsi2"
13997 [(parallel
13998 [(set (match_operand:SI 0 "register_operand" "")
13999 (minus:SI (const_int 31)
14000 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14001 (clobber (reg:CC 17))])
14002 (parallel
14003 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14004 (clobber (reg:CC 17))])]
14005 ""
14006 "")
14007
14008 (define_insn "*bsr"
14009 [(set (match_operand:SI 0 "register_operand" "=r")
14010 (minus:SI (const_int 31)
14011 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14012 (clobber (reg:CC 17))]
14013 ""
14014 "bsr{l}\t{%1, %0|%0, %1}"
14015 [(set_attr "prefix_0f" "1")])
14016 \f
14017 ;; Thread-local storage patterns for ELF.
14018 ;;
14019 ;; Note that these code sequences must appear exactly as shown
14020 ;; in order to allow linker relaxation.
14021
14022 (define_insn "*tls_global_dynamic_32_gnu"
14023 [(set (match_operand:SI 0 "register_operand" "=a")
14024 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14025 (match_operand:SI 2 "tls_symbolic_operand" "")
14026 (match_operand:SI 3 "call_insn_operand" "")]
14027 UNSPEC_TLS_GD))
14028 (clobber (match_scratch:SI 4 "=d"))
14029 (clobber (match_scratch:SI 5 "=c"))
14030 (clobber (reg:CC 17))]
14031 "!TARGET_64BIT && TARGET_GNU_TLS"
14032 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14033 [(set_attr "type" "multi")
14034 (set_attr "length" "12")])
14035
14036 (define_insn "*tls_global_dynamic_32_sun"
14037 [(set (match_operand:SI 0 "register_operand" "=a")
14038 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14039 (match_operand:SI 2 "tls_symbolic_operand" "")
14040 (match_operand:SI 3 "call_insn_operand" "")]
14041 UNSPEC_TLS_GD))
14042 (clobber (match_scratch:SI 4 "=d"))
14043 (clobber (match_scratch:SI 5 "=c"))
14044 (clobber (reg:CC 17))]
14045 "!TARGET_64BIT && TARGET_SUN_TLS"
14046 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14047 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14048 [(set_attr "type" "multi")
14049 (set_attr "length" "14")])
14050
14051 (define_expand "tls_global_dynamic_32"
14052 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14053 (unspec:SI
14054 [(match_dup 2)
14055 (match_operand:SI 1 "tls_symbolic_operand" "")
14056 (match_dup 3)]
14057 UNSPEC_TLS_GD))
14058 (clobber (match_scratch:SI 4 ""))
14059 (clobber (match_scratch:SI 5 ""))
14060 (clobber (reg:CC 17))])]
14061 ""
14062 {
14063 if (flag_pic)
14064 operands[2] = pic_offset_table_rtx;
14065 else
14066 {
14067 operands[2] = gen_reg_rtx (Pmode);
14068 emit_insn (gen_set_got (operands[2]));
14069 }
14070 operands[3] = ix86_tls_get_addr ();
14071 })
14072
14073 (define_insn "*tls_global_dynamic_64"
14074 [(set (match_operand:DI 0 "register_operand" "=a")
14075 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14076 (match_operand:DI 3 "" "")))
14077 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14078 UNSPEC_TLS_GD)]
14079 "TARGET_64BIT"
14080 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14081 [(set_attr "type" "multi")
14082 (set_attr "length" "16")])
14083
14084 (define_expand "tls_global_dynamic_64"
14085 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14086 (call (mem:QI (match_dup 2)) (const_int 0)))
14087 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14088 UNSPEC_TLS_GD)])]
14089 ""
14090 {
14091 operands[2] = ix86_tls_get_addr ();
14092 })
14093
14094 (define_insn "*tls_local_dynamic_base_32_gnu"
14095 [(set (match_operand:SI 0 "register_operand" "=a")
14096 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14097 (match_operand:SI 2 "call_insn_operand" "")]
14098 UNSPEC_TLS_LD_BASE))
14099 (clobber (match_scratch:SI 3 "=d"))
14100 (clobber (match_scratch:SI 4 "=c"))
14101 (clobber (reg:CC 17))]
14102 "!TARGET_64BIT && TARGET_GNU_TLS"
14103 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14104 [(set_attr "type" "multi")
14105 (set_attr "length" "11")])
14106
14107 (define_insn "*tls_local_dynamic_base_32_sun"
14108 [(set (match_operand:SI 0 "register_operand" "=a")
14109 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14110 (match_operand:SI 2 "call_insn_operand" "")]
14111 UNSPEC_TLS_LD_BASE))
14112 (clobber (match_scratch:SI 3 "=d"))
14113 (clobber (match_scratch:SI 4 "=c"))
14114 (clobber (reg:CC 17))]
14115 "!TARGET_64BIT && TARGET_SUN_TLS"
14116 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14117 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14118 [(set_attr "type" "multi")
14119 (set_attr "length" "13")])
14120
14121 (define_expand "tls_local_dynamic_base_32"
14122 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14123 (unspec:SI [(match_dup 1) (match_dup 2)]
14124 UNSPEC_TLS_LD_BASE))
14125 (clobber (match_scratch:SI 3 ""))
14126 (clobber (match_scratch:SI 4 ""))
14127 (clobber (reg:CC 17))])]
14128 ""
14129 {
14130 if (flag_pic)
14131 operands[1] = pic_offset_table_rtx;
14132 else
14133 {
14134 operands[1] = gen_reg_rtx (Pmode);
14135 emit_insn (gen_set_got (operands[1]));
14136 }
14137 operands[2] = ix86_tls_get_addr ();
14138 })
14139
14140 (define_insn "*tls_local_dynamic_base_64"
14141 [(set (match_operand:DI 0 "register_operand" "=a")
14142 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14143 (match_operand:DI 2 "" "")))
14144 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14145 "TARGET_64BIT"
14146 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14147 [(set_attr "type" "multi")
14148 (set_attr "length" "12")])
14149
14150 (define_expand "tls_local_dynamic_base_64"
14151 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14152 (call (mem:QI (match_dup 1)) (const_int 0)))
14153 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14154 ""
14155 {
14156 operands[1] = ix86_tls_get_addr ();
14157 })
14158
14159 ;; Local dynamic of a single variable is a lose. Show combine how
14160 ;; to convert that back to global dynamic.
14161
14162 (define_insn_and_split "*tls_local_dynamic_32_once"
14163 [(set (match_operand:SI 0 "register_operand" "=a")
14164 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14165 (match_operand:SI 2 "call_insn_operand" "")]
14166 UNSPEC_TLS_LD_BASE)
14167 (const:SI (unspec:SI
14168 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14169 UNSPEC_DTPOFF))))
14170 (clobber (match_scratch:SI 4 "=d"))
14171 (clobber (match_scratch:SI 5 "=c"))
14172 (clobber (reg:CC 17))]
14173 ""
14174 "#"
14175 ""
14176 [(parallel [(set (match_dup 0)
14177 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14178 UNSPEC_TLS_GD))
14179 (clobber (match_dup 4))
14180 (clobber (match_dup 5))
14181 (clobber (reg:CC 17))])]
14182 "")
14183
14184 ;; Load and add the thread base pointer from %gs:0.
14185
14186 (define_insn "*load_tp_si"
14187 [(set (match_operand:SI 0 "register_operand" "=r")
14188 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14189 "!TARGET_64BIT"
14190 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14191 [(set_attr "type" "imov")
14192 (set_attr "modrm" "0")
14193 (set_attr "length" "7")
14194 (set_attr "memory" "load")
14195 (set_attr "imm_disp" "false")])
14196
14197 (define_insn "*add_tp_si"
14198 [(set (match_operand:SI 0 "register_operand" "=r")
14199 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14200 (match_operand:SI 1 "register_operand" "0")))
14201 (clobber (reg:CC 17))]
14202 "!TARGET_64BIT"
14203 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14204 [(set_attr "type" "alu")
14205 (set_attr "modrm" "0")
14206 (set_attr "length" "7")
14207 (set_attr "memory" "load")
14208 (set_attr "imm_disp" "false")])
14209
14210 (define_insn "*load_tp_di"
14211 [(set (match_operand:DI 0 "register_operand" "=r")
14212 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14213 "TARGET_64BIT"
14214 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14215 [(set_attr "type" "imov")
14216 (set_attr "modrm" "0")
14217 (set_attr "length" "7")
14218 (set_attr "memory" "load")
14219 (set_attr "imm_disp" "false")])
14220
14221 (define_insn "*add_tp_di"
14222 [(set (match_operand:DI 0 "register_operand" "=r")
14223 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14224 (match_operand:DI 1 "register_operand" "0")))
14225 (clobber (reg:CC 17))]
14226 "TARGET_64BIT"
14227 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14228 [(set_attr "type" "alu")
14229 (set_attr "modrm" "0")
14230 (set_attr "length" "7")
14231 (set_attr "memory" "load")
14232 (set_attr "imm_disp" "false")])
14233 \f
14234 ;; These patterns match the binary 387 instructions for addM3, subM3,
14235 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14236 ;; SFmode. The first is the normal insn, the second the same insn but
14237 ;; with one operand a conversion, and the third the same insn but with
14238 ;; the other operand a conversion. The conversion may be SFmode or
14239 ;; SImode if the target mode DFmode, but only SImode if the target mode
14240 ;; is SFmode.
14241
14242 ;; Gcc is slightly more smart about handling normal two address instructions
14243 ;; so use special patterns for add and mull.
14244 (define_insn "*fop_sf_comm_nosse"
14245 [(set (match_operand:SF 0 "register_operand" "=f")
14246 (match_operator:SF 3 "binary_fp_operator"
14247 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14248 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14249 "TARGET_80387 && !TARGET_SSE_MATH
14250 && COMMUTATIVE_ARITH_P (operands[3])
14251 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14252 "* return output_387_binary_op (insn, operands);"
14253 [(set (attr "type")
14254 (if_then_else (match_operand:SF 3 "mult_operator" "")
14255 (const_string "fmul")
14256 (const_string "fop")))
14257 (set_attr "mode" "SF")])
14258
14259 (define_insn "*fop_sf_comm"
14260 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14261 (match_operator:SF 3 "binary_fp_operator"
14262 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14263 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14264 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14265 && COMMUTATIVE_ARITH_P (operands[3])
14266 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14267 "* return output_387_binary_op (insn, operands);"
14268 [(set (attr "type")
14269 (if_then_else (eq_attr "alternative" "1")
14270 (if_then_else (match_operand:SF 3 "mult_operator" "")
14271 (const_string "ssemul")
14272 (const_string "sseadd"))
14273 (if_then_else (match_operand:SF 3 "mult_operator" "")
14274 (const_string "fmul")
14275 (const_string "fop"))))
14276 (set_attr "mode" "SF")])
14277
14278 (define_insn "*fop_sf_comm_sse"
14279 [(set (match_operand:SF 0 "register_operand" "=x")
14280 (match_operator:SF 3 "binary_fp_operator"
14281 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14282 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14283 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14284 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14285 "* return output_387_binary_op (insn, operands);"
14286 [(set (attr "type")
14287 (if_then_else (match_operand:SF 3 "mult_operator" "")
14288 (const_string "ssemul")
14289 (const_string "sseadd")))
14290 (set_attr "mode" "SF")])
14291
14292 (define_insn "*fop_df_comm_nosse"
14293 [(set (match_operand:DF 0 "register_operand" "=f")
14294 (match_operator:DF 3 "binary_fp_operator"
14295 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14296 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14297 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14298 && COMMUTATIVE_ARITH_P (operands[3])
14299 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14300 "* return output_387_binary_op (insn, operands);"
14301 [(set (attr "type")
14302 (if_then_else (match_operand:SF 3 "mult_operator" "")
14303 (const_string "fmul")
14304 (const_string "fop")))
14305 (set_attr "mode" "DF")])
14306
14307 (define_insn "*fop_df_comm"
14308 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14309 (match_operator:DF 3 "binary_fp_operator"
14310 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14311 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14312 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14313 && COMMUTATIVE_ARITH_P (operands[3])
14314 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14315 "* return output_387_binary_op (insn, operands);"
14316 [(set (attr "type")
14317 (if_then_else (eq_attr "alternative" "1")
14318 (if_then_else (match_operand:SF 3 "mult_operator" "")
14319 (const_string "ssemul")
14320 (const_string "sseadd"))
14321 (if_then_else (match_operand:SF 3 "mult_operator" "")
14322 (const_string "fmul")
14323 (const_string "fop"))))
14324 (set_attr "mode" "DF")])
14325
14326 (define_insn "*fop_df_comm_sse"
14327 [(set (match_operand:DF 0 "register_operand" "=Y")
14328 (match_operator:DF 3 "binary_fp_operator"
14329 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14330 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14331 "TARGET_SSE2 && TARGET_SSE_MATH
14332 && COMMUTATIVE_ARITH_P (operands[3])
14333 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14334 "* return output_387_binary_op (insn, operands);"
14335 [(set (attr "type")
14336 (if_then_else (match_operand:SF 3 "mult_operator" "")
14337 (const_string "ssemul")
14338 (const_string "sseadd")))
14339 (set_attr "mode" "DF")])
14340
14341 (define_insn "*fop_xf_comm"
14342 [(set (match_operand:XF 0 "register_operand" "=f")
14343 (match_operator:XF 3 "binary_fp_operator"
14344 [(match_operand:XF 1 "register_operand" "%0")
14345 (match_operand:XF 2 "register_operand" "f")]))]
14346 "TARGET_80387
14347 && COMMUTATIVE_ARITH_P (operands[3])"
14348 "* return output_387_binary_op (insn, operands);"
14349 [(set (attr "type")
14350 (if_then_else (match_operand:XF 3 "mult_operator" "")
14351 (const_string "fmul")
14352 (const_string "fop")))
14353 (set_attr "mode" "XF")])
14354
14355 (define_insn "*fop_sf_1_nosse"
14356 [(set (match_operand:SF 0 "register_operand" "=f,f")
14357 (match_operator:SF 3 "binary_fp_operator"
14358 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14359 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14360 "TARGET_80387 && !TARGET_SSE_MATH
14361 && !COMMUTATIVE_ARITH_P (operands[3])
14362 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14363 "* return output_387_binary_op (insn, operands);"
14364 [(set (attr "type")
14365 (cond [(match_operand:SF 3 "mult_operator" "")
14366 (const_string "fmul")
14367 (match_operand:SF 3 "div_operator" "")
14368 (const_string "fdiv")
14369 ]
14370 (const_string "fop")))
14371 (set_attr "mode" "SF")])
14372
14373 (define_insn "*fop_sf_1"
14374 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14375 (match_operator:SF 3 "binary_fp_operator"
14376 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14377 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14378 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14379 && !COMMUTATIVE_ARITH_P (operands[3])
14380 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14381 "* return output_387_binary_op (insn, operands);"
14382 [(set (attr "type")
14383 (cond [(and (eq_attr "alternative" "2")
14384 (match_operand:SF 3 "mult_operator" ""))
14385 (const_string "ssemul")
14386 (and (eq_attr "alternative" "2")
14387 (match_operand:SF 3 "div_operator" ""))
14388 (const_string "ssediv")
14389 (eq_attr "alternative" "2")
14390 (const_string "sseadd")
14391 (match_operand:SF 3 "mult_operator" "")
14392 (const_string "fmul")
14393 (match_operand:SF 3 "div_operator" "")
14394 (const_string "fdiv")
14395 ]
14396 (const_string "fop")))
14397 (set_attr "mode" "SF")])
14398
14399 (define_insn "*fop_sf_1_sse"
14400 [(set (match_operand:SF 0 "register_operand" "=x")
14401 (match_operator:SF 3 "binary_fp_operator"
14402 [(match_operand:SF 1 "register_operand" "0")
14403 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14404 "TARGET_SSE_MATH
14405 && !COMMUTATIVE_ARITH_P (operands[3])"
14406 "* return output_387_binary_op (insn, operands);"
14407 [(set (attr "type")
14408 (cond [(match_operand:SF 3 "mult_operator" "")
14409 (const_string "ssemul")
14410 (match_operand:SF 3 "div_operator" "")
14411 (const_string "ssediv")
14412 ]
14413 (const_string "sseadd")))
14414 (set_attr "mode" "SF")])
14415
14416 ;; ??? Add SSE splitters for these!
14417 (define_insn "*fop_sf_2"
14418 [(set (match_operand:SF 0 "register_operand" "=f,f")
14419 (match_operator:SF 3 "binary_fp_operator"
14420 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14421 (match_operand:SF 2 "register_operand" "0,0")]))]
14422 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14423 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14424 [(set (attr "type")
14425 (cond [(match_operand:SF 3 "mult_operator" "")
14426 (const_string "fmul")
14427 (match_operand:SF 3 "div_operator" "")
14428 (const_string "fdiv")
14429 ]
14430 (const_string "fop")))
14431 (set_attr "fp_int_src" "true")
14432 (set_attr "mode" "SI")])
14433
14434 (define_insn "*fop_sf_3"
14435 [(set (match_operand:SF 0 "register_operand" "=f,f")
14436 (match_operator:SF 3 "binary_fp_operator"
14437 [(match_operand:SF 1 "register_operand" "0,0")
14438 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14439 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14440 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14441 [(set (attr "type")
14442 (cond [(match_operand:SF 3 "mult_operator" "")
14443 (const_string "fmul")
14444 (match_operand:SF 3 "div_operator" "")
14445 (const_string "fdiv")
14446 ]
14447 (const_string "fop")))
14448 (set_attr "fp_int_src" "true")
14449 (set_attr "mode" "SI")])
14450
14451 (define_insn "*fop_df_1_nosse"
14452 [(set (match_operand:DF 0 "register_operand" "=f,f")
14453 (match_operator:DF 3 "binary_fp_operator"
14454 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14455 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14456 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14457 && !COMMUTATIVE_ARITH_P (operands[3])
14458 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14459 "* return output_387_binary_op (insn, operands);"
14460 [(set (attr "type")
14461 (cond [(match_operand:DF 3 "mult_operator" "")
14462 (const_string "fmul")
14463 (match_operand:DF 3 "div_operator" "")
14464 (const_string "fdiv")
14465 ]
14466 (const_string "fop")))
14467 (set_attr "mode" "DF")])
14468
14469
14470 (define_insn "*fop_df_1"
14471 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14472 (match_operator:DF 3 "binary_fp_operator"
14473 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14474 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14475 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14476 && !COMMUTATIVE_ARITH_P (operands[3])
14477 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14478 "* return output_387_binary_op (insn, operands);"
14479 [(set (attr "type")
14480 (cond [(and (eq_attr "alternative" "2")
14481 (match_operand:SF 3 "mult_operator" ""))
14482 (const_string "ssemul")
14483 (and (eq_attr "alternative" "2")
14484 (match_operand:SF 3 "div_operator" ""))
14485 (const_string "ssediv")
14486 (eq_attr "alternative" "2")
14487 (const_string "sseadd")
14488 (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 (define_insn "*fop_df_1_sse"
14497 [(set (match_operand:DF 0 "register_operand" "=Y")
14498 (match_operator:DF 3 "binary_fp_operator"
14499 [(match_operand:DF 1 "register_operand" "0")
14500 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14501 "TARGET_SSE2 && TARGET_SSE_MATH
14502 && !COMMUTATIVE_ARITH_P (operands[3])"
14503 "* return output_387_binary_op (insn, operands);"
14504 [(set_attr "mode" "DF")
14505 (set (attr "type")
14506 (cond [(match_operand:SF 3 "mult_operator" "")
14507 (const_string "ssemul")
14508 (match_operand:SF 3 "div_operator" "")
14509 (const_string "ssediv")
14510 ]
14511 (const_string "sseadd")))])
14512
14513 ;; ??? Add SSE splitters for these!
14514 (define_insn "*fop_df_2"
14515 [(set (match_operand:DF 0 "register_operand" "=f,f")
14516 (match_operator:DF 3 "binary_fp_operator"
14517 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14518 (match_operand:DF 2 "register_operand" "0,0")]))]
14519 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14520 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14521 [(set (attr "type")
14522 (cond [(match_operand:DF 3 "mult_operator" "")
14523 (const_string "fmul")
14524 (match_operand:DF 3 "div_operator" "")
14525 (const_string "fdiv")
14526 ]
14527 (const_string "fop")))
14528 (set_attr "fp_int_src" "true")
14529 (set_attr "mode" "SI")])
14530
14531 (define_insn "*fop_df_3"
14532 [(set (match_operand:DF 0 "register_operand" "=f,f")
14533 (match_operator:DF 3 "binary_fp_operator"
14534 [(match_operand:DF 1 "register_operand" "0,0")
14535 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14536 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14537 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14538 [(set (attr "type")
14539 (cond [(match_operand:DF 3 "mult_operator" "")
14540 (const_string "fmul")
14541 (match_operand:DF 3 "div_operator" "")
14542 (const_string "fdiv")
14543 ]
14544 (const_string "fop")))
14545 (set_attr "fp_int_src" "true")
14546 (set_attr "mode" "SI")])
14547
14548 (define_insn "*fop_df_4"
14549 [(set (match_operand:DF 0 "register_operand" "=f,f")
14550 (match_operator:DF 3 "binary_fp_operator"
14551 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14552 (match_operand:DF 2 "register_operand" "0,f")]))]
14553 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14554 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14555 "* return output_387_binary_op (insn, operands);"
14556 [(set (attr "type")
14557 (cond [(match_operand:DF 3 "mult_operator" "")
14558 (const_string "fmul")
14559 (match_operand:DF 3 "div_operator" "")
14560 (const_string "fdiv")
14561 ]
14562 (const_string "fop")))
14563 (set_attr "mode" "SF")])
14564
14565 (define_insn "*fop_df_5"
14566 [(set (match_operand:DF 0 "register_operand" "=f,f")
14567 (match_operator:DF 3 "binary_fp_operator"
14568 [(match_operand:DF 1 "register_operand" "0,f")
14569 (float_extend:DF
14570 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14571 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14572 "* return output_387_binary_op (insn, operands);"
14573 [(set (attr "type")
14574 (cond [(match_operand:DF 3 "mult_operator" "")
14575 (const_string "fmul")
14576 (match_operand:DF 3 "div_operator" "")
14577 (const_string "fdiv")
14578 ]
14579 (const_string "fop")))
14580 (set_attr "mode" "SF")])
14581
14582 (define_insn "*fop_df_6"
14583 [(set (match_operand:DF 0 "register_operand" "=f,f")
14584 (match_operator:DF 3 "binary_fp_operator"
14585 [(float_extend:DF
14586 (match_operand:SF 1 "register_operand" "0,f"))
14587 (float_extend:DF
14588 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14589 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14590 "* return output_387_binary_op (insn, operands);"
14591 [(set (attr "type")
14592 (cond [(match_operand:DF 3 "mult_operator" "")
14593 (const_string "fmul")
14594 (match_operand:DF 3 "div_operator" "")
14595 (const_string "fdiv")
14596 ]
14597 (const_string "fop")))
14598 (set_attr "mode" "SF")])
14599
14600 (define_insn "*fop_xf_1"
14601 [(set (match_operand:XF 0 "register_operand" "=f,f")
14602 (match_operator:XF 3 "binary_fp_operator"
14603 [(match_operand:XF 1 "register_operand" "0,f")
14604 (match_operand:XF 2 "register_operand" "f,0")]))]
14605 "TARGET_80387
14606 && !COMMUTATIVE_ARITH_P (operands[3])"
14607 "* return output_387_binary_op (insn, operands);"
14608 [(set (attr "type")
14609 (cond [(match_operand:XF 3 "mult_operator" "")
14610 (const_string "fmul")
14611 (match_operand:XF 3 "div_operator" "")
14612 (const_string "fdiv")
14613 ]
14614 (const_string "fop")))
14615 (set_attr "mode" "XF")])
14616
14617 (define_insn "*fop_xf_2"
14618 [(set (match_operand:XF 0 "register_operand" "=f,f")
14619 (match_operator:XF 3 "binary_fp_operator"
14620 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14621 (match_operand:XF 2 "register_operand" "0,0")]))]
14622 "TARGET_80387 && TARGET_USE_FIOP"
14623 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14624 [(set (attr "type")
14625 (cond [(match_operand:XF 3 "mult_operator" "")
14626 (const_string "fmul")
14627 (match_operand:XF 3 "div_operator" "")
14628 (const_string "fdiv")
14629 ]
14630 (const_string "fop")))
14631 (set_attr "fp_int_src" "true")
14632 (set_attr "mode" "SI")])
14633
14634 (define_insn "*fop_xf_3"
14635 [(set (match_operand:XF 0 "register_operand" "=f,f")
14636 (match_operator:XF 3 "binary_fp_operator"
14637 [(match_operand:XF 1 "register_operand" "0,0")
14638 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14639 "TARGET_80387 && TARGET_USE_FIOP"
14640 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14641 [(set (attr "type")
14642 (cond [(match_operand:XF 3 "mult_operator" "")
14643 (const_string "fmul")
14644 (match_operand:XF 3 "div_operator" "")
14645 (const_string "fdiv")
14646 ]
14647 (const_string "fop")))
14648 (set_attr "fp_int_src" "true")
14649 (set_attr "mode" "SI")])
14650
14651 (define_insn "*fop_xf_4"
14652 [(set (match_operand:XF 0 "register_operand" "=f,f")
14653 (match_operator:XF 3 "binary_fp_operator"
14654 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14655 (match_operand:XF 2 "register_operand" "0,f")]))]
14656 "TARGET_80387"
14657 "* return output_387_binary_op (insn, operands);"
14658 [(set (attr "type")
14659 (cond [(match_operand:XF 3 "mult_operator" "")
14660 (const_string "fmul")
14661 (match_operand:XF 3 "div_operator" "")
14662 (const_string "fdiv")
14663 ]
14664 (const_string "fop")))
14665 (set_attr "mode" "SF")])
14666
14667 (define_insn "*fop_xf_5"
14668 [(set (match_operand:XF 0 "register_operand" "=f,f")
14669 (match_operator:XF 3 "binary_fp_operator"
14670 [(match_operand:XF 1 "register_operand" "0,f")
14671 (float_extend:XF
14672 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14673 "TARGET_80387"
14674 "* return output_387_binary_op (insn, operands);"
14675 [(set (attr "type")
14676 (cond [(match_operand:XF 3 "mult_operator" "")
14677 (const_string "fmul")
14678 (match_operand:XF 3 "div_operator" "")
14679 (const_string "fdiv")
14680 ]
14681 (const_string "fop")))
14682 (set_attr "mode" "SF")])
14683
14684 (define_insn "*fop_xf_6"
14685 [(set (match_operand:XF 0 "register_operand" "=f,f")
14686 (match_operator:XF 3 "binary_fp_operator"
14687 [(float_extend:XF
14688 (match_operand 1 "register_operand" "0,f"))
14689 (float_extend:XF
14690 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14691 "TARGET_80387"
14692 "* return output_387_binary_op (insn, operands);"
14693 [(set (attr "type")
14694 (cond [(match_operand:XF 3 "mult_operator" "")
14695 (const_string "fmul")
14696 (match_operand:XF 3 "div_operator" "")
14697 (const_string "fdiv")
14698 ]
14699 (const_string "fop")))
14700 (set_attr "mode" "SF")])
14701
14702 (define_split
14703 [(set (match_operand 0 "register_operand" "")
14704 (match_operator 3 "binary_fp_operator"
14705 [(float (match_operand:SI 1 "register_operand" ""))
14706 (match_operand 2 "register_operand" "")]))]
14707 "TARGET_80387 && reload_completed
14708 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14709 [(const_int 0)]
14710 {
14711 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14712 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14713 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14714 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14715 GET_MODE (operands[3]),
14716 operands[4],
14717 operands[2])));
14718 ix86_free_from_memory (GET_MODE (operands[1]));
14719 DONE;
14720 })
14721
14722 (define_split
14723 [(set (match_operand 0 "register_operand" "")
14724 (match_operator 3 "binary_fp_operator"
14725 [(match_operand 1 "register_operand" "")
14726 (float (match_operand:SI 2 "register_operand" ""))]))]
14727 "TARGET_80387 && reload_completed
14728 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14729 [(const_int 0)]
14730 {
14731 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14732 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14733 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14734 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14735 GET_MODE (operands[3]),
14736 operands[1],
14737 operands[4])));
14738 ix86_free_from_memory (GET_MODE (operands[2]));
14739 DONE;
14740 })
14741 \f
14742 ;; FPU special functions.
14743
14744 (define_expand "sqrtsf2"
14745 [(set (match_operand:SF 0 "register_operand" "")
14746 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14747 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14748 {
14749 if (!TARGET_SSE_MATH)
14750 operands[1] = force_reg (SFmode, operands[1]);
14751 })
14752
14753 (define_insn "sqrtsf2_1"
14754 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14755 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14756 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14757 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14758 "@
14759 fsqrt
14760 sqrtss\t{%1, %0|%0, %1}"
14761 [(set_attr "type" "fpspc,sse")
14762 (set_attr "mode" "SF,SF")
14763 (set_attr "athlon_decode" "direct,*")])
14764
14765 (define_insn "sqrtsf2_1_sse_only"
14766 [(set (match_operand:SF 0 "register_operand" "=x")
14767 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14768 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14769 "sqrtss\t{%1, %0|%0, %1}"
14770 [(set_attr "type" "sse")
14771 (set_attr "mode" "SF")
14772 (set_attr "athlon_decode" "*")])
14773
14774 (define_insn "sqrtsf2_i387"
14775 [(set (match_operand:SF 0 "register_operand" "=f")
14776 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14777 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14778 && !TARGET_SSE_MATH"
14779 "fsqrt"
14780 [(set_attr "type" "fpspc")
14781 (set_attr "mode" "SF")
14782 (set_attr "athlon_decode" "direct")])
14783
14784 (define_expand "sqrtdf2"
14785 [(set (match_operand:DF 0 "register_operand" "")
14786 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14787 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14788 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14789 {
14790 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14791 operands[1] = force_reg (DFmode, operands[1]);
14792 })
14793
14794 (define_insn "sqrtdf2_1"
14795 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14796 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14797 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14798 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14799 "@
14800 fsqrt
14801 sqrtsd\t{%1, %0|%0, %1}"
14802 [(set_attr "type" "fpspc,sse")
14803 (set_attr "mode" "DF,DF")
14804 (set_attr "athlon_decode" "direct,*")])
14805
14806 (define_insn "sqrtdf2_1_sse_only"
14807 [(set (match_operand:DF 0 "register_operand" "=Y")
14808 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14809 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14810 "sqrtsd\t{%1, %0|%0, %1}"
14811 [(set_attr "type" "sse")
14812 (set_attr "mode" "DF")
14813 (set_attr "athlon_decode" "*")])
14814
14815 (define_insn "sqrtdf2_i387"
14816 [(set (match_operand:DF 0 "register_operand" "=f")
14817 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14818 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14819 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14820 "fsqrt"
14821 [(set_attr "type" "fpspc")
14822 (set_attr "mode" "DF")
14823 (set_attr "athlon_decode" "direct")])
14824
14825 (define_insn "*sqrtextendsfdf2"
14826 [(set (match_operand:DF 0 "register_operand" "=f")
14827 (sqrt:DF (float_extend:DF
14828 (match_operand:SF 1 "register_operand" "0"))))]
14829 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14830 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14831 "fsqrt"
14832 [(set_attr "type" "fpspc")
14833 (set_attr "mode" "DF")
14834 (set_attr "athlon_decode" "direct")])
14835
14836 (define_insn "sqrtxf2"
14837 [(set (match_operand:XF 0 "register_operand" "=f")
14838 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14839 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14840 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14841 "fsqrt"
14842 [(set_attr "type" "fpspc")
14843 (set_attr "mode" "XF")
14844 (set_attr "athlon_decode" "direct")])
14845
14846 (define_insn "*sqrtextenddfxf2"
14847 [(set (match_operand:XF 0 "register_operand" "=f")
14848 (sqrt:XF (float_extend:XF
14849 (match_operand:DF 1 "register_operand" "0"))))]
14850 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14851 "fsqrt"
14852 [(set_attr "type" "fpspc")
14853 (set_attr "mode" "XF")
14854 (set_attr "athlon_decode" "direct")])
14855
14856 (define_insn "*sqrtextendsfxf2"
14857 [(set (match_operand:XF 0 "register_operand" "=f")
14858 (sqrt:XF (float_extend:XF
14859 (match_operand:SF 1 "register_operand" "0"))))]
14860 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14861 "fsqrt"
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "XF")
14864 (set_attr "athlon_decode" "direct")])
14865
14866 (define_insn "fpremxf4"
14867 [(set (match_operand:XF 0 "register_operand" "=f")
14868 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14869 (match_operand:XF 3 "register_operand" "1")]
14870 UNSPEC_FPREM_F))
14871 (set (match_operand:XF 1 "register_operand" "=u")
14872 (unspec:XF [(match_dup 2) (match_dup 3)]
14873 UNSPEC_FPREM_U))
14874 (set (reg:CCFP 18)
14875 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14876 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14877 && flag_unsafe_math_optimizations"
14878 "fprem"
14879 [(set_attr "type" "fpspc")
14880 (set_attr "mode" "XF")])
14881
14882 (define_expand "fmodsf3"
14883 [(use (match_operand:SF 0 "register_operand" ""))
14884 (use (match_operand:SF 1 "register_operand" ""))
14885 (use (match_operand:SF 2 "register_operand" ""))]
14886 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14887 && flag_unsafe_math_optimizations"
14888 {
14889 rtx label = gen_label_rtx ();
14890
14891 rtx op1 = gen_reg_rtx (XFmode);
14892 rtx op2 = gen_reg_rtx (XFmode);
14893
14894 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14895 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14896
14897 emit_label (label);
14898
14899 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14900 ix86_emit_fp_unordered_jump (label);
14901
14902 emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14903 DONE;
14904 })
14905
14906 (define_expand "fmoddf3"
14907 [(use (match_operand:DF 0 "register_operand" ""))
14908 (use (match_operand:DF 1 "register_operand" ""))
14909 (use (match_operand:DF 2 "register_operand" ""))]
14910 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14911 && flag_unsafe_math_optimizations"
14912 {
14913 rtx label = gen_label_rtx ();
14914
14915 rtx op1 = gen_reg_rtx (XFmode);
14916 rtx op2 = gen_reg_rtx (XFmode);
14917
14918 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14919 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14920
14921 emit_label (label);
14922
14923 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14924 ix86_emit_fp_unordered_jump (label);
14925
14926 emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14927 DONE;
14928 })
14929
14930 (define_expand "fmodxf3"
14931 [(use (match_operand:XF 0 "register_operand" ""))
14932 (use (match_operand:XF 1 "register_operand" ""))
14933 (use (match_operand:XF 2 "register_operand" ""))]
14934 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14935 && flag_unsafe_math_optimizations"
14936 {
14937 rtx label = gen_label_rtx ();
14938
14939 emit_label (label);
14940
14941 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14942 operands[1], operands[2]));
14943 ix86_emit_fp_unordered_jump (label);
14944
14945 emit_move_insn (operands[0], operands[1]);
14946 DONE;
14947 })
14948
14949 (define_insn "fprem1xf4"
14950 [(set (match_operand:XF 0 "register_operand" "=f")
14951 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14952 (match_operand:XF 3 "register_operand" "1")]
14953 UNSPEC_FPREM1_F))
14954 (set (match_operand:XF 1 "register_operand" "=u")
14955 (unspec:XF [(match_dup 2) (match_dup 3)]
14956 UNSPEC_FPREM1_U))
14957 (set (reg:CCFP 18)
14958 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14959 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14960 && flag_unsafe_math_optimizations"
14961 "fprem1"
14962 [(set_attr "type" "fpspc")
14963 (set_attr "mode" "XF")])
14964
14965 (define_expand "dremsf3"
14966 [(use (match_operand:SF 0 "register_operand" ""))
14967 (use (match_operand:SF 1 "register_operand" ""))
14968 (use (match_operand:SF 2 "register_operand" ""))]
14969 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14970 && flag_unsafe_math_optimizations"
14971 {
14972 rtx label = gen_label_rtx ();
14973
14974 rtx op1 = gen_reg_rtx (XFmode);
14975 rtx op2 = gen_reg_rtx (XFmode);
14976
14977 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14978 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14979
14980 emit_label (label);
14981
14982 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14983 ix86_emit_fp_unordered_jump (label);
14984
14985 emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14986 DONE;
14987 })
14988
14989 (define_expand "dremdf3"
14990 [(use (match_operand:DF 0 "register_operand" ""))
14991 (use (match_operand:DF 1 "register_operand" ""))
14992 (use (match_operand:DF 2 "register_operand" ""))]
14993 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14994 && flag_unsafe_math_optimizations"
14995 {
14996 rtx label = gen_label_rtx ();
14997
14998 rtx op1 = gen_reg_rtx (XFmode);
14999 rtx op2 = gen_reg_rtx (XFmode);
15000
15001 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15002 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15003
15004 emit_label (label);
15005
15006 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15007 ix86_emit_fp_unordered_jump (label);
15008
15009 emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15010 DONE;
15011 })
15012
15013 (define_expand "dremxf3"
15014 [(use (match_operand:XF 0 "register_operand" ""))
15015 (use (match_operand:XF 1 "register_operand" ""))
15016 (use (match_operand:XF 2 "register_operand" ""))]
15017 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15018 && flag_unsafe_math_optimizations"
15019 {
15020 rtx label = gen_label_rtx ();
15021
15022 emit_label (label);
15023
15024 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15025 operands[1], operands[2]));
15026 ix86_emit_fp_unordered_jump (label);
15027
15028 emit_move_insn (operands[0], operands[1]);
15029 DONE;
15030 })
15031
15032 (define_insn "*sindf2"
15033 [(set (match_operand:DF 0 "register_operand" "=f")
15034 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15035 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15036 && flag_unsafe_math_optimizations"
15037 "fsin"
15038 [(set_attr "type" "fpspc")
15039 (set_attr "mode" "DF")])
15040
15041 (define_insn "*sinsf2"
15042 [(set (match_operand:SF 0 "register_operand" "=f")
15043 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15044 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15045 && flag_unsafe_math_optimizations"
15046 "fsin"
15047 [(set_attr "type" "fpspc")
15048 (set_attr "mode" "SF")])
15049
15050 (define_insn "*sinextendsfdf2"
15051 [(set (match_operand:DF 0 "register_operand" "=f")
15052 (unspec:DF [(float_extend:DF
15053 (match_operand:SF 1 "register_operand" "0"))]
15054 UNSPEC_SIN))]
15055 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15056 && flag_unsafe_math_optimizations"
15057 "fsin"
15058 [(set_attr "type" "fpspc")
15059 (set_attr "mode" "DF")])
15060
15061 (define_insn "*sinxf2"
15062 [(set (match_operand:XF 0 "register_operand" "=f")
15063 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15064 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15065 && flag_unsafe_math_optimizations"
15066 "fsin"
15067 [(set_attr "type" "fpspc")
15068 (set_attr "mode" "XF")])
15069
15070 (define_insn "*cosdf2"
15071 [(set (match_operand:DF 0 "register_operand" "=f")
15072 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15073 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15074 && flag_unsafe_math_optimizations"
15075 "fcos"
15076 [(set_attr "type" "fpspc")
15077 (set_attr "mode" "DF")])
15078
15079 (define_insn "*cossf2"
15080 [(set (match_operand:SF 0 "register_operand" "=f")
15081 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15082 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15083 && flag_unsafe_math_optimizations"
15084 "fcos"
15085 [(set_attr "type" "fpspc")
15086 (set_attr "mode" "SF")])
15087
15088 (define_insn "*cosextendsfdf2"
15089 [(set (match_operand:DF 0 "register_operand" "=f")
15090 (unspec:DF [(float_extend:DF
15091 (match_operand:SF 1 "register_operand" "0"))]
15092 UNSPEC_COS))]
15093 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15094 && flag_unsafe_math_optimizations"
15095 "fcos"
15096 [(set_attr "type" "fpspc")
15097 (set_attr "mode" "DF")])
15098
15099 (define_insn "*cosxf2"
15100 [(set (match_operand:XF 0 "register_operand" "=f")
15101 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15102 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15103 && flag_unsafe_math_optimizations"
15104 "fcos"
15105 [(set_attr "type" "fpspc")
15106 (set_attr "mode" "XF")])
15107
15108 ;; With sincos pattern defined, sin and cos builtin function will be
15109 ;; expanded to sincos pattern with one of its outputs left unused.
15110 ;; Cse pass will detected, if two sincos patterns can be combined,
15111 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15112 ;; depending on the unused output.
15113
15114 (define_insn "sincosdf3"
15115 [(set (match_operand:DF 0 "register_operand" "=f")
15116 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15117 UNSPEC_SINCOS_COS))
15118 (set (match_operand:DF 1 "register_operand" "=u")
15119 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15120 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15121 && flag_unsafe_math_optimizations"
15122 "fsincos"
15123 [(set_attr "type" "fpspc")
15124 (set_attr "mode" "DF")])
15125
15126 (define_split
15127 [(set (match_operand:DF 0 "register_operand" "")
15128 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15129 UNSPEC_SINCOS_COS))
15130 (set (match_operand:DF 1 "register_operand" "")
15131 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15132 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15133 && !reload_completed && !reload_in_progress"
15134 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15135 "")
15136
15137 (define_split
15138 [(set (match_operand:DF 0 "register_operand" "")
15139 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15140 UNSPEC_SINCOS_COS))
15141 (set (match_operand:DF 1 "register_operand" "")
15142 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15143 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15144 && !reload_completed && !reload_in_progress"
15145 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15146 "")
15147
15148 (define_insn "sincossf3"
15149 [(set (match_operand:SF 0 "register_operand" "=f")
15150 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15151 UNSPEC_SINCOS_COS))
15152 (set (match_operand:SF 1 "register_operand" "=u")
15153 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15154 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15155 && flag_unsafe_math_optimizations"
15156 "fsincos"
15157 [(set_attr "type" "fpspc")
15158 (set_attr "mode" "SF")])
15159
15160 (define_split
15161 [(set (match_operand:SF 0 "register_operand" "")
15162 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15163 UNSPEC_SINCOS_COS))
15164 (set (match_operand:SF 1 "register_operand" "")
15165 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15166 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15167 && !reload_completed && !reload_in_progress"
15168 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15169 "")
15170
15171 (define_split
15172 [(set (match_operand:SF 0 "register_operand" "")
15173 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15174 UNSPEC_SINCOS_COS))
15175 (set (match_operand:SF 1 "register_operand" "")
15176 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15177 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15178 && !reload_completed && !reload_in_progress"
15179 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15180 "")
15181
15182 (define_insn "*sincosextendsfdf3"
15183 [(set (match_operand:DF 0 "register_operand" "=f")
15184 (unspec:DF [(float_extend:DF
15185 (match_operand:SF 2 "register_operand" "0"))]
15186 UNSPEC_SINCOS_COS))
15187 (set (match_operand:DF 1 "register_operand" "=u")
15188 (unspec:DF [(float_extend:DF
15189 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15190 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15191 && flag_unsafe_math_optimizations"
15192 "fsincos"
15193 [(set_attr "type" "fpspc")
15194 (set_attr "mode" "DF")])
15195
15196 (define_split
15197 [(set (match_operand:DF 0 "register_operand" "")
15198 (unspec:DF [(float_extend:DF
15199 (match_operand:SF 2 "register_operand" ""))]
15200 UNSPEC_SINCOS_COS))
15201 (set (match_operand:DF 1 "register_operand" "")
15202 (unspec:DF [(float_extend:DF
15203 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15204 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15205 && !reload_completed && !reload_in_progress"
15206 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15207 (match_dup 2))] UNSPEC_SIN))]
15208 "")
15209
15210 (define_split
15211 [(set (match_operand:DF 0 "register_operand" "")
15212 (unspec:DF [(float_extend:DF
15213 (match_operand:SF 2 "register_operand" ""))]
15214 UNSPEC_SINCOS_COS))
15215 (set (match_operand:DF 1 "register_operand" "")
15216 (unspec:DF [(float_extend:DF
15217 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15218 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15219 && !reload_completed && !reload_in_progress"
15220 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15221 (match_dup 2))] UNSPEC_COS))]
15222 "")
15223
15224 (define_insn "sincosxf3"
15225 [(set (match_operand:XF 0 "register_operand" "=f")
15226 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15227 UNSPEC_SINCOS_COS))
15228 (set (match_operand:XF 1 "register_operand" "=u")
15229 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15230 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15231 && flag_unsafe_math_optimizations"
15232 "fsincos"
15233 [(set_attr "type" "fpspc")
15234 (set_attr "mode" "XF")])
15235
15236 (define_split
15237 [(set (match_operand:XF 0 "register_operand" "")
15238 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15239 UNSPEC_SINCOS_COS))
15240 (set (match_operand:XF 1 "register_operand" "")
15241 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15242 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15243 && !reload_completed && !reload_in_progress"
15244 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15245 "")
15246
15247 (define_split
15248 [(set (match_operand:XF 0 "register_operand" "")
15249 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15250 UNSPEC_SINCOS_COS))
15251 (set (match_operand:XF 1 "register_operand" "")
15252 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15253 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15254 && !reload_completed && !reload_in_progress"
15255 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15256 "")
15257
15258 (define_insn "*tandf3_1"
15259 [(set (match_operand:DF 0 "register_operand" "=f")
15260 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15261 UNSPEC_TAN_ONE))
15262 (set (match_operand:DF 1 "register_operand" "=u")
15263 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15264 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15265 && flag_unsafe_math_optimizations"
15266 "fptan"
15267 [(set_attr "type" "fpspc")
15268 (set_attr "mode" "DF")])
15269
15270 ;; optimize sequence: fptan
15271 ;; fstp %st(0)
15272 ;; fld1
15273 ;; into fptan insn.
15274
15275 (define_peephole2
15276 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15277 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15278 UNSPEC_TAN_ONE))
15279 (set (match_operand:DF 1 "register_operand" "")
15280 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15281 (set (match_dup 0)
15282 (match_operand:DF 3 "immediate_operand" ""))]
15283 "standard_80387_constant_p (operands[3]) == 2"
15284 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15285 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15286 "")
15287
15288 (define_expand "tandf2"
15289 [(parallel [(set (match_dup 2)
15290 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15291 UNSPEC_TAN_ONE))
15292 (set (match_operand:DF 0 "register_operand" "")
15293 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15294 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15295 && flag_unsafe_math_optimizations"
15296 {
15297 operands[2] = gen_reg_rtx (DFmode);
15298 })
15299
15300 (define_insn "*tansf3_1"
15301 [(set (match_operand:SF 0 "register_operand" "=f")
15302 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15303 UNSPEC_TAN_ONE))
15304 (set (match_operand:SF 1 "register_operand" "=u")
15305 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15306 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15307 && flag_unsafe_math_optimizations"
15308 "fptan"
15309 [(set_attr "type" "fpspc")
15310 (set_attr "mode" "SF")])
15311
15312 ;; optimize sequence: fptan
15313 ;; fstp %st(0)
15314 ;; fld1
15315 ;; into fptan insn.
15316
15317 (define_peephole2
15318 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15319 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15320 UNSPEC_TAN_ONE))
15321 (set (match_operand:SF 1 "register_operand" "")
15322 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15323 (set (match_dup 0)
15324 (match_operand:SF 3 "immediate_operand" ""))]
15325 "standard_80387_constant_p (operands[3]) == 2"
15326 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15327 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15328 "")
15329
15330 (define_expand "tansf2"
15331 [(parallel [(set (match_dup 2)
15332 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15333 UNSPEC_TAN_ONE))
15334 (set (match_operand:SF 0 "register_operand" "")
15335 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15336 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15337 && flag_unsafe_math_optimizations"
15338 {
15339 operands[2] = gen_reg_rtx (SFmode);
15340 })
15341
15342 (define_insn "*tanxf3_1"
15343 [(set (match_operand:XF 0 "register_operand" "=f")
15344 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15345 UNSPEC_TAN_ONE))
15346 (set (match_operand:XF 1 "register_operand" "=u")
15347 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15348 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15349 && flag_unsafe_math_optimizations"
15350 "fptan"
15351 [(set_attr "type" "fpspc")
15352 (set_attr "mode" "XF")])
15353
15354 ;; optimize sequence: fptan
15355 ;; fstp %st(0)
15356 ;; fld1
15357 ;; into fptan insn.
15358
15359 (define_peephole2
15360 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15361 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15362 UNSPEC_TAN_ONE))
15363 (set (match_operand:XF 1 "register_operand" "")
15364 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15365 (set (match_dup 0)
15366 (match_operand:XF 3 "immediate_operand" ""))]
15367 "standard_80387_constant_p (operands[3]) == 2"
15368 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15369 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15370 "")
15371
15372 (define_expand "tanxf2"
15373 [(parallel [(set (match_dup 2)
15374 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15375 UNSPEC_TAN_ONE))
15376 (set (match_operand:XF 0 "register_operand" "")
15377 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15378 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15379 && flag_unsafe_math_optimizations"
15380 {
15381 operands[2] = gen_reg_rtx (XFmode);
15382 })
15383
15384 (define_insn "atan2df3_1"
15385 [(set (match_operand:DF 0 "register_operand" "=f")
15386 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15387 (match_operand:DF 1 "register_operand" "u")]
15388 UNSPEC_FPATAN))
15389 (clobber (match_scratch:DF 3 "=1"))]
15390 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15391 && flag_unsafe_math_optimizations"
15392 "fpatan"
15393 [(set_attr "type" "fpspc")
15394 (set_attr "mode" "DF")])
15395
15396 (define_expand "atan2df3"
15397 [(use (match_operand:DF 0 "register_operand" "=f"))
15398 (use (match_operand:DF 2 "register_operand" "0"))
15399 (use (match_operand:DF 1 "register_operand" "u"))]
15400 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15401 && flag_unsafe_math_optimizations"
15402 {
15403 rtx copy = gen_reg_rtx (DFmode);
15404 emit_move_insn (copy, operands[1]);
15405 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15406 DONE;
15407 })
15408
15409 (define_expand "atandf2"
15410 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15411 (unspec:DF [(match_dup 2)
15412 (match_operand:DF 1 "register_operand" "")]
15413 UNSPEC_FPATAN))
15414 (clobber (match_scratch:DF 3 ""))])]
15415 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15416 && flag_unsafe_math_optimizations"
15417 {
15418 operands[2] = gen_reg_rtx (DFmode);
15419 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15420 })
15421
15422 (define_insn "atan2sf3_1"
15423 [(set (match_operand:SF 0 "register_operand" "=f")
15424 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15425 (match_operand:SF 1 "register_operand" "u")]
15426 UNSPEC_FPATAN))
15427 (clobber (match_scratch:SF 3 "=1"))]
15428 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15429 && flag_unsafe_math_optimizations"
15430 "fpatan"
15431 [(set_attr "type" "fpspc")
15432 (set_attr "mode" "SF")])
15433
15434 (define_expand "atan2sf3"
15435 [(use (match_operand:SF 0 "register_operand" "=f"))
15436 (use (match_operand:SF 2 "register_operand" "0"))
15437 (use (match_operand:SF 1 "register_operand" "u"))]
15438 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15439 && flag_unsafe_math_optimizations"
15440 {
15441 rtx copy = gen_reg_rtx (SFmode);
15442 emit_move_insn (copy, operands[1]);
15443 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15444 DONE;
15445 })
15446
15447 (define_expand "atansf2"
15448 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15449 (unspec:SF [(match_dup 2)
15450 (match_operand:SF 1 "register_operand" "")]
15451 UNSPEC_FPATAN))
15452 (clobber (match_scratch:SF 3 ""))])]
15453 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15454 && flag_unsafe_math_optimizations"
15455 {
15456 operands[2] = gen_reg_rtx (SFmode);
15457 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15458 })
15459
15460 (define_insn "atan2xf3_1"
15461 [(set (match_operand:XF 0 "register_operand" "=f")
15462 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15463 (match_operand:XF 1 "register_operand" "u")]
15464 UNSPEC_FPATAN))
15465 (clobber (match_scratch:XF 3 "=1"))]
15466 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15467 && flag_unsafe_math_optimizations"
15468 "fpatan"
15469 [(set_attr "type" "fpspc")
15470 (set_attr "mode" "XF")])
15471
15472 (define_expand "atan2xf3"
15473 [(use (match_operand:XF 0 "register_operand" "=f"))
15474 (use (match_operand:XF 2 "register_operand" "0"))
15475 (use (match_operand:XF 1 "register_operand" "u"))]
15476 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15477 && flag_unsafe_math_optimizations"
15478 {
15479 rtx copy = gen_reg_rtx (XFmode);
15480 emit_move_insn (copy, operands[1]);
15481 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15482 DONE;
15483 })
15484
15485 (define_expand "atanxf2"
15486 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15487 (unspec:XF [(match_dup 2)
15488 (match_operand:XF 1 "register_operand" "")]
15489 UNSPEC_FPATAN))
15490 (clobber (match_scratch:XF 3 ""))])]
15491 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15492 && flag_unsafe_math_optimizations"
15493 {
15494 operands[2] = gen_reg_rtx (XFmode);
15495 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15496 })
15497
15498 (define_expand "asindf2"
15499 [(set (match_dup 2)
15500 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15501 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15502 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15503 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15504 (parallel [(set (match_dup 7)
15505 (unspec:XF [(match_dup 6) (match_dup 2)]
15506 UNSPEC_FPATAN))
15507 (clobber (match_scratch:XF 8 ""))])
15508 (set (match_operand:DF 0 "register_operand" "")
15509 (float_truncate:DF (match_dup 7)))]
15510 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15511 && flag_unsafe_math_optimizations"
15512 {
15513 int i;
15514
15515 for (i=2; i<8; i++)
15516 operands[i] = gen_reg_rtx (XFmode);
15517
15518 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15519 })
15520
15521 (define_expand "asinsf2"
15522 [(set (match_dup 2)
15523 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15524 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15525 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15526 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15527 (parallel [(set (match_dup 7)
15528 (unspec:XF [(match_dup 6) (match_dup 2)]
15529 UNSPEC_FPATAN))
15530 (clobber (match_scratch:XF 8 ""))])
15531 (set (match_operand:SF 0 "register_operand" "")
15532 (float_truncate:SF (match_dup 7)))]
15533 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15534 && flag_unsafe_math_optimizations"
15535 {
15536 int i;
15537
15538 for (i=2; i<8; i++)
15539 operands[i] = gen_reg_rtx (XFmode);
15540
15541 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15542 })
15543
15544 (define_expand "asinxf2"
15545 [(set (match_dup 2)
15546 (mult:XF (match_operand:XF 1 "register_operand" "")
15547 (match_dup 1)))
15548 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15549 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15550 (parallel [(set (match_operand:XF 0 "register_operand" "")
15551 (unspec:XF [(match_dup 5) (match_dup 1)]
15552 UNSPEC_FPATAN))
15553 (clobber (match_scratch:XF 6 ""))])]
15554 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15555 && flag_unsafe_math_optimizations"
15556 {
15557 int i;
15558
15559 for (i=2; i<6; i++)
15560 operands[i] = gen_reg_rtx (XFmode);
15561
15562 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15563 })
15564
15565 (define_expand "acosdf2"
15566 [(set (match_dup 2)
15567 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15568 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15569 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15570 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15571 (parallel [(set (match_dup 7)
15572 (unspec:XF [(match_dup 2) (match_dup 6)]
15573 UNSPEC_FPATAN))
15574 (clobber (match_scratch:XF 8 ""))])
15575 (set (match_operand:DF 0 "register_operand" "")
15576 (float_truncate:DF (match_dup 7)))]
15577 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15578 && flag_unsafe_math_optimizations"
15579 {
15580 int i;
15581
15582 for (i=2; i<8; i++)
15583 operands[i] = gen_reg_rtx (XFmode);
15584
15585 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15586 })
15587
15588 (define_expand "acossf2"
15589 [(set (match_dup 2)
15590 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15591 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15592 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15593 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15594 (parallel [(set (match_dup 7)
15595 (unspec:XF [(match_dup 2) (match_dup 6)]
15596 UNSPEC_FPATAN))
15597 (clobber (match_scratch:XF 8 ""))])
15598 (set (match_operand:SF 0 "register_operand" "")
15599 (float_truncate:SF (match_dup 7)))]
15600 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15601 && flag_unsafe_math_optimizations"
15602 {
15603 int i;
15604
15605 for (i=2; i<8; i++)
15606 operands[i] = gen_reg_rtx (XFmode);
15607
15608 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15609 })
15610
15611 (define_expand "acosxf2"
15612 [(set (match_dup 2)
15613 (mult:XF (match_operand:XF 1 "register_operand" "")
15614 (match_dup 1)))
15615 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15616 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15617 (parallel [(set (match_operand:XF 0 "register_operand" "")
15618 (unspec:XF [(match_dup 1) (match_dup 5)]
15619 UNSPEC_FPATAN))
15620 (clobber (match_scratch:XF 6 ""))])]
15621 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15622 && flag_unsafe_math_optimizations"
15623 {
15624 int i;
15625
15626 for (i=2; i<6; i++)
15627 operands[i] = gen_reg_rtx (XFmode);
15628
15629 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15630 })
15631
15632 (define_insn "fyl2x_xf3"
15633 [(set (match_operand:XF 0 "register_operand" "=f")
15634 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15635 (match_operand:XF 1 "register_operand" "u")]
15636 UNSPEC_FYL2X))
15637 (clobber (match_scratch:XF 3 "=1"))]
15638 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15639 && flag_unsafe_math_optimizations"
15640 "fyl2x"
15641 [(set_attr "type" "fpspc")
15642 (set_attr "mode" "XF")])
15643
15644 (define_expand "logsf2"
15645 [(set (match_dup 2)
15646 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15647 (parallel [(set (match_dup 4)
15648 (unspec:XF [(match_dup 2)
15649 (match_dup 3)] UNSPEC_FYL2X))
15650 (clobber (match_scratch:XF 5 ""))])
15651 (set (match_operand:SF 0 "register_operand" "")
15652 (float_truncate:SF (match_dup 4)))]
15653 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15654 && flag_unsafe_math_optimizations"
15655 {
15656 rtx temp;
15657
15658 operands[2] = gen_reg_rtx (XFmode);
15659 operands[3] = gen_reg_rtx (XFmode);
15660 operands[4] = gen_reg_rtx (XFmode);
15661
15662 temp = standard_80387_constant_rtx (4); /* fldln2 */
15663 emit_move_insn (operands[3], temp);
15664 })
15665
15666 (define_expand "logdf2"
15667 [(set (match_dup 2)
15668 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15669 (parallel [(set (match_dup 4)
15670 (unspec:XF [(match_dup 2)
15671 (match_dup 3)] UNSPEC_FYL2X))
15672 (clobber (match_scratch:XF 5 ""))])
15673 (set (match_operand:DF 0 "register_operand" "")
15674 (float_truncate:DF (match_dup 4)))]
15675 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15676 && flag_unsafe_math_optimizations"
15677 {
15678 rtx temp;
15679
15680 operands[2] = gen_reg_rtx (XFmode);
15681 operands[3] = gen_reg_rtx (XFmode);
15682 operands[4] = gen_reg_rtx (XFmode);
15683
15684 temp = standard_80387_constant_rtx (4); /* fldln2 */
15685 emit_move_insn (operands[3], temp);
15686 })
15687
15688 (define_expand "logxf2"
15689 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15690 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15691 (match_dup 2)] UNSPEC_FYL2X))
15692 (clobber (match_scratch:XF 3 ""))])]
15693 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15694 && flag_unsafe_math_optimizations"
15695 {
15696 rtx temp;
15697
15698 operands[2] = gen_reg_rtx (XFmode);
15699 temp = standard_80387_constant_rtx (4); /* fldln2 */
15700 emit_move_insn (operands[2], temp);
15701 })
15702
15703 (define_expand "log10sf2"
15704 [(set (match_dup 2)
15705 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15706 (parallel [(set (match_dup 4)
15707 (unspec:XF [(match_dup 2)
15708 (match_dup 3)] UNSPEC_FYL2X))
15709 (clobber (match_scratch:XF 5 ""))])
15710 (set (match_operand:SF 0 "register_operand" "")
15711 (float_truncate:SF (match_dup 4)))]
15712 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15713 && flag_unsafe_math_optimizations"
15714 {
15715 rtx temp;
15716
15717 operands[2] = gen_reg_rtx (XFmode);
15718 operands[3] = gen_reg_rtx (XFmode);
15719 operands[4] = gen_reg_rtx (XFmode);
15720
15721 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15722 emit_move_insn (operands[3], temp);
15723 })
15724
15725 (define_expand "log10df2"
15726 [(set (match_dup 2)
15727 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15728 (parallel [(set (match_dup 4)
15729 (unspec:XF [(match_dup 2)
15730 (match_dup 3)] UNSPEC_FYL2X))
15731 (clobber (match_scratch:XF 5 ""))])
15732 (set (match_operand:DF 0 "register_operand" "")
15733 (float_truncate:DF (match_dup 4)))]
15734 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15735 && flag_unsafe_math_optimizations"
15736 {
15737 rtx temp;
15738
15739 operands[2] = gen_reg_rtx (XFmode);
15740 operands[3] = gen_reg_rtx (XFmode);
15741 operands[4] = gen_reg_rtx (XFmode);
15742
15743 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15744 emit_move_insn (operands[3], temp);
15745 })
15746
15747 (define_expand "log10xf2"
15748 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15749 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15750 (match_dup 2)] UNSPEC_FYL2X))
15751 (clobber (match_scratch:XF 3 ""))])]
15752 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15753 && flag_unsafe_math_optimizations"
15754 {
15755 rtx temp;
15756
15757 operands[2] = gen_reg_rtx (XFmode);
15758 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15759 emit_move_insn (operands[2], temp);
15760 })
15761
15762 (define_expand "log2sf2"
15763 [(set (match_dup 2)
15764 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15765 (parallel [(set (match_dup 4)
15766 (unspec:XF [(match_dup 2)
15767 (match_dup 3)] UNSPEC_FYL2X))
15768 (clobber (match_scratch:XF 5 ""))])
15769 (set (match_operand:SF 0 "register_operand" "")
15770 (float_truncate:SF (match_dup 4)))]
15771 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15772 && flag_unsafe_math_optimizations"
15773 {
15774 operands[2] = gen_reg_rtx (XFmode);
15775 operands[3] = gen_reg_rtx (XFmode);
15776 operands[4] = gen_reg_rtx (XFmode);
15777
15778 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15779 })
15780
15781 (define_expand "log2df2"
15782 [(set (match_dup 2)
15783 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15784 (parallel [(set (match_dup 4)
15785 (unspec:XF [(match_dup 2)
15786 (match_dup 3)] UNSPEC_FYL2X))
15787 (clobber (match_scratch:XF 5 ""))])
15788 (set (match_operand:DF 0 "register_operand" "")
15789 (float_truncate:DF (match_dup 4)))]
15790 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15791 && flag_unsafe_math_optimizations"
15792 {
15793 operands[2] = gen_reg_rtx (XFmode);
15794 operands[3] = gen_reg_rtx (XFmode);
15795 operands[4] = gen_reg_rtx (XFmode);
15796
15797 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15798 })
15799
15800 (define_expand "log2xf2"
15801 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15803 (match_dup 2)] UNSPEC_FYL2X))
15804 (clobber (match_scratch:XF 3 ""))])]
15805 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15806 && flag_unsafe_math_optimizations"
15807 {
15808 operands[2] = gen_reg_rtx (XFmode);
15809 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15810 })
15811
15812 (define_insn "fyl2xp1_xf3"
15813 [(set (match_operand:XF 0 "register_operand" "=f")
15814 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15815 (match_operand:XF 1 "register_operand" "u")]
15816 UNSPEC_FYL2XP1))
15817 (clobber (match_scratch:XF 3 "=1"))]
15818 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15819 && flag_unsafe_math_optimizations"
15820 "fyl2xp1"
15821 [(set_attr "type" "fpspc")
15822 (set_attr "mode" "XF")])
15823
15824 (define_expand "log1psf2"
15825 [(use (match_operand:XF 0 "register_operand" ""))
15826 (use (match_operand:XF 1 "register_operand" ""))]
15827 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15828 && flag_unsafe_math_optimizations"
15829 {
15830 rtx op0 = gen_reg_rtx (XFmode);
15831 rtx op1 = gen_reg_rtx (XFmode);
15832
15833 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15834 ix86_emit_i387_log1p (op0, op1);
15835 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15836 DONE;
15837 })
15838
15839 (define_expand "log1pdf2"
15840 [(use (match_operand:XF 0 "register_operand" ""))
15841 (use (match_operand:XF 1 "register_operand" ""))]
15842 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15843 && flag_unsafe_math_optimizations"
15844 {
15845 rtx op0 = gen_reg_rtx (XFmode);
15846 rtx op1 = gen_reg_rtx (XFmode);
15847
15848 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15849 ix86_emit_i387_log1p (op0, op1);
15850 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15851 DONE;
15852 })
15853
15854 (define_expand "log1pxf2"
15855 [(use (match_operand:XF 0 "register_operand" ""))
15856 (use (match_operand:XF 1 "register_operand" ""))]
15857 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15858 && flag_unsafe_math_optimizations"
15859 {
15860 ix86_emit_i387_log1p (operands[0], operands[1]);
15861 DONE;
15862 })
15863
15864 (define_insn "*fxtractxf3"
15865 [(set (match_operand:XF 0 "register_operand" "=f")
15866 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15867 UNSPEC_XTRACT_FRACT))
15868 (set (match_operand:XF 1 "register_operand" "=u")
15869 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15870 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15871 && flag_unsafe_math_optimizations"
15872 "fxtract"
15873 [(set_attr "type" "fpspc")
15874 (set_attr "mode" "XF")])
15875
15876 (define_expand "logbsf2"
15877 [(set (match_dup 2)
15878 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15879 (parallel [(set (match_dup 3)
15880 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15881 (set (match_dup 4)
15882 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15883 (set (match_operand:SF 0 "register_operand" "")
15884 (float_truncate:SF (match_dup 4)))]
15885 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15886 && flag_unsafe_math_optimizations"
15887 {
15888 operands[2] = gen_reg_rtx (XFmode);
15889 operands[3] = gen_reg_rtx (XFmode);
15890 operands[4] = gen_reg_rtx (XFmode);
15891 })
15892
15893 (define_expand "logbdf2"
15894 [(set (match_dup 2)
15895 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15896 (parallel [(set (match_dup 3)
15897 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15898 (set (match_dup 4)
15899 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15900 (set (match_operand:DF 0 "register_operand" "")
15901 (float_truncate:DF (match_dup 4)))]
15902 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15903 && flag_unsafe_math_optimizations"
15904 {
15905 operands[2] = gen_reg_rtx (XFmode);
15906 operands[3] = gen_reg_rtx (XFmode);
15907 operands[4] = gen_reg_rtx (XFmode);
15908 })
15909
15910 (define_expand "logbxf2"
15911 [(parallel [(set (match_dup 2)
15912 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15913 UNSPEC_XTRACT_FRACT))
15914 (set (match_operand:XF 0 "register_operand" "")
15915 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15916 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15917 && flag_unsafe_math_optimizations"
15918 {
15919 operands[2] = gen_reg_rtx (XFmode);
15920 })
15921
15922 (define_expand "ilogbsi2"
15923 [(parallel [(set (match_dup 2)
15924 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15925 UNSPEC_XTRACT_FRACT))
15926 (set (match_operand:XF 3 "register_operand" "")
15927 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15928 (parallel [(set (match_operand:SI 0 "register_operand" "")
15929 (fix:SI (match_dup 3)))
15930 (clobber (reg:CC 17))])]
15931 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15932 && flag_unsafe_math_optimizations"
15933 {
15934 operands[2] = gen_reg_rtx (XFmode);
15935 operands[3] = gen_reg_rtx (XFmode);
15936 })
15937
15938 (define_insn "*frndintxf2"
15939 [(set (match_operand:XF 0 "register_operand" "=f")
15940 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15941 UNSPEC_FRNDINT))]
15942 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15943 && flag_unsafe_math_optimizations"
15944 "frndint"
15945 [(set_attr "type" "fpspc")
15946 (set_attr "mode" "XF")])
15947
15948 (define_insn "*f2xm1xf2"
15949 [(set (match_operand:XF 0 "register_operand" "=f")
15950 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15951 UNSPEC_F2XM1))]
15952 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15953 && flag_unsafe_math_optimizations"
15954 "f2xm1"
15955 [(set_attr "type" "fpspc")
15956 (set_attr "mode" "XF")])
15957
15958 (define_insn "*fscalexf4"
15959 [(set (match_operand:XF 0 "register_operand" "=f")
15960 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15961 (match_operand:XF 3 "register_operand" "1")]
15962 UNSPEC_FSCALE_FRACT))
15963 (set (match_operand:XF 1 "register_operand" "=u")
15964 (unspec:XF [(match_dup 2) (match_dup 3)]
15965 UNSPEC_FSCALE_EXP))]
15966 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15967 && flag_unsafe_math_optimizations"
15968 "fscale"
15969 [(set_attr "type" "fpspc")
15970 (set_attr "mode" "XF")])
15971
15972 (define_expand "expsf2"
15973 [(set (match_dup 2)
15974 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15975 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15976 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15977 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15978 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15979 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15980 (parallel [(set (match_dup 10)
15981 (unspec:XF [(match_dup 9) (match_dup 5)]
15982 UNSPEC_FSCALE_FRACT))
15983 (set (match_dup 11)
15984 (unspec:XF [(match_dup 9) (match_dup 5)]
15985 UNSPEC_FSCALE_EXP))])
15986 (set (match_operand:SF 0 "register_operand" "")
15987 (float_truncate:SF (match_dup 10)))]
15988 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15989 && flag_unsafe_math_optimizations"
15990 {
15991 rtx temp;
15992 int i;
15993
15994 for (i=2; i<12; i++)
15995 operands[i] = gen_reg_rtx (XFmode);
15996 temp = standard_80387_constant_rtx (5); /* fldl2e */
15997 emit_move_insn (operands[3], temp);
15998 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15999 })
16000
16001 (define_expand "expdf2"
16002 [(set (match_dup 2)
16003 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16004 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16005 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16006 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16007 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16008 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16009 (parallel [(set (match_dup 10)
16010 (unspec:XF [(match_dup 9) (match_dup 5)]
16011 UNSPEC_FSCALE_FRACT))
16012 (set (match_dup 11)
16013 (unspec:XF [(match_dup 9) (match_dup 5)]
16014 UNSPEC_FSCALE_EXP))])
16015 (set (match_operand:DF 0 "register_operand" "")
16016 (float_truncate:DF (match_dup 10)))]
16017 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16018 && flag_unsafe_math_optimizations"
16019 {
16020 rtx temp;
16021 int i;
16022
16023 for (i=2; i<12; i++)
16024 operands[i] = gen_reg_rtx (XFmode);
16025 temp = standard_80387_constant_rtx (5); /* fldl2e */
16026 emit_move_insn (operands[3], temp);
16027 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16028 })
16029
16030 (define_expand "expxf2"
16031 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16032 (match_dup 2)))
16033 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16034 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16035 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16036 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16037 (parallel [(set (match_operand:XF 0 "register_operand" "")
16038 (unspec:XF [(match_dup 8) (match_dup 4)]
16039 UNSPEC_FSCALE_FRACT))
16040 (set (match_dup 9)
16041 (unspec:XF [(match_dup 8) (match_dup 4)]
16042 UNSPEC_FSCALE_EXP))])]
16043 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16044 && flag_unsafe_math_optimizations"
16045 {
16046 rtx temp;
16047 int i;
16048
16049 for (i=2; i<10; i++)
16050 operands[i] = gen_reg_rtx (XFmode);
16051 temp = standard_80387_constant_rtx (5); /* fldl2e */
16052 emit_move_insn (operands[2], temp);
16053 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16054 })
16055
16056 (define_expand "exp10sf2"
16057 [(set (match_dup 2)
16058 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16059 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16060 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16061 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16062 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16063 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16064 (parallel [(set (match_dup 10)
16065 (unspec:XF [(match_dup 9) (match_dup 5)]
16066 UNSPEC_FSCALE_FRACT))
16067 (set (match_dup 11)
16068 (unspec:XF [(match_dup 9) (match_dup 5)]
16069 UNSPEC_FSCALE_EXP))])
16070 (set (match_operand:SF 0 "register_operand" "")
16071 (float_truncate:SF (match_dup 10)))]
16072 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16073 && flag_unsafe_math_optimizations"
16074 {
16075 rtx temp;
16076 int i;
16077
16078 for (i=2; i<12; i++)
16079 operands[i] = gen_reg_rtx (XFmode);
16080 temp = standard_80387_constant_rtx (6); /* fldl2t */
16081 emit_move_insn (operands[3], temp);
16082 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16083 })
16084
16085 (define_expand "exp10df2"
16086 [(set (match_dup 2)
16087 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16088 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16089 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16090 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16091 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16092 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16093 (parallel [(set (match_dup 10)
16094 (unspec:XF [(match_dup 9) (match_dup 5)]
16095 UNSPEC_FSCALE_FRACT))
16096 (set (match_dup 11)
16097 (unspec:XF [(match_dup 9) (match_dup 5)]
16098 UNSPEC_FSCALE_EXP))])
16099 (set (match_operand:DF 0 "register_operand" "")
16100 (float_truncate:DF (match_dup 10)))]
16101 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16102 && flag_unsafe_math_optimizations"
16103 {
16104 rtx temp;
16105 int i;
16106
16107 for (i=2; i<12; i++)
16108 operands[i] = gen_reg_rtx (XFmode);
16109 temp = standard_80387_constant_rtx (6); /* fldl2t */
16110 emit_move_insn (operands[3], temp);
16111 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16112 })
16113
16114 (define_expand "exp10xf2"
16115 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16116 (match_dup 2)))
16117 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16118 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16119 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16120 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16121 (parallel [(set (match_operand:XF 0 "register_operand" "")
16122 (unspec:XF [(match_dup 8) (match_dup 4)]
16123 UNSPEC_FSCALE_FRACT))
16124 (set (match_dup 9)
16125 (unspec:XF [(match_dup 8) (match_dup 4)]
16126 UNSPEC_FSCALE_EXP))])]
16127 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16128 && flag_unsafe_math_optimizations"
16129 {
16130 rtx temp;
16131 int i;
16132
16133 for (i=2; i<10; i++)
16134 operands[i] = gen_reg_rtx (XFmode);
16135 temp = standard_80387_constant_rtx (6); /* fldl2t */
16136 emit_move_insn (operands[2], temp);
16137 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16138 })
16139
16140 (define_expand "exp2sf2"
16141 [(set (match_dup 2)
16142 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16143 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16144 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16145 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16146 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16147 (parallel [(set (match_dup 8)
16148 (unspec:XF [(match_dup 7) (match_dup 3)]
16149 UNSPEC_FSCALE_FRACT))
16150 (set (match_dup 9)
16151 (unspec:XF [(match_dup 7) (match_dup 3)]
16152 UNSPEC_FSCALE_EXP))])
16153 (set (match_operand:SF 0 "register_operand" "")
16154 (float_truncate:SF (match_dup 8)))]
16155 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16156 && flag_unsafe_math_optimizations"
16157 {
16158 int i;
16159
16160 for (i=2; i<10; i++)
16161 operands[i] = gen_reg_rtx (XFmode);
16162 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16163 })
16164
16165 (define_expand "exp2df2"
16166 [(set (match_dup 2)
16167 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16168 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16169 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16170 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16171 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16172 (parallel [(set (match_dup 8)
16173 (unspec:XF [(match_dup 7) (match_dup 3)]
16174 UNSPEC_FSCALE_FRACT))
16175 (set (match_dup 9)
16176 (unspec:XF [(match_dup 7) (match_dup 3)]
16177 UNSPEC_FSCALE_EXP))])
16178 (set (match_operand:DF 0 "register_operand" "")
16179 (float_truncate:DF (match_dup 8)))]
16180 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16181 && flag_unsafe_math_optimizations"
16182 {
16183 int i;
16184
16185 for (i=2; i<10; i++)
16186 operands[i] = gen_reg_rtx (XFmode);
16187 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16188 })
16189
16190 (define_expand "exp2xf2"
16191 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16192 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16193 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16194 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16195 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16196 (parallel [(set (match_operand:XF 0 "register_operand" "")
16197 (unspec:XF [(match_dup 7) (match_dup 3)]
16198 UNSPEC_FSCALE_FRACT))
16199 (set (match_dup 8)
16200 (unspec:XF [(match_dup 7) (match_dup 3)]
16201 UNSPEC_FSCALE_EXP))])]
16202 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16203 && flag_unsafe_math_optimizations"
16204 {
16205 int i;
16206
16207 for (i=2; i<9; i++)
16208 operands[i] = gen_reg_rtx (XFmode);
16209 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16210 })
16211
16212 (define_expand "expm1df2"
16213 [(set (match_dup 2)
16214 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16215 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16216 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16217 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16218 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16219 (parallel [(set (match_dup 8)
16220 (unspec:XF [(match_dup 7) (match_dup 5)]
16221 UNSPEC_FSCALE_FRACT))
16222 (set (match_dup 9)
16223 (unspec:XF [(match_dup 7) (match_dup 5)]
16224 UNSPEC_FSCALE_EXP))])
16225 (parallel [(set (match_dup 11)
16226 (unspec:XF [(match_dup 10) (match_dup 9)]
16227 UNSPEC_FSCALE_FRACT))
16228 (set (match_dup 12)
16229 (unspec:XF [(match_dup 10) (match_dup 9)]
16230 UNSPEC_FSCALE_EXP))])
16231 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16232 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16233 (set (match_operand:DF 0 "register_operand" "")
16234 (float_truncate:DF (match_dup 14)))]
16235 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16236 && flag_unsafe_math_optimizations"
16237 {
16238 rtx temp;
16239 int i;
16240
16241 for (i=2; i<15; i++)
16242 operands[i] = gen_reg_rtx (XFmode);
16243 temp = standard_80387_constant_rtx (5); /* fldl2e */
16244 emit_move_insn (operands[3], temp);
16245 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16246 })
16247
16248 (define_expand "expm1sf2"
16249 [(set (match_dup 2)
16250 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16251 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16252 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16253 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16254 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16255 (parallel [(set (match_dup 8)
16256 (unspec:XF [(match_dup 7) (match_dup 5)]
16257 UNSPEC_FSCALE_FRACT))
16258 (set (match_dup 9)
16259 (unspec:XF [(match_dup 7) (match_dup 5)]
16260 UNSPEC_FSCALE_EXP))])
16261 (parallel [(set (match_dup 11)
16262 (unspec:XF [(match_dup 10) (match_dup 9)]
16263 UNSPEC_FSCALE_FRACT))
16264 (set (match_dup 12)
16265 (unspec:XF [(match_dup 10) (match_dup 9)]
16266 UNSPEC_FSCALE_EXP))])
16267 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16268 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16269 (set (match_operand:SF 0 "register_operand" "")
16270 (float_truncate:SF (match_dup 14)))]
16271 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16272 && flag_unsafe_math_optimizations"
16273 {
16274 rtx temp;
16275 int i;
16276
16277 for (i=2; i<15; i++)
16278 operands[i] = gen_reg_rtx (XFmode);
16279 temp = standard_80387_constant_rtx (5); /* fldl2e */
16280 emit_move_insn (operands[3], temp);
16281 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16282 })
16283
16284 (define_expand "expm1xf2"
16285 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16286 (match_dup 2)))
16287 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16288 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16289 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16290 (parallel [(set (match_dup 7)
16291 (unspec:XF [(match_dup 6) (match_dup 4)]
16292 UNSPEC_FSCALE_FRACT))
16293 (set (match_dup 8)
16294 (unspec:XF [(match_dup 6) (match_dup 4)]
16295 UNSPEC_FSCALE_EXP))])
16296 (parallel [(set (match_dup 10)
16297 (unspec:XF [(match_dup 9) (match_dup 8)]
16298 UNSPEC_FSCALE_FRACT))
16299 (set (match_dup 11)
16300 (unspec:XF [(match_dup 9) (match_dup 8)]
16301 UNSPEC_FSCALE_EXP))])
16302 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16303 (set (match_operand:XF 0 "register_operand" "")
16304 (plus:XF (match_dup 12) (match_dup 7)))]
16305 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16306 && flag_unsafe_math_optimizations"
16307 {
16308 rtx temp;
16309 int i;
16310
16311 for (i=2; i<13; i++)
16312 operands[i] = gen_reg_rtx (XFmode);
16313 temp = standard_80387_constant_rtx (5); /* fldl2e */
16314 emit_move_insn (operands[2], temp);
16315 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16316 })
16317 \f
16318 ;; Block operation instructions
16319
16320 (define_insn "cld"
16321 [(set (reg:SI 19) (const_int 0))]
16322 ""
16323 "cld"
16324 [(set_attr "type" "cld")])
16325
16326 (define_expand "movstrsi"
16327 [(use (match_operand:BLK 0 "memory_operand" ""))
16328 (use (match_operand:BLK 1 "memory_operand" ""))
16329 (use (match_operand:SI 2 "nonmemory_operand" ""))
16330 (use (match_operand:SI 3 "const_int_operand" ""))]
16331 "! optimize_size"
16332 {
16333 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16334 DONE;
16335 else
16336 FAIL;
16337 })
16338
16339 (define_expand "movstrdi"
16340 [(use (match_operand:BLK 0 "memory_operand" ""))
16341 (use (match_operand:BLK 1 "memory_operand" ""))
16342 (use (match_operand:DI 2 "nonmemory_operand" ""))
16343 (use (match_operand:DI 3 "const_int_operand" ""))]
16344 "TARGET_64BIT"
16345 {
16346 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16347 DONE;
16348 else
16349 FAIL;
16350 })
16351
16352 ;; Most CPUs don't like single string operations
16353 ;; Handle this case here to simplify previous expander.
16354
16355 (define_expand "strmov"
16356 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16357 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16358 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16359 (clobber (reg:CC 17))])
16360 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16361 (clobber (reg:CC 17))])]
16362 ""
16363 {
16364 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16365
16366 /* If .md ever supports :P for Pmode, these can be directly
16367 in the pattern above. */
16368 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16369 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16370
16371 if (TARGET_SINGLE_STRINGOP || optimize_size)
16372 {
16373 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16374 operands[2], operands[3],
16375 operands[5], operands[6]));
16376 DONE;
16377 }
16378
16379 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16380 })
16381
16382 (define_expand "strmov_singleop"
16383 [(parallel [(set (match_operand 1 "memory_operand" "")
16384 (match_operand 3 "memory_operand" ""))
16385 (set (match_operand 0 "register_operand" "")
16386 (match_operand 4 "" ""))
16387 (set (match_operand 2 "register_operand" "")
16388 (match_operand 5 "" ""))
16389 (use (reg:SI 19))])]
16390 "TARGET_SINGLE_STRINGOP || optimize_size"
16391 "")
16392
16393 (define_insn "*strmovdi_rex_1"
16394 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16395 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16396 (set (match_operand:DI 0 "register_operand" "=D")
16397 (plus:DI (match_dup 2)
16398 (const_int 8)))
16399 (set (match_operand:DI 1 "register_operand" "=S")
16400 (plus:DI (match_dup 3)
16401 (const_int 8)))
16402 (use (reg:SI 19))]
16403 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16404 "movsq"
16405 [(set_attr "type" "str")
16406 (set_attr "mode" "DI")
16407 (set_attr "memory" "both")])
16408
16409 (define_insn "*strmovsi_1"
16410 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16411 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16412 (set (match_operand:SI 0 "register_operand" "=D")
16413 (plus:SI (match_dup 2)
16414 (const_int 4)))
16415 (set (match_operand:SI 1 "register_operand" "=S")
16416 (plus:SI (match_dup 3)
16417 (const_int 4)))
16418 (use (reg:SI 19))]
16419 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16420 "{movsl|movsd}"
16421 [(set_attr "type" "str")
16422 (set_attr "mode" "SI")
16423 (set_attr "memory" "both")])
16424
16425 (define_insn "*strmovsi_rex_1"
16426 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16427 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16428 (set (match_operand:DI 0 "register_operand" "=D")
16429 (plus:DI (match_dup 2)
16430 (const_int 4)))
16431 (set (match_operand:DI 1 "register_operand" "=S")
16432 (plus:DI (match_dup 3)
16433 (const_int 4)))
16434 (use (reg:SI 19))]
16435 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16436 "{movsl|movsd}"
16437 [(set_attr "type" "str")
16438 (set_attr "mode" "SI")
16439 (set_attr "memory" "both")])
16440
16441 (define_insn "*strmovhi_1"
16442 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16443 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16444 (set (match_operand:SI 0 "register_operand" "=D")
16445 (plus:SI (match_dup 2)
16446 (const_int 2)))
16447 (set (match_operand:SI 1 "register_operand" "=S")
16448 (plus:SI (match_dup 3)
16449 (const_int 2)))
16450 (use (reg:SI 19))]
16451 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16452 "movsw"
16453 [(set_attr "type" "str")
16454 (set_attr "memory" "both")
16455 (set_attr "mode" "HI")])
16456
16457 (define_insn "*strmovhi_rex_1"
16458 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16459 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16460 (set (match_operand:DI 0 "register_operand" "=D")
16461 (plus:DI (match_dup 2)
16462 (const_int 2)))
16463 (set (match_operand:DI 1 "register_operand" "=S")
16464 (plus:DI (match_dup 3)
16465 (const_int 2)))
16466 (use (reg:SI 19))]
16467 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16468 "movsw"
16469 [(set_attr "type" "str")
16470 (set_attr "memory" "both")
16471 (set_attr "mode" "HI")])
16472
16473 (define_insn "*strmovqi_1"
16474 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16475 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16476 (set (match_operand:SI 0 "register_operand" "=D")
16477 (plus:SI (match_dup 2)
16478 (const_int 1)))
16479 (set (match_operand:SI 1 "register_operand" "=S")
16480 (plus:SI (match_dup 3)
16481 (const_int 1)))
16482 (use (reg:SI 19))]
16483 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16484 "movsb"
16485 [(set_attr "type" "str")
16486 (set_attr "memory" "both")
16487 (set_attr "mode" "QI")])
16488
16489 (define_insn "*strmovqi_rex_1"
16490 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16491 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16492 (set (match_operand:DI 0 "register_operand" "=D")
16493 (plus:DI (match_dup 2)
16494 (const_int 1)))
16495 (set (match_operand:DI 1 "register_operand" "=S")
16496 (plus:DI (match_dup 3)
16497 (const_int 1)))
16498 (use (reg:SI 19))]
16499 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16500 "movsb"
16501 [(set_attr "type" "str")
16502 (set_attr "memory" "both")
16503 (set_attr "mode" "QI")])
16504
16505 (define_expand "rep_mov"
16506 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16507 (set (match_operand 0 "register_operand" "")
16508 (match_operand 5 "" ""))
16509 (set (match_operand 2 "register_operand" "")
16510 (match_operand 6 "" ""))
16511 (set (match_operand 1 "memory_operand" "")
16512 (match_operand 3 "memory_operand" ""))
16513 (use (match_dup 4))
16514 (use (reg:SI 19))])]
16515 ""
16516 "")
16517
16518 (define_insn "*rep_movdi_rex64"
16519 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16520 (set (match_operand:DI 0 "register_operand" "=D")
16521 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16522 (const_int 3))
16523 (match_operand:DI 3 "register_operand" "0")))
16524 (set (match_operand:DI 1 "register_operand" "=S")
16525 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16526 (match_operand:DI 4 "register_operand" "1")))
16527 (set (mem:BLK (match_dup 3))
16528 (mem:BLK (match_dup 4)))
16529 (use (match_dup 5))
16530 (use (reg:SI 19))]
16531 "TARGET_64BIT"
16532 "{rep\;movsq|rep movsq}"
16533 [(set_attr "type" "str")
16534 (set_attr "prefix_rep" "1")
16535 (set_attr "memory" "both")
16536 (set_attr "mode" "DI")])
16537
16538 (define_insn "*rep_movsi"
16539 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16540 (set (match_operand:SI 0 "register_operand" "=D")
16541 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16542 (const_int 2))
16543 (match_operand:SI 3 "register_operand" "0")))
16544 (set (match_operand:SI 1 "register_operand" "=S")
16545 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16546 (match_operand:SI 4 "register_operand" "1")))
16547 (set (mem:BLK (match_dup 3))
16548 (mem:BLK (match_dup 4)))
16549 (use (match_dup 5))
16550 (use (reg:SI 19))]
16551 "!TARGET_64BIT"
16552 "{rep\;movsl|rep movsd}"
16553 [(set_attr "type" "str")
16554 (set_attr "prefix_rep" "1")
16555 (set_attr "memory" "both")
16556 (set_attr "mode" "SI")])
16557
16558 (define_insn "*rep_movsi_rex64"
16559 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16560 (set (match_operand:DI 0 "register_operand" "=D")
16561 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16562 (const_int 2))
16563 (match_operand:DI 3 "register_operand" "0")))
16564 (set (match_operand:DI 1 "register_operand" "=S")
16565 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16566 (match_operand:DI 4 "register_operand" "1")))
16567 (set (mem:BLK (match_dup 3))
16568 (mem:BLK (match_dup 4)))
16569 (use (match_dup 5))
16570 (use (reg:SI 19))]
16571 "TARGET_64BIT"
16572 "{rep\;movsl|rep movsd}"
16573 [(set_attr "type" "str")
16574 (set_attr "prefix_rep" "1")
16575 (set_attr "memory" "both")
16576 (set_attr "mode" "SI")])
16577
16578 (define_insn "*rep_movqi"
16579 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16580 (set (match_operand:SI 0 "register_operand" "=D")
16581 (plus:SI (match_operand:SI 3 "register_operand" "0")
16582 (match_operand:SI 5 "register_operand" "2")))
16583 (set (match_operand:SI 1 "register_operand" "=S")
16584 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16585 (set (mem:BLK (match_dup 3))
16586 (mem:BLK (match_dup 4)))
16587 (use (match_dup 5))
16588 (use (reg:SI 19))]
16589 "!TARGET_64BIT"
16590 "{rep\;movsb|rep movsb}"
16591 [(set_attr "type" "str")
16592 (set_attr "prefix_rep" "1")
16593 (set_attr "memory" "both")
16594 (set_attr "mode" "SI")])
16595
16596 (define_insn "*rep_movqi_rex64"
16597 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16598 (set (match_operand:DI 0 "register_operand" "=D")
16599 (plus:DI (match_operand:DI 3 "register_operand" "0")
16600 (match_operand:DI 5 "register_operand" "2")))
16601 (set (match_operand:DI 1 "register_operand" "=S")
16602 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16603 (set (mem:BLK (match_dup 3))
16604 (mem:BLK (match_dup 4)))
16605 (use (match_dup 5))
16606 (use (reg:SI 19))]
16607 "TARGET_64BIT"
16608 "{rep\;movsb|rep movsb}"
16609 [(set_attr "type" "str")
16610 (set_attr "prefix_rep" "1")
16611 (set_attr "memory" "both")
16612 (set_attr "mode" "SI")])
16613
16614 (define_expand "clrstrsi"
16615 [(use (match_operand:BLK 0 "memory_operand" ""))
16616 (use (match_operand:SI 1 "nonmemory_operand" ""))
16617 (use (match_operand 2 "const_int_operand" ""))]
16618 ""
16619 {
16620 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16621 DONE;
16622 else
16623 FAIL;
16624 })
16625
16626 (define_expand "clrstrdi"
16627 [(use (match_operand:BLK 0 "memory_operand" ""))
16628 (use (match_operand:DI 1 "nonmemory_operand" ""))
16629 (use (match_operand 2 "const_int_operand" ""))]
16630 "TARGET_64BIT"
16631 {
16632 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16633 DONE;
16634 else
16635 FAIL;
16636 })
16637
16638 ;; Most CPUs don't like single string operations
16639 ;; Handle this case here to simplify previous expander.
16640
16641 (define_expand "strset"
16642 [(set (match_operand 1 "memory_operand" "")
16643 (match_operand 2 "register_operand" ""))
16644 (parallel [(set (match_operand 0 "register_operand" "")
16645 (match_dup 3))
16646 (clobber (reg:CC 17))])]
16647 ""
16648 {
16649 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16650 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16651
16652 /* If .md ever supports :P for Pmode, this can be directly
16653 in the pattern above. */
16654 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16655 GEN_INT (GET_MODE_SIZE (GET_MODE
16656 (operands[2]))));
16657 if (TARGET_SINGLE_STRINGOP || optimize_size)
16658 {
16659 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16660 operands[3]));
16661 DONE;
16662 }
16663 })
16664
16665 (define_expand "strset_singleop"
16666 [(parallel [(set (match_operand 1 "memory_operand" "")
16667 (match_operand 2 "register_operand" ""))
16668 (set (match_operand 0 "register_operand" "")
16669 (match_operand 3 "" ""))
16670 (use (reg:SI 19))])]
16671 "TARGET_SINGLE_STRINGOP || optimize_size"
16672 "")
16673
16674 (define_insn "*strsetdi_rex_1"
16675 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16676 (match_operand:SI 2 "register_operand" "a"))
16677 (set (match_operand:DI 0 "register_operand" "=D")
16678 (plus:DI (match_dup 1)
16679 (const_int 8)))
16680 (use (reg:SI 19))]
16681 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16682 "stosq"
16683 [(set_attr "type" "str")
16684 (set_attr "memory" "store")
16685 (set_attr "mode" "DI")])
16686
16687 (define_insn "*strsetsi_1"
16688 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16689 (match_operand:SI 2 "register_operand" "a"))
16690 (set (match_operand:SI 0 "register_operand" "=D")
16691 (plus:SI (match_dup 1)
16692 (const_int 4)))
16693 (use (reg:SI 19))]
16694 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16695 "{stosl|stosd}"
16696 [(set_attr "type" "str")
16697 (set_attr "memory" "store")
16698 (set_attr "mode" "SI")])
16699
16700 (define_insn "*strsetsi_rex_1"
16701 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16702 (match_operand:SI 2 "register_operand" "a"))
16703 (set (match_operand:DI 0 "register_operand" "=D")
16704 (plus:DI (match_dup 1)
16705 (const_int 4)))
16706 (use (reg:SI 19))]
16707 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16708 "{stosl|stosd}"
16709 [(set_attr "type" "str")
16710 (set_attr "memory" "store")
16711 (set_attr "mode" "SI")])
16712
16713 (define_insn "*strsethi_1"
16714 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16715 (match_operand:HI 2 "register_operand" "a"))
16716 (set (match_operand:SI 0 "register_operand" "=D")
16717 (plus:SI (match_dup 1)
16718 (const_int 2)))
16719 (use (reg:SI 19))]
16720 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16721 "stosw"
16722 [(set_attr "type" "str")
16723 (set_attr "memory" "store")
16724 (set_attr "mode" "HI")])
16725
16726 (define_insn "*strsethi_rex_1"
16727 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16728 (match_operand:HI 2 "register_operand" "a"))
16729 (set (match_operand:DI 0 "register_operand" "=D")
16730 (plus:DI (match_dup 1)
16731 (const_int 2)))
16732 (use (reg:SI 19))]
16733 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16734 "stosw"
16735 [(set_attr "type" "str")
16736 (set_attr "memory" "store")
16737 (set_attr "mode" "HI")])
16738
16739 (define_insn "*strsetqi_1"
16740 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16741 (match_operand:QI 2 "register_operand" "a"))
16742 (set (match_operand:SI 0 "register_operand" "=D")
16743 (plus:SI (match_dup 1)
16744 (const_int 1)))
16745 (use (reg:SI 19))]
16746 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16747 "stosb"
16748 [(set_attr "type" "str")
16749 (set_attr "memory" "store")
16750 (set_attr "mode" "QI")])
16751
16752 (define_insn "*strsetqi_rex_1"
16753 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16754 (match_operand:QI 2 "register_operand" "a"))
16755 (set (match_operand:DI 0 "register_operand" "=D")
16756 (plus:DI (match_dup 1)
16757 (const_int 1)))
16758 (use (reg:SI 19))]
16759 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16760 "stosb"
16761 [(set_attr "type" "str")
16762 (set_attr "memory" "store")
16763 (set_attr "mode" "QI")])
16764
16765 (define_expand "rep_stos"
16766 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16767 (set (match_operand 0 "register_operand" "")
16768 (match_operand 4 "" ""))
16769 (set (match_operand 2 "memory_operand" "") (const_int 0))
16770 (use (match_operand 3 "register_operand" ""))
16771 (use (match_dup 1))
16772 (use (reg:SI 19))])]
16773 ""
16774 "")
16775
16776 (define_insn "*rep_stosdi_rex64"
16777 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16778 (set (match_operand:DI 0 "register_operand" "=D")
16779 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16780 (const_int 3))
16781 (match_operand:DI 3 "register_operand" "0")))
16782 (set (mem:BLK (match_dup 3))
16783 (const_int 0))
16784 (use (match_operand:DI 2 "register_operand" "a"))
16785 (use (match_dup 4))
16786 (use (reg:SI 19))]
16787 "TARGET_64BIT"
16788 "{rep\;stosq|rep stosq}"
16789 [(set_attr "type" "str")
16790 (set_attr "prefix_rep" "1")
16791 (set_attr "memory" "store")
16792 (set_attr "mode" "DI")])
16793
16794 (define_insn "*rep_stossi"
16795 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16796 (set (match_operand:SI 0 "register_operand" "=D")
16797 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16798 (const_int 2))
16799 (match_operand:SI 3 "register_operand" "0")))
16800 (set (mem:BLK (match_dup 3))
16801 (const_int 0))
16802 (use (match_operand:SI 2 "register_operand" "a"))
16803 (use (match_dup 4))
16804 (use (reg:SI 19))]
16805 "!TARGET_64BIT"
16806 "{rep\;stosl|rep stosd}"
16807 [(set_attr "type" "str")
16808 (set_attr "prefix_rep" "1")
16809 (set_attr "memory" "store")
16810 (set_attr "mode" "SI")])
16811
16812 (define_insn "*rep_stossi_rex64"
16813 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16814 (set (match_operand:DI 0 "register_operand" "=D")
16815 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16816 (const_int 2))
16817 (match_operand:DI 3 "register_operand" "0")))
16818 (set (mem:BLK (match_dup 3))
16819 (const_int 0))
16820 (use (match_operand:SI 2 "register_operand" "a"))
16821 (use (match_dup 4))
16822 (use (reg:SI 19))]
16823 "TARGET_64BIT"
16824 "{rep\;stosl|rep stosd}"
16825 [(set_attr "type" "str")
16826 (set_attr "prefix_rep" "1")
16827 (set_attr "memory" "store")
16828 (set_attr "mode" "SI")])
16829
16830 (define_insn "*rep_stosqi"
16831 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16832 (set (match_operand:SI 0 "register_operand" "=D")
16833 (plus:SI (match_operand:SI 3 "register_operand" "0")
16834 (match_operand:SI 4 "register_operand" "1")))
16835 (set (mem:BLK (match_dup 3))
16836 (const_int 0))
16837 (use (match_operand:QI 2 "register_operand" "a"))
16838 (use (match_dup 4))
16839 (use (reg:SI 19))]
16840 "!TARGET_64BIT"
16841 "{rep\;stosb|rep stosb}"
16842 [(set_attr "type" "str")
16843 (set_attr "prefix_rep" "1")
16844 (set_attr "memory" "store")
16845 (set_attr "mode" "QI")])
16846
16847 (define_insn "*rep_stosqi_rex64"
16848 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16849 (set (match_operand:DI 0 "register_operand" "=D")
16850 (plus:DI (match_operand:DI 3 "register_operand" "0")
16851 (match_operand:DI 4 "register_operand" "1")))
16852 (set (mem:BLK (match_dup 3))
16853 (const_int 0))
16854 (use (match_operand:QI 2 "register_operand" "a"))
16855 (use (match_dup 4))
16856 (use (reg:SI 19))]
16857 "TARGET_64BIT"
16858 "{rep\;stosb|rep stosb}"
16859 [(set_attr "type" "str")
16860 (set_attr "prefix_rep" "1")
16861 (set_attr "memory" "store")
16862 (set_attr "mode" "QI")])
16863
16864 (define_expand "cmpstrsi"
16865 [(set (match_operand:SI 0 "register_operand" "")
16866 (compare:SI (match_operand:BLK 1 "general_operand" "")
16867 (match_operand:BLK 2 "general_operand" "")))
16868 (use (match_operand 3 "general_operand" ""))
16869 (use (match_operand 4 "immediate_operand" ""))]
16870 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16871 {
16872 rtx addr1, addr2, out, outlow, count, countreg, align;
16873
16874 /* Can't use this if the user has appropriated esi or edi. */
16875 if (global_regs[4] || global_regs[5])
16876 FAIL;
16877
16878 out = operands[0];
16879 if (GET_CODE (out) != REG)
16880 out = gen_reg_rtx (SImode);
16881
16882 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16883 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16884 if (addr1 != XEXP (operands[1], 0))
16885 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16886 if (addr2 != XEXP (operands[2], 0))
16887 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16888
16889 count = operands[3];
16890 countreg = ix86_zero_extend_to_Pmode (count);
16891
16892 /* %%% Iff we are testing strict equality, we can use known alignment
16893 to good advantage. This may be possible with combine, particularly
16894 once cc0 is dead. */
16895 align = operands[4];
16896
16897 emit_insn (gen_cld ());
16898 if (GET_CODE (count) == CONST_INT)
16899 {
16900 if (INTVAL (count) == 0)
16901 {
16902 emit_move_insn (operands[0], const0_rtx);
16903 DONE;
16904 }
16905 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16906 operands[1], operands[2]));
16907 }
16908 else
16909 {
16910 if (TARGET_64BIT)
16911 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16912 else
16913 emit_insn (gen_cmpsi_1 (countreg, countreg));
16914 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16915 operands[1], operands[2]));
16916 }
16917
16918 outlow = gen_lowpart (QImode, out);
16919 emit_insn (gen_cmpintqi (outlow));
16920 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16921
16922 if (operands[0] != out)
16923 emit_move_insn (operands[0], out);
16924
16925 DONE;
16926 })
16927
16928 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16929
16930 (define_expand "cmpintqi"
16931 [(set (match_dup 1)
16932 (gtu:QI (reg:CC 17) (const_int 0)))
16933 (set (match_dup 2)
16934 (ltu:QI (reg:CC 17) (const_int 0)))
16935 (parallel [(set (match_operand:QI 0 "register_operand" "")
16936 (minus:QI (match_dup 1)
16937 (match_dup 2)))
16938 (clobber (reg:CC 17))])]
16939 ""
16940 "operands[1] = gen_reg_rtx (QImode);
16941 operands[2] = gen_reg_rtx (QImode);")
16942
16943 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16944 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16945
16946 (define_expand "cmpstrqi_nz_1"
16947 [(parallel [(set (reg:CC 17)
16948 (compare:CC (match_operand 4 "memory_operand" "")
16949 (match_operand 5 "memory_operand" "")))
16950 (use (match_operand 2 "register_operand" ""))
16951 (use (match_operand:SI 3 "immediate_operand" ""))
16952 (use (reg:SI 19))
16953 (clobber (match_operand 0 "register_operand" ""))
16954 (clobber (match_operand 1 "register_operand" ""))
16955 (clobber (match_dup 2))])]
16956 ""
16957 "")
16958
16959 (define_insn "*cmpstrqi_nz_1"
16960 [(set (reg:CC 17)
16961 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16962 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16963 (use (match_operand:SI 6 "register_operand" "2"))
16964 (use (match_operand:SI 3 "immediate_operand" "i"))
16965 (use (reg:SI 19))
16966 (clobber (match_operand:SI 0 "register_operand" "=S"))
16967 (clobber (match_operand:SI 1 "register_operand" "=D"))
16968 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16969 "!TARGET_64BIT"
16970 "repz{\;| }cmpsb"
16971 [(set_attr "type" "str")
16972 (set_attr "mode" "QI")
16973 (set_attr "prefix_rep" "1")])
16974
16975 (define_insn "*cmpstrqi_nz_rex_1"
16976 [(set (reg:CC 17)
16977 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16978 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16979 (use (match_operand:DI 6 "register_operand" "2"))
16980 (use (match_operand:SI 3 "immediate_operand" "i"))
16981 (use (reg:SI 19))
16982 (clobber (match_operand:DI 0 "register_operand" "=S"))
16983 (clobber (match_operand:DI 1 "register_operand" "=D"))
16984 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16985 "TARGET_64BIT"
16986 "repz{\;| }cmpsb"
16987 [(set_attr "type" "str")
16988 (set_attr "mode" "QI")
16989 (set_attr "prefix_rep" "1")])
16990
16991 ;; The same, but the count is not known to not be zero.
16992
16993 (define_expand "cmpstrqi_1"
16994 [(parallel [(set (reg:CC 17)
16995 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16996 (const_int 0))
16997 (compare:CC (match_operand 4 "memory_operand" "")
16998 (match_operand 5 "memory_operand" ""))
16999 (const_int 0)))
17000 (use (match_operand:SI 3 "immediate_operand" ""))
17001 (use (reg:CC 17))
17002 (use (reg:SI 19))
17003 (clobber (match_operand 0 "register_operand" ""))
17004 (clobber (match_operand 1 "register_operand" ""))
17005 (clobber (match_dup 2))])]
17006 ""
17007 "")
17008
17009 (define_insn "*cmpstrqi_1"
17010 [(set (reg:CC 17)
17011 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17012 (const_int 0))
17013 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17014 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17015 (const_int 0)))
17016 (use (match_operand:SI 3 "immediate_operand" "i"))
17017 (use (reg:CC 17))
17018 (use (reg:SI 19))
17019 (clobber (match_operand:SI 0 "register_operand" "=S"))
17020 (clobber (match_operand:SI 1 "register_operand" "=D"))
17021 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17022 "!TARGET_64BIT"
17023 "repz{\;| }cmpsb"
17024 [(set_attr "type" "str")
17025 (set_attr "mode" "QI")
17026 (set_attr "prefix_rep" "1")])
17027
17028 (define_insn "*cmpstrqi_rex_1"
17029 [(set (reg:CC 17)
17030 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17031 (const_int 0))
17032 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17033 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17034 (const_int 0)))
17035 (use (match_operand:SI 3 "immediate_operand" "i"))
17036 (use (reg:CC 17))
17037 (use (reg:SI 19))
17038 (clobber (match_operand:DI 0 "register_operand" "=S"))
17039 (clobber (match_operand:DI 1 "register_operand" "=D"))
17040 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17041 "TARGET_64BIT"
17042 "repz{\;| }cmpsb"
17043 [(set_attr "type" "str")
17044 (set_attr "mode" "QI")
17045 (set_attr "prefix_rep" "1")])
17046
17047 (define_expand "strlensi"
17048 [(set (match_operand:SI 0 "register_operand" "")
17049 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17050 (match_operand:QI 2 "immediate_operand" "")
17051 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17052 ""
17053 {
17054 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17055 DONE;
17056 else
17057 FAIL;
17058 })
17059
17060 (define_expand "strlendi"
17061 [(set (match_operand:DI 0 "register_operand" "")
17062 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17063 (match_operand:QI 2 "immediate_operand" "")
17064 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17065 ""
17066 {
17067 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17068 DONE;
17069 else
17070 FAIL;
17071 })
17072
17073 (define_expand "strlenqi_1"
17074 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17075 (use (reg:SI 19))
17076 (clobber (match_operand 1 "register_operand" ""))
17077 (clobber (reg:CC 17))])]
17078 ""
17079 "")
17080
17081 (define_insn "*strlenqi_1"
17082 [(set (match_operand:SI 0 "register_operand" "=&c")
17083 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17084 (match_operand:QI 2 "register_operand" "a")
17085 (match_operand:SI 3 "immediate_operand" "i")
17086 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17087 (use (reg:SI 19))
17088 (clobber (match_operand:SI 1 "register_operand" "=D"))
17089 (clobber (reg:CC 17))]
17090 "!TARGET_64BIT"
17091 "repnz{\;| }scasb"
17092 [(set_attr "type" "str")
17093 (set_attr "mode" "QI")
17094 (set_attr "prefix_rep" "1")])
17095
17096 (define_insn "*strlenqi_rex_1"
17097 [(set (match_operand:DI 0 "register_operand" "=&c")
17098 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17099 (match_operand:QI 2 "register_operand" "a")
17100 (match_operand:DI 3 "immediate_operand" "i")
17101 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17102 (use (reg:SI 19))
17103 (clobber (match_operand:DI 1 "register_operand" "=D"))
17104 (clobber (reg:CC 17))]
17105 "TARGET_64BIT"
17106 "repnz{\;| }scasb"
17107 [(set_attr "type" "str")
17108 (set_attr "mode" "QI")
17109 (set_attr "prefix_rep" "1")])
17110
17111 ;; Peephole optimizations to clean up after cmpstr*. This should be
17112 ;; handled in combine, but it is not currently up to the task.
17113 ;; When used for their truth value, the cmpstr* expanders generate
17114 ;; code like this:
17115 ;;
17116 ;; repz cmpsb
17117 ;; seta %al
17118 ;; setb %dl
17119 ;; cmpb %al, %dl
17120 ;; jcc label
17121 ;;
17122 ;; The intermediate three instructions are unnecessary.
17123
17124 ;; This one handles cmpstr*_nz_1...
17125 (define_peephole2
17126 [(parallel[
17127 (set (reg:CC 17)
17128 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17129 (mem:BLK (match_operand 5 "register_operand" ""))))
17130 (use (match_operand 6 "register_operand" ""))
17131 (use (match_operand:SI 3 "immediate_operand" ""))
17132 (use (reg:SI 19))
17133 (clobber (match_operand 0 "register_operand" ""))
17134 (clobber (match_operand 1 "register_operand" ""))
17135 (clobber (match_operand 2 "register_operand" ""))])
17136 (set (match_operand:QI 7 "register_operand" "")
17137 (gtu:QI (reg:CC 17) (const_int 0)))
17138 (set (match_operand:QI 8 "register_operand" "")
17139 (ltu:QI (reg:CC 17) (const_int 0)))
17140 (set (reg 17)
17141 (compare (match_dup 7) (match_dup 8)))
17142 ]
17143 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17144 [(parallel[
17145 (set (reg:CC 17)
17146 (compare:CC (mem:BLK (match_dup 4))
17147 (mem:BLK (match_dup 5))))
17148 (use (match_dup 6))
17149 (use (match_dup 3))
17150 (use (reg:SI 19))
17151 (clobber (match_dup 0))
17152 (clobber (match_dup 1))
17153 (clobber (match_dup 2))])]
17154 "")
17155
17156 ;; ...and this one handles cmpstr*_1.
17157 (define_peephole2
17158 [(parallel[
17159 (set (reg:CC 17)
17160 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17161 (const_int 0))
17162 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17163 (mem:BLK (match_operand 5 "register_operand" "")))
17164 (const_int 0)))
17165 (use (match_operand:SI 3 "immediate_operand" ""))
17166 (use (reg:CC 17))
17167 (use (reg:SI 19))
17168 (clobber (match_operand 0 "register_operand" ""))
17169 (clobber (match_operand 1 "register_operand" ""))
17170 (clobber (match_operand 2 "register_operand" ""))])
17171 (set (match_operand:QI 7 "register_operand" "")
17172 (gtu:QI (reg:CC 17) (const_int 0)))
17173 (set (match_operand:QI 8 "register_operand" "")
17174 (ltu:QI (reg:CC 17) (const_int 0)))
17175 (set (reg 17)
17176 (compare (match_dup 7) (match_dup 8)))
17177 ]
17178 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17179 [(parallel[
17180 (set (reg:CC 17)
17181 (if_then_else:CC (ne (match_dup 6)
17182 (const_int 0))
17183 (compare:CC (mem:BLK (match_dup 4))
17184 (mem:BLK (match_dup 5)))
17185 (const_int 0)))
17186 (use (match_dup 3))
17187 (use (reg:CC 17))
17188 (use (reg:SI 19))
17189 (clobber (match_dup 0))
17190 (clobber (match_dup 1))
17191 (clobber (match_dup 2))])]
17192 "")
17193
17194
17195 \f
17196 ;; Conditional move instructions.
17197
17198 (define_expand "movdicc"
17199 [(set (match_operand:DI 0 "register_operand" "")
17200 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17201 (match_operand:DI 2 "general_operand" "")
17202 (match_operand:DI 3 "general_operand" "")))]
17203 "TARGET_64BIT"
17204 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17205
17206 (define_insn "x86_movdicc_0_m1_rex64"
17207 [(set (match_operand:DI 0 "register_operand" "=r")
17208 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17209 (const_int -1)
17210 (const_int 0)))
17211 (clobber (reg:CC 17))]
17212 "TARGET_64BIT"
17213 "sbb{q}\t%0, %0"
17214 ; Since we don't have the proper number of operands for an alu insn,
17215 ; fill in all the blanks.
17216 [(set_attr "type" "alu")
17217 (set_attr "pent_pair" "pu")
17218 (set_attr "memory" "none")
17219 (set_attr "imm_disp" "false")
17220 (set_attr "mode" "DI")
17221 (set_attr "length_immediate" "0")])
17222
17223 (define_insn "movdicc_c_rex64"
17224 [(set (match_operand:DI 0 "register_operand" "=r,r")
17225 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17226 [(reg 17) (const_int 0)])
17227 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17228 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17229 "TARGET_64BIT && TARGET_CMOVE
17230 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17231 "@
17232 cmov%O2%C1\t{%2, %0|%0, %2}
17233 cmov%O2%c1\t{%3, %0|%0, %3}"
17234 [(set_attr "type" "icmov")
17235 (set_attr "mode" "DI")])
17236
17237 (define_expand "movsicc"
17238 [(set (match_operand:SI 0 "register_operand" "")
17239 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17240 (match_operand:SI 2 "general_operand" "")
17241 (match_operand:SI 3 "general_operand" "")))]
17242 ""
17243 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17244
17245 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17246 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17247 ;; So just document what we're doing explicitly.
17248
17249 (define_insn "x86_movsicc_0_m1"
17250 [(set (match_operand:SI 0 "register_operand" "=r")
17251 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17252 (const_int -1)
17253 (const_int 0)))
17254 (clobber (reg:CC 17))]
17255 ""
17256 "sbb{l}\t%0, %0"
17257 ; Since we don't have the proper number of operands for an alu insn,
17258 ; fill in all the blanks.
17259 [(set_attr "type" "alu")
17260 (set_attr "pent_pair" "pu")
17261 (set_attr "memory" "none")
17262 (set_attr "imm_disp" "false")
17263 (set_attr "mode" "SI")
17264 (set_attr "length_immediate" "0")])
17265
17266 (define_insn "*movsicc_noc"
17267 [(set (match_operand:SI 0 "register_operand" "=r,r")
17268 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17269 [(reg 17) (const_int 0)])
17270 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17271 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17272 "TARGET_CMOVE
17273 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17274 "@
17275 cmov%O2%C1\t{%2, %0|%0, %2}
17276 cmov%O2%c1\t{%3, %0|%0, %3}"
17277 [(set_attr "type" "icmov")
17278 (set_attr "mode" "SI")])
17279
17280 (define_expand "movhicc"
17281 [(set (match_operand:HI 0 "register_operand" "")
17282 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17283 (match_operand:HI 2 "general_operand" "")
17284 (match_operand:HI 3 "general_operand" "")))]
17285 "TARGET_HIMODE_MATH"
17286 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17287
17288 (define_insn "*movhicc_noc"
17289 [(set (match_operand:HI 0 "register_operand" "=r,r")
17290 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17291 [(reg 17) (const_int 0)])
17292 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17293 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17294 "TARGET_CMOVE
17295 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17296 "@
17297 cmov%O2%C1\t{%2, %0|%0, %2}
17298 cmov%O2%c1\t{%3, %0|%0, %3}"
17299 [(set_attr "type" "icmov")
17300 (set_attr "mode" "HI")])
17301
17302 (define_expand "movqicc"
17303 [(set (match_operand:QI 0 "register_operand" "")
17304 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17305 (match_operand:QI 2 "general_operand" "")
17306 (match_operand:QI 3 "general_operand" "")))]
17307 "TARGET_QIMODE_MATH"
17308 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17309
17310 (define_insn_and_split "*movqicc_noc"
17311 [(set (match_operand:QI 0 "register_operand" "=r,r")
17312 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17313 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17314 (match_operand:QI 2 "register_operand" "r,0")
17315 (match_operand:QI 3 "register_operand" "0,r")))]
17316 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17317 "#"
17318 "&& reload_completed"
17319 [(set (match_dup 0)
17320 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17321 (match_dup 2)
17322 (match_dup 3)))]
17323 "operands[0] = gen_lowpart (SImode, operands[0]);
17324 operands[2] = gen_lowpart (SImode, operands[2]);
17325 operands[3] = gen_lowpart (SImode, operands[3]);"
17326 [(set_attr "type" "icmov")
17327 (set_attr "mode" "SI")])
17328
17329 (define_expand "movsfcc"
17330 [(set (match_operand:SF 0 "register_operand" "")
17331 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17332 (match_operand:SF 2 "register_operand" "")
17333 (match_operand:SF 3 "register_operand" "")))]
17334 "TARGET_CMOVE"
17335 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17336
17337 (define_insn "*movsfcc_1"
17338 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17339 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17340 [(reg 17) (const_int 0)])
17341 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17342 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17343 "TARGET_CMOVE
17344 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17345 "@
17346 fcmov%F1\t{%2, %0|%0, %2}
17347 fcmov%f1\t{%3, %0|%0, %3}
17348 cmov%O2%C1\t{%2, %0|%0, %2}
17349 cmov%O2%c1\t{%3, %0|%0, %3}"
17350 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17351 (set_attr "mode" "SF,SF,SI,SI")])
17352
17353 (define_expand "movdfcc"
17354 [(set (match_operand:DF 0 "register_operand" "")
17355 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17356 (match_operand:DF 2 "register_operand" "")
17357 (match_operand:DF 3 "register_operand" "")))]
17358 "TARGET_CMOVE"
17359 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17360
17361 (define_insn "*movdfcc_1"
17362 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17363 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17364 [(reg 17) (const_int 0)])
17365 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17366 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17367 "!TARGET_64BIT && TARGET_CMOVE
17368 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17369 "@
17370 fcmov%F1\t{%2, %0|%0, %2}
17371 fcmov%f1\t{%3, %0|%0, %3}
17372 #
17373 #"
17374 [(set_attr "type" "fcmov,fcmov,multi,multi")
17375 (set_attr "mode" "DF")])
17376
17377 (define_insn "*movdfcc_1_rex64"
17378 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17379 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17380 [(reg 17) (const_int 0)])
17381 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17382 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17383 "TARGET_64BIT && TARGET_CMOVE
17384 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17385 "@
17386 fcmov%F1\t{%2, %0|%0, %2}
17387 fcmov%f1\t{%3, %0|%0, %3}
17388 cmov%O2%C1\t{%2, %0|%0, %2}
17389 cmov%O2%c1\t{%3, %0|%0, %3}"
17390 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17391 (set_attr "mode" "DF")])
17392
17393 (define_split
17394 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17395 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17396 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17397 (match_operand:DF 2 "nonimmediate_operand" "")
17398 (match_operand:DF 3 "nonimmediate_operand" "")))]
17399 "!TARGET_64BIT && reload_completed"
17400 [(set (match_dup 2)
17401 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17402 (match_dup 5)
17403 (match_dup 7)))
17404 (set (match_dup 3)
17405 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17406 (match_dup 6)
17407 (match_dup 8)))]
17408 "split_di (operands+2, 1, operands+5, operands+6);
17409 split_di (operands+3, 1, operands+7, operands+8);
17410 split_di (operands, 1, operands+2, operands+3);")
17411
17412 (define_expand "movxfcc"
17413 [(set (match_operand:XF 0 "register_operand" "")
17414 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17415 (match_operand:XF 2 "register_operand" "")
17416 (match_operand:XF 3 "register_operand" "")))]
17417 "TARGET_CMOVE"
17418 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17419
17420 (define_insn "*movxfcc_1"
17421 [(set (match_operand:XF 0 "register_operand" "=f,f")
17422 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17423 [(reg 17) (const_int 0)])
17424 (match_operand:XF 2 "register_operand" "f,0")
17425 (match_operand:XF 3 "register_operand" "0,f")))]
17426 "TARGET_CMOVE"
17427 "@
17428 fcmov%F1\t{%2, %0|%0, %2}
17429 fcmov%f1\t{%3, %0|%0, %3}"
17430 [(set_attr "type" "fcmov")
17431 (set_attr "mode" "XF")])
17432
17433 (define_expand "minsf3"
17434 [(parallel [
17435 (set (match_operand:SF 0 "register_operand" "")
17436 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17437 (match_operand:SF 2 "nonimmediate_operand" ""))
17438 (match_dup 1)
17439 (match_dup 2)))
17440 (clobber (reg:CC 17))])]
17441 "TARGET_SSE"
17442 "")
17443
17444 (define_insn "*minsf"
17445 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17446 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17447 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17448 (match_dup 1)
17449 (match_dup 2)))
17450 (clobber (reg:CC 17))]
17451 "TARGET_SSE && TARGET_IEEE_FP"
17452 "#")
17453
17454 (define_insn "*minsf_nonieee"
17455 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17456 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17457 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17458 (match_dup 1)
17459 (match_dup 2)))
17460 (clobber (reg:CC 17))]
17461 "TARGET_SSE && !TARGET_IEEE_FP
17462 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17463 "#")
17464
17465 (define_split
17466 [(set (match_operand:SF 0 "register_operand" "")
17467 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17468 (match_operand:SF 2 "nonimmediate_operand" ""))
17469 (match_operand:SF 3 "register_operand" "")
17470 (match_operand:SF 4 "nonimmediate_operand" "")))
17471 (clobber (reg:CC 17))]
17472 "SSE_REG_P (operands[0]) && reload_completed
17473 && ((operands_match_p (operands[1], operands[3])
17474 && operands_match_p (operands[2], operands[4]))
17475 || (operands_match_p (operands[1], operands[4])
17476 && operands_match_p (operands[2], operands[3])))"
17477 [(set (match_dup 0)
17478 (if_then_else:SF (lt (match_dup 1)
17479 (match_dup 2))
17480 (match_dup 1)
17481 (match_dup 2)))])
17482
17483 ;; Conditional addition patterns
17484 (define_expand "addqicc"
17485 [(match_operand:QI 0 "register_operand" "")
17486 (match_operand 1 "comparison_operator" "")
17487 (match_operand:QI 2 "register_operand" "")
17488 (match_operand:QI 3 "const_int_operand" "")]
17489 ""
17490 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17491
17492 (define_expand "addhicc"
17493 [(match_operand:HI 0 "register_operand" "")
17494 (match_operand 1 "comparison_operator" "")
17495 (match_operand:HI 2 "register_operand" "")
17496 (match_operand:HI 3 "const_int_operand" "")]
17497 ""
17498 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17499
17500 (define_expand "addsicc"
17501 [(match_operand:SI 0 "register_operand" "")
17502 (match_operand 1 "comparison_operator" "")
17503 (match_operand:SI 2 "register_operand" "")
17504 (match_operand:SI 3 "const_int_operand" "")]
17505 ""
17506 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17507
17508 (define_expand "adddicc"
17509 [(match_operand:DI 0 "register_operand" "")
17510 (match_operand 1 "comparison_operator" "")
17511 (match_operand:DI 2 "register_operand" "")
17512 (match_operand:DI 3 "const_int_operand" "")]
17513 "TARGET_64BIT"
17514 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17515
17516 ;; We can't represent the LT test directly. Do this by swapping the operands.
17517
17518 (define_split
17519 [(set (match_operand:SF 0 "fp_register_operand" "")
17520 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17521 (match_operand:SF 2 "register_operand" ""))
17522 (match_operand:SF 3 "register_operand" "")
17523 (match_operand:SF 4 "register_operand" "")))
17524 (clobber (reg:CC 17))]
17525 "reload_completed
17526 && ((operands_match_p (operands[1], operands[3])
17527 && operands_match_p (operands[2], operands[4]))
17528 || (operands_match_p (operands[1], operands[4])
17529 && operands_match_p (operands[2], operands[3])))"
17530 [(set (reg:CCFP 17)
17531 (compare:CCFP (match_dup 2)
17532 (match_dup 1)))
17533 (set (match_dup 0)
17534 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17535 (match_dup 1)
17536 (match_dup 2)))])
17537
17538 (define_insn "*minsf_sse"
17539 [(set (match_operand:SF 0 "register_operand" "=x")
17540 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17541 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17542 (match_dup 1)
17543 (match_dup 2)))]
17544 "TARGET_SSE && reload_completed"
17545 "minss\t{%2, %0|%0, %2}"
17546 [(set_attr "type" "sse")
17547 (set_attr "mode" "SF")])
17548
17549 (define_expand "mindf3"
17550 [(parallel [
17551 (set (match_operand:DF 0 "register_operand" "")
17552 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17553 (match_operand:DF 2 "nonimmediate_operand" ""))
17554 (match_dup 1)
17555 (match_dup 2)))
17556 (clobber (reg:CC 17))])]
17557 "TARGET_SSE2 && TARGET_SSE_MATH"
17558 "#")
17559
17560 (define_insn "*mindf"
17561 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17562 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17563 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17564 (match_dup 1)
17565 (match_dup 2)))
17566 (clobber (reg:CC 17))]
17567 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17568 "#")
17569
17570 (define_insn "*mindf_nonieee"
17571 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17572 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17573 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17574 (match_dup 1)
17575 (match_dup 2)))
17576 (clobber (reg:CC 17))]
17577 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17578 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17579 "#")
17580
17581 (define_split
17582 [(set (match_operand:DF 0 "register_operand" "")
17583 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17584 (match_operand:DF 2 "nonimmediate_operand" ""))
17585 (match_operand:DF 3 "register_operand" "")
17586 (match_operand:DF 4 "nonimmediate_operand" "")))
17587 (clobber (reg:CC 17))]
17588 "SSE_REG_P (operands[0]) && reload_completed
17589 && ((operands_match_p (operands[1], operands[3])
17590 && operands_match_p (operands[2], operands[4]))
17591 || (operands_match_p (operands[1], operands[4])
17592 && operands_match_p (operands[2], operands[3])))"
17593 [(set (match_dup 0)
17594 (if_then_else:DF (lt (match_dup 1)
17595 (match_dup 2))
17596 (match_dup 1)
17597 (match_dup 2)))])
17598
17599 ;; We can't represent the LT test directly. Do this by swapping the operands.
17600 (define_split
17601 [(set (match_operand:DF 0 "fp_register_operand" "")
17602 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17603 (match_operand:DF 2 "register_operand" ""))
17604 (match_operand:DF 3 "register_operand" "")
17605 (match_operand:DF 4 "register_operand" "")))
17606 (clobber (reg:CC 17))]
17607 "reload_completed
17608 && ((operands_match_p (operands[1], operands[3])
17609 && operands_match_p (operands[2], operands[4]))
17610 || (operands_match_p (operands[1], operands[4])
17611 && operands_match_p (operands[2], operands[3])))"
17612 [(set (reg:CCFP 17)
17613 (compare:CCFP (match_dup 2)
17614 (match_dup 1)))
17615 (set (match_dup 0)
17616 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17617 (match_dup 1)
17618 (match_dup 2)))])
17619
17620 (define_insn "*mindf_sse"
17621 [(set (match_operand:DF 0 "register_operand" "=Y")
17622 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17623 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17624 (match_dup 1)
17625 (match_dup 2)))]
17626 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17627 "minsd\t{%2, %0|%0, %2}"
17628 [(set_attr "type" "sse")
17629 (set_attr "mode" "DF")])
17630
17631 (define_expand "maxsf3"
17632 [(parallel [
17633 (set (match_operand:SF 0 "register_operand" "")
17634 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17635 (match_operand:SF 2 "nonimmediate_operand" ""))
17636 (match_dup 1)
17637 (match_dup 2)))
17638 (clobber (reg:CC 17))])]
17639 "TARGET_SSE"
17640 "#")
17641
17642 (define_insn "*maxsf"
17643 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17644 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17645 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17646 (match_dup 1)
17647 (match_dup 2)))
17648 (clobber (reg:CC 17))]
17649 "TARGET_SSE && TARGET_IEEE_FP"
17650 "#")
17651
17652 (define_insn "*maxsf_nonieee"
17653 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17654 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17655 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17656 (match_dup 1)
17657 (match_dup 2)))
17658 (clobber (reg:CC 17))]
17659 "TARGET_SSE && !TARGET_IEEE_FP
17660 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17661 "#")
17662
17663 (define_split
17664 [(set (match_operand:SF 0 "register_operand" "")
17665 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17666 (match_operand:SF 2 "nonimmediate_operand" ""))
17667 (match_operand:SF 3 "register_operand" "")
17668 (match_operand:SF 4 "nonimmediate_operand" "")))
17669 (clobber (reg:CC 17))]
17670 "SSE_REG_P (operands[0]) && reload_completed
17671 && ((operands_match_p (operands[1], operands[3])
17672 && operands_match_p (operands[2], operands[4]))
17673 || (operands_match_p (operands[1], operands[4])
17674 && operands_match_p (operands[2], operands[3])))"
17675 [(set (match_dup 0)
17676 (if_then_else:SF (gt (match_dup 1)
17677 (match_dup 2))
17678 (match_dup 1)
17679 (match_dup 2)))])
17680
17681 (define_split
17682 [(set (match_operand:SF 0 "fp_register_operand" "")
17683 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17684 (match_operand:SF 2 "register_operand" ""))
17685 (match_operand:SF 3 "register_operand" "")
17686 (match_operand:SF 4 "register_operand" "")))
17687 (clobber (reg:CC 17))]
17688 "reload_completed
17689 && ((operands_match_p (operands[1], operands[3])
17690 && operands_match_p (operands[2], operands[4]))
17691 || (operands_match_p (operands[1], operands[4])
17692 && operands_match_p (operands[2], operands[3])))"
17693 [(set (reg:CCFP 17)
17694 (compare:CCFP (match_dup 1)
17695 (match_dup 2)))
17696 (set (match_dup 0)
17697 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17698 (match_dup 1)
17699 (match_dup 2)))])
17700
17701 (define_insn "*maxsf_sse"
17702 [(set (match_operand:SF 0 "register_operand" "=x")
17703 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17704 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17705 (match_dup 1)
17706 (match_dup 2)))]
17707 "TARGET_SSE && reload_completed"
17708 "maxss\t{%2, %0|%0, %2}"
17709 [(set_attr "type" "sse")
17710 (set_attr "mode" "SF")])
17711
17712 (define_expand "maxdf3"
17713 [(parallel [
17714 (set (match_operand:DF 0 "register_operand" "")
17715 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17716 (match_operand:DF 2 "nonimmediate_operand" ""))
17717 (match_dup 1)
17718 (match_dup 2)))
17719 (clobber (reg:CC 17))])]
17720 "TARGET_SSE2 && TARGET_SSE_MATH"
17721 "#")
17722
17723 (define_insn "*maxdf"
17724 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17725 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17726 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17727 (match_dup 1)
17728 (match_dup 2)))
17729 (clobber (reg:CC 17))]
17730 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17731 "#")
17732
17733 (define_insn "*maxdf_nonieee"
17734 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17735 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17736 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17737 (match_dup 1)
17738 (match_dup 2)))
17739 (clobber (reg:CC 17))]
17740 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17741 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17742 "#")
17743
17744 (define_split
17745 [(set (match_operand:DF 0 "register_operand" "")
17746 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17747 (match_operand:DF 2 "nonimmediate_operand" ""))
17748 (match_operand:DF 3 "register_operand" "")
17749 (match_operand:DF 4 "nonimmediate_operand" "")))
17750 (clobber (reg:CC 17))]
17751 "SSE_REG_P (operands[0]) && reload_completed
17752 && ((operands_match_p (operands[1], operands[3])
17753 && operands_match_p (operands[2], operands[4]))
17754 || (operands_match_p (operands[1], operands[4])
17755 && operands_match_p (operands[2], operands[3])))"
17756 [(set (match_dup 0)
17757 (if_then_else:DF (gt (match_dup 1)
17758 (match_dup 2))
17759 (match_dup 1)
17760 (match_dup 2)))])
17761
17762 (define_split
17763 [(set (match_operand:DF 0 "fp_register_operand" "")
17764 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17765 (match_operand:DF 2 "register_operand" ""))
17766 (match_operand:DF 3 "register_operand" "")
17767 (match_operand:DF 4 "register_operand" "")))
17768 (clobber (reg:CC 17))]
17769 "reload_completed
17770 && ((operands_match_p (operands[1], operands[3])
17771 && operands_match_p (operands[2], operands[4]))
17772 || (operands_match_p (operands[1], operands[4])
17773 && operands_match_p (operands[2], operands[3])))"
17774 [(set (reg:CCFP 17)
17775 (compare:CCFP (match_dup 1)
17776 (match_dup 2)))
17777 (set (match_dup 0)
17778 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17779 (match_dup 1)
17780 (match_dup 2)))])
17781
17782 (define_insn "*maxdf_sse"
17783 [(set (match_operand:DF 0 "register_operand" "=Y")
17784 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17785 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17786 (match_dup 1)
17787 (match_dup 2)))]
17788 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17789 "maxsd\t{%2, %0|%0, %2}"
17790 [(set_attr "type" "sse")
17791 (set_attr "mode" "DF")])
17792 \f
17793 ;; Misc patterns (?)
17794
17795 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17796 ;; Otherwise there will be nothing to keep
17797 ;;
17798 ;; [(set (reg ebp) (reg esp))]
17799 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17800 ;; (clobber (eflags)]
17801 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17802 ;;
17803 ;; in proper program order.
17804 (define_insn "pro_epilogue_adjust_stack_1"
17805 [(set (match_operand:SI 0 "register_operand" "=r,r")
17806 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17807 (match_operand:SI 2 "immediate_operand" "i,i")))
17808 (clobber (reg:CC 17))
17809 (clobber (mem:BLK (scratch)))]
17810 "!TARGET_64BIT"
17811 {
17812 switch (get_attr_type (insn))
17813 {
17814 case TYPE_IMOV:
17815 return "mov{l}\t{%1, %0|%0, %1}";
17816
17817 case TYPE_ALU:
17818 if (GET_CODE (operands[2]) == CONST_INT
17819 && (INTVAL (operands[2]) == 128
17820 || (INTVAL (operands[2]) < 0
17821 && INTVAL (operands[2]) != -128)))
17822 {
17823 operands[2] = GEN_INT (-INTVAL (operands[2]));
17824 return "sub{l}\t{%2, %0|%0, %2}";
17825 }
17826 return "add{l}\t{%2, %0|%0, %2}";
17827
17828 case TYPE_LEA:
17829 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17830 return "lea{l}\t{%a2, %0|%0, %a2}";
17831
17832 default:
17833 abort ();
17834 }
17835 }
17836 [(set (attr "type")
17837 (cond [(eq_attr "alternative" "0")
17838 (const_string "alu")
17839 (match_operand:SI 2 "const0_operand" "")
17840 (const_string "imov")
17841 ]
17842 (const_string "lea")))
17843 (set_attr "mode" "SI")])
17844
17845 (define_insn "pro_epilogue_adjust_stack_rex64"
17846 [(set (match_operand:DI 0 "register_operand" "=r,r")
17847 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17848 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17849 (clobber (reg:CC 17))
17850 (clobber (mem:BLK (scratch)))]
17851 "TARGET_64BIT"
17852 {
17853 switch (get_attr_type (insn))
17854 {
17855 case TYPE_IMOV:
17856 return "mov{q}\t{%1, %0|%0, %1}";
17857
17858 case TYPE_ALU:
17859 if (GET_CODE (operands[2]) == CONST_INT
17860 /* Avoid overflows. */
17861 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17862 && (INTVAL (operands[2]) == 128
17863 || (INTVAL (operands[2]) < 0
17864 && INTVAL (operands[2]) != -128)))
17865 {
17866 operands[2] = GEN_INT (-INTVAL (operands[2]));
17867 return "sub{q}\t{%2, %0|%0, %2}";
17868 }
17869 return "add{q}\t{%2, %0|%0, %2}";
17870
17871 case TYPE_LEA:
17872 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17873 return "lea{q}\t{%a2, %0|%0, %a2}";
17874
17875 default:
17876 abort ();
17877 }
17878 }
17879 [(set (attr "type")
17880 (cond [(eq_attr "alternative" "0")
17881 (const_string "alu")
17882 (match_operand:DI 2 "const0_operand" "")
17883 (const_string "imov")
17884 ]
17885 (const_string "lea")))
17886 (set_attr "mode" "DI")])
17887
17888 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17889 [(set (match_operand:DI 0 "register_operand" "=r,r")
17890 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17891 (match_operand:DI 3 "immediate_operand" "i,i")))
17892 (use (match_operand:DI 2 "register_operand" "r,r"))
17893 (clobber (reg:CC 17))
17894 (clobber (mem:BLK (scratch)))]
17895 "TARGET_64BIT"
17896 {
17897 switch (get_attr_type (insn))
17898 {
17899 case TYPE_ALU:
17900 return "add{q}\t{%2, %0|%0, %2}";
17901
17902 case TYPE_LEA:
17903 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17904 return "lea{q}\t{%a2, %0|%0, %a2}";
17905
17906 default:
17907 abort ();
17908 }
17909 }
17910 [(set_attr "type" "alu,lea")
17911 (set_attr "mode" "DI")])
17912
17913 ;; Placeholder for the conditional moves. This one is split either to SSE
17914 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17915 ;; fact is that compares supported by the cmp??ss instructions are exactly
17916 ;; swapped of those supported by cmove sequence.
17917 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17918 ;; supported by i387 comparisons and we do need to emit two conditional moves
17919 ;; in tandem.
17920
17921 (define_insn "sse_movsfcc"
17922 [(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")
17923 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17924 [(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")
17925 (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")])
17926 (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")
17927 (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")))
17928 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17929 (clobber (reg:CC 17))]
17930 "TARGET_SSE
17931 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17932 /* Avoid combine from being smart and converting min/max
17933 instruction patterns into conditional moves. */
17934 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17935 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17936 || !rtx_equal_p (operands[4], operands[2])
17937 || !rtx_equal_p (operands[5], operands[3]))
17938 && (!TARGET_IEEE_FP
17939 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17940 "#")
17941
17942 (define_insn "sse_movsfcc_eq"
17943 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17944 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17945 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17946 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17947 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17948 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17949 (clobber (reg:CC 17))]
17950 "TARGET_SSE
17951 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17952 "#")
17953
17954 (define_insn "sse_movdfcc"
17955 [(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")
17956 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17957 [(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")
17958 (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")])
17959 (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")
17960 (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")))
17961 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17962 (clobber (reg:CC 17))]
17963 "TARGET_SSE2
17964 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17965 /* Avoid combine from being smart and converting min/max
17966 instruction patterns into conditional moves. */
17967 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17968 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17969 || !rtx_equal_p (operands[4], operands[2])
17970 || !rtx_equal_p (operands[5], operands[3]))
17971 && (!TARGET_IEEE_FP
17972 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17973 "#")
17974
17975 (define_insn "sse_movdfcc_eq"
17976 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17977 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17978 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17979 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17980 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17981 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17982 (clobber (reg:CC 17))]
17983 "TARGET_SSE
17984 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17985 "#")
17986
17987 ;; For non-sse moves just expand the usual cmove sequence.
17988 (define_split
17989 [(set (match_operand 0 "register_operand" "")
17990 (if_then_else (match_operator 1 "comparison_operator"
17991 [(match_operand 4 "nonimmediate_operand" "")
17992 (match_operand 5 "register_operand" "")])
17993 (match_operand 2 "nonimmediate_operand" "")
17994 (match_operand 3 "nonimmediate_operand" "")))
17995 (clobber (match_operand 6 "" ""))
17996 (clobber (reg:CC 17))]
17997 "!SSE_REG_P (operands[0]) && reload_completed
17998 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17999 [(const_int 0)]
18000 {
18001 ix86_compare_op0 = operands[5];
18002 ix86_compare_op1 = operands[4];
18003 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18004 VOIDmode, operands[5], operands[4]);
18005 ix86_expand_fp_movcc (operands);
18006 DONE;
18007 })
18008
18009 ;; Split SSE based conditional move into sequence:
18010 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
18011 ;; and op2, op0 - zero op2 if comparison was false
18012 ;; nand op0, op3 - load op3 to op0 if comparison was false
18013 ;; or op2, op0 - get the nonzero one into the result.
18014 (define_split
18015 [(set (match_operand:SF 0 "register_operand" "")
18016 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18017 [(match_operand:SF 4 "register_operand" "")
18018 (match_operand:SF 5 "nonimmediate_operand" "")])
18019 (match_operand:SF 2 "register_operand" "")
18020 (match_operand:SF 3 "register_operand" "")))
18021 (clobber (match_operand 6 "" ""))
18022 (clobber (reg:CC 17))]
18023 "SSE_REG_P (operands[0]) && reload_completed"
18024 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18025 (set (match_dup 2) (and:V4SF (match_dup 2)
18026 (match_dup 8)))
18027 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18028 (match_dup 3)))
18029 (set (match_dup 0) (ior:V4SF (match_dup 6)
18030 (match_dup 7)))]
18031 {
18032 /* If op2 == op3, op3 would be clobbered before it is used. */
18033 if (operands_match_p (operands[2], operands[3]))
18034 {
18035 emit_move_insn (operands[0], operands[2]);
18036 DONE;
18037 }
18038
18039 PUT_MODE (operands[1], GET_MODE (operands[0]));
18040 if (operands_match_p (operands[0], operands[4]))
18041 operands[6] = operands[4], operands[7] = operands[2];
18042 else
18043 operands[6] = operands[2], operands[7] = operands[4];
18044 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18045 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18046 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18047 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18048 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18049 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18050 })
18051
18052 (define_split
18053 [(set (match_operand:DF 0 "register_operand" "")
18054 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18055 [(match_operand:DF 4 "register_operand" "")
18056 (match_operand:DF 5 "nonimmediate_operand" "")])
18057 (match_operand:DF 2 "register_operand" "")
18058 (match_operand:DF 3 "register_operand" "")))
18059 (clobber (match_operand 6 "" ""))
18060 (clobber (reg:CC 17))]
18061 "SSE_REG_P (operands[0]) && reload_completed"
18062 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18063 (set (match_dup 2) (and:V2DF (match_dup 2)
18064 (match_dup 8)))
18065 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18066 (match_dup 3)))
18067 (set (match_dup 0) (ior:V2DF (match_dup 6)
18068 (match_dup 7)))]
18069 {
18070 if (GET_MODE (operands[2]) == DFmode
18071 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18072 {
18073 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18074 emit_insn (gen_sse2_unpcklpd (op, op, op));
18075 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18076 emit_insn (gen_sse2_unpcklpd (op, op, op));
18077 }
18078
18079 /* If op2 == op3, op3 would be clobbered before it is used. */
18080 if (operands_match_p (operands[2], operands[3]))
18081 {
18082 emit_move_insn (operands[0], operands[2]);
18083 DONE;
18084 }
18085
18086 PUT_MODE (operands[1], GET_MODE (operands[0]));
18087 if (operands_match_p (operands[0], operands[4]))
18088 operands[6] = operands[4], operands[7] = operands[2];
18089 else
18090 operands[6] = operands[2], operands[7] = operands[4];
18091 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18092 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18093 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18094 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18095 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18096 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18097 })
18098
18099 ;; Special case of conditional move we can handle effectively.
18100 ;; Do not brother with the integer/floating point case, since these are
18101 ;; bot considerably slower, unlike in the generic case.
18102 (define_insn "*sse_movsfcc_const0_1"
18103 [(set (match_operand:SF 0 "register_operand" "=&x")
18104 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18105 [(match_operand:SF 4 "register_operand" "0")
18106 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18107 (match_operand:SF 2 "register_operand" "x")
18108 (match_operand:SF 3 "const0_operand" "X")))]
18109 "TARGET_SSE"
18110 "#")
18111
18112 (define_insn "*sse_movsfcc_const0_2"
18113 [(set (match_operand:SF 0 "register_operand" "=&x")
18114 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18115 [(match_operand:SF 4 "register_operand" "0")
18116 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18117 (match_operand:SF 2 "const0_operand" "X")
18118 (match_operand:SF 3 "register_operand" "x")))]
18119 "TARGET_SSE"
18120 "#")
18121
18122 (define_insn "*sse_movsfcc_const0_3"
18123 [(set (match_operand:SF 0 "register_operand" "=&x")
18124 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18125 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18126 (match_operand:SF 5 "register_operand" "0")])
18127 (match_operand:SF 2 "register_operand" "x")
18128 (match_operand:SF 3 "const0_operand" "X")))]
18129 "TARGET_SSE"
18130 "#")
18131
18132 (define_insn "*sse_movsfcc_const0_4"
18133 [(set (match_operand:SF 0 "register_operand" "=&x")
18134 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18135 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18136 (match_operand:SF 5 "register_operand" "0")])
18137 (match_operand:SF 2 "const0_operand" "X")
18138 (match_operand:SF 3 "register_operand" "x")))]
18139 "TARGET_SSE"
18140 "#")
18141
18142 (define_insn "*sse_movdfcc_const0_1"
18143 [(set (match_operand:DF 0 "register_operand" "=&Y")
18144 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18145 [(match_operand:DF 4 "register_operand" "0")
18146 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18147 (match_operand:DF 2 "register_operand" "Y")
18148 (match_operand:DF 3 "const0_operand" "X")))]
18149 "TARGET_SSE2"
18150 "#")
18151
18152 (define_insn "*sse_movdfcc_const0_2"
18153 [(set (match_operand:DF 0 "register_operand" "=&Y")
18154 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18155 [(match_operand:DF 4 "register_operand" "0")
18156 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18157 (match_operand:DF 2 "const0_operand" "X")
18158 (match_operand:DF 3 "register_operand" "Y")))]
18159 "TARGET_SSE2"
18160 "#")
18161
18162 (define_insn "*sse_movdfcc_const0_3"
18163 [(set (match_operand:DF 0 "register_operand" "=&Y")
18164 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18165 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18166 (match_operand:DF 5 "register_operand" "0")])
18167 (match_operand:DF 2 "register_operand" "Y")
18168 (match_operand:DF 3 "const0_operand" "X")))]
18169 "TARGET_SSE2"
18170 "#")
18171
18172 (define_insn "*sse_movdfcc_const0_4"
18173 [(set (match_operand:DF 0 "register_operand" "=&Y")
18174 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18175 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18176 (match_operand:DF 5 "register_operand" "0")])
18177 (match_operand:DF 2 "const0_operand" "X")
18178 (match_operand:DF 3 "register_operand" "Y")))]
18179 "TARGET_SSE2"
18180 "#")
18181
18182 (define_split
18183 [(set (match_operand:SF 0 "register_operand" "")
18184 (if_then_else (match_operator:SF 1 "comparison_operator"
18185 [(match_operand:SF 4 "nonimmediate_operand" "")
18186 (match_operand:SF 5 "nonimmediate_operand" "")])
18187 (match_operand:SF 2 "nonmemory_operand" "")
18188 (match_operand:SF 3 "nonmemory_operand" "")))]
18189 "SSE_REG_P (operands[0]) && reload_completed
18190 && (const0_operand (operands[2], GET_MODE (operands[0]))
18191 || const0_operand (operands[3], GET_MODE (operands[0])))"
18192 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18193 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18194 {
18195 PUT_MODE (operands[1], GET_MODE (operands[0]));
18196 if (!sse_comparison_operator (operands[1], VOIDmode)
18197 || !rtx_equal_p (operands[0], operands[4]))
18198 {
18199 rtx tmp = operands[5];
18200 operands[5] = operands[4];
18201 operands[4] = tmp;
18202 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18203 }
18204 if (!rtx_equal_p (operands[0], operands[4]))
18205 abort ();
18206 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18207 if (const0_operand (operands[2], GET_MODE (operands[2])))
18208 {
18209 operands[7] = operands[3];
18210 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
18211 }
18212 else
18213 {
18214 operands[7] = operands[2];
18215 operands[6] = operands[0];
18216 }
18217 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18218 })
18219
18220 (define_split
18221 [(set (match_operand:DF 0 "register_operand" "")
18222 (if_then_else (match_operator:DF 1 "comparison_operator"
18223 [(match_operand:DF 4 "nonimmediate_operand" "")
18224 (match_operand:DF 5 "nonimmediate_operand" "")])
18225 (match_operand:DF 2 "nonmemory_operand" "")
18226 (match_operand:DF 3 "nonmemory_operand" "")))]
18227 "SSE_REG_P (operands[0]) && reload_completed
18228 && (const0_operand (operands[2], GET_MODE (operands[0]))
18229 || const0_operand (operands[3], GET_MODE (operands[0])))"
18230 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18231 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18232 {
18233 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18234 && GET_MODE (operands[2]) == DFmode)
18235 {
18236 if (REG_P (operands[2]))
18237 {
18238 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18239 emit_insn (gen_sse2_unpcklpd (op, op, op));
18240 }
18241 if (REG_P (operands[3]))
18242 {
18243 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18244 emit_insn (gen_sse2_unpcklpd (op, op, op));
18245 }
18246 }
18247 PUT_MODE (operands[1], GET_MODE (operands[0]));
18248 if (!sse_comparison_operator (operands[1], VOIDmode)
18249 || !rtx_equal_p (operands[0], operands[4]))
18250 {
18251 rtx tmp = operands[5];
18252 operands[5] = operands[4];
18253 operands[4] = tmp;
18254 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18255 }
18256 if (!rtx_equal_p (operands[0], operands[4]))
18257 abort ();
18258 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18259 if (const0_operand (operands[2], GET_MODE (operands[2])))
18260 {
18261 operands[7] = operands[3];
18262 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18263 }
18264 else
18265 {
18266 operands[7] = operands[2];
18267 operands[6] = operands[8];
18268 }
18269 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18270 })
18271
18272 (define_expand "allocate_stack_worker"
18273 [(match_operand:SI 0 "register_operand" "")]
18274 "TARGET_STACK_PROBE"
18275 {
18276 if (reload_completed)
18277 {
18278 if (TARGET_64BIT)
18279 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18280 else
18281 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18282 }
18283 else
18284 {
18285 if (TARGET_64BIT)
18286 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18287 else
18288 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18289 }
18290 DONE;
18291 })
18292
18293 (define_insn "allocate_stack_worker_1"
18294 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18295 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
18296 (clobber (match_scratch:SI 1 "=0"))
18297 (clobber (reg:CC 17))]
18298 "!TARGET_64BIT && TARGET_STACK_PROBE"
18299 "call\t__alloca"
18300 [(set_attr "type" "multi")
18301 (set_attr "length" "5")])
18302
18303 (define_expand "allocate_stack_worker_postreload"
18304 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
18305 UNSPEC_STACK_PROBE)
18306 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
18307 (clobber (match_dup 0))
18308 (clobber (reg:CC 17))])]
18309 ""
18310 "")
18311
18312 (define_insn "allocate_stack_worker_rex64"
18313 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18314 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
18315 (clobber (match_scratch:DI 1 "=0"))
18316 (clobber (reg:CC 17))]
18317 "TARGET_64BIT && TARGET_STACK_PROBE"
18318 "call\t__alloca"
18319 [(set_attr "type" "multi")
18320 (set_attr "length" "5")])
18321
18322 (define_expand "allocate_stack_worker_rex64_postreload"
18323 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
18324 UNSPEC_STACK_PROBE)
18325 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
18326 (clobber (match_dup 0))
18327 (clobber (reg:CC 17))])]
18328 ""
18329 "")
18330
18331 (define_expand "allocate_stack"
18332 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18333 (minus:SI (reg:SI 7)
18334 (match_operand:SI 1 "general_operand" "")))
18335 (clobber (reg:CC 17))])
18336 (parallel [(set (reg:SI 7)
18337 (minus:SI (reg:SI 7) (match_dup 1)))
18338 (clobber (reg:CC 17))])]
18339 "TARGET_STACK_PROBE"
18340 {
18341 #ifdef CHECK_STACK_LIMIT
18342 if (GET_CODE (operands[1]) == CONST_INT
18343 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18344 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18345 operands[1]));
18346 else
18347 #endif
18348 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18349 operands[1])));
18350
18351 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18352 DONE;
18353 })
18354
18355 (define_expand "builtin_setjmp_receiver"
18356 [(label_ref (match_operand 0 "" ""))]
18357 "!TARGET_64BIT && flag_pic"
18358 {
18359 emit_insn (gen_set_got (pic_offset_table_rtx));
18360 DONE;
18361 })
18362 \f
18363 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18364
18365 (define_split
18366 [(set (match_operand 0 "register_operand" "")
18367 (match_operator 3 "promotable_binary_operator"
18368 [(match_operand 1 "register_operand" "")
18369 (match_operand 2 "aligned_operand" "")]))
18370 (clobber (reg:CC 17))]
18371 "! TARGET_PARTIAL_REG_STALL && reload_completed
18372 && ((GET_MODE (operands[0]) == HImode
18373 && ((!optimize_size && !TARGET_FAST_PREFIX)
18374 || GET_CODE (operands[2]) != CONST_INT
18375 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18376 || (GET_MODE (operands[0]) == QImode
18377 && (TARGET_PROMOTE_QImode || optimize_size)))"
18378 [(parallel [(set (match_dup 0)
18379 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18380 (clobber (reg:CC 17))])]
18381 "operands[0] = gen_lowpart (SImode, operands[0]);
18382 operands[1] = gen_lowpart (SImode, operands[1]);
18383 if (GET_CODE (operands[3]) != ASHIFT)
18384 operands[2] = gen_lowpart (SImode, operands[2]);
18385 PUT_MODE (operands[3], SImode);")
18386
18387 ; Promote the QImode tests, as i386 has encoding of the AND
18388 ; instruction with 32-bit sign-extended immediate and thus the
18389 ; instruction size is unchanged, except in the %eax case for
18390 ; which it is increased by one byte, hence the ! optimize_size.
18391 (define_split
18392 [(set (reg 17)
18393 (compare (and (match_operand 1 "aligned_operand" "")
18394 (match_operand 2 "const_int_operand" ""))
18395 (const_int 0)))
18396 (set (match_operand 0 "register_operand" "")
18397 (and (match_dup 1) (match_dup 2)))]
18398 "! TARGET_PARTIAL_REG_STALL && reload_completed
18399 /* Ensure that the operand will remain sign-extended immediate. */
18400 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18401 && ! optimize_size
18402 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18403 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18404 [(parallel [(set (reg:CCNO 17)
18405 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18406 (const_int 0)))
18407 (set (match_dup 0)
18408 (and:SI (match_dup 1) (match_dup 2)))])]
18409 "operands[2]
18410 = gen_int_mode (INTVAL (operands[2])
18411 & GET_MODE_MASK (GET_MODE (operands[0])),
18412 SImode);
18413 operands[0] = gen_lowpart (SImode, operands[0]);
18414 operands[1] = gen_lowpart (SImode, operands[1]);")
18415
18416 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18417 ; the TEST instruction with 32-bit sign-extended immediate and thus
18418 ; the instruction size would at least double, which is not what we
18419 ; want even with ! optimize_size.
18420 (define_split
18421 [(set (reg 17)
18422 (compare (and (match_operand:HI 0 "aligned_operand" "")
18423 (match_operand:HI 1 "const_int_operand" ""))
18424 (const_int 0)))]
18425 "! TARGET_PARTIAL_REG_STALL && reload_completed
18426 /* Ensure that the operand will remain sign-extended immediate. */
18427 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18428 && ! TARGET_FAST_PREFIX
18429 && ! optimize_size"
18430 [(set (reg:CCNO 17)
18431 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18432 (const_int 0)))]
18433 "operands[1]
18434 = gen_int_mode (INTVAL (operands[1])
18435 & GET_MODE_MASK (GET_MODE (operands[0])),
18436 SImode);
18437 operands[0] = gen_lowpart (SImode, operands[0]);")
18438
18439 (define_split
18440 [(set (match_operand 0 "register_operand" "")
18441 (neg (match_operand 1 "register_operand" "")))
18442 (clobber (reg:CC 17))]
18443 "! TARGET_PARTIAL_REG_STALL && reload_completed
18444 && (GET_MODE (operands[0]) == HImode
18445 || (GET_MODE (operands[0]) == QImode
18446 && (TARGET_PROMOTE_QImode || optimize_size)))"
18447 [(parallel [(set (match_dup 0)
18448 (neg:SI (match_dup 1)))
18449 (clobber (reg:CC 17))])]
18450 "operands[0] = gen_lowpart (SImode, operands[0]);
18451 operands[1] = gen_lowpart (SImode, operands[1]);")
18452
18453 (define_split
18454 [(set (match_operand 0 "register_operand" "")
18455 (not (match_operand 1 "register_operand" "")))]
18456 "! TARGET_PARTIAL_REG_STALL && reload_completed
18457 && (GET_MODE (operands[0]) == HImode
18458 || (GET_MODE (operands[0]) == QImode
18459 && (TARGET_PROMOTE_QImode || optimize_size)))"
18460 [(set (match_dup 0)
18461 (not:SI (match_dup 1)))]
18462 "operands[0] = gen_lowpart (SImode, operands[0]);
18463 operands[1] = gen_lowpart (SImode, operands[1]);")
18464
18465 (define_split
18466 [(set (match_operand 0 "register_operand" "")
18467 (if_then_else (match_operator 1 "comparison_operator"
18468 [(reg 17) (const_int 0)])
18469 (match_operand 2 "register_operand" "")
18470 (match_operand 3 "register_operand" "")))]
18471 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18472 && (GET_MODE (operands[0]) == HImode
18473 || (GET_MODE (operands[0]) == QImode
18474 && (TARGET_PROMOTE_QImode || optimize_size)))"
18475 [(set (match_dup 0)
18476 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18477 "operands[0] = gen_lowpart (SImode, operands[0]);
18478 operands[2] = gen_lowpart (SImode, operands[2]);
18479 operands[3] = gen_lowpart (SImode, operands[3]);")
18480
18481 \f
18482 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18483 ;; transform a complex memory operation into two memory to register operations.
18484
18485 ;; Don't push memory operands
18486 (define_peephole2
18487 [(set (match_operand:SI 0 "push_operand" "")
18488 (match_operand:SI 1 "memory_operand" ""))
18489 (match_scratch:SI 2 "r")]
18490 "! optimize_size && ! TARGET_PUSH_MEMORY"
18491 [(set (match_dup 2) (match_dup 1))
18492 (set (match_dup 0) (match_dup 2))]
18493 "")
18494
18495 (define_peephole2
18496 [(set (match_operand:DI 0 "push_operand" "")
18497 (match_operand:DI 1 "memory_operand" ""))
18498 (match_scratch:DI 2 "r")]
18499 "! optimize_size && ! TARGET_PUSH_MEMORY"
18500 [(set (match_dup 2) (match_dup 1))
18501 (set (match_dup 0) (match_dup 2))]
18502 "")
18503
18504 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18505 ;; SImode pushes.
18506 (define_peephole2
18507 [(set (match_operand:SF 0 "push_operand" "")
18508 (match_operand:SF 1 "memory_operand" ""))
18509 (match_scratch:SF 2 "r")]
18510 "! optimize_size && ! TARGET_PUSH_MEMORY"
18511 [(set (match_dup 2) (match_dup 1))
18512 (set (match_dup 0) (match_dup 2))]
18513 "")
18514
18515 (define_peephole2
18516 [(set (match_operand:HI 0 "push_operand" "")
18517 (match_operand:HI 1 "memory_operand" ""))
18518 (match_scratch:HI 2 "r")]
18519 "! optimize_size && ! TARGET_PUSH_MEMORY"
18520 [(set (match_dup 2) (match_dup 1))
18521 (set (match_dup 0) (match_dup 2))]
18522 "")
18523
18524 (define_peephole2
18525 [(set (match_operand:QI 0 "push_operand" "")
18526 (match_operand:QI 1 "memory_operand" ""))
18527 (match_scratch:QI 2 "q")]
18528 "! optimize_size && ! TARGET_PUSH_MEMORY"
18529 [(set (match_dup 2) (match_dup 1))
18530 (set (match_dup 0) (match_dup 2))]
18531 "")
18532
18533 ;; Don't move an immediate directly to memory when the instruction
18534 ;; gets too big.
18535 (define_peephole2
18536 [(match_scratch:SI 1 "r")
18537 (set (match_operand:SI 0 "memory_operand" "")
18538 (const_int 0))]
18539 "! optimize_size
18540 && ! TARGET_USE_MOV0
18541 && TARGET_SPLIT_LONG_MOVES
18542 && get_attr_length (insn) >= ix86_cost->large_insn
18543 && peep2_regno_dead_p (0, FLAGS_REG)"
18544 [(parallel [(set (match_dup 1) (const_int 0))
18545 (clobber (reg:CC 17))])
18546 (set (match_dup 0) (match_dup 1))]
18547 "")
18548
18549 (define_peephole2
18550 [(match_scratch:HI 1 "r")
18551 (set (match_operand:HI 0 "memory_operand" "")
18552 (const_int 0))]
18553 "! optimize_size
18554 && ! TARGET_USE_MOV0
18555 && TARGET_SPLIT_LONG_MOVES
18556 && get_attr_length (insn) >= ix86_cost->large_insn
18557 && peep2_regno_dead_p (0, FLAGS_REG)"
18558 [(parallel [(set (match_dup 2) (const_int 0))
18559 (clobber (reg:CC 17))])
18560 (set (match_dup 0) (match_dup 1))]
18561 "operands[2] = gen_lowpart (SImode, operands[1]);")
18562
18563 (define_peephole2
18564 [(match_scratch:QI 1 "q")
18565 (set (match_operand:QI 0 "memory_operand" "")
18566 (const_int 0))]
18567 "! optimize_size
18568 && ! TARGET_USE_MOV0
18569 && TARGET_SPLIT_LONG_MOVES
18570 && get_attr_length (insn) >= ix86_cost->large_insn
18571 && peep2_regno_dead_p (0, FLAGS_REG)"
18572 [(parallel [(set (match_dup 2) (const_int 0))
18573 (clobber (reg:CC 17))])
18574 (set (match_dup 0) (match_dup 1))]
18575 "operands[2] = gen_lowpart (SImode, operands[1]);")
18576
18577 (define_peephole2
18578 [(match_scratch:SI 2 "r")
18579 (set (match_operand:SI 0 "memory_operand" "")
18580 (match_operand:SI 1 "immediate_operand" ""))]
18581 "! optimize_size
18582 && get_attr_length (insn) >= ix86_cost->large_insn
18583 && TARGET_SPLIT_LONG_MOVES"
18584 [(set (match_dup 2) (match_dup 1))
18585 (set (match_dup 0) (match_dup 2))]
18586 "")
18587
18588 (define_peephole2
18589 [(match_scratch:HI 2 "r")
18590 (set (match_operand:HI 0 "memory_operand" "")
18591 (match_operand:HI 1 "immediate_operand" ""))]
18592 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18593 && TARGET_SPLIT_LONG_MOVES"
18594 [(set (match_dup 2) (match_dup 1))
18595 (set (match_dup 0) (match_dup 2))]
18596 "")
18597
18598 (define_peephole2
18599 [(match_scratch:QI 2 "q")
18600 (set (match_operand:QI 0 "memory_operand" "")
18601 (match_operand:QI 1 "immediate_operand" ""))]
18602 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18603 && TARGET_SPLIT_LONG_MOVES"
18604 [(set (match_dup 2) (match_dup 1))
18605 (set (match_dup 0) (match_dup 2))]
18606 "")
18607
18608 ;; Don't compare memory with zero, load and use a test instead.
18609 (define_peephole2
18610 [(set (reg 17)
18611 (compare (match_operand:SI 0 "memory_operand" "")
18612 (const_int 0)))
18613 (match_scratch:SI 3 "r")]
18614 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18615 [(set (match_dup 3) (match_dup 0))
18616 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18617 "")
18618
18619 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18620 ;; Don't split NOTs with a displacement operand, because resulting XOR
18621 ;; will not be pairable anyway.
18622 ;;
18623 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18624 ;; represented using a modRM byte. The XOR replacement is long decoded,
18625 ;; so this split helps here as well.
18626 ;;
18627 ;; Note: Can't do this as a regular split because we can't get proper
18628 ;; lifetime information then.
18629
18630 (define_peephole2
18631 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18632 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18633 "!optimize_size
18634 && peep2_regno_dead_p (0, FLAGS_REG)
18635 && ((TARGET_PENTIUM
18636 && (GET_CODE (operands[0]) != MEM
18637 || !memory_displacement_operand (operands[0], SImode)))
18638 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18639 [(parallel [(set (match_dup 0)
18640 (xor:SI (match_dup 1) (const_int -1)))
18641 (clobber (reg:CC 17))])]
18642 "")
18643
18644 (define_peephole2
18645 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18646 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18647 "!optimize_size
18648 && peep2_regno_dead_p (0, FLAGS_REG)
18649 && ((TARGET_PENTIUM
18650 && (GET_CODE (operands[0]) != MEM
18651 || !memory_displacement_operand (operands[0], HImode)))
18652 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18653 [(parallel [(set (match_dup 0)
18654 (xor:HI (match_dup 1) (const_int -1)))
18655 (clobber (reg:CC 17))])]
18656 "")
18657
18658 (define_peephole2
18659 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18660 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18661 "!optimize_size
18662 && peep2_regno_dead_p (0, FLAGS_REG)
18663 && ((TARGET_PENTIUM
18664 && (GET_CODE (operands[0]) != MEM
18665 || !memory_displacement_operand (operands[0], QImode)))
18666 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18667 [(parallel [(set (match_dup 0)
18668 (xor:QI (match_dup 1) (const_int -1)))
18669 (clobber (reg:CC 17))])]
18670 "")
18671
18672 ;; Non pairable "test imm, reg" instructions can be translated to
18673 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18674 ;; byte opcode instead of two, have a short form for byte operands),
18675 ;; so do it for other CPUs as well. Given that the value was dead,
18676 ;; this should not create any new dependencies. Pass on the sub-word
18677 ;; versions if we're concerned about partial register stalls.
18678
18679 (define_peephole2
18680 [(set (reg 17)
18681 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18682 (match_operand:SI 1 "immediate_operand" ""))
18683 (const_int 0)))]
18684 "ix86_match_ccmode (insn, CCNOmode)
18685 && (true_regnum (operands[0]) != 0
18686 || (GET_CODE (operands[1]) == CONST_INT
18687 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18688 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18689 [(parallel
18690 [(set (reg:CCNO 17)
18691 (compare:CCNO (and:SI (match_dup 0)
18692 (match_dup 1))
18693 (const_int 0)))
18694 (set (match_dup 0)
18695 (and:SI (match_dup 0) (match_dup 1)))])]
18696 "")
18697
18698 ;; We don't need to handle HImode case, because it will be promoted to SImode
18699 ;; on ! TARGET_PARTIAL_REG_STALL
18700
18701 (define_peephole2
18702 [(set (reg 17)
18703 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18704 (match_operand:QI 1 "immediate_operand" ""))
18705 (const_int 0)))]
18706 "! TARGET_PARTIAL_REG_STALL
18707 && ix86_match_ccmode (insn, CCNOmode)
18708 && true_regnum (operands[0]) != 0
18709 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18710 [(parallel
18711 [(set (reg:CCNO 17)
18712 (compare:CCNO (and:QI (match_dup 0)
18713 (match_dup 1))
18714 (const_int 0)))
18715 (set (match_dup 0)
18716 (and:QI (match_dup 0) (match_dup 1)))])]
18717 "")
18718
18719 (define_peephole2
18720 [(set (reg 17)
18721 (compare
18722 (and:SI
18723 (zero_extract:SI
18724 (match_operand 0 "ext_register_operand" "")
18725 (const_int 8)
18726 (const_int 8))
18727 (match_operand 1 "const_int_operand" ""))
18728 (const_int 0)))]
18729 "! TARGET_PARTIAL_REG_STALL
18730 && ix86_match_ccmode (insn, CCNOmode)
18731 && true_regnum (operands[0]) != 0
18732 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18733 [(parallel [(set (reg:CCNO 17)
18734 (compare:CCNO
18735 (and:SI
18736 (zero_extract:SI
18737 (match_dup 0)
18738 (const_int 8)
18739 (const_int 8))
18740 (match_dup 1))
18741 (const_int 0)))
18742 (set (zero_extract:SI (match_dup 0)
18743 (const_int 8)
18744 (const_int 8))
18745 (and:SI
18746 (zero_extract:SI
18747 (match_dup 0)
18748 (const_int 8)
18749 (const_int 8))
18750 (match_dup 1)))])]
18751 "")
18752
18753 ;; Don't do logical operations with memory inputs.
18754 (define_peephole2
18755 [(match_scratch:SI 2 "r")
18756 (parallel [(set (match_operand:SI 0 "register_operand" "")
18757 (match_operator:SI 3 "arith_or_logical_operator"
18758 [(match_dup 0)
18759 (match_operand:SI 1 "memory_operand" "")]))
18760 (clobber (reg:CC 17))])]
18761 "! optimize_size && ! TARGET_READ_MODIFY"
18762 [(set (match_dup 2) (match_dup 1))
18763 (parallel [(set (match_dup 0)
18764 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18765 (clobber (reg:CC 17))])]
18766 "")
18767
18768 (define_peephole2
18769 [(match_scratch:SI 2 "r")
18770 (parallel [(set (match_operand:SI 0 "register_operand" "")
18771 (match_operator:SI 3 "arith_or_logical_operator"
18772 [(match_operand:SI 1 "memory_operand" "")
18773 (match_dup 0)]))
18774 (clobber (reg:CC 17))])]
18775 "! optimize_size && ! TARGET_READ_MODIFY"
18776 [(set (match_dup 2) (match_dup 1))
18777 (parallel [(set (match_dup 0)
18778 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18779 (clobber (reg:CC 17))])]
18780 "")
18781
18782 ; Don't do logical operations with memory outputs
18783 ;
18784 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18785 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18786 ; the same decoder scheduling characteristics as the original.
18787
18788 (define_peephole2
18789 [(match_scratch:SI 2 "r")
18790 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18791 (match_operator:SI 3 "arith_or_logical_operator"
18792 [(match_dup 0)
18793 (match_operand:SI 1 "nonmemory_operand" "")]))
18794 (clobber (reg:CC 17))])]
18795 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18796 [(set (match_dup 2) (match_dup 0))
18797 (parallel [(set (match_dup 2)
18798 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18799 (clobber (reg:CC 17))])
18800 (set (match_dup 0) (match_dup 2))]
18801 "")
18802
18803 (define_peephole2
18804 [(match_scratch:SI 2 "r")
18805 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18806 (match_operator:SI 3 "arith_or_logical_operator"
18807 [(match_operand:SI 1 "nonmemory_operand" "")
18808 (match_dup 0)]))
18809 (clobber (reg:CC 17))])]
18810 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18811 [(set (match_dup 2) (match_dup 0))
18812 (parallel [(set (match_dup 2)
18813 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18814 (clobber (reg:CC 17))])
18815 (set (match_dup 0) (match_dup 2))]
18816 "")
18817
18818 ;; Attempt to always use XOR for zeroing registers.
18819 (define_peephole2
18820 [(set (match_operand 0 "register_operand" "")
18821 (const_int 0))]
18822 "(GET_MODE (operands[0]) == QImode
18823 || GET_MODE (operands[0]) == HImode
18824 || GET_MODE (operands[0]) == SImode
18825 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18826 && (! TARGET_USE_MOV0 || optimize_size)
18827 && peep2_regno_dead_p (0, FLAGS_REG)"
18828 [(parallel [(set (match_dup 0) (const_int 0))
18829 (clobber (reg:CC 17))])]
18830 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18831 operands[0]);")
18832
18833 (define_peephole2
18834 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18835 (const_int 0))]
18836 "(GET_MODE (operands[0]) == QImode
18837 || GET_MODE (operands[0]) == HImode)
18838 && (! TARGET_USE_MOV0 || optimize_size)
18839 && peep2_regno_dead_p (0, FLAGS_REG)"
18840 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18841 (clobber (reg:CC 17))])])
18842
18843 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18844 (define_peephole2
18845 [(set (match_operand 0 "register_operand" "")
18846 (const_int -1))]
18847 "(GET_MODE (operands[0]) == HImode
18848 || GET_MODE (operands[0]) == SImode
18849 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18850 && (optimize_size || TARGET_PENTIUM)
18851 && peep2_regno_dead_p (0, FLAGS_REG)"
18852 [(parallel [(set (match_dup 0) (const_int -1))
18853 (clobber (reg:CC 17))])]
18854 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18855 operands[0]);")
18856
18857 ;; Attempt to convert simple leas to adds. These can be created by
18858 ;; move expanders.
18859 (define_peephole2
18860 [(set (match_operand:SI 0 "register_operand" "")
18861 (plus:SI (match_dup 0)
18862 (match_operand:SI 1 "nonmemory_operand" "")))]
18863 "peep2_regno_dead_p (0, FLAGS_REG)"
18864 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18865 (clobber (reg:CC 17))])]
18866 "")
18867
18868 (define_peephole2
18869 [(set (match_operand:SI 0 "register_operand" "")
18870 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18871 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18872 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18873 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18874 (clobber (reg:CC 17))])]
18875 "operands[2] = gen_lowpart (SImode, operands[2]);")
18876
18877 (define_peephole2
18878 [(set (match_operand:DI 0 "register_operand" "")
18879 (plus:DI (match_dup 0)
18880 (match_operand:DI 1 "x86_64_general_operand" "")))]
18881 "peep2_regno_dead_p (0, FLAGS_REG)"
18882 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18883 (clobber (reg:CC 17))])]
18884 "")
18885
18886 (define_peephole2
18887 [(set (match_operand:SI 0 "register_operand" "")
18888 (mult:SI (match_dup 0)
18889 (match_operand:SI 1 "const_int_operand" "")))]
18890 "exact_log2 (INTVAL (operands[1])) >= 0
18891 && peep2_regno_dead_p (0, FLAGS_REG)"
18892 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18893 (clobber (reg:CC 17))])]
18894 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18895
18896 (define_peephole2
18897 [(set (match_operand:DI 0 "register_operand" "")
18898 (mult:DI (match_dup 0)
18899 (match_operand:DI 1 "const_int_operand" "")))]
18900 "exact_log2 (INTVAL (operands[1])) >= 0
18901 && peep2_regno_dead_p (0, FLAGS_REG)"
18902 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18903 (clobber (reg:CC 17))])]
18904 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18905
18906 (define_peephole2
18907 [(set (match_operand:SI 0 "register_operand" "")
18908 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18909 (match_operand:DI 2 "const_int_operand" "")) 0))]
18910 "exact_log2 (INTVAL (operands[2])) >= 0
18911 && REGNO (operands[0]) == REGNO (operands[1])
18912 && peep2_regno_dead_p (0, FLAGS_REG)"
18913 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18914 (clobber (reg:CC 17))])]
18915 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18916
18917 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18918 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18919 ;; many CPUs it is also faster, since special hardware to avoid esp
18920 ;; dependencies is present.
18921
18922 ;; While some of these conversions may be done using splitters, we use peepholes
18923 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18924
18925 ;; Convert prologue esp subtractions to push.
18926 ;; We need register to push. In order to keep verify_flow_info happy we have
18927 ;; two choices
18928 ;; - use scratch and clobber it in order to avoid dependencies
18929 ;; - use already live register
18930 ;; We can't use the second way right now, since there is no reliable way how to
18931 ;; verify that given register is live. First choice will also most likely in
18932 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18933 ;; call clobbered registers are dead. We may want to use base pointer as an
18934 ;; alternative when no register is available later.
18935
18936 (define_peephole2
18937 [(match_scratch:SI 0 "r")
18938 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18939 (clobber (reg:CC 17))
18940 (clobber (mem:BLK (scratch)))])]
18941 "optimize_size || !TARGET_SUB_ESP_4"
18942 [(clobber (match_dup 0))
18943 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18944 (clobber (mem:BLK (scratch)))])])
18945
18946 (define_peephole2
18947 [(match_scratch:SI 0 "r")
18948 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18949 (clobber (reg:CC 17))
18950 (clobber (mem:BLK (scratch)))])]
18951 "optimize_size || !TARGET_SUB_ESP_8"
18952 [(clobber (match_dup 0))
18953 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18954 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18955 (clobber (mem:BLK (scratch)))])])
18956
18957 ;; Convert esp subtractions to push.
18958 (define_peephole2
18959 [(match_scratch:SI 0 "r")
18960 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18961 (clobber (reg:CC 17))])]
18962 "optimize_size || !TARGET_SUB_ESP_4"
18963 [(clobber (match_dup 0))
18964 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18965
18966 (define_peephole2
18967 [(match_scratch:SI 0 "r")
18968 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18969 (clobber (reg:CC 17))])]
18970 "optimize_size || !TARGET_SUB_ESP_8"
18971 [(clobber (match_dup 0))
18972 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18973 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18974
18975 ;; Convert epilogue deallocator to pop.
18976 (define_peephole2
18977 [(match_scratch:SI 0 "r")
18978 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18979 (clobber (reg:CC 17))
18980 (clobber (mem:BLK (scratch)))])]
18981 "optimize_size || !TARGET_ADD_ESP_4"
18982 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18983 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18984 (clobber (mem:BLK (scratch)))])]
18985 "")
18986
18987 ;; Two pops case is tricky, since pop causes dependency on destination register.
18988 ;; We use two registers if available.
18989 (define_peephole2
18990 [(match_scratch:SI 0 "r")
18991 (match_scratch:SI 1 "r")
18992 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18993 (clobber (reg:CC 17))
18994 (clobber (mem:BLK (scratch)))])]
18995 "optimize_size || !TARGET_ADD_ESP_8"
18996 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18997 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18998 (clobber (mem:BLK (scratch)))])
18999 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
19000 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
19001 "")
19002
19003 (define_peephole2
19004 [(match_scratch:SI 0 "r")
19005 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
19006 (clobber (reg:CC 17))
19007 (clobber (mem:BLK (scratch)))])]
19008 "optimize_size"
19009 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
19010 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
19011 (clobber (mem:BLK (scratch)))])
19012 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
19013 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
19014 "")
19015
19016 ;; Convert esp additions to pop.
19017 (define_peephole2
19018 [(match_scratch:SI 0 "r")
19019 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
19020 (clobber (reg:CC 17))])]
19021 ""
19022 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
19023 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
19024 "")
19025
19026 ;; Two pops case is tricky, since pop causes dependency on destination register.
19027 ;; We use two registers if available.
19028 (define_peephole2
19029 [(match_scratch:SI 0 "r")
19030 (match_scratch:SI 1 "r")
19031 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
19032 (clobber (reg:CC 17))])]
19033 ""
19034 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
19035 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
19036 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
19037 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
19038 "")
19039
19040 (define_peephole2
19041 [(match_scratch:SI 0 "r")
19042 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
19043 (clobber (reg:CC 17))])]
19044 "optimize_size"
19045 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
19046 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
19047 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
19048 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
19049 "")
19050 \f
19051 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19052 ;; required and register dies.
19053 (define_peephole2
19054 [(set (reg 17)
19055 (compare (match_operand:SI 0 "register_operand" "")
19056 (match_operand:SI 1 "incdec_operand" "")))]
19057 "ix86_match_ccmode (insn, CCGCmode)
19058 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19059 [(parallel [(set (reg:CCGC 17)
19060 (compare:CCGC (match_dup 0)
19061 (match_dup 1)))
19062 (clobber (match_dup 0))])]
19063 "")
19064
19065 (define_peephole2
19066 [(set (reg 17)
19067 (compare (match_operand:HI 0 "register_operand" "")
19068 (match_operand:HI 1 "incdec_operand" "")))]
19069 "ix86_match_ccmode (insn, CCGCmode)
19070 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19071 [(parallel [(set (reg:CCGC 17)
19072 (compare:CCGC (match_dup 0)
19073 (match_dup 1)))
19074 (clobber (match_dup 0))])]
19075 "")
19076
19077 (define_peephole2
19078 [(set (reg 17)
19079 (compare (match_operand:QI 0 "register_operand" "")
19080 (match_operand:QI 1 "incdec_operand" "")))]
19081 "ix86_match_ccmode (insn, CCGCmode)
19082 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19083 [(parallel [(set (reg:CCGC 17)
19084 (compare:CCGC (match_dup 0)
19085 (match_dup 1)))
19086 (clobber (match_dup 0))])]
19087 "")
19088
19089 ;; Convert compares with 128 to shorter add -128
19090 (define_peephole2
19091 [(set (reg 17)
19092 (compare (match_operand:SI 0 "register_operand" "")
19093 (const_int 128)))]
19094 "ix86_match_ccmode (insn, CCGCmode)
19095 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19096 [(parallel [(set (reg:CCGC 17)
19097 (compare:CCGC (match_dup 0)
19098 (const_int 128)))
19099 (clobber (match_dup 0))])]
19100 "")
19101
19102 (define_peephole2
19103 [(set (reg 17)
19104 (compare (match_operand:HI 0 "register_operand" "")
19105 (const_int 128)))]
19106 "ix86_match_ccmode (insn, CCGCmode)
19107 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19108 [(parallel [(set (reg:CCGC 17)
19109 (compare:CCGC (match_dup 0)
19110 (const_int 128)))
19111 (clobber (match_dup 0))])]
19112 "")
19113 \f
19114 (define_peephole2
19115 [(match_scratch:DI 0 "r")
19116 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
19117 (clobber (reg:CC 17))
19118 (clobber (mem:BLK (scratch)))])]
19119 "optimize_size || !TARGET_SUB_ESP_4"
19120 [(clobber (match_dup 0))
19121 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
19122 (clobber (mem:BLK (scratch)))])])
19123
19124 (define_peephole2
19125 [(match_scratch:DI 0 "r")
19126 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
19127 (clobber (reg:CC 17))
19128 (clobber (mem:BLK (scratch)))])]
19129 "optimize_size || !TARGET_SUB_ESP_8"
19130 [(clobber (match_dup 0))
19131 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
19132 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
19133 (clobber (mem:BLK (scratch)))])])
19134
19135 ;; Convert esp subtractions to push.
19136 (define_peephole2
19137 [(match_scratch:DI 0 "r")
19138 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
19139 (clobber (reg:CC 17))])]
19140 "optimize_size || !TARGET_SUB_ESP_4"
19141 [(clobber (match_dup 0))
19142 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
19143
19144 (define_peephole2
19145 [(match_scratch:DI 0 "r")
19146 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
19147 (clobber (reg:CC 17))])]
19148 "optimize_size || !TARGET_SUB_ESP_8"
19149 [(clobber (match_dup 0))
19150 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
19151 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
19152
19153 ;; Convert epilogue deallocator to pop.
19154 (define_peephole2
19155 [(match_scratch:DI 0 "r")
19156 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19157 (clobber (reg:CC 17))
19158 (clobber (mem:BLK (scratch)))])]
19159 "optimize_size || !TARGET_ADD_ESP_4"
19160 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19161 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19162 (clobber (mem:BLK (scratch)))])]
19163 "")
19164
19165 ;; Two pops case is tricky, since pop causes dependency on destination register.
19166 ;; We use two registers if available.
19167 (define_peephole2
19168 [(match_scratch:DI 0 "r")
19169 (match_scratch:DI 1 "r")
19170 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19171 (clobber (reg:CC 17))
19172 (clobber (mem:BLK (scratch)))])]
19173 "optimize_size || !TARGET_ADD_ESP_8"
19174 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19175 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19176 (clobber (mem:BLK (scratch)))])
19177 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
19178 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19179 "")
19180
19181 (define_peephole2
19182 [(match_scratch:DI 0 "r")
19183 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19184 (clobber (reg:CC 17))
19185 (clobber (mem:BLK (scratch)))])]
19186 "optimize_size"
19187 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19188 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19189 (clobber (mem:BLK (scratch)))])
19190 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19191 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19192 "")
19193
19194 ;; Convert esp additions to pop.
19195 (define_peephole2
19196 [(match_scratch:DI 0 "r")
19197 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19198 (clobber (reg:CC 17))])]
19199 ""
19200 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19201 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19202 "")
19203
19204 ;; Two pops case is tricky, since pop causes dependency on destination register.
19205 ;; We use two registers if available.
19206 (define_peephole2
19207 [(match_scratch:DI 0 "r")
19208 (match_scratch:DI 1 "r")
19209 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19210 (clobber (reg:CC 17))])]
19211 ""
19212 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19213 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19214 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
19215 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19216 "")
19217
19218 (define_peephole2
19219 [(match_scratch:DI 0 "r")
19220 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19221 (clobber (reg:CC 17))])]
19222 "optimize_size"
19223 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19224 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19225 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19226 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19227 "")
19228 \f
19229 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19230 ;; imul $32bit_imm, reg, reg is direct decoded.
19231 (define_peephole2
19232 [(match_scratch:DI 3 "r")
19233 (parallel [(set (match_operand:DI 0 "register_operand" "")
19234 (mult:DI (match_operand:DI 1 "memory_operand" "")
19235 (match_operand:DI 2 "immediate_operand" "")))
19236 (clobber (reg:CC 17))])]
19237 "TARGET_K8 && !optimize_size
19238 && (GET_CODE (operands[2]) != CONST_INT
19239 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19240 [(set (match_dup 3) (match_dup 1))
19241 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19242 (clobber (reg:CC 17))])]
19243 "")
19244
19245 (define_peephole2
19246 [(match_scratch:SI 3 "r")
19247 (parallel [(set (match_operand:SI 0 "register_operand" "")
19248 (mult:SI (match_operand:SI 1 "memory_operand" "")
19249 (match_operand:SI 2 "immediate_operand" "")))
19250 (clobber (reg:CC 17))])]
19251 "TARGET_K8 && !optimize_size
19252 && (GET_CODE (operands[2]) != CONST_INT
19253 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19254 [(set (match_dup 3) (match_dup 1))
19255 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19256 (clobber (reg:CC 17))])]
19257 "")
19258
19259 (define_peephole2
19260 [(match_scratch:SI 3 "r")
19261 (parallel [(set (match_operand:DI 0 "register_operand" "")
19262 (zero_extend:DI
19263 (mult:SI (match_operand:SI 1 "memory_operand" "")
19264 (match_operand:SI 2 "immediate_operand" ""))))
19265 (clobber (reg:CC 17))])]
19266 "TARGET_K8 && !optimize_size
19267 && (GET_CODE (operands[2]) != CONST_INT
19268 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19269 [(set (match_dup 3) (match_dup 1))
19270 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19271 (clobber (reg:CC 17))])]
19272 "")
19273
19274 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19275 ;; Convert it into imul reg, reg
19276 ;; It would be better to force assembler to encode instruction using long
19277 ;; immediate, but there is apparently no way to do so.
19278 (define_peephole2
19279 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19280 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19281 (match_operand:DI 2 "const_int_operand" "")))
19282 (clobber (reg:CC 17))])
19283 (match_scratch:DI 3 "r")]
19284 "TARGET_K8 && !optimize_size
19285 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19286 [(set (match_dup 3) (match_dup 2))
19287 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19288 (clobber (reg:CC 17))])]
19289 {
19290 if (!rtx_equal_p (operands[0], operands[1]))
19291 emit_move_insn (operands[0], operands[1]);
19292 })
19293
19294 (define_peephole2
19295 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19296 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19297 (match_operand:SI 2 "const_int_operand" "")))
19298 (clobber (reg:CC 17))])
19299 (match_scratch:SI 3 "r")]
19300 "TARGET_K8 && !optimize_size
19301 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19302 [(set (match_dup 3) (match_dup 2))
19303 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19304 (clobber (reg:CC 17))])]
19305 {
19306 if (!rtx_equal_p (operands[0], operands[1]))
19307 emit_move_insn (operands[0], operands[1]);
19308 })
19309
19310 (define_peephole2
19311 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19312 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19313 (match_operand:HI 2 "immediate_operand" "")))
19314 (clobber (reg:CC 17))])
19315 (match_scratch:HI 3 "r")]
19316 "TARGET_K8 && !optimize_size"
19317 [(set (match_dup 3) (match_dup 2))
19318 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19319 (clobber (reg:CC 17))])]
19320 {
19321 if (!rtx_equal_p (operands[0], operands[1]))
19322 emit_move_insn (operands[0], operands[1]);
19323 })
19324 \f
19325 ;; Call-value patterns last so that the wildcard operand does not
19326 ;; disrupt insn-recog's switch tables.
19327
19328 (define_insn "*call_value_pop_0"
19329 [(set (match_operand 0 "" "")
19330 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19331 (match_operand:SI 2 "" "")))
19332 (set (reg:SI 7) (plus:SI (reg:SI 7)
19333 (match_operand:SI 3 "immediate_operand" "")))]
19334 "!TARGET_64BIT"
19335 {
19336 if (SIBLING_CALL_P (insn))
19337 return "jmp\t%P1";
19338 else
19339 return "call\t%P1";
19340 }
19341 [(set_attr "type" "callv")])
19342
19343 (define_insn "*call_value_pop_1"
19344 [(set (match_operand 0 "" "")
19345 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19346 (match_operand:SI 2 "" "")))
19347 (set (reg:SI 7) (plus:SI (reg:SI 7)
19348 (match_operand:SI 3 "immediate_operand" "i")))]
19349 "!TARGET_64BIT"
19350 {
19351 if (constant_call_address_operand (operands[1], QImode))
19352 {
19353 if (SIBLING_CALL_P (insn))
19354 return "jmp\t%P1";
19355 else
19356 return "call\t%P1";
19357 }
19358 if (SIBLING_CALL_P (insn))
19359 return "jmp\t%A1";
19360 else
19361 return "call\t%A1";
19362 }
19363 [(set_attr "type" "callv")])
19364
19365 (define_insn "*call_value_0"
19366 [(set (match_operand 0 "" "")
19367 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19368 (match_operand:SI 2 "" "")))]
19369 "!TARGET_64BIT"
19370 {
19371 if (SIBLING_CALL_P (insn))
19372 return "jmp\t%P1";
19373 else
19374 return "call\t%P1";
19375 }
19376 [(set_attr "type" "callv")])
19377
19378 (define_insn "*call_value_0_rex64"
19379 [(set (match_operand 0 "" "")
19380 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19381 (match_operand:DI 2 "const_int_operand" "")))]
19382 "TARGET_64BIT"
19383 {
19384 if (SIBLING_CALL_P (insn))
19385 return "jmp\t%P1";
19386 else
19387 return "call\t%P1";
19388 }
19389 [(set_attr "type" "callv")])
19390
19391 (define_insn "*call_value_1"
19392 [(set (match_operand 0 "" "")
19393 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19394 (match_operand:SI 2 "" "")))]
19395 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19396 {
19397 if (constant_call_address_operand (operands[1], QImode))
19398 return "call\t%P1";
19399 return "call\t%*%1";
19400 }
19401 [(set_attr "type" "callv")])
19402
19403 (define_insn "*sibcall_value_1"
19404 [(set (match_operand 0 "" "")
19405 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19406 (match_operand:SI 2 "" "")))]
19407 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19408 {
19409 if (constant_call_address_operand (operands[1], QImode))
19410 return "jmp\t%P1";
19411 return "jmp\t%*%1";
19412 }
19413 [(set_attr "type" "callv")])
19414
19415 (define_insn "*call_value_1_rex64"
19416 [(set (match_operand 0 "" "")
19417 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19418 (match_operand:DI 2 "" "")))]
19419 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19420 {
19421 if (constant_call_address_operand (operands[1], QImode))
19422 return "call\t%P1";
19423 return "call\t%A1";
19424 }
19425 [(set_attr "type" "callv")])
19426
19427 (define_insn "*sibcall_value_1_rex64"
19428 [(set (match_operand 0 "" "")
19429 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19430 (match_operand:DI 2 "" "")))]
19431 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19432 "jmp\t%P1"
19433 [(set_attr "type" "callv")])
19434
19435 (define_insn "*sibcall_value_1_rex64_v"
19436 [(set (match_operand 0 "" "")
19437 (call (mem:QI (reg:DI 40))
19438 (match_operand:DI 1 "" "")))]
19439 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19440 "jmp\t*%%r11"
19441 [(set_attr "type" "callv")])
19442 \f
19443 (define_insn "trap"
19444 [(trap_if (const_int 1) (const_int 5))]
19445 ""
19446 "int\t$5")
19447
19448 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19449 ;;; for the sake of bounds checking. By emitting bounds checks as
19450 ;;; conditional traps rather than as conditional jumps around
19451 ;;; unconditional traps we avoid introducing spurious basic-block
19452 ;;; boundaries and facilitate elimination of redundant checks. In
19453 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19454 ;;; interrupt 5.
19455 ;;;
19456 ;;; FIXME: Static branch prediction rules for ix86 are such that
19457 ;;; forward conditional branches predict as untaken. As implemented
19458 ;;; below, pseudo conditional traps violate that rule. We should use
19459 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19460 ;;; section loaded at the end of the text segment and branch forward
19461 ;;; there on bounds-failure, and then jump back immediately (in case
19462 ;;; the system chooses to ignore bounds violations, or to report
19463 ;;; violations and continue execution).
19464
19465 (define_expand "conditional_trap"
19466 [(trap_if (match_operator 0 "comparison_operator"
19467 [(match_dup 2) (const_int 0)])
19468 (match_operand 1 "const_int_operand" ""))]
19469 ""
19470 {
19471 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19472 ix86_expand_compare (GET_CODE (operands[0]),
19473 NULL, NULL),
19474 operands[1]));
19475 DONE;
19476 })
19477
19478 (define_insn "*conditional_trap_1"
19479 [(trap_if (match_operator 0 "comparison_operator"
19480 [(reg 17) (const_int 0)])
19481 (match_operand 1 "const_int_operand" ""))]
19482 ""
19483 {
19484 operands[2] = gen_label_rtx ();
19485 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19486 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19487 CODE_LABEL_NUMBER (operands[2]));
19488 RET;
19489 })
19490
19491 ;; Pentium III SIMD instructions.
19492
19493 ;; Moves for SSE/MMX regs.
19494
19495 (define_insn "movv4sf_internal"
19496 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19497 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19498 "TARGET_SSE"
19499 "@
19500 xorps\t%0, %0
19501 movaps\t{%1, %0|%0, %1}
19502 movaps\t{%1, %0|%0, %1}"
19503 [(set_attr "type" "ssemov")
19504 (set_attr "mode" "V4SF")])
19505
19506 (define_split
19507 [(set (match_operand:V4SF 0 "register_operand" "")
19508 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19509 "TARGET_SSE"
19510 [(set (match_dup 0)
19511 (vec_merge:V4SF
19512 (vec_duplicate:V4SF (match_dup 1))
19513 (match_dup 2)
19514 (const_int 1)))]
19515 {
19516 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19517 operands[2] = CONST0_RTX (V4SFmode);
19518 })
19519
19520 (define_insn "movv4si_internal"
19521 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19522 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19523 "TARGET_SSE"
19524 {
19525 switch (which_alternative)
19526 {
19527 case 0:
19528 if (get_attr_mode (insn) == MODE_V4SF)
19529 return "xorps\t%0, %0";
19530 else
19531 return "pxor\t%0, %0";
19532 case 1:
19533 case 2:
19534 if (get_attr_mode (insn) == MODE_V4SF)
19535 return "movaps\t{%1, %0|%0, %1}";
19536 else
19537 return "movdqa\t{%1, %0|%0, %1}";
19538 default:
19539 abort ();
19540 }
19541 }
19542 [(set_attr "type" "ssemov")
19543 (set (attr "mode")
19544 (cond [(eq_attr "alternative" "0,1")
19545 (if_then_else
19546 (ne (symbol_ref "optimize_size")
19547 (const_int 0))
19548 (const_string "V4SF")
19549 (const_string "TI"))
19550 (eq_attr "alternative" "2")
19551 (if_then_else
19552 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19553 (const_int 0))
19554 (ne (symbol_ref "optimize_size")
19555 (const_int 0)))
19556 (const_string "V4SF")
19557 (const_string "TI"))]
19558 (const_string "TI")))])
19559
19560 (define_insn "movv2di_internal"
19561 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19562 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19563 "TARGET_SSE"
19564 {
19565 switch (which_alternative)
19566 {
19567 case 0:
19568 if (get_attr_mode (insn) == MODE_V4SF)
19569 return "xorps\t%0, %0";
19570 else
19571 return "pxor\t%0, %0";
19572 case 1:
19573 case 2:
19574 if (get_attr_mode (insn) == MODE_V4SF)
19575 return "movaps\t{%1, %0|%0, %1}";
19576 else
19577 return "movdqa\t{%1, %0|%0, %1}";
19578 default:
19579 abort ();
19580 }
19581 }
19582 [(set_attr "type" "ssemov")
19583 (set (attr "mode")
19584 (cond [(eq_attr "alternative" "0,1")
19585 (if_then_else
19586 (ne (symbol_ref "optimize_size")
19587 (const_int 0))
19588 (const_string "V4SF")
19589 (const_string "TI"))
19590 (eq_attr "alternative" "2")
19591 (if_then_else
19592 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19593 (const_int 0))
19594 (ne (symbol_ref "optimize_size")
19595 (const_int 0)))
19596 (const_string "V4SF")
19597 (const_string "TI"))]
19598 (const_string "TI")))])
19599
19600 (define_split
19601 [(set (match_operand:V2DF 0 "register_operand" "")
19602 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19603 "TARGET_SSE2"
19604 [(set (match_dup 0)
19605 (vec_merge:V2DF
19606 (vec_duplicate:V2DF (match_dup 1))
19607 (match_dup 2)
19608 (const_int 1)))]
19609 {
19610 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19611 operands[2] = CONST0_RTX (V2DFmode);
19612 })
19613
19614 (define_insn "movv8qi_internal"
19615 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19616 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19617 "TARGET_MMX
19618 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19619 "@
19620 pxor\t%0, %0
19621 movq\t{%1, %0|%0, %1}
19622 movq\t{%1, %0|%0, %1}"
19623 [(set_attr "type" "mmxmov")
19624 (set_attr "mode" "DI")])
19625
19626 (define_insn "movv4hi_internal"
19627 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19628 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19629 "TARGET_MMX
19630 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19631 "@
19632 pxor\t%0, %0
19633 movq\t{%1, %0|%0, %1}
19634 movq\t{%1, %0|%0, %1}"
19635 [(set_attr "type" "mmxmov")
19636 (set_attr "mode" "DI")])
19637
19638 (define_insn "movv2si_internal"
19639 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19640 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19641 "TARGET_MMX
19642 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19643 "@
19644 pxor\t%0, %0
19645 movq\t{%1, %0|%0, %1}
19646 movq\t{%1, %0|%0, %1}"
19647 [(set_attr "type" "mmxcvt")
19648 (set_attr "mode" "DI")])
19649
19650 (define_insn "movv2sf_internal"
19651 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19652 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19653 "TARGET_3DNOW
19654 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19655 "@
19656 pxor\t%0, %0
19657 movq\t{%1, %0|%0, %1}
19658 movq\t{%1, %0|%0, %1}"
19659 [(set_attr "type" "mmxcvt")
19660 (set_attr "mode" "DI")])
19661
19662 (define_expand "movti"
19663 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19664 (match_operand:TI 1 "nonimmediate_operand" ""))]
19665 "TARGET_SSE || TARGET_64BIT"
19666 {
19667 if (TARGET_64BIT)
19668 ix86_expand_move (TImode, operands);
19669 else
19670 ix86_expand_vector_move (TImode, operands);
19671 DONE;
19672 })
19673
19674 (define_expand "movtf"
19675 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19676 (match_operand:TF 1 "nonimmediate_operand" ""))]
19677 "TARGET_64BIT"
19678 {
19679 if (TARGET_64BIT)
19680 ix86_expand_move (TFmode, operands);
19681 else
19682 ix86_expand_vector_move (TFmode, operands);
19683 DONE;
19684 })
19685
19686 (define_insn "movv2df_internal"
19687 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19688 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19689 "TARGET_SSE2
19690 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19691 {
19692 switch (which_alternative)
19693 {
19694 case 0:
19695 if (get_attr_mode (insn) == MODE_V4SF)
19696 return "xorps\t%0, %0";
19697 else
19698 return "xorpd\t%0, %0";
19699 case 1:
19700 case 2:
19701 if (get_attr_mode (insn) == MODE_V4SF)
19702 return "movaps\t{%1, %0|%0, %1}";
19703 else
19704 return "movapd\t{%1, %0|%0, %1}";
19705 default:
19706 abort ();
19707 }
19708 }
19709 [(set_attr "type" "ssemov")
19710 (set (attr "mode")
19711 (cond [(eq_attr "alternative" "0,1")
19712 (if_then_else
19713 (ne (symbol_ref "optimize_size")
19714 (const_int 0))
19715 (const_string "V4SF")
19716 (const_string "V2DF"))
19717 (eq_attr "alternative" "2")
19718 (if_then_else
19719 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19720 (const_int 0))
19721 (ne (symbol_ref "optimize_size")
19722 (const_int 0)))
19723 (const_string "V4SF")
19724 (const_string "V2DF"))]
19725 (const_string "V2DF")))])
19726
19727 (define_insn "movv8hi_internal"
19728 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19729 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19730 "TARGET_SSE2
19731 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19732 {
19733 switch (which_alternative)
19734 {
19735 case 0:
19736 if (get_attr_mode (insn) == MODE_V4SF)
19737 return "xorps\t%0, %0";
19738 else
19739 return "pxor\t%0, %0";
19740 case 1:
19741 case 2:
19742 if (get_attr_mode (insn) == MODE_V4SF)
19743 return "movaps\t{%1, %0|%0, %1}";
19744 else
19745 return "movdqa\t{%1, %0|%0, %1}";
19746 default:
19747 abort ();
19748 }
19749 }
19750 [(set_attr "type" "ssemov")
19751 (set (attr "mode")
19752 (cond [(eq_attr "alternative" "0,1")
19753 (if_then_else
19754 (ne (symbol_ref "optimize_size")
19755 (const_int 0))
19756 (const_string "V4SF")
19757 (const_string "TI"))
19758 (eq_attr "alternative" "2")
19759 (if_then_else
19760 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19761 (const_int 0))
19762 (ne (symbol_ref "optimize_size")
19763 (const_int 0)))
19764 (const_string "V4SF")
19765 (const_string "TI"))]
19766 (const_string "TI")))])
19767
19768 (define_insn "movv16qi_internal"
19769 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19770 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19771 "TARGET_SSE2
19772 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19773 {
19774 switch (which_alternative)
19775 {
19776 case 0:
19777 if (get_attr_mode (insn) == MODE_V4SF)
19778 return "xorps\t%0, %0";
19779 else
19780 return "pxor\t%0, %0";
19781 case 1:
19782 case 2:
19783 if (get_attr_mode (insn) == MODE_V4SF)
19784 return "movaps\t{%1, %0|%0, %1}";
19785 else
19786 return "movdqa\t{%1, %0|%0, %1}";
19787 default:
19788 abort ();
19789 }
19790 }
19791 [(set_attr "type" "ssemov")
19792 (set (attr "mode")
19793 (cond [(eq_attr "alternative" "0,1")
19794 (if_then_else
19795 (ne (symbol_ref "optimize_size")
19796 (const_int 0))
19797 (const_string "V4SF")
19798 (const_string "TI"))
19799 (eq_attr "alternative" "2")
19800 (if_then_else
19801 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19802 (const_int 0))
19803 (ne (symbol_ref "optimize_size")
19804 (const_int 0)))
19805 (const_string "V4SF")
19806 (const_string "TI"))]
19807 (const_string "TI")))])
19808
19809 (define_expand "movv2df"
19810 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19811 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19812 "TARGET_SSE2"
19813 {
19814 ix86_expand_vector_move (V2DFmode, operands);
19815 DONE;
19816 })
19817
19818 (define_expand "movv8hi"
19819 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19820 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19821 "TARGET_SSE2"
19822 {
19823 ix86_expand_vector_move (V8HImode, operands);
19824 DONE;
19825 })
19826
19827 (define_expand "movv16qi"
19828 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19829 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19830 "TARGET_SSE2"
19831 {
19832 ix86_expand_vector_move (V16QImode, operands);
19833 DONE;
19834 })
19835
19836 (define_expand "movv4sf"
19837 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19838 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19839 "TARGET_SSE"
19840 {
19841 ix86_expand_vector_move (V4SFmode, operands);
19842 DONE;
19843 })
19844
19845 (define_expand "movv4si"
19846 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19847 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19848 "TARGET_SSE"
19849 {
19850 ix86_expand_vector_move (V4SImode, operands);
19851 DONE;
19852 })
19853
19854 (define_expand "movv2di"
19855 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19856 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19857 "TARGET_SSE"
19858 {
19859 ix86_expand_vector_move (V2DImode, operands);
19860 DONE;
19861 })
19862
19863 (define_expand "movv2si"
19864 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19865 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19866 "TARGET_MMX"
19867 {
19868 ix86_expand_vector_move (V2SImode, operands);
19869 DONE;
19870 })
19871
19872 (define_expand "movv4hi"
19873 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19874 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19875 "TARGET_MMX"
19876 {
19877 ix86_expand_vector_move (V4HImode, operands);
19878 DONE;
19879 })
19880
19881 (define_expand "movv8qi"
19882 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19883 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19884 "TARGET_MMX"
19885 {
19886 ix86_expand_vector_move (V8QImode, operands);
19887 DONE;
19888 })
19889
19890 (define_expand "movv2sf"
19891 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19892 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19893 "TARGET_3DNOW"
19894 {
19895 ix86_expand_vector_move (V2SFmode, operands);
19896 DONE;
19897 })
19898
19899 (define_insn "*pushti"
19900 [(set (match_operand:TI 0 "push_operand" "=<")
19901 (match_operand:TI 1 "register_operand" "x"))]
19902 "TARGET_SSE"
19903 "#")
19904
19905 (define_insn "*pushv2df"
19906 [(set (match_operand:V2DF 0 "push_operand" "=<")
19907 (match_operand:V2DF 1 "register_operand" "x"))]
19908 "TARGET_SSE"
19909 "#")
19910
19911 (define_insn "*pushv2di"
19912 [(set (match_operand:V2DI 0 "push_operand" "=<")
19913 (match_operand:V2DI 1 "register_operand" "x"))]
19914 "TARGET_SSE2"
19915 "#")
19916
19917 (define_insn "*pushv8hi"
19918 [(set (match_operand:V8HI 0 "push_operand" "=<")
19919 (match_operand:V8HI 1 "register_operand" "x"))]
19920 "TARGET_SSE2"
19921 "#")
19922
19923 (define_insn "*pushv16qi"
19924 [(set (match_operand:V16QI 0 "push_operand" "=<")
19925 (match_operand:V16QI 1 "register_operand" "x"))]
19926 "TARGET_SSE2"
19927 "#")
19928
19929 (define_insn "*pushv4sf"
19930 [(set (match_operand:V4SF 0 "push_operand" "=<")
19931 (match_operand:V4SF 1 "register_operand" "x"))]
19932 "TARGET_SSE"
19933 "#")
19934
19935 (define_insn "*pushv4si"
19936 [(set (match_operand:V4SI 0 "push_operand" "=<")
19937 (match_operand:V4SI 1 "register_operand" "x"))]
19938 "TARGET_SSE2"
19939 "#")
19940
19941 (define_insn "*pushv2si"
19942 [(set (match_operand:V2SI 0 "push_operand" "=<")
19943 (match_operand:V2SI 1 "register_operand" "y"))]
19944 "TARGET_MMX"
19945 "#")
19946
19947 (define_insn "*pushv4hi"
19948 [(set (match_operand:V4HI 0 "push_operand" "=<")
19949 (match_operand:V4HI 1 "register_operand" "y"))]
19950 "TARGET_MMX"
19951 "#")
19952
19953 (define_insn "*pushv8qi"
19954 [(set (match_operand:V8QI 0 "push_operand" "=<")
19955 (match_operand:V8QI 1 "register_operand" "y"))]
19956 "TARGET_MMX"
19957 "#")
19958
19959 (define_insn "*pushv2sf"
19960 [(set (match_operand:V2SF 0 "push_operand" "=<")
19961 (match_operand:V2SF 1 "register_operand" "y"))]
19962 "TARGET_3DNOW"
19963 "#")
19964
19965 (define_split
19966 [(set (match_operand 0 "push_operand" "")
19967 (match_operand 1 "register_operand" ""))]
19968 "!TARGET_64BIT && reload_completed
19969 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19970 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19971 (set (match_dup 2) (match_dup 1))]
19972 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19973 stack_pointer_rtx);
19974 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19975
19976 (define_split
19977 [(set (match_operand 0 "push_operand" "")
19978 (match_operand 1 "register_operand" ""))]
19979 "TARGET_64BIT && reload_completed
19980 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19981 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19982 (set (match_dup 2) (match_dup 1))]
19983 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19984 stack_pointer_rtx);
19985 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19986
19987
19988 (define_insn "movti_internal"
19989 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19990 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19991 "TARGET_SSE && !TARGET_64BIT
19992 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19993 {
19994 switch (which_alternative)
19995 {
19996 case 0:
19997 if (get_attr_mode (insn) == MODE_V4SF)
19998 return "xorps\t%0, %0";
19999 else
20000 return "pxor\t%0, %0";
20001 case 1:
20002 case 2:
20003 if (get_attr_mode (insn) == MODE_V4SF)
20004 return "movaps\t{%1, %0|%0, %1}";
20005 else
20006 return "movdqa\t{%1, %0|%0, %1}";
20007 default:
20008 abort ();
20009 }
20010 }
20011 [(set_attr "type" "ssemov,ssemov,ssemov")
20012 (set (attr "mode")
20013 (cond [(eq_attr "alternative" "0,1")
20014 (if_then_else
20015 (ne (symbol_ref "optimize_size")
20016 (const_int 0))
20017 (const_string "V4SF")
20018 (const_string "TI"))
20019 (eq_attr "alternative" "2")
20020 (if_then_else
20021 (ne (symbol_ref "optimize_size")
20022 (const_int 0))
20023 (const_string "V4SF")
20024 (const_string "TI"))]
20025 (const_string "TI")))])
20026
20027 (define_insn "*movti_rex64"
20028 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20029 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20030 "TARGET_64BIT
20031 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20032 {
20033 switch (which_alternative)
20034 {
20035 case 0:
20036 case 1:
20037 return "#";
20038 case 2:
20039 if (get_attr_mode (insn) == MODE_V4SF)
20040 return "xorps\t%0, %0";
20041 else
20042 return "pxor\t%0, %0";
20043 case 3:
20044 case 4:
20045 if (get_attr_mode (insn) == MODE_V4SF)
20046 return "movaps\t{%1, %0|%0, %1}";
20047 else
20048 return "movdqa\t{%1, %0|%0, %1}";
20049 default:
20050 abort ();
20051 }
20052 }
20053 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20054 (set (attr "mode")
20055 (cond [(eq_attr "alternative" "2,3")
20056 (if_then_else
20057 (ne (symbol_ref "optimize_size")
20058 (const_int 0))
20059 (const_string "V4SF")
20060 (const_string "TI"))
20061 (eq_attr "alternative" "4")
20062 (if_then_else
20063 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20064 (const_int 0))
20065 (ne (symbol_ref "optimize_size")
20066 (const_int 0)))
20067 (const_string "V4SF")
20068 (const_string "TI"))]
20069 (const_string "DI")))])
20070
20071 (define_insn "*movtf_rex64"
20072 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20073 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20074 "TARGET_64BIT
20075 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20076 {
20077 switch (which_alternative)
20078 {
20079 case 0:
20080 case 1:
20081 return "#";
20082 case 2:
20083 if (get_attr_mode (insn) == MODE_V4SF)
20084 return "xorps\t%0, %0";
20085 else
20086 return "pxor\t%0, %0";
20087 case 3:
20088 case 4:
20089 if (get_attr_mode (insn) == MODE_V4SF)
20090 return "movaps\t{%1, %0|%0, %1}";
20091 else
20092 return "movdqa\t{%1, %0|%0, %1}";
20093 default:
20094 abort ();
20095 }
20096 }
20097 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20098 (set (attr "mode")
20099 (cond [(eq_attr "alternative" "2,3")
20100 (if_then_else
20101 (ne (symbol_ref "optimize_size")
20102 (const_int 0))
20103 (const_string "V4SF")
20104 (const_string "TI"))
20105 (eq_attr "alternative" "4")
20106 (if_then_else
20107 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20108 (const_int 0))
20109 (ne (symbol_ref "optimize_size")
20110 (const_int 0)))
20111 (const_string "V4SF")
20112 (const_string "TI"))]
20113 (const_string "DI")))])
20114
20115 (define_split
20116 [(set (match_operand:TI 0 "nonimmediate_operand" "")
20117 (match_operand:TI 1 "general_operand" ""))]
20118 "reload_completed && !SSE_REG_P (operands[0])
20119 && !SSE_REG_P (operands[1])"
20120 [(const_int 0)]
20121 "ix86_split_long_move (operands); DONE;")
20122
20123 (define_split
20124 [(set (match_operand:TF 0 "nonimmediate_operand" "")
20125 (match_operand:TF 1 "general_operand" ""))]
20126 "reload_completed && !SSE_REG_P (operands[0])
20127 && !SSE_REG_P (operands[1])"
20128 [(const_int 0)]
20129 "ix86_split_long_move (operands); DONE;")
20130
20131 ;; These two patterns are useful for specifying exactly whether to use
20132 ;; movaps or movups
20133 (define_expand "sse_movaps"
20134 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20135 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20136 UNSPEC_MOVA))]
20137 "TARGET_SSE"
20138 {
20139 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20140 {
20141 rtx tmp = gen_reg_rtx (V4SFmode);
20142 emit_insn (gen_sse_movaps (tmp, operands[1]));
20143 emit_move_insn (operands[0], tmp);
20144 DONE;
20145 }
20146 })
20147
20148 (define_insn "*sse_movaps_1"
20149 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20150 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20151 UNSPEC_MOVA))]
20152 "TARGET_SSE
20153 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20154 "movaps\t{%1, %0|%0, %1}"
20155 [(set_attr "type" "ssemov,ssemov")
20156 (set_attr "mode" "V4SF")])
20157
20158 (define_expand "sse_movups"
20159 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20160 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20161 UNSPEC_MOVU))]
20162 "TARGET_SSE"
20163 {
20164 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20165 {
20166 rtx tmp = gen_reg_rtx (V4SFmode);
20167 emit_insn (gen_sse_movups (tmp, operands[1]));
20168 emit_move_insn (operands[0], tmp);
20169 DONE;
20170 }
20171 })
20172
20173 (define_insn "*sse_movups_1"
20174 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20175 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20176 UNSPEC_MOVU))]
20177 "TARGET_SSE
20178 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20179 "movups\t{%1, %0|%0, %1}"
20180 [(set_attr "type" "ssecvt,ssecvt")
20181 (set_attr "mode" "V4SF")])
20182
20183 ;; SSE Strange Moves.
20184
20185 (define_insn "sse_movmskps"
20186 [(set (match_operand:SI 0 "register_operand" "=r")
20187 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20188 UNSPEC_MOVMSK))]
20189 "TARGET_SSE"
20190 "movmskps\t{%1, %0|%0, %1}"
20191 [(set_attr "type" "ssecvt")
20192 (set_attr "mode" "V4SF")])
20193
20194 (define_insn "mmx_pmovmskb"
20195 [(set (match_operand:SI 0 "register_operand" "=r")
20196 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20197 UNSPEC_MOVMSK))]
20198 "TARGET_SSE || TARGET_3DNOW_A"
20199 "pmovmskb\t{%1, %0|%0, %1}"
20200 [(set_attr "type" "ssecvt")
20201 (set_attr "mode" "V4SF")])
20202
20203
20204 (define_insn "mmx_maskmovq"
20205 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20206 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20207 (match_operand:V8QI 2 "register_operand" "y")]
20208 UNSPEC_MASKMOV))]
20209 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20210 ;; @@@ check ordering of operands in intel/nonintel syntax
20211 "maskmovq\t{%2, %1|%1, %2}"
20212 [(set_attr "type" "mmxcvt")
20213 (set_attr "mode" "DI")])
20214
20215 (define_insn "mmx_maskmovq_rex"
20216 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20217 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20218 (match_operand:V8QI 2 "register_operand" "y")]
20219 UNSPEC_MASKMOV))]
20220 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20221 ;; @@@ check ordering of operands in intel/nonintel syntax
20222 "maskmovq\t{%2, %1|%1, %2}"
20223 [(set_attr "type" "mmxcvt")
20224 (set_attr "mode" "DI")])
20225
20226 (define_insn "sse_movntv4sf"
20227 [(set (match_operand:V4SF 0 "memory_operand" "=m")
20228 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20229 UNSPEC_MOVNT))]
20230 "TARGET_SSE"
20231 "movntps\t{%1, %0|%0, %1}"
20232 [(set_attr "type" "ssemov")
20233 (set_attr "mode" "V4SF")])
20234
20235 (define_insn "sse_movntdi"
20236 [(set (match_operand:DI 0 "memory_operand" "=m")
20237 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20238 UNSPEC_MOVNT))]
20239 "TARGET_SSE || TARGET_3DNOW_A"
20240 "movntq\t{%1, %0|%0, %1}"
20241 [(set_attr "type" "mmxmov")
20242 (set_attr "mode" "DI")])
20243
20244 (define_insn "sse_movhlps"
20245 [(set (match_operand:V4SF 0 "register_operand" "=x")
20246 (vec_merge:V4SF
20247 (match_operand:V4SF 1 "register_operand" "0")
20248 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20249 (parallel [(const_int 2)
20250 (const_int 3)
20251 (const_int 0)
20252 (const_int 1)]))
20253 (const_int 3)))]
20254 "TARGET_SSE"
20255 "movhlps\t{%2, %0|%0, %2}"
20256 [(set_attr "type" "ssecvt")
20257 (set_attr "mode" "V4SF")])
20258
20259 (define_insn "sse_movlhps"
20260 [(set (match_operand:V4SF 0 "register_operand" "=x")
20261 (vec_merge:V4SF
20262 (match_operand:V4SF 1 "register_operand" "0")
20263 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20264 (parallel [(const_int 2)
20265 (const_int 3)
20266 (const_int 0)
20267 (const_int 1)]))
20268 (const_int 12)))]
20269 "TARGET_SSE"
20270 "movlhps\t{%2, %0|%0, %2}"
20271 [(set_attr "type" "ssecvt")
20272 (set_attr "mode" "V4SF")])
20273
20274 (define_insn "sse_movhps"
20275 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20276 (vec_merge:V4SF
20277 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20278 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20279 (const_int 12)))]
20280 "TARGET_SSE
20281 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20282 "movhps\t{%2, %0|%0, %2}"
20283 [(set_attr "type" "ssecvt")
20284 (set_attr "mode" "V4SF")])
20285
20286 (define_insn "sse_movlps"
20287 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20288 (vec_merge:V4SF
20289 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20290 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20291 (const_int 3)))]
20292 "TARGET_SSE
20293 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20294 "movlps\t{%2, %0|%0, %2}"
20295 [(set_attr "type" "ssecvt")
20296 (set_attr "mode" "V4SF")])
20297
20298 (define_expand "sse_loadss"
20299 [(match_operand:V4SF 0 "register_operand" "")
20300 (match_operand:SF 1 "memory_operand" "")]
20301 "TARGET_SSE"
20302 {
20303 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20304 CONST0_RTX (V4SFmode)));
20305 DONE;
20306 })
20307
20308 (define_insn "sse_loadss_1"
20309 [(set (match_operand:V4SF 0 "register_operand" "=x")
20310 (vec_merge:V4SF
20311 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20312 (match_operand:V4SF 2 "const0_operand" "X")
20313 (const_int 1)))]
20314 "TARGET_SSE"
20315 "movss\t{%1, %0|%0, %1}"
20316 [(set_attr "type" "ssemov")
20317 (set_attr "mode" "SF")])
20318
20319 (define_insn "sse_movss"
20320 [(set (match_operand:V4SF 0 "register_operand" "=x")
20321 (vec_merge:V4SF
20322 (match_operand:V4SF 1 "register_operand" "0")
20323 (match_operand:V4SF 2 "register_operand" "x")
20324 (const_int 1)))]
20325 "TARGET_SSE"
20326 "movss\t{%2, %0|%0, %2}"
20327 [(set_attr "type" "ssemov")
20328 (set_attr "mode" "SF")])
20329
20330 (define_insn "sse_storess"
20331 [(set (match_operand:SF 0 "memory_operand" "=m")
20332 (vec_select:SF
20333 (match_operand:V4SF 1 "register_operand" "x")
20334 (parallel [(const_int 0)])))]
20335 "TARGET_SSE"
20336 "movss\t{%1, %0|%0, %1}"
20337 [(set_attr "type" "ssemov")
20338 (set_attr "mode" "SF")])
20339
20340 (define_insn "sse_shufps"
20341 [(set (match_operand:V4SF 0 "register_operand" "=x")
20342 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20343 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20344 (match_operand:SI 3 "immediate_operand" "i")]
20345 UNSPEC_SHUFFLE))]
20346 "TARGET_SSE"
20347 ;; @@@ check operand order for intel/nonintel syntax
20348 "shufps\t{%3, %2, %0|%0, %2, %3}"
20349 [(set_attr "type" "ssecvt")
20350 (set_attr "mode" "V4SF")])
20351
20352
20353 ;; SSE arithmetic
20354
20355 (define_insn "addv4sf3"
20356 [(set (match_operand:V4SF 0 "register_operand" "=x")
20357 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20358 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20359 "TARGET_SSE"
20360 "addps\t{%2, %0|%0, %2}"
20361 [(set_attr "type" "sseadd")
20362 (set_attr "mode" "V4SF")])
20363
20364 (define_insn "vmaddv4sf3"
20365 [(set (match_operand:V4SF 0 "register_operand" "=x")
20366 (vec_merge:V4SF
20367 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20368 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20369 (match_dup 1)
20370 (const_int 1)))]
20371 "TARGET_SSE"
20372 "addss\t{%2, %0|%0, %2}"
20373 [(set_attr "type" "sseadd")
20374 (set_attr "mode" "SF")])
20375
20376 (define_insn "subv4sf3"
20377 [(set (match_operand:V4SF 0 "register_operand" "=x")
20378 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20379 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20380 "TARGET_SSE"
20381 "subps\t{%2, %0|%0, %2}"
20382 [(set_attr "type" "sseadd")
20383 (set_attr "mode" "V4SF")])
20384
20385 (define_insn "vmsubv4sf3"
20386 [(set (match_operand:V4SF 0 "register_operand" "=x")
20387 (vec_merge:V4SF
20388 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20389 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20390 (match_dup 1)
20391 (const_int 1)))]
20392 "TARGET_SSE"
20393 "subss\t{%2, %0|%0, %2}"
20394 [(set_attr "type" "sseadd")
20395 (set_attr "mode" "SF")])
20396
20397 (define_insn "mulv4sf3"
20398 [(set (match_operand:V4SF 0 "register_operand" "=x")
20399 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20400 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20401 "TARGET_SSE"
20402 "mulps\t{%2, %0|%0, %2}"
20403 [(set_attr "type" "ssemul")
20404 (set_attr "mode" "V4SF")])
20405
20406 (define_insn "vmmulv4sf3"
20407 [(set (match_operand:V4SF 0 "register_operand" "=x")
20408 (vec_merge:V4SF
20409 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20410 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20411 (match_dup 1)
20412 (const_int 1)))]
20413 "TARGET_SSE"
20414 "mulss\t{%2, %0|%0, %2}"
20415 [(set_attr "type" "ssemul")
20416 (set_attr "mode" "SF")])
20417
20418 (define_insn "divv4sf3"
20419 [(set (match_operand:V4SF 0 "register_operand" "=x")
20420 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20421 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20422 "TARGET_SSE"
20423 "divps\t{%2, %0|%0, %2}"
20424 [(set_attr "type" "ssediv")
20425 (set_attr "mode" "V4SF")])
20426
20427 (define_insn "vmdivv4sf3"
20428 [(set (match_operand:V4SF 0 "register_operand" "=x")
20429 (vec_merge:V4SF
20430 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20431 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20432 (match_dup 1)
20433 (const_int 1)))]
20434 "TARGET_SSE"
20435 "divss\t{%2, %0|%0, %2}"
20436 [(set_attr "type" "ssediv")
20437 (set_attr "mode" "SF")])
20438
20439
20440 ;; SSE square root/reciprocal
20441
20442 (define_insn "rcpv4sf2"
20443 [(set (match_operand:V4SF 0 "register_operand" "=x")
20444 (unspec:V4SF
20445 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20446 "TARGET_SSE"
20447 "rcpps\t{%1, %0|%0, %1}"
20448 [(set_attr "type" "sse")
20449 (set_attr "mode" "V4SF")])
20450
20451 (define_insn "vmrcpv4sf2"
20452 [(set (match_operand:V4SF 0 "register_operand" "=x")
20453 (vec_merge:V4SF
20454 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20455 UNSPEC_RCP)
20456 (match_operand:V4SF 2 "register_operand" "0")
20457 (const_int 1)))]
20458 "TARGET_SSE"
20459 "rcpss\t{%1, %0|%0, %1}"
20460 [(set_attr "type" "sse")
20461 (set_attr "mode" "SF")])
20462
20463 (define_insn "rsqrtv4sf2"
20464 [(set (match_operand:V4SF 0 "register_operand" "=x")
20465 (unspec:V4SF
20466 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20467 "TARGET_SSE"
20468 "rsqrtps\t{%1, %0|%0, %1}"
20469 [(set_attr "type" "sse")
20470 (set_attr "mode" "V4SF")])
20471
20472 (define_insn "vmrsqrtv4sf2"
20473 [(set (match_operand:V4SF 0 "register_operand" "=x")
20474 (vec_merge:V4SF
20475 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20476 UNSPEC_RSQRT)
20477 (match_operand:V4SF 2 "register_operand" "0")
20478 (const_int 1)))]
20479 "TARGET_SSE"
20480 "rsqrtss\t{%1, %0|%0, %1}"
20481 [(set_attr "type" "sse")
20482 (set_attr "mode" "SF")])
20483
20484 (define_insn "sqrtv4sf2"
20485 [(set (match_operand:V4SF 0 "register_operand" "=x")
20486 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20487 "TARGET_SSE"
20488 "sqrtps\t{%1, %0|%0, %1}"
20489 [(set_attr "type" "sse")
20490 (set_attr "mode" "V4SF")])
20491
20492 (define_insn "vmsqrtv4sf2"
20493 [(set (match_operand:V4SF 0 "register_operand" "=x")
20494 (vec_merge:V4SF
20495 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20496 (match_operand:V4SF 2 "register_operand" "0")
20497 (const_int 1)))]
20498 "TARGET_SSE"
20499 "sqrtss\t{%1, %0|%0, %1}"
20500 [(set_attr "type" "sse")
20501 (set_attr "mode" "SF")])
20502
20503 ;; SSE logical operations.
20504
20505 ;; SSE defines logical operations on floating point values. This brings
20506 ;; interesting challenge to RTL representation where logicals are only valid
20507 ;; on integral types. We deal with this by representing the floating point
20508 ;; logical as logical on arguments casted to TImode as this is what hardware
20509 ;; really does. Unfortunately hardware requires the type information to be
20510 ;; present and thus we must avoid subregs from being simplified and eliminated
20511 ;; in later compilation phases.
20512 ;;
20513 ;; We have following variants from each instruction:
20514 ;; sse_andsf3 - the operation taking V4SF vector operands
20515 ;; and doing TImode cast on them
20516 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20517 ;; TImode, since backend insist on eliminating casts
20518 ;; on memory operands
20519 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20520 ;; We can not accept memory operand here as instruction reads
20521 ;; whole scalar. This is generated only post reload by GCC
20522 ;; scalar float operations that expands to logicals (fabs)
20523 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20524 ;; memory operand. Eventually combine can be able
20525 ;; to synthesize these using splitter.
20526 ;; sse2_anddf3, *sse2_anddf3_memory
20527 ;;
20528 ;;
20529 ;; These are not called andti3 etc. because we really really don't want
20530 ;; the compiler to widen DImode ands to TImode ands and then try to move
20531 ;; into DImode subregs of SSE registers, and them together, and move out
20532 ;; of DImode subregs again!
20533 ;; SSE1 single precision floating point logical operation
20534 (define_expand "sse_andv4sf3"
20535 [(set (match_operand:V4SF 0 "register_operand" "")
20536 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20537 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20538 "TARGET_SSE"
20539 "")
20540
20541 (define_insn "*sse_andv4sf3"
20542 [(set (match_operand:V4SF 0 "register_operand" "=x")
20543 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20544 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20545 "TARGET_SSE
20546 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20547 "andps\t{%2, %0|%0, %2}"
20548 [(set_attr "type" "sselog")
20549 (set_attr "mode" "V4SF")])
20550
20551 (define_expand "sse_nandv4sf3"
20552 [(set (match_operand:V4SF 0 "register_operand" "")
20553 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20554 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20555 "TARGET_SSE"
20556 "")
20557
20558 (define_insn "*sse_nandv4sf3"
20559 [(set (match_operand:V4SF 0 "register_operand" "=x")
20560 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20561 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20562 "TARGET_SSE"
20563 "andnps\t{%2, %0|%0, %2}"
20564 [(set_attr "type" "sselog")
20565 (set_attr "mode" "V4SF")])
20566
20567 (define_expand "sse_iorv4sf3"
20568 [(set (match_operand:V4SF 0 "register_operand" "")
20569 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20570 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20571 "TARGET_SSE"
20572 "")
20573
20574 (define_insn "*sse_iorv4sf3"
20575 [(set (match_operand:V4SF 0 "register_operand" "=x")
20576 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20577 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20578 "TARGET_SSE
20579 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20580 "orps\t{%2, %0|%0, %2}"
20581 [(set_attr "type" "sselog")
20582 (set_attr "mode" "V4SF")])
20583
20584 (define_expand "sse_xorv4sf3"
20585 [(set (match_operand:V4SF 0 "register_operand" "")
20586 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20587 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20588 "TARGET_SSE"
20589 "")
20590
20591 (define_insn "*sse_xorv4sf3"
20592 [(set (match_operand:V4SF 0 "register_operand" "=x")
20593 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20594 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20595 "TARGET_SSE
20596 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20597 "xorps\t{%2, %0|%0, %2}"
20598 [(set_attr "type" "sselog")
20599 (set_attr "mode" "V4SF")])
20600
20601 ;; SSE2 double precision floating point logical operation
20602
20603 (define_expand "sse2_andv2df3"
20604 [(set (match_operand:V2DF 0 "register_operand" "")
20605 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20606 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20607 "TARGET_SSE2"
20608 "")
20609
20610 (define_insn "*sse2_andv2df3"
20611 [(set (match_operand:V2DF 0 "register_operand" "=x")
20612 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20613 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20614 "TARGET_SSE2
20615 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20616 "andpd\t{%2, %0|%0, %2}"
20617 [(set_attr "type" "sselog")
20618 (set_attr "mode" "V2DF")])
20619
20620 (define_expand "sse2_nandv2df3"
20621 [(set (match_operand:V2DF 0 "register_operand" "")
20622 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20623 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20624 "TARGET_SSE2"
20625 "")
20626
20627 (define_insn "*sse2_nandv2df3"
20628 [(set (match_operand:V2DF 0 "register_operand" "=x")
20629 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20630 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20631 "TARGET_SSE2"
20632 "andnpd\t{%2, %0|%0, %2}"
20633 [(set_attr "type" "sselog")
20634 (set_attr "mode" "V2DF")])
20635
20636 (define_expand "sse2_iorv2df3"
20637 [(set (match_operand:V2DF 0 "register_operand" "")
20638 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20639 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20640 "TARGET_SSE2"
20641 "")
20642
20643 (define_insn "*sse2_iorv2df3"
20644 [(set (match_operand:V2DF 0 "register_operand" "=x")
20645 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20646 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20647 "TARGET_SSE2
20648 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20649 "orpd\t{%2, %0|%0, %2}"
20650 [(set_attr "type" "sselog")
20651 (set_attr "mode" "V2DF")])
20652
20653 (define_expand "sse2_xorv2df3"
20654 [(set (match_operand:V2DF 0 "register_operand" "")
20655 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20656 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20657 "TARGET_SSE2"
20658 "")
20659
20660 (define_insn "*sse2_xorv2df3"
20661 [(set (match_operand:V2DF 0 "register_operand" "=x")
20662 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20663 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20664 "TARGET_SSE2
20665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20666 "xorpd\t{%2, %0|%0, %2}"
20667 [(set_attr "type" "sselog")
20668 (set_attr "mode" "V2DF")])
20669
20670 ;; SSE2 integral logicals. These patterns must always come after floating
20671 ;; point ones since we don't want compiler to use integer opcodes on floating
20672 ;; point SSE values to avoid matching of subregs in the match_operand.
20673 (define_insn "*sse2_andti3"
20674 [(set (match_operand:TI 0 "register_operand" "=x")
20675 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20676 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20677 "TARGET_SSE2
20678 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20679 "pand\t{%2, %0|%0, %2}"
20680 [(set_attr "type" "sselog")
20681 (set_attr "mode" "TI")])
20682
20683 (define_insn "sse2_andv2di3"
20684 [(set (match_operand:V2DI 0 "register_operand" "=x")
20685 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20686 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20687 "TARGET_SSE2
20688 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20689 "pand\t{%2, %0|%0, %2}"
20690 [(set_attr "type" "sselog")
20691 (set_attr "mode" "TI")])
20692
20693 (define_insn "*sse2_nandti3"
20694 [(set (match_operand:TI 0 "register_operand" "=x")
20695 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20696 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20697 "TARGET_SSE2"
20698 "pandn\t{%2, %0|%0, %2}"
20699 [(set_attr "type" "sselog")
20700 (set_attr "mode" "TI")])
20701
20702 (define_insn "sse2_nandv2di3"
20703 [(set (match_operand:V2DI 0 "register_operand" "=x")
20704 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20705 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20706 "TARGET_SSE2
20707 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20708 "pandn\t{%2, %0|%0, %2}"
20709 [(set_attr "type" "sselog")
20710 (set_attr "mode" "TI")])
20711
20712 (define_insn "*sse2_iorti3"
20713 [(set (match_operand:TI 0 "register_operand" "=x")
20714 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20715 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20716 "TARGET_SSE2
20717 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20718 "por\t{%2, %0|%0, %2}"
20719 [(set_attr "type" "sselog")
20720 (set_attr "mode" "TI")])
20721
20722 (define_insn "sse2_iorv2di3"
20723 [(set (match_operand:V2DI 0 "register_operand" "=x")
20724 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20725 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20726 "TARGET_SSE2
20727 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20728 "por\t{%2, %0|%0, %2}"
20729 [(set_attr "type" "sselog")
20730 (set_attr "mode" "TI")])
20731
20732 (define_insn "*sse2_xorti3"
20733 [(set (match_operand:TI 0 "register_operand" "=x")
20734 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20735 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20736 "TARGET_SSE2
20737 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20738 "pxor\t{%2, %0|%0, %2}"
20739 [(set_attr "type" "sselog")
20740 (set_attr "mode" "TI")])
20741
20742 (define_insn "sse2_xorv2di3"
20743 [(set (match_operand:V2DI 0 "register_operand" "=x")
20744 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20745 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20746 "TARGET_SSE2
20747 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20748 "pxor\t{%2, %0|%0, %2}"
20749 [(set_attr "type" "sselog")
20750 (set_attr "mode" "TI")])
20751
20752 ;; Use xor, but don't show input operands so they aren't live before
20753 ;; this insn.
20754 (define_insn "sse_clrv4sf"
20755 [(set (match_operand:V4SF 0 "register_operand" "=x")
20756 (match_operand:V4SF 1 "const0_operand" "X"))]
20757 "TARGET_SSE"
20758 {
20759 if (get_attr_mode (insn) == MODE_TI)
20760 return "pxor\t{%0, %0|%0, %0}";
20761 else
20762 return "xorps\t{%0, %0|%0, %0}";
20763 }
20764 [(set_attr "type" "sselog")
20765 (set_attr "memory" "none")
20766 (set (attr "mode")
20767 (if_then_else
20768 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20769 (const_int 0))
20770 (ne (symbol_ref "TARGET_SSE2")
20771 (const_int 0)))
20772 (eq (symbol_ref "optimize_size")
20773 (const_int 0)))
20774 (const_string "TI")
20775 (const_string "V4SF")))])
20776
20777 ;; Use xor, but don't show input operands so they aren't live before
20778 ;; this insn.
20779 (define_insn "sse_clrv2df"
20780 [(set (match_operand:V2DF 0 "register_operand" "=x")
20781 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20782 "TARGET_SSE2"
20783 "xorpd\t{%0, %0|%0, %0}"
20784 [(set_attr "type" "sselog")
20785 (set_attr "memory" "none")
20786 (set_attr "mode" "V4SF")])
20787
20788 ;; SSE mask-generating compares
20789
20790 (define_insn "maskcmpv4sf3"
20791 [(set (match_operand:V4SI 0 "register_operand" "=x")
20792 (match_operator:V4SI 3 "sse_comparison_operator"
20793 [(match_operand:V4SF 1 "register_operand" "0")
20794 (match_operand:V4SF 2 "register_operand" "x")]))]
20795 "TARGET_SSE"
20796 "cmp%D3ps\t{%2, %0|%0, %2}"
20797 [(set_attr "type" "ssecmp")
20798 (set_attr "mode" "V4SF")])
20799
20800 (define_insn "maskncmpv4sf3"
20801 [(set (match_operand:V4SI 0 "register_operand" "=x")
20802 (not:V4SI
20803 (match_operator:V4SI 3 "sse_comparison_operator"
20804 [(match_operand:V4SF 1 "register_operand" "0")
20805 (match_operand:V4SF 2 "register_operand" "x")])))]
20806 "TARGET_SSE"
20807 {
20808 if (GET_CODE (operands[3]) == UNORDERED)
20809 return "cmpordps\t{%2, %0|%0, %2}";
20810 else
20811 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20812 }
20813 [(set_attr "type" "ssecmp")
20814 (set_attr "mode" "V4SF")])
20815
20816 (define_insn "vmmaskcmpv4sf3"
20817 [(set (match_operand:V4SI 0 "register_operand" "=x")
20818 (vec_merge:V4SI
20819 (match_operator:V4SI 3 "sse_comparison_operator"
20820 [(match_operand:V4SF 1 "register_operand" "0")
20821 (match_operand:V4SF 2 "register_operand" "x")])
20822 (subreg:V4SI (match_dup 1) 0)
20823 (const_int 1)))]
20824 "TARGET_SSE"
20825 "cmp%D3ss\t{%2, %0|%0, %2}"
20826 [(set_attr "type" "ssecmp")
20827 (set_attr "mode" "SF")])
20828
20829 (define_insn "vmmaskncmpv4sf3"
20830 [(set (match_operand:V4SI 0 "register_operand" "=x")
20831 (vec_merge:V4SI
20832 (not:V4SI
20833 (match_operator:V4SI 3 "sse_comparison_operator"
20834 [(match_operand:V4SF 1 "register_operand" "0")
20835 (match_operand:V4SF 2 "register_operand" "x")]))
20836 (subreg:V4SI (match_dup 1) 0)
20837 (const_int 1)))]
20838 "TARGET_SSE"
20839 {
20840 if (GET_CODE (operands[3]) == UNORDERED)
20841 return "cmpordss\t{%2, %0|%0, %2}";
20842 else
20843 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20844 }
20845 [(set_attr "type" "ssecmp")
20846 (set_attr "mode" "SF")])
20847
20848 (define_insn "sse_comi"
20849 [(set (reg:CCFP 17)
20850 (compare:CCFP (vec_select:SF
20851 (match_operand:V4SF 0 "register_operand" "x")
20852 (parallel [(const_int 0)]))
20853 (vec_select:SF
20854 (match_operand:V4SF 1 "register_operand" "x")
20855 (parallel [(const_int 0)]))))]
20856 "TARGET_SSE"
20857 "comiss\t{%1, %0|%0, %1}"
20858 [(set_attr "type" "ssecomi")
20859 (set_attr "mode" "SF")])
20860
20861 (define_insn "sse_ucomi"
20862 [(set (reg:CCFPU 17)
20863 (compare:CCFPU (vec_select:SF
20864 (match_operand:V4SF 0 "register_operand" "x")
20865 (parallel [(const_int 0)]))
20866 (vec_select:SF
20867 (match_operand:V4SF 1 "register_operand" "x")
20868 (parallel [(const_int 0)]))))]
20869 "TARGET_SSE"
20870 "ucomiss\t{%1, %0|%0, %1}"
20871 [(set_attr "type" "ssecomi")
20872 (set_attr "mode" "SF")])
20873
20874
20875 ;; SSE unpack
20876
20877 (define_insn "sse_unpckhps"
20878 [(set (match_operand:V4SF 0 "register_operand" "=x")
20879 (vec_merge:V4SF
20880 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20881 (parallel [(const_int 2)
20882 (const_int 0)
20883 (const_int 3)
20884 (const_int 1)]))
20885 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20886 (parallel [(const_int 0)
20887 (const_int 2)
20888 (const_int 1)
20889 (const_int 3)]))
20890 (const_int 5)))]
20891 "TARGET_SSE"
20892 "unpckhps\t{%2, %0|%0, %2}"
20893 [(set_attr "type" "ssecvt")
20894 (set_attr "mode" "V4SF")])
20895
20896 (define_insn "sse_unpcklps"
20897 [(set (match_operand:V4SF 0 "register_operand" "=x")
20898 (vec_merge:V4SF
20899 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20900 (parallel [(const_int 0)
20901 (const_int 2)
20902 (const_int 1)
20903 (const_int 3)]))
20904 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20905 (parallel [(const_int 2)
20906 (const_int 0)
20907 (const_int 3)
20908 (const_int 1)]))
20909 (const_int 5)))]
20910 "TARGET_SSE"
20911 "unpcklps\t{%2, %0|%0, %2}"
20912 [(set_attr "type" "ssecvt")
20913 (set_attr "mode" "V4SF")])
20914
20915
20916 ;; SSE min/max
20917
20918 (define_insn "smaxv4sf3"
20919 [(set (match_operand:V4SF 0 "register_operand" "=x")
20920 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20921 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20922 "TARGET_SSE"
20923 "maxps\t{%2, %0|%0, %2}"
20924 [(set_attr "type" "sse")
20925 (set_attr "mode" "V4SF")])
20926
20927 (define_insn "vmsmaxv4sf3"
20928 [(set (match_operand:V4SF 0 "register_operand" "=x")
20929 (vec_merge:V4SF
20930 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20931 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20932 (match_dup 1)
20933 (const_int 1)))]
20934 "TARGET_SSE"
20935 "maxss\t{%2, %0|%0, %2}"
20936 [(set_attr "type" "sse")
20937 (set_attr "mode" "SF")])
20938
20939 (define_insn "sminv4sf3"
20940 [(set (match_operand:V4SF 0 "register_operand" "=x")
20941 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20942 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20943 "TARGET_SSE"
20944 "minps\t{%2, %0|%0, %2}"
20945 [(set_attr "type" "sse")
20946 (set_attr "mode" "V4SF")])
20947
20948 (define_insn "vmsminv4sf3"
20949 [(set (match_operand:V4SF 0 "register_operand" "=x")
20950 (vec_merge:V4SF
20951 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20952 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20953 (match_dup 1)
20954 (const_int 1)))]
20955 "TARGET_SSE"
20956 "minss\t{%2, %0|%0, %2}"
20957 [(set_attr "type" "sse")
20958 (set_attr "mode" "SF")])
20959
20960 ;; SSE <-> integer/MMX conversions
20961
20962 (define_insn "cvtpi2ps"
20963 [(set (match_operand:V4SF 0 "register_operand" "=x")
20964 (vec_merge:V4SF
20965 (match_operand:V4SF 1 "register_operand" "0")
20966 (vec_duplicate:V4SF
20967 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20968 (const_int 12)))]
20969 "TARGET_SSE"
20970 "cvtpi2ps\t{%2, %0|%0, %2}"
20971 [(set_attr "type" "ssecvt")
20972 (set_attr "mode" "V4SF")])
20973
20974 (define_insn "cvtps2pi"
20975 [(set (match_operand:V2SI 0 "register_operand" "=y")
20976 (vec_select:V2SI
20977 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20978 (parallel [(const_int 0) (const_int 1)])))]
20979 "TARGET_SSE"
20980 "cvtps2pi\t{%1, %0|%0, %1}"
20981 [(set_attr "type" "ssecvt")
20982 (set_attr "mode" "V4SF")])
20983
20984 (define_insn "cvttps2pi"
20985 [(set (match_operand:V2SI 0 "register_operand" "=y")
20986 (vec_select:V2SI
20987 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20988 UNSPEC_FIX)
20989 (parallel [(const_int 0) (const_int 1)])))]
20990 "TARGET_SSE"
20991 "cvttps2pi\t{%1, %0|%0, %1}"
20992 [(set_attr "type" "ssecvt")
20993 (set_attr "mode" "SF")])
20994
20995 (define_insn "cvtsi2ss"
20996 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20997 (vec_merge:V4SF
20998 (match_operand:V4SF 1 "register_operand" "0,0")
20999 (vec_duplicate:V4SF
21000 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21001 (const_int 14)))]
21002 "TARGET_SSE"
21003 "cvtsi2ss\t{%2, %0|%0, %2}"
21004 [(set_attr "type" "sseicvt")
21005 (set_attr "athlon_decode" "vector,double")
21006 (set_attr "mode" "SF")])
21007
21008 (define_insn "cvtsi2ssq"
21009 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21010 (vec_merge:V4SF
21011 (match_operand:V4SF 1 "register_operand" "0,0")
21012 (vec_duplicate:V4SF
21013 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21014 (const_int 14)))]
21015 "TARGET_SSE && TARGET_64BIT"
21016 "cvtsi2ssq\t{%2, %0|%0, %2}"
21017 [(set_attr "type" "sseicvt")
21018 (set_attr "athlon_decode" "vector,double")
21019 (set_attr "mode" "SF")])
21020
21021 (define_insn "cvtss2si"
21022 [(set (match_operand:SI 0 "register_operand" "=r,r")
21023 (vec_select:SI
21024 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21025 (parallel [(const_int 0)])))]
21026 "TARGET_SSE"
21027 "cvtss2si\t{%1, %0|%0, %1}"
21028 [(set_attr "type" "sseicvt")
21029 (set_attr "athlon_decode" "double,vector")
21030 (set_attr "mode" "SI")])
21031
21032 (define_insn "cvtss2siq"
21033 [(set (match_operand:DI 0 "register_operand" "=r,r")
21034 (vec_select:DI
21035 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21036 (parallel [(const_int 0)])))]
21037 "TARGET_SSE"
21038 "cvtss2siq\t{%1, %0|%0, %1}"
21039 [(set_attr "type" "sseicvt")
21040 (set_attr "athlon_decode" "double,vector")
21041 (set_attr "mode" "DI")])
21042
21043 (define_insn "cvttss2si"
21044 [(set (match_operand:SI 0 "register_operand" "=r,r")
21045 (vec_select:SI
21046 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21047 UNSPEC_FIX)
21048 (parallel [(const_int 0)])))]
21049 "TARGET_SSE"
21050 "cvttss2si\t{%1, %0|%0, %1}"
21051 [(set_attr "type" "sseicvt")
21052 (set_attr "mode" "SF")
21053 (set_attr "athlon_decode" "double,vector")])
21054
21055 (define_insn "cvttss2siq"
21056 [(set (match_operand:DI 0 "register_operand" "=r,r")
21057 (vec_select:DI
21058 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21059 UNSPEC_FIX)
21060 (parallel [(const_int 0)])))]
21061 "TARGET_SSE && TARGET_64BIT"
21062 "cvttss2siq\t{%1, %0|%0, %1}"
21063 [(set_attr "type" "sseicvt")
21064 (set_attr "mode" "SF")
21065 (set_attr "athlon_decode" "double,vector")])
21066
21067
21068 ;; MMX insns
21069
21070 ;; MMX arithmetic
21071
21072 (define_insn "addv8qi3"
21073 [(set (match_operand:V8QI 0 "register_operand" "=y")
21074 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21075 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21076 "TARGET_MMX"
21077 "paddb\t{%2, %0|%0, %2}"
21078 [(set_attr "type" "mmxadd")
21079 (set_attr "mode" "DI")])
21080
21081 (define_insn "addv4hi3"
21082 [(set (match_operand:V4HI 0 "register_operand" "=y")
21083 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21084 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21085 "TARGET_MMX"
21086 "paddw\t{%2, %0|%0, %2}"
21087 [(set_attr "type" "mmxadd")
21088 (set_attr "mode" "DI")])
21089
21090 (define_insn "addv2si3"
21091 [(set (match_operand:V2SI 0 "register_operand" "=y")
21092 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21093 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21094 "TARGET_MMX"
21095 "paddd\t{%2, %0|%0, %2}"
21096 [(set_attr "type" "mmxadd")
21097 (set_attr "mode" "DI")])
21098
21099 (define_insn "mmx_adddi3"
21100 [(set (match_operand:DI 0 "register_operand" "=y")
21101 (unspec:DI
21102 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21103 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21104 UNSPEC_NOP))]
21105 "TARGET_MMX"
21106 "paddq\t{%2, %0|%0, %2}"
21107 [(set_attr "type" "mmxadd")
21108 (set_attr "mode" "DI")])
21109
21110 (define_insn "ssaddv8qi3"
21111 [(set (match_operand:V8QI 0 "register_operand" "=y")
21112 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21113 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21114 "TARGET_MMX"
21115 "paddsb\t{%2, %0|%0, %2}"
21116 [(set_attr "type" "mmxadd")
21117 (set_attr "mode" "DI")])
21118
21119 (define_insn "ssaddv4hi3"
21120 [(set (match_operand:V4HI 0 "register_operand" "=y")
21121 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21122 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21123 "TARGET_MMX"
21124 "paddsw\t{%2, %0|%0, %2}"
21125 [(set_attr "type" "mmxadd")
21126 (set_attr "mode" "DI")])
21127
21128 (define_insn "usaddv8qi3"
21129 [(set (match_operand:V8QI 0 "register_operand" "=y")
21130 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21131 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21132 "TARGET_MMX"
21133 "paddusb\t{%2, %0|%0, %2}"
21134 [(set_attr "type" "mmxadd")
21135 (set_attr "mode" "DI")])
21136
21137 (define_insn "usaddv4hi3"
21138 [(set (match_operand:V4HI 0 "register_operand" "=y")
21139 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21140 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21141 "TARGET_MMX"
21142 "paddusw\t{%2, %0|%0, %2}"
21143 [(set_attr "type" "mmxadd")
21144 (set_attr "mode" "DI")])
21145
21146 (define_insn "subv8qi3"
21147 [(set (match_operand:V8QI 0 "register_operand" "=y")
21148 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21149 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21150 "TARGET_MMX"
21151 "psubb\t{%2, %0|%0, %2}"
21152 [(set_attr "type" "mmxadd")
21153 (set_attr "mode" "DI")])
21154
21155 (define_insn "subv4hi3"
21156 [(set (match_operand:V4HI 0 "register_operand" "=y")
21157 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21158 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21159 "TARGET_MMX"
21160 "psubw\t{%2, %0|%0, %2}"
21161 [(set_attr "type" "mmxadd")
21162 (set_attr "mode" "DI")])
21163
21164 (define_insn "subv2si3"
21165 [(set (match_operand:V2SI 0 "register_operand" "=y")
21166 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21167 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21168 "TARGET_MMX"
21169 "psubd\t{%2, %0|%0, %2}"
21170 [(set_attr "type" "mmxadd")
21171 (set_attr "mode" "DI")])
21172
21173 (define_insn "mmx_subdi3"
21174 [(set (match_operand:DI 0 "register_operand" "=y")
21175 (unspec:DI
21176 [(minus:DI (match_operand:DI 1 "register_operand" "0")
21177 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21178 UNSPEC_NOP))]
21179 "TARGET_MMX"
21180 "psubq\t{%2, %0|%0, %2}"
21181 [(set_attr "type" "mmxadd")
21182 (set_attr "mode" "DI")])
21183
21184 (define_insn "sssubv8qi3"
21185 [(set (match_operand:V8QI 0 "register_operand" "=y")
21186 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21187 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21188 "TARGET_MMX"
21189 "psubsb\t{%2, %0|%0, %2}"
21190 [(set_attr "type" "mmxadd")
21191 (set_attr "mode" "DI")])
21192
21193 (define_insn "sssubv4hi3"
21194 [(set (match_operand:V4HI 0 "register_operand" "=y")
21195 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21196 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21197 "TARGET_MMX"
21198 "psubsw\t{%2, %0|%0, %2}"
21199 [(set_attr "type" "mmxadd")
21200 (set_attr "mode" "DI")])
21201
21202 (define_insn "ussubv8qi3"
21203 [(set (match_operand:V8QI 0 "register_operand" "=y")
21204 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21205 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21206 "TARGET_MMX"
21207 "psubusb\t{%2, %0|%0, %2}"
21208 [(set_attr "type" "mmxadd")
21209 (set_attr "mode" "DI")])
21210
21211 (define_insn "ussubv4hi3"
21212 [(set (match_operand:V4HI 0 "register_operand" "=y")
21213 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21214 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21215 "TARGET_MMX"
21216 "psubusw\t{%2, %0|%0, %2}"
21217 [(set_attr "type" "mmxadd")
21218 (set_attr "mode" "DI")])
21219
21220 (define_insn "mulv4hi3"
21221 [(set (match_operand:V4HI 0 "register_operand" "=y")
21222 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21223 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21224 "TARGET_MMX"
21225 "pmullw\t{%2, %0|%0, %2}"
21226 [(set_attr "type" "mmxmul")
21227 (set_attr "mode" "DI")])
21228
21229 (define_insn "smulv4hi3_highpart"
21230 [(set (match_operand:V4HI 0 "register_operand" "=y")
21231 (truncate:V4HI
21232 (lshiftrt:V4SI
21233 (mult:V4SI (sign_extend:V4SI
21234 (match_operand:V4HI 1 "register_operand" "0"))
21235 (sign_extend:V4SI
21236 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21237 (const_int 16))))]
21238 "TARGET_MMX"
21239 "pmulhw\t{%2, %0|%0, %2}"
21240 [(set_attr "type" "mmxmul")
21241 (set_attr "mode" "DI")])
21242
21243 (define_insn "umulv4hi3_highpart"
21244 [(set (match_operand:V4HI 0 "register_operand" "=y")
21245 (truncate:V4HI
21246 (lshiftrt:V4SI
21247 (mult:V4SI (zero_extend:V4SI
21248 (match_operand:V4HI 1 "register_operand" "0"))
21249 (zero_extend:V4SI
21250 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21251 (const_int 16))))]
21252 "TARGET_SSE || TARGET_3DNOW_A"
21253 "pmulhuw\t{%2, %0|%0, %2}"
21254 [(set_attr "type" "mmxmul")
21255 (set_attr "mode" "DI")])
21256
21257 (define_insn "mmx_pmaddwd"
21258 [(set (match_operand:V2SI 0 "register_operand" "=y")
21259 (plus:V2SI
21260 (mult:V2SI
21261 (sign_extend:V2SI
21262 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21263 (parallel [(const_int 0) (const_int 2)])))
21264 (sign_extend:V2SI
21265 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21266 (parallel [(const_int 0) (const_int 2)]))))
21267 (mult:V2SI
21268 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21269 (parallel [(const_int 1)
21270 (const_int 3)])))
21271 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21272 (parallel [(const_int 1)
21273 (const_int 3)]))))))]
21274 "TARGET_MMX"
21275 "pmaddwd\t{%2, %0|%0, %2}"
21276 [(set_attr "type" "mmxmul")
21277 (set_attr "mode" "DI")])
21278
21279
21280 ;; MMX logical operations
21281 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21282 ;; normal code that also wants to use the FPU from getting broken.
21283 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21284 (define_insn "mmx_iordi3"
21285 [(set (match_operand:DI 0 "register_operand" "=y")
21286 (unspec:DI
21287 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21288 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21289 UNSPEC_NOP))]
21290 "TARGET_MMX"
21291 "por\t{%2, %0|%0, %2}"
21292 [(set_attr "type" "mmxadd")
21293 (set_attr "mode" "DI")])
21294
21295 (define_insn "mmx_xordi3"
21296 [(set (match_operand:DI 0 "register_operand" "=y")
21297 (unspec:DI
21298 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21299 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21300 UNSPEC_NOP))]
21301 "TARGET_MMX"
21302 "pxor\t{%2, %0|%0, %2}"
21303 [(set_attr "type" "mmxadd")
21304 (set_attr "mode" "DI")
21305 (set_attr "memory" "none")])
21306
21307 ;; Same as pxor, but don't show input operands so that we don't think
21308 ;; they are live.
21309 (define_insn "mmx_clrdi"
21310 [(set (match_operand:DI 0 "register_operand" "=y")
21311 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21312 "TARGET_MMX"
21313 "pxor\t{%0, %0|%0, %0}"
21314 [(set_attr "type" "mmxadd")
21315 (set_attr "mode" "DI")
21316 (set_attr "memory" "none")])
21317
21318 (define_insn "mmx_anddi3"
21319 [(set (match_operand:DI 0 "register_operand" "=y")
21320 (unspec:DI
21321 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21322 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21323 UNSPEC_NOP))]
21324 "TARGET_MMX"
21325 "pand\t{%2, %0|%0, %2}"
21326 [(set_attr "type" "mmxadd")
21327 (set_attr "mode" "DI")])
21328
21329 (define_insn "mmx_nanddi3"
21330 [(set (match_operand:DI 0 "register_operand" "=y")
21331 (unspec:DI
21332 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21333 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21334 UNSPEC_NOP))]
21335 "TARGET_MMX"
21336 "pandn\t{%2, %0|%0, %2}"
21337 [(set_attr "type" "mmxadd")
21338 (set_attr "mode" "DI")])
21339
21340
21341 ;; MMX unsigned averages/sum of absolute differences
21342
21343 (define_insn "mmx_uavgv8qi3"
21344 [(set (match_operand:V8QI 0 "register_operand" "=y")
21345 (ashiftrt:V8QI
21346 (plus:V8QI (plus:V8QI
21347 (match_operand:V8QI 1 "register_operand" "0")
21348 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21349 (const_vector:V8QI [(const_int 1)
21350 (const_int 1)
21351 (const_int 1)
21352 (const_int 1)
21353 (const_int 1)
21354 (const_int 1)
21355 (const_int 1)
21356 (const_int 1)]))
21357 (const_int 1)))]
21358 "TARGET_SSE || TARGET_3DNOW_A"
21359 "pavgb\t{%2, %0|%0, %2}"
21360 [(set_attr "type" "mmxshft")
21361 (set_attr "mode" "DI")])
21362
21363 (define_insn "mmx_uavgv4hi3"
21364 [(set (match_operand:V4HI 0 "register_operand" "=y")
21365 (ashiftrt:V4HI
21366 (plus:V4HI (plus:V4HI
21367 (match_operand:V4HI 1 "register_operand" "0")
21368 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21369 (const_vector:V4HI [(const_int 1)
21370 (const_int 1)
21371 (const_int 1)
21372 (const_int 1)]))
21373 (const_int 1)))]
21374 "TARGET_SSE || TARGET_3DNOW_A"
21375 "pavgw\t{%2, %0|%0, %2}"
21376 [(set_attr "type" "mmxshft")
21377 (set_attr "mode" "DI")])
21378
21379 (define_insn "mmx_psadbw"
21380 [(set (match_operand:DI 0 "register_operand" "=y")
21381 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21382 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21383 UNSPEC_PSADBW))]
21384 "TARGET_SSE || TARGET_3DNOW_A"
21385 "psadbw\t{%2, %0|%0, %2}"
21386 [(set_attr "type" "mmxshft")
21387 (set_attr "mode" "DI")])
21388
21389
21390 ;; MMX insert/extract/shuffle
21391
21392 (define_insn "mmx_pinsrw"
21393 [(set (match_operand:V4HI 0 "register_operand" "=y")
21394 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21395 (vec_duplicate:V4HI
21396 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21397 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21398 "TARGET_SSE || TARGET_3DNOW_A"
21399 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21400 [(set_attr "type" "mmxcvt")
21401 (set_attr "mode" "DI")])
21402
21403 (define_insn "mmx_pextrw"
21404 [(set (match_operand:SI 0 "register_operand" "=r")
21405 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21406 (parallel
21407 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21408 "TARGET_SSE || TARGET_3DNOW_A"
21409 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21410 [(set_attr "type" "mmxcvt")
21411 (set_attr "mode" "DI")])
21412
21413 (define_insn "mmx_pshufw"
21414 [(set (match_operand:V4HI 0 "register_operand" "=y")
21415 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21416 (match_operand:SI 2 "immediate_operand" "i")]
21417 UNSPEC_SHUFFLE))]
21418 "TARGET_SSE || TARGET_3DNOW_A"
21419 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21420 [(set_attr "type" "mmxcvt")
21421 (set_attr "mode" "DI")])
21422
21423
21424 ;; MMX mask-generating comparisons
21425
21426 (define_insn "eqv8qi3"
21427 [(set (match_operand:V8QI 0 "register_operand" "=y")
21428 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21429 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21430 "TARGET_MMX"
21431 "pcmpeqb\t{%2, %0|%0, %2}"
21432 [(set_attr "type" "mmxcmp")
21433 (set_attr "mode" "DI")])
21434
21435 (define_insn "eqv4hi3"
21436 [(set (match_operand:V4HI 0 "register_operand" "=y")
21437 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21438 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21439 "TARGET_MMX"
21440 "pcmpeqw\t{%2, %0|%0, %2}"
21441 [(set_attr "type" "mmxcmp")
21442 (set_attr "mode" "DI")])
21443
21444 (define_insn "eqv2si3"
21445 [(set (match_operand:V2SI 0 "register_operand" "=y")
21446 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21447 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21448 "TARGET_MMX"
21449 "pcmpeqd\t{%2, %0|%0, %2}"
21450 [(set_attr "type" "mmxcmp")
21451 (set_attr "mode" "DI")])
21452
21453 (define_insn "gtv8qi3"
21454 [(set (match_operand:V8QI 0 "register_operand" "=y")
21455 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21456 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21457 "TARGET_MMX"
21458 "pcmpgtb\t{%2, %0|%0, %2}"
21459 [(set_attr "type" "mmxcmp")
21460 (set_attr "mode" "DI")])
21461
21462 (define_insn "gtv4hi3"
21463 [(set (match_operand:V4HI 0 "register_operand" "=y")
21464 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21465 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21466 "TARGET_MMX"
21467 "pcmpgtw\t{%2, %0|%0, %2}"
21468 [(set_attr "type" "mmxcmp")
21469 (set_attr "mode" "DI")])
21470
21471 (define_insn "gtv2si3"
21472 [(set (match_operand:V2SI 0 "register_operand" "=y")
21473 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21474 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21475 "TARGET_MMX"
21476 "pcmpgtd\t{%2, %0|%0, %2}"
21477 [(set_attr "type" "mmxcmp")
21478 (set_attr "mode" "DI")])
21479
21480
21481 ;; MMX max/min insns
21482
21483 (define_insn "umaxv8qi3"
21484 [(set (match_operand:V8QI 0 "register_operand" "=y")
21485 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21486 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21487 "TARGET_SSE || TARGET_3DNOW_A"
21488 "pmaxub\t{%2, %0|%0, %2}"
21489 [(set_attr "type" "mmxadd")
21490 (set_attr "mode" "DI")])
21491
21492 (define_insn "smaxv4hi3"
21493 [(set (match_operand:V4HI 0 "register_operand" "=y")
21494 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21495 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21496 "TARGET_SSE || TARGET_3DNOW_A"
21497 "pmaxsw\t{%2, %0|%0, %2}"
21498 [(set_attr "type" "mmxadd")
21499 (set_attr "mode" "DI")])
21500
21501 (define_insn "uminv8qi3"
21502 [(set (match_operand:V8QI 0 "register_operand" "=y")
21503 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21504 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21505 "TARGET_SSE || TARGET_3DNOW_A"
21506 "pminub\t{%2, %0|%0, %2}"
21507 [(set_attr "type" "mmxadd")
21508 (set_attr "mode" "DI")])
21509
21510 (define_insn "sminv4hi3"
21511 [(set (match_operand:V4HI 0 "register_operand" "=y")
21512 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21513 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21514 "TARGET_SSE || TARGET_3DNOW_A"
21515 "pminsw\t{%2, %0|%0, %2}"
21516 [(set_attr "type" "mmxadd")
21517 (set_attr "mode" "DI")])
21518
21519
21520 ;; MMX shifts
21521
21522 (define_insn "ashrv4hi3"
21523 [(set (match_operand:V4HI 0 "register_operand" "=y")
21524 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21525 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21526 "TARGET_MMX"
21527 "psraw\t{%2, %0|%0, %2}"
21528 [(set_attr "type" "mmxshft")
21529 (set_attr "mode" "DI")])
21530
21531 (define_insn "ashrv2si3"
21532 [(set (match_operand:V2SI 0 "register_operand" "=y")
21533 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21534 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21535 "TARGET_MMX"
21536 "psrad\t{%2, %0|%0, %2}"
21537 [(set_attr "type" "mmxshft")
21538 (set_attr "mode" "DI")])
21539
21540 (define_insn "lshrv4hi3"
21541 [(set (match_operand:V4HI 0 "register_operand" "=y")
21542 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21543 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21544 "TARGET_MMX"
21545 "psrlw\t{%2, %0|%0, %2}"
21546 [(set_attr "type" "mmxshft")
21547 (set_attr "mode" "DI")])
21548
21549 (define_insn "lshrv2si3"
21550 [(set (match_operand:V2SI 0 "register_operand" "=y")
21551 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21552 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21553 "TARGET_MMX"
21554 "psrld\t{%2, %0|%0, %2}"
21555 [(set_attr "type" "mmxshft")
21556 (set_attr "mode" "DI")])
21557
21558 ;; See logical MMX insns.
21559 (define_insn "mmx_lshrdi3"
21560 [(set (match_operand:DI 0 "register_operand" "=y")
21561 (unspec:DI
21562 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21563 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21564 UNSPEC_NOP))]
21565 "TARGET_MMX"
21566 "psrlq\t{%2, %0|%0, %2}"
21567 [(set_attr "type" "mmxshft")
21568 (set_attr "mode" "DI")])
21569
21570 (define_insn "ashlv4hi3"
21571 [(set (match_operand:V4HI 0 "register_operand" "=y")
21572 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21573 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21574 "TARGET_MMX"
21575 "psllw\t{%2, %0|%0, %2}"
21576 [(set_attr "type" "mmxshft")
21577 (set_attr "mode" "DI")])
21578
21579 (define_insn "ashlv2si3"
21580 [(set (match_operand:V2SI 0 "register_operand" "=y")
21581 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21582 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21583 "TARGET_MMX"
21584 "pslld\t{%2, %0|%0, %2}"
21585 [(set_attr "type" "mmxshft")
21586 (set_attr "mode" "DI")])
21587
21588 ;; See logical MMX insns.
21589 (define_insn "mmx_ashldi3"
21590 [(set (match_operand:DI 0 "register_operand" "=y")
21591 (unspec:DI
21592 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21593 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21594 UNSPEC_NOP))]
21595 "TARGET_MMX"
21596 "psllq\t{%2, %0|%0, %2}"
21597 [(set_attr "type" "mmxshft")
21598 (set_attr "mode" "DI")])
21599
21600
21601 ;; MMX pack/unpack insns.
21602
21603 (define_insn "mmx_packsswb"
21604 [(set (match_operand:V8QI 0 "register_operand" "=y")
21605 (vec_concat:V8QI
21606 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21607 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21608 "TARGET_MMX"
21609 "packsswb\t{%2, %0|%0, %2}"
21610 [(set_attr "type" "mmxshft")
21611 (set_attr "mode" "DI")])
21612
21613 (define_insn "mmx_packssdw"
21614 [(set (match_operand:V4HI 0 "register_operand" "=y")
21615 (vec_concat:V4HI
21616 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21617 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21618 "TARGET_MMX"
21619 "packssdw\t{%2, %0|%0, %2}"
21620 [(set_attr "type" "mmxshft")
21621 (set_attr "mode" "DI")])
21622
21623 (define_insn "mmx_packuswb"
21624 [(set (match_operand:V8QI 0 "register_operand" "=y")
21625 (vec_concat:V8QI
21626 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21627 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21628 "TARGET_MMX"
21629 "packuswb\t{%2, %0|%0, %2}"
21630 [(set_attr "type" "mmxshft")
21631 (set_attr "mode" "DI")])
21632
21633 (define_insn "mmx_punpckhbw"
21634 [(set (match_operand:V8QI 0 "register_operand" "=y")
21635 (vec_merge:V8QI
21636 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21637 (parallel [(const_int 4)
21638 (const_int 0)
21639 (const_int 5)
21640 (const_int 1)
21641 (const_int 6)
21642 (const_int 2)
21643 (const_int 7)
21644 (const_int 3)]))
21645 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21646 (parallel [(const_int 0)
21647 (const_int 4)
21648 (const_int 1)
21649 (const_int 5)
21650 (const_int 2)
21651 (const_int 6)
21652 (const_int 3)
21653 (const_int 7)]))
21654 (const_int 85)))]
21655 "TARGET_MMX"
21656 "punpckhbw\t{%2, %0|%0, %2}"
21657 [(set_attr "type" "mmxcvt")
21658 (set_attr "mode" "DI")])
21659
21660 (define_insn "mmx_punpckhwd"
21661 [(set (match_operand:V4HI 0 "register_operand" "=y")
21662 (vec_merge:V4HI
21663 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21664 (parallel [(const_int 0)
21665 (const_int 2)
21666 (const_int 1)
21667 (const_int 3)]))
21668 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21669 (parallel [(const_int 2)
21670 (const_int 0)
21671 (const_int 3)
21672 (const_int 1)]))
21673 (const_int 5)))]
21674 "TARGET_MMX"
21675 "punpckhwd\t{%2, %0|%0, %2}"
21676 [(set_attr "type" "mmxcvt")
21677 (set_attr "mode" "DI")])
21678
21679 (define_insn "mmx_punpckhdq"
21680 [(set (match_operand:V2SI 0 "register_operand" "=y")
21681 (vec_merge:V2SI
21682 (match_operand:V2SI 1 "register_operand" "0")
21683 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21684 (parallel [(const_int 1)
21685 (const_int 0)]))
21686 (const_int 1)))]
21687 "TARGET_MMX"
21688 "punpckhdq\t{%2, %0|%0, %2}"
21689 [(set_attr "type" "mmxcvt")
21690 (set_attr "mode" "DI")])
21691
21692 (define_insn "mmx_punpcklbw"
21693 [(set (match_operand:V8QI 0 "register_operand" "=y")
21694 (vec_merge:V8QI
21695 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21696 (parallel [(const_int 0)
21697 (const_int 4)
21698 (const_int 1)
21699 (const_int 5)
21700 (const_int 2)
21701 (const_int 6)
21702 (const_int 3)
21703 (const_int 7)]))
21704 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21705 (parallel [(const_int 4)
21706 (const_int 0)
21707 (const_int 5)
21708 (const_int 1)
21709 (const_int 6)
21710 (const_int 2)
21711 (const_int 7)
21712 (const_int 3)]))
21713 (const_int 85)))]
21714 "TARGET_MMX"
21715 "punpcklbw\t{%2, %0|%0, %2}"
21716 [(set_attr "type" "mmxcvt")
21717 (set_attr "mode" "DI")])
21718
21719 (define_insn "mmx_punpcklwd"
21720 [(set (match_operand:V4HI 0 "register_operand" "=y")
21721 (vec_merge:V4HI
21722 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21723 (parallel [(const_int 2)
21724 (const_int 0)
21725 (const_int 3)
21726 (const_int 1)]))
21727 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21728 (parallel [(const_int 0)
21729 (const_int 2)
21730 (const_int 1)
21731 (const_int 3)]))
21732 (const_int 5)))]
21733 "TARGET_MMX"
21734 "punpcklwd\t{%2, %0|%0, %2}"
21735 [(set_attr "type" "mmxcvt")
21736 (set_attr "mode" "DI")])
21737
21738 (define_insn "mmx_punpckldq"
21739 [(set (match_operand:V2SI 0 "register_operand" "=y")
21740 (vec_merge:V2SI
21741 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21742 (parallel [(const_int 1)
21743 (const_int 0)]))
21744 (match_operand:V2SI 2 "register_operand" "y")
21745 (const_int 1)))]
21746 "TARGET_MMX"
21747 "punpckldq\t{%2, %0|%0, %2}"
21748 [(set_attr "type" "mmxcvt")
21749 (set_attr "mode" "DI")])
21750
21751
21752 ;; Miscellaneous stuff
21753
21754 (define_insn "emms"
21755 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21756 (clobber (reg:XF 8))
21757 (clobber (reg:XF 9))
21758 (clobber (reg:XF 10))
21759 (clobber (reg:XF 11))
21760 (clobber (reg:XF 12))
21761 (clobber (reg:XF 13))
21762 (clobber (reg:XF 14))
21763 (clobber (reg:XF 15))
21764 (clobber (reg:DI 29))
21765 (clobber (reg:DI 30))
21766 (clobber (reg:DI 31))
21767 (clobber (reg:DI 32))
21768 (clobber (reg:DI 33))
21769 (clobber (reg:DI 34))
21770 (clobber (reg:DI 35))
21771 (clobber (reg:DI 36))]
21772 "TARGET_MMX"
21773 "emms"
21774 [(set_attr "type" "mmx")
21775 (set_attr "memory" "unknown")])
21776
21777 (define_insn "ldmxcsr"
21778 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21779 UNSPECV_LDMXCSR)]
21780 "TARGET_SSE"
21781 "ldmxcsr\t%0"
21782 [(set_attr "type" "sse")
21783 (set_attr "memory" "load")])
21784
21785 (define_insn "stmxcsr"
21786 [(set (match_operand:SI 0 "memory_operand" "=m")
21787 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21788 "TARGET_SSE"
21789 "stmxcsr\t%0"
21790 [(set_attr "type" "sse")
21791 (set_attr "memory" "store")])
21792
21793 (define_expand "sfence"
21794 [(set (match_dup 0)
21795 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21796 "TARGET_SSE || TARGET_3DNOW_A"
21797 {
21798 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21799 MEM_VOLATILE_P (operands[0]) = 1;
21800 })
21801
21802 (define_insn "*sfence_insn"
21803 [(set (match_operand:BLK 0 "" "")
21804 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21805 "TARGET_SSE || TARGET_3DNOW_A"
21806 "sfence"
21807 [(set_attr "type" "sse")
21808 (set_attr "memory" "unknown")])
21809
21810 (define_expand "sse_prologue_save"
21811 [(parallel [(set (match_operand:BLK 0 "" "")
21812 (unspec:BLK [(reg:DI 21)
21813 (reg:DI 22)
21814 (reg:DI 23)
21815 (reg:DI 24)
21816 (reg:DI 25)
21817 (reg:DI 26)
21818 (reg:DI 27)
21819 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21820 (use (match_operand:DI 1 "register_operand" ""))
21821 (use (match_operand:DI 2 "immediate_operand" ""))
21822 (use (label_ref:DI (match_operand 3 "" "")))])]
21823 "TARGET_64BIT"
21824 "")
21825
21826 (define_insn "*sse_prologue_save_insn"
21827 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21828 (match_operand:DI 4 "const_int_operand" "n")))
21829 (unspec:BLK [(reg:DI 21)
21830 (reg:DI 22)
21831 (reg:DI 23)
21832 (reg:DI 24)
21833 (reg:DI 25)
21834 (reg:DI 26)
21835 (reg:DI 27)
21836 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21837 (use (match_operand:DI 1 "register_operand" "r"))
21838 (use (match_operand:DI 2 "const_int_operand" "i"))
21839 (use (label_ref:DI (match_operand 3 "" "X")))]
21840 "TARGET_64BIT
21841 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21842 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21843 "*
21844 {
21845 int i;
21846 operands[0] = gen_rtx_MEM (Pmode,
21847 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21848 output_asm_insn (\"jmp\\t%A1\", operands);
21849 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21850 {
21851 operands[4] = adjust_address (operands[0], DImode, i*16);
21852 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21853 PUT_MODE (operands[4], TImode);
21854 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21855 output_asm_insn (\"rex\", operands);
21856 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21857 }
21858 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21859 CODE_LABEL_NUMBER (operands[3]));
21860 RET;
21861 }
21862 "
21863 [(set_attr "type" "other")
21864 (set_attr "length_immediate" "0")
21865 (set_attr "length_address" "0")
21866 (set_attr "length" "135")
21867 (set_attr "memory" "store")
21868 (set_attr "modrm" "0")
21869 (set_attr "mode" "DI")])
21870
21871 ;; 3Dnow! instructions
21872
21873 (define_insn "addv2sf3"
21874 [(set (match_operand:V2SF 0 "register_operand" "=y")
21875 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21876 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21877 "TARGET_3DNOW"
21878 "pfadd\\t{%2, %0|%0, %2}"
21879 [(set_attr "type" "mmxadd")
21880 (set_attr "mode" "V2SF")])
21881
21882 (define_insn "subv2sf3"
21883 [(set (match_operand:V2SF 0 "register_operand" "=y")
21884 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21885 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21886 "TARGET_3DNOW"
21887 "pfsub\\t{%2, %0|%0, %2}"
21888 [(set_attr "type" "mmxadd")
21889 (set_attr "mode" "V2SF")])
21890
21891 (define_insn "subrv2sf3"
21892 [(set (match_operand:V2SF 0 "register_operand" "=y")
21893 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21894 (match_operand:V2SF 1 "register_operand" "0")))]
21895 "TARGET_3DNOW"
21896 "pfsubr\\t{%2, %0|%0, %2}"
21897 [(set_attr "type" "mmxadd")
21898 (set_attr "mode" "V2SF")])
21899
21900 (define_insn "gtv2sf3"
21901 [(set (match_operand:V2SI 0 "register_operand" "=y")
21902 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21903 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21904 "TARGET_3DNOW"
21905 "pfcmpgt\\t{%2, %0|%0, %2}"
21906 [(set_attr "type" "mmxcmp")
21907 (set_attr "mode" "V2SF")])
21908
21909 (define_insn "gev2sf3"
21910 [(set (match_operand:V2SI 0 "register_operand" "=y")
21911 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21912 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21913 "TARGET_3DNOW"
21914 "pfcmpge\\t{%2, %0|%0, %2}"
21915 [(set_attr "type" "mmxcmp")
21916 (set_attr "mode" "V2SF")])
21917
21918 (define_insn "eqv2sf3"
21919 [(set (match_operand:V2SI 0 "register_operand" "=y")
21920 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21921 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21922 "TARGET_3DNOW"
21923 "pfcmpeq\\t{%2, %0|%0, %2}"
21924 [(set_attr "type" "mmxcmp")
21925 (set_attr "mode" "V2SF")])
21926
21927 (define_insn "pfmaxv2sf3"
21928 [(set (match_operand:V2SF 0 "register_operand" "=y")
21929 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21930 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21931 "TARGET_3DNOW"
21932 "pfmax\\t{%2, %0|%0, %2}"
21933 [(set_attr "type" "mmxadd")
21934 (set_attr "mode" "V2SF")])
21935
21936 (define_insn "pfminv2sf3"
21937 [(set (match_operand:V2SF 0 "register_operand" "=y")
21938 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21939 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21940 "TARGET_3DNOW"
21941 "pfmin\\t{%2, %0|%0, %2}"
21942 [(set_attr "type" "mmxadd")
21943 (set_attr "mode" "V2SF")])
21944
21945 (define_insn "mulv2sf3"
21946 [(set (match_operand:V2SF 0 "register_operand" "=y")
21947 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21948 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21949 "TARGET_3DNOW"
21950 "pfmul\\t{%2, %0|%0, %2}"
21951 [(set_attr "type" "mmxmul")
21952 (set_attr "mode" "V2SF")])
21953
21954 (define_insn "femms"
21955 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21956 (clobber (reg:XF 8))
21957 (clobber (reg:XF 9))
21958 (clobber (reg:XF 10))
21959 (clobber (reg:XF 11))
21960 (clobber (reg:XF 12))
21961 (clobber (reg:XF 13))
21962 (clobber (reg:XF 14))
21963 (clobber (reg:XF 15))
21964 (clobber (reg:DI 29))
21965 (clobber (reg:DI 30))
21966 (clobber (reg:DI 31))
21967 (clobber (reg:DI 32))
21968 (clobber (reg:DI 33))
21969 (clobber (reg:DI 34))
21970 (clobber (reg:DI 35))
21971 (clobber (reg:DI 36))]
21972 "TARGET_3DNOW"
21973 "femms"
21974 [(set_attr "type" "mmx")
21975 (set_attr "memory" "none")])
21976
21977 (define_insn "pf2id"
21978 [(set (match_operand:V2SI 0 "register_operand" "=y")
21979 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21980 "TARGET_3DNOW"
21981 "pf2id\\t{%1, %0|%0, %1}"
21982 [(set_attr "type" "mmxcvt")
21983 (set_attr "mode" "V2SF")])
21984
21985 (define_insn "pf2iw"
21986 [(set (match_operand:V2SI 0 "register_operand" "=y")
21987 (sign_extend:V2SI
21988 (ss_truncate:V2HI
21989 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21990 "TARGET_3DNOW_A"
21991 "pf2iw\\t{%1, %0|%0, %1}"
21992 [(set_attr "type" "mmxcvt")
21993 (set_attr "mode" "V2SF")])
21994
21995 (define_insn "pfacc"
21996 [(set (match_operand:V2SF 0 "register_operand" "=y")
21997 (vec_concat:V2SF
21998 (plus:SF
21999 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22000 (parallel [(const_int 0)]))
22001 (vec_select:SF (match_dup 1)
22002 (parallel [(const_int 1)])))
22003 (plus:SF
22004 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22005 (parallel [(const_int 0)]))
22006 (vec_select:SF (match_dup 2)
22007 (parallel [(const_int 1)])))))]
22008 "TARGET_3DNOW"
22009 "pfacc\\t{%2, %0|%0, %2}"
22010 [(set_attr "type" "mmxadd")
22011 (set_attr "mode" "V2SF")])
22012
22013 (define_insn "pfnacc"
22014 [(set (match_operand:V2SF 0 "register_operand" "=y")
22015 (vec_concat:V2SF
22016 (minus:SF
22017 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22018 (parallel [(const_int 0)]))
22019 (vec_select:SF (match_dup 1)
22020 (parallel [(const_int 1)])))
22021 (minus:SF
22022 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22023 (parallel [(const_int 0)]))
22024 (vec_select:SF (match_dup 2)
22025 (parallel [(const_int 1)])))))]
22026 "TARGET_3DNOW_A"
22027 "pfnacc\\t{%2, %0|%0, %2}"
22028 [(set_attr "type" "mmxadd")
22029 (set_attr "mode" "V2SF")])
22030
22031 (define_insn "pfpnacc"
22032 [(set (match_operand:V2SF 0 "register_operand" "=y")
22033 (vec_concat:V2SF
22034 (minus:SF
22035 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22036 (parallel [(const_int 0)]))
22037 (vec_select:SF (match_dup 1)
22038 (parallel [(const_int 1)])))
22039 (plus:SF
22040 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22041 (parallel [(const_int 0)]))
22042 (vec_select:SF (match_dup 2)
22043 (parallel [(const_int 1)])))))]
22044 "TARGET_3DNOW_A"
22045 "pfpnacc\\t{%2, %0|%0, %2}"
22046 [(set_attr "type" "mmxadd")
22047 (set_attr "mode" "V2SF")])
22048
22049 (define_insn "pi2fw"
22050 [(set (match_operand:V2SF 0 "register_operand" "=y")
22051 (float:V2SF
22052 (vec_concat:V2SI
22053 (sign_extend:SI
22054 (truncate:HI
22055 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22056 (parallel [(const_int 0)]))))
22057 (sign_extend:SI
22058 (truncate:HI
22059 (vec_select:SI (match_dup 1)
22060 (parallel [(const_int 1)])))))))]
22061 "TARGET_3DNOW_A"
22062 "pi2fw\\t{%1, %0|%0, %1}"
22063 [(set_attr "type" "mmxcvt")
22064 (set_attr "mode" "V2SF")])
22065
22066 (define_insn "floatv2si2"
22067 [(set (match_operand:V2SF 0 "register_operand" "=y")
22068 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22069 "TARGET_3DNOW"
22070 "pi2fd\\t{%1, %0|%0, %1}"
22071 [(set_attr "type" "mmxcvt")
22072 (set_attr "mode" "V2SF")])
22073
22074 ;; This insn is identical to pavgb in operation, but the opcode is
22075 ;; different. To avoid accidentally matching pavgb, use an unspec.
22076
22077 (define_insn "pavgusb"
22078 [(set (match_operand:V8QI 0 "register_operand" "=y")
22079 (unspec:V8QI
22080 [(match_operand:V8QI 1 "register_operand" "0")
22081 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22082 UNSPEC_PAVGUSB))]
22083 "TARGET_3DNOW"
22084 "pavgusb\\t{%2, %0|%0, %2}"
22085 [(set_attr "type" "mmxshft")
22086 (set_attr "mode" "TI")])
22087
22088 ;; 3DNow reciprocal and sqrt
22089
22090 (define_insn "pfrcpv2sf2"
22091 [(set (match_operand:V2SF 0 "register_operand" "=y")
22092 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22093 UNSPEC_PFRCP))]
22094 "TARGET_3DNOW"
22095 "pfrcp\\t{%1, %0|%0, %1}"
22096 [(set_attr "type" "mmx")
22097 (set_attr "mode" "TI")])
22098
22099 (define_insn "pfrcpit1v2sf3"
22100 [(set (match_operand:V2SF 0 "register_operand" "=y")
22101 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22102 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22103 UNSPEC_PFRCPIT1))]
22104 "TARGET_3DNOW"
22105 "pfrcpit1\\t{%2, %0|%0, %2}"
22106 [(set_attr "type" "mmx")
22107 (set_attr "mode" "TI")])
22108
22109 (define_insn "pfrcpit2v2sf3"
22110 [(set (match_operand:V2SF 0 "register_operand" "=y")
22111 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22112 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22113 UNSPEC_PFRCPIT2))]
22114 "TARGET_3DNOW"
22115 "pfrcpit2\\t{%2, %0|%0, %2}"
22116 [(set_attr "type" "mmx")
22117 (set_attr "mode" "TI")])
22118
22119 (define_insn "pfrsqrtv2sf2"
22120 [(set (match_operand:V2SF 0 "register_operand" "=y")
22121 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22122 UNSPEC_PFRSQRT))]
22123 "TARGET_3DNOW"
22124 "pfrsqrt\\t{%1, %0|%0, %1}"
22125 [(set_attr "type" "mmx")
22126 (set_attr "mode" "TI")])
22127
22128 (define_insn "pfrsqit1v2sf3"
22129 [(set (match_operand:V2SF 0 "register_operand" "=y")
22130 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22131 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22132 UNSPEC_PFRSQIT1))]
22133 "TARGET_3DNOW"
22134 "pfrsqit1\\t{%2, %0|%0, %2}"
22135 [(set_attr "type" "mmx")
22136 (set_attr "mode" "TI")])
22137
22138 (define_insn "pmulhrwv4hi3"
22139 [(set (match_operand:V4HI 0 "register_operand" "=y")
22140 (truncate:V4HI
22141 (lshiftrt:V4SI
22142 (plus:V4SI
22143 (mult:V4SI
22144 (sign_extend:V4SI
22145 (match_operand:V4HI 1 "register_operand" "0"))
22146 (sign_extend:V4SI
22147 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22148 (const_vector:V4SI [(const_int 32768)
22149 (const_int 32768)
22150 (const_int 32768)
22151 (const_int 32768)]))
22152 (const_int 16))))]
22153 "TARGET_3DNOW"
22154 "pmulhrw\\t{%2, %0|%0, %2}"
22155 [(set_attr "type" "mmxmul")
22156 (set_attr "mode" "TI")])
22157
22158 (define_insn "pswapdv2si2"
22159 [(set (match_operand:V2SI 0 "register_operand" "=y")
22160 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22161 (parallel [(const_int 1) (const_int 0)])))]
22162 "TARGET_3DNOW_A"
22163 "pswapd\\t{%1, %0|%0, %1}"
22164 [(set_attr "type" "mmxcvt")
22165 (set_attr "mode" "TI")])
22166
22167 (define_insn "pswapdv2sf2"
22168 [(set (match_operand:V2SF 0 "register_operand" "=y")
22169 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22170 (parallel [(const_int 1) (const_int 0)])))]
22171 "TARGET_3DNOW_A"
22172 "pswapd\\t{%1, %0|%0, %1}"
22173 [(set_attr "type" "mmxcvt")
22174 (set_attr "mode" "TI")])
22175
22176 (define_expand "prefetch"
22177 [(prefetch (match_operand 0 "address_operand" "")
22178 (match_operand:SI 1 "const_int_operand" "")
22179 (match_operand:SI 2 "const_int_operand" ""))]
22180 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22181 {
22182 int rw = INTVAL (operands[1]);
22183 int locality = INTVAL (operands[2]);
22184
22185 if (rw != 0 && rw != 1)
22186 abort ();
22187 if (locality < 0 || locality > 3)
22188 abort ();
22189 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22190 abort ();
22191
22192 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22193 suported by SSE counterpart or the SSE prefetch is not available
22194 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22195 of locality. */
22196 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22197 operands[2] = GEN_INT (3);
22198 else
22199 operands[1] = const0_rtx;
22200 })
22201
22202 (define_insn "*prefetch_sse"
22203 [(prefetch (match_operand:SI 0 "address_operand" "p")
22204 (const_int 0)
22205 (match_operand:SI 1 "const_int_operand" ""))]
22206 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22207 {
22208 static const char * const patterns[4] = {
22209 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22210 };
22211
22212 int locality = INTVAL (operands[1]);
22213 if (locality < 0 || locality > 3)
22214 abort ();
22215
22216 return patterns[locality];
22217 }
22218 [(set_attr "type" "sse")
22219 (set_attr "memory" "none")])
22220
22221 (define_insn "*prefetch_sse_rex"
22222 [(prefetch (match_operand:DI 0 "address_operand" "p")
22223 (const_int 0)
22224 (match_operand:SI 1 "const_int_operand" ""))]
22225 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22226 {
22227 static const char * const patterns[4] = {
22228 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22229 };
22230
22231 int locality = INTVAL (operands[1]);
22232 if (locality < 0 || locality > 3)
22233 abort ();
22234
22235 return patterns[locality];
22236 }
22237 [(set_attr "type" "sse")
22238 (set_attr "memory" "none")])
22239
22240 (define_insn "*prefetch_3dnow"
22241 [(prefetch (match_operand:SI 0 "address_operand" "p")
22242 (match_operand:SI 1 "const_int_operand" "n")
22243 (const_int 3))]
22244 "TARGET_3DNOW && !TARGET_64BIT"
22245 {
22246 if (INTVAL (operands[1]) == 0)
22247 return "prefetch\t%a0";
22248 else
22249 return "prefetchw\t%a0";
22250 }
22251 [(set_attr "type" "mmx")
22252 (set_attr "memory" "none")])
22253
22254 (define_insn "*prefetch_3dnow_rex"
22255 [(prefetch (match_operand:DI 0 "address_operand" "p")
22256 (match_operand:SI 1 "const_int_operand" "n")
22257 (const_int 3))]
22258 "TARGET_3DNOW && TARGET_64BIT"
22259 {
22260 if (INTVAL (operands[1]) == 0)
22261 return "prefetch\t%a0";
22262 else
22263 return "prefetchw\t%a0";
22264 }
22265 [(set_attr "type" "mmx")
22266 (set_attr "memory" "none")])
22267
22268 ;; SSE2 support
22269
22270 (define_insn "addv2df3"
22271 [(set (match_operand:V2DF 0 "register_operand" "=x")
22272 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22273 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22274 "TARGET_SSE2"
22275 "addpd\t{%2, %0|%0, %2}"
22276 [(set_attr "type" "sseadd")
22277 (set_attr "mode" "V2DF")])
22278
22279 (define_insn "vmaddv2df3"
22280 [(set (match_operand:V2DF 0 "register_operand" "=x")
22281 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22282 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22283 (match_dup 1)
22284 (const_int 1)))]
22285 "TARGET_SSE2"
22286 "addsd\t{%2, %0|%0, %2}"
22287 [(set_attr "type" "sseadd")
22288 (set_attr "mode" "DF")])
22289
22290 (define_insn "subv2df3"
22291 [(set (match_operand:V2DF 0 "register_operand" "=x")
22292 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22293 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22294 "TARGET_SSE2"
22295 "subpd\t{%2, %0|%0, %2}"
22296 [(set_attr "type" "sseadd")
22297 (set_attr "mode" "V2DF")])
22298
22299 (define_insn "vmsubv2df3"
22300 [(set (match_operand:V2DF 0 "register_operand" "=x")
22301 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22302 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22303 (match_dup 1)
22304 (const_int 1)))]
22305 "TARGET_SSE2"
22306 "subsd\t{%2, %0|%0, %2}"
22307 [(set_attr "type" "sseadd")
22308 (set_attr "mode" "DF")])
22309
22310 (define_insn "mulv2df3"
22311 [(set (match_operand:V2DF 0 "register_operand" "=x")
22312 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22313 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22314 "TARGET_SSE2"
22315 "mulpd\t{%2, %0|%0, %2}"
22316 [(set_attr "type" "ssemul")
22317 (set_attr "mode" "V2DF")])
22318
22319 (define_insn "vmmulv2df3"
22320 [(set (match_operand:V2DF 0 "register_operand" "=x")
22321 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22322 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22323 (match_dup 1)
22324 (const_int 1)))]
22325 "TARGET_SSE2"
22326 "mulsd\t{%2, %0|%0, %2}"
22327 [(set_attr "type" "ssemul")
22328 (set_attr "mode" "DF")])
22329
22330 (define_insn "divv2df3"
22331 [(set (match_operand:V2DF 0 "register_operand" "=x")
22332 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22333 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22334 "TARGET_SSE2"
22335 "divpd\t{%2, %0|%0, %2}"
22336 [(set_attr "type" "ssediv")
22337 (set_attr "mode" "V2DF")])
22338
22339 (define_insn "vmdivv2df3"
22340 [(set (match_operand:V2DF 0 "register_operand" "=x")
22341 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22342 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22343 (match_dup 1)
22344 (const_int 1)))]
22345 "TARGET_SSE2"
22346 "divsd\t{%2, %0|%0, %2}"
22347 [(set_attr "type" "ssediv")
22348 (set_attr "mode" "DF")])
22349
22350 ;; SSE min/max
22351
22352 (define_insn "smaxv2df3"
22353 [(set (match_operand:V2DF 0 "register_operand" "=x")
22354 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22355 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22356 "TARGET_SSE2"
22357 "maxpd\t{%2, %0|%0, %2}"
22358 [(set_attr "type" "sseadd")
22359 (set_attr "mode" "V2DF")])
22360
22361 (define_insn "vmsmaxv2df3"
22362 [(set (match_operand:V2DF 0 "register_operand" "=x")
22363 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22364 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22365 (match_dup 1)
22366 (const_int 1)))]
22367 "TARGET_SSE2"
22368 "maxsd\t{%2, %0|%0, %2}"
22369 [(set_attr "type" "sseadd")
22370 (set_attr "mode" "DF")])
22371
22372 (define_insn "sminv2df3"
22373 [(set (match_operand:V2DF 0 "register_operand" "=x")
22374 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22375 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22376 "TARGET_SSE2"
22377 "minpd\t{%2, %0|%0, %2}"
22378 [(set_attr "type" "sseadd")
22379 (set_attr "mode" "V2DF")])
22380
22381 (define_insn "vmsminv2df3"
22382 [(set (match_operand:V2DF 0 "register_operand" "=x")
22383 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22384 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22385 (match_dup 1)
22386 (const_int 1)))]
22387 "TARGET_SSE2"
22388 "minsd\t{%2, %0|%0, %2}"
22389 [(set_attr "type" "sseadd")
22390 (set_attr "mode" "DF")])
22391 ;; SSE2 square root. There doesn't appear to be an extension for the
22392 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22393
22394 (define_insn "sqrtv2df2"
22395 [(set (match_operand:V2DF 0 "register_operand" "=x")
22396 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22397 "TARGET_SSE2"
22398 "sqrtpd\t{%1, %0|%0, %1}"
22399 [(set_attr "type" "sse")
22400 (set_attr "mode" "V2DF")])
22401
22402 (define_insn "vmsqrtv2df2"
22403 [(set (match_operand:V2DF 0 "register_operand" "=x")
22404 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22405 (match_operand:V2DF 2 "register_operand" "0")
22406 (const_int 1)))]
22407 "TARGET_SSE2"
22408 "sqrtsd\t{%1, %0|%0, %1}"
22409 [(set_attr "type" "sse")
22410 (set_attr "mode" "SF")])
22411
22412 ;; SSE mask-generating compares
22413
22414 (define_insn "maskcmpv2df3"
22415 [(set (match_operand:V2DI 0 "register_operand" "=x")
22416 (match_operator:V2DI 3 "sse_comparison_operator"
22417 [(match_operand:V2DF 1 "register_operand" "0")
22418 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22419 "TARGET_SSE2"
22420 "cmp%D3pd\t{%2, %0|%0, %2}"
22421 [(set_attr "type" "ssecmp")
22422 (set_attr "mode" "V2DF")])
22423
22424 (define_insn "maskncmpv2df3"
22425 [(set (match_operand:V2DI 0 "register_operand" "=x")
22426 (not:V2DI
22427 (match_operator:V2DI 3 "sse_comparison_operator"
22428 [(match_operand:V2DF 1 "register_operand" "0")
22429 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22430 "TARGET_SSE2"
22431 {
22432 if (GET_CODE (operands[3]) == UNORDERED)
22433 return "cmpordps\t{%2, %0|%0, %2}";
22434 else
22435 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22436 }
22437 [(set_attr "type" "ssecmp")
22438 (set_attr "mode" "V2DF")])
22439
22440 (define_insn "vmmaskcmpv2df3"
22441 [(set (match_operand:V2DI 0 "register_operand" "=x")
22442 (vec_merge:V2DI
22443 (match_operator:V2DI 3 "sse_comparison_operator"
22444 [(match_operand:V2DF 1 "register_operand" "0")
22445 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22446 (subreg:V2DI (match_dup 1) 0)
22447 (const_int 1)))]
22448 "TARGET_SSE2"
22449 "cmp%D3sd\t{%2, %0|%0, %2}"
22450 [(set_attr "type" "ssecmp")
22451 (set_attr "mode" "DF")])
22452
22453 (define_insn "vmmaskncmpv2df3"
22454 [(set (match_operand:V2DI 0 "register_operand" "=x")
22455 (vec_merge:V2DI
22456 (not:V2DI
22457 (match_operator:V2DI 3 "sse_comparison_operator"
22458 [(match_operand:V2DF 1 "register_operand" "0")
22459 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22460 (subreg:V2DI (match_dup 1) 0)
22461 (const_int 1)))]
22462 "TARGET_SSE2"
22463 {
22464 if (GET_CODE (operands[3]) == UNORDERED)
22465 return "cmpordsd\t{%2, %0|%0, %2}";
22466 else
22467 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22468 }
22469 [(set_attr "type" "ssecmp")
22470 (set_attr "mode" "DF")])
22471
22472 (define_insn "sse2_comi"
22473 [(set (reg:CCFP 17)
22474 (compare:CCFP (vec_select:DF
22475 (match_operand:V2DF 0 "register_operand" "x")
22476 (parallel [(const_int 0)]))
22477 (vec_select:DF
22478 (match_operand:V2DF 1 "register_operand" "x")
22479 (parallel [(const_int 0)]))))]
22480 "TARGET_SSE2"
22481 "comisd\t{%1, %0|%0, %1}"
22482 [(set_attr "type" "ssecomi")
22483 (set_attr "mode" "DF")])
22484
22485 (define_insn "sse2_ucomi"
22486 [(set (reg:CCFPU 17)
22487 (compare:CCFPU (vec_select:DF
22488 (match_operand:V2DF 0 "register_operand" "x")
22489 (parallel [(const_int 0)]))
22490 (vec_select:DF
22491 (match_operand:V2DF 1 "register_operand" "x")
22492 (parallel [(const_int 0)]))))]
22493 "TARGET_SSE2"
22494 "ucomisd\t{%1, %0|%0, %1}"
22495 [(set_attr "type" "ssecomi")
22496 (set_attr "mode" "DF")])
22497
22498 ;; SSE Strange Moves.
22499
22500 (define_insn "sse2_movmskpd"
22501 [(set (match_operand:SI 0 "register_operand" "=r")
22502 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22503 UNSPEC_MOVMSK))]
22504 "TARGET_SSE2"
22505 "movmskpd\t{%1, %0|%0, %1}"
22506 [(set_attr "type" "ssecvt")
22507 (set_attr "mode" "V2DF")])
22508
22509 (define_insn "sse2_pmovmskb"
22510 [(set (match_operand:SI 0 "register_operand" "=r")
22511 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22512 UNSPEC_MOVMSK))]
22513 "TARGET_SSE2"
22514 "pmovmskb\t{%1, %0|%0, %1}"
22515 [(set_attr "type" "ssecvt")
22516 (set_attr "mode" "V2DF")])
22517
22518 (define_insn "sse2_maskmovdqu"
22519 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22520 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22521 (match_operand:V16QI 2 "register_operand" "x")]
22522 UNSPEC_MASKMOV))]
22523 "TARGET_SSE2"
22524 ;; @@@ check ordering of operands in intel/nonintel syntax
22525 "maskmovdqu\t{%2, %1|%1, %2}"
22526 [(set_attr "type" "ssecvt")
22527 (set_attr "mode" "TI")])
22528
22529 (define_insn "sse2_maskmovdqu_rex64"
22530 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22531 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22532 (match_operand:V16QI 2 "register_operand" "x")]
22533 UNSPEC_MASKMOV))]
22534 "TARGET_SSE2"
22535 ;; @@@ check ordering of operands in intel/nonintel syntax
22536 "maskmovdqu\t{%2, %1|%1, %2}"
22537 [(set_attr "type" "ssecvt")
22538 (set_attr "mode" "TI")])
22539
22540 (define_insn "sse2_movntv2df"
22541 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22542 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22543 UNSPEC_MOVNT))]
22544 "TARGET_SSE2"
22545 "movntpd\t{%1, %0|%0, %1}"
22546 [(set_attr "type" "ssecvt")
22547 (set_attr "mode" "V2DF")])
22548
22549 (define_insn "sse2_movntv2di"
22550 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22551 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22552 UNSPEC_MOVNT))]
22553 "TARGET_SSE2"
22554 "movntdq\t{%1, %0|%0, %1}"
22555 [(set_attr "type" "ssecvt")
22556 (set_attr "mode" "TI")])
22557
22558 (define_insn "sse2_movntsi"
22559 [(set (match_operand:SI 0 "memory_operand" "=m")
22560 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22561 UNSPEC_MOVNT))]
22562 "TARGET_SSE2"
22563 "movnti\t{%1, %0|%0, %1}"
22564 [(set_attr "type" "ssecvt")
22565 (set_attr "mode" "V2DF")])
22566
22567 ;; SSE <-> integer/MMX conversions
22568
22569 ;; Conversions between SI and SF
22570
22571 (define_insn "cvtdq2ps"
22572 [(set (match_operand:V4SF 0 "register_operand" "=x")
22573 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22574 "TARGET_SSE2"
22575 "cvtdq2ps\t{%1, %0|%0, %1}"
22576 [(set_attr "type" "ssecvt")
22577 (set_attr "mode" "V2DF")])
22578
22579 (define_insn "cvtps2dq"
22580 [(set (match_operand:V4SI 0 "register_operand" "=x")
22581 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22582 "TARGET_SSE2"
22583 "cvtps2dq\t{%1, %0|%0, %1}"
22584 [(set_attr "type" "ssecvt")
22585 (set_attr "mode" "TI")])
22586
22587 (define_insn "cvttps2dq"
22588 [(set (match_operand:V4SI 0 "register_operand" "=x")
22589 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22590 UNSPEC_FIX))]
22591 "TARGET_SSE2"
22592 "cvttps2dq\t{%1, %0|%0, %1}"
22593 [(set_attr "type" "ssecvt")
22594 (set_attr "mode" "TI")])
22595
22596 ;; Conversions between SI and DF
22597
22598 (define_insn "cvtdq2pd"
22599 [(set (match_operand:V2DF 0 "register_operand" "=x")
22600 (float:V2DF (vec_select:V2SI
22601 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22602 (parallel
22603 [(const_int 0)
22604 (const_int 1)]))))]
22605 "TARGET_SSE2"
22606 "cvtdq2pd\t{%1, %0|%0, %1}"
22607 [(set_attr "type" "ssecvt")
22608 (set_attr "mode" "V2DF")])
22609
22610 (define_insn "cvtpd2dq"
22611 [(set (match_operand:V4SI 0 "register_operand" "=x")
22612 (vec_concat:V4SI
22613 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22614 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22615 "TARGET_SSE2"
22616 "cvtpd2dq\t{%1, %0|%0, %1}"
22617 [(set_attr "type" "ssecvt")
22618 (set_attr "mode" "TI")])
22619
22620 (define_insn "cvttpd2dq"
22621 [(set (match_operand:V4SI 0 "register_operand" "=x")
22622 (vec_concat:V4SI
22623 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22624 UNSPEC_FIX)
22625 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22626 "TARGET_SSE2"
22627 "cvttpd2dq\t{%1, %0|%0, %1}"
22628 [(set_attr "type" "ssecvt")
22629 (set_attr "mode" "TI")])
22630
22631 (define_insn "cvtpd2pi"
22632 [(set (match_operand:V2SI 0 "register_operand" "=y")
22633 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22634 "TARGET_SSE2"
22635 "cvtpd2pi\t{%1, %0|%0, %1}"
22636 [(set_attr "type" "ssecvt")
22637 (set_attr "mode" "TI")])
22638
22639 (define_insn "cvttpd2pi"
22640 [(set (match_operand:V2SI 0 "register_operand" "=y")
22641 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22642 UNSPEC_FIX))]
22643 "TARGET_SSE2"
22644 "cvttpd2pi\t{%1, %0|%0, %1}"
22645 [(set_attr "type" "ssecvt")
22646 (set_attr "mode" "TI")])
22647
22648 (define_insn "cvtpi2pd"
22649 [(set (match_operand:V2DF 0 "register_operand" "=x")
22650 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22651 "TARGET_SSE2"
22652 "cvtpi2pd\t{%1, %0|%0, %1}"
22653 [(set_attr "type" "ssecvt")
22654 (set_attr "mode" "TI")])
22655
22656 ;; Conversions between SI and DF
22657
22658 (define_insn "cvtsd2si"
22659 [(set (match_operand:SI 0 "register_operand" "=r,r")
22660 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22661 (parallel [(const_int 0)]))))]
22662 "TARGET_SSE2"
22663 "cvtsd2si\t{%1, %0|%0, %1}"
22664 [(set_attr "type" "sseicvt")
22665 (set_attr "athlon_decode" "double,vector")
22666 (set_attr "mode" "SI")])
22667
22668 (define_insn "cvtsd2siq"
22669 [(set (match_operand:DI 0 "register_operand" "=r,r")
22670 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22671 (parallel [(const_int 0)]))))]
22672 "TARGET_SSE2 && TARGET_64BIT"
22673 "cvtsd2siq\t{%1, %0|%0, %1}"
22674 [(set_attr "type" "sseicvt")
22675 (set_attr "athlon_decode" "double,vector")
22676 (set_attr "mode" "DI")])
22677
22678 (define_insn "cvttsd2si"
22679 [(set (match_operand:SI 0 "register_operand" "=r,r")
22680 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22681 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22682 "TARGET_SSE2"
22683 "cvttsd2si\t{%1, %0|%0, %1}"
22684 [(set_attr "type" "sseicvt")
22685 (set_attr "mode" "SI")
22686 (set_attr "athlon_decode" "double,vector")])
22687
22688 (define_insn "cvttsd2siq"
22689 [(set (match_operand:DI 0 "register_operand" "=r,r")
22690 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22691 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22692 "TARGET_SSE2 && TARGET_64BIT"
22693 "cvttsd2siq\t{%1, %0|%0, %1}"
22694 [(set_attr "type" "sseicvt")
22695 (set_attr "mode" "DI")
22696 (set_attr "athlon_decode" "double,vector")])
22697
22698 (define_insn "cvtsi2sd"
22699 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22700 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22701 (vec_duplicate:V2DF
22702 (float:DF
22703 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22704 (const_int 2)))]
22705 "TARGET_SSE2"
22706 "cvtsi2sd\t{%2, %0|%0, %2}"
22707 [(set_attr "type" "sseicvt")
22708 (set_attr "mode" "DF")
22709 (set_attr "athlon_decode" "double,direct")])
22710
22711 (define_insn "cvtsi2sdq"
22712 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22713 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22714 (vec_duplicate:V2DF
22715 (float:DF
22716 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22717 (const_int 2)))]
22718 "TARGET_SSE2 && TARGET_64BIT"
22719 "cvtsi2sdq\t{%2, %0|%0, %2}"
22720 [(set_attr "type" "sseicvt")
22721 (set_attr "mode" "DF")
22722 (set_attr "athlon_decode" "double,direct")])
22723
22724 ;; Conversions between SF and DF
22725
22726 (define_insn "cvtsd2ss"
22727 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22728 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22729 (vec_duplicate:V4SF
22730 (float_truncate:V2SF
22731 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22732 (const_int 14)))]
22733 "TARGET_SSE2"
22734 "cvtsd2ss\t{%2, %0|%0, %2}"
22735 [(set_attr "type" "ssecvt")
22736 (set_attr "athlon_decode" "vector,double")
22737 (set_attr "mode" "SF")])
22738
22739 (define_insn "cvtss2sd"
22740 [(set (match_operand:V2DF 0 "register_operand" "=x")
22741 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22742 (float_extend:V2DF
22743 (vec_select:V2SF
22744 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22745 (parallel [(const_int 0)
22746 (const_int 1)])))
22747 (const_int 2)))]
22748 "TARGET_SSE2"
22749 "cvtss2sd\t{%2, %0|%0, %2}"
22750 [(set_attr "type" "ssecvt")
22751 (set_attr "mode" "DF")])
22752
22753 (define_insn "cvtpd2ps"
22754 [(set (match_operand:V4SF 0 "register_operand" "=x")
22755 (subreg:V4SF
22756 (vec_concat:V4SI
22757 (subreg:V2SI (float_truncate:V2SF
22758 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22759 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22760 "TARGET_SSE2"
22761 "cvtpd2ps\t{%1, %0|%0, %1}"
22762 [(set_attr "type" "ssecvt")
22763 (set_attr "mode" "V4SF")])
22764
22765 (define_insn "cvtps2pd"
22766 [(set (match_operand:V2DF 0 "register_operand" "=x")
22767 (float_extend:V2DF
22768 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22769 (parallel [(const_int 0)
22770 (const_int 1)]))))]
22771 "TARGET_SSE2"
22772 "cvtps2pd\t{%1, %0|%0, %1}"
22773 [(set_attr "type" "ssecvt")
22774 (set_attr "mode" "V2DF")])
22775
22776 ;; SSE2 variants of MMX insns
22777
22778 ;; MMX arithmetic
22779
22780 (define_insn "addv16qi3"
22781 [(set (match_operand:V16QI 0 "register_operand" "=x")
22782 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22783 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22784 "TARGET_SSE2"
22785 "paddb\t{%2, %0|%0, %2}"
22786 [(set_attr "type" "sseiadd")
22787 (set_attr "mode" "TI")])
22788
22789 (define_insn "addv8hi3"
22790 [(set (match_operand:V8HI 0 "register_operand" "=x")
22791 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22792 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22793 "TARGET_SSE2"
22794 "paddw\t{%2, %0|%0, %2}"
22795 [(set_attr "type" "sseiadd")
22796 (set_attr "mode" "TI")])
22797
22798 (define_insn "addv4si3"
22799 [(set (match_operand:V4SI 0 "register_operand" "=x")
22800 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22801 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22802 "TARGET_SSE2"
22803 "paddd\t{%2, %0|%0, %2}"
22804 [(set_attr "type" "sseiadd")
22805 (set_attr "mode" "TI")])
22806
22807 (define_insn "addv2di3"
22808 [(set (match_operand:V2DI 0 "register_operand" "=x")
22809 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22810 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22811 "TARGET_SSE2"
22812 "paddq\t{%2, %0|%0, %2}"
22813 [(set_attr "type" "sseiadd")
22814 (set_attr "mode" "TI")])
22815
22816 (define_insn "ssaddv16qi3"
22817 [(set (match_operand:V16QI 0 "register_operand" "=x")
22818 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22819 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22820 "TARGET_SSE2"
22821 "paddsb\t{%2, %0|%0, %2}"
22822 [(set_attr "type" "sseiadd")
22823 (set_attr "mode" "TI")])
22824
22825 (define_insn "ssaddv8hi3"
22826 [(set (match_operand:V8HI 0 "register_operand" "=x")
22827 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22828 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22829 "TARGET_SSE2"
22830 "paddsw\t{%2, %0|%0, %2}"
22831 [(set_attr "type" "sseiadd")
22832 (set_attr "mode" "TI")])
22833
22834 (define_insn "usaddv16qi3"
22835 [(set (match_operand:V16QI 0 "register_operand" "=x")
22836 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22837 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22838 "TARGET_SSE2"
22839 "paddusb\t{%2, %0|%0, %2}"
22840 [(set_attr "type" "sseiadd")
22841 (set_attr "mode" "TI")])
22842
22843 (define_insn "usaddv8hi3"
22844 [(set (match_operand:V8HI 0 "register_operand" "=x")
22845 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22846 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22847 "TARGET_SSE2"
22848 "paddusw\t{%2, %0|%0, %2}"
22849 [(set_attr "type" "sseiadd")
22850 (set_attr "mode" "TI")])
22851
22852 (define_insn "subv16qi3"
22853 [(set (match_operand:V16QI 0 "register_operand" "=x")
22854 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22855 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22856 "TARGET_SSE2"
22857 "psubb\t{%2, %0|%0, %2}"
22858 [(set_attr "type" "sseiadd")
22859 (set_attr "mode" "TI")])
22860
22861 (define_insn "subv8hi3"
22862 [(set (match_operand:V8HI 0 "register_operand" "=x")
22863 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22864 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22865 "TARGET_SSE2"
22866 "psubw\t{%2, %0|%0, %2}"
22867 [(set_attr "type" "sseiadd")
22868 (set_attr "mode" "TI")])
22869
22870 (define_insn "subv4si3"
22871 [(set (match_operand:V4SI 0 "register_operand" "=x")
22872 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22873 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22874 "TARGET_SSE2"
22875 "psubd\t{%2, %0|%0, %2}"
22876 [(set_attr "type" "sseiadd")
22877 (set_attr "mode" "TI")])
22878
22879 (define_insn "subv2di3"
22880 [(set (match_operand:V2DI 0 "register_operand" "=x")
22881 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22882 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22883 "TARGET_SSE2"
22884 "psubq\t{%2, %0|%0, %2}"
22885 [(set_attr "type" "sseiadd")
22886 (set_attr "mode" "TI")])
22887
22888 (define_insn "sssubv16qi3"
22889 [(set (match_operand:V16QI 0 "register_operand" "=x")
22890 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22891 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22892 "TARGET_SSE2"
22893 "psubsb\t{%2, %0|%0, %2}"
22894 [(set_attr "type" "sseiadd")
22895 (set_attr "mode" "TI")])
22896
22897 (define_insn "sssubv8hi3"
22898 [(set (match_operand:V8HI 0 "register_operand" "=x")
22899 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22900 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22901 "TARGET_SSE2"
22902 "psubsw\t{%2, %0|%0, %2}"
22903 [(set_attr "type" "sseiadd")
22904 (set_attr "mode" "TI")])
22905
22906 (define_insn "ussubv16qi3"
22907 [(set (match_operand:V16QI 0 "register_operand" "=x")
22908 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22909 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22910 "TARGET_SSE2"
22911 "psubusb\t{%2, %0|%0, %2}"
22912 [(set_attr "type" "sseiadd")
22913 (set_attr "mode" "TI")])
22914
22915 (define_insn "ussubv8hi3"
22916 [(set (match_operand:V8HI 0 "register_operand" "=x")
22917 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22918 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22919 "TARGET_SSE2"
22920 "psubusw\t{%2, %0|%0, %2}"
22921 [(set_attr "type" "sseiadd")
22922 (set_attr "mode" "TI")])
22923
22924 (define_insn "mulv8hi3"
22925 [(set (match_operand:V8HI 0 "register_operand" "=x")
22926 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22927 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22928 "TARGET_SSE2"
22929 "pmullw\t{%2, %0|%0, %2}"
22930 [(set_attr "type" "sseimul")
22931 (set_attr "mode" "TI")])
22932
22933 (define_insn "smulv8hi3_highpart"
22934 [(set (match_operand:V8HI 0 "register_operand" "=x")
22935 (truncate:V8HI
22936 (lshiftrt:V8SI
22937 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22938 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22939 (const_int 16))))]
22940 "TARGET_SSE2"
22941 "pmulhw\t{%2, %0|%0, %2}"
22942 [(set_attr "type" "sseimul")
22943 (set_attr "mode" "TI")])
22944
22945 (define_insn "umulv8hi3_highpart"
22946 [(set (match_operand:V8HI 0 "register_operand" "=x")
22947 (truncate:V8HI
22948 (lshiftrt:V8SI
22949 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22950 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22951 (const_int 16))))]
22952 "TARGET_SSE2"
22953 "pmulhuw\t{%2, %0|%0, %2}"
22954 [(set_attr "type" "sseimul")
22955 (set_attr "mode" "TI")])
22956
22957 (define_insn "sse2_umulsidi3"
22958 [(set (match_operand:DI 0 "register_operand" "=y")
22959 (mult:DI (zero_extend:DI (vec_select:SI
22960 (match_operand:V2SI 1 "register_operand" "0")
22961 (parallel [(const_int 0)])))
22962 (zero_extend:DI (vec_select:SI
22963 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22964 (parallel [(const_int 0)])))))]
22965 "TARGET_SSE2"
22966 "pmuludq\t{%2, %0|%0, %2}"
22967 [(set_attr "type" "sseimul")
22968 (set_attr "mode" "TI")])
22969
22970 (define_insn "sse2_umulv2siv2di3"
22971 [(set (match_operand:V2DI 0 "register_operand" "=x")
22972 (mult:V2DI (zero_extend:V2DI
22973 (vec_select:V2SI
22974 (match_operand:V4SI 1 "register_operand" "0")
22975 (parallel [(const_int 0) (const_int 2)])))
22976 (zero_extend:V2DI
22977 (vec_select:V2SI
22978 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22979 (parallel [(const_int 0) (const_int 2)])))))]
22980 "TARGET_SSE2"
22981 "pmuludq\t{%2, %0|%0, %2}"
22982 [(set_attr "type" "sseimul")
22983 (set_attr "mode" "TI")])
22984
22985 (define_insn "sse2_pmaddwd"
22986 [(set (match_operand:V4SI 0 "register_operand" "=x")
22987 (plus:V4SI
22988 (mult:V4SI
22989 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22990 (parallel [(const_int 0)
22991 (const_int 2)
22992 (const_int 4)
22993 (const_int 6)])))
22994 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22995 (parallel [(const_int 0)
22996 (const_int 2)
22997 (const_int 4)
22998 (const_int 6)]))))
22999 (mult:V4SI
23000 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23001 (parallel [(const_int 1)
23002 (const_int 3)
23003 (const_int 5)
23004 (const_int 7)])))
23005 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23006 (parallel [(const_int 1)
23007 (const_int 3)
23008 (const_int 5)
23009 (const_int 7)]))))))]
23010 "TARGET_SSE2"
23011 "pmaddwd\t{%2, %0|%0, %2}"
23012 [(set_attr "type" "sseiadd")
23013 (set_attr "mode" "TI")])
23014
23015 ;; Same as pxor, but don't show input operands so that we don't think
23016 ;; they are live.
23017 (define_insn "sse2_clrti"
23018 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23019 "TARGET_SSE2"
23020 {
23021 if (get_attr_mode (insn) == MODE_TI)
23022 return "pxor\t%0, %0";
23023 else
23024 return "xorps\t%0, %0";
23025 }
23026 [(set_attr "type" "ssemov")
23027 (set_attr "memory" "none")
23028 (set (attr "mode")
23029 (if_then_else
23030 (ne (symbol_ref "optimize_size")
23031 (const_int 0))
23032 (const_string "V4SF")
23033 (const_string "TI")))])
23034
23035 ;; MMX unsigned averages/sum of absolute differences
23036
23037 (define_insn "sse2_uavgv16qi3"
23038 [(set (match_operand:V16QI 0 "register_operand" "=x")
23039 (ashiftrt:V16QI
23040 (plus:V16QI (plus:V16QI
23041 (match_operand:V16QI 1 "register_operand" "0")
23042 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23043 (const_vector:V16QI [(const_int 1) (const_int 1)
23044 (const_int 1) (const_int 1)
23045 (const_int 1) (const_int 1)
23046 (const_int 1) (const_int 1)
23047 (const_int 1) (const_int 1)
23048 (const_int 1) (const_int 1)
23049 (const_int 1) (const_int 1)
23050 (const_int 1) (const_int 1)]))
23051 (const_int 1)))]
23052 "TARGET_SSE2"
23053 "pavgb\t{%2, %0|%0, %2}"
23054 [(set_attr "type" "sseiadd")
23055 (set_attr "mode" "TI")])
23056
23057 (define_insn "sse2_uavgv8hi3"
23058 [(set (match_operand:V8HI 0 "register_operand" "=x")
23059 (ashiftrt:V8HI
23060 (plus:V8HI (plus:V8HI
23061 (match_operand:V8HI 1 "register_operand" "0")
23062 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23063 (const_vector:V8HI [(const_int 1) (const_int 1)
23064 (const_int 1) (const_int 1)
23065 (const_int 1) (const_int 1)
23066 (const_int 1) (const_int 1)]))
23067 (const_int 1)))]
23068 "TARGET_SSE2"
23069 "pavgw\t{%2, %0|%0, %2}"
23070 [(set_attr "type" "sseiadd")
23071 (set_attr "mode" "TI")])
23072
23073 ;; @@@ this isn't the right representation.
23074 (define_insn "sse2_psadbw"
23075 [(set (match_operand:V2DI 0 "register_operand" "=x")
23076 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23077 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23078 UNSPEC_PSADBW))]
23079 "TARGET_SSE2"
23080 "psadbw\t{%2, %0|%0, %2}"
23081 [(set_attr "type" "sseiadd")
23082 (set_attr "mode" "TI")])
23083
23084
23085 ;; MMX insert/extract/shuffle
23086
23087 (define_insn "sse2_pinsrw"
23088 [(set (match_operand:V8HI 0 "register_operand" "=x")
23089 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23090 (vec_duplicate:V8HI
23091 (truncate:HI
23092 (match_operand:SI 2 "nonimmediate_operand" "rm")))
23093 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23094 "TARGET_SSE2"
23095 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23096 [(set_attr "type" "ssecvt")
23097 (set_attr "mode" "TI")])
23098
23099 (define_insn "sse2_pextrw"
23100 [(set (match_operand:SI 0 "register_operand" "=r")
23101 (zero_extend:SI
23102 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23103 (parallel
23104 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23105 "TARGET_SSE2"
23106 "pextrw\t{%2, %1, %0|%0, %1, %2}"
23107 [(set_attr "type" "ssecvt")
23108 (set_attr "mode" "TI")])
23109
23110 (define_insn "sse2_pshufd"
23111 [(set (match_operand:V4SI 0 "register_operand" "=x")
23112 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23113 (match_operand:SI 2 "immediate_operand" "i")]
23114 UNSPEC_SHUFFLE))]
23115 "TARGET_SSE2"
23116 "pshufd\t{%2, %1, %0|%0, %1, %2}"
23117 [(set_attr "type" "ssecvt")
23118 (set_attr "mode" "TI")])
23119
23120 (define_insn "sse2_pshuflw"
23121 [(set (match_operand:V8HI 0 "register_operand" "=x")
23122 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23123 (match_operand:SI 2 "immediate_operand" "i")]
23124 UNSPEC_PSHUFLW))]
23125 "TARGET_SSE2"
23126 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23127 [(set_attr "type" "ssecvt")
23128 (set_attr "mode" "TI")])
23129
23130 (define_insn "sse2_pshufhw"
23131 [(set (match_operand:V8HI 0 "register_operand" "=x")
23132 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23133 (match_operand:SI 2 "immediate_operand" "i")]
23134 UNSPEC_PSHUFHW))]
23135 "TARGET_SSE2"
23136 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23137 [(set_attr "type" "ssecvt")
23138 (set_attr "mode" "TI")])
23139
23140 ;; MMX mask-generating comparisons
23141
23142 (define_insn "eqv16qi3"
23143 [(set (match_operand:V16QI 0 "register_operand" "=x")
23144 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23145 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23146 "TARGET_SSE2"
23147 "pcmpeqb\t{%2, %0|%0, %2}"
23148 [(set_attr "type" "ssecmp")
23149 (set_attr "mode" "TI")])
23150
23151 (define_insn "eqv8hi3"
23152 [(set (match_operand:V8HI 0 "register_operand" "=x")
23153 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23154 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23155 "TARGET_SSE2"
23156 "pcmpeqw\t{%2, %0|%0, %2}"
23157 [(set_attr "type" "ssecmp")
23158 (set_attr "mode" "TI")])
23159
23160 (define_insn "eqv4si3"
23161 [(set (match_operand:V4SI 0 "register_operand" "=x")
23162 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23163 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23164 "TARGET_SSE2"
23165 "pcmpeqd\t{%2, %0|%0, %2}"
23166 [(set_attr "type" "ssecmp")
23167 (set_attr "mode" "TI")])
23168
23169 (define_insn "gtv16qi3"
23170 [(set (match_operand:V16QI 0 "register_operand" "=x")
23171 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23172 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23173 "TARGET_SSE2"
23174 "pcmpgtb\t{%2, %0|%0, %2}"
23175 [(set_attr "type" "ssecmp")
23176 (set_attr "mode" "TI")])
23177
23178 (define_insn "gtv8hi3"
23179 [(set (match_operand:V8HI 0 "register_operand" "=x")
23180 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23181 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23182 "TARGET_SSE2"
23183 "pcmpgtw\t{%2, %0|%0, %2}"
23184 [(set_attr "type" "ssecmp")
23185 (set_attr "mode" "TI")])
23186
23187 (define_insn "gtv4si3"
23188 [(set (match_operand:V4SI 0 "register_operand" "=x")
23189 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23190 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23191 "TARGET_SSE2"
23192 "pcmpgtd\t{%2, %0|%0, %2}"
23193 [(set_attr "type" "ssecmp")
23194 (set_attr "mode" "TI")])
23195
23196
23197 ;; MMX max/min insns
23198
23199 (define_insn "umaxv16qi3"
23200 [(set (match_operand:V16QI 0 "register_operand" "=x")
23201 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23202 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23203 "TARGET_SSE2"
23204 "pmaxub\t{%2, %0|%0, %2}"
23205 [(set_attr "type" "sseiadd")
23206 (set_attr "mode" "TI")])
23207
23208 (define_insn "smaxv8hi3"
23209 [(set (match_operand:V8HI 0 "register_operand" "=x")
23210 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23211 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23212 "TARGET_SSE2"
23213 "pmaxsw\t{%2, %0|%0, %2}"
23214 [(set_attr "type" "sseiadd")
23215 (set_attr "mode" "TI")])
23216
23217 (define_insn "uminv16qi3"
23218 [(set (match_operand:V16QI 0 "register_operand" "=x")
23219 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23220 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23221 "TARGET_SSE2"
23222 "pminub\t{%2, %0|%0, %2}"
23223 [(set_attr "type" "sseiadd")
23224 (set_attr "mode" "TI")])
23225
23226 (define_insn "sminv8hi3"
23227 [(set (match_operand:V8HI 0 "register_operand" "=x")
23228 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23229 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23230 "TARGET_SSE2"
23231 "pminsw\t{%2, %0|%0, %2}"
23232 [(set_attr "type" "sseiadd")
23233 (set_attr "mode" "TI")])
23234
23235
23236 ;; MMX shifts
23237
23238 (define_insn "ashrv8hi3"
23239 [(set (match_operand:V8HI 0 "register_operand" "=x")
23240 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23241 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23242 "TARGET_SSE2"
23243 "psraw\t{%2, %0|%0, %2}"
23244 [(set_attr "type" "sseishft")
23245 (set_attr "mode" "TI")])
23246
23247 (define_insn "ashrv4si3"
23248 [(set (match_operand:V4SI 0 "register_operand" "=x")
23249 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23250 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23251 "TARGET_SSE2"
23252 "psrad\t{%2, %0|%0, %2}"
23253 [(set_attr "type" "sseishft")
23254 (set_attr "mode" "TI")])
23255
23256 (define_insn "lshrv8hi3"
23257 [(set (match_operand:V8HI 0 "register_operand" "=x")
23258 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23259 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23260 "TARGET_SSE2"
23261 "psrlw\t{%2, %0|%0, %2}"
23262 [(set_attr "type" "sseishft")
23263 (set_attr "mode" "TI")])
23264
23265 (define_insn "lshrv4si3"
23266 [(set (match_operand:V4SI 0 "register_operand" "=x")
23267 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23268 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23269 "TARGET_SSE2"
23270 "psrld\t{%2, %0|%0, %2}"
23271 [(set_attr "type" "sseishft")
23272 (set_attr "mode" "TI")])
23273
23274 (define_insn "lshrv2di3"
23275 [(set (match_operand:V2DI 0 "register_operand" "=x")
23276 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23277 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23278 "TARGET_SSE2"
23279 "psrlq\t{%2, %0|%0, %2}"
23280 [(set_attr "type" "sseishft")
23281 (set_attr "mode" "TI")])
23282
23283 (define_insn "ashlv8hi3"
23284 [(set (match_operand:V8HI 0 "register_operand" "=x")
23285 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23286 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23287 "TARGET_SSE2"
23288 "psllw\t{%2, %0|%0, %2}"
23289 [(set_attr "type" "sseishft")
23290 (set_attr "mode" "TI")])
23291
23292 (define_insn "ashlv4si3"
23293 [(set (match_operand:V4SI 0 "register_operand" "=x")
23294 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23295 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23296 "TARGET_SSE2"
23297 "pslld\t{%2, %0|%0, %2}"
23298 [(set_attr "type" "sseishft")
23299 (set_attr "mode" "TI")])
23300
23301 (define_insn "ashlv2di3"
23302 [(set (match_operand:V2DI 0 "register_operand" "=x")
23303 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23304 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23305 "TARGET_SSE2"
23306 "psllq\t{%2, %0|%0, %2}"
23307 [(set_attr "type" "sseishft")
23308 (set_attr "mode" "TI")])
23309
23310 (define_insn "ashrv8hi3_ti"
23311 [(set (match_operand:V8HI 0 "register_operand" "=x")
23312 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23313 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23314 "TARGET_SSE2"
23315 "psraw\t{%2, %0|%0, %2}"
23316 [(set_attr "type" "sseishft")
23317 (set_attr "mode" "TI")])
23318
23319 (define_insn "ashrv4si3_ti"
23320 [(set (match_operand:V4SI 0 "register_operand" "=x")
23321 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23322 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23323 "TARGET_SSE2"
23324 "psrad\t{%2, %0|%0, %2}"
23325 [(set_attr "type" "sseishft")
23326 (set_attr "mode" "TI")])
23327
23328 (define_insn "lshrv8hi3_ti"
23329 [(set (match_operand:V8HI 0 "register_operand" "=x")
23330 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23331 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23332 "TARGET_SSE2"
23333 "psrlw\t{%2, %0|%0, %2}"
23334 [(set_attr "type" "sseishft")
23335 (set_attr "mode" "TI")])
23336
23337 (define_insn "lshrv4si3_ti"
23338 [(set (match_operand:V4SI 0 "register_operand" "=x")
23339 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23340 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23341 "TARGET_SSE2"
23342 "psrld\t{%2, %0|%0, %2}"
23343 [(set_attr "type" "sseishft")
23344 (set_attr "mode" "TI")])
23345
23346 (define_insn "lshrv2di3_ti"
23347 [(set (match_operand:V2DI 0 "register_operand" "=x")
23348 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23349 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23350 "TARGET_SSE2"
23351 "psrlq\t{%2, %0|%0, %2}"
23352 [(set_attr "type" "sseishft")
23353 (set_attr "mode" "TI")])
23354
23355 (define_insn "ashlv8hi3_ti"
23356 [(set (match_operand:V8HI 0 "register_operand" "=x")
23357 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23358 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23359 "TARGET_SSE2"
23360 "psllw\t{%2, %0|%0, %2}"
23361 [(set_attr "type" "sseishft")
23362 (set_attr "mode" "TI")])
23363
23364 (define_insn "ashlv4si3_ti"
23365 [(set (match_operand:V4SI 0 "register_operand" "=x")
23366 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23367 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23368 "TARGET_SSE2"
23369 "pslld\t{%2, %0|%0, %2}"
23370 [(set_attr "type" "sseishft")
23371 (set_attr "mode" "TI")])
23372
23373 (define_insn "ashlv2di3_ti"
23374 [(set (match_operand:V2DI 0 "register_operand" "=x")
23375 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23376 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23377 "TARGET_SSE2"
23378 "psllq\t{%2, %0|%0, %2}"
23379 [(set_attr "type" "sseishft")
23380 (set_attr "mode" "TI")])
23381
23382 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23383 ;; we wouldn't need here it since we never generate TImode arithmetic.
23384
23385 ;; There has to be some kind of prize for the weirdest new instruction...
23386 (define_insn "sse2_ashlti3"
23387 [(set (match_operand:TI 0 "register_operand" "=x")
23388 (unspec:TI
23389 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23390 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23391 (const_int 8)))] UNSPEC_NOP))]
23392 "TARGET_SSE2"
23393 "pslldq\t{%2, %0|%0, %2}"
23394 [(set_attr "type" "sseishft")
23395 (set_attr "mode" "TI")])
23396
23397 (define_insn "sse2_lshrti3"
23398 [(set (match_operand:TI 0 "register_operand" "=x")
23399 (unspec:TI
23400 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23401 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23402 (const_int 8)))] UNSPEC_NOP))]
23403 "TARGET_SSE2"
23404 "psrldq\t{%2, %0|%0, %2}"
23405 [(set_attr "type" "sseishft")
23406 (set_attr "mode" "TI")])
23407
23408 ;; SSE unpack
23409
23410 (define_insn "sse2_unpckhpd"
23411 [(set (match_operand:V2DF 0 "register_operand" "=x")
23412 (vec_concat:V2DF
23413 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23414 (parallel [(const_int 1)]))
23415 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23416 (parallel [(const_int 1)]))))]
23417 "TARGET_SSE2"
23418 "unpckhpd\t{%2, %0|%0, %2}"
23419 [(set_attr "type" "ssecvt")
23420 (set_attr "mode" "V2DF")])
23421
23422 (define_insn "sse2_unpcklpd"
23423 [(set (match_operand:V2DF 0 "register_operand" "=x")
23424 (vec_concat:V2DF
23425 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23426 (parallel [(const_int 0)]))
23427 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23428 (parallel [(const_int 0)]))))]
23429 "TARGET_SSE2"
23430 "unpcklpd\t{%2, %0|%0, %2}"
23431 [(set_attr "type" "ssecvt")
23432 (set_attr "mode" "V2DF")])
23433
23434 ;; MMX pack/unpack insns.
23435
23436 (define_insn "sse2_packsswb"
23437 [(set (match_operand:V16QI 0 "register_operand" "=x")
23438 (vec_concat:V16QI
23439 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23440 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23441 "TARGET_SSE2"
23442 "packsswb\t{%2, %0|%0, %2}"
23443 [(set_attr "type" "ssecvt")
23444 (set_attr "mode" "TI")])
23445
23446 (define_insn "sse2_packssdw"
23447 [(set (match_operand:V8HI 0 "register_operand" "=x")
23448 (vec_concat:V8HI
23449 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23450 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23451 "TARGET_SSE2"
23452 "packssdw\t{%2, %0|%0, %2}"
23453 [(set_attr "type" "ssecvt")
23454 (set_attr "mode" "TI")])
23455
23456 (define_insn "sse2_packuswb"
23457 [(set (match_operand:V16QI 0 "register_operand" "=x")
23458 (vec_concat:V16QI
23459 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23460 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23461 "TARGET_SSE2"
23462 "packuswb\t{%2, %0|%0, %2}"
23463 [(set_attr "type" "ssecvt")
23464 (set_attr "mode" "TI")])
23465
23466 (define_insn "sse2_punpckhbw"
23467 [(set (match_operand:V16QI 0 "register_operand" "=x")
23468 (vec_merge:V16QI
23469 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23470 (parallel [(const_int 8) (const_int 0)
23471 (const_int 9) (const_int 1)
23472 (const_int 10) (const_int 2)
23473 (const_int 11) (const_int 3)
23474 (const_int 12) (const_int 4)
23475 (const_int 13) (const_int 5)
23476 (const_int 14) (const_int 6)
23477 (const_int 15) (const_int 7)]))
23478 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23479 (parallel [(const_int 0) (const_int 8)
23480 (const_int 1) (const_int 9)
23481 (const_int 2) (const_int 10)
23482 (const_int 3) (const_int 11)
23483 (const_int 4) (const_int 12)
23484 (const_int 5) (const_int 13)
23485 (const_int 6) (const_int 14)
23486 (const_int 7) (const_int 15)]))
23487 (const_int 21845)))]
23488 "TARGET_SSE2"
23489 "punpckhbw\t{%2, %0|%0, %2}"
23490 [(set_attr "type" "ssecvt")
23491 (set_attr "mode" "TI")])
23492
23493 (define_insn "sse2_punpckhwd"
23494 [(set (match_operand:V8HI 0 "register_operand" "=x")
23495 (vec_merge:V8HI
23496 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23497 (parallel [(const_int 4) (const_int 0)
23498 (const_int 5) (const_int 1)
23499 (const_int 6) (const_int 2)
23500 (const_int 7) (const_int 3)]))
23501 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23502 (parallel [(const_int 0) (const_int 4)
23503 (const_int 1) (const_int 5)
23504 (const_int 2) (const_int 6)
23505 (const_int 3) (const_int 7)]))
23506 (const_int 85)))]
23507 "TARGET_SSE2"
23508 "punpckhwd\t{%2, %0|%0, %2}"
23509 [(set_attr "type" "ssecvt")
23510 (set_attr "mode" "TI")])
23511
23512 (define_insn "sse2_punpckhdq"
23513 [(set (match_operand:V4SI 0 "register_operand" "=x")
23514 (vec_merge:V4SI
23515 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23516 (parallel [(const_int 2) (const_int 0)
23517 (const_int 3) (const_int 1)]))
23518 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23519 (parallel [(const_int 0) (const_int 2)
23520 (const_int 1) (const_int 3)]))
23521 (const_int 5)))]
23522 "TARGET_SSE2"
23523 "punpckhdq\t{%2, %0|%0, %2}"
23524 [(set_attr "type" "ssecvt")
23525 (set_attr "mode" "TI")])
23526
23527 (define_insn "sse2_punpcklbw"
23528 [(set (match_operand:V16QI 0 "register_operand" "=x")
23529 (vec_merge:V16QI
23530 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23531 (parallel [(const_int 0) (const_int 8)
23532 (const_int 1) (const_int 9)
23533 (const_int 2) (const_int 10)
23534 (const_int 3) (const_int 11)
23535 (const_int 4) (const_int 12)
23536 (const_int 5) (const_int 13)
23537 (const_int 6) (const_int 14)
23538 (const_int 7) (const_int 15)]))
23539 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23540 (parallel [(const_int 8) (const_int 0)
23541 (const_int 9) (const_int 1)
23542 (const_int 10) (const_int 2)
23543 (const_int 11) (const_int 3)
23544 (const_int 12) (const_int 4)
23545 (const_int 13) (const_int 5)
23546 (const_int 14) (const_int 6)
23547 (const_int 15) (const_int 7)]))
23548 (const_int 21845)))]
23549 "TARGET_SSE2"
23550 "punpcklbw\t{%2, %0|%0, %2}"
23551 [(set_attr "type" "ssecvt")
23552 (set_attr "mode" "TI")])
23553
23554 (define_insn "sse2_punpcklwd"
23555 [(set (match_operand:V8HI 0 "register_operand" "=x")
23556 (vec_merge:V8HI
23557 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23558 (parallel [(const_int 0) (const_int 4)
23559 (const_int 1) (const_int 5)
23560 (const_int 2) (const_int 6)
23561 (const_int 3) (const_int 7)]))
23562 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23563 (parallel [(const_int 4) (const_int 0)
23564 (const_int 5) (const_int 1)
23565 (const_int 6) (const_int 2)
23566 (const_int 7) (const_int 3)]))
23567 (const_int 85)))]
23568 "TARGET_SSE2"
23569 "punpcklwd\t{%2, %0|%0, %2}"
23570 [(set_attr "type" "ssecvt")
23571 (set_attr "mode" "TI")])
23572
23573 (define_insn "sse2_punpckldq"
23574 [(set (match_operand:V4SI 0 "register_operand" "=x")
23575 (vec_merge:V4SI
23576 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23577 (parallel [(const_int 0) (const_int 2)
23578 (const_int 1) (const_int 3)]))
23579 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23580 (parallel [(const_int 2) (const_int 0)
23581 (const_int 3) (const_int 1)]))
23582 (const_int 5)))]
23583 "TARGET_SSE2"
23584 "punpckldq\t{%2, %0|%0, %2}"
23585 [(set_attr "type" "ssecvt")
23586 (set_attr "mode" "TI")])
23587
23588 (define_insn "sse2_punpcklqdq"
23589 [(set (match_operand:V2DI 0 "register_operand" "=x")
23590 (vec_merge:V2DI
23591 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23592 (parallel [(const_int 1)
23593 (const_int 0)]))
23594 (match_operand:V2DI 1 "register_operand" "0")
23595 (const_int 1)))]
23596 "TARGET_SSE2"
23597 "punpcklqdq\t{%2, %0|%0, %2}"
23598 [(set_attr "type" "ssecvt")
23599 (set_attr "mode" "TI")])
23600
23601 (define_insn "sse2_punpckhqdq"
23602 [(set (match_operand:V2DI 0 "register_operand" "=x")
23603 (vec_merge:V2DI
23604 (match_operand:V2DI 1 "register_operand" "0")
23605 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23606 (parallel [(const_int 1)
23607 (const_int 0)]))
23608 (const_int 1)))]
23609 "TARGET_SSE2"
23610 "punpckhqdq\t{%2, %0|%0, %2}"
23611 [(set_attr "type" "ssecvt")
23612 (set_attr "mode" "TI")])
23613
23614 ;; SSE2 moves
23615
23616 (define_insn "sse2_movapd"
23617 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23618 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23619 UNSPEC_MOVA))]
23620 "TARGET_SSE2
23621 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23622 "movapd\t{%1, %0|%0, %1}"
23623 [(set_attr "type" "ssemov")
23624 (set_attr "mode" "V2DF")])
23625
23626 (define_insn "sse2_movupd"
23627 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23628 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23629 UNSPEC_MOVU))]
23630 "TARGET_SSE2
23631 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23632 "movupd\t{%1, %0|%0, %1}"
23633 [(set_attr "type" "ssecvt")
23634 (set_attr "mode" "V2DF")])
23635
23636 (define_insn "sse2_movdqa"
23637 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23638 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23639 UNSPEC_MOVA))]
23640 "TARGET_SSE2
23641 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23642 "movdqa\t{%1, %0|%0, %1}"
23643 [(set_attr "type" "ssemov")
23644 (set_attr "mode" "TI")])
23645
23646 (define_insn "sse2_movdqu"
23647 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23648 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23649 UNSPEC_MOVU))]
23650 "TARGET_SSE2
23651 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23652 "movdqu\t{%1, %0|%0, %1}"
23653 [(set_attr "type" "ssecvt")
23654 (set_attr "mode" "TI")])
23655
23656 (define_insn "sse2_movdq2q"
23657 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23658 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23659 (parallel [(const_int 0)])))]
23660 "TARGET_SSE2 && !TARGET_64BIT"
23661 "@
23662 movq\t{%1, %0|%0, %1}
23663 movdq2q\t{%1, %0|%0, %1}"
23664 [(set_attr "type" "ssecvt")
23665 (set_attr "mode" "TI")])
23666
23667 (define_insn "sse2_movdq2q_rex64"
23668 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23669 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23670 (parallel [(const_int 0)])))]
23671 "TARGET_SSE2 && TARGET_64BIT"
23672 "@
23673 movq\t{%1, %0|%0, %1}
23674 movdq2q\t{%1, %0|%0, %1}
23675 movd\t{%1, %0|%0, %1}"
23676 [(set_attr "type" "ssecvt")
23677 (set_attr "mode" "TI")])
23678
23679 (define_insn "sse2_movq2dq"
23680 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23681 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23682 (const_int 0)))]
23683 "TARGET_SSE2 && !TARGET_64BIT"
23684 "@
23685 movq\t{%1, %0|%0, %1}
23686 movq2dq\t{%1, %0|%0, %1}"
23687 [(set_attr "type" "ssecvt,ssemov")
23688 (set_attr "mode" "TI")])
23689
23690 (define_insn "sse2_movq2dq_rex64"
23691 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23692 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23693 (const_int 0)))]
23694 "TARGET_SSE2 && TARGET_64BIT"
23695 "@
23696 movq\t{%1, %0|%0, %1}
23697 movq2dq\t{%1, %0|%0, %1}
23698 movd\t{%1, %0|%0, %1}"
23699 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23700 (set_attr "mode" "TI")])
23701
23702 (define_insn "sse2_movq"
23703 [(set (match_operand:V2DI 0 "register_operand" "=x")
23704 (vec_concat:V2DI (vec_select:DI
23705 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23706 (parallel [(const_int 0)]))
23707 (const_int 0)))]
23708 "TARGET_SSE2"
23709 "movq\t{%1, %0|%0, %1}"
23710 [(set_attr "type" "ssemov")
23711 (set_attr "mode" "TI")])
23712
23713 (define_insn "sse2_loadd"
23714 [(set (match_operand:V4SI 0 "register_operand" "=x")
23715 (vec_merge:V4SI
23716 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23717 (const_vector:V4SI [(const_int 0)
23718 (const_int 0)
23719 (const_int 0)
23720 (const_int 0)])
23721 (const_int 1)))]
23722 "TARGET_SSE2"
23723 "movd\t{%1, %0|%0, %1}"
23724 [(set_attr "type" "ssemov")
23725 (set_attr "mode" "TI")])
23726
23727 (define_insn "sse2_stored"
23728 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23729 (vec_select:SI
23730 (match_operand:V4SI 1 "register_operand" "x")
23731 (parallel [(const_int 0)])))]
23732 "TARGET_SSE2"
23733 "movd\t{%1, %0|%0, %1}"
23734 [(set_attr "type" "ssemov")
23735 (set_attr "mode" "TI")])
23736
23737 (define_insn "sse2_movhpd"
23738 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23739 (vec_merge:V2DF
23740 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23741 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23742 (const_int 2)))]
23743 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23744 "movhpd\t{%2, %0|%0, %2}"
23745 [(set_attr "type" "ssecvt")
23746 (set_attr "mode" "V2DF")])
23747
23748 (define_expand "sse2_loadsd"
23749 [(match_operand:V2DF 0 "register_operand" "")
23750 (match_operand:DF 1 "memory_operand" "")]
23751 "TARGET_SSE2"
23752 {
23753 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23754 CONST0_RTX (V2DFmode)));
23755 DONE;
23756 })
23757
23758 (define_insn "sse2_loadsd_1"
23759 [(set (match_operand:V2DF 0 "register_operand" "=x")
23760 (vec_merge:V2DF
23761 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23762 (match_operand:V2DF 2 "const0_operand" "X")
23763 (const_int 1)))]
23764 "TARGET_SSE2"
23765 "movsd\t{%1, %0|%0, %1}"
23766 [(set_attr "type" "ssecvt")
23767 (set_attr "mode" "DF")])
23768
23769 (define_insn "sse2_movsd"
23770 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23771 (vec_merge:V2DF
23772 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23773 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23774 (const_int 1)))]
23775 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
23776 "@movsd\t{%2, %0|%0, %2}
23777 movlpd\t{%2, %0|%0, %2}
23778 movlpd\t{%2, %0|%0, %2}"
23779 [(set_attr "type" "ssecvt")
23780 (set_attr "mode" "DF,V2DF,V2DF")])
23781
23782 (define_insn "sse2_storesd"
23783 [(set (match_operand:DF 0 "memory_operand" "=m")
23784 (vec_select:DF
23785 (match_operand:V2DF 1 "register_operand" "x")
23786 (parallel [(const_int 0)])))]
23787 "TARGET_SSE2"
23788 "movsd\t{%1, %0|%0, %1}"
23789 [(set_attr "type" "ssecvt")
23790 (set_attr "mode" "DF")])
23791
23792 (define_insn "sse2_shufpd"
23793 [(set (match_operand:V2DF 0 "register_operand" "=x")
23794 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23795 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23796 (match_operand:SI 3 "immediate_operand" "i")]
23797 UNSPEC_SHUFFLE))]
23798 "TARGET_SSE2"
23799 ;; @@@ check operand order for intel/nonintel syntax
23800 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23801 [(set_attr "type" "ssecvt")
23802 (set_attr "mode" "V2DF")])
23803
23804 (define_insn "sse2_clflush"
23805 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23806 UNSPECV_CLFLUSH)]
23807 "TARGET_SSE2"
23808 "clflush %0"
23809 [(set_attr "type" "sse")
23810 (set_attr "memory" "unknown")])
23811
23812 (define_expand "sse2_mfence"
23813 [(set (match_dup 0)
23814 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23815 "TARGET_SSE2"
23816 {
23817 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23818 MEM_VOLATILE_P (operands[0]) = 1;
23819 })
23820
23821 (define_insn "*mfence_insn"
23822 [(set (match_operand:BLK 0 "" "")
23823 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23824 "TARGET_SSE2"
23825 "mfence"
23826 [(set_attr "type" "sse")
23827 (set_attr "memory" "unknown")])
23828
23829 (define_expand "sse2_lfence"
23830 [(set (match_dup 0)
23831 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23832 "TARGET_SSE2"
23833 {
23834 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23835 MEM_VOLATILE_P (operands[0]) = 1;
23836 })
23837
23838 (define_insn "*lfence_insn"
23839 [(set (match_operand:BLK 0 "" "")
23840 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23841 "TARGET_SSE2"
23842 "lfence"
23843 [(set_attr "type" "sse")
23844 (set_attr "memory" "unknown")])
23845
23846 ;; SSE3
23847
23848 (define_insn "mwait"
23849 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23850 (match_operand:SI 1 "register_operand" "c")]
23851 UNSPECV_MWAIT)]
23852 "TARGET_SSE3"
23853 "mwait\t%0, %1"
23854 [(set_attr "length" "3")])
23855
23856 (define_insn "monitor"
23857 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23858 (match_operand:SI 1 "register_operand" "c")
23859 (match_operand:SI 2 "register_operand" "d")]
23860 UNSPECV_MONITOR)]
23861 "TARGET_SSE3"
23862 "monitor\t%0, %1, %2"
23863 [(set_attr "length" "3")])
23864
23865 ;; SSE3 arithmetic
23866
23867 (define_insn "addsubv4sf3"
23868 [(set (match_operand:V4SF 0 "register_operand" "=x")
23869 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23870 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23871 UNSPEC_ADDSUB))]
23872 "TARGET_SSE3"
23873 "addsubps\t{%2, %0|%0, %2}"
23874 [(set_attr "type" "sseadd")
23875 (set_attr "mode" "V4SF")])
23876
23877 (define_insn "addsubv2df3"
23878 [(set (match_operand:V2DF 0 "register_operand" "=x")
23879 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23880 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23881 UNSPEC_ADDSUB))]
23882 "TARGET_SSE3"
23883 "addsubpd\t{%2, %0|%0, %2}"
23884 [(set_attr "type" "sseadd")
23885 (set_attr "mode" "V2DF")])
23886
23887 (define_insn "haddv4sf3"
23888 [(set (match_operand:V4SF 0 "register_operand" "=x")
23889 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23890 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23891 UNSPEC_HADD))]
23892 "TARGET_SSE3"
23893 "haddps\t{%2, %0|%0, %2}"
23894 [(set_attr "type" "sseadd")
23895 (set_attr "mode" "V4SF")])
23896
23897 (define_insn "haddv2df3"
23898 [(set (match_operand:V2DF 0 "register_operand" "=x")
23899 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23900 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23901 UNSPEC_HADD))]
23902 "TARGET_SSE3"
23903 "haddpd\t{%2, %0|%0, %2}"
23904 [(set_attr "type" "sseadd")
23905 (set_attr "mode" "V2DF")])
23906
23907 (define_insn "hsubv4sf3"
23908 [(set (match_operand:V4SF 0 "register_operand" "=x")
23909 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23910 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23911 UNSPEC_HSUB))]
23912 "TARGET_SSE3"
23913 "hsubps\t{%2, %0|%0, %2}"
23914 [(set_attr "type" "sseadd")
23915 (set_attr "mode" "V4SF")])
23916
23917 (define_insn "hsubv2df3"
23918 [(set (match_operand:V2DF 0 "register_operand" "=x")
23919 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23920 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23921 UNSPEC_HSUB))]
23922 "TARGET_SSE3"
23923 "hsubpd\t{%2, %0|%0, %2}"
23924 [(set_attr "type" "sseadd")
23925 (set_attr "mode" "V2DF")])
23926
23927 (define_insn "movshdup"
23928 [(set (match_operand:V4SF 0 "register_operand" "=x")
23929 (unspec:V4SF
23930 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23931 "TARGET_SSE3"
23932 "movshdup\t{%1, %0|%0, %1}"
23933 [(set_attr "type" "sse")
23934 (set_attr "mode" "V4SF")])
23935
23936 (define_insn "movsldup"
23937 [(set (match_operand:V4SF 0 "register_operand" "=x")
23938 (unspec:V4SF
23939 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23940 "TARGET_SSE3"
23941 "movsldup\t{%1, %0|%0, %1}"
23942 [(set_attr "type" "sse")
23943 (set_attr "mode" "V4SF")])
23944
23945 (define_insn "lddqu"
23946 [(set (match_operand:V16QI 0 "register_operand" "=x")
23947 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23948 UNSPEC_LDQQU))]
23949 "TARGET_SSE3"
23950 "lddqu\t{%1, %0|%0, %1}"
23951 [(set_attr "type" "ssecvt")
23952 (set_attr "mode" "TI")])
23953
23954 (define_insn "loadddup"
23955 [(set (match_operand:V2DF 0 "register_operand" "=x")
23956 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23957 "TARGET_SSE3"
23958 "movddup\t{%1, %0|%0, %1}"
23959 [(set_attr "type" "ssecvt")
23960 (set_attr "mode" "DF")])
23961
23962 (define_insn "movddup"
23963 [(set (match_operand:V2DF 0 "register_operand" "=x")
23964 (vec_duplicate:V2DF
23965 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23966 (parallel [(const_int 0)]))))]
23967 "TARGET_SSE3"
23968 "movddup\t{%1, %0|%0, %1}"
23969 [(set_attr "type" "ssecvt")
23970 (set_attr "mode" "DF")])
This page took 1.084676 seconds and 5 git commands to generate.