Deleted Added
full compact
i386.md (237021) i386.md (251212)
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, 2005, 2006
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, 51 Franklin Street, Fifth Floor,
23;; Boston, MA 02110-1301, 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_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_REG_SAVE 14)
70 (UNSPEC_DEF_CFA 15)
71
72 ; TLS support
73 (UNSPEC_TP 16)
74 (UNSPEC_TLS_GD 17)
75 (UNSPEC_TLS_LD_BASE 18)
76 (UNSPEC_TLSDESC 19)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 20)
80 (UNSPEC_FNSTSW 21)
81 (UNSPEC_SAHF 22)
82 (UNSPEC_FSTCW 23)
83 (UNSPEC_ADD_CARRY 24)
84 (UNSPEC_FLDCW 25)
85 (UNSPEC_REP 26)
86 (UNSPEC_EH_RETURN 27)
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
91 (UNSPEC_MASKMOV 31)
92 (UNSPEC_MOVMSK 32)
93 (UNSPEC_MOVNT 33)
94 (UNSPEC_MOVU 34)
95 (UNSPEC_RCP 35)
96 (UNSPEC_RSQRT 36)
97 (UNSPEC_SFENCE 37)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
99 (UNSPEC_PFRCP 39)
100 (UNSPEC_PFRCPIT1 40)
101 (UNSPEC_PFRCPIT2 41)
102 (UNSPEC_PFRSQRT 42)
103 (UNSPEC_PFRSQIT1 43)
104 (UNSPEC_MFENCE 44)
105 (UNSPEC_LFENCE 45)
106 (UNSPEC_PSADBW 46)
107 (UNSPEC_LDQQU 47)
108
109 ; Generic math support
110 (UNSPEC_COPYSIGN 50)
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
113
114 ; x87 Floating point
115 (UNSPEC_SIN 60)
116 (UNSPEC_COS 61)
117 (UNSPEC_FPATAN 62)
118 (UNSPEC_FYL2X 63)
119 (UNSPEC_FYL2XP1 64)
120 (UNSPEC_FRNDINT 65)
121 (UNSPEC_FIST 66)
122 (UNSPEC_F2XM1 67)
123
124 ; x87 Rounding
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
131
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_TAN_ONE 82)
136 (UNSPEC_TAN_TAN 83)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
141 (UNSPEC_FPREM_F 88)
142 (UNSPEC_FPREM_U 89)
143 (UNSPEC_FPREM1_F 90)
144 (UNSPEC_FPREM1_U 91)
145
146 ; SSP patterns
147 (UNSPEC_SP_SET 100)
148 (UNSPEC_SP_TEST 101)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
151
152 ; SSSE3
153 (UNSPEC_PSHUFB 120)
154 (UNSPEC_PSIGN 121)
155 (UNSPEC_PALIGNR 122)
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, 2005, 2006
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, 51 Franklin Street, Fifth Floor,
23;; Boston, MA 02110-1301, 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_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_REG_SAVE 14)
70 (UNSPEC_DEF_CFA 15)
71
72 ; TLS support
73 (UNSPEC_TP 16)
74 (UNSPEC_TLS_GD 17)
75 (UNSPEC_TLS_LD_BASE 18)
76 (UNSPEC_TLSDESC 19)
77
78 ; Other random patterns
79 (UNSPEC_SCAS 20)
80 (UNSPEC_FNSTSW 21)
81 (UNSPEC_SAHF 22)
82 (UNSPEC_FSTCW 23)
83 (UNSPEC_ADD_CARRY 24)
84 (UNSPEC_FLDCW 25)
85 (UNSPEC_REP 26)
86 (UNSPEC_EH_RETURN 27)
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
91 (UNSPEC_MASKMOV 31)
92 (UNSPEC_MOVMSK 32)
93 (UNSPEC_MOVNT 33)
94 (UNSPEC_MOVU 34)
95 (UNSPEC_RCP 35)
96 (UNSPEC_RSQRT 36)
97 (UNSPEC_SFENCE 37)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
99 (UNSPEC_PFRCP 39)
100 (UNSPEC_PFRCPIT1 40)
101 (UNSPEC_PFRCPIT2 41)
102 (UNSPEC_PFRSQRT 42)
103 (UNSPEC_PFRSQIT1 43)
104 (UNSPEC_MFENCE 44)
105 (UNSPEC_LFENCE 45)
106 (UNSPEC_PSADBW 46)
107 (UNSPEC_LDQQU 47)
108
109 ; Generic math support
110 (UNSPEC_COPYSIGN 50)
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
113
114 ; x87 Floating point
115 (UNSPEC_SIN 60)
116 (UNSPEC_COS 61)
117 (UNSPEC_FPATAN 62)
118 (UNSPEC_FYL2X 63)
119 (UNSPEC_FYL2XP1 64)
120 (UNSPEC_FRNDINT 65)
121 (UNSPEC_FIST 66)
122 (UNSPEC_F2XM1 67)
123
124 ; x87 Rounding
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
131
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_TAN_ONE 82)
136 (UNSPEC_TAN_TAN 83)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
141 (UNSPEC_FPREM_F 88)
142 (UNSPEC_FPREM_U 89)
143 (UNSPEC_FPREM1_F 90)
144 (UNSPEC_FPREM1_U 91)
145
146 ; SSP patterns
147 (UNSPEC_SP_SET 100)
148 (UNSPEC_SP_TEST 101)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
151
152 ; SSSE3
153 (UNSPEC_PSHUFB 120)
154 (UNSPEC_PSIGN 121)
155 (UNSPEC_PALIGNR 122)
156
157 ; For SSE4A support
158 (UNSPEC_EXTRQI 130)
159 (UNSPEC_EXTRQ 131)
160 (UNSPEC_INSERTQI 132)
161 (UNSPEC_INSERTQ 133)
156 ])
157
158(define_constants
159 [(UNSPECV_BLOCKAGE 0)
160 (UNSPECV_STACK_PROBE 1)
161 (UNSPECV_EMMS 2)
162 (UNSPECV_LDMXCSR 3)
163 (UNSPECV_STMXCSR 4)
164 (UNSPECV_FEMMS 5)
165 (UNSPECV_CLFLUSH 6)
166 (UNSPECV_ALIGN 7)
167 (UNSPECV_MONITOR 8)
168 (UNSPECV_MWAIT 9)
169 (UNSPECV_CMPXCHG_1 10)
170 (UNSPECV_CMPXCHG_2 11)
171 (UNSPECV_XCHG 12)
172 (UNSPECV_LOCK 13)
173 ])
174
175;; Registers by name.
176(define_constants
177 [(BP_REG 6)
178 (SP_REG 7)
179 (FLAGS_REG 17)
180 (FPSR_REG 18)
181 (DIRFLAG_REG 19)
182 ])
183
184;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
185;; from i386.c.
186
187;; In C guard expressions, put expressions which may be compile-time
188;; constants first. This allows for better optimization. For
189;; example, write "TARGET_64BIT && reload_completed", not
190;; "reload_completed && TARGET_64BIT".
191
192
193;; Processor type. This attribute must exactly match the processor_type
194;; enumeration in i386.h.
162 ])
163
164(define_constants
165 [(UNSPECV_BLOCKAGE 0)
166 (UNSPECV_STACK_PROBE 1)
167 (UNSPECV_EMMS 2)
168 (UNSPECV_LDMXCSR 3)
169 (UNSPECV_STMXCSR 4)
170 (UNSPECV_FEMMS 5)
171 (UNSPECV_CLFLUSH 6)
172 (UNSPECV_ALIGN 7)
173 (UNSPECV_MONITOR 8)
174 (UNSPECV_MWAIT 9)
175 (UNSPECV_CMPXCHG_1 10)
176 (UNSPECV_CMPXCHG_2 11)
177 (UNSPECV_XCHG 12)
178 (UNSPECV_LOCK 13)
179 ])
180
181;; Registers by name.
182(define_constants
183 [(BP_REG 6)
184 (SP_REG 7)
185 (FLAGS_REG 17)
186 (FPSR_REG 18)
187 (DIRFLAG_REG 19)
188 ])
189
190;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
191;; from i386.c.
192
193;; In C guard expressions, put expressions which may be compile-time
194;; constants first. This allows for better optimization. For
195;; example, write "TARGET_64BIT && reload_completed", not
196;; "reload_completed && TARGET_64BIT".
197
198
199;; Processor type. This attribute must exactly match the processor_type
200;; enumeration in i386.h.
195(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
201(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202 nocona,core2,generic32,generic64,amdfam10"
196 (const (symbol_ref "ix86_tune")))
197
198;; A basic instruction type. Refinements due to arguments to be
199;; provided in other attributes.
200(define_attr "type"
201 "other,multi,
202 alu,alu1,negnot,imov,imovx,lea,
203 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
204 icmp,test,ibr,setcc,icmov,
205 push,pop,call,callv,leave,
203 (const (symbol_ref "ix86_tune")))
204
205;; A basic instruction type. Refinements due to arguments to be
206;; provided in other attributes.
207(define_attr "type"
208 "other,multi,
209 alu,alu1,negnot,imov,imovx,lea,
210 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211 icmp,test,ibr,setcc,icmov,
212 push,pop,call,callv,leave,
206 str,cld,
213 str,bitmanip,cld,
207 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
208 sselog,sselog1,sseiadd,sseishft,sseimul,
214 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215 sselog,sselog1,sseiadd,sseishft,sseimul,
209 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
210 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
211 (const_string "other"))
212
213;; Main data type used by the insn
214(define_attr "mode"
215 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
216 (const_string "unknown"))
217
218;; The CPU unit operations uses.
219(define_attr "unit" "integer,i387,sse,mmx,unknown"
220 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
221 (const_string "i387")
222 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
217 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218 (const_string "other"))
219
220;; Main data type used by the insn
221(define_attr "mode"
222 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223 (const_string "unknown"))
224
225;; The CPU unit operations uses.
226(define_attr "unit" "integer,i387,sse,mmx,unknown"
227 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228 (const_string "i387")
229 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
223 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
230 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
224 (const_string "sse")
225 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
226 (const_string "mmx")
227 (eq_attr "type" "other")
228 (const_string "unknown")]
229 (const_string "integer")))
230
231;; The (bounding maximum) length of an instruction immediate.
232(define_attr "length_immediate" ""
231 (const_string "sse")
232 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
233 (const_string "mmx")
234 (eq_attr "type" "other")
235 (const_string "unknown")]
236 (const_string "integer")))
237
238;; The (bounding maximum) length of an instruction immediate.
239(define_attr "length_immediate" ""
233 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
240 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave,
241 bitmanip")
234 (const_int 0)
235 (eq_attr "unit" "i387,sse,mmx")
236 (const_int 0)
237 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
238 imul,icmp,push,pop")
239 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
240 (eq_attr "type" "imov,test")
241 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
242 (eq_attr "type" "call")
243 (if_then_else (match_operand 0 "constant_call_address_operand" "")
244 (const_int 4)
245 (const_int 0))
246 (eq_attr "type" "callv")
247 (if_then_else (match_operand 1 "constant_call_address_operand" "")
248 (const_int 4)
249 (const_int 0))
250 ;; We don't know the size before shorten_branches. Expect
251 ;; the instruction to fit for better scheduling.
252 (eq_attr "type" "ibr")
253 (const_int 1)
254 ]
255 (symbol_ref "/* Update immediate_length and other attributes! */
256 gcc_unreachable (),1")))
257
258;; The (bounding maximum) length of an instruction address.
259(define_attr "length_address" ""
260 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
261 (const_int 0)
262 (and (eq_attr "type" "call")
263 (match_operand 0 "constant_call_address_operand" ""))
264 (const_int 0)
265 (and (eq_attr "type" "callv")
266 (match_operand 1 "constant_call_address_operand" ""))
267 (const_int 0)
268 ]
269 (symbol_ref "ix86_attr_length_address_default (insn)")))
270
271;; Set when length prefix is used.
272(define_attr "prefix_data16" ""
273 (if_then_else (ior (eq_attr "mode" "HI")
274 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
275 (const_int 1)
276 (const_int 0)))
277
278;; Set when string REP prefix is used.
279(define_attr "prefix_rep" ""
280 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
281 (const_int 1)
282 (const_int 0)))
283
284;; Set when 0f opcode prefix is used.
285(define_attr "prefix_0f" ""
286 (if_then_else
242 (const_int 0)
243 (eq_attr "unit" "i387,sse,mmx")
244 (const_int 0)
245 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
246 imul,icmp,push,pop")
247 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248 (eq_attr "type" "imov,test")
249 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250 (eq_attr "type" "call")
251 (if_then_else (match_operand 0 "constant_call_address_operand" "")
252 (const_int 4)
253 (const_int 0))
254 (eq_attr "type" "callv")
255 (if_then_else (match_operand 1 "constant_call_address_operand" "")
256 (const_int 4)
257 (const_int 0))
258 ;; We don't know the size before shorten_branches. Expect
259 ;; the instruction to fit for better scheduling.
260 (eq_attr "type" "ibr")
261 (const_int 1)
262 ]
263 (symbol_ref "/* Update immediate_length and other attributes! */
264 gcc_unreachable (),1")))
265
266;; The (bounding maximum) length of an instruction address.
267(define_attr "length_address" ""
268 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
269 (const_int 0)
270 (and (eq_attr "type" "call")
271 (match_operand 0 "constant_call_address_operand" ""))
272 (const_int 0)
273 (and (eq_attr "type" "callv")
274 (match_operand 1 "constant_call_address_operand" ""))
275 (const_int 0)
276 ]
277 (symbol_ref "ix86_attr_length_address_default (insn)")))
278
279;; Set when length prefix is used.
280(define_attr "prefix_data16" ""
281 (if_then_else (ior (eq_attr "mode" "HI")
282 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
283 (const_int 1)
284 (const_int 0)))
285
286;; Set when string REP prefix is used.
287(define_attr "prefix_rep" ""
288 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
289 (const_int 1)
290 (const_int 0)))
291
292;; Set when 0f opcode prefix is used.
293(define_attr "prefix_0f" ""
294 (if_then_else
287 (ior (eq_attr "type" "imovx,setcc,icmov")
295 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
288 (eq_attr "unit" "sse,mmx"))
289 (const_int 1)
290 (const_int 0)))
291
292;; Set when REX opcode prefix is used.
293(define_attr "prefix_rex" ""
294 (cond [(and (eq_attr "mode" "DI")
295 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
296 (const_int 1)
297 (and (eq_attr "mode" "QI")
298 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
299 (const_int 0)))
300 (const_int 1)
301 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302 (const_int 0))
303 (const_int 1)
304 ]
305 (const_int 0)))
306
307;; Set when modrm byte is used.
308(define_attr "modrm" ""
309 (cond [(eq_attr "type" "str,cld,leave")
310 (const_int 0)
311 (eq_attr "unit" "i387")
312 (const_int 0)
313 (and (eq_attr "type" "incdec")
314 (ior (match_operand:SI 1 "register_operand" "")
315 (match_operand:HI 1 "register_operand" "")))
316 (const_int 0)
317 (and (eq_attr "type" "push")
318 (not (match_operand 1 "memory_operand" "")))
319 (const_int 0)
320 (and (eq_attr "type" "pop")
321 (not (match_operand 0 "memory_operand" "")))
322 (const_int 0)
323 (and (eq_attr "type" "imov")
324 (ior (and (match_operand 0 "register_operand" "")
325 (match_operand 1 "immediate_operand" ""))
326 (ior (and (match_operand 0 "ax_reg_operand" "")
327 (match_operand 1 "memory_displacement_only_operand" ""))
328 (and (match_operand 0 "memory_displacement_only_operand" "")
329 (match_operand 1 "ax_reg_operand" "")))))
330 (const_int 0)
331 (and (eq_attr "type" "call")
332 (match_operand 0 "constant_call_address_operand" ""))
333 (const_int 0)
334 (and (eq_attr "type" "callv")
335 (match_operand 1 "constant_call_address_operand" ""))
336 (const_int 0)
337 ]
338 (const_int 1)))
339
340;; The (bounding maximum) length of an instruction in bytes.
341;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
342;; Later we may want to split them and compute proper length as for
343;; other insns.
344(define_attr "length" ""
345 (cond [(eq_attr "type" "other,multi,fistp,frndint")
346 (const_int 16)
347 (eq_attr "type" "fcmp")
348 (const_int 4)
349 (eq_attr "unit" "i387")
350 (plus (const_int 2)
351 (plus (attr "prefix_data16")
352 (attr "length_address")))]
353 (plus (plus (attr "modrm")
354 (plus (attr "prefix_0f")
355 (plus (attr "prefix_rex")
356 (const_int 1))))
357 (plus (attr "prefix_rep")
358 (plus (attr "prefix_data16")
359 (plus (attr "length_immediate")
360 (attr "length_address")))))))
361
362;; The `memory' attribute is `none' if no memory is referenced, `load' or
363;; `store' if there is a simple memory reference therein, or `unknown'
364;; if the instruction is complex.
365
366(define_attr "memory" "none,load,store,both,unknown"
367 (cond [(eq_attr "type" "other,multi,str")
368 (const_string "unknown")
369 (eq_attr "type" "lea,fcmov,fpspc,cld")
370 (const_string "none")
371 (eq_attr "type" "fistp,leave")
372 (const_string "both")
373 (eq_attr "type" "frndint")
374 (const_string "load")
375 (eq_attr "type" "push")
376 (if_then_else (match_operand 1 "memory_operand" "")
377 (const_string "both")
378 (const_string "store"))
379 (eq_attr "type" "pop")
380 (if_then_else (match_operand 0 "memory_operand" "")
381 (const_string "both")
382 (const_string "load"))
383 (eq_attr "type" "setcc")
384 (if_then_else (match_operand 0 "memory_operand" "")
385 (const_string "store")
386 (const_string "none"))
387 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
388 (if_then_else (ior (match_operand 0 "memory_operand" "")
389 (match_operand 1 "memory_operand" ""))
390 (const_string "load")
391 (const_string "none"))
392 (eq_attr "type" "ibr")
393 (if_then_else (match_operand 0 "memory_operand" "")
394 (const_string "load")
395 (const_string "none"))
396 (eq_attr "type" "call")
397 (if_then_else (match_operand 0 "constant_call_address_operand" "")
398 (const_string "none")
399 (const_string "load"))
400 (eq_attr "type" "callv")
401 (if_then_else (match_operand 1 "constant_call_address_operand" "")
402 (const_string "none")
403 (const_string "load"))
404 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
405 (match_operand 1 "memory_operand" ""))
406 (const_string "both")
407 (and (match_operand 0 "memory_operand" "")
408 (match_operand 1 "memory_operand" ""))
409 (const_string "both")
410 (match_operand 0 "memory_operand" "")
411 (const_string "store")
412 (match_operand 1 "memory_operand" "")
413 (const_string "load")
414 (and (eq_attr "type"
415 "!alu1,negnot,ishift1,
296 (eq_attr "unit" "sse,mmx"))
297 (const_int 1)
298 (const_int 0)))
299
300;; Set when REX opcode prefix is used.
301(define_attr "prefix_rex" ""
302 (cond [(and (eq_attr "mode" "DI")
303 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
304 (const_int 1)
305 (and (eq_attr "mode" "QI")
306 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
307 (const_int 0)))
308 (const_int 1)
309 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310 (const_int 0))
311 (const_int 1)
312 ]
313 (const_int 0)))
314
315;; Set when modrm byte is used.
316(define_attr "modrm" ""
317 (cond [(eq_attr "type" "str,cld,leave")
318 (const_int 0)
319 (eq_attr "unit" "i387")
320 (const_int 0)
321 (and (eq_attr "type" "incdec")
322 (ior (match_operand:SI 1 "register_operand" "")
323 (match_operand:HI 1 "register_operand" "")))
324 (const_int 0)
325 (and (eq_attr "type" "push")
326 (not (match_operand 1 "memory_operand" "")))
327 (const_int 0)
328 (and (eq_attr "type" "pop")
329 (not (match_operand 0 "memory_operand" "")))
330 (const_int 0)
331 (and (eq_attr "type" "imov")
332 (ior (and (match_operand 0 "register_operand" "")
333 (match_operand 1 "immediate_operand" ""))
334 (ior (and (match_operand 0 "ax_reg_operand" "")
335 (match_operand 1 "memory_displacement_only_operand" ""))
336 (and (match_operand 0 "memory_displacement_only_operand" "")
337 (match_operand 1 "ax_reg_operand" "")))))
338 (const_int 0)
339 (and (eq_attr "type" "call")
340 (match_operand 0 "constant_call_address_operand" ""))
341 (const_int 0)
342 (and (eq_attr "type" "callv")
343 (match_operand 1 "constant_call_address_operand" ""))
344 (const_int 0)
345 ]
346 (const_int 1)))
347
348;; The (bounding maximum) length of an instruction in bytes.
349;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350;; Later we may want to split them and compute proper length as for
351;; other insns.
352(define_attr "length" ""
353 (cond [(eq_attr "type" "other,multi,fistp,frndint")
354 (const_int 16)
355 (eq_attr "type" "fcmp")
356 (const_int 4)
357 (eq_attr "unit" "i387")
358 (plus (const_int 2)
359 (plus (attr "prefix_data16")
360 (attr "length_address")))]
361 (plus (plus (attr "modrm")
362 (plus (attr "prefix_0f")
363 (plus (attr "prefix_rex")
364 (const_int 1))))
365 (plus (attr "prefix_rep")
366 (plus (attr "prefix_data16")
367 (plus (attr "length_immediate")
368 (attr "length_address")))))))
369
370;; The `memory' attribute is `none' if no memory is referenced, `load' or
371;; `store' if there is a simple memory reference therein, or `unknown'
372;; if the instruction is complex.
373
374(define_attr "memory" "none,load,store,both,unknown"
375 (cond [(eq_attr "type" "other,multi,str")
376 (const_string "unknown")
377 (eq_attr "type" "lea,fcmov,fpspc,cld")
378 (const_string "none")
379 (eq_attr "type" "fistp,leave")
380 (const_string "both")
381 (eq_attr "type" "frndint")
382 (const_string "load")
383 (eq_attr "type" "push")
384 (if_then_else (match_operand 1 "memory_operand" "")
385 (const_string "both")
386 (const_string "store"))
387 (eq_attr "type" "pop")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "both")
390 (const_string "load"))
391 (eq_attr "type" "setcc")
392 (if_then_else (match_operand 0 "memory_operand" "")
393 (const_string "store")
394 (const_string "none"))
395 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396 (if_then_else (ior (match_operand 0 "memory_operand" "")
397 (match_operand 1 "memory_operand" ""))
398 (const_string "load")
399 (const_string "none"))
400 (eq_attr "type" "ibr")
401 (if_then_else (match_operand 0 "memory_operand" "")
402 (const_string "load")
403 (const_string "none"))
404 (eq_attr "type" "call")
405 (if_then_else (match_operand 0 "constant_call_address_operand" "")
406 (const_string "none")
407 (const_string "load"))
408 (eq_attr "type" "callv")
409 (if_then_else (match_operand 1 "constant_call_address_operand" "")
410 (const_string "none")
411 (const_string "load"))
412 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413 (match_operand 1 "memory_operand" ""))
414 (const_string "both")
415 (and (match_operand 0 "memory_operand" "")
416 (match_operand 1 "memory_operand" ""))
417 (const_string "both")
418 (match_operand 0 "memory_operand" "")
419 (const_string "store")
420 (match_operand 1 "memory_operand" "")
421 (const_string "load")
422 (and (eq_attr "type"
423 "!alu1,negnot,ishift1,
416 imov,imovx,icmp,test,
424 imov,imovx,icmp,test,bitmanip,
417 fmov,fcmp,fsgn,
418 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
419 mmx,mmxmov,mmxcmp,mmxcvt")
420 (match_operand 2 "memory_operand" ""))
421 (const_string "load")
422 (and (eq_attr "type" "icmov")
423 (match_operand 3 "memory_operand" ""))
424 (const_string "load")
425 ]
426 (const_string "none")))
427
428;; Indicates if an instruction has both an immediate and a displacement.
429
430(define_attr "imm_disp" "false,true,unknown"
431 (cond [(eq_attr "type" "other,multi")
432 (const_string "unknown")
433 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
434 (and (match_operand 0 "memory_displacement_operand" "")
435 (match_operand 1 "immediate_operand" "")))
436 (const_string "true")
437 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
438 (and (match_operand 0 "memory_displacement_operand" "")
439 (match_operand 2 "immediate_operand" "")))
440 (const_string "true")
441 ]
442 (const_string "false")))
443
444;; Indicates if an FP operation has an integer source.
445
446(define_attr "fp_int_src" "false,true"
447 (const_string "false"))
448
449;; Defines rounding mode of an FP operation.
450
451(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
452 (const_string "any"))
453
454;; Describe a user's asm statement.
455(define_asm_attributes
456 [(set_attr "length" "128")
457 (set_attr "type" "multi")])
458
459;; All x87 floating point modes
460(define_mode_macro X87MODEF [SF DF XF])
461
462;; All integer modes handled by x87 fisttp operator.
463(define_mode_macro X87MODEI [HI SI DI])
464
465;; All integer modes handled by integer x87 operators.
466(define_mode_macro X87MODEI12 [HI SI])
467
468;; All SSE floating point modes
469(define_mode_macro SSEMODEF [SF DF])
470
471;; All integer modes handled by SSE cvtts?2si* operators.
472(define_mode_macro SSEMODEI24 [SI DI])
473
474
475;; Scheduling descriptions
476
477(include "pentium.md")
478(include "ppro.md")
479(include "k6.md")
480(include "athlon.md")
481(include "geode.md")
482
483
484;; Operand and operator predicates and constraints
485
486(include "predicates.md")
487(include "constraints.md")
488
489
490;; Compare instructions.
491
492;; All compare insns have expanders that save the operands away without
493;; actually generating RTL. The bCOND or sCOND (emitted immediately
494;; after the cmp) will actually emit the cmpM.
495
496(define_expand "cmpti"
497 [(set (reg:CC FLAGS_REG)
498 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
499 (match_operand:TI 1 "x86_64_general_operand" "")))]
500 "TARGET_64BIT"
501{
502 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
503 operands[0] = force_reg (TImode, operands[0]);
504 ix86_compare_op0 = operands[0];
505 ix86_compare_op1 = operands[1];
506 DONE;
507})
508
509(define_expand "cmpdi"
510 [(set (reg:CC FLAGS_REG)
511 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
512 (match_operand:DI 1 "x86_64_general_operand" "")))]
513 ""
514{
515 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
516 operands[0] = force_reg (DImode, operands[0]);
517 ix86_compare_op0 = operands[0];
518 ix86_compare_op1 = operands[1];
519 DONE;
520})
521
522(define_expand "cmpsi"
523 [(set (reg:CC FLAGS_REG)
524 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
525 (match_operand:SI 1 "general_operand" "")))]
526 ""
527{
528 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
529 operands[0] = force_reg (SImode, operands[0]);
530 ix86_compare_op0 = operands[0];
531 ix86_compare_op1 = operands[1];
532 DONE;
533})
534
535(define_expand "cmphi"
536 [(set (reg:CC FLAGS_REG)
537 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
538 (match_operand:HI 1 "general_operand" "")))]
539 ""
540{
541 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
542 operands[0] = force_reg (HImode, operands[0]);
543 ix86_compare_op0 = operands[0];
544 ix86_compare_op1 = operands[1];
545 DONE;
546})
547
548(define_expand "cmpqi"
549 [(set (reg:CC FLAGS_REG)
550 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
551 (match_operand:QI 1 "general_operand" "")))]
552 "TARGET_QIMODE_MATH"
553{
554 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
555 operands[0] = force_reg (QImode, operands[0]);
556 ix86_compare_op0 = operands[0];
557 ix86_compare_op1 = operands[1];
558 DONE;
559})
560
561(define_insn "cmpdi_ccno_1_rex64"
562 [(set (reg FLAGS_REG)
563 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
564 (match_operand:DI 1 "const0_operand" "n,n")))]
565 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
566 "@
567 test{q}\t{%0, %0|%0, %0}
568 cmp{q}\t{%1, %0|%0, %1}"
569 [(set_attr "type" "test,icmp")
570 (set_attr "length_immediate" "0,1")
571 (set_attr "mode" "DI")])
572
573(define_insn "*cmpdi_minus_1_rex64"
574 [(set (reg FLAGS_REG)
575 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
576 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
577 (const_int 0)))]
578 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
579 "cmp{q}\t{%1, %0|%0, %1}"
580 [(set_attr "type" "icmp")
581 (set_attr "mode" "DI")])
582
583(define_expand "cmpdi_1_rex64"
584 [(set (reg:CC FLAGS_REG)
585 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
586 (match_operand:DI 1 "general_operand" "")))]
587 "TARGET_64BIT"
588 "")
589
590(define_insn "cmpdi_1_insn_rex64"
591 [(set (reg FLAGS_REG)
592 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
593 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
594 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
595 "cmp{q}\t{%1, %0|%0, %1}"
596 [(set_attr "type" "icmp")
597 (set_attr "mode" "DI")])
598
599
600(define_insn "*cmpsi_ccno_1"
601 [(set (reg FLAGS_REG)
602 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
603 (match_operand:SI 1 "const0_operand" "n,n")))]
604 "ix86_match_ccmode (insn, CCNOmode)"
605 "@
606 test{l}\t{%0, %0|%0, %0}
607 cmp{l}\t{%1, %0|%0, %1}"
608 [(set_attr "type" "test,icmp")
609 (set_attr "length_immediate" "0,1")
610 (set_attr "mode" "SI")])
611
612(define_insn "*cmpsi_minus_1"
613 [(set (reg FLAGS_REG)
614 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
615 (match_operand:SI 1 "general_operand" "ri,mr"))
616 (const_int 0)))]
617 "ix86_match_ccmode (insn, CCGOCmode)"
618 "cmp{l}\t{%1, %0|%0, %1}"
619 [(set_attr "type" "icmp")
620 (set_attr "mode" "SI")])
621
622(define_expand "cmpsi_1"
623 [(set (reg:CC FLAGS_REG)
624 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625 (match_operand:SI 1 "general_operand" "ri,mr")))]
626 ""
627 "")
628
629(define_insn "*cmpsi_1_insn"
630 [(set (reg FLAGS_REG)
631 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632 (match_operand:SI 1 "general_operand" "ri,mr")))]
633 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
634 && ix86_match_ccmode (insn, CCmode)"
635 "cmp{l}\t{%1, %0|%0, %1}"
636 [(set_attr "type" "icmp")
637 (set_attr "mode" "SI")])
638
639(define_insn "*cmphi_ccno_1"
640 [(set (reg FLAGS_REG)
641 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
642 (match_operand:HI 1 "const0_operand" "n,n")))]
643 "ix86_match_ccmode (insn, CCNOmode)"
644 "@
645 test{w}\t{%0, %0|%0, %0}
646 cmp{w}\t{%1, %0|%0, %1}"
647 [(set_attr "type" "test,icmp")
648 (set_attr "length_immediate" "0,1")
649 (set_attr "mode" "HI")])
650
651(define_insn "*cmphi_minus_1"
652 [(set (reg FLAGS_REG)
653 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
654 (match_operand:HI 1 "general_operand" "ri,mr"))
655 (const_int 0)))]
656 "ix86_match_ccmode (insn, CCGOCmode)"
657 "cmp{w}\t{%1, %0|%0, %1}"
658 [(set_attr "type" "icmp")
659 (set_attr "mode" "HI")])
660
661(define_insn "*cmphi_1"
662 [(set (reg FLAGS_REG)
663 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
664 (match_operand:HI 1 "general_operand" "ri,mr")))]
665 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
666 && ix86_match_ccmode (insn, CCmode)"
667 "cmp{w}\t{%1, %0|%0, %1}"
668 [(set_attr "type" "icmp")
669 (set_attr "mode" "HI")])
670
671(define_insn "*cmpqi_ccno_1"
672 [(set (reg FLAGS_REG)
673 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
674 (match_operand:QI 1 "const0_operand" "n,n")))]
675 "ix86_match_ccmode (insn, CCNOmode)"
676 "@
677 test{b}\t{%0, %0|%0, %0}
678 cmp{b}\t{$0, %0|%0, 0}"
679 [(set_attr "type" "test,icmp")
680 (set_attr "length_immediate" "0,1")
681 (set_attr "mode" "QI")])
682
683(define_insn "*cmpqi_1"
684 [(set (reg FLAGS_REG)
685 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
686 (match_operand:QI 1 "general_operand" "qi,mq")))]
687 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
688 && ix86_match_ccmode (insn, CCmode)"
689 "cmp{b}\t{%1, %0|%0, %1}"
690 [(set_attr "type" "icmp")
691 (set_attr "mode" "QI")])
692
693(define_insn "*cmpqi_minus_1"
694 [(set (reg FLAGS_REG)
695 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
696 (match_operand:QI 1 "general_operand" "qi,mq"))
697 (const_int 0)))]
698 "ix86_match_ccmode (insn, CCGOCmode)"
699 "cmp{b}\t{%1, %0|%0, %1}"
700 [(set_attr "type" "icmp")
701 (set_attr "mode" "QI")])
702
703(define_insn "*cmpqi_ext_1"
704 [(set (reg FLAGS_REG)
705 (compare
706 (match_operand:QI 0 "general_operand" "Qm")
707 (subreg:QI
708 (zero_extract:SI
709 (match_operand 1 "ext_register_operand" "Q")
710 (const_int 8)
711 (const_int 8)) 0)))]
712 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
713 "cmp{b}\t{%h1, %0|%0, %h1}"
714 [(set_attr "type" "icmp")
715 (set_attr "mode" "QI")])
716
717(define_insn "*cmpqi_ext_1_rex64"
718 [(set (reg FLAGS_REG)
719 (compare
720 (match_operand:QI 0 "register_operand" "Q")
721 (subreg:QI
722 (zero_extract:SI
723 (match_operand 1 "ext_register_operand" "Q")
724 (const_int 8)
725 (const_int 8)) 0)))]
726 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
727 "cmp{b}\t{%h1, %0|%0, %h1}"
728 [(set_attr "type" "icmp")
729 (set_attr "mode" "QI")])
730
731(define_insn "*cmpqi_ext_2"
732 [(set (reg FLAGS_REG)
733 (compare
734 (subreg:QI
735 (zero_extract:SI
736 (match_operand 0 "ext_register_operand" "Q")
737 (const_int 8)
738 (const_int 8)) 0)
739 (match_operand:QI 1 "const0_operand" "n")))]
740 "ix86_match_ccmode (insn, CCNOmode)"
741 "test{b}\t%h0, %h0"
742 [(set_attr "type" "test")
743 (set_attr "length_immediate" "0")
744 (set_attr "mode" "QI")])
745
746(define_expand "cmpqi_ext_3"
747 [(set (reg:CC FLAGS_REG)
748 (compare:CC
749 (subreg:QI
750 (zero_extract:SI
751 (match_operand 0 "ext_register_operand" "")
752 (const_int 8)
753 (const_int 8)) 0)
754 (match_operand:QI 1 "general_operand" "")))]
755 ""
756 "")
757
758(define_insn "cmpqi_ext_3_insn"
759 [(set (reg FLAGS_REG)
760 (compare
761 (subreg:QI
762 (zero_extract:SI
763 (match_operand 0 "ext_register_operand" "Q")
764 (const_int 8)
765 (const_int 8)) 0)
766 (match_operand:QI 1 "general_operand" "Qmn")))]
767 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
768 "cmp{b}\t{%1, %h0|%h0, %1}"
769 [(set_attr "type" "icmp")
770 (set_attr "mode" "QI")])
771
772(define_insn "cmpqi_ext_3_insn_rex64"
773 [(set (reg FLAGS_REG)
774 (compare
775 (subreg:QI
776 (zero_extract:SI
777 (match_operand 0 "ext_register_operand" "Q")
778 (const_int 8)
779 (const_int 8)) 0)
780 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
781 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
782 "cmp{b}\t{%1, %h0|%h0, %1}"
783 [(set_attr "type" "icmp")
784 (set_attr "mode" "QI")])
785
786(define_insn "*cmpqi_ext_4"
787 [(set (reg FLAGS_REG)
788 (compare
789 (subreg:QI
790 (zero_extract:SI
791 (match_operand 0 "ext_register_operand" "Q")
792 (const_int 8)
793 (const_int 8)) 0)
794 (subreg:QI
795 (zero_extract:SI
796 (match_operand 1 "ext_register_operand" "Q")
797 (const_int 8)
798 (const_int 8)) 0)))]
799 "ix86_match_ccmode (insn, CCmode)"
800 "cmp{b}\t{%h1, %h0|%h0, %h1}"
801 [(set_attr "type" "icmp")
802 (set_attr "mode" "QI")])
803
804;; These implement float point compares.
805;; %%% See if we can get away with VOIDmode operands on the actual insns,
806;; which would allow mix and match FP modes on the compares. Which is what
807;; the old patterns did, but with many more of them.
808
809(define_expand "cmpxf"
810 [(set (reg:CC FLAGS_REG)
811 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
812 (match_operand:XF 1 "nonmemory_operand" "")))]
813 "TARGET_80387"
814{
815 ix86_compare_op0 = operands[0];
816 ix86_compare_op1 = operands[1];
817 DONE;
818})
819
820(define_expand "cmpdf"
821 [(set (reg:CC FLAGS_REG)
822 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
823 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
824 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
825{
826 ix86_compare_op0 = operands[0];
827 ix86_compare_op1 = operands[1];
828 DONE;
829})
830
831(define_expand "cmpsf"
832 [(set (reg:CC FLAGS_REG)
833 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
834 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
835 "TARGET_80387 || TARGET_SSE_MATH"
836{
837 ix86_compare_op0 = operands[0];
838 ix86_compare_op1 = operands[1];
839 DONE;
840})
841
842;; FP compares, step 1:
843;; Set the FP condition codes.
844;;
845;; CCFPmode compare with exceptions
846;; CCFPUmode compare with no exceptions
847
848;; We may not use "#" to split and emit these, since the REG_DEAD notes
849;; used to manage the reg stack popping would not be preserved.
850
851(define_insn "*cmpfp_0"
852 [(set (match_operand:HI 0 "register_operand" "=a")
853 (unspec:HI
854 [(compare:CCFP
855 (match_operand 1 "register_operand" "f")
856 (match_operand 2 "const0_operand" "X"))]
857 UNSPEC_FNSTSW))]
858 "TARGET_80387
859 && FLOAT_MODE_P (GET_MODE (operands[1]))
860 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
861 "* return output_fp_compare (insn, operands, 0, 0);"
862 [(set_attr "type" "multi")
863 (set_attr "unit" "i387")
864 (set (attr "mode")
865 (cond [(match_operand:SF 1 "" "")
866 (const_string "SF")
867 (match_operand:DF 1 "" "")
868 (const_string "DF")
869 ]
870 (const_string "XF")))])
871
872(define_insn "*cmpfp_sf"
873 [(set (match_operand:HI 0 "register_operand" "=a")
874 (unspec:HI
875 [(compare:CCFP
876 (match_operand:SF 1 "register_operand" "f")
877 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
878 UNSPEC_FNSTSW))]
879 "TARGET_80387"
880 "* return output_fp_compare (insn, operands, 0, 0);"
881 [(set_attr "type" "multi")
882 (set_attr "unit" "i387")
883 (set_attr "mode" "SF")])
884
885(define_insn "*cmpfp_df"
886 [(set (match_operand:HI 0 "register_operand" "=a")
887 (unspec:HI
888 [(compare:CCFP
889 (match_operand:DF 1 "register_operand" "f")
890 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
891 UNSPEC_FNSTSW))]
892 "TARGET_80387"
893 "* return output_fp_compare (insn, operands, 0, 0);"
894 [(set_attr "type" "multi")
895 (set_attr "unit" "i387")
896 (set_attr "mode" "DF")])
897
898(define_insn "*cmpfp_xf"
899 [(set (match_operand:HI 0 "register_operand" "=a")
900 (unspec:HI
901 [(compare:CCFP
902 (match_operand:XF 1 "register_operand" "f")
903 (match_operand:XF 2 "register_operand" "f"))]
904 UNSPEC_FNSTSW))]
905 "TARGET_80387"
906 "* return output_fp_compare (insn, operands, 0, 0);"
907 [(set_attr "type" "multi")
908 (set_attr "unit" "i387")
909 (set_attr "mode" "XF")])
910
911(define_insn "*cmpfp_u"
912 [(set (match_operand:HI 0 "register_operand" "=a")
913 (unspec:HI
914 [(compare:CCFPU
915 (match_operand 1 "register_operand" "f")
916 (match_operand 2 "register_operand" "f"))]
917 UNSPEC_FNSTSW))]
918 "TARGET_80387
919 && FLOAT_MODE_P (GET_MODE (operands[1]))
920 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
921 "* return output_fp_compare (insn, operands, 0, 1);"
922 [(set_attr "type" "multi")
923 (set_attr "unit" "i387")
924 (set (attr "mode")
925 (cond [(match_operand:SF 1 "" "")
926 (const_string "SF")
927 (match_operand:DF 1 "" "")
928 (const_string "DF")
929 ]
930 (const_string "XF")))])
931
932(define_insn "*cmpfp_<mode>"
933 [(set (match_operand:HI 0 "register_operand" "=a")
934 (unspec:HI
935 [(compare:CCFP
936 (match_operand 1 "register_operand" "f")
937 (match_operator 3 "float_operator"
938 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
939 UNSPEC_FNSTSW))]
940 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
941 && FLOAT_MODE_P (GET_MODE (operands[1]))
942 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
943 "* return output_fp_compare (insn, operands, 0, 0);"
944 [(set_attr "type" "multi")
945 (set_attr "unit" "i387")
946 (set_attr "fp_int_src" "true")
947 (set_attr "mode" "<MODE>")])
948
949;; FP compares, step 2
950;; Move the fpsw to ax.
951
952(define_insn "x86_fnstsw_1"
953 [(set (match_operand:HI 0 "register_operand" "=a")
954 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
955 "TARGET_80387"
956 "fnstsw\t%0"
957 [(set_attr "length" "2")
958 (set_attr "mode" "SI")
959 (set_attr "unit" "i387")])
960
961;; FP compares, step 3
962;; Get ax into flags, general case.
963
964(define_insn "x86_sahf_1"
965 [(set (reg:CC FLAGS_REG)
966 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
967 "!TARGET_64BIT"
968 "sahf"
969 [(set_attr "length" "1")
970 (set_attr "athlon_decode" "vector")
425 fmov,fcmp,fsgn,
426 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427 mmx,mmxmov,mmxcmp,mmxcvt")
428 (match_operand 2 "memory_operand" ""))
429 (const_string "load")
430 (and (eq_attr "type" "icmov")
431 (match_operand 3 "memory_operand" ""))
432 (const_string "load")
433 ]
434 (const_string "none")))
435
436;; Indicates if an instruction has both an immediate and a displacement.
437
438(define_attr "imm_disp" "false,true,unknown"
439 (cond [(eq_attr "type" "other,multi")
440 (const_string "unknown")
441 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442 (and (match_operand 0 "memory_displacement_operand" "")
443 (match_operand 1 "immediate_operand" "")))
444 (const_string "true")
445 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446 (and (match_operand 0 "memory_displacement_operand" "")
447 (match_operand 2 "immediate_operand" "")))
448 (const_string "true")
449 ]
450 (const_string "false")))
451
452;; Indicates if an FP operation has an integer source.
453
454(define_attr "fp_int_src" "false,true"
455 (const_string "false"))
456
457;; Defines rounding mode of an FP operation.
458
459(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460 (const_string "any"))
461
462;; Describe a user's asm statement.
463(define_asm_attributes
464 [(set_attr "length" "128")
465 (set_attr "type" "multi")])
466
467;; All x87 floating point modes
468(define_mode_macro X87MODEF [SF DF XF])
469
470;; All integer modes handled by x87 fisttp operator.
471(define_mode_macro X87MODEI [HI SI DI])
472
473;; All integer modes handled by integer x87 operators.
474(define_mode_macro X87MODEI12 [HI SI])
475
476;; All SSE floating point modes
477(define_mode_macro SSEMODEF [SF DF])
478
479;; All integer modes handled by SSE cvtts?2si* operators.
480(define_mode_macro SSEMODEI24 [SI DI])
481
482
483;; Scheduling descriptions
484
485(include "pentium.md")
486(include "ppro.md")
487(include "k6.md")
488(include "athlon.md")
489(include "geode.md")
490
491
492;; Operand and operator predicates and constraints
493
494(include "predicates.md")
495(include "constraints.md")
496
497
498;; Compare instructions.
499
500;; All compare insns have expanders that save the operands away without
501;; actually generating RTL. The bCOND or sCOND (emitted immediately
502;; after the cmp) will actually emit the cmpM.
503
504(define_expand "cmpti"
505 [(set (reg:CC FLAGS_REG)
506 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507 (match_operand:TI 1 "x86_64_general_operand" "")))]
508 "TARGET_64BIT"
509{
510 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
511 operands[0] = force_reg (TImode, operands[0]);
512 ix86_compare_op0 = operands[0];
513 ix86_compare_op1 = operands[1];
514 DONE;
515})
516
517(define_expand "cmpdi"
518 [(set (reg:CC FLAGS_REG)
519 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520 (match_operand:DI 1 "x86_64_general_operand" "")))]
521 ""
522{
523 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
524 operands[0] = force_reg (DImode, operands[0]);
525 ix86_compare_op0 = operands[0];
526 ix86_compare_op1 = operands[1];
527 DONE;
528})
529
530(define_expand "cmpsi"
531 [(set (reg:CC FLAGS_REG)
532 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533 (match_operand:SI 1 "general_operand" "")))]
534 ""
535{
536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
537 operands[0] = force_reg (SImode, operands[0]);
538 ix86_compare_op0 = operands[0];
539 ix86_compare_op1 = operands[1];
540 DONE;
541})
542
543(define_expand "cmphi"
544 [(set (reg:CC FLAGS_REG)
545 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546 (match_operand:HI 1 "general_operand" "")))]
547 ""
548{
549 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
550 operands[0] = force_reg (HImode, operands[0]);
551 ix86_compare_op0 = operands[0];
552 ix86_compare_op1 = operands[1];
553 DONE;
554})
555
556(define_expand "cmpqi"
557 [(set (reg:CC FLAGS_REG)
558 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559 (match_operand:QI 1 "general_operand" "")))]
560 "TARGET_QIMODE_MATH"
561{
562 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
563 operands[0] = force_reg (QImode, operands[0]);
564 ix86_compare_op0 = operands[0];
565 ix86_compare_op1 = operands[1];
566 DONE;
567})
568
569(define_insn "cmpdi_ccno_1_rex64"
570 [(set (reg FLAGS_REG)
571 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572 (match_operand:DI 1 "const0_operand" "n,n")))]
573 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
574 "@
575 test{q}\t{%0, %0|%0, %0}
576 cmp{q}\t{%1, %0|%0, %1}"
577 [(set_attr "type" "test,icmp")
578 (set_attr "length_immediate" "0,1")
579 (set_attr "mode" "DI")])
580
581(define_insn "*cmpdi_minus_1_rex64"
582 [(set (reg FLAGS_REG)
583 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
585 (const_int 0)))]
586 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587 "cmp{q}\t{%1, %0|%0, %1}"
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "DI")])
590
591(define_expand "cmpdi_1_rex64"
592 [(set (reg:CC FLAGS_REG)
593 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594 (match_operand:DI 1 "general_operand" "")))]
595 "TARGET_64BIT"
596 "")
597
598(define_insn "cmpdi_1_insn_rex64"
599 [(set (reg FLAGS_REG)
600 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603 "cmp{q}\t{%1, %0|%0, %1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "DI")])
606
607
608(define_insn "*cmpsi_ccno_1"
609 [(set (reg FLAGS_REG)
610 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611 (match_operand:SI 1 "const0_operand" "n,n")))]
612 "ix86_match_ccmode (insn, CCNOmode)"
613 "@
614 test{l}\t{%0, %0|%0, %0}
615 cmp{l}\t{%1, %0|%0, %1}"
616 [(set_attr "type" "test,icmp")
617 (set_attr "length_immediate" "0,1")
618 (set_attr "mode" "SI")])
619
620(define_insn "*cmpsi_minus_1"
621 [(set (reg FLAGS_REG)
622 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623 (match_operand:SI 1 "general_operand" "ri,mr"))
624 (const_int 0)))]
625 "ix86_match_ccmode (insn, CCGOCmode)"
626 "cmp{l}\t{%1, %0|%0, %1}"
627 [(set_attr "type" "icmp")
628 (set_attr "mode" "SI")])
629
630(define_expand "cmpsi_1"
631 [(set (reg:CC FLAGS_REG)
632 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633 (match_operand:SI 1 "general_operand" "ri,mr")))]
634 ""
635 "")
636
637(define_insn "*cmpsi_1_insn"
638 [(set (reg FLAGS_REG)
639 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640 (match_operand:SI 1 "general_operand" "ri,mr")))]
641 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
642 && ix86_match_ccmode (insn, CCmode)"
643 "cmp{l}\t{%1, %0|%0, %1}"
644 [(set_attr "type" "icmp")
645 (set_attr "mode" "SI")])
646
647(define_insn "*cmphi_ccno_1"
648 [(set (reg FLAGS_REG)
649 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650 (match_operand:HI 1 "const0_operand" "n,n")))]
651 "ix86_match_ccmode (insn, CCNOmode)"
652 "@
653 test{w}\t{%0, %0|%0, %0}
654 cmp{w}\t{%1, %0|%0, %1}"
655 [(set_attr "type" "test,icmp")
656 (set_attr "length_immediate" "0,1")
657 (set_attr "mode" "HI")])
658
659(define_insn "*cmphi_minus_1"
660 [(set (reg FLAGS_REG)
661 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662 (match_operand:HI 1 "general_operand" "ri,mr"))
663 (const_int 0)))]
664 "ix86_match_ccmode (insn, CCGOCmode)"
665 "cmp{w}\t{%1, %0|%0, %1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "HI")])
668
669(define_insn "*cmphi_1"
670 [(set (reg FLAGS_REG)
671 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672 (match_operand:HI 1 "general_operand" "ri,mr")))]
673 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
674 && ix86_match_ccmode (insn, CCmode)"
675 "cmp{w}\t{%1, %0|%0, %1}"
676 [(set_attr "type" "icmp")
677 (set_attr "mode" "HI")])
678
679(define_insn "*cmpqi_ccno_1"
680 [(set (reg FLAGS_REG)
681 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682 (match_operand:QI 1 "const0_operand" "n,n")))]
683 "ix86_match_ccmode (insn, CCNOmode)"
684 "@
685 test{b}\t{%0, %0|%0, %0}
686 cmp{b}\t{$0, %0|%0, 0}"
687 [(set_attr "type" "test,icmp")
688 (set_attr "length_immediate" "0,1")
689 (set_attr "mode" "QI")])
690
691(define_insn "*cmpqi_1"
692 [(set (reg FLAGS_REG)
693 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694 (match_operand:QI 1 "general_operand" "qi,mq")))]
695 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
696 && ix86_match_ccmode (insn, CCmode)"
697 "cmp{b}\t{%1, %0|%0, %1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "QI")])
700
701(define_insn "*cmpqi_minus_1"
702 [(set (reg FLAGS_REG)
703 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704 (match_operand:QI 1 "general_operand" "qi,mq"))
705 (const_int 0)))]
706 "ix86_match_ccmode (insn, CCGOCmode)"
707 "cmp{b}\t{%1, %0|%0, %1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "QI")])
710
711(define_insn "*cmpqi_ext_1"
712 [(set (reg FLAGS_REG)
713 (compare
714 (match_operand:QI 0 "general_operand" "Qm")
715 (subreg:QI
716 (zero_extract:SI
717 (match_operand 1 "ext_register_operand" "Q")
718 (const_int 8)
719 (const_int 8)) 0)))]
720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%h1, %0|%0, %h1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
724
725(define_insn "*cmpqi_ext_1_rex64"
726 [(set (reg FLAGS_REG)
727 (compare
728 (match_operand:QI 0 "register_operand" "Q")
729 (subreg:QI
730 (zero_extract:SI
731 (match_operand 1 "ext_register_operand" "Q")
732 (const_int 8)
733 (const_int 8)) 0)))]
734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735 "cmp{b}\t{%h1, %0|%0, %h1}"
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "QI")])
738
739(define_insn "*cmpqi_ext_2"
740 [(set (reg FLAGS_REG)
741 (compare
742 (subreg:QI
743 (zero_extract:SI
744 (match_operand 0 "ext_register_operand" "Q")
745 (const_int 8)
746 (const_int 8)) 0)
747 (match_operand:QI 1 "const0_operand" "n")))]
748 "ix86_match_ccmode (insn, CCNOmode)"
749 "test{b}\t%h0, %h0"
750 [(set_attr "type" "test")
751 (set_attr "length_immediate" "0")
752 (set_attr "mode" "QI")])
753
754(define_expand "cmpqi_ext_3"
755 [(set (reg:CC FLAGS_REG)
756 (compare:CC
757 (subreg:QI
758 (zero_extract:SI
759 (match_operand 0 "ext_register_operand" "")
760 (const_int 8)
761 (const_int 8)) 0)
762 (match_operand:QI 1 "general_operand" "")))]
763 ""
764 "")
765
766(define_insn "cmpqi_ext_3_insn"
767 [(set (reg FLAGS_REG)
768 (compare
769 (subreg:QI
770 (zero_extract:SI
771 (match_operand 0 "ext_register_operand" "Q")
772 (const_int 8)
773 (const_int 8)) 0)
774 (match_operand:QI 1 "general_operand" "Qmn")))]
775 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776 "cmp{b}\t{%1, %h0|%h0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "QI")])
779
780(define_insn "cmpqi_ext_3_insn_rex64"
781 [(set (reg FLAGS_REG)
782 (compare
783 (subreg:QI
784 (zero_extract:SI
785 (match_operand 0 "ext_register_operand" "Q")
786 (const_int 8)
787 (const_int 8)) 0)
788 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790 "cmp{b}\t{%1, %h0|%h0, %1}"
791 [(set_attr "type" "icmp")
792 (set_attr "mode" "QI")])
793
794(define_insn "*cmpqi_ext_4"
795 [(set (reg FLAGS_REG)
796 (compare
797 (subreg:QI
798 (zero_extract:SI
799 (match_operand 0 "ext_register_operand" "Q")
800 (const_int 8)
801 (const_int 8)) 0)
802 (subreg:QI
803 (zero_extract:SI
804 (match_operand 1 "ext_register_operand" "Q")
805 (const_int 8)
806 (const_int 8)) 0)))]
807 "ix86_match_ccmode (insn, CCmode)"
808 "cmp{b}\t{%h1, %h0|%h0, %h1}"
809 [(set_attr "type" "icmp")
810 (set_attr "mode" "QI")])
811
812;; These implement float point compares.
813;; %%% See if we can get away with VOIDmode operands on the actual insns,
814;; which would allow mix and match FP modes on the compares. Which is what
815;; the old patterns did, but with many more of them.
816
817(define_expand "cmpxf"
818 [(set (reg:CC FLAGS_REG)
819 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820 (match_operand:XF 1 "nonmemory_operand" "")))]
821 "TARGET_80387"
822{
823 ix86_compare_op0 = operands[0];
824 ix86_compare_op1 = operands[1];
825 DONE;
826})
827
828(define_expand "cmpdf"
829 [(set (reg:CC FLAGS_REG)
830 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
833{
834 ix86_compare_op0 = operands[0];
835 ix86_compare_op1 = operands[1];
836 DONE;
837})
838
839(define_expand "cmpsf"
840 [(set (reg:CC FLAGS_REG)
841 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843 "TARGET_80387 || TARGET_SSE_MATH"
844{
845 ix86_compare_op0 = operands[0];
846 ix86_compare_op1 = operands[1];
847 DONE;
848})
849
850;; FP compares, step 1:
851;; Set the FP condition codes.
852;;
853;; CCFPmode compare with exceptions
854;; CCFPUmode compare with no exceptions
855
856;; We may not use "#" to split and emit these, since the REG_DEAD notes
857;; used to manage the reg stack popping would not be preserved.
858
859(define_insn "*cmpfp_0"
860 [(set (match_operand:HI 0 "register_operand" "=a")
861 (unspec:HI
862 [(compare:CCFP
863 (match_operand 1 "register_operand" "f")
864 (match_operand 2 "const0_operand" "X"))]
865 UNSPEC_FNSTSW))]
866 "TARGET_80387
867 && FLOAT_MODE_P (GET_MODE (operands[1]))
868 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869 "* return output_fp_compare (insn, operands, 0, 0);"
870 [(set_attr "type" "multi")
871 (set_attr "unit" "i387")
872 (set (attr "mode")
873 (cond [(match_operand:SF 1 "" "")
874 (const_string "SF")
875 (match_operand:DF 1 "" "")
876 (const_string "DF")
877 ]
878 (const_string "XF")))])
879
880(define_insn "*cmpfp_sf"
881 [(set (match_operand:HI 0 "register_operand" "=a")
882 (unspec:HI
883 [(compare:CCFP
884 (match_operand:SF 1 "register_operand" "f")
885 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
886 UNSPEC_FNSTSW))]
887 "TARGET_80387"
888 "* return output_fp_compare (insn, operands, 0, 0);"
889 [(set_attr "type" "multi")
890 (set_attr "unit" "i387")
891 (set_attr "mode" "SF")])
892
893(define_insn "*cmpfp_df"
894 [(set (match_operand:HI 0 "register_operand" "=a")
895 (unspec:HI
896 [(compare:CCFP
897 (match_operand:DF 1 "register_operand" "f")
898 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
899 UNSPEC_FNSTSW))]
900 "TARGET_80387"
901 "* return output_fp_compare (insn, operands, 0, 0);"
902 [(set_attr "type" "multi")
903 (set_attr "unit" "i387")
904 (set_attr "mode" "DF")])
905
906(define_insn "*cmpfp_xf"
907 [(set (match_operand:HI 0 "register_operand" "=a")
908 (unspec:HI
909 [(compare:CCFP
910 (match_operand:XF 1 "register_operand" "f")
911 (match_operand:XF 2 "register_operand" "f"))]
912 UNSPEC_FNSTSW))]
913 "TARGET_80387"
914 "* return output_fp_compare (insn, operands, 0, 0);"
915 [(set_attr "type" "multi")
916 (set_attr "unit" "i387")
917 (set_attr "mode" "XF")])
918
919(define_insn "*cmpfp_u"
920 [(set (match_operand:HI 0 "register_operand" "=a")
921 (unspec:HI
922 [(compare:CCFPU
923 (match_operand 1 "register_operand" "f")
924 (match_operand 2 "register_operand" "f"))]
925 UNSPEC_FNSTSW))]
926 "TARGET_80387
927 && FLOAT_MODE_P (GET_MODE (operands[1]))
928 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929 "* return output_fp_compare (insn, operands, 0, 1);"
930 [(set_attr "type" "multi")
931 (set_attr "unit" "i387")
932 (set (attr "mode")
933 (cond [(match_operand:SF 1 "" "")
934 (const_string "SF")
935 (match_operand:DF 1 "" "")
936 (const_string "DF")
937 ]
938 (const_string "XF")))])
939
940(define_insn "*cmpfp_<mode>"
941 [(set (match_operand:HI 0 "register_operand" "=a")
942 (unspec:HI
943 [(compare:CCFP
944 (match_operand 1 "register_operand" "f")
945 (match_operator 3 "float_operator"
946 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
947 UNSPEC_FNSTSW))]
948 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949 && FLOAT_MODE_P (GET_MODE (operands[1]))
950 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951 "* return output_fp_compare (insn, operands, 0, 0);"
952 [(set_attr "type" "multi")
953 (set_attr "unit" "i387")
954 (set_attr "fp_int_src" "true")
955 (set_attr "mode" "<MODE>")])
956
957;; FP compares, step 2
958;; Move the fpsw to ax.
959
960(define_insn "x86_fnstsw_1"
961 [(set (match_operand:HI 0 "register_operand" "=a")
962 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963 "TARGET_80387"
964 "fnstsw\t%0"
965 [(set_attr "length" "2")
966 (set_attr "mode" "SI")
967 (set_attr "unit" "i387")])
968
969;; FP compares, step 3
970;; Get ax into flags, general case.
971
972(define_insn "x86_sahf_1"
973 [(set (reg:CC FLAGS_REG)
974 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975 "!TARGET_64BIT"
976 "sahf"
977 [(set_attr "length" "1")
978 (set_attr "athlon_decode" "vector")
979 (set_attr "amdfam10_decode" "direct")
971 (set_attr "mode" "SI")])
972
973;; Pentium Pro can do steps 1 through 3 in one go.
980 (set_attr "mode" "SI")])
981
982;; Pentium Pro can do steps 1 through 3 in one go.
974
983;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
975(define_insn "*cmpfp_i_mixed"
976 [(set (reg:CCFP FLAGS_REG)
977 (compare:CCFP (match_operand 0 "register_operand" "f,x")
978 (match_operand 1 "nonimmediate_operand" "f,xm")))]
979 "TARGET_MIX_SSE_I387
980 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982 "* return output_fp_compare (insn, operands, 1, 0);"
983 [(set_attr "type" "fcmp,ssecomi")
984 (set (attr "mode")
985 (if_then_else (match_operand:SF 1 "" "")
986 (const_string "SF")
987 (const_string "DF")))
984(define_insn "*cmpfp_i_mixed"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "f,x")
987 (match_operand 1 "nonimmediate_operand" "f,xm")))]
988 "TARGET_MIX_SSE_I387
989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991 "* return output_fp_compare (insn, operands, 1, 0);"
992 [(set_attr "type" "fcmp,ssecomi")
993 (set (attr "mode")
994 (if_then_else (match_operand:SF 1 "" "")
995 (const_string "SF")
996 (const_string "DF")))
988 (set_attr "athlon_decode" "vector")])
997 (set_attr "athlon_decode" "vector")
998 (set_attr "amdfam10_decode" "direct")])
989
990(define_insn "*cmpfp_i_sse"
991 [(set (reg:CCFP FLAGS_REG)
992 (compare:CCFP (match_operand 0 "register_operand" "x")
993 (match_operand 1 "nonimmediate_operand" "xm")))]
994 "TARGET_SSE_MATH
995 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
996 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
997 "* return output_fp_compare (insn, operands, 1, 0);"
998 [(set_attr "type" "ssecomi")
999 (set (attr "mode")
1000 (if_then_else (match_operand:SF 1 "" "")
1001 (const_string "SF")
1002 (const_string "DF")))
999
1000(define_insn "*cmpfp_i_sse"
1001 [(set (reg:CCFP FLAGS_REG)
1002 (compare:CCFP (match_operand 0 "register_operand" "x")
1003 (match_operand 1 "nonimmediate_operand" "xm")))]
1004 "TARGET_SSE_MATH
1005 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "ssecomi")
1009 (set (attr "mode")
1010 (if_then_else (match_operand:SF 1 "" "")
1011 (const_string "SF")
1012 (const_string "DF")))
1003 (set_attr "athlon_decode" "vector")])
1013 (set_attr "athlon_decode" "vector")
1014 (set_attr "amdfam10_decode" "direct")])
1004
1005(define_insn "*cmpfp_i_i387"
1006 [(set (reg:CCFP FLAGS_REG)
1007 (compare:CCFP (match_operand 0 "register_operand" "f")
1008 (match_operand 1 "register_operand" "f")))]
1009 "TARGET_80387 && TARGET_CMOVE
1010 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1011 && FLOAT_MODE_P (GET_MODE (operands[0]))
1012 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1013 "* return output_fp_compare (insn, operands, 1, 0);"
1014 [(set_attr "type" "fcmp")
1015 (set (attr "mode")
1016 (cond [(match_operand:SF 1 "" "")
1017 (const_string "SF")
1018 (match_operand:DF 1 "" "")
1019 (const_string "DF")
1020 ]
1021 (const_string "XF")))
1015
1016(define_insn "*cmpfp_i_i387"
1017 [(set (reg:CCFP FLAGS_REG)
1018 (compare:CCFP (match_operand 0 "register_operand" "f")
1019 (match_operand 1 "register_operand" "f")))]
1020 "TARGET_80387 && TARGET_CMOVE
1021 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1022 && FLOAT_MODE_P (GET_MODE (operands[0]))
1023 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024 "* return output_fp_compare (insn, operands, 1, 0);"
1025 [(set_attr "type" "fcmp")
1026 (set (attr "mode")
1027 (cond [(match_operand:SF 1 "" "")
1028 (const_string "SF")
1029 (match_operand:DF 1 "" "")
1030 (const_string "DF")
1031 ]
1032 (const_string "XF")))
1022 (set_attr "athlon_decode" "vector")])
1033 (set_attr "athlon_decode" "vector")
1034 (set_attr "amdfam10_decode" "direct")])
1023
1024(define_insn "*cmpfp_iu_mixed"
1025 [(set (reg:CCFPU FLAGS_REG)
1026 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1027 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1028 "TARGET_MIX_SSE_I387
1029 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031 "* return output_fp_compare (insn, operands, 1, 1);"
1032 [(set_attr "type" "fcmp,ssecomi")
1033 (set (attr "mode")
1034 (if_then_else (match_operand:SF 1 "" "")
1035 (const_string "SF")
1036 (const_string "DF")))
1035
1036(define_insn "*cmpfp_iu_mixed"
1037 [(set (reg:CCFPU FLAGS_REG)
1038 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1039 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1040 "TARGET_MIX_SSE_I387
1041 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1042 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1043 "* return output_fp_compare (insn, operands, 1, 1);"
1044 [(set_attr "type" "fcmp,ssecomi")
1045 (set (attr "mode")
1046 (if_then_else (match_operand:SF 1 "" "")
1047 (const_string "SF")
1048 (const_string "DF")))
1037 (set_attr "athlon_decode" "vector")])
1049 (set_attr "athlon_decode" "vector")
1050 (set_attr "amdfam10_decode" "direct")])
1038
1039(define_insn "*cmpfp_iu_sse"
1040 [(set (reg:CCFPU FLAGS_REG)
1041 (compare:CCFPU (match_operand 0 "register_operand" "x")
1042 (match_operand 1 "nonimmediate_operand" "xm")))]
1043 "TARGET_SSE_MATH
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" "ssecomi")
1048 (set (attr "mode")
1049 (if_then_else (match_operand:SF 1 "" "")
1050 (const_string "SF")
1051 (const_string "DF")))
1051
1052(define_insn "*cmpfp_iu_sse"
1053 [(set (reg:CCFPU FLAGS_REG)
1054 (compare:CCFPU (match_operand 0 "register_operand" "x")
1055 (match_operand 1 "nonimmediate_operand" "xm")))]
1056 "TARGET_SSE_MATH
1057 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1058 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1059 "* return output_fp_compare (insn, operands, 1, 1);"
1060 [(set_attr "type" "ssecomi")
1061 (set (attr "mode")
1062 (if_then_else (match_operand:SF 1 "" "")
1063 (const_string "SF")
1064 (const_string "DF")))
1052 (set_attr "athlon_decode" "vector")])
1065 (set_attr "athlon_decode" "vector")
1066 (set_attr "amdfam10_decode" "direct")])
1053
1054(define_insn "*cmpfp_iu_387"
1055 [(set (reg:CCFPU FLAGS_REG)
1056 (compare:CCFPU (match_operand 0 "register_operand" "f")
1057 (match_operand 1 "register_operand" "f")))]
1058 "TARGET_80387 && TARGET_CMOVE
1059 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1060 && FLOAT_MODE_P (GET_MODE (operands[0]))
1061 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1062 "* return output_fp_compare (insn, operands, 1, 1);"
1063 [(set_attr "type" "fcmp")
1064 (set (attr "mode")
1065 (cond [(match_operand:SF 1 "" "")
1066 (const_string "SF")
1067 (match_operand:DF 1 "" "")
1068 (const_string "DF")
1069 ]
1070 (const_string "XF")))
1067
1068(define_insn "*cmpfp_iu_387"
1069 [(set (reg:CCFPU FLAGS_REG)
1070 (compare:CCFPU (match_operand 0 "register_operand" "f")
1071 (match_operand 1 "register_operand" "f")))]
1072 "TARGET_80387 && TARGET_CMOVE
1073 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1074 && FLOAT_MODE_P (GET_MODE (operands[0]))
1075 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1076 "* return output_fp_compare (insn, operands, 1, 1);"
1077 [(set_attr "type" "fcmp")
1078 (set (attr "mode")
1079 (cond [(match_operand:SF 1 "" "")
1080 (const_string "SF")
1081 (match_operand:DF 1 "" "")
1082 (const_string "DF")
1083 ]
1084 (const_string "XF")))
1071 (set_attr "athlon_decode" "vector")])
1085 (set_attr "athlon_decode" "vector")
1086 (set_attr "amdfam10_decode" "direct")])
1072
1073;; Move instructions.
1074
1075;; General case of fullword move.
1076
1077(define_expand "movsi"
1078 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1079 (match_operand:SI 1 "general_operand" ""))]
1080 ""
1081 "ix86_expand_move (SImode, operands); DONE;")
1082
1083;; Push/pop instructions. They are separate since autoinc/dec is not a
1084;; general_operand.
1085;;
1086;; %%% We don't use a post-inc memory reference because x86 is not a
1087;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1088;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1089;; targets without our curiosities, and it is just as easy to represent
1090;; this differently.
1091
1092(define_insn "*pushsi2"
1093 [(set (match_operand:SI 0 "push_operand" "=<")
1094 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1095 "!TARGET_64BIT"
1096 "push{l}\t%1"
1097 [(set_attr "type" "push")
1098 (set_attr "mode" "SI")])
1099
1100;; For 64BIT abi we always round up to 8 bytes.
1101(define_insn "*pushsi2_rex64"
1102 [(set (match_operand:SI 0 "push_operand" "=X")
1103 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1104 "TARGET_64BIT"
1105 "push{q}\t%q1"
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1108
1109(define_insn "*pushsi2_prologue"
1110 [(set (match_operand:SI 0 "push_operand" "=<")
1111 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1112 (clobber (mem:BLK (scratch)))]
1113 "!TARGET_64BIT"
1114 "push{l}\t%1"
1115 [(set_attr "type" "push")
1116 (set_attr "mode" "SI")])
1117
1118(define_insn "*popsi1_epilogue"
1119 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1120 (mem:SI (reg:SI SP_REG)))
1121 (set (reg:SI SP_REG)
1122 (plus:SI (reg:SI SP_REG) (const_int 4)))
1123 (clobber (mem:BLK (scratch)))]
1124 "!TARGET_64BIT"
1125 "pop{l}\t%0"
1126 [(set_attr "type" "pop")
1127 (set_attr "mode" "SI")])
1128
1129(define_insn "popsi1"
1130 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1131 (mem:SI (reg:SI SP_REG)))
1132 (set (reg:SI SP_REG)
1133 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1134 "!TARGET_64BIT"
1135 "pop{l}\t%0"
1136 [(set_attr "type" "pop")
1137 (set_attr "mode" "SI")])
1138
1139(define_insn "*movsi_xor"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (match_operand:SI 1 "const0_operand" "i"))
1142 (clobber (reg:CC FLAGS_REG))]
1143 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1144 "xor{l}\t{%0, %0|%0, %0}"
1145 [(set_attr "type" "alu1")
1146 (set_attr "mode" "SI")
1147 (set_attr "length_immediate" "0")])
1148
1149(define_insn "*movsi_or"
1150 [(set (match_operand:SI 0 "register_operand" "=r")
1151 (match_operand:SI 1 "immediate_operand" "i"))
1152 (clobber (reg:CC FLAGS_REG))]
1153 "reload_completed
1154 && operands[1] == constm1_rtx
1155 && (TARGET_PENTIUM || optimize_size)"
1156{
1157 operands[1] = constm1_rtx;
1158 return "or{l}\t{%1, %0|%0, %1}";
1159}
1160 [(set_attr "type" "alu1")
1161 (set_attr "mode" "SI")
1162 (set_attr "length_immediate" "1")])
1163
1164(define_insn "*movsi_1"
1165 [(set (match_operand:SI 0 "nonimmediate_operand"
1166 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1167 (match_operand:SI 1 "general_operand"
1168 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1169 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1170{
1171 switch (get_attr_type (insn))
1172 {
1173 case TYPE_SSELOG1:
1174 if (get_attr_mode (insn) == MODE_TI)
1175 return "pxor\t%0, %0";
1176 return "xorps\t%0, %0";
1177
1178 case TYPE_SSEMOV:
1179 switch (get_attr_mode (insn))
1180 {
1181 case MODE_TI:
1182 return "movdqa\t{%1, %0|%0, %1}";
1183 case MODE_V4SF:
1184 return "movaps\t{%1, %0|%0, %1}";
1185 case MODE_SI:
1186 return "movd\t{%1, %0|%0, %1}";
1187 case MODE_SF:
1188 return "movss\t{%1, %0|%0, %1}";
1189 default:
1190 gcc_unreachable ();
1191 }
1192
1193 case TYPE_MMXADD:
1194 return "pxor\t%0, %0";
1195
1196 case TYPE_MMXMOV:
1197 if (get_attr_mode (insn) == MODE_DI)
1198 return "movq\t{%1, %0|%0, %1}";
1199 return "movd\t{%1, %0|%0, %1}";
1200
1201 case TYPE_LEA:
1202 return "lea{l}\t{%1, %0|%0, %1}";
1203
1204 default:
1205 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1206 return "mov{l}\t{%1, %0|%0, %1}";
1207 }
1208}
1209 [(set (attr "type")
1210 (cond [(eq_attr "alternative" "2")
1211 (const_string "mmxadd")
1212 (eq_attr "alternative" "3,4,5")
1213 (const_string "mmxmov")
1214 (eq_attr "alternative" "6")
1215 (const_string "sselog1")
1216 (eq_attr "alternative" "7,8,9,10,11")
1217 (const_string "ssemov")
1218 (match_operand:DI 1 "pic_32bit_operand" "")
1219 (const_string "lea")
1220 ]
1221 (const_string "imov")))
1222 (set (attr "mode")
1223 (cond [(eq_attr "alternative" "2,3")
1224 (const_string "DI")
1225 (eq_attr "alternative" "6,7")
1226 (if_then_else
1227 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1228 (const_string "V4SF")
1229 (const_string "TI"))
1230 (and (eq_attr "alternative" "8,9,10,11")
1231 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1232 (const_string "SF")
1233 ]
1234 (const_string "SI")))])
1235
1236;; Stores and loads of ax to arbitrary constant address.
1237;; We fake an second form of instruction to force reload to load address
1238;; into register when rax is not available
1239(define_insn "*movabssi_1_rex64"
1240 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1241 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1242 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1243 "@
1244 movabs{l}\t{%1, %P0|%P0, %1}
1245 mov{l}\t{%1, %a0|%a0, %1}"
1246 [(set_attr "type" "imov")
1247 (set_attr "modrm" "0,*")
1248 (set_attr "length_address" "8,0")
1249 (set_attr "length_immediate" "0,*")
1250 (set_attr "memory" "store")
1251 (set_attr "mode" "SI")])
1252
1253(define_insn "*movabssi_2_rex64"
1254 [(set (match_operand:SI 0 "register_operand" "=a,r")
1255 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1256 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1257 "@
1258 movabs{l}\t{%P1, %0|%0, %P1}
1259 mov{l}\t{%a1, %0|%0, %a1}"
1260 [(set_attr "type" "imov")
1261 (set_attr "modrm" "0,*")
1262 (set_attr "length_address" "8,0")
1263 (set_attr "length_immediate" "0")
1264 (set_attr "memory" "load")
1265 (set_attr "mode" "SI")])
1266
1267(define_insn "*swapsi"
1268 [(set (match_operand:SI 0 "register_operand" "+r")
1269 (match_operand:SI 1 "register_operand" "+r"))
1270 (set (match_dup 1)
1271 (match_dup 0))]
1272 ""
1273 "xchg{l}\t%1, %0"
1274 [(set_attr "type" "imov")
1275 (set_attr "mode" "SI")
1276 (set_attr "pent_pair" "np")
1087
1088;; Move instructions.
1089
1090;; General case of fullword move.
1091
1092(define_expand "movsi"
1093 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1094 (match_operand:SI 1 "general_operand" ""))]
1095 ""
1096 "ix86_expand_move (SImode, operands); DONE;")
1097
1098;; Push/pop instructions. They are separate since autoinc/dec is not a
1099;; general_operand.
1100;;
1101;; %%% We don't use a post-inc memory reference because x86 is not a
1102;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1103;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1104;; targets without our curiosities, and it is just as easy to represent
1105;; this differently.
1106
1107(define_insn "*pushsi2"
1108 [(set (match_operand:SI 0 "push_operand" "=<")
1109 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1110 "!TARGET_64BIT"
1111 "push{l}\t%1"
1112 [(set_attr "type" "push")
1113 (set_attr "mode" "SI")])
1114
1115;; For 64BIT abi we always round up to 8 bytes.
1116(define_insn "*pushsi2_rex64"
1117 [(set (match_operand:SI 0 "push_operand" "=X")
1118 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1119 "TARGET_64BIT"
1120 "push{q}\t%q1"
1121 [(set_attr "type" "push")
1122 (set_attr "mode" "SI")])
1123
1124(define_insn "*pushsi2_prologue"
1125 [(set (match_operand:SI 0 "push_operand" "=<")
1126 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1127 (clobber (mem:BLK (scratch)))]
1128 "!TARGET_64BIT"
1129 "push{l}\t%1"
1130 [(set_attr "type" "push")
1131 (set_attr "mode" "SI")])
1132
1133(define_insn "*popsi1_epilogue"
1134 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1135 (mem:SI (reg:SI SP_REG)))
1136 (set (reg:SI SP_REG)
1137 (plus:SI (reg:SI SP_REG) (const_int 4)))
1138 (clobber (mem:BLK (scratch)))]
1139 "!TARGET_64BIT"
1140 "pop{l}\t%0"
1141 [(set_attr "type" "pop")
1142 (set_attr "mode" "SI")])
1143
1144(define_insn "popsi1"
1145 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1146 (mem:SI (reg:SI SP_REG)))
1147 (set (reg:SI SP_REG)
1148 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1149 "!TARGET_64BIT"
1150 "pop{l}\t%0"
1151 [(set_attr "type" "pop")
1152 (set_attr "mode" "SI")])
1153
1154(define_insn "*movsi_xor"
1155 [(set (match_operand:SI 0 "register_operand" "=r")
1156 (match_operand:SI 1 "const0_operand" "i"))
1157 (clobber (reg:CC FLAGS_REG))]
1158 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1159 "xor{l}\t{%0, %0|%0, %0}"
1160 [(set_attr "type" "alu1")
1161 (set_attr "mode" "SI")
1162 (set_attr "length_immediate" "0")])
1163
1164(define_insn "*movsi_or"
1165 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (match_operand:SI 1 "immediate_operand" "i"))
1167 (clobber (reg:CC FLAGS_REG))]
1168 "reload_completed
1169 && operands[1] == constm1_rtx
1170 && (TARGET_PENTIUM || optimize_size)"
1171{
1172 operands[1] = constm1_rtx;
1173 return "or{l}\t{%1, %0|%0, %1}";
1174}
1175 [(set_attr "type" "alu1")
1176 (set_attr "mode" "SI")
1177 (set_attr "length_immediate" "1")])
1178
1179(define_insn "*movsi_1"
1180 [(set (match_operand:SI 0 "nonimmediate_operand"
1181 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1182 (match_operand:SI 1 "general_operand"
1183 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1184 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1185{
1186 switch (get_attr_type (insn))
1187 {
1188 case TYPE_SSELOG1:
1189 if (get_attr_mode (insn) == MODE_TI)
1190 return "pxor\t%0, %0";
1191 return "xorps\t%0, %0";
1192
1193 case TYPE_SSEMOV:
1194 switch (get_attr_mode (insn))
1195 {
1196 case MODE_TI:
1197 return "movdqa\t{%1, %0|%0, %1}";
1198 case MODE_V4SF:
1199 return "movaps\t{%1, %0|%0, %1}";
1200 case MODE_SI:
1201 return "movd\t{%1, %0|%0, %1}";
1202 case MODE_SF:
1203 return "movss\t{%1, %0|%0, %1}";
1204 default:
1205 gcc_unreachable ();
1206 }
1207
1208 case TYPE_MMXADD:
1209 return "pxor\t%0, %0";
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 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1221 return "mov{l}\t{%1, %0|%0, %1}";
1222 }
1223}
1224 [(set (attr "type")
1225 (cond [(eq_attr "alternative" "2")
1226 (const_string "mmxadd")
1227 (eq_attr "alternative" "3,4,5")
1228 (const_string "mmxmov")
1229 (eq_attr "alternative" "6")
1230 (const_string "sselog1")
1231 (eq_attr "alternative" "7,8,9,10,11")
1232 (const_string "ssemov")
1233 (match_operand:DI 1 "pic_32bit_operand" "")
1234 (const_string "lea")
1235 ]
1236 (const_string "imov")))
1237 (set (attr "mode")
1238 (cond [(eq_attr "alternative" "2,3")
1239 (const_string "DI")
1240 (eq_attr "alternative" "6,7")
1241 (if_then_else
1242 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1243 (const_string "V4SF")
1244 (const_string "TI"))
1245 (and (eq_attr "alternative" "8,9,10,11")
1246 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1247 (const_string "SF")
1248 ]
1249 (const_string "SI")))])
1250
1251;; Stores and loads of ax to arbitrary constant address.
1252;; We fake an second form of instruction to force reload to load address
1253;; into register when rax is not available
1254(define_insn "*movabssi_1_rex64"
1255 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1256 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1257 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1258 "@
1259 movabs{l}\t{%1, %P0|%P0, %1}
1260 mov{l}\t{%1, %a0|%a0, %1}"
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" "store")
1266 (set_attr "mode" "SI")])
1267
1268(define_insn "*movabssi_2_rex64"
1269 [(set (match_operand:SI 0 "register_operand" "=a,r")
1270 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1271 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1272 "@
1273 movabs{l}\t{%P1, %0|%0, %P1}
1274 mov{l}\t{%a1, %0|%0, %a1}"
1275 [(set_attr "type" "imov")
1276 (set_attr "modrm" "0,*")
1277 (set_attr "length_address" "8,0")
1278 (set_attr "length_immediate" "0")
1279 (set_attr "memory" "load")
1280 (set_attr "mode" "SI")])
1281
1282(define_insn "*swapsi"
1283 [(set (match_operand:SI 0 "register_operand" "+r")
1284 (match_operand:SI 1 "register_operand" "+r"))
1285 (set (match_dup 1)
1286 (match_dup 0))]
1287 ""
1288 "xchg{l}\t%1, %0"
1289 [(set_attr "type" "imov")
1290 (set_attr "mode" "SI")
1291 (set_attr "pent_pair" "np")
1277 (set_attr "athlon_decode" "vector")])
1292 (set_attr "athlon_decode" "vector")
1293 (set_attr "amdfam10_decode" "double")])
1278
1279(define_expand "movhi"
1280 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1281 (match_operand:HI 1 "general_operand" ""))]
1282 ""
1283 "ix86_expand_move (HImode, operands); DONE;")
1284
1285(define_insn "*pushhi2"
1286 [(set (match_operand:HI 0 "push_operand" "=X")
1287 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1288 "!TARGET_64BIT"
1289 "push{l}\t%k1"
1290 [(set_attr "type" "push")
1291 (set_attr "mode" "SI")])
1292
1293;; For 64BIT abi we always round up to 8 bytes.
1294(define_insn "*pushhi2_rex64"
1295 [(set (match_operand:HI 0 "push_operand" "=X")
1296 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1297 "TARGET_64BIT"
1298 "push{q}\t%q1"
1299 [(set_attr "type" "push")
1300 (set_attr "mode" "DI")])
1301
1302(define_insn "*movhi_1"
1303 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1304 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1305 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1306{
1307 switch (get_attr_type (insn))
1308 {
1309 case TYPE_IMOVX:
1310 /* movzwl is faster than movw on p2 due to partial word stalls,
1311 though not as fast as an aligned movl. */
1312 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1313 default:
1314 if (get_attr_mode (insn) == MODE_SI)
1315 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1316 else
1317 return "mov{w}\t{%1, %0|%0, %1}";
1318 }
1319}
1320 [(set (attr "type")
1321 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1322 (const_string "imov")
1323 (and (eq_attr "alternative" "0")
1324 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1325 (const_int 0))
1326 (eq (symbol_ref "TARGET_HIMODE_MATH")
1327 (const_int 0))))
1328 (const_string "imov")
1329 (and (eq_attr "alternative" "1,2")
1330 (match_operand:HI 1 "aligned_operand" ""))
1331 (const_string "imov")
1332 (and (ne (symbol_ref "TARGET_MOVX")
1333 (const_int 0))
1334 (eq_attr "alternative" "0,2"))
1335 (const_string "imovx")
1336 ]
1337 (const_string "imov")))
1338 (set (attr "mode")
1339 (cond [(eq_attr "type" "imovx")
1340 (const_string "SI")
1341 (and (eq_attr "alternative" "1,2")
1342 (match_operand:HI 1 "aligned_operand" ""))
1343 (const_string "SI")
1344 (and (eq_attr "alternative" "0")
1345 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1346 (const_int 0))
1347 (eq (symbol_ref "TARGET_HIMODE_MATH")
1348 (const_int 0))))
1349 (const_string "SI")
1350 ]
1351 (const_string "HI")))])
1352
1353;; Stores and loads of ax to arbitrary constant address.
1354;; We fake an second form of instruction to force reload to load address
1355;; into register when rax is not available
1356(define_insn "*movabshi_1_rex64"
1357 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1358 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1359 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1360 "@
1361 movabs{w}\t{%1, %P0|%P0, %1}
1362 mov{w}\t{%1, %a0|%a0, %1}"
1363 [(set_attr "type" "imov")
1364 (set_attr "modrm" "0,*")
1365 (set_attr "length_address" "8,0")
1366 (set_attr "length_immediate" "0,*")
1367 (set_attr "memory" "store")
1368 (set_attr "mode" "HI")])
1369
1370(define_insn "*movabshi_2_rex64"
1371 [(set (match_operand:HI 0 "register_operand" "=a,r")
1372 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1373 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1374 "@
1375 movabs{w}\t{%P1, %0|%0, %P1}
1376 mov{w}\t{%a1, %0|%0, %a1}"
1377 [(set_attr "type" "imov")
1378 (set_attr "modrm" "0,*")
1379 (set_attr "length_address" "8,0")
1380 (set_attr "length_immediate" "0")
1381 (set_attr "memory" "load")
1382 (set_attr "mode" "HI")])
1383
1384(define_insn "*swaphi_1"
1385 [(set (match_operand:HI 0 "register_operand" "+r")
1386 (match_operand:HI 1 "register_operand" "+r"))
1387 (set (match_dup 1)
1388 (match_dup 0))]
1389 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1390 "xchg{l}\t%k1, %k0"
1391 [(set_attr "type" "imov")
1392 (set_attr "mode" "SI")
1393 (set_attr "pent_pair" "np")
1294
1295(define_expand "movhi"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297 (match_operand:HI 1 "general_operand" ""))]
1298 ""
1299 "ix86_expand_move (HImode, operands); DONE;")
1300
1301(define_insn "*pushhi2"
1302 [(set (match_operand:HI 0 "push_operand" "=X")
1303 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1304 "!TARGET_64BIT"
1305 "push{l}\t%k1"
1306 [(set_attr "type" "push")
1307 (set_attr "mode" "SI")])
1308
1309;; For 64BIT abi we always round up to 8 bytes.
1310(define_insn "*pushhi2_rex64"
1311 [(set (match_operand:HI 0 "push_operand" "=X")
1312 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1313 "TARGET_64BIT"
1314 "push{q}\t%q1"
1315 [(set_attr "type" "push")
1316 (set_attr "mode" "DI")])
1317
1318(define_insn "*movhi_1"
1319 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1320 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1321 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1322{
1323 switch (get_attr_type (insn))
1324 {
1325 case TYPE_IMOVX:
1326 /* movzwl is faster than movw on p2 due to partial word stalls,
1327 though not as fast as an aligned movl. */
1328 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1329 default:
1330 if (get_attr_mode (insn) == MODE_SI)
1331 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1332 else
1333 return "mov{w}\t{%1, %0|%0, %1}";
1334 }
1335}
1336 [(set (attr "type")
1337 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1338 (const_string "imov")
1339 (and (eq_attr "alternative" "0")
1340 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341 (const_int 0))
1342 (eq (symbol_ref "TARGET_HIMODE_MATH")
1343 (const_int 0))))
1344 (const_string "imov")
1345 (and (eq_attr "alternative" "1,2")
1346 (match_operand:HI 1 "aligned_operand" ""))
1347 (const_string "imov")
1348 (and (ne (symbol_ref "TARGET_MOVX")
1349 (const_int 0))
1350 (eq_attr "alternative" "0,2"))
1351 (const_string "imovx")
1352 ]
1353 (const_string "imov")))
1354 (set (attr "mode")
1355 (cond [(eq_attr "type" "imovx")
1356 (const_string "SI")
1357 (and (eq_attr "alternative" "1,2")
1358 (match_operand:HI 1 "aligned_operand" ""))
1359 (const_string "SI")
1360 (and (eq_attr "alternative" "0")
1361 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1362 (const_int 0))
1363 (eq (symbol_ref "TARGET_HIMODE_MATH")
1364 (const_int 0))))
1365 (const_string "SI")
1366 ]
1367 (const_string "HI")))])
1368
1369;; Stores and loads of ax to arbitrary constant address.
1370;; We fake an second form of instruction to force reload to load address
1371;; into register when rax is not available
1372(define_insn "*movabshi_1_rex64"
1373 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1374 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1375 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1376 "@
1377 movabs{w}\t{%1, %P0|%P0, %1}
1378 mov{w}\t{%1, %a0|%a0, %1}"
1379 [(set_attr "type" "imov")
1380 (set_attr "modrm" "0,*")
1381 (set_attr "length_address" "8,0")
1382 (set_attr "length_immediate" "0,*")
1383 (set_attr "memory" "store")
1384 (set_attr "mode" "HI")])
1385
1386(define_insn "*movabshi_2_rex64"
1387 [(set (match_operand:HI 0 "register_operand" "=a,r")
1388 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1389 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1390 "@
1391 movabs{w}\t{%P1, %0|%0, %P1}
1392 mov{w}\t{%a1, %0|%0, %a1}"
1393 [(set_attr "type" "imov")
1394 (set_attr "modrm" "0,*")
1395 (set_attr "length_address" "8,0")
1396 (set_attr "length_immediate" "0")
1397 (set_attr "memory" "load")
1398 (set_attr "mode" "HI")])
1399
1400(define_insn "*swaphi_1"
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 || optimize_size"
1406 "xchg{l}\t%k1, %k0"
1407 [(set_attr "type" "imov")
1408 (set_attr "mode" "SI")
1409 (set_attr "pent_pair" "np")
1394 (set_attr "athlon_decode" "vector")])
1410 (set_attr "athlon_decode" "vector")
1411 (set_attr "amdfam10_decode" "double")])
1395
1412
1413;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1396(define_insn "*swaphi_2"
1397 [(set (match_operand:HI 0 "register_operand" "+r")
1398 (match_operand:HI 1 "register_operand" "+r"))
1399 (set (match_dup 1)
1400 (match_dup 0))]
1401 "TARGET_PARTIAL_REG_STALL"
1402 "xchg{w}\t%1, %0"
1403 [(set_attr "type" "imov")
1404 (set_attr "mode" "HI")
1405 (set_attr "pent_pair" "np")
1406 (set_attr "athlon_decode" "vector")])
1407
1408(define_expand "movstricthi"
1409 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1410 (match_operand:HI 1 "general_operand" ""))]
1411 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1412{
1413 /* Don't generate memory->memory moves, go through a register */
1414 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1415 operands[1] = force_reg (HImode, operands[1]);
1416})
1417
1418(define_insn "*movstricthi_1"
1419 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1420 (match_operand:HI 1 "general_operand" "rn,m"))]
1421 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1422 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1423 "mov{w}\t{%1, %0|%0, %1}"
1424 [(set_attr "type" "imov")
1425 (set_attr "mode" "HI")])
1426
1427(define_insn "*movstricthi_xor"
1428 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1429 (match_operand:HI 1 "const0_operand" "i"))
1430 (clobber (reg:CC FLAGS_REG))]
1431 "reload_completed
1432 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1433 "xor{w}\t{%0, %0|%0, %0}"
1434 [(set_attr "type" "alu1")
1435 (set_attr "mode" "HI")
1436 (set_attr "length_immediate" "0")])
1437
1438(define_expand "movqi"
1439 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1440 (match_operand:QI 1 "general_operand" ""))]
1441 ""
1442 "ix86_expand_move (QImode, operands); DONE;")
1443
1444;; emit_push_insn when it calls move_by_pieces requires an insn to
1445;; "push a byte". But actually we use pushl, which has the effect
1446;; of rounding the amount pushed up to a word.
1447
1448(define_insn "*pushqi2"
1449 [(set (match_operand:QI 0 "push_operand" "=X")
1450 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1451 "!TARGET_64BIT"
1452 "push{l}\t%k1"
1453 [(set_attr "type" "push")
1454 (set_attr "mode" "SI")])
1455
1456;; For 64BIT abi we always round up to 8 bytes.
1457(define_insn "*pushqi2_rex64"
1458 [(set (match_operand:QI 0 "push_operand" "=X")
1459 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1460 "TARGET_64BIT"
1461 "push{q}\t%q1"
1462 [(set_attr "type" "push")
1463 (set_attr "mode" "DI")])
1464
1465;; Situation is quite tricky about when to choose full sized (SImode) move
1466;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1467;; partial register dependency machines (such as AMD Athlon), where QImode
1468;; moves issue extra dependency and for partial register stalls machines
1469;; that don't use QImode patterns (and QImode move cause stall on the next
1470;; instruction).
1471;;
1472;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1473;; register stall machines with, where we use QImode instructions, since
1474;; partial register stall can be caused there. Then we use movzx.
1475(define_insn "*movqi_1"
1476 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1477 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1478 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1479{
1480 switch (get_attr_type (insn))
1481 {
1482 case TYPE_IMOVX:
1483 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1484 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1485 default:
1486 if (get_attr_mode (insn) == MODE_SI)
1487 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1488 else
1489 return "mov{b}\t{%1, %0|%0, %1}";
1490 }
1491}
1492 [(set (attr "type")
1493 (cond [(and (eq_attr "alternative" "5")
1494 (not (match_operand:QI 1 "aligned_operand" "")))
1495 (const_string "imovx")
1496 (ne (symbol_ref "optimize_size") (const_int 0))
1497 (const_string "imov")
1498 (and (eq_attr "alternative" "3")
1499 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500 (const_int 0))
1501 (eq (symbol_ref "TARGET_QIMODE_MATH")
1502 (const_int 0))))
1503 (const_string "imov")
1504 (eq_attr "alternative" "3,5")
1505 (const_string "imovx")
1506 (and (ne (symbol_ref "TARGET_MOVX")
1507 (const_int 0))
1508 (eq_attr "alternative" "2"))
1509 (const_string "imovx")
1510 ]
1511 (const_string "imov")))
1512 (set (attr "mode")
1513 (cond [(eq_attr "alternative" "3,4,5")
1514 (const_string "SI")
1515 (eq_attr "alternative" "6")
1516 (const_string "QI")
1517 (eq_attr "type" "imovx")
1518 (const_string "SI")
1519 (and (eq_attr "type" "imov")
1520 (and (eq_attr "alternative" "0,1")
1521 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1522 (const_int 0))
1523 (and (eq (symbol_ref "optimize_size")
1524 (const_int 0))
1525 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
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")
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 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1549 if (! q_regs_operand (op1, QImode))
1550 {
1551 emit_insn (gen_movqi (op2, op1));
1552 op1 = op2;
1553 }
1554 emit_insn (gen_movqi (op0, op1));
1555 DONE;
1556})
1557
1558(define_insn "*swapqi_1"
1559 [(set (match_operand:QI 0 "register_operand" "+r")
1560 (match_operand:QI 1 "register_operand" "+r"))
1561 (set (match_dup 1)
1562 (match_dup 0))]
1563 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1564 "xchg{l}\t%k1, %k0"
1565 [(set_attr "type" "imov")
1566 (set_attr "mode" "SI")
1567 (set_attr "pent_pair" "np")
1414(define_insn "*swaphi_2"
1415 [(set (match_operand:HI 0 "register_operand" "+r")
1416 (match_operand:HI 1 "register_operand" "+r"))
1417 (set (match_dup 1)
1418 (match_dup 0))]
1419 "TARGET_PARTIAL_REG_STALL"
1420 "xchg{w}\t%1, %0"
1421 [(set_attr "type" "imov")
1422 (set_attr "mode" "HI")
1423 (set_attr "pent_pair" "np")
1424 (set_attr "athlon_decode" "vector")])
1425
1426(define_expand "movstricthi"
1427 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1428 (match_operand:HI 1 "general_operand" ""))]
1429 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1430{
1431 /* Don't generate memory->memory moves, go through a register */
1432 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1433 operands[1] = force_reg (HImode, operands[1]);
1434})
1435
1436(define_insn "*movstricthi_1"
1437 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1438 (match_operand:HI 1 "general_operand" "rn,m"))]
1439 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1440 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1441 "mov{w}\t{%1, %0|%0, %1}"
1442 [(set_attr "type" "imov")
1443 (set_attr "mode" "HI")])
1444
1445(define_insn "*movstricthi_xor"
1446 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1447 (match_operand:HI 1 "const0_operand" "i"))
1448 (clobber (reg:CC FLAGS_REG))]
1449 "reload_completed
1450 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1451 "xor{w}\t{%0, %0|%0, %0}"
1452 [(set_attr "type" "alu1")
1453 (set_attr "mode" "HI")
1454 (set_attr "length_immediate" "0")])
1455
1456(define_expand "movqi"
1457 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1458 (match_operand:QI 1 "general_operand" ""))]
1459 ""
1460 "ix86_expand_move (QImode, operands); DONE;")
1461
1462;; emit_push_insn when it calls move_by_pieces requires an insn to
1463;; "push a byte". But actually we use pushl, which has the effect
1464;; of rounding the amount pushed up to a word.
1465
1466(define_insn "*pushqi2"
1467 [(set (match_operand:QI 0 "push_operand" "=X")
1468 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1469 "!TARGET_64BIT"
1470 "push{l}\t%k1"
1471 [(set_attr "type" "push")
1472 (set_attr "mode" "SI")])
1473
1474;; For 64BIT abi we always round up to 8 bytes.
1475(define_insn "*pushqi2_rex64"
1476 [(set (match_operand:QI 0 "push_operand" "=X")
1477 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1478 "TARGET_64BIT"
1479 "push{q}\t%q1"
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "DI")])
1482
1483;; Situation is quite tricky about when to choose full sized (SImode) move
1484;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1485;; partial register dependency machines (such as AMD Athlon), where QImode
1486;; moves issue extra dependency and for partial register stalls machines
1487;; that don't use QImode patterns (and QImode move cause stall on the next
1488;; instruction).
1489;;
1490;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1491;; register stall machines with, where we use QImode instructions, since
1492;; partial register stall can be caused there. Then we use movzx.
1493(define_insn "*movqi_1"
1494 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1495 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1496 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1497{
1498 switch (get_attr_type (insn))
1499 {
1500 case TYPE_IMOVX:
1501 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1502 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1503 default:
1504 if (get_attr_mode (insn) == MODE_SI)
1505 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1506 else
1507 return "mov{b}\t{%1, %0|%0, %1}";
1508 }
1509}
1510 [(set (attr "type")
1511 (cond [(and (eq_attr "alternative" "5")
1512 (not (match_operand:QI 1 "aligned_operand" "")))
1513 (const_string "imovx")
1514 (ne (symbol_ref "optimize_size") (const_int 0))
1515 (const_string "imov")
1516 (and (eq_attr "alternative" "3")
1517 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518 (const_int 0))
1519 (eq (symbol_ref "TARGET_QIMODE_MATH")
1520 (const_int 0))))
1521 (const_string "imov")
1522 (eq_attr "alternative" "3,5")
1523 (const_string "imovx")
1524 (and (ne (symbol_ref "TARGET_MOVX")
1525 (const_int 0))
1526 (eq_attr "alternative" "2"))
1527 (const_string "imovx")
1528 ]
1529 (const_string "imov")))
1530 (set (attr "mode")
1531 (cond [(eq_attr "alternative" "3,4,5")
1532 (const_string "SI")
1533 (eq_attr "alternative" "6")
1534 (const_string "QI")
1535 (eq_attr "type" "imovx")
1536 (const_string "SI")
1537 (and (eq_attr "type" "imov")
1538 (and (eq_attr "alternative" "0,1")
1539 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1540 (const_int 0))
1541 (and (eq (symbol_ref "optimize_size")
1542 (const_int 0))
1543 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1544 (const_int 0))))))
1545 (const_string "SI")
1546 ;; Avoid partial register stalls when not using QImode arithmetic
1547 (and (eq_attr "type" "imov")
1548 (and (eq_attr "alternative" "0,1")
1549 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1550 (const_int 0))
1551 (eq (symbol_ref "TARGET_QIMODE_MATH")
1552 (const_int 0)))))
1553 (const_string "SI")
1554 ]
1555 (const_string "QI")))])
1556
1557(define_expand "reload_outqi"
1558 [(parallel [(match_operand:QI 0 "" "=m")
1559 (match_operand:QI 1 "register_operand" "r")
1560 (match_operand:QI 2 "register_operand" "=&q")])]
1561 ""
1562{
1563 rtx op0, op1, op2;
1564 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1565
1566 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1567 if (! q_regs_operand (op1, QImode))
1568 {
1569 emit_insn (gen_movqi (op2, op1));
1570 op1 = op2;
1571 }
1572 emit_insn (gen_movqi (op0, op1));
1573 DONE;
1574})
1575
1576(define_insn "*swapqi_1"
1577 [(set (match_operand:QI 0 "register_operand" "+r")
1578 (match_operand:QI 1 "register_operand" "+r"))
1579 (set (match_dup 1)
1580 (match_dup 0))]
1581 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1582 "xchg{l}\t%k1, %k0"
1583 [(set_attr "type" "imov")
1584 (set_attr "mode" "SI")
1585 (set_attr "pent_pair" "np")
1568 (set_attr "athlon_decode" "vector")])
1586 (set_attr "athlon_decode" "vector")
1587 (set_attr "amdfam10_decode" "vector")])
1569
1588
1589;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1570(define_insn "*swapqi_2"
1571 [(set (match_operand:QI 0 "register_operand" "+q")
1572 (match_operand:QI 1 "register_operand" "+q"))
1573 (set (match_dup 1)
1574 (match_dup 0))]
1575 "TARGET_PARTIAL_REG_STALL"
1576 "xchg{b}\t%1, %0"
1577 [(set_attr "type" "imov")
1578 (set_attr "mode" "QI")
1579 (set_attr "pent_pair" "np")
1580 (set_attr "athlon_decode" "vector")])
1581
1582(define_expand "movstrictqi"
1583 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1584 (match_operand:QI 1 "general_operand" ""))]
1585 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1586{
1587 /* Don't generate memory->memory moves, go through a register. */
1588 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1589 operands[1] = force_reg (QImode, operands[1]);
1590})
1591
1592(define_insn "*movstrictqi_1"
1593 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1594 (match_operand:QI 1 "general_operand" "*qn,m"))]
1595 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1596 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1597 "mov{b}\t{%1, %0|%0, %1}"
1598 [(set_attr "type" "imov")
1599 (set_attr "mode" "QI")])
1600
1601(define_insn "*movstrictqi_xor"
1602 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1603 (match_operand:QI 1 "const0_operand" "i"))
1604 (clobber (reg:CC FLAGS_REG))]
1605 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1606 "xor{b}\t{%0, %0|%0, %0}"
1607 [(set_attr "type" "alu1")
1608 (set_attr "mode" "QI")
1609 (set_attr "length_immediate" "0")])
1610
1611(define_insn "*movsi_extv_1"
1612 [(set (match_operand:SI 0 "register_operand" "=R")
1613 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1614 (const_int 8)
1615 (const_int 8)))]
1616 ""
1617 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1618 [(set_attr "type" "imovx")
1619 (set_attr "mode" "SI")])
1620
1621(define_insn "*movhi_extv_1"
1622 [(set (match_operand:HI 0 "register_operand" "=R")
1623 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1624 (const_int 8)
1625 (const_int 8)))]
1626 ""
1627 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1628 [(set_attr "type" "imovx")
1629 (set_attr "mode" "SI")])
1630
1631(define_insn "*movqi_extv_1"
1632 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1633 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1634 (const_int 8)
1635 (const_int 8)))]
1636 "!TARGET_64BIT"
1637{
1638 switch (get_attr_type (insn))
1639 {
1640 case TYPE_IMOVX:
1641 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1642 default:
1643 return "mov{b}\t{%h1, %0|%0, %h1}";
1644 }
1645}
1646 [(set (attr "type")
1647 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649 (ne (symbol_ref "TARGET_MOVX")
1650 (const_int 0))))
1651 (const_string "imovx")
1652 (const_string "imov")))
1653 (set (attr "mode")
1654 (if_then_else (eq_attr "type" "imovx")
1655 (const_string "SI")
1656 (const_string "QI")))])
1657
1658(define_insn "*movqi_extv_1_rex64"
1659 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1660 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1661 (const_int 8)
1662 (const_int 8)))]
1663 "TARGET_64BIT"
1664{
1665 switch (get_attr_type (insn))
1666 {
1667 case TYPE_IMOVX:
1668 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1669 default:
1670 return "mov{b}\t{%h1, %0|%0, %h1}";
1671 }
1672}
1673 [(set (attr "type")
1674 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1675 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1676 (ne (symbol_ref "TARGET_MOVX")
1677 (const_int 0))))
1678 (const_string "imovx")
1679 (const_string "imov")))
1680 (set (attr "mode")
1681 (if_then_else (eq_attr "type" "imovx")
1682 (const_string "SI")
1683 (const_string "QI")))])
1684
1685;; Stores and loads of ax to arbitrary constant address.
1686;; We fake an second form of instruction to force reload to load address
1687;; into register when rax is not available
1688(define_insn "*movabsqi_1_rex64"
1689 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1690 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1691 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1692 "@
1693 movabs{b}\t{%1, %P0|%P0, %1}
1694 mov{b}\t{%1, %a0|%a0, %1}"
1695 [(set_attr "type" "imov")
1696 (set_attr "modrm" "0,*")
1697 (set_attr "length_address" "8,0")
1698 (set_attr "length_immediate" "0,*")
1699 (set_attr "memory" "store")
1700 (set_attr "mode" "QI")])
1701
1702(define_insn "*movabsqi_2_rex64"
1703 [(set (match_operand:QI 0 "register_operand" "=a,r")
1704 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1705 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1706 "@
1707 movabs{b}\t{%P1, %0|%0, %P1}
1708 mov{b}\t{%a1, %0|%0, %a1}"
1709 [(set_attr "type" "imov")
1710 (set_attr "modrm" "0,*")
1711 (set_attr "length_address" "8,0")
1712 (set_attr "length_immediate" "0")
1713 (set_attr "memory" "load")
1714 (set_attr "mode" "QI")])
1715
1716(define_insn "*movdi_extzv_1"
1717 [(set (match_operand:DI 0 "register_operand" "=R")
1718 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1719 (const_int 8)
1720 (const_int 8)))]
1721 "TARGET_64BIT"
1722 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1723 [(set_attr "type" "imovx")
1724 (set_attr "mode" "DI")])
1725
1726(define_insn "*movsi_extzv_1"
1727 [(set (match_operand:SI 0 "register_operand" "=R")
1728 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1729 (const_int 8)
1730 (const_int 8)))]
1731 ""
1732 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1733 [(set_attr "type" "imovx")
1734 (set_attr "mode" "SI")])
1735
1736(define_insn "*movqi_extzv_2"
1737 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1738 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1739 (const_int 8)
1740 (const_int 8)) 0))]
1741 "!TARGET_64BIT"
1742{
1743 switch (get_attr_type (insn))
1744 {
1745 case TYPE_IMOVX:
1746 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1747 default:
1748 return "mov{b}\t{%h1, %0|%0, %h1}";
1749 }
1750}
1751 [(set (attr "type")
1752 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1753 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1754 (ne (symbol_ref "TARGET_MOVX")
1755 (const_int 0))))
1756 (const_string "imovx")
1757 (const_string "imov")))
1758 (set (attr "mode")
1759 (if_then_else (eq_attr "type" "imovx")
1760 (const_string "SI")
1761 (const_string "QI")))])
1762
1763(define_insn "*movqi_extzv_2_rex64"
1764 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1765 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1766 (const_int 8)
1767 (const_int 8)) 0))]
1768 "TARGET_64BIT"
1769{
1770 switch (get_attr_type (insn))
1771 {
1772 case TYPE_IMOVX:
1773 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1774 default:
1775 return "mov{b}\t{%h1, %0|%0, %h1}";
1776 }
1777}
1778 [(set (attr "type")
1779 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1780 (ne (symbol_ref "TARGET_MOVX")
1781 (const_int 0)))
1782 (const_string "imovx")
1783 (const_string "imov")))
1784 (set (attr "mode")
1785 (if_then_else (eq_attr "type" "imovx")
1786 (const_string "SI")
1787 (const_string "QI")))])
1788
1789(define_insn "movsi_insv_1"
1790 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1791 (const_int 8)
1792 (const_int 8))
1793 (match_operand:SI 1 "general_operand" "Qmn"))]
1794 "!TARGET_64BIT"
1795 "mov{b}\t{%b1, %h0|%h0, %b1}"
1796 [(set_attr "type" "imov")
1797 (set_attr "mode" "QI")])
1798
1799(define_insn "movdi_insv_1_rex64"
1800 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1801 (const_int 8)
1802 (const_int 8))
1803 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1804 "TARGET_64BIT"
1805 "mov{b}\t{%b1, %h0|%h0, %b1}"
1806 [(set_attr "type" "imov")
1807 (set_attr "mode" "QI")])
1808
1809(define_insn "*movqi_insv_2"
1810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811 (const_int 8)
1812 (const_int 8))
1813 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1814 (const_int 8)))]
1815 ""
1816 "mov{b}\t{%h1, %h0|%h0, %h1}"
1817 [(set_attr "type" "imov")
1818 (set_attr "mode" "QI")])
1819
1820(define_expand "movdi"
1821 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1822 (match_operand:DI 1 "general_operand" ""))]
1823 ""
1824 "ix86_expand_move (DImode, operands); DONE;")
1825
1826(define_insn "*pushdi"
1827 [(set (match_operand:DI 0 "push_operand" "=<")
1828 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1829 "!TARGET_64BIT"
1830 "#")
1831
1832(define_insn "*pushdi2_rex64"
1833 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1834 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1835 "TARGET_64BIT"
1836 "@
1837 push{q}\t%1
1838 #"
1839 [(set_attr "type" "push,multi")
1840 (set_attr "mode" "DI")])
1841
1842;; Convert impossible pushes of immediate to existing instructions.
1843;; First try to get scratch register and go through it. In case this
1844;; fails, push sign extended lower part first and then overwrite
1845;; upper part by 32bit move.
1846(define_peephole2
1847 [(match_scratch:DI 2 "r")
1848 (set (match_operand:DI 0 "push_operand" "")
1849 (match_operand:DI 1 "immediate_operand" ""))]
1850 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1851 && !x86_64_immediate_operand (operands[1], DImode)"
1852 [(set (match_dup 2) (match_dup 1))
1853 (set (match_dup 0) (match_dup 2))]
1854 "")
1855
1856;; We need to define this as both peepholer and splitter for case
1857;; peephole2 pass is not run.
1858;; "&& 1" is needed to keep it from matching the previous pattern.
1859(define_peephole2
1860 [(set (match_operand:DI 0 "push_operand" "")
1861 (match_operand:DI 1 "immediate_operand" ""))]
1862 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1863 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1864 [(set (match_dup 0) (match_dup 1))
1865 (set (match_dup 2) (match_dup 3))]
1866 "split_di (operands + 1, 1, operands + 2, operands + 3);
1867 operands[1] = gen_lowpart (DImode, operands[2]);
1868 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1869 GEN_INT (4)));
1870 ")
1871
1872(define_split
1873 [(set (match_operand:DI 0 "push_operand" "")
1874 (match_operand:DI 1 "immediate_operand" ""))]
1875 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1876 ? flow2_completed : reload_completed)
1877 && !symbolic_operand (operands[1], DImode)
1878 && !x86_64_immediate_operand (operands[1], DImode)"
1879 [(set (match_dup 0) (match_dup 1))
1880 (set (match_dup 2) (match_dup 3))]
1881 "split_di (operands + 1, 1, operands + 2, operands + 3);
1882 operands[1] = gen_lowpart (DImode, operands[2]);
1883 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1884 GEN_INT (4)));
1885 ")
1886
1887(define_insn "*pushdi2_prologue_rex64"
1888 [(set (match_operand:DI 0 "push_operand" "=<")
1889 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1890 (clobber (mem:BLK (scratch)))]
1891 "TARGET_64BIT"
1892 "push{q}\t%1"
1893 [(set_attr "type" "push")
1894 (set_attr "mode" "DI")])
1895
1896(define_insn "*popdi1_epilogue_rex64"
1897 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1898 (mem:DI (reg:DI SP_REG)))
1899 (set (reg:DI SP_REG)
1900 (plus:DI (reg:DI SP_REG) (const_int 8)))
1901 (clobber (mem:BLK (scratch)))]
1902 "TARGET_64BIT"
1903 "pop{q}\t%0"
1904 [(set_attr "type" "pop")
1905 (set_attr "mode" "DI")])
1906
1907(define_insn "popdi1"
1908 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1909 (mem:DI (reg:DI SP_REG)))
1910 (set (reg:DI SP_REG)
1911 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1912 "TARGET_64BIT"
1913 "pop{q}\t%0"
1914 [(set_attr "type" "pop")
1915 (set_attr "mode" "DI")])
1916
1917(define_insn "*movdi_xor_rex64"
1918 [(set (match_operand:DI 0 "register_operand" "=r")
1919 (match_operand:DI 1 "const0_operand" "i"))
1920 (clobber (reg:CC FLAGS_REG))]
1921 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1922 && reload_completed"
1923 "xor{l}\t{%k0, %k0|%k0, %k0}"
1924 [(set_attr "type" "alu1")
1925 (set_attr "mode" "SI")
1926 (set_attr "length_immediate" "0")])
1927
1928(define_insn "*movdi_or_rex64"
1929 [(set (match_operand:DI 0 "register_operand" "=r")
1930 (match_operand:DI 1 "const_int_operand" "i"))
1931 (clobber (reg:CC FLAGS_REG))]
1932 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1933 && reload_completed
1934 && operands[1] == constm1_rtx"
1935{
1936 operands[1] = constm1_rtx;
1937 return "or{q}\t{%1, %0|%0, %1}";
1938}
1939 [(set_attr "type" "alu1")
1940 (set_attr "mode" "DI")
1941 (set_attr "length_immediate" "1")])
1942
1943(define_insn "*movdi_2"
1944 [(set (match_operand:DI 0 "nonimmediate_operand"
1945 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1946 (match_operand:DI 1 "general_operand"
1947 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1948 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1949 "@
1950 #
1951 #
1952 pxor\t%0, %0
1953 movq\t{%1, %0|%0, %1}
1954 movq\t{%1, %0|%0, %1}
1955 pxor\t%0, %0
1956 movq\t{%1, %0|%0, %1}
1957 movdqa\t{%1, %0|%0, %1}
1958 movq\t{%1, %0|%0, %1}
1959 xorps\t%0, %0
1960 movlps\t{%1, %0|%0, %1}
1961 movaps\t{%1, %0|%0, %1}
1962 movlps\t{%1, %0|%0, %1}"
1963 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1964 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1965
1966(define_split
1967 [(set (match_operand:DI 0 "push_operand" "")
1968 (match_operand:DI 1 "general_operand" ""))]
1969 "!TARGET_64BIT && reload_completed
1970 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1971 [(const_int 0)]
1972 "ix86_split_long_move (operands); DONE;")
1973
1974;; %%% This multiword shite has got to go.
1975(define_split
1976 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1977 (match_operand:DI 1 "general_operand" ""))]
1978 "!TARGET_64BIT && reload_completed
1979 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1980 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1981 [(const_int 0)]
1982 "ix86_split_long_move (operands); DONE;")
1983
1984(define_insn "*movdi_1_rex64"
1985 [(set (match_operand:DI 0 "nonimmediate_operand"
1986 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1987 (match_operand:DI 1 "general_operand"
1988 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1989 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1990{
1991 switch (get_attr_type (insn))
1992 {
1993 case TYPE_SSECVT:
1994 if (which_alternative == 13)
1995 return "movq2dq\t{%1, %0|%0, %1}";
1996 else
1997 return "movdq2q\t{%1, %0|%0, %1}";
1998 case TYPE_SSEMOV:
1999 if (get_attr_mode (insn) == MODE_TI)
2000 return "movdqa\t{%1, %0|%0, %1}";
2001 /* FALLTHRU */
2002 case TYPE_MMXMOV:
2003 /* Moves from and into integer register is done using movd opcode with
2004 REX prefix. */
2005 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006 return "movd\t{%1, %0|%0, %1}";
2007 return "movq\t{%1, %0|%0, %1}";
2008 case TYPE_SSELOG1:
2009 case TYPE_MMXADD:
2010 return "pxor\t%0, %0";
2011 case TYPE_MULTI:
2012 return "#";
2013 case TYPE_LEA:
2014 return "lea{q}\t{%a1, %0|%0, %a1}";
2015 default:
2016 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2017 if (get_attr_mode (insn) == MODE_SI)
2018 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2019 else if (which_alternative == 2)
2020 return "movabs{q}\t{%1, %0|%0, %1}";
2021 else
2022 return "mov{q}\t{%1, %0|%0, %1}";
2023 }
2024}
2025 [(set (attr "type")
2026 (cond [(eq_attr "alternative" "5")
2027 (const_string "mmxadd")
2028 (eq_attr "alternative" "6,7,8")
2029 (const_string "mmxmov")
2030 (eq_attr "alternative" "9")
2031 (const_string "sselog1")
2032 (eq_attr "alternative" "10,11,12")
2033 (const_string "ssemov")
2034 (eq_attr "alternative" "13,14")
2035 (const_string "ssecvt")
2036 (eq_attr "alternative" "4")
2037 (const_string "multi")
2038 (match_operand:DI 1 "pic_32bit_operand" "")
2039 (const_string "lea")
2040 ]
2041 (const_string "imov")))
2042 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2043 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2044 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2045
2046;; Stores and loads of ax to arbitrary constant address.
2047;; We fake an second form of instruction to force reload to load address
2048;; into register when rax is not available
2049(define_insn "*movabsdi_1_rex64"
2050 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2051 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2052 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2053 "@
2054 movabs{q}\t{%1, %P0|%P0, %1}
2055 mov{q}\t{%1, %a0|%a0, %1}"
2056 [(set_attr "type" "imov")
2057 (set_attr "modrm" "0,*")
2058 (set_attr "length_address" "8,0")
2059 (set_attr "length_immediate" "0,*")
2060 (set_attr "memory" "store")
2061 (set_attr "mode" "DI")])
2062
2063(define_insn "*movabsdi_2_rex64"
2064 [(set (match_operand:DI 0 "register_operand" "=a,r")
2065 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2066 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2067 "@
2068 movabs{q}\t{%P1, %0|%0, %P1}
2069 mov{q}\t{%a1, %0|%0, %a1}"
2070 [(set_attr "type" "imov")
2071 (set_attr "modrm" "0,*")
2072 (set_attr "length_address" "8,0")
2073 (set_attr "length_immediate" "0")
2074 (set_attr "memory" "load")
2075 (set_attr "mode" "DI")])
2076
2077;; Convert impossible stores of immediate to existing instructions.
2078;; First try to get scratch register and go through it. In case this
2079;; fails, move by 32bit parts.
2080(define_peephole2
2081 [(match_scratch:DI 2 "r")
2082 (set (match_operand:DI 0 "memory_operand" "")
2083 (match_operand:DI 1 "immediate_operand" ""))]
2084 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085 && !x86_64_immediate_operand (operands[1], DImode)"
2086 [(set (match_dup 2) (match_dup 1))
2087 (set (match_dup 0) (match_dup 2))]
2088 "")
2089
2090;; We need to define this as both peepholer and splitter for case
2091;; peephole2 pass is not run.
2092;; "&& 1" is needed to keep it from matching the previous pattern.
2093(define_peephole2
2094 [(set (match_operand:DI 0 "memory_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2097 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2098 [(set (match_dup 2) (match_dup 3))
2099 (set (match_dup 4) (match_dup 5))]
2100 "split_di (operands, 2, operands + 2, operands + 4);")
2101
2102(define_split
2103 [(set (match_operand:DI 0 "memory_operand" "")
2104 (match_operand:DI 1 "immediate_operand" ""))]
2105 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2106 ? flow2_completed : reload_completed)
2107 && !symbolic_operand (operands[1], DImode)
2108 && !x86_64_immediate_operand (operands[1], DImode)"
2109 [(set (match_dup 2) (match_dup 3))
2110 (set (match_dup 4) (match_dup 5))]
2111 "split_di (operands, 2, operands + 2, operands + 4);")
2112
2113(define_insn "*swapdi_rex64"
2114 [(set (match_operand:DI 0 "register_operand" "+r")
2115 (match_operand:DI 1 "register_operand" "+r"))
2116 (set (match_dup 1)
2117 (match_dup 0))]
2118 "TARGET_64BIT"
2119 "xchg{q}\t%1, %0"
2120 [(set_attr "type" "imov")
2121 (set_attr "mode" "DI")
2122 (set_attr "pent_pair" "np")
1590(define_insn "*swapqi_2"
1591 [(set (match_operand:QI 0 "register_operand" "+q")
1592 (match_operand:QI 1 "register_operand" "+q"))
1593 (set (match_dup 1)
1594 (match_dup 0))]
1595 "TARGET_PARTIAL_REG_STALL"
1596 "xchg{b}\t%1, %0"
1597 [(set_attr "type" "imov")
1598 (set_attr "mode" "QI")
1599 (set_attr "pent_pair" "np")
1600 (set_attr "athlon_decode" "vector")])
1601
1602(define_expand "movstrictqi"
1603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1604 (match_operand:QI 1 "general_operand" ""))]
1605 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1606{
1607 /* Don't generate memory->memory moves, go through a register. */
1608 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1609 operands[1] = force_reg (QImode, operands[1]);
1610})
1611
1612(define_insn "*movstrictqi_1"
1613 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1614 (match_operand:QI 1 "general_operand" "*qn,m"))]
1615 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1616 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1617 "mov{b}\t{%1, %0|%0, %1}"
1618 [(set_attr "type" "imov")
1619 (set_attr "mode" "QI")])
1620
1621(define_insn "*movstrictqi_xor"
1622 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1623 (match_operand:QI 1 "const0_operand" "i"))
1624 (clobber (reg:CC FLAGS_REG))]
1625 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1626 "xor{b}\t{%0, %0|%0, %0}"
1627 [(set_attr "type" "alu1")
1628 (set_attr "mode" "QI")
1629 (set_attr "length_immediate" "0")])
1630
1631(define_insn "*movsi_extv_1"
1632 [(set (match_operand:SI 0 "register_operand" "=R")
1633 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1634 (const_int 8)
1635 (const_int 8)))]
1636 ""
1637 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1638 [(set_attr "type" "imovx")
1639 (set_attr "mode" "SI")])
1640
1641(define_insn "*movhi_extv_1"
1642 [(set (match_operand:HI 0 "register_operand" "=R")
1643 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1644 (const_int 8)
1645 (const_int 8)))]
1646 ""
1647 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1648 [(set_attr "type" "imovx")
1649 (set_attr "mode" "SI")])
1650
1651(define_insn "*movqi_extv_1"
1652 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1653 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654 (const_int 8)
1655 (const_int 8)))]
1656 "!TARGET_64BIT"
1657{
1658 switch (get_attr_type (insn))
1659 {
1660 case TYPE_IMOVX:
1661 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1662 default:
1663 return "mov{b}\t{%h1, %0|%0, %h1}";
1664 }
1665}
1666 [(set (attr "type")
1667 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669 (ne (symbol_ref "TARGET_MOVX")
1670 (const_int 0))))
1671 (const_string "imovx")
1672 (const_string "imov")))
1673 (set (attr "mode")
1674 (if_then_else (eq_attr "type" "imovx")
1675 (const_string "SI")
1676 (const_string "QI")))])
1677
1678(define_insn "*movqi_extv_1_rex64"
1679 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1680 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1681 (const_int 8)
1682 (const_int 8)))]
1683 "TARGET_64BIT"
1684{
1685 switch (get_attr_type (insn))
1686 {
1687 case TYPE_IMOVX:
1688 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1689 default:
1690 return "mov{b}\t{%h1, %0|%0, %h1}";
1691 }
1692}
1693 [(set (attr "type")
1694 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1695 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1696 (ne (symbol_ref "TARGET_MOVX")
1697 (const_int 0))))
1698 (const_string "imovx")
1699 (const_string "imov")))
1700 (set (attr "mode")
1701 (if_then_else (eq_attr "type" "imovx")
1702 (const_string "SI")
1703 (const_string "QI")))])
1704
1705;; Stores and loads of ax to arbitrary constant address.
1706;; We fake an second form of instruction to force reload to load address
1707;; into register when rax is not available
1708(define_insn "*movabsqi_1_rex64"
1709 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1710 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1711 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1712 "@
1713 movabs{b}\t{%1, %P0|%P0, %1}
1714 mov{b}\t{%1, %a0|%a0, %1}"
1715 [(set_attr "type" "imov")
1716 (set_attr "modrm" "0,*")
1717 (set_attr "length_address" "8,0")
1718 (set_attr "length_immediate" "0,*")
1719 (set_attr "memory" "store")
1720 (set_attr "mode" "QI")])
1721
1722(define_insn "*movabsqi_2_rex64"
1723 [(set (match_operand:QI 0 "register_operand" "=a,r")
1724 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1725 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1726 "@
1727 movabs{b}\t{%P1, %0|%0, %P1}
1728 mov{b}\t{%a1, %0|%0, %a1}"
1729 [(set_attr "type" "imov")
1730 (set_attr "modrm" "0,*")
1731 (set_attr "length_address" "8,0")
1732 (set_attr "length_immediate" "0")
1733 (set_attr "memory" "load")
1734 (set_attr "mode" "QI")])
1735
1736(define_insn "*movdi_extzv_1"
1737 [(set (match_operand:DI 0 "register_operand" "=R")
1738 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1739 (const_int 8)
1740 (const_int 8)))]
1741 "TARGET_64BIT"
1742 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1743 [(set_attr "type" "imovx")
1744 (set_attr "mode" "DI")])
1745
1746(define_insn "*movsi_extzv_1"
1747 [(set (match_operand:SI 0 "register_operand" "=R")
1748 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1749 (const_int 8)
1750 (const_int 8)))]
1751 ""
1752 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1753 [(set_attr "type" "imovx")
1754 (set_attr "mode" "SI")])
1755
1756(define_insn "*movqi_extzv_2"
1757 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1758 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759 (const_int 8)
1760 (const_int 8)) 0))]
1761 "!TARGET_64BIT"
1762{
1763 switch (get_attr_type (insn))
1764 {
1765 case TYPE_IMOVX:
1766 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1767 default:
1768 return "mov{b}\t{%h1, %0|%0, %h1}";
1769 }
1770}
1771 [(set (attr "type")
1772 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1773 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774 (ne (symbol_ref "TARGET_MOVX")
1775 (const_int 0))))
1776 (const_string "imovx")
1777 (const_string "imov")))
1778 (set (attr "mode")
1779 (if_then_else (eq_attr "type" "imovx")
1780 (const_string "SI")
1781 (const_string "QI")))])
1782
1783(define_insn "*movqi_extzv_2_rex64"
1784 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1785 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1786 (const_int 8)
1787 (const_int 8)) 0))]
1788 "TARGET_64BIT"
1789{
1790 switch (get_attr_type (insn))
1791 {
1792 case TYPE_IMOVX:
1793 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1794 default:
1795 return "mov{b}\t{%h1, %0|%0, %h1}";
1796 }
1797}
1798 [(set (attr "type")
1799 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1800 (ne (symbol_ref "TARGET_MOVX")
1801 (const_int 0)))
1802 (const_string "imovx")
1803 (const_string "imov")))
1804 (set (attr "mode")
1805 (if_then_else (eq_attr "type" "imovx")
1806 (const_string "SI")
1807 (const_string "QI")))])
1808
1809(define_insn "movsi_insv_1"
1810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811 (const_int 8)
1812 (const_int 8))
1813 (match_operand:SI 1 "general_operand" "Qmn"))]
1814 "!TARGET_64BIT"
1815 "mov{b}\t{%b1, %h0|%h0, %b1}"
1816 [(set_attr "type" "imov")
1817 (set_attr "mode" "QI")])
1818
1819(define_insn "movdi_insv_1_rex64"
1820 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1821 (const_int 8)
1822 (const_int 8))
1823 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1824 "TARGET_64BIT"
1825 "mov{b}\t{%b1, %h0|%h0, %b1}"
1826 [(set_attr "type" "imov")
1827 (set_attr "mode" "QI")])
1828
1829(define_insn "*movqi_insv_2"
1830 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1831 (const_int 8)
1832 (const_int 8))
1833 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1834 (const_int 8)))]
1835 ""
1836 "mov{b}\t{%h1, %h0|%h0, %h1}"
1837 [(set_attr "type" "imov")
1838 (set_attr "mode" "QI")])
1839
1840(define_expand "movdi"
1841 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1842 (match_operand:DI 1 "general_operand" ""))]
1843 ""
1844 "ix86_expand_move (DImode, operands); DONE;")
1845
1846(define_insn "*pushdi"
1847 [(set (match_operand:DI 0 "push_operand" "=<")
1848 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1849 "!TARGET_64BIT"
1850 "#")
1851
1852(define_insn "*pushdi2_rex64"
1853 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1854 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1855 "TARGET_64BIT"
1856 "@
1857 push{q}\t%1
1858 #"
1859 [(set_attr "type" "push,multi")
1860 (set_attr "mode" "DI")])
1861
1862;; Convert impossible pushes of immediate to existing instructions.
1863;; First try to get scratch register and go through it. In case this
1864;; fails, push sign extended lower part first and then overwrite
1865;; upper part by 32bit move.
1866(define_peephole2
1867 [(match_scratch:DI 2 "r")
1868 (set (match_operand:DI 0 "push_operand" "")
1869 (match_operand:DI 1 "immediate_operand" ""))]
1870 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1871 && !x86_64_immediate_operand (operands[1], DImode)"
1872 [(set (match_dup 2) (match_dup 1))
1873 (set (match_dup 0) (match_dup 2))]
1874 "")
1875
1876;; We need to define this as both peepholer and splitter for case
1877;; peephole2 pass is not run.
1878;; "&& 1" is needed to keep it from matching the previous pattern.
1879(define_peephole2
1880 [(set (match_operand:DI 0 "push_operand" "")
1881 (match_operand:DI 1 "immediate_operand" ""))]
1882 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1883 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1884 [(set (match_dup 0) (match_dup 1))
1885 (set (match_dup 2) (match_dup 3))]
1886 "split_di (operands + 1, 1, operands + 2, operands + 3);
1887 operands[1] = gen_lowpart (DImode, operands[2]);
1888 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889 GEN_INT (4)));
1890 ")
1891
1892(define_split
1893 [(set (match_operand:DI 0 "push_operand" "")
1894 (match_operand:DI 1 "immediate_operand" ""))]
1895 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1896 ? flow2_completed : reload_completed)
1897 && !symbolic_operand (operands[1], DImode)
1898 && !x86_64_immediate_operand (operands[1], DImode)"
1899 [(set (match_dup 0) (match_dup 1))
1900 (set (match_dup 2) (match_dup 3))]
1901 "split_di (operands + 1, 1, operands + 2, operands + 3);
1902 operands[1] = gen_lowpart (DImode, operands[2]);
1903 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1904 GEN_INT (4)));
1905 ")
1906
1907(define_insn "*pushdi2_prologue_rex64"
1908 [(set (match_operand:DI 0 "push_operand" "=<")
1909 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1910 (clobber (mem:BLK (scratch)))]
1911 "TARGET_64BIT"
1912 "push{q}\t%1"
1913 [(set_attr "type" "push")
1914 (set_attr "mode" "DI")])
1915
1916(define_insn "*popdi1_epilogue_rex64"
1917 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918 (mem:DI (reg:DI SP_REG)))
1919 (set (reg:DI SP_REG)
1920 (plus:DI (reg:DI SP_REG) (const_int 8)))
1921 (clobber (mem:BLK (scratch)))]
1922 "TARGET_64BIT"
1923 "pop{q}\t%0"
1924 [(set_attr "type" "pop")
1925 (set_attr "mode" "DI")])
1926
1927(define_insn "popdi1"
1928 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1929 (mem:DI (reg:DI SP_REG)))
1930 (set (reg:DI SP_REG)
1931 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1932 "TARGET_64BIT"
1933 "pop{q}\t%0"
1934 [(set_attr "type" "pop")
1935 (set_attr "mode" "DI")])
1936
1937(define_insn "*movdi_xor_rex64"
1938 [(set (match_operand:DI 0 "register_operand" "=r")
1939 (match_operand:DI 1 "const0_operand" "i"))
1940 (clobber (reg:CC FLAGS_REG))]
1941 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1942 && reload_completed"
1943 "xor{l}\t{%k0, %k0|%k0, %k0}"
1944 [(set_attr "type" "alu1")
1945 (set_attr "mode" "SI")
1946 (set_attr "length_immediate" "0")])
1947
1948(define_insn "*movdi_or_rex64"
1949 [(set (match_operand:DI 0 "register_operand" "=r")
1950 (match_operand:DI 1 "const_int_operand" "i"))
1951 (clobber (reg:CC FLAGS_REG))]
1952 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1953 && reload_completed
1954 && operands[1] == constm1_rtx"
1955{
1956 operands[1] = constm1_rtx;
1957 return "or{q}\t{%1, %0|%0, %1}";
1958}
1959 [(set_attr "type" "alu1")
1960 (set_attr "mode" "DI")
1961 (set_attr "length_immediate" "1")])
1962
1963(define_insn "*movdi_2"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1966 (match_operand:DI 1 "general_operand"
1967 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1968 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969 "@
1970 #
1971 #
1972 pxor\t%0, %0
1973 movq\t{%1, %0|%0, %1}
1974 movq\t{%1, %0|%0, %1}
1975 pxor\t%0, %0
1976 movq\t{%1, %0|%0, %1}
1977 movdqa\t{%1, %0|%0, %1}
1978 movq\t{%1, %0|%0, %1}
1979 xorps\t%0, %0
1980 movlps\t{%1, %0|%0, %1}
1981 movaps\t{%1, %0|%0, %1}
1982 movlps\t{%1, %0|%0, %1}"
1983 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1984 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1985
1986(define_split
1987 [(set (match_operand:DI 0 "push_operand" "")
1988 (match_operand:DI 1 "general_operand" ""))]
1989 "!TARGET_64BIT && reload_completed
1990 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1991 [(const_int 0)]
1992 "ix86_split_long_move (operands); DONE;")
1993
1994;; %%% This multiword shite has got to go.
1995(define_split
1996 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1997 (match_operand:DI 1 "general_operand" ""))]
1998 "!TARGET_64BIT && reload_completed
1999 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2000 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2001 [(const_int 0)]
2002 "ix86_split_long_move (operands); DONE;")
2003
2004(define_insn "*movdi_1_rex64"
2005 [(set (match_operand:DI 0 "nonimmediate_operand"
2006 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2007 (match_operand:DI 1 "general_operand"
2008 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2009 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2010{
2011 switch (get_attr_type (insn))
2012 {
2013 case TYPE_SSECVT:
2014 if (which_alternative == 13)
2015 return "movq2dq\t{%1, %0|%0, %1}";
2016 else
2017 return "movdq2q\t{%1, %0|%0, %1}";
2018 case TYPE_SSEMOV:
2019 if (get_attr_mode (insn) == MODE_TI)
2020 return "movdqa\t{%1, %0|%0, %1}";
2021 /* FALLTHRU */
2022 case TYPE_MMXMOV:
2023 /* Moves from and into integer register is done using movd opcode with
2024 REX prefix. */
2025 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2026 return "movd\t{%1, %0|%0, %1}";
2027 return "movq\t{%1, %0|%0, %1}";
2028 case TYPE_SSELOG1:
2029 case TYPE_MMXADD:
2030 return "pxor\t%0, %0";
2031 case TYPE_MULTI:
2032 return "#";
2033 case TYPE_LEA:
2034 return "lea{q}\t{%a1, %0|%0, %a1}";
2035 default:
2036 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2037 if (get_attr_mode (insn) == MODE_SI)
2038 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2039 else if (which_alternative == 2)
2040 return "movabs{q}\t{%1, %0|%0, %1}";
2041 else
2042 return "mov{q}\t{%1, %0|%0, %1}";
2043 }
2044}
2045 [(set (attr "type")
2046 (cond [(eq_attr "alternative" "5")
2047 (const_string "mmxadd")
2048 (eq_attr "alternative" "6,7,8")
2049 (const_string "mmxmov")
2050 (eq_attr "alternative" "9")
2051 (const_string "sselog1")
2052 (eq_attr "alternative" "10,11,12")
2053 (const_string "ssemov")
2054 (eq_attr "alternative" "13,14")
2055 (const_string "ssecvt")
2056 (eq_attr "alternative" "4")
2057 (const_string "multi")
2058 (match_operand:DI 1 "pic_32bit_operand" "")
2059 (const_string "lea")
2060 ]
2061 (const_string "imov")))
2062 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2063 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2064 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2065
2066;; Stores and loads of ax to arbitrary constant address.
2067;; We fake an second form of instruction to force reload to load address
2068;; into register when rax is not available
2069(define_insn "*movabsdi_1_rex64"
2070 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2071 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2072 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2073 "@
2074 movabs{q}\t{%1, %P0|%P0, %1}
2075 mov{q}\t{%1, %a0|%a0, %1}"
2076 [(set_attr "type" "imov")
2077 (set_attr "modrm" "0,*")
2078 (set_attr "length_address" "8,0")
2079 (set_attr "length_immediate" "0,*")
2080 (set_attr "memory" "store")
2081 (set_attr "mode" "DI")])
2082
2083(define_insn "*movabsdi_2_rex64"
2084 [(set (match_operand:DI 0 "register_operand" "=a,r")
2085 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2086 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2087 "@
2088 movabs{q}\t{%P1, %0|%0, %P1}
2089 mov{q}\t{%a1, %0|%0, %a1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "modrm" "0,*")
2092 (set_attr "length_address" "8,0")
2093 (set_attr "length_immediate" "0")
2094 (set_attr "memory" "load")
2095 (set_attr "mode" "DI")])
2096
2097;; Convert impossible stores of immediate to existing instructions.
2098;; First try to get scratch register and go through it. In case this
2099;; fails, move by 32bit parts.
2100(define_peephole2
2101 [(match_scratch:DI 2 "r")
2102 (set (match_operand:DI 0 "memory_operand" "")
2103 (match_operand:DI 1 "immediate_operand" ""))]
2104 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2105 && !x86_64_immediate_operand (operands[1], DImode)"
2106 [(set (match_dup 2) (match_dup 1))
2107 (set (match_dup 0) (match_dup 2))]
2108 "")
2109
2110;; We need to define this as both peepholer and splitter for case
2111;; peephole2 pass is not run.
2112;; "&& 1" is needed to keep it from matching the previous pattern.
2113(define_peephole2
2114 [(set (match_operand:DI 0 "memory_operand" "")
2115 (match_operand:DI 1 "immediate_operand" ""))]
2116 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2118 [(set (match_dup 2) (match_dup 3))
2119 (set (match_dup 4) (match_dup 5))]
2120 "split_di (operands, 2, operands + 2, operands + 4);")
2121
2122(define_split
2123 [(set (match_operand:DI 0 "memory_operand" "")
2124 (match_operand:DI 1 "immediate_operand" ""))]
2125 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2126 ? flow2_completed : reload_completed)
2127 && !symbolic_operand (operands[1], DImode)
2128 && !x86_64_immediate_operand (operands[1], DImode)"
2129 [(set (match_dup 2) (match_dup 3))
2130 (set (match_dup 4) (match_dup 5))]
2131 "split_di (operands, 2, operands + 2, operands + 4);")
2132
2133(define_insn "*swapdi_rex64"
2134 [(set (match_operand:DI 0 "register_operand" "+r")
2135 (match_operand:DI 1 "register_operand" "+r"))
2136 (set (match_dup 1)
2137 (match_dup 0))]
2138 "TARGET_64BIT"
2139 "xchg{q}\t%1, %0"
2140 [(set_attr "type" "imov")
2141 (set_attr "mode" "DI")
2142 (set_attr "pent_pair" "np")
2123 (set_attr "athlon_decode" "vector")])
2143 (set_attr "athlon_decode" "vector")
2144 (set_attr "amdfam10_decode" "double")])
2124
2125(define_expand "movti"
2126 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2127 (match_operand:TI 1 "nonimmediate_operand" ""))]
2128 "TARGET_SSE || TARGET_64BIT"
2129{
2130 if (TARGET_64BIT)
2131 ix86_expand_move (TImode, operands);
2132 else
2133 ix86_expand_vector_move (TImode, operands);
2134 DONE;
2135})
2136
2137(define_insn "*movti_internal"
2138 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2139 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2140 "TARGET_SSE && !TARGET_64BIT
2141 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2142{
2143 switch (which_alternative)
2144 {
2145 case 0:
2146 if (get_attr_mode (insn) == MODE_V4SF)
2147 return "xorps\t%0, %0";
2148 else
2149 return "pxor\t%0, %0";
2150 case 1:
2151 case 2:
2152 if (get_attr_mode (insn) == MODE_V4SF)
2153 return "movaps\t{%1, %0|%0, %1}";
2154 else
2155 return "movdqa\t{%1, %0|%0, %1}";
2156 default:
2157 gcc_unreachable ();
2158 }
2159}
2160 [(set_attr "type" "sselog1,ssemov,ssemov")
2161 (set (attr "mode")
2162 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2163 (ne (symbol_ref "optimize_size") (const_int 0)))
2164 (const_string "V4SF")
2165 (and (eq_attr "alternative" "2")
2166 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2167 (const_int 0)))
2168 (const_string "V4SF")]
2169 (const_string "TI")))])
2170
2171(define_insn "*movti_rex64"
2172 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2173 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2174 "TARGET_64BIT
2175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2176{
2177 switch (which_alternative)
2178 {
2179 case 0:
2180 case 1:
2181 return "#";
2182 case 2:
2183 if (get_attr_mode (insn) == MODE_V4SF)
2184 return "xorps\t%0, %0";
2185 else
2186 return "pxor\t%0, %0";
2187 case 3:
2188 case 4:
2189 if (get_attr_mode (insn) == MODE_V4SF)
2190 return "movaps\t{%1, %0|%0, %1}";
2191 else
2192 return "movdqa\t{%1, %0|%0, %1}";
2193 default:
2194 gcc_unreachable ();
2195 }
2196}
2197 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2198 (set (attr "mode")
2199 (cond [(eq_attr "alternative" "2,3")
2200 (if_then_else
2201 (ne (symbol_ref "optimize_size")
2202 (const_int 0))
2203 (const_string "V4SF")
2204 (const_string "TI"))
2205 (eq_attr "alternative" "4")
2206 (if_then_else
2207 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2208 (const_int 0))
2209 (ne (symbol_ref "optimize_size")
2210 (const_int 0)))
2211 (const_string "V4SF")
2212 (const_string "TI"))]
2213 (const_string "DI")))])
2214
2215(define_split
2216 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2217 (match_operand:TI 1 "general_operand" ""))]
2218 "reload_completed && !SSE_REG_P (operands[0])
2219 && !SSE_REG_P (operands[1])"
2220 [(const_int 0)]
2221 "ix86_split_long_move (operands); DONE;")
2222
2223(define_expand "movsf"
2224 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2225 (match_operand:SF 1 "general_operand" ""))]
2226 ""
2227 "ix86_expand_move (SFmode, operands); DONE;")
2228
2229(define_insn "*pushsf"
2230 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2231 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2232 "!TARGET_64BIT"
2233{
2234 /* Anything else should be already split before reg-stack. */
2235 gcc_assert (which_alternative == 1);
2236 return "push{l}\t%1";
2237}
2238 [(set_attr "type" "multi,push,multi")
2239 (set_attr "unit" "i387,*,*")
2240 (set_attr "mode" "SF,SI,SF")])
2241
2242(define_insn "*pushsf_rex64"
2243 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2244 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2245 "TARGET_64BIT"
2246{
2247 /* Anything else should be already split before reg-stack. */
2248 gcc_assert (which_alternative == 1);
2249 return "push{q}\t%q1";
2250}
2251 [(set_attr "type" "multi,push,multi")
2252 (set_attr "unit" "i387,*,*")
2253 (set_attr "mode" "SF,DI,SF")])
2254
2255(define_split
2256 [(set (match_operand:SF 0 "push_operand" "")
2257 (match_operand:SF 1 "memory_operand" ""))]
2258 "reload_completed
2259 && GET_CODE (operands[1]) == MEM
2260 && constant_pool_reference_p (operands[1])"
2261 [(set (match_dup 0)
2262 (match_dup 1))]
2263 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2264
2265
2266;; %%% Kill this when call knows how to work this out.
2267(define_split
2268 [(set (match_operand:SF 0 "push_operand" "")
2269 (match_operand:SF 1 "any_fp_register_operand" ""))]
2270 "!TARGET_64BIT"
2271 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2272 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2273
2274(define_split
2275 [(set (match_operand:SF 0 "push_operand" "")
2276 (match_operand:SF 1 "any_fp_register_operand" ""))]
2277 "TARGET_64BIT"
2278 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2279 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2280
2281(define_insn "*movsf_1"
2282 [(set (match_operand:SF 0 "nonimmediate_operand"
2283 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2284 (match_operand:SF 1 "general_operand"
2285 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2286 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2287 && (reload_in_progress || reload_completed
2288 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2289 || GET_CODE (operands[1]) != CONST_DOUBLE
2290 || memory_operand (operands[0], SFmode))"
2291{
2292 switch (which_alternative)
2293 {
2294 case 0:
2295 return output_387_reg_move (insn, operands);
2296
2297 case 1:
2298 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2299 return "fstp%z0\t%y0";
2300 else
2301 return "fst%z0\t%y0";
2302
2303 case 2:
2304 return standard_80387_constant_opcode (operands[1]);
2305
2306 case 3:
2307 case 4:
2308 return "mov{l}\t{%1, %0|%0, %1}";
2309 case 5:
2310 if (get_attr_mode (insn) == MODE_TI)
2311 return "pxor\t%0, %0";
2312 else
2313 return "xorps\t%0, %0";
2314 case 6:
2315 if (get_attr_mode (insn) == MODE_V4SF)
2316 return "movaps\t{%1, %0|%0, %1}";
2317 else
2318 return "movss\t{%1, %0|%0, %1}";
2319 case 7:
2320 case 8:
2321 return "movss\t{%1, %0|%0, %1}";
2322
2323 case 9:
2324 case 10:
2325 return "movd\t{%1, %0|%0, %1}";
2326
2327 case 11:
2328 return "movq\t{%1, %0|%0, %1}";
2329
2330 default:
2331 gcc_unreachable ();
2332 }
2333}
2334 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2335 (set (attr "mode")
2336 (cond [(eq_attr "alternative" "3,4,9,10")
2337 (const_string "SI")
2338 (eq_attr "alternative" "5")
2339 (if_then_else
2340 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2341 (const_int 0))
2342 (ne (symbol_ref "TARGET_SSE2")
2343 (const_int 0)))
2344 (eq (symbol_ref "optimize_size")
2345 (const_int 0)))
2346 (const_string "TI")
2347 (const_string "V4SF"))
2348 /* For architectures resolving dependencies on
2349 whole SSE registers use APS move to break dependency
2350 chains, otherwise use short move to avoid extra work.
2351
2352 Do the same for architectures resolving dependencies on
2353 the parts. While in DF mode it is better to always handle
2354 just register parts, the SF mode is different due to lack
2355 of instructions to load just part of the register. It is
2356 better to maintain the whole registers in single format
2357 to avoid problems on using packed logical operations. */
2358 (eq_attr "alternative" "6")
2359 (if_then_else
2360 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2361 (const_int 0))
2362 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2363 (const_int 0)))
2364 (const_string "V4SF")
2365 (const_string "SF"))
2366 (eq_attr "alternative" "11")
2367 (const_string "DI")]
2368 (const_string "SF")))])
2369
2370(define_insn "*swapsf"
2371 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2372 (match_operand:SF 1 "fp_register_operand" "+f"))
2373 (set (match_dup 1)
2374 (match_dup 0))]
2375 "reload_completed || TARGET_80387"
2376{
2377 if (STACK_TOP_P (operands[0]))
2378 return "fxch\t%1";
2379 else
2380 return "fxch\t%0";
2381}
2382 [(set_attr "type" "fxch")
2383 (set_attr "mode" "SF")])
2384
2385(define_expand "movdf"
2386 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2387 (match_operand:DF 1 "general_operand" ""))]
2388 ""
2389 "ix86_expand_move (DFmode, operands); DONE;")
2390
2391;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2392;; Size of pushdf using integer instructions is 2+2*memory operand size
2393;; On the average, pushdf using integers can be still shorter. Allow this
2394;; pattern for optimize_size too.
2395
2396(define_insn "*pushdf_nointeger"
2397 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2398 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2399 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2400{
2401 /* This insn should be already split before reg-stack. */
2402 gcc_unreachable ();
2403}
2404 [(set_attr "type" "multi")
2405 (set_attr "unit" "i387,*,*,*")
2406 (set_attr "mode" "DF,SI,SI,DF")])
2407
2408(define_insn "*pushdf_integer"
2409 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2410 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2411 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2412{
2413 /* This insn should be already split before reg-stack. */
2414 gcc_unreachable ();
2415}
2416 [(set_attr "type" "multi")
2417 (set_attr "unit" "i387,*,*")
2418 (set_attr "mode" "DF,SI,DF")])
2419
2420;; %%% Kill this when call knows how to work this out.
2421(define_split
2422 [(set (match_operand:DF 0 "push_operand" "")
2423 (match_operand:DF 1 "any_fp_register_operand" ""))]
2424 "!TARGET_64BIT && reload_completed"
2425 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2426 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2427 "")
2428
2429(define_split
2430 [(set (match_operand:DF 0 "push_operand" "")
2431 (match_operand:DF 1 "any_fp_register_operand" ""))]
2432 "TARGET_64BIT && reload_completed"
2433 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2434 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2435 "")
2436
2437(define_split
2438 [(set (match_operand:DF 0 "push_operand" "")
2439 (match_operand:DF 1 "general_operand" ""))]
2440 "reload_completed"
2441 [(const_int 0)]
2442 "ix86_split_long_move (operands); DONE;")
2443
2444;; Moving is usually shorter when only FP registers are used. This separate
2445;; movdf pattern avoids the use of integer registers for FP operations
2446;; when optimizing for size.
2447
2448(define_insn "*movdf_nointeger"
2449 [(set (match_operand:DF 0 "nonimmediate_operand"
2450 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2451 (match_operand:DF 1 "general_operand"
2452 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
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 gcc_unreachable ();
2488 }
2489 case 6:
2490 case 7:
2491 case 8:
2492 switch (get_attr_mode (insn))
2493 {
2494 case MODE_V4SF:
2495 return "movaps\t{%1, %0|%0, %1}";
2496 case MODE_V2DF:
2497 return "movapd\t{%1, %0|%0, %1}";
2498 case MODE_TI:
2499 return "movdqa\t{%1, %0|%0, %1}";
2500 case MODE_DI:
2501 return "movq\t{%1, %0|%0, %1}";
2502 case MODE_DF:
2503 return "movsd\t{%1, %0|%0, %1}";
2504 case MODE_V1DF:
2505 return "movlpd\t{%1, %0|%0, %1}";
2506 case MODE_V2SF:
2507 return "movlps\t{%1, %0|%0, %1}";
2508 default:
2509 gcc_unreachable ();
2510 }
2511
2512 default:
2513 gcc_unreachable ();
2514 }
2515}
2516 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2517 (set (attr "mode")
2518 (cond [(eq_attr "alternative" "0,1,2")
2519 (const_string "DF")
2520 (eq_attr "alternative" "3,4")
2521 (const_string "SI")
2522
2523 /* For SSE1, we have many fewer alternatives. */
2524 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2525 (cond [(eq_attr "alternative" "5,6")
2526 (const_string "V4SF")
2527 ]
2528 (const_string "V2SF"))
2529
2530 /* xorps is one byte shorter. */
2531 (eq_attr "alternative" "5")
2532 (cond [(ne (symbol_ref "optimize_size")
2533 (const_int 0))
2534 (const_string "V4SF")
2535 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2536 (const_int 0))
2537 (const_string "TI")
2538 ]
2539 (const_string "V2DF"))
2540
2541 /* For architectures resolving dependencies on
2542 whole SSE registers use APD move to break dependency
2543 chains, otherwise use short move to avoid extra work.
2544
2545 movaps encodes one byte shorter. */
2546 (eq_attr "alternative" "6")
2547 (cond
2548 [(ne (symbol_ref "optimize_size")
2549 (const_int 0))
2550 (const_string "V4SF")
2551 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2552 (const_int 0))
2553 (const_string "V2DF")
2554 ]
2555 (const_string "DF"))
2556 /* For architectures resolving dependencies on register
2557 parts we may avoid extra work to zero out upper part
2558 of register. */
2559 (eq_attr "alternative" "7")
2560 (if_then_else
2561 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2562 (const_int 0))
2563 (const_string "V1DF")
2564 (const_string "DF"))
2565 ]
2566 (const_string "DF")))])
2567
2568(define_insn "*movdf_integer"
2569 [(set (match_operand:DF 0 "nonimmediate_operand"
2570 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2571 (match_operand:DF 1 "general_operand"
2572 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2573 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2574 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2575 && (reload_in_progress || reload_completed
2576 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2577 || GET_CODE (operands[1]) != CONST_DOUBLE
2578 || memory_operand (operands[0], DFmode))"
2579{
2580 switch (which_alternative)
2581 {
2582 case 0:
2583 return output_387_reg_move (insn, operands);
2584
2585 case 1:
2586 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2587 return "fstp%z0\t%y0";
2588 else
2589 return "fst%z0\t%y0";
2590
2591 case 2:
2592 return standard_80387_constant_opcode (operands[1]);
2593
2594 case 3:
2595 case 4:
2596 return "#";
2597
2598 case 5:
2599 switch (get_attr_mode (insn))
2600 {
2601 case MODE_V4SF:
2602 return "xorps\t%0, %0";
2603 case MODE_V2DF:
2604 return "xorpd\t%0, %0";
2605 case MODE_TI:
2606 return "pxor\t%0, %0";
2607 default:
2608 gcc_unreachable ();
2609 }
2610 case 6:
2611 case 7:
2612 case 8:
2613 switch (get_attr_mode (insn))
2614 {
2615 case MODE_V4SF:
2616 return "movaps\t{%1, %0|%0, %1}";
2617 case MODE_V2DF:
2618 return "movapd\t{%1, %0|%0, %1}";
2619 case MODE_TI:
2620 return "movdqa\t{%1, %0|%0, %1}";
2621 case MODE_DI:
2622 return "movq\t{%1, %0|%0, %1}";
2623 case MODE_DF:
2624 return "movsd\t{%1, %0|%0, %1}";
2625 case MODE_V1DF:
2626 return "movlpd\t{%1, %0|%0, %1}";
2627 case MODE_V2SF:
2628 return "movlps\t{%1, %0|%0, %1}";
2629 default:
2630 gcc_unreachable ();
2631 }
2632
2633 default:
2634 gcc_unreachable();
2635 }
2636}
2637 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2638 (set (attr "mode")
2639 (cond [(eq_attr "alternative" "0,1,2")
2640 (const_string "DF")
2641 (eq_attr "alternative" "3,4")
2642 (const_string "SI")
2643
2644 /* For SSE1, we have many fewer alternatives. */
2645 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2646 (cond [(eq_attr "alternative" "5,6")
2647 (const_string "V4SF")
2648 ]
2649 (const_string "V2SF"))
2650
2651 /* xorps is one byte shorter. */
2652 (eq_attr "alternative" "5")
2653 (cond [(ne (symbol_ref "optimize_size")
2654 (const_int 0))
2655 (const_string "V4SF")
2656 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2657 (const_int 0))
2658 (const_string "TI")
2659 ]
2660 (const_string "V2DF"))
2661
2662 /* For architectures resolving dependencies on
2663 whole SSE registers use APD move to break dependency
2664 chains, otherwise use short move to avoid extra work.
2665
2666 movaps encodes one byte shorter. */
2667 (eq_attr "alternative" "6")
2668 (cond
2669 [(ne (symbol_ref "optimize_size")
2670 (const_int 0))
2671 (const_string "V4SF")
2672 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2673 (const_int 0))
2674 (const_string "V2DF")
2675 ]
2676 (const_string "DF"))
2677 /* For architectures resolving dependencies on register
2678 parts we may avoid extra work to zero out upper part
2679 of register. */
2680 (eq_attr "alternative" "7")
2681 (if_then_else
2682 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2683 (const_int 0))
2684 (const_string "V1DF")
2685 (const_string "DF"))
2686 ]
2687 (const_string "DF")))])
2688
2689(define_split
2690 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2691 (match_operand:DF 1 "general_operand" ""))]
2692 "reload_completed
2693 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2694 && ! (ANY_FP_REG_P (operands[0]) ||
2695 (GET_CODE (operands[0]) == SUBREG
2696 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2697 && ! (ANY_FP_REG_P (operands[1]) ||
2698 (GET_CODE (operands[1]) == SUBREG
2699 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2700 [(const_int 0)]
2701 "ix86_split_long_move (operands); DONE;")
2702
2703(define_insn "*swapdf"
2704 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2705 (match_operand:DF 1 "fp_register_operand" "+f"))
2706 (set (match_dup 1)
2707 (match_dup 0))]
2708 "reload_completed || TARGET_80387"
2709{
2710 if (STACK_TOP_P (operands[0]))
2711 return "fxch\t%1";
2712 else
2713 return "fxch\t%0";
2714}
2715 [(set_attr "type" "fxch")
2716 (set_attr "mode" "DF")])
2717
2718(define_expand "movxf"
2719 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2720 (match_operand:XF 1 "general_operand" ""))]
2721 ""
2722 "ix86_expand_move (XFmode, operands); DONE;")
2723
2724;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2725;; Size of pushdf using integer instructions is 3+3*memory operand size
2726;; Pushing using integer instructions is longer except for constants
2727;; and direct memory references.
2728;; (assuming that any given constant is pushed only once, but this ought to be
2729;; handled elsewhere).
2730
2731(define_insn "*pushxf_nointeger"
2732 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2733 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2734 "optimize_size"
2735{
2736 /* This insn should be already split before reg-stack. */
2737 gcc_unreachable ();
2738}
2739 [(set_attr "type" "multi")
2740 (set_attr "unit" "i387,*,*")
2741 (set_attr "mode" "XF,SI,SI")])
2742
2743(define_insn "*pushxf_integer"
2744 [(set (match_operand:XF 0 "push_operand" "=<,<")
2745 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2746 "!optimize_size"
2747{
2748 /* This insn should be already split before reg-stack. */
2749 gcc_unreachable ();
2750}
2751 [(set_attr "type" "multi")
2752 (set_attr "unit" "i387,*")
2753 (set_attr "mode" "XF,SI")])
2754
2755(define_split
2756 [(set (match_operand 0 "push_operand" "")
2757 (match_operand 1 "general_operand" ""))]
2758 "reload_completed
2759 && (GET_MODE (operands[0]) == XFmode
2760 || GET_MODE (operands[0]) == DFmode)
2761 && !ANY_FP_REG_P (operands[1])"
2762 [(const_int 0)]
2763 "ix86_split_long_move (operands); DONE;")
2764
2765(define_split
2766 [(set (match_operand:XF 0 "push_operand" "")
2767 (match_operand:XF 1 "any_fp_register_operand" ""))]
2768 "!TARGET_64BIT"
2769 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2770 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2771 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772
2773(define_split
2774 [(set (match_operand:XF 0 "push_operand" "")
2775 (match_operand:XF 1 "any_fp_register_operand" ""))]
2776 "TARGET_64BIT"
2777 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2778 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2780
2781;; Do not use integer registers when optimizing for size
2782(define_insn "*movxf_nointeger"
2783 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2784 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785 "optimize_size
2786 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2787 && (reload_in_progress || reload_completed
2788 || GET_CODE (operands[1]) != CONST_DOUBLE
2789 || memory_operand (operands[0], XFmode))"
2790{
2791 switch (which_alternative)
2792 {
2793 case 0:
2794 return output_387_reg_move (insn, operands);
2795
2796 case 1:
2797 /* There is no non-popping store to memory for XFmode. So if
2798 we need one, follow the store with a load. */
2799 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2800 return "fstp%z0\t%y0\;fld%z0\t%y0";
2801 else
2802 return "fstp%z0\t%y0";
2803
2804 case 2:
2805 return standard_80387_constant_opcode (operands[1]);
2806
2807 case 3: case 4:
2808 return "#";
2809 default:
2810 gcc_unreachable ();
2811 }
2812}
2813 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2814 (set_attr "mode" "XF,XF,XF,SI,SI")])
2815
2816(define_insn "*movxf_integer"
2817 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2818 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2819 "!optimize_size
2820 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2821 && (reload_in_progress || reload_completed
2822 || GET_CODE (operands[1]) != CONST_DOUBLE
2823 || memory_operand (operands[0], XFmode))"
2824{
2825 switch (which_alternative)
2826 {
2827 case 0:
2828 return output_387_reg_move (insn, operands);
2829
2830 case 1:
2831 /* There is no non-popping store to memory for XFmode. So if
2832 we need one, follow the store with a load. */
2833 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2834 return "fstp%z0\t%y0\;fld%z0\t%y0";
2835 else
2836 return "fstp%z0\t%y0";
2837
2838 case 2:
2839 return standard_80387_constant_opcode (operands[1]);
2840
2841 case 3: case 4:
2842 return "#";
2843
2844 default:
2845 gcc_unreachable ();
2846 }
2847}
2848 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2849 (set_attr "mode" "XF,XF,XF,SI,SI")])
2850
2851(define_split
2852 [(set (match_operand 0 "nonimmediate_operand" "")
2853 (match_operand 1 "general_operand" ""))]
2854 "reload_completed
2855 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2856 && GET_MODE (operands[0]) == XFmode
2857 && ! (ANY_FP_REG_P (operands[0]) ||
2858 (GET_CODE (operands[0]) == SUBREG
2859 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2860 && ! (ANY_FP_REG_P (operands[1]) ||
2861 (GET_CODE (operands[1]) == SUBREG
2862 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2863 [(const_int 0)]
2864 "ix86_split_long_move (operands); DONE;")
2865
2866(define_split
2867 [(set (match_operand 0 "register_operand" "")
2868 (match_operand 1 "memory_operand" ""))]
2869 "reload_completed
2870 && GET_CODE (operands[1]) == MEM
2871 && (GET_MODE (operands[0]) == XFmode
2872 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2873 && constant_pool_reference_p (operands[1])"
2874 [(set (match_dup 0) (match_dup 1))]
2875{
2876 rtx c = avoid_constant_pool_reference (operands[1]);
2877 rtx r = operands[0];
2878
2879 if (GET_CODE (r) == SUBREG)
2880 r = SUBREG_REG (r);
2881
2882 if (SSE_REG_P (r))
2883 {
2884 if (!standard_sse_constant_p (c))
2885 FAIL;
2886 }
2887 else if (FP_REG_P (r))
2888 {
2889 if (!standard_80387_constant_p (c))
2890 FAIL;
2891 }
2892 else if (MMX_REG_P (r))
2893 FAIL;
2894
2895 operands[1] = c;
2896})
2897
2898(define_insn "swapxf"
2899 [(set (match_operand:XF 0 "register_operand" "+f")
2900 (match_operand:XF 1 "register_operand" "+f"))
2901 (set (match_dup 1)
2902 (match_dup 0))]
2903 "TARGET_80387"
2904{
2905 if (STACK_TOP_P (operands[0]))
2906 return "fxch\t%1";
2907 else
2908 return "fxch\t%0";
2909}
2910 [(set_attr "type" "fxch")
2911 (set_attr "mode" "XF")])
2912
2913(define_expand "movtf"
2914 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2915 (match_operand:TF 1 "nonimmediate_operand" ""))]
2916 "TARGET_64BIT"
2917{
2918 ix86_expand_move (TFmode, operands);
2919 DONE;
2920})
2921
2922(define_insn "*movtf_internal"
2923 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2924 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2925 "TARGET_64BIT
2926 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2927{
2928 switch (which_alternative)
2929 {
2930 case 0:
2931 case 1:
2932 return "#";
2933 case 2:
2934 if (get_attr_mode (insn) == MODE_V4SF)
2935 return "xorps\t%0, %0";
2936 else
2937 return "pxor\t%0, %0";
2938 case 3:
2939 case 4:
2940 if (get_attr_mode (insn) == MODE_V4SF)
2941 return "movaps\t{%1, %0|%0, %1}";
2942 else
2943 return "movdqa\t{%1, %0|%0, %1}";
2944 default:
2945 gcc_unreachable ();
2946 }
2947}
2948 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2949 (set (attr "mode")
2950 (cond [(eq_attr "alternative" "2,3")
2951 (if_then_else
2952 (ne (symbol_ref "optimize_size")
2953 (const_int 0))
2954 (const_string "V4SF")
2955 (const_string "TI"))
2956 (eq_attr "alternative" "4")
2957 (if_then_else
2958 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2959 (const_int 0))
2960 (ne (symbol_ref "optimize_size")
2961 (const_int 0)))
2962 (const_string "V4SF")
2963 (const_string "TI"))]
2964 (const_string "DI")))])
2965
2966(define_split
2967 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2968 (match_operand:TF 1 "general_operand" ""))]
2969 "reload_completed && !SSE_REG_P (operands[0])
2970 && !SSE_REG_P (operands[1])"
2971 [(const_int 0)]
2972 "ix86_split_long_move (operands); DONE;")
2973
2974;; Zero extension instructions
2975
2976(define_expand "zero_extendhisi2"
2977 [(set (match_operand:SI 0 "register_operand" "")
2978 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2979 ""
2980{
2981 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2982 {
2983 operands[1] = force_reg (HImode, operands[1]);
2984 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2985 DONE;
2986 }
2987})
2988
2989(define_insn "zero_extendhisi2_and"
2990 [(set (match_operand:SI 0 "register_operand" "=r")
2991 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2992 (clobber (reg:CC FLAGS_REG))]
2993 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994 "#"
2995 [(set_attr "type" "alu1")
2996 (set_attr "mode" "SI")])
2997
2998(define_split
2999 [(set (match_operand:SI 0 "register_operand" "")
3000 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3001 (clobber (reg:CC FLAGS_REG))]
3002 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3003 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3004 (clobber (reg:CC FLAGS_REG))])]
3005 "")
3006
3007(define_insn "*zero_extendhisi2_movzwl"
3008 [(set (match_operand:SI 0 "register_operand" "=r")
3009 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3010 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3011 "movz{wl|x}\t{%1, %0|%0, %1}"
3012 [(set_attr "type" "imovx")
3013 (set_attr "mode" "SI")])
3014
3015(define_expand "zero_extendqihi2"
3016 [(parallel
3017 [(set (match_operand:HI 0 "register_operand" "")
3018 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3019 (clobber (reg:CC FLAGS_REG))])]
3020 ""
3021 "")
3022
3023(define_insn "*zero_extendqihi2_and"
3024 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3025 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026 (clobber (reg:CC FLAGS_REG))]
3027 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028 "#"
3029 [(set_attr "type" "alu1")
3030 (set_attr "mode" "HI")])
3031
3032(define_insn "*zero_extendqihi2_movzbw_and"
3033 [(set (match_operand:HI 0 "register_operand" "=r,r")
3034 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035 (clobber (reg:CC FLAGS_REG))]
3036 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037 "#"
3038 [(set_attr "type" "imovx,alu1")
3039 (set_attr "mode" "HI")])
3040
3041; zero extend to SImode here to avoid partial register stalls
3042(define_insn "*zero_extendqihi2_movzbl"
3043 [(set (match_operand:HI 0 "register_operand" "=r")
3044 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3045 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3046 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3047 [(set_attr "type" "imovx")
3048 (set_attr "mode" "SI")])
3049
3050;; For the movzbw case strip only the clobber
3051(define_split
3052 [(set (match_operand:HI 0 "register_operand" "")
3053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3054 (clobber (reg:CC FLAGS_REG))]
3055 "reload_completed
3056 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3057 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3058 [(set (match_operand:HI 0 "register_operand" "")
3059 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3060
3061;; When source and destination does not overlap, clear destination
3062;; first and then do the movb
3063(define_split
3064 [(set (match_operand:HI 0 "register_operand" "")
3065 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3066 (clobber (reg:CC FLAGS_REG))]
3067 "reload_completed
3068 && ANY_QI_REG_P (operands[0])
3069 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071 [(set (match_dup 0) (const_int 0))
3072 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073 "operands[2] = gen_lowpart (QImode, operands[0]);")
3074
3075;; Rest is handled by single and.
3076(define_split
3077 [(set (match_operand:HI 0 "register_operand" "")
3078 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3079 (clobber (reg:CC FLAGS_REG))]
3080 "reload_completed
3081 && true_regnum (operands[0]) == true_regnum (operands[1])"
3082 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3083 (clobber (reg:CC FLAGS_REG))])]
3084 "")
3085
3086(define_expand "zero_extendqisi2"
3087 [(parallel
3088 [(set (match_operand:SI 0 "register_operand" "")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3090 (clobber (reg:CC FLAGS_REG))])]
3091 ""
3092 "")
3093
3094(define_insn "*zero_extendqisi2_and"
3095 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3096 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3097 (clobber (reg:CC FLAGS_REG))]
3098 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3099 "#"
3100 [(set_attr "type" "alu1")
3101 (set_attr "mode" "SI")])
3102
3103(define_insn "*zero_extendqisi2_movzbw_and"
3104 [(set (match_operand:SI 0 "register_operand" "=r,r")
3105 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3106 (clobber (reg:CC FLAGS_REG))]
3107 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3108 "#"
3109 [(set_attr "type" "imovx,alu1")
3110 (set_attr "mode" "SI")])
3111
3112(define_insn "*zero_extendqisi2_movzbw"
3113 [(set (match_operand:SI 0 "register_operand" "=r")
3114 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3115 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3116 "movz{bl|x}\t{%1, %0|%0, %1}"
3117 [(set_attr "type" "imovx")
3118 (set_attr "mode" "SI")])
3119
3120;; For the movzbl case strip only the clobber
3121(define_split
3122 [(set (match_operand:SI 0 "register_operand" "")
3123 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3124 (clobber (reg:CC FLAGS_REG))]
3125 "reload_completed
3126 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3127 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3128 [(set (match_dup 0)
3129 (zero_extend:SI (match_dup 1)))])
3130
3131;; When source and destination does not overlap, clear destination
3132;; first and then do the movb
3133(define_split
3134 [(set (match_operand:SI 0 "register_operand" "")
3135 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3136 (clobber (reg:CC FLAGS_REG))]
3137 "reload_completed
3138 && ANY_QI_REG_P (operands[0])
3139 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3140 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3141 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3142 [(set (match_dup 0) (const_int 0))
3143 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3144 "operands[2] = gen_lowpart (QImode, operands[0]);")
3145
3146;; Rest is handled by single and.
3147(define_split
3148 [(set (match_operand:SI 0 "register_operand" "")
3149 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3150 (clobber (reg:CC FLAGS_REG))]
3151 "reload_completed
3152 && true_regnum (operands[0]) == true_regnum (operands[1])"
3153 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3154 (clobber (reg:CC FLAGS_REG))])]
3155 "")
3156
3157;; %%% Kill me once multi-word ops are sane.
3158(define_expand "zero_extendsidi2"
3159 [(set (match_operand:DI 0 "register_operand" "=r")
3160 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3161 ""
3162 "if (!TARGET_64BIT)
3163 {
3164 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3165 DONE;
3166 }
3167 ")
3168
3169(define_insn "zero_extendsidi2_32"
3170 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3171 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3172 (clobber (reg:CC FLAGS_REG))]
3173 "!TARGET_64BIT"
3174 "@
3175 #
3176 #
3177 #
3178 movd\t{%1, %0|%0, %1}
3179 movd\t{%1, %0|%0, %1}"
3180 [(set_attr "mode" "SI,SI,SI,DI,TI")
3181 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3182
3183(define_insn "zero_extendsidi2_rex64"
3184 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3185 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3186 "TARGET_64BIT"
3187 "@
3188 mov\t{%k1, %k0|%k0, %k1}
3189 #
3190 movd\t{%1, %0|%0, %1}
3191 movd\t{%1, %0|%0, %1}"
3192 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3193 (set_attr "mode" "SI,DI,SI,SI")])
3194
3195(define_split
3196 [(set (match_operand:DI 0 "memory_operand" "")
3197 (zero_extend:DI (match_dup 0)))]
3198 "TARGET_64BIT"
3199 [(set (match_dup 4) (const_int 0))]
3200 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3201
3202(define_split
3203 [(set (match_operand:DI 0 "register_operand" "")
3204 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3205 (clobber (reg:CC FLAGS_REG))]
3206 "!TARGET_64BIT && reload_completed
3207 && true_regnum (operands[0]) == true_regnum (operands[1])"
3208 [(set (match_dup 4) (const_int 0))]
3209 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3210
3211(define_split
3212 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3213 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3214 (clobber (reg:CC FLAGS_REG))]
3215 "!TARGET_64BIT && reload_completed
3216 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3217 [(set (match_dup 3) (match_dup 1))
3218 (set (match_dup 4) (const_int 0))]
3219 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3220
3221(define_insn "zero_extendhidi2"
3222 [(set (match_operand:DI 0 "register_operand" "=r")
3223 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3224 "TARGET_64BIT"
3225 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3226 [(set_attr "type" "imovx")
3227 (set_attr "mode" "DI")])
3228
3229(define_insn "zero_extendqidi2"
3230 [(set (match_operand:DI 0 "register_operand" "=r")
3231 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3232 "TARGET_64BIT"
3233 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3234 [(set_attr "type" "imovx")
3235 (set_attr "mode" "DI")])
3236
3237;; Sign extension instructions
3238
3239(define_expand "extendsidi2"
3240 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3241 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3242 (clobber (reg:CC FLAGS_REG))
3243 (clobber (match_scratch:SI 2 ""))])]
3244 ""
3245{
3246 if (TARGET_64BIT)
3247 {
3248 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3249 DONE;
3250 }
3251})
3252
3253(define_insn "*extendsidi2_1"
3254 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3255 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3256 (clobber (reg:CC FLAGS_REG))
3257 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3258 "!TARGET_64BIT"
3259 "#")
3260
3261(define_insn "extendsidi2_rex64"
3262 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3263 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3264 "TARGET_64BIT"
3265 "@
3266 {cltq|cdqe}
3267 movs{lq|x}\t{%1,%0|%0, %1}"
3268 [(set_attr "type" "imovx")
3269 (set_attr "mode" "DI")
3270 (set_attr "prefix_0f" "0")
3271 (set_attr "modrm" "0,1")])
3272
3273(define_insn "extendhidi2"
3274 [(set (match_operand:DI 0 "register_operand" "=r")
3275 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3276 "TARGET_64BIT"
3277 "movs{wq|x}\t{%1,%0|%0, %1}"
3278 [(set_attr "type" "imovx")
3279 (set_attr "mode" "DI")])
3280
3281(define_insn "extendqidi2"
3282 [(set (match_operand:DI 0 "register_operand" "=r")
3283 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3284 "TARGET_64BIT"
3285 "movs{bq|x}\t{%1,%0|%0, %1}"
3286 [(set_attr "type" "imovx")
3287 (set_attr "mode" "DI")])
3288
3289;; Extend to memory case when source register does die.
3290(define_split
3291 [(set (match_operand:DI 0 "memory_operand" "")
3292 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3293 (clobber (reg:CC FLAGS_REG))
3294 (clobber (match_operand:SI 2 "register_operand" ""))]
3295 "(reload_completed
3296 && dead_or_set_p (insn, operands[1])
3297 && !reg_mentioned_p (operands[1], operands[0]))"
3298 [(set (match_dup 3) (match_dup 1))
3299 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3300 (clobber (reg:CC FLAGS_REG))])
3301 (set (match_dup 4) (match_dup 1))]
3302 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3303
3304;; Extend to memory case when source register does not die.
3305(define_split
3306 [(set (match_operand:DI 0 "memory_operand" "")
3307 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3308 (clobber (reg:CC FLAGS_REG))
3309 (clobber (match_operand:SI 2 "register_operand" ""))]
3310 "reload_completed"
3311 [(const_int 0)]
3312{
3313 split_di (&operands[0], 1, &operands[3], &operands[4]);
3314
3315 emit_move_insn (operands[3], operands[1]);
3316
3317 /* Generate a cltd if possible and doing so it profitable. */
3318 if (true_regnum (operands[1]) == 0
3319 && true_regnum (operands[2]) == 1
3320 && (optimize_size || TARGET_USE_CLTD))
3321 {
3322 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3323 }
3324 else
3325 {
3326 emit_move_insn (operands[2], operands[1]);
3327 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3328 }
3329 emit_move_insn (operands[4], operands[2]);
3330 DONE;
3331})
3332
3333;; Extend to register case. Optimize case where source and destination
3334;; registers match and cases where we can use cltd.
3335(define_split
3336 [(set (match_operand:DI 0 "register_operand" "")
3337 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3338 (clobber (reg:CC FLAGS_REG))
3339 (clobber (match_scratch:SI 2 ""))]
3340 "reload_completed"
3341 [(const_int 0)]
3342{
3343 split_di (&operands[0], 1, &operands[3], &operands[4]);
3344
3345 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3346 emit_move_insn (operands[3], operands[1]);
3347
3348 /* Generate a cltd if possible and doing so it profitable. */
3349 if (true_regnum (operands[3]) == 0
3350 && (optimize_size || TARGET_USE_CLTD))
3351 {
3352 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3353 DONE;
3354 }
3355
3356 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3357 emit_move_insn (operands[4], operands[1]);
3358
3359 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3360 DONE;
3361})
3362
3363(define_insn "extendhisi2"
3364 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3365 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3366 ""
3367{
3368 switch (get_attr_prefix_0f (insn))
3369 {
3370 case 0:
3371 return "{cwtl|cwde}";
3372 default:
3373 return "movs{wl|x}\t{%1,%0|%0, %1}";
3374 }
3375}
3376 [(set_attr "type" "imovx")
3377 (set_attr "mode" "SI")
3378 (set (attr "prefix_0f")
3379 ;; movsx is short decodable while cwtl is vector decoded.
3380 (if_then_else (and (eq_attr "cpu" "!k6")
3381 (eq_attr "alternative" "0"))
3382 (const_string "0")
3383 (const_string "1")))
3384 (set (attr "modrm")
3385 (if_then_else (eq_attr "prefix_0f" "0")
3386 (const_string "0")
3387 (const_string "1")))])
3388
3389(define_insn "*extendhisi2_zext"
3390 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3391 (zero_extend:DI
3392 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3393 "TARGET_64BIT"
3394{
3395 switch (get_attr_prefix_0f (insn))
3396 {
3397 case 0:
3398 return "{cwtl|cwde}";
3399 default:
3400 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3401 }
3402}
3403 [(set_attr "type" "imovx")
3404 (set_attr "mode" "SI")
3405 (set (attr "prefix_0f")
3406 ;; movsx is short decodable while cwtl is vector decoded.
3407 (if_then_else (and (eq_attr "cpu" "!k6")
3408 (eq_attr "alternative" "0"))
3409 (const_string "0")
3410 (const_string "1")))
3411 (set (attr "modrm")
3412 (if_then_else (eq_attr "prefix_0f" "0")
3413 (const_string "0")
3414 (const_string "1")))])
3415
3416(define_insn "extendqihi2"
3417 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3418 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3419 ""
3420{
3421 switch (get_attr_prefix_0f (insn))
3422 {
3423 case 0:
3424 return "{cbtw|cbw}";
3425 default:
3426 return "movs{bw|x}\t{%1,%0|%0, %1}";
3427 }
3428}
3429 [(set_attr "type" "imovx")
3430 (set_attr "mode" "HI")
3431 (set (attr "prefix_0f")
3432 ;; movsx is short decodable while cwtl is vector decoded.
3433 (if_then_else (and (eq_attr "cpu" "!k6")
3434 (eq_attr "alternative" "0"))
3435 (const_string "0")
3436 (const_string "1")))
3437 (set (attr "modrm")
3438 (if_then_else (eq_attr "prefix_0f" "0")
3439 (const_string "0")
3440 (const_string "1")))])
3441
3442(define_insn "extendqisi2"
3443 [(set (match_operand:SI 0 "register_operand" "=r")
3444 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3445 ""
3446 "movs{bl|x}\t{%1,%0|%0, %1}"
3447 [(set_attr "type" "imovx")
3448 (set_attr "mode" "SI")])
3449
3450(define_insn "*extendqisi2_zext"
3451 [(set (match_operand:DI 0 "register_operand" "=r")
3452 (zero_extend:DI
3453 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3454 "TARGET_64BIT"
3455 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3456 [(set_attr "type" "imovx")
3457 (set_attr "mode" "SI")])
3458
3459;; Conversions between float and double.
3460
3461;; These are all no-ops in the model used for the 80387. So just
3462;; emit moves.
3463
3464;; %%% Kill these when call knows how to work out a DFmode push earlier.
3465(define_insn "*dummy_extendsfdf2"
3466 [(set (match_operand:DF 0 "push_operand" "=<")
3467 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3468 "0"
3469 "#")
3470
3471(define_split
3472 [(set (match_operand:DF 0 "push_operand" "")
3473 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474 "!TARGET_64BIT"
3475 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3476 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
3478(define_split
3479 [(set (match_operand:DF 0 "push_operand" "")
3480 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3481 "TARGET_64BIT"
3482 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3483 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3484
3485(define_insn "*dummy_extendsfxf2"
3486 [(set (match_operand:XF 0 "push_operand" "=<")
3487 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3488 "0"
3489 "#")
3490
3491(define_split
3492 [(set (match_operand:XF 0 "push_operand" "")
3493 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3494 ""
3495 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3496 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3497 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3498
3499(define_split
3500 [(set (match_operand:XF 0 "push_operand" "")
3501 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3502 "TARGET_64BIT"
3503 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3504 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3505 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3506
3507(define_split
3508 [(set (match_operand:XF 0 "push_operand" "")
3509 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3510 ""
3511 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3512 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3513 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3514
3515(define_split
3516 [(set (match_operand:XF 0 "push_operand" "")
3517 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3518 "TARGET_64BIT"
3519 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3520 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3521 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3522
3523(define_expand "extendsfdf2"
3524 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3525 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3526 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3527{
3528 /* ??? Needed for compress_float_constant since all fp constants
3529 are LEGITIMATE_CONSTANT_P. */
3530 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3531 {
3532 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3533 && standard_80387_constant_p (operands[1]) > 0)
3534 {
3535 operands[1] = simplify_const_unary_operation
3536 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3537 emit_move_insn_1 (operands[0], operands[1]);
3538 DONE;
3539 }
3540 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3541 }
3542 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3543 operands[1] = force_reg (SFmode, operands[1]);
3544})
3545
3546(define_insn "*extendsfdf2_mixed"
3547 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3548 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3549 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3550 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3551{
3552 switch (which_alternative)
3553 {
3554 case 0:
3555 return output_387_reg_move (insn, operands);
3556
3557 case 1:
3558 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3559 return "fstp%z0\t%y0";
3560 else
3561 return "fst%z0\t%y0";
3562
3563 case 2:
3564 return "cvtss2sd\t{%1, %0|%0, %1}";
3565
3566 default:
3567 gcc_unreachable ();
3568 }
3569}
3570 [(set_attr "type" "fmov,fmov,ssecvt")
3571 (set_attr "mode" "SF,XF,DF")])
3572
3573(define_insn "*extendsfdf2_sse"
3574 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3575 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3576 "TARGET_SSE2 && TARGET_SSE_MATH
3577 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3578 "cvtss2sd\t{%1, %0|%0, %1}"
3579 [(set_attr "type" "ssecvt")
3580 (set_attr "mode" "DF")])
3581
3582(define_insn "*extendsfdf2_i387"
3583 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3584 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3585 "TARGET_80387
3586 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3587{
3588 switch (which_alternative)
3589 {
3590 case 0:
3591 return output_387_reg_move (insn, operands);
3592
3593 case 1:
3594 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3595 return "fstp%z0\t%y0";
3596 else
3597 return "fst%z0\t%y0";
3598
3599 default:
3600 gcc_unreachable ();
3601 }
3602}
3603 [(set_attr "type" "fmov")
3604 (set_attr "mode" "SF,XF")])
3605
3606(define_expand "extendsfxf2"
3607 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3608 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3609 "TARGET_80387"
3610{
3611 /* ??? Needed for compress_float_constant since all fp constants
3612 are LEGITIMATE_CONSTANT_P. */
3613 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3614 {
3615 if (standard_80387_constant_p (operands[1]) > 0)
3616 {
3617 operands[1] = simplify_const_unary_operation
3618 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3619 emit_move_insn_1 (operands[0], operands[1]);
3620 DONE;
3621 }
3622 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3623 }
3624 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3625 operands[1] = force_reg (SFmode, operands[1]);
3626})
3627
3628(define_insn "*extendsfxf2_i387"
3629 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3630 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3631 "TARGET_80387
3632 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3633{
3634 switch (which_alternative)
3635 {
3636 case 0:
3637 return output_387_reg_move (insn, operands);
3638
3639 case 1:
3640 /* There is no non-popping store to memory for XFmode. So if
3641 we need one, follow the store with a load. */
3642 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3643 return "fstp%z0\t%y0";
3644 else
3645 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3646
3647 default:
3648 gcc_unreachable ();
3649 }
3650}
3651 [(set_attr "type" "fmov")
3652 (set_attr "mode" "SF,XF")])
3653
3654(define_expand "extenddfxf2"
3655 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3656 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3657 "TARGET_80387"
3658{
3659 /* ??? Needed for compress_float_constant since all fp constants
3660 are LEGITIMATE_CONSTANT_P. */
3661 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3662 {
3663 if (standard_80387_constant_p (operands[1]) > 0)
3664 {
3665 operands[1] = simplify_const_unary_operation
3666 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3667 emit_move_insn_1 (operands[0], operands[1]);
3668 DONE;
3669 }
3670 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3671 }
3672 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3673 operands[1] = force_reg (DFmode, operands[1]);
3674})
3675
3676(define_insn "*extenddfxf2_i387"
3677 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3678 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3679 "TARGET_80387
3680 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3681{
3682 switch (which_alternative)
3683 {
3684 case 0:
3685 return output_387_reg_move (insn, operands);
3686
3687 case 1:
3688 /* There is no non-popping store to memory for XFmode. So if
3689 we need one, follow the store with a load. */
3690 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3692 else
3693 return "fstp%z0\t%y0";
3694
3695 default:
3696 gcc_unreachable ();
3697 }
3698}
3699 [(set_attr "type" "fmov")
3700 (set_attr "mode" "DF,XF")])
3701
3702;; %%% This seems bad bad news.
3703;; This cannot output into an f-reg because there is no way to be sure
3704;; of truncating in that case. Otherwise this is just like a simple move
3705;; insn. So we pretend we can output to a reg in order to get better
3706;; register preferencing, but we really use a stack slot.
3707
3708;; Conversion from DFmode to SFmode.
3709
3710(define_expand "truncdfsf2"
3711 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3712 (float_truncate:SF
3713 (match_operand:DF 1 "nonimmediate_operand" "")))]
3714 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3715{
3716 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3717 operands[1] = force_reg (DFmode, operands[1]);
3718
3719 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3720 ;
3721 else if (flag_unsafe_math_optimizations)
3722 ;
3723 else
3724 {
3725 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3726 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3727 DONE;
3728 }
3729})
3730
3731(define_expand "truncdfsf2_with_temp"
3732 [(parallel [(set (match_operand:SF 0 "" "")
3733 (float_truncate:SF (match_operand:DF 1 "" "")))
3734 (clobber (match_operand:SF 2 "" ""))])]
3735 "")
3736
3737(define_insn "*truncdfsf_fast_mixed"
3738 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3739 (float_truncate:SF
3740 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3741 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3742{
3743 switch (which_alternative)
3744 {
3745 case 0:
3746 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3747 return "fstp%z0\t%y0";
3748 else
3749 return "fst%z0\t%y0";
3750 case 1:
3751 return output_387_reg_move (insn, operands);
3752 case 2:
3753 return "cvtsd2ss\t{%1, %0|%0, %1}";
3754 default:
3755 gcc_unreachable ();
3756 }
3757}
3758 [(set_attr "type" "fmov,fmov,ssecvt")
3759 (set_attr "mode" "SF")])
3760
3761;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3762;; because nothing we do here is unsafe.
3763(define_insn "*truncdfsf_fast_sse"
3764 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3765 (float_truncate:SF
3766 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3767 "TARGET_SSE2 && TARGET_SSE_MATH"
3768 "cvtsd2ss\t{%1, %0|%0, %1}"
3769 [(set_attr "type" "ssecvt")
3770 (set_attr "mode" "SF")])
3771
3772(define_insn "*truncdfsf_fast_i387"
3773 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3774 (float_truncate:SF
3775 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3776 "TARGET_80387 && flag_unsafe_math_optimizations"
3777 "* return output_387_reg_move (insn, operands);"
3778 [(set_attr "type" "fmov")
3779 (set_attr "mode" "SF")])
3780
3781(define_insn "*truncdfsf_mixed"
3782 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3783 (float_truncate:SF
3784 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3785 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3786 "TARGET_MIX_SSE_I387"
3787{
3788 switch (which_alternative)
3789 {
3790 case 0:
3791 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3792 return "fstp%z0\t%y0";
3793 else
3794 return "fst%z0\t%y0";
3795 case 1:
3796 return "#";
3797 case 2:
3798 return "cvtsd2ss\t{%1, %0|%0, %1}";
3799 default:
3800 gcc_unreachable ();
3801 }
3802}
3803 [(set_attr "type" "fmov,multi,ssecvt")
3804 (set_attr "unit" "*,i387,*")
3805 (set_attr "mode" "SF")])
3806
3807(define_insn "*truncdfsf_i387"
3808 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3809 (float_truncate:SF
3810 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3811 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3812 "TARGET_80387"
3813{
3814 switch (which_alternative)
3815 {
3816 case 0:
3817 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3818 return "fstp%z0\t%y0";
3819 else
3820 return "fst%z0\t%y0";
3821 case 1:
3822 return "#";
3823 default:
3824 gcc_unreachable ();
3825 }
3826}
3827 [(set_attr "type" "fmov,multi")
3828 (set_attr "unit" "*,i387")
3829 (set_attr "mode" "SF")])
3830
3831(define_insn "*truncdfsf2_i387_1"
3832 [(set (match_operand:SF 0 "memory_operand" "=m")
3833 (float_truncate:SF
3834 (match_operand:DF 1 "register_operand" "f")))]
3835 "TARGET_80387
3836 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3837 && !TARGET_MIX_SSE_I387"
3838{
3839 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3840 return "fstp%z0\t%y0";
3841 else
3842 return "fst%z0\t%y0";
3843}
3844 [(set_attr "type" "fmov")
3845 (set_attr "mode" "SF")])
3846
3847(define_split
3848 [(set (match_operand:SF 0 "register_operand" "")
3849 (float_truncate:SF
3850 (match_operand:DF 1 "fp_register_operand" "")))
3851 (clobber (match_operand 2 "" ""))]
3852 "reload_completed"
3853 [(set (match_dup 2) (match_dup 1))
3854 (set (match_dup 0) (match_dup 2))]
3855{
3856 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3857})
3858
3859;; Conversion from XFmode to SFmode.
3860
3861(define_expand "truncxfsf2"
3862 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3863 (float_truncate:SF
3864 (match_operand:XF 1 "register_operand" "")))
3865 (clobber (match_dup 2))])]
3866 "TARGET_80387"
3867{
3868 if (flag_unsafe_math_optimizations)
3869 {
3870 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3871 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3872 if (reg != operands[0])
3873 emit_move_insn (operands[0], reg);
3874 DONE;
3875 }
3876 else
3877 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3878})
3879
3880(define_insn "*truncxfsf2_mixed"
3881 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3882 (float_truncate:SF
3883 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3884 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3885 "TARGET_MIX_SSE_I387"
3886{
3887 gcc_assert (!which_alternative);
3888 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889 return "fstp%z0\t%y0";
3890 else
3891 return "fst%z0\t%y0";
3892}
3893 [(set_attr "type" "fmov,multi,multi,multi")
3894 (set_attr "unit" "*,i387,i387,i387")
3895 (set_attr "mode" "SF")])
3896
3897(define_insn "truncxfsf2_i387_noop"
3898 [(set (match_operand:SF 0 "register_operand" "=f")
3899 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3900 "TARGET_80387 && flag_unsafe_math_optimizations"
3901{
3902 return output_387_reg_move (insn, operands);
3903}
3904 [(set_attr "type" "fmov")
3905 (set_attr "mode" "SF")])
3906
3907(define_insn "*truncxfsf2_i387"
3908 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3909 (float_truncate:SF
3910 (match_operand:XF 1 "register_operand" "f,f,f")))
3911 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3912 "TARGET_80387"
3913{
3914 gcc_assert (!which_alternative);
3915 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3916 return "fstp%z0\t%y0";
3917 else
3918 return "fst%z0\t%y0";
3919}
3920 [(set_attr "type" "fmov,multi,multi")
3921 (set_attr "unit" "*,i387,i387")
3922 (set_attr "mode" "SF")])
3923
3924(define_insn "*truncxfsf2_i387_1"
3925 [(set (match_operand:SF 0 "memory_operand" "=m")
3926 (float_truncate:SF
3927 (match_operand:XF 1 "register_operand" "f")))]
3928 "TARGET_80387"
3929{
3930 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931 return "fstp%z0\t%y0";
3932 else
3933 return "fst%z0\t%y0";
3934}
3935 [(set_attr "type" "fmov")
3936 (set_attr "mode" "SF")])
3937
3938(define_split
3939 [(set (match_operand:SF 0 "register_operand" "")
3940 (float_truncate:SF
3941 (match_operand:XF 1 "register_operand" "")))
3942 (clobber (match_operand:SF 2 "memory_operand" ""))]
3943 "TARGET_80387 && reload_completed"
3944 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3945 (set (match_dup 0) (match_dup 2))]
3946 "")
3947
3948(define_split
3949 [(set (match_operand:SF 0 "memory_operand" "")
3950 (float_truncate:SF
3951 (match_operand:XF 1 "register_operand" "")))
3952 (clobber (match_operand:SF 2 "memory_operand" ""))]
3953 "TARGET_80387"
3954 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3955 "")
3956
3957;; Conversion from XFmode to DFmode.
3958
3959(define_expand "truncxfdf2"
3960 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3961 (float_truncate:DF
3962 (match_operand:XF 1 "register_operand" "")))
3963 (clobber (match_dup 2))])]
3964 "TARGET_80387"
3965{
3966 if (flag_unsafe_math_optimizations)
3967 {
3968 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3969 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3970 if (reg != operands[0])
3971 emit_move_insn (operands[0], reg);
3972 DONE;
3973 }
3974 else
3975 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3976})
3977
3978(define_insn "*truncxfdf2_mixed"
3979 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3980 (float_truncate:DF
3981 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3982 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3983 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3984{
3985 gcc_assert (!which_alternative);
3986 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3987 return "fstp%z0\t%y0";
3988 else
3989 return "fst%z0\t%y0";
3990}
3991 [(set_attr "type" "fmov,multi,multi,multi")
3992 (set_attr "unit" "*,i387,i387,i387")
3993 (set_attr "mode" "DF")])
3994
3995(define_insn "truncxfdf2_i387_noop"
3996 [(set (match_operand:DF 0 "register_operand" "=f")
3997 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3998 "TARGET_80387 && flag_unsafe_math_optimizations"
3999{
4000 return output_387_reg_move (insn, operands);
4001}
4002 [(set_attr "type" "fmov")
4003 (set_attr "mode" "DF")])
4004
4005(define_insn "*truncxfdf2_i387"
4006 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4007 (float_truncate:DF
4008 (match_operand:XF 1 "register_operand" "f,f,f")))
4009 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4010 "TARGET_80387"
4011{
4012 gcc_assert (!which_alternative);
4013 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4014 return "fstp%z0\t%y0";
4015 else
4016 return "fst%z0\t%y0";
4017}
4018 [(set_attr "type" "fmov,multi,multi")
4019 (set_attr "unit" "*,i387,i387")
4020 (set_attr "mode" "DF")])
4021
4022(define_insn "*truncxfdf2_i387_1"
4023 [(set (match_operand:DF 0 "memory_operand" "=m")
4024 (float_truncate:DF
4025 (match_operand:XF 1 "register_operand" "f")))]
4026 "TARGET_80387"
4027{
4028 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4029 return "fstp%z0\t%y0";
4030 else
4031 return "fst%z0\t%y0";
4032}
4033 [(set_attr "type" "fmov")
4034 (set_attr "mode" "DF")])
4035
4036(define_split
4037 [(set (match_operand:DF 0 "register_operand" "")
4038 (float_truncate:DF
4039 (match_operand:XF 1 "register_operand" "")))
4040 (clobber (match_operand:DF 2 "memory_operand" ""))]
4041 "TARGET_80387 && reload_completed"
4042 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4043 (set (match_dup 0) (match_dup 2))]
4044 "")
4045
4046(define_split
4047 [(set (match_operand:DF 0 "memory_operand" "")
4048 (float_truncate:DF
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:DF 2 "memory_operand" ""))]
4051 "TARGET_80387"
4052 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4053 "")
4054
4055;; Signed conversion to DImode.
4056
4057(define_expand "fix_truncxfdi2"
4058 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4059 (fix:DI (match_operand:XF 1 "register_operand" "")))
4060 (clobber (reg:CC FLAGS_REG))])]
4061 "TARGET_80387"
4062{
4063 if (TARGET_FISTTP)
4064 {
4065 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4066 DONE;
4067 }
4068})
4069
4070(define_expand "fix_trunc<mode>di2"
4071 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4073 (clobber (reg:CC FLAGS_REG))])]
4074 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4075{
4076 if (TARGET_FISTTP
4077 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4078 {
4079 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4080 DONE;
4081 }
4082 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4083 {
4084 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4085 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4086 if (out != operands[0])
4087 emit_move_insn (operands[0], out);
4088 DONE;
4089 }
4090})
4091
4092;; Signed conversion to SImode.
4093
4094(define_expand "fix_truncxfsi2"
4095 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4096 (fix:SI (match_operand:XF 1 "register_operand" "")))
4097 (clobber (reg:CC FLAGS_REG))])]
4098 "TARGET_80387"
4099{
4100 if (TARGET_FISTTP)
4101 {
4102 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4103 DONE;
4104 }
4105})
4106
4107(define_expand "fix_trunc<mode>si2"
4108 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4109 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4110 (clobber (reg:CC FLAGS_REG))])]
4111 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4112{
4113 if (TARGET_FISTTP
4114 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4115 {
4116 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4117 DONE;
4118 }
4119 if (SSE_FLOAT_MODE_P (<MODE>mode))
4120 {
4121 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4122 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4123 if (out != operands[0])
4124 emit_move_insn (operands[0], out);
4125 DONE;
4126 }
4127})
4128
4129;; Signed conversion to HImode.
4130
4131(define_expand "fix_trunc<mode>hi2"
4132 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4133 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4134 (clobber (reg:CC FLAGS_REG))])]
4135 "TARGET_80387
4136 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4137{
4138 if (TARGET_FISTTP)
4139 {
4140 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4141 DONE;
4142 }
4143})
4144
4145;; When SSE is available, it is always faster to use it!
4146(define_insn "fix_truncsfdi_sse"
4147 [(set (match_operand:DI 0 "register_operand" "=r,r")
4148 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4149 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4150 "cvttss2si{q}\t{%1, %0|%0, %1}"
4151 [(set_attr "type" "sseicvt")
4152 (set_attr "mode" "SF")
2145
2146(define_expand "movti"
2147 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2148 (match_operand:TI 1 "nonimmediate_operand" ""))]
2149 "TARGET_SSE || TARGET_64BIT"
2150{
2151 if (TARGET_64BIT)
2152 ix86_expand_move (TImode, operands);
2153 else
2154 ix86_expand_vector_move (TImode, operands);
2155 DONE;
2156})
2157
2158(define_insn "*movti_internal"
2159 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2160 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2161 "TARGET_SSE && !TARGET_64BIT
2162 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2163{
2164 switch (which_alternative)
2165 {
2166 case 0:
2167 if (get_attr_mode (insn) == MODE_V4SF)
2168 return "xorps\t%0, %0";
2169 else
2170 return "pxor\t%0, %0";
2171 case 1:
2172 case 2:
2173 if (get_attr_mode (insn) == MODE_V4SF)
2174 return "movaps\t{%1, %0|%0, %1}";
2175 else
2176 return "movdqa\t{%1, %0|%0, %1}";
2177 default:
2178 gcc_unreachable ();
2179 }
2180}
2181 [(set_attr "type" "sselog1,ssemov,ssemov")
2182 (set (attr "mode")
2183 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2184 (ne (symbol_ref "optimize_size") (const_int 0)))
2185 (const_string "V4SF")
2186 (and (eq_attr "alternative" "2")
2187 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2188 (const_int 0)))
2189 (const_string "V4SF")]
2190 (const_string "TI")))])
2191
2192(define_insn "*movti_rex64"
2193 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2194 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2195 "TARGET_64BIT
2196 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2197{
2198 switch (which_alternative)
2199 {
2200 case 0:
2201 case 1:
2202 return "#";
2203 case 2:
2204 if (get_attr_mode (insn) == MODE_V4SF)
2205 return "xorps\t%0, %0";
2206 else
2207 return "pxor\t%0, %0";
2208 case 3:
2209 case 4:
2210 if (get_attr_mode (insn) == MODE_V4SF)
2211 return "movaps\t{%1, %0|%0, %1}";
2212 else
2213 return "movdqa\t{%1, %0|%0, %1}";
2214 default:
2215 gcc_unreachable ();
2216 }
2217}
2218 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2219 (set (attr "mode")
2220 (cond [(eq_attr "alternative" "2,3")
2221 (if_then_else
2222 (ne (symbol_ref "optimize_size")
2223 (const_int 0))
2224 (const_string "V4SF")
2225 (const_string "TI"))
2226 (eq_attr "alternative" "4")
2227 (if_then_else
2228 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2229 (const_int 0))
2230 (ne (symbol_ref "optimize_size")
2231 (const_int 0)))
2232 (const_string "V4SF")
2233 (const_string "TI"))]
2234 (const_string "DI")))])
2235
2236(define_split
2237 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2238 (match_operand:TI 1 "general_operand" ""))]
2239 "reload_completed && !SSE_REG_P (operands[0])
2240 && !SSE_REG_P (operands[1])"
2241 [(const_int 0)]
2242 "ix86_split_long_move (operands); DONE;")
2243
2244(define_expand "movsf"
2245 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2246 (match_operand:SF 1 "general_operand" ""))]
2247 ""
2248 "ix86_expand_move (SFmode, operands); DONE;")
2249
2250(define_insn "*pushsf"
2251 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2252 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2253 "!TARGET_64BIT"
2254{
2255 /* Anything else should be already split before reg-stack. */
2256 gcc_assert (which_alternative == 1);
2257 return "push{l}\t%1";
2258}
2259 [(set_attr "type" "multi,push,multi")
2260 (set_attr "unit" "i387,*,*")
2261 (set_attr "mode" "SF,SI,SF")])
2262
2263(define_insn "*pushsf_rex64"
2264 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2265 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2266 "TARGET_64BIT"
2267{
2268 /* Anything else should be already split before reg-stack. */
2269 gcc_assert (which_alternative == 1);
2270 return "push{q}\t%q1";
2271}
2272 [(set_attr "type" "multi,push,multi")
2273 (set_attr "unit" "i387,*,*")
2274 (set_attr "mode" "SF,DI,SF")])
2275
2276(define_split
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "memory_operand" ""))]
2279 "reload_completed
2280 && GET_CODE (operands[1]) == MEM
2281 && constant_pool_reference_p (operands[1])"
2282 [(set (match_dup 0)
2283 (match_dup 1))]
2284 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2285
2286
2287;; %%% Kill this when call knows how to work this out.
2288(define_split
2289 [(set (match_operand:SF 0 "push_operand" "")
2290 (match_operand:SF 1 "any_fp_register_operand" ""))]
2291 "!TARGET_64BIT"
2292 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2293 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2294
2295(define_split
2296 [(set (match_operand:SF 0 "push_operand" "")
2297 (match_operand:SF 1 "any_fp_register_operand" ""))]
2298 "TARGET_64BIT"
2299 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2300 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2301
2302(define_insn "*movsf_1"
2303 [(set (match_operand:SF 0 "nonimmediate_operand"
2304 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2305 (match_operand:SF 1 "general_operand"
2306 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2307 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2308 && (reload_in_progress || reload_completed
2309 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2310 || GET_CODE (operands[1]) != CONST_DOUBLE
2311 || memory_operand (operands[0], SFmode))"
2312{
2313 switch (which_alternative)
2314 {
2315 case 0:
2316 return output_387_reg_move (insn, operands);
2317
2318 case 1:
2319 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320 return "fstp%z0\t%y0";
2321 else
2322 return "fst%z0\t%y0";
2323
2324 case 2:
2325 return standard_80387_constant_opcode (operands[1]);
2326
2327 case 3:
2328 case 4:
2329 return "mov{l}\t{%1, %0|%0, %1}";
2330 case 5:
2331 if (get_attr_mode (insn) == MODE_TI)
2332 return "pxor\t%0, %0";
2333 else
2334 return "xorps\t%0, %0";
2335 case 6:
2336 if (get_attr_mode (insn) == MODE_V4SF)
2337 return "movaps\t{%1, %0|%0, %1}";
2338 else
2339 return "movss\t{%1, %0|%0, %1}";
2340 case 7:
2341 case 8:
2342 return "movss\t{%1, %0|%0, %1}";
2343
2344 case 9:
2345 case 10:
2346 return "movd\t{%1, %0|%0, %1}";
2347
2348 case 11:
2349 return "movq\t{%1, %0|%0, %1}";
2350
2351 default:
2352 gcc_unreachable ();
2353 }
2354}
2355 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356 (set (attr "mode")
2357 (cond [(eq_attr "alternative" "3,4,9,10")
2358 (const_string "SI")
2359 (eq_attr "alternative" "5")
2360 (if_then_else
2361 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362 (const_int 0))
2363 (ne (symbol_ref "TARGET_SSE2")
2364 (const_int 0)))
2365 (eq (symbol_ref "optimize_size")
2366 (const_int 0)))
2367 (const_string "TI")
2368 (const_string "V4SF"))
2369 /* For architectures resolving dependencies on
2370 whole SSE registers use APS move to break dependency
2371 chains, otherwise use short move to avoid extra work.
2372
2373 Do the same for architectures resolving dependencies on
2374 the parts. While in DF mode it is better to always handle
2375 just register parts, the SF mode is different due to lack
2376 of instructions to load just part of the register. It is
2377 better to maintain the whole registers in single format
2378 to avoid problems on using packed logical operations. */
2379 (eq_attr "alternative" "6")
2380 (if_then_else
2381 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382 (const_int 0))
2383 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2384 (const_int 0)))
2385 (const_string "V4SF")
2386 (const_string "SF"))
2387 (eq_attr "alternative" "11")
2388 (const_string "DI")]
2389 (const_string "SF")))])
2390
2391(define_insn "*swapsf"
2392 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2393 (match_operand:SF 1 "fp_register_operand" "+f"))
2394 (set (match_dup 1)
2395 (match_dup 0))]
2396 "reload_completed || TARGET_80387"
2397{
2398 if (STACK_TOP_P (operands[0]))
2399 return "fxch\t%1";
2400 else
2401 return "fxch\t%0";
2402}
2403 [(set_attr "type" "fxch")
2404 (set_attr "mode" "SF")])
2405
2406(define_expand "movdf"
2407 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408 (match_operand:DF 1 "general_operand" ""))]
2409 ""
2410 "ix86_expand_move (DFmode, operands); DONE;")
2411
2412;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413;; Size of pushdf using integer instructions is 2+2*memory operand size
2414;; On the average, pushdf using integers can be still shorter. Allow this
2415;; pattern for optimize_size too.
2416
2417(define_insn "*pushdf_nointeger"
2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2420 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421{
2422 /* This insn should be already split before reg-stack. */
2423 gcc_unreachable ();
2424}
2425 [(set_attr "type" "multi")
2426 (set_attr "unit" "i387,*,*,*")
2427 (set_attr "mode" "DF,SI,SI,DF")])
2428
2429(define_insn "*pushdf_integer"
2430 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2432 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433{
2434 /* This insn should be already split before reg-stack. */
2435 gcc_unreachable ();
2436}
2437 [(set_attr "type" "multi")
2438 (set_attr "unit" "i387,*,*")
2439 (set_attr "mode" "DF,SI,DF")])
2440
2441;; %%% Kill this when call knows how to work this out.
2442(define_split
2443 [(set (match_operand:DF 0 "push_operand" "")
2444 (match_operand:DF 1 "any_fp_register_operand" ""))]
2445 "!TARGET_64BIT && reload_completed"
2446 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2447 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2448 "")
2449
2450(define_split
2451 [(set (match_operand:DF 0 "push_operand" "")
2452 (match_operand:DF 1 "any_fp_register_operand" ""))]
2453 "TARGET_64BIT && reload_completed"
2454 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2455 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2456 "")
2457
2458(define_split
2459 [(set (match_operand:DF 0 "push_operand" "")
2460 (match_operand:DF 1 "general_operand" ""))]
2461 "reload_completed"
2462 [(const_int 0)]
2463 "ix86_split_long_move (operands); DONE;")
2464
2465;; Moving is usually shorter when only FP registers are used. This separate
2466;; movdf pattern avoids the use of integer registers for FP operations
2467;; when optimizing for size.
2468
2469(define_insn "*movdf_nointeger"
2470 [(set (match_operand:DF 0 "nonimmediate_operand"
2471 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2472 (match_operand:DF 1 "general_operand"
2473 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2474 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2475 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2476 && (reload_in_progress || reload_completed
2477 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2478 || GET_CODE (operands[1]) != CONST_DOUBLE
2479 || memory_operand (operands[0], DFmode))"
2480{
2481 switch (which_alternative)
2482 {
2483 case 0:
2484 return output_387_reg_move (insn, operands);
2485
2486 case 1:
2487 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2488 return "fstp%z0\t%y0";
2489 else
2490 return "fst%z0\t%y0";
2491
2492 case 2:
2493 return standard_80387_constant_opcode (operands[1]);
2494
2495 case 3:
2496 case 4:
2497 return "#";
2498 case 5:
2499 switch (get_attr_mode (insn))
2500 {
2501 case MODE_V4SF:
2502 return "xorps\t%0, %0";
2503 case MODE_V2DF:
2504 return "xorpd\t%0, %0";
2505 case MODE_TI:
2506 return "pxor\t%0, %0";
2507 default:
2508 gcc_unreachable ();
2509 }
2510 case 6:
2511 case 7:
2512 case 8:
2513 switch (get_attr_mode (insn))
2514 {
2515 case MODE_V4SF:
2516 return "movaps\t{%1, %0|%0, %1}";
2517 case MODE_V2DF:
2518 return "movapd\t{%1, %0|%0, %1}";
2519 case MODE_TI:
2520 return "movdqa\t{%1, %0|%0, %1}";
2521 case MODE_DI:
2522 return "movq\t{%1, %0|%0, %1}";
2523 case MODE_DF:
2524 return "movsd\t{%1, %0|%0, %1}";
2525 case MODE_V1DF:
2526 return "movlpd\t{%1, %0|%0, %1}";
2527 case MODE_V2SF:
2528 return "movlps\t{%1, %0|%0, %1}";
2529 default:
2530 gcc_unreachable ();
2531 }
2532
2533 default:
2534 gcc_unreachable ();
2535 }
2536}
2537 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2538 (set (attr "mode")
2539 (cond [(eq_attr "alternative" "0,1,2")
2540 (const_string "DF")
2541 (eq_attr "alternative" "3,4")
2542 (const_string "SI")
2543
2544 /* For SSE1, we have many fewer alternatives. */
2545 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2546 (cond [(eq_attr "alternative" "5,6")
2547 (const_string "V4SF")
2548 ]
2549 (const_string "V2SF"))
2550
2551 /* xorps is one byte shorter. */
2552 (eq_attr "alternative" "5")
2553 (cond [(ne (symbol_ref "optimize_size")
2554 (const_int 0))
2555 (const_string "V4SF")
2556 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2557 (const_int 0))
2558 (const_string "TI")
2559 ]
2560 (const_string "V2DF"))
2561
2562 /* For architectures resolving dependencies on
2563 whole SSE registers use APD move to break dependency
2564 chains, otherwise use short move to avoid extra work.
2565
2566 movaps encodes one byte shorter. */
2567 (eq_attr "alternative" "6")
2568 (cond
2569 [(ne (symbol_ref "optimize_size")
2570 (const_int 0))
2571 (const_string "V4SF")
2572 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2573 (const_int 0))
2574 (const_string "V2DF")
2575 ]
2576 (const_string "DF"))
2577 /* For architectures resolving dependencies on register
2578 parts we may avoid extra work to zero out upper part
2579 of register. */
2580 (eq_attr "alternative" "7")
2581 (if_then_else
2582 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2583 (const_int 0))
2584 (const_string "V1DF")
2585 (const_string "DF"))
2586 ]
2587 (const_string "DF")))])
2588
2589(define_insn "*movdf_integer"
2590 [(set (match_operand:DF 0 "nonimmediate_operand"
2591 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2592 (match_operand:DF 1 "general_operand"
2593 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2594 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2595 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2596 && (reload_in_progress || reload_completed
2597 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2598 || GET_CODE (operands[1]) != CONST_DOUBLE
2599 || memory_operand (operands[0], DFmode))"
2600{
2601 switch (which_alternative)
2602 {
2603 case 0:
2604 return output_387_reg_move (insn, operands);
2605
2606 case 1:
2607 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2608 return "fstp%z0\t%y0";
2609 else
2610 return "fst%z0\t%y0";
2611
2612 case 2:
2613 return standard_80387_constant_opcode (operands[1]);
2614
2615 case 3:
2616 case 4:
2617 return "#";
2618
2619 case 5:
2620 switch (get_attr_mode (insn))
2621 {
2622 case MODE_V4SF:
2623 return "xorps\t%0, %0";
2624 case MODE_V2DF:
2625 return "xorpd\t%0, %0";
2626 case MODE_TI:
2627 return "pxor\t%0, %0";
2628 default:
2629 gcc_unreachable ();
2630 }
2631 case 6:
2632 case 7:
2633 case 8:
2634 switch (get_attr_mode (insn))
2635 {
2636 case MODE_V4SF:
2637 return "movaps\t{%1, %0|%0, %1}";
2638 case MODE_V2DF:
2639 return "movapd\t{%1, %0|%0, %1}";
2640 case MODE_TI:
2641 return "movdqa\t{%1, %0|%0, %1}";
2642 case MODE_DI:
2643 return "movq\t{%1, %0|%0, %1}";
2644 case MODE_DF:
2645 return "movsd\t{%1, %0|%0, %1}";
2646 case MODE_V1DF:
2647 return "movlpd\t{%1, %0|%0, %1}";
2648 case MODE_V2SF:
2649 return "movlps\t{%1, %0|%0, %1}";
2650 default:
2651 gcc_unreachable ();
2652 }
2653
2654 default:
2655 gcc_unreachable();
2656 }
2657}
2658 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2659 (set (attr "mode")
2660 (cond [(eq_attr "alternative" "0,1,2")
2661 (const_string "DF")
2662 (eq_attr "alternative" "3,4")
2663 (const_string "SI")
2664
2665 /* For SSE1, we have many fewer alternatives. */
2666 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2667 (cond [(eq_attr "alternative" "5,6")
2668 (const_string "V4SF")
2669 ]
2670 (const_string "V2SF"))
2671
2672 /* xorps is one byte shorter. */
2673 (eq_attr "alternative" "5")
2674 (cond [(ne (symbol_ref "optimize_size")
2675 (const_int 0))
2676 (const_string "V4SF")
2677 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2678 (const_int 0))
2679 (const_string "TI")
2680 ]
2681 (const_string "V2DF"))
2682
2683 /* For architectures resolving dependencies on
2684 whole SSE registers use APD move to break dependency
2685 chains, otherwise use short move to avoid extra work.
2686
2687 movaps encodes one byte shorter. */
2688 (eq_attr "alternative" "6")
2689 (cond
2690 [(ne (symbol_ref "optimize_size")
2691 (const_int 0))
2692 (const_string "V4SF")
2693 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2694 (const_int 0))
2695 (const_string "V2DF")
2696 ]
2697 (const_string "DF"))
2698 /* For architectures resolving dependencies on register
2699 parts we may avoid extra work to zero out upper part
2700 of register. */
2701 (eq_attr "alternative" "7")
2702 (if_then_else
2703 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2704 (const_int 0))
2705 (const_string "V1DF")
2706 (const_string "DF"))
2707 ]
2708 (const_string "DF")))])
2709
2710(define_split
2711 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2712 (match_operand:DF 1 "general_operand" ""))]
2713 "reload_completed
2714 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2715 && ! (ANY_FP_REG_P (operands[0]) ||
2716 (GET_CODE (operands[0]) == SUBREG
2717 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2718 && ! (ANY_FP_REG_P (operands[1]) ||
2719 (GET_CODE (operands[1]) == SUBREG
2720 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2721 [(const_int 0)]
2722 "ix86_split_long_move (operands); DONE;")
2723
2724(define_insn "*swapdf"
2725 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2726 (match_operand:DF 1 "fp_register_operand" "+f"))
2727 (set (match_dup 1)
2728 (match_dup 0))]
2729 "reload_completed || TARGET_80387"
2730{
2731 if (STACK_TOP_P (operands[0]))
2732 return "fxch\t%1";
2733 else
2734 return "fxch\t%0";
2735}
2736 [(set_attr "type" "fxch")
2737 (set_attr "mode" "DF")])
2738
2739(define_expand "movxf"
2740 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2741 (match_operand:XF 1 "general_operand" ""))]
2742 ""
2743 "ix86_expand_move (XFmode, operands); DONE;")
2744
2745;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2746;; Size of pushdf using integer instructions is 3+3*memory operand size
2747;; Pushing using integer instructions is longer except for constants
2748;; and direct memory references.
2749;; (assuming that any given constant is pushed only once, but this ought to be
2750;; handled elsewhere).
2751
2752(define_insn "*pushxf_nointeger"
2753 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2754 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2755 "optimize_size"
2756{
2757 /* This insn should be already split before reg-stack. */
2758 gcc_unreachable ();
2759}
2760 [(set_attr "type" "multi")
2761 (set_attr "unit" "i387,*,*")
2762 (set_attr "mode" "XF,SI,SI")])
2763
2764(define_insn "*pushxf_integer"
2765 [(set (match_operand:XF 0 "push_operand" "=<,<")
2766 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2767 "!optimize_size"
2768{
2769 /* This insn should be already split before reg-stack. */
2770 gcc_unreachable ();
2771}
2772 [(set_attr "type" "multi")
2773 (set_attr "unit" "i387,*")
2774 (set_attr "mode" "XF,SI")])
2775
2776(define_split
2777 [(set (match_operand 0 "push_operand" "")
2778 (match_operand 1 "general_operand" ""))]
2779 "reload_completed
2780 && (GET_MODE (operands[0]) == XFmode
2781 || GET_MODE (operands[0]) == DFmode)
2782 && !ANY_FP_REG_P (operands[1])"
2783 [(const_int 0)]
2784 "ix86_split_long_move (operands); DONE;")
2785
2786(define_split
2787 [(set (match_operand:XF 0 "push_operand" "")
2788 (match_operand:XF 1 "any_fp_register_operand" ""))]
2789 "!TARGET_64BIT"
2790 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2791 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2792 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2793
2794(define_split
2795 [(set (match_operand:XF 0 "push_operand" "")
2796 (match_operand:XF 1 "any_fp_register_operand" ""))]
2797 "TARGET_64BIT"
2798 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2799 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2800 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2801
2802;; Do not use integer registers when optimizing for size
2803(define_insn "*movxf_nointeger"
2804 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2805 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2806 "optimize_size
2807 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808 && (reload_in_progress || reload_completed
2809 || GET_CODE (operands[1]) != CONST_DOUBLE
2810 || memory_operand (operands[0], XFmode))"
2811{
2812 switch (which_alternative)
2813 {
2814 case 0:
2815 return output_387_reg_move (insn, operands);
2816
2817 case 1:
2818 /* There is no non-popping store to memory for XFmode. So if
2819 we need one, follow the store with a load. */
2820 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821 return "fstp%z0\t%y0\;fld%z0\t%y0";
2822 else
2823 return "fstp%z0\t%y0";
2824
2825 case 2:
2826 return standard_80387_constant_opcode (operands[1]);
2827
2828 case 3: case 4:
2829 return "#";
2830 default:
2831 gcc_unreachable ();
2832 }
2833}
2834 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2835 (set_attr "mode" "XF,XF,XF,SI,SI")])
2836
2837(define_insn "*movxf_integer"
2838 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2839 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2840 "!optimize_size
2841 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2842 && (reload_in_progress || reload_completed
2843 || GET_CODE (operands[1]) != CONST_DOUBLE
2844 || memory_operand (operands[0], XFmode))"
2845{
2846 switch (which_alternative)
2847 {
2848 case 0:
2849 return output_387_reg_move (insn, operands);
2850
2851 case 1:
2852 /* There is no non-popping store to memory for XFmode. So if
2853 we need one, follow the store with a load. */
2854 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2855 return "fstp%z0\t%y0\;fld%z0\t%y0";
2856 else
2857 return "fstp%z0\t%y0";
2858
2859 case 2:
2860 return standard_80387_constant_opcode (operands[1]);
2861
2862 case 3: case 4:
2863 return "#";
2864
2865 default:
2866 gcc_unreachable ();
2867 }
2868}
2869 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2870 (set_attr "mode" "XF,XF,XF,SI,SI")])
2871
2872(define_split
2873 [(set (match_operand 0 "nonimmediate_operand" "")
2874 (match_operand 1 "general_operand" ""))]
2875 "reload_completed
2876 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2877 && GET_MODE (operands[0]) == XFmode
2878 && ! (ANY_FP_REG_P (operands[0]) ||
2879 (GET_CODE (operands[0]) == SUBREG
2880 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2881 && ! (ANY_FP_REG_P (operands[1]) ||
2882 (GET_CODE (operands[1]) == SUBREG
2883 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2884 [(const_int 0)]
2885 "ix86_split_long_move (operands); DONE;")
2886
2887(define_split
2888 [(set (match_operand 0 "register_operand" "")
2889 (match_operand 1 "memory_operand" ""))]
2890 "reload_completed
2891 && GET_CODE (operands[1]) == MEM
2892 && (GET_MODE (operands[0]) == XFmode
2893 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2894 && constant_pool_reference_p (operands[1])"
2895 [(set (match_dup 0) (match_dup 1))]
2896{
2897 rtx c = avoid_constant_pool_reference (operands[1]);
2898 rtx r = operands[0];
2899
2900 if (GET_CODE (r) == SUBREG)
2901 r = SUBREG_REG (r);
2902
2903 if (SSE_REG_P (r))
2904 {
2905 if (!standard_sse_constant_p (c))
2906 FAIL;
2907 }
2908 else if (FP_REG_P (r))
2909 {
2910 if (!standard_80387_constant_p (c))
2911 FAIL;
2912 }
2913 else if (MMX_REG_P (r))
2914 FAIL;
2915
2916 operands[1] = c;
2917})
2918
2919(define_insn "swapxf"
2920 [(set (match_operand:XF 0 "register_operand" "+f")
2921 (match_operand:XF 1 "register_operand" "+f"))
2922 (set (match_dup 1)
2923 (match_dup 0))]
2924 "TARGET_80387"
2925{
2926 if (STACK_TOP_P (operands[0]))
2927 return "fxch\t%1";
2928 else
2929 return "fxch\t%0";
2930}
2931 [(set_attr "type" "fxch")
2932 (set_attr "mode" "XF")])
2933
2934(define_expand "movtf"
2935 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2936 (match_operand:TF 1 "nonimmediate_operand" ""))]
2937 "TARGET_64BIT"
2938{
2939 ix86_expand_move (TFmode, operands);
2940 DONE;
2941})
2942
2943(define_insn "*movtf_internal"
2944 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2945 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2946 "TARGET_64BIT
2947 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2948{
2949 switch (which_alternative)
2950 {
2951 case 0:
2952 case 1:
2953 return "#";
2954 case 2:
2955 if (get_attr_mode (insn) == MODE_V4SF)
2956 return "xorps\t%0, %0";
2957 else
2958 return "pxor\t%0, %0";
2959 case 3:
2960 case 4:
2961 if (get_attr_mode (insn) == MODE_V4SF)
2962 return "movaps\t{%1, %0|%0, %1}";
2963 else
2964 return "movdqa\t{%1, %0|%0, %1}";
2965 default:
2966 gcc_unreachable ();
2967 }
2968}
2969 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2970 (set (attr "mode")
2971 (cond [(eq_attr "alternative" "2,3")
2972 (if_then_else
2973 (ne (symbol_ref "optimize_size")
2974 (const_int 0))
2975 (const_string "V4SF")
2976 (const_string "TI"))
2977 (eq_attr "alternative" "4")
2978 (if_then_else
2979 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2980 (const_int 0))
2981 (ne (symbol_ref "optimize_size")
2982 (const_int 0)))
2983 (const_string "V4SF")
2984 (const_string "TI"))]
2985 (const_string "DI")))])
2986
2987(define_split
2988 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2989 (match_operand:TF 1 "general_operand" ""))]
2990 "reload_completed && !SSE_REG_P (operands[0])
2991 && !SSE_REG_P (operands[1])"
2992 [(const_int 0)]
2993 "ix86_split_long_move (operands); DONE;")
2994
2995;; Zero extension instructions
2996
2997(define_expand "zero_extendhisi2"
2998 [(set (match_operand:SI 0 "register_operand" "")
2999 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3000 ""
3001{
3002 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3003 {
3004 operands[1] = force_reg (HImode, operands[1]);
3005 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3006 DONE;
3007 }
3008})
3009
3010(define_insn "zero_extendhisi2_and"
3011 [(set (match_operand:SI 0 "register_operand" "=r")
3012 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3013 (clobber (reg:CC FLAGS_REG))]
3014 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3015 "#"
3016 [(set_attr "type" "alu1")
3017 (set_attr "mode" "SI")])
3018
3019(define_split
3020 [(set (match_operand:SI 0 "register_operand" "")
3021 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3022 (clobber (reg:CC FLAGS_REG))]
3023 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3024 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3025 (clobber (reg:CC FLAGS_REG))])]
3026 "")
3027
3028(define_insn "*zero_extendhisi2_movzwl"
3029 [(set (match_operand:SI 0 "register_operand" "=r")
3030 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3031 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032 "movz{wl|x}\t{%1, %0|%0, %1}"
3033 [(set_attr "type" "imovx")
3034 (set_attr "mode" "SI")])
3035
3036(define_expand "zero_extendqihi2"
3037 [(parallel
3038 [(set (match_operand:HI 0 "register_operand" "")
3039 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3040 (clobber (reg:CC FLAGS_REG))])]
3041 ""
3042 "")
3043
3044(define_insn "*zero_extendqihi2_and"
3045 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3047 (clobber (reg:CC FLAGS_REG))]
3048 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3049 "#"
3050 [(set_attr "type" "alu1")
3051 (set_attr "mode" "HI")])
3052
3053(define_insn "*zero_extendqihi2_movzbw_and"
3054 [(set (match_operand:HI 0 "register_operand" "=r,r")
3055 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3056 (clobber (reg:CC FLAGS_REG))]
3057 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3058 "#"
3059 [(set_attr "type" "imovx,alu1")
3060 (set_attr "mode" "HI")])
3061
3062; zero extend to SImode here to avoid partial register stalls
3063(define_insn "*zero_extendqihi2_movzbl"
3064 [(set (match_operand:HI 0 "register_operand" "=r")
3065 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3066 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3067 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3068 [(set_attr "type" "imovx")
3069 (set_attr "mode" "SI")])
3070
3071;; For the movzbw case strip only the clobber
3072(define_split
3073 [(set (match_operand:HI 0 "register_operand" "")
3074 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3075 (clobber (reg:CC FLAGS_REG))]
3076 "reload_completed
3077 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3078 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3079 [(set (match_operand:HI 0 "register_operand" "")
3080 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3081
3082;; When source and destination does not overlap, clear destination
3083;; first and then do the movb
3084(define_split
3085 [(set (match_operand:HI 0 "register_operand" "")
3086 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3087 (clobber (reg:CC FLAGS_REG))]
3088 "reload_completed
3089 && ANY_QI_REG_P (operands[0])
3090 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3091 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3092 [(set (match_dup 0) (const_int 0))
3093 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3094 "operands[2] = gen_lowpart (QImode, operands[0]);")
3095
3096;; Rest is handled by single and.
3097(define_split
3098 [(set (match_operand:HI 0 "register_operand" "")
3099 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3100 (clobber (reg:CC FLAGS_REG))]
3101 "reload_completed
3102 && true_regnum (operands[0]) == true_regnum (operands[1])"
3103 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3104 (clobber (reg:CC FLAGS_REG))])]
3105 "")
3106
3107(define_expand "zero_extendqisi2"
3108 [(parallel
3109 [(set (match_operand:SI 0 "register_operand" "")
3110 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111 (clobber (reg:CC FLAGS_REG))])]
3112 ""
3113 "")
3114
3115(define_insn "*zero_extendqisi2_and"
3116 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3117 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3118 (clobber (reg:CC FLAGS_REG))]
3119 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3120 "#"
3121 [(set_attr "type" "alu1")
3122 (set_attr "mode" "SI")])
3123
3124(define_insn "*zero_extendqisi2_movzbw_and"
3125 [(set (match_operand:SI 0 "register_operand" "=r,r")
3126 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3127 (clobber (reg:CC FLAGS_REG))]
3128 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3129 "#"
3130 [(set_attr "type" "imovx,alu1")
3131 (set_attr "mode" "SI")])
3132
3133(define_insn "*zero_extendqisi2_movzbw"
3134 [(set (match_operand:SI 0 "register_operand" "=r")
3135 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3136 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3137 "movz{bl|x}\t{%1, %0|%0, %1}"
3138 [(set_attr "type" "imovx")
3139 (set_attr "mode" "SI")])
3140
3141;; For the movzbl case strip only the clobber
3142(define_split
3143 [(set (match_operand:SI 0 "register_operand" "")
3144 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3145 (clobber (reg:CC FLAGS_REG))]
3146 "reload_completed
3147 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3148 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3149 [(set (match_dup 0)
3150 (zero_extend:SI (match_dup 1)))])
3151
3152;; When source and destination does not overlap, clear destination
3153;; first and then do the movb
3154(define_split
3155 [(set (match_operand:SI 0 "register_operand" "")
3156 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3157 (clobber (reg:CC FLAGS_REG))]
3158 "reload_completed
3159 && ANY_QI_REG_P (operands[0])
3160 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3161 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3162 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3163 [(set (match_dup 0) (const_int 0))
3164 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3165 "operands[2] = gen_lowpart (QImode, operands[0]);")
3166
3167;; Rest is handled by single and.
3168(define_split
3169 [(set (match_operand:SI 0 "register_operand" "")
3170 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3171 (clobber (reg:CC FLAGS_REG))]
3172 "reload_completed
3173 && true_regnum (operands[0]) == true_regnum (operands[1])"
3174 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3175 (clobber (reg:CC FLAGS_REG))])]
3176 "")
3177
3178;; %%% Kill me once multi-word ops are sane.
3179(define_expand "zero_extendsidi2"
3180 [(set (match_operand:DI 0 "register_operand" "=r")
3181 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3182 ""
3183 "if (!TARGET_64BIT)
3184 {
3185 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3186 DONE;
3187 }
3188 ")
3189
3190(define_insn "zero_extendsidi2_32"
3191 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3192 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3193 (clobber (reg:CC FLAGS_REG))]
3194 "!TARGET_64BIT"
3195 "@
3196 #
3197 #
3198 #
3199 movd\t{%1, %0|%0, %1}
3200 movd\t{%1, %0|%0, %1}"
3201 [(set_attr "mode" "SI,SI,SI,DI,TI")
3202 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3203
3204(define_insn "zero_extendsidi2_rex64"
3205 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3206 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3207 "TARGET_64BIT"
3208 "@
3209 mov\t{%k1, %k0|%k0, %k1}
3210 #
3211 movd\t{%1, %0|%0, %1}
3212 movd\t{%1, %0|%0, %1}"
3213 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3214 (set_attr "mode" "SI,DI,SI,SI")])
3215
3216(define_split
3217 [(set (match_operand:DI 0 "memory_operand" "")
3218 (zero_extend:DI (match_dup 0)))]
3219 "TARGET_64BIT"
3220 [(set (match_dup 4) (const_int 0))]
3221 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3222
3223(define_split
3224 [(set (match_operand:DI 0 "register_operand" "")
3225 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3226 (clobber (reg:CC FLAGS_REG))]
3227 "!TARGET_64BIT && reload_completed
3228 && true_regnum (operands[0]) == true_regnum (operands[1])"
3229 [(set (match_dup 4) (const_int 0))]
3230 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3231
3232(define_split
3233 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3234 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3235 (clobber (reg:CC FLAGS_REG))]
3236 "!TARGET_64BIT && reload_completed
3237 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3238 [(set (match_dup 3) (match_dup 1))
3239 (set (match_dup 4) (const_int 0))]
3240 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3241
3242(define_insn "zero_extendhidi2"
3243 [(set (match_operand:DI 0 "register_operand" "=r")
3244 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3245 "TARGET_64BIT"
3246 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3247 [(set_attr "type" "imovx")
3248 (set_attr "mode" "DI")])
3249
3250(define_insn "zero_extendqidi2"
3251 [(set (match_operand:DI 0 "register_operand" "=r")
3252 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3253 "TARGET_64BIT"
3254 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3255 [(set_attr "type" "imovx")
3256 (set_attr "mode" "DI")])
3257
3258;; Sign extension instructions
3259
3260(define_expand "extendsidi2"
3261 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3262 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3263 (clobber (reg:CC FLAGS_REG))
3264 (clobber (match_scratch:SI 2 ""))])]
3265 ""
3266{
3267 if (TARGET_64BIT)
3268 {
3269 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3270 DONE;
3271 }
3272})
3273
3274(define_insn "*extendsidi2_1"
3275 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3276 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3277 (clobber (reg:CC FLAGS_REG))
3278 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3279 "!TARGET_64BIT"
3280 "#")
3281
3282(define_insn "extendsidi2_rex64"
3283 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3284 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3285 "TARGET_64BIT"
3286 "@
3287 {cltq|cdqe}
3288 movs{lq|x}\t{%1,%0|%0, %1}"
3289 [(set_attr "type" "imovx")
3290 (set_attr "mode" "DI")
3291 (set_attr "prefix_0f" "0")
3292 (set_attr "modrm" "0,1")])
3293
3294(define_insn "extendhidi2"
3295 [(set (match_operand:DI 0 "register_operand" "=r")
3296 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3297 "TARGET_64BIT"
3298 "movs{wq|x}\t{%1,%0|%0, %1}"
3299 [(set_attr "type" "imovx")
3300 (set_attr "mode" "DI")])
3301
3302(define_insn "extendqidi2"
3303 [(set (match_operand:DI 0 "register_operand" "=r")
3304 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3305 "TARGET_64BIT"
3306 "movs{bq|x}\t{%1,%0|%0, %1}"
3307 [(set_attr "type" "imovx")
3308 (set_attr "mode" "DI")])
3309
3310;; Extend to memory case when source register does die.
3311(define_split
3312 [(set (match_operand:DI 0 "memory_operand" "")
3313 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3314 (clobber (reg:CC FLAGS_REG))
3315 (clobber (match_operand:SI 2 "register_operand" ""))]
3316 "(reload_completed
3317 && dead_or_set_p (insn, operands[1])
3318 && !reg_mentioned_p (operands[1], operands[0]))"
3319 [(set (match_dup 3) (match_dup 1))
3320 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3321 (clobber (reg:CC FLAGS_REG))])
3322 (set (match_dup 4) (match_dup 1))]
3323 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3324
3325;; Extend to memory case when source register does not die.
3326(define_split
3327 [(set (match_operand:DI 0 "memory_operand" "")
3328 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329 (clobber (reg:CC FLAGS_REG))
3330 (clobber (match_operand:SI 2 "register_operand" ""))]
3331 "reload_completed"
3332 [(const_int 0)]
3333{
3334 split_di (&operands[0], 1, &operands[3], &operands[4]);
3335
3336 emit_move_insn (operands[3], operands[1]);
3337
3338 /* Generate a cltd if possible and doing so it profitable. */
3339 if (true_regnum (operands[1]) == 0
3340 && true_regnum (operands[2]) == 1
3341 && (optimize_size || TARGET_USE_CLTD))
3342 {
3343 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3344 }
3345 else
3346 {
3347 emit_move_insn (operands[2], operands[1]);
3348 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3349 }
3350 emit_move_insn (operands[4], operands[2]);
3351 DONE;
3352})
3353
3354;; Extend to register case. Optimize case where source and destination
3355;; registers match and cases where we can use cltd.
3356(define_split
3357 [(set (match_operand:DI 0 "register_operand" "")
3358 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3359 (clobber (reg:CC FLAGS_REG))
3360 (clobber (match_scratch:SI 2 ""))]
3361 "reload_completed"
3362 [(const_int 0)]
3363{
3364 split_di (&operands[0], 1, &operands[3], &operands[4]);
3365
3366 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3367 emit_move_insn (operands[3], operands[1]);
3368
3369 /* Generate a cltd if possible and doing so it profitable. */
3370 if (true_regnum (operands[3]) == 0
3371 && (optimize_size || TARGET_USE_CLTD))
3372 {
3373 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3374 DONE;
3375 }
3376
3377 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3378 emit_move_insn (operands[4], operands[1]);
3379
3380 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3381 DONE;
3382})
3383
3384(define_insn "extendhisi2"
3385 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3386 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3387 ""
3388{
3389 switch (get_attr_prefix_0f (insn))
3390 {
3391 case 0:
3392 return "{cwtl|cwde}";
3393 default:
3394 return "movs{wl|x}\t{%1,%0|%0, %1}";
3395 }
3396}
3397 [(set_attr "type" "imovx")
3398 (set_attr "mode" "SI")
3399 (set (attr "prefix_0f")
3400 ;; movsx is short decodable while cwtl is vector decoded.
3401 (if_then_else (and (eq_attr "cpu" "!k6")
3402 (eq_attr "alternative" "0"))
3403 (const_string "0")
3404 (const_string "1")))
3405 (set (attr "modrm")
3406 (if_then_else (eq_attr "prefix_0f" "0")
3407 (const_string "0")
3408 (const_string "1")))])
3409
3410(define_insn "*extendhisi2_zext"
3411 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3412 (zero_extend:DI
3413 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3414 "TARGET_64BIT"
3415{
3416 switch (get_attr_prefix_0f (insn))
3417 {
3418 case 0:
3419 return "{cwtl|cwde}";
3420 default:
3421 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3422 }
3423}
3424 [(set_attr "type" "imovx")
3425 (set_attr "mode" "SI")
3426 (set (attr "prefix_0f")
3427 ;; movsx is short decodable while cwtl is vector decoded.
3428 (if_then_else (and (eq_attr "cpu" "!k6")
3429 (eq_attr "alternative" "0"))
3430 (const_string "0")
3431 (const_string "1")))
3432 (set (attr "modrm")
3433 (if_then_else (eq_attr "prefix_0f" "0")
3434 (const_string "0")
3435 (const_string "1")))])
3436
3437(define_insn "extendqihi2"
3438 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3439 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3440 ""
3441{
3442 switch (get_attr_prefix_0f (insn))
3443 {
3444 case 0:
3445 return "{cbtw|cbw}";
3446 default:
3447 return "movs{bw|x}\t{%1,%0|%0, %1}";
3448 }
3449}
3450 [(set_attr "type" "imovx")
3451 (set_attr "mode" "HI")
3452 (set (attr "prefix_0f")
3453 ;; movsx is short decodable while cwtl is vector decoded.
3454 (if_then_else (and (eq_attr "cpu" "!k6")
3455 (eq_attr "alternative" "0"))
3456 (const_string "0")
3457 (const_string "1")))
3458 (set (attr "modrm")
3459 (if_then_else (eq_attr "prefix_0f" "0")
3460 (const_string "0")
3461 (const_string "1")))])
3462
3463(define_insn "extendqisi2"
3464 [(set (match_operand:SI 0 "register_operand" "=r")
3465 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3466 ""
3467 "movs{bl|x}\t{%1,%0|%0, %1}"
3468 [(set_attr "type" "imovx")
3469 (set_attr "mode" "SI")])
3470
3471(define_insn "*extendqisi2_zext"
3472 [(set (match_operand:DI 0 "register_operand" "=r")
3473 (zero_extend:DI
3474 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3475 "TARGET_64BIT"
3476 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3477 [(set_attr "type" "imovx")
3478 (set_attr "mode" "SI")])
3479
3480;; Conversions between float and double.
3481
3482;; These are all no-ops in the model used for the 80387. So just
3483;; emit moves.
3484
3485;; %%% Kill these when call knows how to work out a DFmode push earlier.
3486(define_insn "*dummy_extendsfdf2"
3487 [(set (match_operand:DF 0 "push_operand" "=<")
3488 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3489 "0"
3490 "#")
3491
3492(define_split
3493 [(set (match_operand:DF 0 "push_operand" "")
3494 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3495 "!TARGET_64BIT"
3496 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3497 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3498
3499(define_split
3500 [(set (match_operand:DF 0 "push_operand" "")
3501 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3502 "TARGET_64BIT"
3503 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3504 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3505
3506(define_insn "*dummy_extendsfxf2"
3507 [(set (match_operand:XF 0 "push_operand" "=<")
3508 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3509 "0"
3510 "#")
3511
3512(define_split
3513 [(set (match_operand:XF 0 "push_operand" "")
3514 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3515 ""
3516 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3517 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3518 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3519
3520(define_split
3521 [(set (match_operand:XF 0 "push_operand" "")
3522 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3523 "TARGET_64BIT"
3524 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3525 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3526 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3527
3528(define_split
3529 [(set (match_operand:XF 0 "push_operand" "")
3530 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3531 ""
3532 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3533 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3534 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3535
3536(define_split
3537 [(set (match_operand:XF 0 "push_operand" "")
3538 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3539 "TARGET_64BIT"
3540 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3541 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3542 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3543
3544(define_expand "extendsfdf2"
3545 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3546 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3547 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3548{
3549 /* ??? Needed for compress_float_constant since all fp constants
3550 are LEGITIMATE_CONSTANT_P. */
3551 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3552 {
3553 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3554 && standard_80387_constant_p (operands[1]) > 0)
3555 {
3556 operands[1] = simplify_const_unary_operation
3557 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3558 emit_move_insn_1 (operands[0], operands[1]);
3559 DONE;
3560 }
3561 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3562 }
3563 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3564 operands[1] = force_reg (SFmode, operands[1]);
3565})
3566
3567(define_insn "*extendsfdf2_mixed"
3568 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3570 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3571 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572{
3573 switch (which_alternative)
3574 {
3575 case 0:
3576 return output_387_reg_move (insn, operands);
3577
3578 case 1:
3579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580 return "fstp%z0\t%y0";
3581 else
3582 return "fst%z0\t%y0";
3583
3584 case 2:
3585 return "cvtss2sd\t{%1, %0|%0, %1}";
3586
3587 default:
3588 gcc_unreachable ();
3589 }
3590}
3591 [(set_attr "type" "fmov,fmov,ssecvt")
3592 (set_attr "mode" "SF,XF,DF")])
3593
3594(define_insn "*extendsfdf2_sse"
3595 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3596 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3597 "TARGET_SSE2 && TARGET_SSE_MATH
3598 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3599 "cvtss2sd\t{%1, %0|%0, %1}"
3600 [(set_attr "type" "ssecvt")
3601 (set_attr "mode" "DF")])
3602
3603(define_insn "*extendsfdf2_i387"
3604 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3605 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3606 "TARGET_80387
3607 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3608{
3609 switch (which_alternative)
3610 {
3611 case 0:
3612 return output_387_reg_move (insn, operands);
3613
3614 case 1:
3615 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3616 return "fstp%z0\t%y0";
3617 else
3618 return "fst%z0\t%y0";
3619
3620 default:
3621 gcc_unreachable ();
3622 }
3623}
3624 [(set_attr "type" "fmov")
3625 (set_attr "mode" "SF,XF")])
3626
3627(define_expand "extendsfxf2"
3628 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3629 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3630 "TARGET_80387"
3631{
3632 /* ??? Needed for compress_float_constant since all fp constants
3633 are LEGITIMATE_CONSTANT_P. */
3634 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3635 {
3636 if (standard_80387_constant_p (operands[1]) > 0)
3637 {
3638 operands[1] = simplify_const_unary_operation
3639 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3640 emit_move_insn_1 (operands[0], operands[1]);
3641 DONE;
3642 }
3643 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3644 }
3645 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3646 operands[1] = force_reg (SFmode, operands[1]);
3647})
3648
3649(define_insn "*extendsfxf2_i387"
3650 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3651 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3652 "TARGET_80387
3653 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3654{
3655 switch (which_alternative)
3656 {
3657 case 0:
3658 return output_387_reg_move (insn, operands);
3659
3660 case 1:
3661 /* There is no non-popping store to memory for XFmode. So if
3662 we need one, follow the store with a load. */
3663 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3664 return "fstp%z0\t%y0";
3665 else
3666 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3667
3668 default:
3669 gcc_unreachable ();
3670 }
3671}
3672 [(set_attr "type" "fmov")
3673 (set_attr "mode" "SF,XF")])
3674
3675(define_expand "extenddfxf2"
3676 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3677 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3678 "TARGET_80387"
3679{
3680 /* ??? Needed for compress_float_constant since all fp constants
3681 are LEGITIMATE_CONSTANT_P. */
3682 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3683 {
3684 if (standard_80387_constant_p (operands[1]) > 0)
3685 {
3686 operands[1] = simplify_const_unary_operation
3687 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3688 emit_move_insn_1 (operands[0], operands[1]);
3689 DONE;
3690 }
3691 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3692 }
3693 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3694 operands[1] = force_reg (DFmode, operands[1]);
3695})
3696
3697(define_insn "*extenddfxf2_i387"
3698 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3699 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3700 "TARGET_80387
3701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3702{
3703 switch (which_alternative)
3704 {
3705 case 0:
3706 return output_387_reg_move (insn, operands);
3707
3708 case 1:
3709 /* There is no non-popping store to memory for XFmode. So if
3710 we need one, follow the store with a load. */
3711 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3713 else
3714 return "fstp%z0\t%y0";
3715
3716 default:
3717 gcc_unreachable ();
3718 }
3719}
3720 [(set_attr "type" "fmov")
3721 (set_attr "mode" "DF,XF")])
3722
3723;; %%% This seems bad bad news.
3724;; This cannot output into an f-reg because there is no way to be sure
3725;; of truncating in that case. Otherwise this is just like a simple move
3726;; insn. So we pretend we can output to a reg in order to get better
3727;; register preferencing, but we really use a stack slot.
3728
3729;; Conversion from DFmode to SFmode.
3730
3731(define_expand "truncdfsf2"
3732 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3733 (float_truncate:SF
3734 (match_operand:DF 1 "nonimmediate_operand" "")))]
3735 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3736{
3737 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3738 operands[1] = force_reg (DFmode, operands[1]);
3739
3740 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3741 ;
3742 else if (flag_unsafe_math_optimizations)
3743 ;
3744 else
3745 {
3746 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3747 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3748 DONE;
3749 }
3750})
3751
3752(define_expand "truncdfsf2_with_temp"
3753 [(parallel [(set (match_operand:SF 0 "" "")
3754 (float_truncate:SF (match_operand:DF 1 "" "")))
3755 (clobber (match_operand:SF 2 "" ""))])]
3756 "")
3757
3758(define_insn "*truncdfsf_fast_mixed"
3759 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3760 (float_truncate:SF
3761 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3762 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3763{
3764 switch (which_alternative)
3765 {
3766 case 0:
3767 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768 return "fstp%z0\t%y0";
3769 else
3770 return "fst%z0\t%y0";
3771 case 1:
3772 return output_387_reg_move (insn, operands);
3773 case 2:
3774 return "cvtsd2ss\t{%1, %0|%0, %1}";
3775 default:
3776 gcc_unreachable ();
3777 }
3778}
3779 [(set_attr "type" "fmov,fmov,ssecvt")
3780 (set_attr "mode" "SF")])
3781
3782;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3783;; because nothing we do here is unsafe.
3784(define_insn "*truncdfsf_fast_sse"
3785 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3786 (float_truncate:SF
3787 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3788 "TARGET_SSE2 && TARGET_SSE_MATH"
3789 "cvtsd2ss\t{%1, %0|%0, %1}"
3790 [(set_attr "type" "ssecvt")
3791 (set_attr "mode" "SF")])
3792
3793(define_insn "*truncdfsf_fast_i387"
3794 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3795 (float_truncate:SF
3796 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3797 "TARGET_80387 && flag_unsafe_math_optimizations"
3798 "* return output_387_reg_move (insn, operands);"
3799 [(set_attr "type" "fmov")
3800 (set_attr "mode" "SF")])
3801
3802(define_insn "*truncdfsf_mixed"
3803 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3804 (float_truncate:SF
3805 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3806 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3807 "TARGET_MIX_SSE_I387"
3808{
3809 switch (which_alternative)
3810 {
3811 case 0:
3812 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813 return "fstp%z0\t%y0";
3814 else
3815 return "fst%z0\t%y0";
3816 case 1:
3817 return "#";
3818 case 2:
3819 return "cvtsd2ss\t{%1, %0|%0, %1}";
3820 default:
3821 gcc_unreachable ();
3822 }
3823}
3824 [(set_attr "type" "fmov,multi,ssecvt")
3825 (set_attr "unit" "*,i387,*")
3826 (set_attr "mode" "SF")])
3827
3828(define_insn "*truncdfsf_i387"
3829 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3830 (float_truncate:SF
3831 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3832 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3833 "TARGET_80387"
3834{
3835 switch (which_alternative)
3836 {
3837 case 0:
3838 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3839 return "fstp%z0\t%y0";
3840 else
3841 return "fst%z0\t%y0";
3842 case 1:
3843 return "#";
3844 default:
3845 gcc_unreachable ();
3846 }
3847}
3848 [(set_attr "type" "fmov,multi")
3849 (set_attr "unit" "*,i387")
3850 (set_attr "mode" "SF")])
3851
3852(define_insn "*truncdfsf2_i387_1"
3853 [(set (match_operand:SF 0 "memory_operand" "=m")
3854 (float_truncate:SF
3855 (match_operand:DF 1 "register_operand" "f")))]
3856 "TARGET_80387
3857 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3858 && !TARGET_MIX_SSE_I387"
3859{
3860 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3861 return "fstp%z0\t%y0";
3862 else
3863 return "fst%z0\t%y0";
3864}
3865 [(set_attr "type" "fmov")
3866 (set_attr "mode" "SF")])
3867
3868(define_split
3869 [(set (match_operand:SF 0 "register_operand" "")
3870 (float_truncate:SF
3871 (match_operand:DF 1 "fp_register_operand" "")))
3872 (clobber (match_operand 2 "" ""))]
3873 "reload_completed"
3874 [(set (match_dup 2) (match_dup 1))
3875 (set (match_dup 0) (match_dup 2))]
3876{
3877 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3878})
3879
3880;; Conversion from XFmode to SFmode.
3881
3882(define_expand "truncxfsf2"
3883 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3884 (float_truncate:SF
3885 (match_operand:XF 1 "register_operand" "")))
3886 (clobber (match_dup 2))])]
3887 "TARGET_80387"
3888{
3889 if (flag_unsafe_math_optimizations)
3890 {
3891 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3892 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3893 if (reg != operands[0])
3894 emit_move_insn (operands[0], reg);
3895 DONE;
3896 }
3897 else
3898 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3899})
3900
3901(define_insn "*truncxfsf2_mixed"
3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3903 (float_truncate:SF
3904 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3905 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3906 "TARGET_MIX_SSE_I387"
3907{
3908 gcc_assert (!which_alternative);
3909 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910 return "fstp%z0\t%y0";
3911 else
3912 return "fst%z0\t%y0";
3913}
3914 [(set_attr "type" "fmov,multi,multi,multi")
3915 (set_attr "unit" "*,i387,i387,i387")
3916 (set_attr "mode" "SF")])
3917
3918(define_insn "truncxfsf2_i387_noop"
3919 [(set (match_operand:SF 0 "register_operand" "=f")
3920 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3921 "TARGET_80387 && flag_unsafe_math_optimizations"
3922{
3923 return output_387_reg_move (insn, operands);
3924}
3925 [(set_attr "type" "fmov")
3926 (set_attr "mode" "SF")])
3927
3928(define_insn "*truncxfsf2_i387"
3929 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3930 (float_truncate:SF
3931 (match_operand:XF 1 "register_operand" "f,f,f")))
3932 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3933 "TARGET_80387"
3934{
3935 gcc_assert (!which_alternative);
3936 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3937 return "fstp%z0\t%y0";
3938 else
3939 return "fst%z0\t%y0";
3940}
3941 [(set_attr "type" "fmov,multi,multi")
3942 (set_attr "unit" "*,i387,i387")
3943 (set_attr "mode" "SF")])
3944
3945(define_insn "*truncxfsf2_i387_1"
3946 [(set (match_operand:SF 0 "memory_operand" "=m")
3947 (float_truncate:SF
3948 (match_operand:XF 1 "register_operand" "f")))]
3949 "TARGET_80387"
3950{
3951 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952 return "fstp%z0\t%y0";
3953 else
3954 return "fst%z0\t%y0";
3955}
3956 [(set_attr "type" "fmov")
3957 (set_attr "mode" "SF")])
3958
3959(define_split
3960 [(set (match_operand:SF 0 "register_operand" "")
3961 (float_truncate:SF
3962 (match_operand:XF 1 "register_operand" "")))
3963 (clobber (match_operand:SF 2 "memory_operand" ""))]
3964 "TARGET_80387 && reload_completed"
3965 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3966 (set (match_dup 0) (match_dup 2))]
3967 "")
3968
3969(define_split
3970 [(set (match_operand:SF 0 "memory_operand" "")
3971 (float_truncate:SF
3972 (match_operand:XF 1 "register_operand" "")))
3973 (clobber (match_operand:SF 2 "memory_operand" ""))]
3974 "TARGET_80387"
3975 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3976 "")
3977
3978;; Conversion from XFmode to DFmode.
3979
3980(define_expand "truncxfdf2"
3981 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3982 (float_truncate:DF
3983 (match_operand:XF 1 "register_operand" "")))
3984 (clobber (match_dup 2))])]
3985 "TARGET_80387"
3986{
3987 if (flag_unsafe_math_optimizations)
3988 {
3989 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3990 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3991 if (reg != operands[0])
3992 emit_move_insn (operands[0], reg);
3993 DONE;
3994 }
3995 else
3996 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3997})
3998
3999(define_insn "*truncxfdf2_mixed"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4001 (float_truncate:DF
4002 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4003 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4004 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4005{
4006 gcc_assert (!which_alternative);
4007 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008 return "fstp%z0\t%y0";
4009 else
4010 return "fst%z0\t%y0";
4011}
4012 [(set_attr "type" "fmov,multi,multi,multi")
4013 (set_attr "unit" "*,i387,i387,i387")
4014 (set_attr "mode" "DF")])
4015
4016(define_insn "truncxfdf2_i387_noop"
4017 [(set (match_operand:DF 0 "register_operand" "=f")
4018 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4019 "TARGET_80387 && flag_unsafe_math_optimizations"
4020{
4021 return output_387_reg_move (insn, operands);
4022}
4023 [(set_attr "type" "fmov")
4024 (set_attr "mode" "DF")])
4025
4026(define_insn "*truncxfdf2_i387"
4027 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4028 (float_truncate:DF
4029 (match_operand:XF 1 "register_operand" "f,f,f")))
4030 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4031 "TARGET_80387"
4032{
4033 gcc_assert (!which_alternative);
4034 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4035 return "fstp%z0\t%y0";
4036 else
4037 return "fst%z0\t%y0";
4038}
4039 [(set_attr "type" "fmov,multi,multi")
4040 (set_attr "unit" "*,i387,i387")
4041 (set_attr "mode" "DF")])
4042
4043(define_insn "*truncxfdf2_i387_1"
4044 [(set (match_operand:DF 0 "memory_operand" "=m")
4045 (float_truncate:DF
4046 (match_operand:XF 1 "register_operand" "f")))]
4047 "TARGET_80387"
4048{
4049 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4050 return "fstp%z0\t%y0";
4051 else
4052 return "fst%z0\t%y0";
4053}
4054 [(set_attr "type" "fmov")
4055 (set_attr "mode" "DF")])
4056
4057(define_split
4058 [(set (match_operand:DF 0 "register_operand" "")
4059 (float_truncate:DF
4060 (match_operand:XF 1 "register_operand" "")))
4061 (clobber (match_operand:DF 2 "memory_operand" ""))]
4062 "TARGET_80387 && reload_completed"
4063 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4064 (set (match_dup 0) (match_dup 2))]
4065 "")
4066
4067(define_split
4068 [(set (match_operand:DF 0 "memory_operand" "")
4069 (float_truncate:DF
4070 (match_operand:XF 1 "register_operand" "")))
4071 (clobber (match_operand:DF 2 "memory_operand" ""))]
4072 "TARGET_80387"
4073 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4074 "")
4075
4076;; Signed conversion to DImode.
4077
4078(define_expand "fix_truncxfdi2"
4079 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080 (fix:DI (match_operand:XF 1 "register_operand" "")))
4081 (clobber (reg:CC FLAGS_REG))])]
4082 "TARGET_80387"
4083{
4084 if (TARGET_FISTTP)
4085 {
4086 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4087 DONE;
4088 }
4089})
4090
4091(define_expand "fix_trunc<mode>di2"
4092 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4093 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4094 (clobber (reg:CC FLAGS_REG))])]
4095 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4096{
4097 if (TARGET_FISTTP
4098 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4099 {
4100 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4101 DONE;
4102 }
4103 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4104 {
4105 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4106 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4107 if (out != operands[0])
4108 emit_move_insn (operands[0], out);
4109 DONE;
4110 }
4111})
4112
4113;; Signed conversion to SImode.
4114
4115(define_expand "fix_truncxfsi2"
4116 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4117 (fix:SI (match_operand:XF 1 "register_operand" "")))
4118 (clobber (reg:CC FLAGS_REG))])]
4119 "TARGET_80387"
4120{
4121 if (TARGET_FISTTP)
4122 {
4123 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4124 DONE;
4125 }
4126})
4127
4128(define_expand "fix_trunc<mode>si2"
4129 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4130 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4131 (clobber (reg:CC FLAGS_REG))])]
4132 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4133{
4134 if (TARGET_FISTTP
4135 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4136 {
4137 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4138 DONE;
4139 }
4140 if (SSE_FLOAT_MODE_P (<MODE>mode))
4141 {
4142 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4143 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4144 if (out != operands[0])
4145 emit_move_insn (operands[0], out);
4146 DONE;
4147 }
4148})
4149
4150;; Signed conversion to HImode.
4151
4152(define_expand "fix_trunc<mode>hi2"
4153 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4154 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4155 (clobber (reg:CC FLAGS_REG))])]
4156 "TARGET_80387
4157 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4158{
4159 if (TARGET_FISTTP)
4160 {
4161 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4162 DONE;
4163 }
4164})
4165
4166;; When SSE is available, it is always faster to use it!
4167(define_insn "fix_truncsfdi_sse"
4168 [(set (match_operand:DI 0 "register_operand" "=r,r")
4169 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4170 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171 "cvttss2si{q}\t{%1, %0|%0, %1}"
4172 [(set_attr "type" "sseicvt")
4173 (set_attr "mode" "SF")
4153 (set_attr "athlon_decode" "double,vector")])
4174 (set_attr "athlon_decode" "double,vector")
4175 (set_attr "amdfam10_decode" "double,double")])
4154
4155(define_insn "fix_truncdfdi_sse"
4156 [(set (match_operand:DI 0 "register_operand" "=r,r")
4157 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4158 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4159 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4160 [(set_attr "type" "sseicvt")
4161 (set_attr "mode" "DF")
4176
4177(define_insn "fix_truncdfdi_sse"
4178 [(set (match_operand:DI 0 "register_operand" "=r,r")
4179 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4180 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4181 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4182 [(set_attr "type" "sseicvt")
4183 (set_attr "mode" "DF")
4162 (set_attr "athlon_decode" "double,vector")])
4184 (set_attr "athlon_decode" "double,vector")
4185 (set_attr "amdfam10_decode" "double,double")])
4163
4164(define_insn "fix_truncsfsi_sse"
4165 [(set (match_operand:SI 0 "register_operand" "=r,r")
4166 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4167 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4168 "cvttss2si\t{%1, %0|%0, %1}"
4169 [(set_attr "type" "sseicvt")
4170 (set_attr "mode" "DF")
4186
4187(define_insn "fix_truncsfsi_sse"
4188 [(set (match_operand:SI 0 "register_operand" "=r,r")
4189 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4190 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4191 "cvttss2si\t{%1, %0|%0, %1}"
4192 [(set_attr "type" "sseicvt")
4193 (set_attr "mode" "DF")
4171 (set_attr "athlon_decode" "double,vector")])
4194 (set_attr "athlon_decode" "double,vector")
4195 (set_attr "amdfam10_decode" "double,double")])
4172
4173(define_insn "fix_truncdfsi_sse"
4174 [(set (match_operand:SI 0 "register_operand" "=r,r")
4175 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4176 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4177 "cvttsd2si\t{%1, %0|%0, %1}"
4178 [(set_attr "type" "sseicvt")
4179 (set_attr "mode" "DF")
4196
4197(define_insn "fix_truncdfsi_sse"
4198 [(set (match_operand:SI 0 "register_operand" "=r,r")
4199 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4200 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4201 "cvttsd2si\t{%1, %0|%0, %1}"
4202 [(set_attr "type" "sseicvt")
4203 (set_attr "mode" "DF")
4180 (set_attr "athlon_decode" "double,vector")])
4204 (set_attr "athlon_decode" "double,vector")
4205 (set_attr "amdfam10_decode" "double,double")])
4181
4182;; Avoid vector decoded forms of the instruction.
4183(define_peephole2
4184 [(match_scratch:DF 2 "Y")
4185 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4186 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4187 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4188 [(set (match_dup 2) (match_dup 1))
4189 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4190 "")
4191
4192(define_peephole2
4193 [(match_scratch:SF 2 "x")
4194 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4195 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4196 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4197 [(set (match_dup 2) (match_dup 1))
4198 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4199 "")
4200
4201(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4202 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4203 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4204 "TARGET_FISTTP
4205 && FLOAT_MODE_P (GET_MODE (operands[1]))
4206 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4207 && (TARGET_64BIT || <MODE>mode != DImode))
4208 && TARGET_SSE_MATH)
4209 && !(reload_completed || reload_in_progress)"
4210 "#"
4211 "&& 1"
4212 [(const_int 0)]
4213{
4214 if (memory_operand (operands[0], VOIDmode))
4215 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4216 else
4217 {
4218 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4219 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4220 operands[1],
4221 operands[2]));
4222 }
4223 DONE;
4224}
4225 [(set_attr "type" "fisttp")
4226 (set_attr "mode" "<MODE>")])
4227
4228(define_insn "fix_trunc<mode>_i387_fisttp"
4229 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4230 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4231 (clobber (match_scratch:XF 2 "=&1f"))]
4232 "TARGET_FISTTP
4233 && FLOAT_MODE_P (GET_MODE (operands[1]))
4234 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4235 && (TARGET_64BIT || <MODE>mode != DImode))
4236 && TARGET_SSE_MATH)"
4237 "* return output_fix_trunc (insn, operands, 1);"
4238 [(set_attr "type" "fisttp")
4239 (set_attr "mode" "<MODE>")])
4240
4241(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4242 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4243 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4244 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4245 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4246 "TARGET_FISTTP
4247 && FLOAT_MODE_P (GET_MODE (operands[1]))
4248 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249 && (TARGET_64BIT || <MODE>mode != DImode))
4250 && TARGET_SSE_MATH)"
4251 "#"
4252 [(set_attr "type" "fisttp")
4253 (set_attr "mode" "<MODE>")])
4254
4255(define_split
4256 [(set (match_operand:X87MODEI 0 "register_operand" "")
4257 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4258 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4259 (clobber (match_scratch 3 ""))]
4260 "reload_completed"
4261 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4262 (clobber (match_dup 3))])
4263 (set (match_dup 0) (match_dup 2))]
4264 "")
4265
4266(define_split
4267 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4268 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4269 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4270 (clobber (match_scratch 3 ""))]
4271 "reload_completed"
4272 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4273 (clobber (match_dup 3))])]
4274 "")
4275
4276;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4277;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4278;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4279;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4280;; function in i386.c.
4281(define_insn_and_split "*fix_trunc<mode>_i387_1"
4282 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4283 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4284 (clobber (reg:CC FLAGS_REG))]
4285 "TARGET_80387 && !TARGET_FISTTP
4286 && FLOAT_MODE_P (GET_MODE (operands[1]))
4287 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4288 && (TARGET_64BIT || <MODE>mode != DImode))
4289 && !(reload_completed || reload_in_progress)"
4290 "#"
4291 "&& 1"
4292 [(const_int 0)]
4293{
4294 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4295
4296 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4297 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4298 if (memory_operand (operands[0], VOIDmode))
4299 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4300 operands[2], operands[3]));
4301 else
4302 {
4303 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4304 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4305 operands[2], operands[3],
4306 operands[4]));
4307 }
4308 DONE;
4309}
4310 [(set_attr "type" "fistp")
4311 (set_attr "i387_cw" "trunc")
4312 (set_attr "mode" "<MODE>")])
4313
4314(define_insn "fix_truncdi_i387"
4315 [(set (match_operand:DI 0 "memory_operand" "=m")
4316 (fix:DI (match_operand 1 "register_operand" "f")))
4317 (use (match_operand:HI 2 "memory_operand" "m"))
4318 (use (match_operand:HI 3 "memory_operand" "m"))
4319 (clobber (match_scratch:XF 4 "=&1f"))]
4320 "TARGET_80387 && !TARGET_FISTTP
4321 && FLOAT_MODE_P (GET_MODE (operands[1]))
4322 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4323 "* return output_fix_trunc (insn, operands, 0);"
4324 [(set_attr "type" "fistp")
4325 (set_attr "i387_cw" "trunc")
4326 (set_attr "mode" "DI")])
4327
4328(define_insn "fix_truncdi_i387_with_temp"
4329 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4330 (fix:DI (match_operand 1 "register_operand" "f,f")))
4331 (use (match_operand:HI 2 "memory_operand" "m,m"))
4332 (use (match_operand:HI 3 "memory_operand" "m,m"))
4333 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4334 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4335 "TARGET_80387 && !TARGET_FISTTP
4336 && FLOAT_MODE_P (GET_MODE (operands[1]))
4337 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4338 "#"
4339 [(set_attr "type" "fistp")
4340 (set_attr "i387_cw" "trunc")
4341 (set_attr "mode" "DI")])
4342
4343(define_split
4344 [(set (match_operand:DI 0 "register_operand" "")
4345 (fix:DI (match_operand 1 "register_operand" "")))
4346 (use (match_operand:HI 2 "memory_operand" ""))
4347 (use (match_operand:HI 3 "memory_operand" ""))
4348 (clobber (match_operand:DI 4 "memory_operand" ""))
4349 (clobber (match_scratch 5 ""))]
4350 "reload_completed"
4351 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4352 (use (match_dup 2))
4353 (use (match_dup 3))
4354 (clobber (match_dup 5))])
4355 (set (match_dup 0) (match_dup 4))]
4356 "")
4357
4358(define_split
4359 [(set (match_operand:DI 0 "memory_operand" "")
4360 (fix:DI (match_operand 1 "register_operand" "")))
4361 (use (match_operand:HI 2 "memory_operand" ""))
4362 (use (match_operand:HI 3 "memory_operand" ""))
4363 (clobber (match_operand:DI 4 "memory_operand" ""))
4364 (clobber (match_scratch 5 ""))]
4365 "reload_completed"
4366 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4367 (use (match_dup 2))
4368 (use (match_dup 3))
4369 (clobber (match_dup 5))])]
4370 "")
4371
4372(define_insn "fix_trunc<mode>_i387"
4373 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4374 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4375 (use (match_operand:HI 2 "memory_operand" "m"))
4376 (use (match_operand:HI 3 "memory_operand" "m"))]
4377 "TARGET_80387 && !TARGET_FISTTP
4378 && FLOAT_MODE_P (GET_MODE (operands[1]))
4379 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380 "* return output_fix_trunc (insn, operands, 0);"
4381 [(set_attr "type" "fistp")
4382 (set_attr "i387_cw" "trunc")
4383 (set_attr "mode" "<MODE>")])
4384
4385(define_insn "fix_trunc<mode>_i387_with_temp"
4386 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4387 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4388 (use (match_operand:HI 2 "memory_operand" "m,m"))
4389 (use (match_operand:HI 3 "memory_operand" "m,m"))
4390 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4391 "TARGET_80387 && !TARGET_FISTTP
4392 && FLOAT_MODE_P (GET_MODE (operands[1]))
4393 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4394 "#"
4395 [(set_attr "type" "fistp")
4396 (set_attr "i387_cw" "trunc")
4397 (set_attr "mode" "<MODE>")])
4398
4399(define_split
4400 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4401 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4402 (use (match_operand:HI 2 "memory_operand" ""))
4403 (use (match_operand:HI 3 "memory_operand" ""))
4404 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4405 "reload_completed"
4406 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4407 (use (match_dup 2))
4408 (use (match_dup 3))])
4409 (set (match_dup 0) (match_dup 4))]
4410 "")
4411
4412(define_split
4413 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4414 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4415 (use (match_operand:HI 2 "memory_operand" ""))
4416 (use (match_operand:HI 3 "memory_operand" ""))
4417 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4418 "reload_completed"
4419 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4420 (use (match_dup 2))
4421 (use (match_dup 3))])]
4422 "")
4423
4424(define_insn "x86_fnstcw_1"
4425 [(set (match_operand:HI 0 "memory_operand" "=m")
4426 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4427 "TARGET_80387"
4428 "fnstcw\t%0"
4429 [(set_attr "length" "2")
4430 (set_attr "mode" "HI")
4431 (set_attr "unit" "i387")])
4432
4433(define_insn "x86_fldcw_1"
4434 [(set (reg:HI FPSR_REG)
4435 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4436 "TARGET_80387"
4437 "fldcw\t%0"
4438 [(set_attr "length" "2")
4439 (set_attr "mode" "HI")
4440 (set_attr "unit" "i387")
4206
4207;; Avoid vector decoded forms of the instruction.
4208(define_peephole2
4209 [(match_scratch:DF 2 "Y")
4210 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4211 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4212 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4213 [(set (match_dup 2) (match_dup 1))
4214 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4215 "")
4216
4217(define_peephole2
4218 [(match_scratch:SF 2 "x")
4219 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4220 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4221 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4222 [(set (match_dup 2) (match_dup 1))
4223 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4224 "")
4225
4226(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4227 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4228 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4229 "TARGET_FISTTP
4230 && FLOAT_MODE_P (GET_MODE (operands[1]))
4231 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4232 && (TARGET_64BIT || <MODE>mode != DImode))
4233 && TARGET_SSE_MATH)
4234 && !(reload_completed || reload_in_progress)"
4235 "#"
4236 "&& 1"
4237 [(const_int 0)]
4238{
4239 if (memory_operand (operands[0], VOIDmode))
4240 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4241 else
4242 {
4243 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4244 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4245 operands[1],
4246 operands[2]));
4247 }
4248 DONE;
4249}
4250 [(set_attr "type" "fisttp")
4251 (set_attr "mode" "<MODE>")])
4252
4253(define_insn "fix_trunc<mode>_i387_fisttp"
4254 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4255 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4256 (clobber (match_scratch:XF 2 "=&1f"))]
4257 "TARGET_FISTTP
4258 && FLOAT_MODE_P (GET_MODE (operands[1]))
4259 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4260 && (TARGET_64BIT || <MODE>mode != DImode))
4261 && TARGET_SSE_MATH)"
4262 "* return output_fix_trunc (insn, operands, 1);"
4263 [(set_attr "type" "fisttp")
4264 (set_attr "mode" "<MODE>")])
4265
4266(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4267 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4268 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4269 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4270 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4271 "TARGET_FISTTP
4272 && FLOAT_MODE_P (GET_MODE (operands[1]))
4273 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4274 && (TARGET_64BIT || <MODE>mode != DImode))
4275 && TARGET_SSE_MATH)"
4276 "#"
4277 [(set_attr "type" "fisttp")
4278 (set_attr "mode" "<MODE>")])
4279
4280(define_split
4281 [(set (match_operand:X87MODEI 0 "register_operand" "")
4282 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4283 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4284 (clobber (match_scratch 3 ""))]
4285 "reload_completed"
4286 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4287 (clobber (match_dup 3))])
4288 (set (match_dup 0) (match_dup 2))]
4289 "")
4290
4291(define_split
4292 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4293 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4294 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4295 (clobber (match_scratch 3 ""))]
4296 "reload_completed"
4297 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4298 (clobber (match_dup 3))])]
4299 "")
4300
4301;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4302;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4303;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4304;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4305;; function in i386.c.
4306(define_insn_and_split "*fix_trunc<mode>_i387_1"
4307 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4308 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4309 (clobber (reg:CC FLAGS_REG))]
4310 "TARGET_80387 && !TARGET_FISTTP
4311 && FLOAT_MODE_P (GET_MODE (operands[1]))
4312 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4313 && (TARGET_64BIT || <MODE>mode != DImode))
4314 && !(reload_completed || reload_in_progress)"
4315 "#"
4316 "&& 1"
4317 [(const_int 0)]
4318{
4319 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4320
4321 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4322 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4323 if (memory_operand (operands[0], VOIDmode))
4324 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4325 operands[2], operands[3]));
4326 else
4327 {
4328 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4329 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4330 operands[2], operands[3],
4331 operands[4]));
4332 }
4333 DONE;
4334}
4335 [(set_attr "type" "fistp")
4336 (set_attr "i387_cw" "trunc")
4337 (set_attr "mode" "<MODE>")])
4338
4339(define_insn "fix_truncdi_i387"
4340 [(set (match_operand:DI 0 "memory_operand" "=m")
4341 (fix:DI (match_operand 1 "register_operand" "f")))
4342 (use (match_operand:HI 2 "memory_operand" "m"))
4343 (use (match_operand:HI 3 "memory_operand" "m"))
4344 (clobber (match_scratch:XF 4 "=&1f"))]
4345 "TARGET_80387 && !TARGET_FISTTP
4346 && FLOAT_MODE_P (GET_MODE (operands[1]))
4347 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4348 "* return output_fix_trunc (insn, operands, 0);"
4349 [(set_attr "type" "fistp")
4350 (set_attr "i387_cw" "trunc")
4351 (set_attr "mode" "DI")])
4352
4353(define_insn "fix_truncdi_i387_with_temp"
4354 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4355 (fix:DI (match_operand 1 "register_operand" "f,f")))
4356 (use (match_operand:HI 2 "memory_operand" "m,m"))
4357 (use (match_operand:HI 3 "memory_operand" "m,m"))
4358 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4359 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4360 "TARGET_80387 && !TARGET_FISTTP
4361 && FLOAT_MODE_P (GET_MODE (operands[1]))
4362 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4363 "#"
4364 [(set_attr "type" "fistp")
4365 (set_attr "i387_cw" "trunc")
4366 (set_attr "mode" "DI")])
4367
4368(define_split
4369 [(set (match_operand:DI 0 "register_operand" "")
4370 (fix:DI (match_operand 1 "register_operand" "")))
4371 (use (match_operand:HI 2 "memory_operand" ""))
4372 (use (match_operand:HI 3 "memory_operand" ""))
4373 (clobber (match_operand:DI 4 "memory_operand" ""))
4374 (clobber (match_scratch 5 ""))]
4375 "reload_completed"
4376 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4377 (use (match_dup 2))
4378 (use (match_dup 3))
4379 (clobber (match_dup 5))])
4380 (set (match_dup 0) (match_dup 4))]
4381 "")
4382
4383(define_split
4384 [(set (match_operand:DI 0 "memory_operand" "")
4385 (fix:DI (match_operand 1 "register_operand" "")))
4386 (use (match_operand:HI 2 "memory_operand" ""))
4387 (use (match_operand:HI 3 "memory_operand" ""))
4388 (clobber (match_operand:DI 4 "memory_operand" ""))
4389 (clobber (match_scratch 5 ""))]
4390 "reload_completed"
4391 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4392 (use (match_dup 2))
4393 (use (match_dup 3))
4394 (clobber (match_dup 5))])]
4395 "")
4396
4397(define_insn "fix_trunc<mode>_i387"
4398 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4399 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4400 (use (match_operand:HI 2 "memory_operand" "m"))
4401 (use (match_operand:HI 3 "memory_operand" "m"))]
4402 "TARGET_80387 && !TARGET_FISTTP
4403 && FLOAT_MODE_P (GET_MODE (operands[1]))
4404 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4405 "* return output_fix_trunc (insn, operands, 0);"
4406 [(set_attr "type" "fistp")
4407 (set_attr "i387_cw" "trunc")
4408 (set_attr "mode" "<MODE>")])
4409
4410(define_insn "fix_trunc<mode>_i387_with_temp"
4411 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4412 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4413 (use (match_operand:HI 2 "memory_operand" "m,m"))
4414 (use (match_operand:HI 3 "memory_operand" "m,m"))
4415 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4416 "TARGET_80387 && !TARGET_FISTTP
4417 && FLOAT_MODE_P (GET_MODE (operands[1]))
4418 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4419 "#"
4420 [(set_attr "type" "fistp")
4421 (set_attr "i387_cw" "trunc")
4422 (set_attr "mode" "<MODE>")])
4423
4424(define_split
4425 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4426 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4427 (use (match_operand:HI 2 "memory_operand" ""))
4428 (use (match_operand:HI 3 "memory_operand" ""))
4429 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4430 "reload_completed"
4431 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4432 (use (match_dup 2))
4433 (use (match_dup 3))])
4434 (set (match_dup 0) (match_dup 4))]
4435 "")
4436
4437(define_split
4438 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4439 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4440 (use (match_operand:HI 2 "memory_operand" ""))
4441 (use (match_operand:HI 3 "memory_operand" ""))
4442 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4443 "reload_completed"
4444 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4445 (use (match_dup 2))
4446 (use (match_dup 3))])]
4447 "")
4448
4449(define_insn "x86_fnstcw_1"
4450 [(set (match_operand:HI 0 "memory_operand" "=m")
4451 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4452 "TARGET_80387"
4453 "fnstcw\t%0"
4454 [(set_attr "length" "2")
4455 (set_attr "mode" "HI")
4456 (set_attr "unit" "i387")])
4457
4458(define_insn "x86_fldcw_1"
4459 [(set (reg:HI FPSR_REG)
4460 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4461 "TARGET_80387"
4462 "fldcw\t%0"
4463 [(set_attr "length" "2")
4464 (set_attr "mode" "HI")
4465 (set_attr "unit" "i387")
4441 (set_attr "athlon_decode" "vector")])
4466 (set_attr "athlon_decode" "vector")
4467 (set_attr "amdfam10_decode" "vector")])
4442
4443;; Conversion between fixed point and floating point.
4444
4445;; Even though we only accept memory inputs, the backend _really_
4446;; wants to be able to do this between registers.
4447
4448(define_expand "floathisf2"
4449 [(set (match_operand:SF 0 "register_operand" "")
4450 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4451 "TARGET_80387 || TARGET_SSE_MATH"
4452{
4453 if (TARGET_SSE_MATH)
4454 {
4455 emit_insn (gen_floatsisf2 (operands[0],
4456 convert_to_mode (SImode, operands[1], 0)));
4457 DONE;
4458 }
4459})
4460
4461(define_insn "*floathisf2_i387"
4462 [(set (match_operand:SF 0 "register_operand" "=f,f")
4463 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4464 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4465 "@
4466 fild%z1\t%1
4467 #"
4468 [(set_attr "type" "fmov,multi")
4469 (set_attr "mode" "SF")
4470 (set_attr "unit" "*,i387")
4471 (set_attr "fp_int_src" "true")])
4472
4473(define_expand "floatsisf2"
4474 [(set (match_operand:SF 0 "register_operand" "")
4475 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4476 "TARGET_80387 || TARGET_SSE_MATH"
4477 "")
4478
4479(define_insn "*floatsisf2_mixed"
4480 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4481 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4482 "TARGET_MIX_SSE_I387"
4483 "@
4484 fild%z1\t%1
4485 #
4486 cvtsi2ss\t{%1, %0|%0, %1}
4487 cvtsi2ss\t{%1, %0|%0, %1}"
4488 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4489 (set_attr "mode" "SF")
4490 (set_attr "unit" "*,i387,*,*")
4491 (set_attr "athlon_decode" "*,*,vector,double")
4468
4469;; Conversion between fixed point and floating point.
4470
4471;; Even though we only accept memory inputs, the backend _really_
4472;; wants to be able to do this between registers.
4473
4474(define_expand "floathisf2"
4475 [(set (match_operand:SF 0 "register_operand" "")
4476 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4477 "TARGET_80387 || TARGET_SSE_MATH"
4478{
4479 if (TARGET_SSE_MATH)
4480 {
4481 emit_insn (gen_floatsisf2 (operands[0],
4482 convert_to_mode (SImode, operands[1], 0)));
4483 DONE;
4484 }
4485})
4486
4487(define_insn "*floathisf2_i387"
4488 [(set (match_operand:SF 0 "register_operand" "=f,f")
4489 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4490 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4491 "@
4492 fild%z1\t%1
4493 #"
4494 [(set_attr "type" "fmov,multi")
4495 (set_attr "mode" "SF")
4496 (set_attr "unit" "*,i387")
4497 (set_attr "fp_int_src" "true")])
4498
4499(define_expand "floatsisf2"
4500 [(set (match_operand:SF 0 "register_operand" "")
4501 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4502 "TARGET_80387 || TARGET_SSE_MATH"
4503 "")
4504
4505(define_insn "*floatsisf2_mixed"
4506 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4507 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4508 "TARGET_MIX_SSE_I387"
4509 "@
4510 fild%z1\t%1
4511 #
4512 cvtsi2ss\t{%1, %0|%0, %1}
4513 cvtsi2ss\t{%1, %0|%0, %1}"
4514 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4515 (set_attr "mode" "SF")
4516 (set_attr "unit" "*,i387,*,*")
4517 (set_attr "athlon_decode" "*,*,vector,double")
4518 (set_attr "amdfam10_decode" "*,*,vector,double")
4492 (set_attr "fp_int_src" "true")])
4493
4494(define_insn "*floatsisf2_sse"
4495 [(set (match_operand:SF 0 "register_operand" "=x,x")
4496 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4497 "TARGET_SSE_MATH"
4498 "cvtsi2ss\t{%1, %0|%0, %1}"
4499 [(set_attr "type" "sseicvt")
4500 (set_attr "mode" "SF")
4501 (set_attr "athlon_decode" "vector,double")
4519 (set_attr "fp_int_src" "true")])
4520
4521(define_insn "*floatsisf2_sse"
4522 [(set (match_operand:SF 0 "register_operand" "=x,x")
4523 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4524 "TARGET_SSE_MATH"
4525 "cvtsi2ss\t{%1, %0|%0, %1}"
4526 [(set_attr "type" "sseicvt")
4527 (set_attr "mode" "SF")
4528 (set_attr "athlon_decode" "vector,double")
4529 (set_attr "amdfam10_decode" "vector,double")
4502 (set_attr "fp_int_src" "true")])
4503
4504(define_insn "*floatsisf2_i387"
4505 [(set (match_operand:SF 0 "register_operand" "=f,f")
4506 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4507 "TARGET_80387"
4508 "@
4509 fild%z1\t%1
4510 #"
4511 [(set_attr "type" "fmov,multi")
4512 (set_attr "mode" "SF")
4513 (set_attr "unit" "*,i387")
4514 (set_attr "fp_int_src" "true")])
4515
4516(define_expand "floatdisf2"
4517 [(set (match_operand:SF 0 "register_operand" "")
4518 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4519 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4520 "")
4521
4522(define_insn "*floatdisf2_mixed"
4523 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4524 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4525 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4526 "@
4527 fild%z1\t%1
4528 #
4529 cvtsi2ss{q}\t{%1, %0|%0, %1}
4530 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4531 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4532 (set_attr "mode" "SF")
4533 (set_attr "unit" "*,i387,*,*")
4534 (set_attr "athlon_decode" "*,*,vector,double")
4530 (set_attr "fp_int_src" "true")])
4531
4532(define_insn "*floatsisf2_i387"
4533 [(set (match_operand:SF 0 "register_operand" "=f,f")
4534 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4535 "TARGET_80387"
4536 "@
4537 fild%z1\t%1
4538 #"
4539 [(set_attr "type" "fmov,multi")
4540 (set_attr "mode" "SF")
4541 (set_attr "unit" "*,i387")
4542 (set_attr "fp_int_src" "true")])
4543
4544(define_expand "floatdisf2"
4545 [(set (match_operand:SF 0 "register_operand" "")
4546 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4547 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4548 "")
4549
4550(define_insn "*floatdisf2_mixed"
4551 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4552 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4553 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4554 "@
4555 fild%z1\t%1
4556 #
4557 cvtsi2ss{q}\t{%1, %0|%0, %1}
4558 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4559 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4560 (set_attr "mode" "SF")
4561 (set_attr "unit" "*,i387,*,*")
4562 (set_attr "athlon_decode" "*,*,vector,double")
4563 (set_attr "amdfam10_decode" "*,*,vector,double")
4535 (set_attr "fp_int_src" "true")])
4536
4537(define_insn "*floatdisf2_sse"
4538 [(set (match_operand:SF 0 "register_operand" "=x,x")
4539 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4540 "TARGET_64BIT && TARGET_SSE_MATH"
4541 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4542 [(set_attr "type" "sseicvt")
4543 (set_attr "mode" "SF")
4544 (set_attr "athlon_decode" "vector,double")
4564 (set_attr "fp_int_src" "true")])
4565
4566(define_insn "*floatdisf2_sse"
4567 [(set (match_operand:SF 0 "register_operand" "=x,x")
4568 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4569 "TARGET_64BIT && TARGET_SSE_MATH"
4570 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4571 [(set_attr "type" "sseicvt")
4572 (set_attr "mode" "SF")
4573 (set_attr "athlon_decode" "vector,double")
4574 (set_attr "amdfam10_decode" "vector,double")
4545 (set_attr "fp_int_src" "true")])
4546
4547(define_insn "*floatdisf2_i387"
4548 [(set (match_operand:SF 0 "register_operand" "=f,f")
4549 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4550 "TARGET_80387"
4551 "@
4552 fild%z1\t%1
4553 #"
4554 [(set_attr "type" "fmov,multi")
4555 (set_attr "mode" "SF")
4556 (set_attr "unit" "*,i387")
4557 (set_attr "fp_int_src" "true")])
4558
4559(define_expand "floathidf2"
4560 [(set (match_operand:DF 0 "register_operand" "")
4561 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4562 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4563{
4564 if (TARGET_SSE2 && TARGET_SSE_MATH)
4565 {
4566 emit_insn (gen_floatsidf2 (operands[0],
4567 convert_to_mode (SImode, operands[1], 0)));
4568 DONE;
4569 }
4570})
4571
4572(define_insn "*floathidf2_i387"
4573 [(set (match_operand:DF 0 "register_operand" "=f,f")
4574 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4575 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4576 "@
4577 fild%z1\t%1
4578 #"
4579 [(set_attr "type" "fmov,multi")
4580 (set_attr "mode" "DF")
4581 (set_attr "unit" "*,i387")
4582 (set_attr "fp_int_src" "true")])
4583
4584(define_expand "floatsidf2"
4585 [(set (match_operand:DF 0 "register_operand" "")
4586 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4587 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4588 "")
4589
4590(define_insn "*floatsidf2_mixed"
4591 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4592 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4594 "@
4595 fild%z1\t%1
4596 #
4597 cvtsi2sd\t{%1, %0|%0, %1}
4598 cvtsi2sd\t{%1, %0|%0, %1}"
4599 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600 (set_attr "mode" "DF")
4601 (set_attr "unit" "*,i387,*,*")
4602 (set_attr "athlon_decode" "*,*,double,direct")
4575 (set_attr "fp_int_src" "true")])
4576
4577(define_insn "*floatdisf2_i387"
4578 [(set (match_operand:SF 0 "register_operand" "=f,f")
4579 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4580 "TARGET_80387"
4581 "@
4582 fild%z1\t%1
4583 #"
4584 [(set_attr "type" "fmov,multi")
4585 (set_attr "mode" "SF")
4586 (set_attr "unit" "*,i387")
4587 (set_attr "fp_int_src" "true")])
4588
4589(define_expand "floathidf2"
4590 [(set (match_operand:DF 0 "register_operand" "")
4591 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4592 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4593{
4594 if (TARGET_SSE2 && TARGET_SSE_MATH)
4595 {
4596 emit_insn (gen_floatsidf2 (operands[0],
4597 convert_to_mode (SImode, operands[1], 0)));
4598 DONE;
4599 }
4600})
4601
4602(define_insn "*floathidf2_i387"
4603 [(set (match_operand:DF 0 "register_operand" "=f,f")
4604 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4605 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4606 "@
4607 fild%z1\t%1
4608 #"
4609 [(set_attr "type" "fmov,multi")
4610 (set_attr "mode" "DF")
4611 (set_attr "unit" "*,i387")
4612 (set_attr "fp_int_src" "true")])
4613
4614(define_expand "floatsidf2"
4615 [(set (match_operand:DF 0 "register_operand" "")
4616 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4617 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4618 "")
4619
4620(define_insn "*floatsidf2_mixed"
4621 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4622 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4623 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4624 "@
4625 fild%z1\t%1
4626 #
4627 cvtsi2sd\t{%1, %0|%0, %1}
4628 cvtsi2sd\t{%1, %0|%0, %1}"
4629 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4630 (set_attr "mode" "DF")
4631 (set_attr "unit" "*,i387,*,*")
4632 (set_attr "athlon_decode" "*,*,double,direct")
4633 (set_attr "amdfam10_decode" "*,*,vector,double")
4603 (set_attr "fp_int_src" "true")])
4604
4605(define_insn "*floatsidf2_sse"
4606 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4607 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4608 "TARGET_SSE2 && TARGET_SSE_MATH"
4609 "cvtsi2sd\t{%1, %0|%0, %1}"
4610 [(set_attr "type" "sseicvt")
4611 (set_attr "mode" "DF")
4612 (set_attr "athlon_decode" "double,direct")
4634 (set_attr "fp_int_src" "true")])
4635
4636(define_insn "*floatsidf2_sse"
4637 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4638 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4639 "TARGET_SSE2 && TARGET_SSE_MATH"
4640 "cvtsi2sd\t{%1, %0|%0, %1}"
4641 [(set_attr "type" "sseicvt")
4642 (set_attr "mode" "DF")
4643 (set_attr "athlon_decode" "double,direct")
4644 (set_attr "amdfam10_decode" "vector,double")
4613 (set_attr "fp_int_src" "true")])
4614
4615(define_insn "*floatsidf2_i387"
4616 [(set (match_operand:DF 0 "register_operand" "=f,f")
4617 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4618 "TARGET_80387"
4619 "@
4620 fild%z1\t%1
4621 #"
4622 [(set_attr "type" "fmov,multi")
4623 (set_attr "mode" "DF")
4624 (set_attr "unit" "*,i387")
4625 (set_attr "fp_int_src" "true")])
4626
4627(define_expand "floatdidf2"
4628 [(set (match_operand:DF 0 "register_operand" "")
4629 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4630 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4631 "")
4632
4633(define_insn "*floatdidf2_mixed"
4634 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4635 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4636 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4637 "@
4638 fild%z1\t%1
4639 #
4640 cvtsi2sd{q}\t{%1, %0|%0, %1}
4641 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4642 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4643 (set_attr "mode" "DF")
4644 (set_attr "unit" "*,i387,*,*")
4645 (set_attr "athlon_decode" "*,*,double,direct")
4645 (set_attr "fp_int_src" "true")])
4646
4647(define_insn "*floatsidf2_i387"
4648 [(set (match_operand:DF 0 "register_operand" "=f,f")
4649 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650 "TARGET_80387"
4651 "@
4652 fild%z1\t%1
4653 #"
4654 [(set_attr "type" "fmov,multi")
4655 (set_attr "mode" "DF")
4656 (set_attr "unit" "*,i387")
4657 (set_attr "fp_int_src" "true")])
4658
4659(define_expand "floatdidf2"
4660 [(set (match_operand:DF 0 "register_operand" "")
4661 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4662 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4663 "")
4664
4665(define_insn "*floatdidf2_mixed"
4666 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4667 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4668 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4669 "@
4670 fild%z1\t%1
4671 #
4672 cvtsi2sd{q}\t{%1, %0|%0, %1}
4673 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4674 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4675 (set_attr "mode" "DF")
4676 (set_attr "unit" "*,i387,*,*")
4677 (set_attr "athlon_decode" "*,*,double,direct")
4678 (set_attr "amdfam10_decode" "*,*,vector,double")
4646 (set_attr "fp_int_src" "true")])
4647
4648(define_insn "*floatdidf2_sse"
4649 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4650 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4651 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4652 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4653 [(set_attr "type" "sseicvt")
4654 (set_attr "mode" "DF")
4655 (set_attr "athlon_decode" "double,direct")
4679 (set_attr "fp_int_src" "true")])
4680
4681(define_insn "*floatdidf2_sse"
4682 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4683 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4684 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4685 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4686 [(set_attr "type" "sseicvt")
4687 (set_attr "mode" "DF")
4688 (set_attr "athlon_decode" "double,direct")
4689 (set_attr "amdfam10_decode" "vector,double")
4656 (set_attr "fp_int_src" "true")])
4657
4658(define_insn "*floatdidf2_i387"
4659 [(set (match_operand:DF 0 "register_operand" "=f,f")
4660 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4661 "TARGET_80387"
4662 "@
4663 fild%z1\t%1
4664 #"
4665 [(set_attr "type" "fmov,multi")
4666 (set_attr "mode" "DF")
4667 (set_attr "unit" "*,i387")
4668 (set_attr "fp_int_src" "true")])
4669
4670(define_insn "floathixf2"
4671 [(set (match_operand:XF 0 "register_operand" "=f,f")
4672 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4673 "TARGET_80387"
4674 "@
4675 fild%z1\t%1
4676 #"
4677 [(set_attr "type" "fmov,multi")
4678 (set_attr "mode" "XF")
4679 (set_attr "unit" "*,i387")
4680 (set_attr "fp_int_src" "true")])
4681
4682(define_insn "floatsixf2"
4683 [(set (match_operand:XF 0 "register_operand" "=f,f")
4684 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4685 "TARGET_80387"
4686 "@
4687 fild%z1\t%1
4688 #"
4689 [(set_attr "type" "fmov,multi")
4690 (set_attr "mode" "XF")
4691 (set_attr "unit" "*,i387")
4692 (set_attr "fp_int_src" "true")])
4693
4694(define_insn "floatdixf2"
4695 [(set (match_operand:XF 0 "register_operand" "=f,f")
4696 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4697 "TARGET_80387"
4698 "@
4699 fild%z1\t%1
4700 #"
4701 [(set_attr "type" "fmov,multi")
4702 (set_attr "mode" "XF")
4703 (set_attr "unit" "*,i387")
4704 (set_attr "fp_int_src" "true")])
4705
4706;; %%% Kill these when reload knows how to do it.
4707(define_split
4708 [(set (match_operand 0 "fp_register_operand" "")
4709 (float (match_operand 1 "register_operand" "")))]
4710 "reload_completed
4711 && TARGET_80387
4712 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4713 [(const_int 0)]
4714{
4715 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4716 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4717 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4718 ix86_free_from_memory (GET_MODE (operands[1]));
4719 DONE;
4720})
4721
4722(define_expand "floatunssisf2"
4723 [(use (match_operand:SF 0 "register_operand" ""))
4724 (use (match_operand:SI 1 "register_operand" ""))]
4725 "!TARGET_64BIT && TARGET_SSE_MATH"
4726 "x86_emit_floatuns (operands); DONE;")
4727
4728(define_expand "floatunsdisf2"
4729 [(use (match_operand:SF 0 "register_operand" ""))
4730 (use (match_operand:DI 1 "register_operand" ""))]
4731 "TARGET_64BIT && TARGET_SSE_MATH"
4732 "x86_emit_floatuns (operands); DONE;")
4733
4734(define_expand "floatunsdidf2"
4735 [(use (match_operand:DF 0 "register_operand" ""))
4736 (use (match_operand:DI 1 "register_operand" ""))]
4737 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4738 "x86_emit_floatuns (operands); DONE;")
4739
4740;; SSE extract/set expanders
4741
4742
4743;; Add instructions
4744
4745;; %%% splits for addditi3
4746
4747(define_expand "addti3"
4748 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4749 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4750 (match_operand:TI 2 "x86_64_general_operand" "")))
4751 (clobber (reg:CC FLAGS_REG))]
4752 "TARGET_64BIT"
4753 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4754
4755(define_insn "*addti3_1"
4756 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4757 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4758 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4759 (clobber (reg:CC FLAGS_REG))]
4760 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4761 "#")
4762
4763(define_split
4764 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4765 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4766 (match_operand:TI 2 "x86_64_general_operand" "")))
4767 (clobber (reg:CC FLAGS_REG))]
4768 "TARGET_64BIT && reload_completed"
4769 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4770 UNSPEC_ADD_CARRY))
4771 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4772 (parallel [(set (match_dup 3)
4773 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4774 (match_dup 4))
4775 (match_dup 5)))
4776 (clobber (reg:CC FLAGS_REG))])]
4777 "split_ti (operands+0, 1, operands+0, operands+3);
4778 split_ti (operands+1, 1, operands+1, operands+4);
4779 split_ti (operands+2, 1, operands+2, operands+5);")
4780
4781;; %%% splits for addsidi3
4782; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4783; (plus:DI (match_operand:DI 1 "general_operand" "")
4784; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4785
4786(define_expand "adddi3"
4787 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4788 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4789 (match_operand:DI 2 "x86_64_general_operand" "")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 ""
4792 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4793
4794(define_insn "*adddi3_1"
4795 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4796 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4797 (match_operand:DI 2 "general_operand" "roiF,riF")))
4798 (clobber (reg:CC FLAGS_REG))]
4799 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4800 "#")
4801
4802(define_split
4803 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4804 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4805 (match_operand:DI 2 "general_operand" "")))
4806 (clobber (reg:CC FLAGS_REG))]
4807 "!TARGET_64BIT && reload_completed"
4808 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4809 UNSPEC_ADD_CARRY))
4810 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4811 (parallel [(set (match_dup 3)
4812 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4813 (match_dup 4))
4814 (match_dup 5)))
4815 (clobber (reg:CC FLAGS_REG))])]
4816 "split_di (operands+0, 1, operands+0, operands+3);
4817 split_di (operands+1, 1, operands+1, operands+4);
4818 split_di (operands+2, 1, operands+2, operands+5);")
4819
4820(define_insn "adddi3_carry_rex64"
4821 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4822 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4823 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4824 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4825 (clobber (reg:CC FLAGS_REG))]
4826 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4827 "adc{q}\t{%2, %0|%0, %2}"
4828 [(set_attr "type" "alu")
4829 (set_attr "pent_pair" "pu")
4830 (set_attr "mode" "DI")])
4831
4832(define_insn "*adddi3_cc_rex64"
4833 [(set (reg:CC FLAGS_REG)
4834 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4835 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4836 UNSPEC_ADD_CARRY))
4837 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4838 (plus:DI (match_dup 1) (match_dup 2)))]
4839 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4840 "add{q}\t{%2, %0|%0, %2}"
4841 [(set_attr "type" "alu")
4842 (set_attr "mode" "DI")])
4843
4844(define_insn "addqi3_carry"
4845 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4846 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4847 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4848 (match_operand:QI 2 "general_operand" "qi,qm")))
4849 (clobber (reg:CC FLAGS_REG))]
4850 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4851 "adc{b}\t{%2, %0|%0, %2}"
4852 [(set_attr "type" "alu")
4853 (set_attr "pent_pair" "pu")
4854 (set_attr "mode" "QI")])
4855
4856(define_insn "addhi3_carry"
4857 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4858 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4859 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4860 (match_operand:HI 2 "general_operand" "ri,rm")))
4861 (clobber (reg:CC FLAGS_REG))]
4862 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4863 "adc{w}\t{%2, %0|%0, %2}"
4864 [(set_attr "type" "alu")
4865 (set_attr "pent_pair" "pu")
4866 (set_attr "mode" "HI")])
4867
4868(define_insn "addsi3_carry"
4869 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4870 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4871 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4872 (match_operand:SI 2 "general_operand" "ri,rm")))
4873 (clobber (reg:CC FLAGS_REG))]
4874 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4875 "adc{l}\t{%2, %0|%0, %2}"
4876 [(set_attr "type" "alu")
4877 (set_attr "pent_pair" "pu")
4878 (set_attr "mode" "SI")])
4879
4880(define_insn "*addsi3_carry_zext"
4881 [(set (match_operand:DI 0 "register_operand" "=r")
4882 (zero_extend:DI
4883 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4884 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4885 (match_operand:SI 2 "general_operand" "rim"))))
4886 (clobber (reg:CC FLAGS_REG))]
4887 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4888 "adc{l}\t{%2, %k0|%k0, %2}"
4889 [(set_attr "type" "alu")
4890 (set_attr "pent_pair" "pu")
4891 (set_attr "mode" "SI")])
4892
4893(define_insn "*addsi3_cc"
4894 [(set (reg:CC FLAGS_REG)
4895 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4896 (match_operand:SI 2 "general_operand" "ri,rm")]
4897 UNSPEC_ADD_CARRY))
4898 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4899 (plus:SI (match_dup 1) (match_dup 2)))]
4900 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4901 "add{l}\t{%2, %0|%0, %2}"
4902 [(set_attr "type" "alu")
4903 (set_attr "mode" "SI")])
4904
4905(define_insn "addqi3_cc"
4906 [(set (reg:CC FLAGS_REG)
4907 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4908 (match_operand:QI 2 "general_operand" "qi,qm")]
4909 UNSPEC_ADD_CARRY))
4910 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4911 (plus:QI (match_dup 1) (match_dup 2)))]
4912 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4913 "add{b}\t{%2, %0|%0, %2}"
4914 [(set_attr "type" "alu")
4915 (set_attr "mode" "QI")])
4916
4917(define_expand "addsi3"
4918 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4919 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4920 (match_operand:SI 2 "general_operand" "")))
4921 (clobber (reg:CC FLAGS_REG))])]
4922 ""
4923 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4924
4925(define_insn "*lea_1"
4926 [(set (match_operand:SI 0 "register_operand" "=r")
4927 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4928 "!TARGET_64BIT"
4929 "lea{l}\t{%a1, %0|%0, %a1}"
4930 [(set_attr "type" "lea")
4931 (set_attr "mode" "SI")])
4932
4933(define_insn "*lea_1_rex64"
4934 [(set (match_operand:SI 0 "register_operand" "=r")
4935 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4936 "TARGET_64BIT"
4937 "lea{l}\t{%a1, %0|%0, %a1}"
4938 [(set_attr "type" "lea")
4939 (set_attr "mode" "SI")])
4940
4941(define_insn "*lea_1_zext"
4942 [(set (match_operand:DI 0 "register_operand" "=r")
4943 (zero_extend:DI
4944 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4945 "TARGET_64BIT"
4946 "lea{l}\t{%a1, %k0|%k0, %a1}"
4947 [(set_attr "type" "lea")
4948 (set_attr "mode" "SI")])
4949
4950(define_insn "*lea_2_rex64"
4951 [(set (match_operand:DI 0 "register_operand" "=r")
4952 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4953 "TARGET_64BIT"
4954 "lea{q}\t{%a1, %0|%0, %a1}"
4955 [(set_attr "type" "lea")
4956 (set_attr "mode" "DI")])
4957
4958;; The lea patterns for non-Pmodes needs to be matched by several
4959;; insns converted to real lea by splitters.
4960
4961(define_insn_and_split "*lea_general_1"
4962 [(set (match_operand 0 "register_operand" "=r")
4963 (plus (plus (match_operand 1 "index_register_operand" "l")
4964 (match_operand 2 "register_operand" "r"))
4965 (match_operand 3 "immediate_operand" "i")))]
4966 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4967 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4968 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4969 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4970 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4971 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4972 || GET_MODE (operands[3]) == VOIDmode)"
4973 "#"
4974 "&& reload_completed"
4975 [(const_int 0)]
4976{
4977 rtx pat;
4978 operands[0] = gen_lowpart (SImode, operands[0]);
4979 operands[1] = gen_lowpart (Pmode, operands[1]);
4980 operands[2] = gen_lowpart (Pmode, operands[2]);
4981 operands[3] = gen_lowpart (Pmode, operands[3]);
4982 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4983 operands[3]);
4984 if (Pmode != SImode)
4985 pat = gen_rtx_SUBREG (SImode, pat, 0);
4986 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4987 DONE;
4988}
4989 [(set_attr "type" "lea")
4990 (set_attr "mode" "SI")])
4991
4992(define_insn_and_split "*lea_general_1_zext"
4993 [(set (match_operand:DI 0 "register_operand" "=r")
4994 (zero_extend:DI
4995 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4996 (match_operand:SI 2 "register_operand" "r"))
4997 (match_operand:SI 3 "immediate_operand" "i"))))]
4998 "TARGET_64BIT"
4999 "#"
5000 "&& reload_completed"
5001 [(set (match_dup 0)
5002 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5003 (match_dup 2))
5004 (match_dup 3)) 0)))]
5005{
5006 operands[1] = gen_lowpart (Pmode, operands[1]);
5007 operands[2] = gen_lowpart (Pmode, operands[2]);
5008 operands[3] = gen_lowpart (Pmode, operands[3]);
5009}
5010 [(set_attr "type" "lea")
5011 (set_attr "mode" "SI")])
5012
5013(define_insn_and_split "*lea_general_2"
5014 [(set (match_operand 0 "register_operand" "=r")
5015 (plus (mult (match_operand 1 "index_register_operand" "l")
5016 (match_operand 2 "const248_operand" "i"))
5017 (match_operand 3 "nonmemory_operand" "ri")))]
5018 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5019 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5020 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5021 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5022 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5023 || GET_MODE (operands[3]) == VOIDmode)"
5024 "#"
5025 "&& reload_completed"
5026 [(const_int 0)]
5027{
5028 rtx pat;
5029 operands[0] = gen_lowpart (SImode, operands[0]);
5030 operands[1] = gen_lowpart (Pmode, operands[1]);
5031 operands[3] = gen_lowpart (Pmode, operands[3]);
5032 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5033 operands[3]);
5034 if (Pmode != SImode)
5035 pat = gen_rtx_SUBREG (SImode, pat, 0);
5036 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5037 DONE;
5038}
5039 [(set_attr "type" "lea")
5040 (set_attr "mode" "SI")])
5041
5042(define_insn_and_split "*lea_general_2_zext"
5043 [(set (match_operand:DI 0 "register_operand" "=r")
5044 (zero_extend:DI
5045 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5046 (match_operand:SI 2 "const248_operand" "n"))
5047 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5048 "TARGET_64BIT"
5049 "#"
5050 "&& reload_completed"
5051 [(set (match_dup 0)
5052 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5053 (match_dup 2))
5054 (match_dup 3)) 0)))]
5055{
5056 operands[1] = gen_lowpart (Pmode, operands[1]);
5057 operands[3] = gen_lowpart (Pmode, operands[3]);
5058}
5059 [(set_attr "type" "lea")
5060 (set_attr "mode" "SI")])
5061
5062(define_insn_and_split "*lea_general_3"
5063 [(set (match_operand 0 "register_operand" "=r")
5064 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5065 (match_operand 2 "const248_operand" "i"))
5066 (match_operand 3 "register_operand" "r"))
5067 (match_operand 4 "immediate_operand" "i")))]
5068 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5069 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5070 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5071 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5072 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5073 "#"
5074 "&& reload_completed"
5075 [(const_int 0)]
5076{
5077 rtx pat;
5078 operands[0] = gen_lowpart (SImode, operands[0]);
5079 operands[1] = gen_lowpart (Pmode, operands[1]);
5080 operands[3] = gen_lowpart (Pmode, operands[3]);
5081 operands[4] = gen_lowpart (Pmode, operands[4]);
5082 pat = gen_rtx_PLUS (Pmode,
5083 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5084 operands[2]),
5085 operands[3]),
5086 operands[4]);
5087 if (Pmode != SImode)
5088 pat = gen_rtx_SUBREG (SImode, pat, 0);
5089 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5090 DONE;
5091}
5092 [(set_attr "type" "lea")
5093 (set_attr "mode" "SI")])
5094
5095(define_insn_and_split "*lea_general_3_zext"
5096 [(set (match_operand:DI 0 "register_operand" "=r")
5097 (zero_extend:DI
5098 (plus:SI (plus:SI (mult:SI
5099 (match_operand:SI 1 "index_register_operand" "l")
5100 (match_operand:SI 2 "const248_operand" "n"))
5101 (match_operand:SI 3 "register_operand" "r"))
5102 (match_operand:SI 4 "immediate_operand" "i"))))]
5103 "TARGET_64BIT"
5104 "#"
5105 "&& reload_completed"
5106 [(set (match_dup 0)
5107 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5108 (match_dup 2))
5109 (match_dup 3))
5110 (match_dup 4)) 0)))]
5111{
5112 operands[1] = gen_lowpart (Pmode, operands[1]);
5113 operands[3] = gen_lowpart (Pmode, operands[3]);
5114 operands[4] = gen_lowpart (Pmode, operands[4]);
5115}
5116 [(set_attr "type" "lea")
5117 (set_attr "mode" "SI")])
5118
5119(define_insn "*adddi_1_rex64"
5120 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5121 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5122 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5123 (clobber (reg:CC FLAGS_REG))]
5124 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5125{
5126 switch (get_attr_type (insn))
5127 {
5128 case TYPE_LEA:
5129 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5130 return "lea{q}\t{%a2, %0|%0, %a2}";
5131
5132 case TYPE_INCDEC:
5133 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5134 if (operands[2] == const1_rtx)
5135 return "inc{q}\t%0";
5136 else
5137 {
5138 gcc_assert (operands[2] == constm1_rtx);
5139 return "dec{q}\t%0";
5140 }
5141
5142 default:
5143 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5144
5145 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5146 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5147 if (GET_CODE (operands[2]) == CONST_INT
5148 /* Avoid overflows. */
5149 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5150 && (INTVAL (operands[2]) == 128
5151 || (INTVAL (operands[2]) < 0
5152 && INTVAL (operands[2]) != -128)))
5153 {
5154 operands[2] = GEN_INT (-INTVAL (operands[2]));
5155 return "sub{q}\t{%2, %0|%0, %2}";
5156 }
5157 return "add{q}\t{%2, %0|%0, %2}";
5158 }
5159}
5160 [(set (attr "type")
5161 (cond [(eq_attr "alternative" "2")
5162 (const_string "lea")
5163 ; Current assemblers are broken and do not allow @GOTOFF in
5164 ; ought but a memory context.
5165 (match_operand:DI 2 "pic_symbolic_operand" "")
5166 (const_string "lea")
5167 (match_operand:DI 2 "incdec_operand" "")
5168 (const_string "incdec")
5169 ]
5170 (const_string "alu")))
5171 (set_attr "mode" "DI")])
5172
5173;; Convert lea to the lea pattern to avoid flags dependency.
5174(define_split
5175 [(set (match_operand:DI 0 "register_operand" "")
5176 (plus:DI (match_operand:DI 1 "register_operand" "")
5177 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5178 (clobber (reg:CC FLAGS_REG))]
5179 "TARGET_64BIT && reload_completed
5180 && true_regnum (operands[0]) != true_regnum (operands[1])"
5181 [(set (match_dup 0)
5182 (plus:DI (match_dup 1)
5183 (match_dup 2)))]
5184 "")
5185
5186(define_insn "*adddi_2_rex64"
5187 [(set (reg FLAGS_REG)
5188 (compare
5189 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5190 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5191 (const_int 0)))
5192 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5193 (plus:DI (match_dup 1) (match_dup 2)))]
5194 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5195 && ix86_binary_operator_ok (PLUS, DImode, operands)
5196 /* Current assemblers are broken and do not allow @GOTOFF in
5197 ought but a memory context. */
5198 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5199{
5200 switch (get_attr_type (insn))
5201 {
5202 case TYPE_INCDEC:
5203 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5204 if (operands[2] == const1_rtx)
5205 return "inc{q}\t%0";
5206 else
5207 {
5208 gcc_assert (operands[2] == constm1_rtx);
5209 return "dec{q}\t%0";
5210 }
5211
5212 default:
5213 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214 /* ???? We ought to handle there the 32bit case too
5215 - do we need new constraint? */
5216 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5217 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5218 if (GET_CODE (operands[2]) == CONST_INT
5219 /* Avoid overflows. */
5220 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5221 && (INTVAL (operands[2]) == 128
5222 || (INTVAL (operands[2]) < 0
5223 && INTVAL (operands[2]) != -128)))
5224 {
5225 operands[2] = GEN_INT (-INTVAL (operands[2]));
5226 return "sub{q}\t{%2, %0|%0, %2}";
5227 }
5228 return "add{q}\t{%2, %0|%0, %2}";
5229 }
5230}
5231 [(set (attr "type")
5232 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5233 (const_string "incdec")
5234 (const_string "alu")))
5235 (set_attr "mode" "DI")])
5236
5237(define_insn "*adddi_3_rex64"
5238 [(set (reg FLAGS_REG)
5239 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5240 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5241 (clobber (match_scratch:DI 0 "=r"))]
5242 "TARGET_64BIT
5243 && ix86_match_ccmode (insn, CCZmode)
5244 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5245 /* Current assemblers are broken and do not allow @GOTOFF in
5246 ought but a memory context. */
5247 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5248{
5249 switch (get_attr_type (insn))
5250 {
5251 case TYPE_INCDEC:
5252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253 if (operands[2] == const1_rtx)
5254 return "inc{q}\t%0";
5255 else
5256 {
5257 gcc_assert (operands[2] == constm1_rtx);
5258 return "dec{q}\t%0";
5259 }
5260
5261 default:
5262 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263 /* ???? We ought to handle there the 32bit case too
5264 - do we need new constraint? */
5265 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5267 if (GET_CODE (operands[2]) == CONST_INT
5268 /* Avoid overflows. */
5269 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270 && (INTVAL (operands[2]) == 128
5271 || (INTVAL (operands[2]) < 0
5272 && INTVAL (operands[2]) != -128)))
5273 {
5274 operands[2] = GEN_INT (-INTVAL (operands[2]));
5275 return "sub{q}\t{%2, %0|%0, %2}";
5276 }
5277 return "add{q}\t{%2, %0|%0, %2}";
5278 }
5279}
5280 [(set (attr "type")
5281 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282 (const_string "incdec")
5283 (const_string "alu")))
5284 (set_attr "mode" "DI")])
5285
5286; For comparisons against 1, -1 and 128, we may generate better code
5287; by converting cmp to add, inc or dec as done by peephole2. This pattern
5288; is matched then. We can't accept general immediate, because for
5289; case of overflows, the result is messed up.
5290; This pattern also don't hold of 0x8000000000000000, since the value overflows
5291; when negated.
5292; Also carry flag is reversed compared to cmp, so this conversion is valid
5293; only for comparisons not depending on it.
5294(define_insn "*adddi_4_rex64"
5295 [(set (reg FLAGS_REG)
5296 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5297 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5298 (clobber (match_scratch:DI 0 "=rm"))]
5299 "TARGET_64BIT
5300 && ix86_match_ccmode (insn, CCGCmode)"
5301{
5302 switch (get_attr_type (insn))
5303 {
5304 case TYPE_INCDEC:
5305 if (operands[2] == constm1_rtx)
5306 return "inc{q}\t%0";
5307 else
5308 {
5309 gcc_assert (operands[2] == const1_rtx);
5310 return "dec{q}\t%0";
5311 }
5312
5313 default:
5314 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5315 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5316 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5317 if ((INTVAL (operands[2]) == -128
5318 || (INTVAL (operands[2]) > 0
5319 && INTVAL (operands[2]) != 128))
5320 /* Avoid overflows. */
5321 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5322 return "sub{q}\t{%2, %0|%0, %2}";
5323 operands[2] = GEN_INT (-INTVAL (operands[2]));
5324 return "add{q}\t{%2, %0|%0, %2}";
5325 }
5326}
5327 [(set (attr "type")
5328 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5329 (const_string "incdec")
5330 (const_string "alu")))
5331 (set_attr "mode" "DI")])
5332
5333(define_insn "*adddi_5_rex64"
5334 [(set (reg FLAGS_REG)
5335 (compare
5336 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5337 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5338 (const_int 0)))
5339 (clobber (match_scratch:DI 0 "=r"))]
5340 "TARGET_64BIT
5341 && ix86_match_ccmode (insn, CCGOCmode)
5342 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5343 /* Current assemblers are broken and do not allow @GOTOFF in
5344 ought but a memory context. */
5345 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5346{
5347 switch (get_attr_type (insn))
5348 {
5349 case TYPE_INCDEC:
5350 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5351 if (operands[2] == const1_rtx)
5352 return "inc{q}\t%0";
5353 else
5354 {
5355 gcc_assert (operands[2] == constm1_rtx);
5356 return "dec{q}\t%0";
5357 }
5358
5359 default:
5360 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5361 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5363 if (GET_CODE (operands[2]) == CONST_INT
5364 /* Avoid overflows. */
5365 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366 && (INTVAL (operands[2]) == 128
5367 || (INTVAL (operands[2]) < 0
5368 && INTVAL (operands[2]) != -128)))
5369 {
5370 operands[2] = GEN_INT (-INTVAL (operands[2]));
5371 return "sub{q}\t{%2, %0|%0, %2}";
5372 }
5373 return "add{q}\t{%2, %0|%0, %2}";
5374 }
5375}
5376 [(set (attr "type")
5377 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378 (const_string "incdec")
5379 (const_string "alu")))
5380 (set_attr "mode" "DI")])
5381
5382
5383(define_insn "*addsi_1"
5384 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5385 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5386 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5387 (clobber (reg:CC FLAGS_REG))]
5388 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5389{
5390 switch (get_attr_type (insn))
5391 {
5392 case TYPE_LEA:
5393 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5394 return "lea{l}\t{%a2, %0|%0, %a2}";
5395
5396 case TYPE_INCDEC:
5397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398 if (operands[2] == const1_rtx)
5399 return "inc{l}\t%0";
5400 else
5401 {
5402 gcc_assert (operands[2] == constm1_rtx);
5403 return "dec{l}\t%0";
5404 }
5405
5406 default:
5407 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5408
5409 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5410 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5411 if (GET_CODE (operands[2]) == CONST_INT
5412 && (INTVAL (operands[2]) == 128
5413 || (INTVAL (operands[2]) < 0
5414 && INTVAL (operands[2]) != -128)))
5415 {
5416 operands[2] = GEN_INT (-INTVAL (operands[2]));
5417 return "sub{l}\t{%2, %0|%0, %2}";
5418 }
5419 return "add{l}\t{%2, %0|%0, %2}";
5420 }
5421}
5422 [(set (attr "type")
5423 (cond [(eq_attr "alternative" "2")
5424 (const_string "lea")
5425 ; Current assemblers are broken and do not allow @GOTOFF in
5426 ; ought but a memory context.
5427 (match_operand:SI 2 "pic_symbolic_operand" "")
5428 (const_string "lea")
5429 (match_operand:SI 2 "incdec_operand" "")
5430 (const_string "incdec")
5431 ]
5432 (const_string "alu")))
5433 (set_attr "mode" "SI")])
5434
5435;; Convert lea to the lea pattern to avoid flags dependency.
5436(define_split
5437 [(set (match_operand 0 "register_operand" "")
5438 (plus (match_operand 1 "register_operand" "")
5439 (match_operand 2 "nonmemory_operand" "")))
5440 (clobber (reg:CC FLAGS_REG))]
5441 "reload_completed
5442 && true_regnum (operands[0]) != true_regnum (operands[1])"
5443 [(const_int 0)]
5444{
5445 rtx pat;
5446 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5447 may confuse gen_lowpart. */
5448 if (GET_MODE (operands[0]) != Pmode)
5449 {
5450 operands[1] = gen_lowpart (Pmode, operands[1]);
5451 operands[2] = gen_lowpart (Pmode, operands[2]);
5452 }
5453 operands[0] = gen_lowpart (SImode, operands[0]);
5454 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5455 if (Pmode != SImode)
5456 pat = gen_rtx_SUBREG (SImode, pat, 0);
5457 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5458 DONE;
5459})
5460
5461;; It may seem that nonimmediate operand is proper one for operand 1.
5462;; The addsi_1 pattern allows nonimmediate operand at that place and
5463;; we take care in ix86_binary_operator_ok to not allow two memory
5464;; operands so proper swapping will be done in reload. This allow
5465;; patterns constructed from addsi_1 to match.
5466(define_insn "addsi_1_zext"
5467 [(set (match_operand:DI 0 "register_operand" "=r,r")
5468 (zero_extend:DI
5469 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5470 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5473{
5474 switch (get_attr_type (insn))
5475 {
5476 case TYPE_LEA:
5477 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5478 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5479
5480 case TYPE_INCDEC:
5481 if (operands[2] == const1_rtx)
5482 return "inc{l}\t%k0";
5483 else
5484 {
5485 gcc_assert (operands[2] == constm1_rtx);
5486 return "dec{l}\t%k0";
5487 }
5488
5489 default:
5490 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5491 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5492 if (GET_CODE (operands[2]) == CONST_INT
5493 && (INTVAL (operands[2]) == 128
5494 || (INTVAL (operands[2]) < 0
5495 && INTVAL (operands[2]) != -128)))
5496 {
5497 operands[2] = GEN_INT (-INTVAL (operands[2]));
5498 return "sub{l}\t{%2, %k0|%k0, %2}";
5499 }
5500 return "add{l}\t{%2, %k0|%k0, %2}";
5501 }
5502}
5503 [(set (attr "type")
5504 (cond [(eq_attr "alternative" "1")
5505 (const_string "lea")
5506 ; Current assemblers are broken and do not allow @GOTOFF in
5507 ; ought but a memory context.
5508 (match_operand:SI 2 "pic_symbolic_operand" "")
5509 (const_string "lea")
5510 (match_operand:SI 2 "incdec_operand" "")
5511 (const_string "incdec")
5512 ]
5513 (const_string "alu")))
5514 (set_attr "mode" "SI")])
5515
5516;; Convert lea to the lea pattern to avoid flags dependency.
5517(define_split
5518 [(set (match_operand:DI 0 "register_operand" "")
5519 (zero_extend:DI
5520 (plus:SI (match_operand:SI 1 "register_operand" "")
5521 (match_operand:SI 2 "nonmemory_operand" ""))))
5522 (clobber (reg:CC FLAGS_REG))]
5523 "TARGET_64BIT && reload_completed
5524 && true_regnum (operands[0]) != true_regnum (operands[1])"
5525 [(set (match_dup 0)
5526 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5527{
5528 operands[1] = gen_lowpart (Pmode, operands[1]);
5529 operands[2] = gen_lowpart (Pmode, operands[2]);
5530})
5531
5532(define_insn "*addsi_2"
5533 [(set (reg FLAGS_REG)
5534 (compare
5535 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5536 (match_operand:SI 2 "general_operand" "rmni,rni"))
5537 (const_int 0)))
5538 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5539 (plus:SI (match_dup 1) (match_dup 2)))]
5540 "ix86_match_ccmode (insn, CCGOCmode)
5541 && ix86_binary_operator_ok (PLUS, SImode, operands)
5542 /* Current assemblers are broken and do not allow @GOTOFF in
5543 ought but a memory context. */
5544 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5545{
5546 switch (get_attr_type (insn))
5547 {
5548 case TYPE_INCDEC:
5549 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550 if (operands[2] == const1_rtx)
5551 return "inc{l}\t%0";
5552 else
5553 {
5554 gcc_assert (operands[2] == constm1_rtx);
5555 return "dec{l}\t%0";
5556 }
5557
5558 default:
5559 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5561 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5562 if (GET_CODE (operands[2]) == CONST_INT
5563 && (INTVAL (operands[2]) == 128
5564 || (INTVAL (operands[2]) < 0
5565 && INTVAL (operands[2]) != -128)))
5566 {
5567 operands[2] = GEN_INT (-INTVAL (operands[2]));
5568 return "sub{l}\t{%2, %0|%0, %2}";
5569 }
5570 return "add{l}\t{%2, %0|%0, %2}";
5571 }
5572}
5573 [(set (attr "type")
5574 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5575 (const_string "incdec")
5576 (const_string "alu")))
5577 (set_attr "mode" "SI")])
5578
5579;; See comment for addsi_1_zext why we do use nonimmediate_operand
5580(define_insn "*addsi_2_zext"
5581 [(set (reg FLAGS_REG)
5582 (compare
5583 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5584 (match_operand:SI 2 "general_operand" "rmni"))
5585 (const_int 0)))
5586 (set (match_operand:DI 0 "register_operand" "=r")
5587 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5588 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5589 && ix86_binary_operator_ok (PLUS, SImode, operands)
5590 /* Current assemblers are broken and do not allow @GOTOFF in
5591 ought but a memory context. */
5592 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5593{
5594 switch (get_attr_type (insn))
5595 {
5596 case TYPE_INCDEC:
5597 if (operands[2] == const1_rtx)
5598 return "inc{l}\t%k0";
5599 else
5600 {
5601 gcc_assert (operands[2] == constm1_rtx);
5602 return "dec{l}\t%k0";
5603 }
5604
5605 default:
5606 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5607 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5608 if (GET_CODE (operands[2]) == CONST_INT
5609 && (INTVAL (operands[2]) == 128
5610 || (INTVAL (operands[2]) < 0
5611 && INTVAL (operands[2]) != -128)))
5612 {
5613 operands[2] = GEN_INT (-INTVAL (operands[2]));
5614 return "sub{l}\t{%2, %k0|%k0, %2}";
5615 }
5616 return "add{l}\t{%2, %k0|%k0, %2}";
5617 }
5618}
5619 [(set (attr "type")
5620 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5621 (const_string "incdec")
5622 (const_string "alu")))
5623 (set_attr "mode" "SI")])
5624
5625(define_insn "*addsi_3"
5626 [(set (reg FLAGS_REG)
5627 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5628 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5629 (clobber (match_scratch:SI 0 "=r"))]
5630 "ix86_match_ccmode (insn, CCZmode)
5631 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5632 /* Current assemblers are broken and do not allow @GOTOFF in
5633 ought but a memory context. */
5634 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5635{
5636 switch (get_attr_type (insn))
5637 {
5638 case TYPE_INCDEC:
5639 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5640 if (operands[2] == const1_rtx)
5641 return "inc{l}\t%0";
5642 else
5643 {
5644 gcc_assert (operands[2] == constm1_rtx);
5645 return "dec{l}\t%0";
5646 }
5647
5648 default:
5649 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5650 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5651 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5652 if (GET_CODE (operands[2]) == CONST_INT
5653 && (INTVAL (operands[2]) == 128
5654 || (INTVAL (operands[2]) < 0
5655 && INTVAL (operands[2]) != -128)))
5656 {
5657 operands[2] = GEN_INT (-INTVAL (operands[2]));
5658 return "sub{l}\t{%2, %0|%0, %2}";
5659 }
5660 return "add{l}\t{%2, %0|%0, %2}";
5661 }
5662}
5663 [(set (attr "type")
5664 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5665 (const_string "incdec")
5666 (const_string "alu")))
5667 (set_attr "mode" "SI")])
5668
5669;; See comment for addsi_1_zext why we do use nonimmediate_operand
5670(define_insn "*addsi_3_zext"
5671 [(set (reg FLAGS_REG)
5672 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5673 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5674 (set (match_operand:DI 0 "register_operand" "=r")
5675 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5676 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5677 && ix86_binary_operator_ok (PLUS, SImode, operands)
5678 /* Current assemblers are broken and do not allow @GOTOFF in
5679 ought but a memory context. */
5680 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5681{
5682 switch (get_attr_type (insn))
5683 {
5684 case TYPE_INCDEC:
5685 if (operands[2] == const1_rtx)
5686 return "inc{l}\t%k0";
5687 else
5688 {
5689 gcc_assert (operands[2] == constm1_rtx);
5690 return "dec{l}\t%k0";
5691 }
5692
5693 default:
5694 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5695 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5696 if (GET_CODE (operands[2]) == CONST_INT
5697 && (INTVAL (operands[2]) == 128
5698 || (INTVAL (operands[2]) < 0
5699 && INTVAL (operands[2]) != -128)))
5700 {
5701 operands[2] = GEN_INT (-INTVAL (operands[2]));
5702 return "sub{l}\t{%2, %k0|%k0, %2}";
5703 }
5704 return "add{l}\t{%2, %k0|%k0, %2}";
5705 }
5706}
5707 [(set (attr "type")
5708 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5709 (const_string "incdec")
5710 (const_string "alu")))
5711 (set_attr "mode" "SI")])
5712
5713; For comparisons against 1, -1 and 128, we may generate better code
5714; by converting cmp to add, inc or dec as done by peephole2. This pattern
5715; is matched then. We can't accept general immediate, because for
5716; case of overflows, the result is messed up.
5717; This pattern also don't hold of 0x80000000, since the value overflows
5718; when negated.
5719; Also carry flag is reversed compared to cmp, so this conversion is valid
5720; only for comparisons not depending on it.
5721(define_insn "*addsi_4"
5722 [(set (reg FLAGS_REG)
5723 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5724 (match_operand:SI 2 "const_int_operand" "n")))
5725 (clobber (match_scratch:SI 0 "=rm"))]
5726 "ix86_match_ccmode (insn, CCGCmode)
5727 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5728{
5729 switch (get_attr_type (insn))
5730 {
5731 case TYPE_INCDEC:
5732 if (operands[2] == constm1_rtx)
5733 return "inc{l}\t%0";
5734 else
5735 {
5736 gcc_assert (operands[2] == const1_rtx);
5737 return "dec{l}\t%0";
5738 }
5739
5740 default:
5741 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5742 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5744 if ((INTVAL (operands[2]) == -128
5745 || (INTVAL (operands[2]) > 0
5746 && INTVAL (operands[2]) != 128)))
5747 return "sub{l}\t{%2, %0|%0, %2}";
5748 operands[2] = GEN_INT (-INTVAL (operands[2]));
5749 return "add{l}\t{%2, %0|%0, %2}";
5750 }
5751}
5752 [(set (attr "type")
5753 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5754 (const_string "incdec")
5755 (const_string "alu")))
5756 (set_attr "mode" "SI")])
5757
5758(define_insn "*addsi_5"
5759 [(set (reg FLAGS_REG)
5760 (compare
5761 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5762 (match_operand:SI 2 "general_operand" "rmni"))
5763 (const_int 0)))
5764 (clobber (match_scratch:SI 0 "=r"))]
5765 "ix86_match_ccmode (insn, CCGOCmode)
5766 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5767 /* Current assemblers are broken and do not allow @GOTOFF in
5768 ought but a memory context. */
5769 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5770{
5771 switch (get_attr_type (insn))
5772 {
5773 case TYPE_INCDEC:
5774 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5775 if (operands[2] == const1_rtx)
5776 return "inc{l}\t%0";
5777 else
5778 {
5779 gcc_assert (operands[2] == constm1_rtx);
5780 return "dec{l}\t%0";
5781 }
5782
5783 default:
5784 gcc_assert (rtx_equal_p (operands[0], operands[1]));
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(define_expand "addhi3"
5805 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5806 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5807 (match_operand:HI 2 "general_operand" "")))
5808 (clobber (reg:CC FLAGS_REG))])]
5809 "TARGET_HIMODE_MATH"
5810 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5811
5812;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5813;; type optimizations enabled by define-splits. This is not important
5814;; for PII, and in fact harmful because of partial register stalls.
5815
5816(define_insn "*addhi_1_lea"
5817 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5818 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5819 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5820 (clobber (reg:CC FLAGS_REG))]
5821 "!TARGET_PARTIAL_REG_STALL
5822 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5823{
5824 switch (get_attr_type (insn))
5825 {
5826 case TYPE_LEA:
5827 return "#";
5828 case TYPE_INCDEC:
5829 if (operands[2] == const1_rtx)
5830 return "inc{w}\t%0";
5831 else
5832 {
5833 gcc_assert (operands[2] == constm1_rtx);
5834 return "dec{w}\t%0";
5835 }
5836
5837 default:
5838 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5839 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5840 if (GET_CODE (operands[2]) == CONST_INT
5841 && (INTVAL (operands[2]) == 128
5842 || (INTVAL (operands[2]) < 0
5843 && INTVAL (operands[2]) != -128)))
5844 {
5845 operands[2] = GEN_INT (-INTVAL (operands[2]));
5846 return "sub{w}\t{%2, %0|%0, %2}";
5847 }
5848 return "add{w}\t{%2, %0|%0, %2}";
5849 }
5850}
5851 [(set (attr "type")
5852 (if_then_else (eq_attr "alternative" "2")
5853 (const_string "lea")
5854 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5855 (const_string "incdec")
5856 (const_string "alu"))))
5857 (set_attr "mode" "HI,HI,SI")])
5858
5859(define_insn "*addhi_1"
5860 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5861 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5862 (match_operand:HI 2 "general_operand" "ri,rm")))
5863 (clobber (reg:CC FLAGS_REG))]
5864 "TARGET_PARTIAL_REG_STALL
5865 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5866{
5867 switch (get_attr_type (insn))
5868 {
5869 case TYPE_INCDEC:
5870 if (operands[2] == const1_rtx)
5871 return "inc{w}\t%0";
5872 else
5873 {
5874 gcc_assert (operands[2] == constm1_rtx);
5875 return "dec{w}\t%0";
5876 }
5877
5878 default:
5879 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5881 if (GET_CODE (operands[2]) == CONST_INT
5882 && (INTVAL (operands[2]) == 128
5883 || (INTVAL (operands[2]) < 0
5884 && INTVAL (operands[2]) != -128)))
5885 {
5886 operands[2] = GEN_INT (-INTVAL (operands[2]));
5887 return "sub{w}\t{%2, %0|%0, %2}";
5888 }
5889 return "add{w}\t{%2, %0|%0, %2}";
5890 }
5891}
5892 [(set (attr "type")
5893 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set_attr "mode" "HI")])
5897
5898(define_insn "*addhi_2"
5899 [(set (reg FLAGS_REG)
5900 (compare
5901 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5902 (match_operand:HI 2 "general_operand" "rmni,rni"))
5903 (const_int 0)))
5904 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5905 (plus:HI (match_dup 1) (match_dup 2)))]
5906 "ix86_match_ccmode (insn, CCGOCmode)
5907 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5908{
5909 switch (get_attr_type (insn))
5910 {
5911 case TYPE_INCDEC:
5912 if (operands[2] == const1_rtx)
5913 return "inc{w}\t%0";
5914 else
5915 {
5916 gcc_assert (operands[2] == constm1_rtx);
5917 return "dec{w}\t%0";
5918 }
5919
5920 default:
5921 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5923 if (GET_CODE (operands[2]) == CONST_INT
5924 && (INTVAL (operands[2]) == 128
5925 || (INTVAL (operands[2]) < 0
5926 && INTVAL (operands[2]) != -128)))
5927 {
5928 operands[2] = GEN_INT (-INTVAL (operands[2]));
5929 return "sub{w}\t{%2, %0|%0, %2}";
5930 }
5931 return "add{w}\t{%2, %0|%0, %2}";
5932 }
5933}
5934 [(set (attr "type")
5935 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936 (const_string "incdec")
5937 (const_string "alu")))
5938 (set_attr "mode" "HI")])
5939
5940(define_insn "*addhi_3"
5941 [(set (reg FLAGS_REG)
5942 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5943 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5944 (clobber (match_scratch:HI 0 "=r"))]
5945 "ix86_match_ccmode (insn, CCZmode)
5946 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5947{
5948 switch (get_attr_type (insn))
5949 {
5950 case TYPE_INCDEC:
5951 if (operands[2] == const1_rtx)
5952 return "inc{w}\t%0";
5953 else
5954 {
5955 gcc_assert (operands[2] == constm1_rtx);
5956 return "dec{w}\t%0";
5957 }
5958
5959 default:
5960 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5962 if (GET_CODE (operands[2]) == CONST_INT
5963 && (INTVAL (operands[2]) == 128
5964 || (INTVAL (operands[2]) < 0
5965 && INTVAL (operands[2]) != -128)))
5966 {
5967 operands[2] = GEN_INT (-INTVAL (operands[2]));
5968 return "sub{w}\t{%2, %0|%0, %2}";
5969 }
5970 return "add{w}\t{%2, %0|%0, %2}";
5971 }
5972}
5973 [(set (attr "type")
5974 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975 (const_string "incdec")
5976 (const_string "alu")))
5977 (set_attr "mode" "HI")])
5978
5979; See comments above addsi_4 for details.
5980(define_insn "*addhi_4"
5981 [(set (reg FLAGS_REG)
5982 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5983 (match_operand:HI 2 "const_int_operand" "n")))
5984 (clobber (match_scratch:HI 0 "=rm"))]
5985 "ix86_match_ccmode (insn, CCGCmode)
5986 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5987{
5988 switch (get_attr_type (insn))
5989 {
5990 case TYPE_INCDEC:
5991 if (operands[2] == constm1_rtx)
5992 return "inc{w}\t%0";
5993 else
5994 {
5995 gcc_assert (operands[2] == const1_rtx);
5996 return "dec{w}\t%0";
5997 }
5998
5999 default:
6000 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6003 if ((INTVAL (operands[2]) == -128
6004 || (INTVAL (operands[2]) > 0
6005 && INTVAL (operands[2]) != 128)))
6006 return "sub{w}\t{%2, %0|%0, %2}";
6007 operands[2] = GEN_INT (-INTVAL (operands[2]));
6008 return "add{w}\t{%2, %0|%0, %2}";
6009 }
6010}
6011 [(set (attr "type")
6012 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6013 (const_string "incdec")
6014 (const_string "alu")))
6015 (set_attr "mode" "SI")])
6016
6017
6018(define_insn "*addhi_5"
6019 [(set (reg FLAGS_REG)
6020 (compare
6021 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6022 (match_operand:HI 2 "general_operand" "rmni"))
6023 (const_int 0)))
6024 (clobber (match_scratch:HI 0 "=r"))]
6025 "ix86_match_ccmode (insn, CCGOCmode)
6026 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6027{
6028 switch (get_attr_type (insn))
6029 {
6030 case TYPE_INCDEC:
6031 if (operands[2] == const1_rtx)
6032 return "inc{w}\t%0";
6033 else
6034 {
6035 gcc_assert (operands[2] == constm1_rtx);
6036 return "dec{w}\t%0";
6037 }
6038
6039 default:
6040 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6041 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6042 if (GET_CODE (operands[2]) == CONST_INT
6043 && (INTVAL (operands[2]) == 128
6044 || (INTVAL (operands[2]) < 0
6045 && INTVAL (operands[2]) != -128)))
6046 {
6047 operands[2] = GEN_INT (-INTVAL (operands[2]));
6048 return "sub{w}\t{%2, %0|%0, %2}";
6049 }
6050 return "add{w}\t{%2, %0|%0, %2}";
6051 }
6052}
6053 [(set (attr "type")
6054 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6055 (const_string "incdec")
6056 (const_string "alu")))
6057 (set_attr "mode" "HI")])
6058
6059(define_expand "addqi3"
6060 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6061 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6062 (match_operand:QI 2 "general_operand" "")))
6063 (clobber (reg:CC FLAGS_REG))])]
6064 "TARGET_QIMODE_MATH"
6065 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6066
6067;; %%% Potential partial reg stall on alternative 2. What to do?
6068(define_insn "*addqi_1_lea"
6069 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6070 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6071 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6072 (clobber (reg:CC FLAGS_REG))]
6073 "!TARGET_PARTIAL_REG_STALL
6074 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6075{
6076 int widen = (which_alternative == 2);
6077 switch (get_attr_type (insn))
6078 {
6079 case TYPE_LEA:
6080 return "#";
6081 case TYPE_INCDEC:
6082 if (operands[2] == const1_rtx)
6083 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6084 else
6085 {
6086 gcc_assert (operands[2] == constm1_rtx);
6087 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6088 }
6089
6090 default:
6091 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6092 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6093 if (GET_CODE (operands[2]) == CONST_INT
6094 && (INTVAL (operands[2]) == 128
6095 || (INTVAL (operands[2]) < 0
6096 && INTVAL (operands[2]) != -128)))
6097 {
6098 operands[2] = GEN_INT (-INTVAL (operands[2]));
6099 if (widen)
6100 return "sub{l}\t{%2, %k0|%k0, %2}";
6101 else
6102 return "sub{b}\t{%2, %0|%0, %2}";
6103 }
6104 if (widen)
6105 return "add{l}\t{%k2, %k0|%k0, %k2}";
6106 else
6107 return "add{b}\t{%2, %0|%0, %2}";
6108 }
6109}
6110 [(set (attr "type")
6111 (if_then_else (eq_attr "alternative" "3")
6112 (const_string "lea")
6113 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6114 (const_string "incdec")
6115 (const_string "alu"))))
6116 (set_attr "mode" "QI,QI,SI,SI")])
6117
6118(define_insn "*addqi_1"
6119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6120 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6121 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6122 (clobber (reg:CC FLAGS_REG))]
6123 "TARGET_PARTIAL_REG_STALL
6124 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6125{
6126 int widen = (which_alternative == 2);
6127 switch (get_attr_type (insn))
6128 {
6129 case TYPE_INCDEC:
6130 if (operands[2] == const1_rtx)
6131 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6132 else
6133 {
6134 gcc_assert (operands[2] == constm1_rtx);
6135 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6136 }
6137
6138 default:
6139 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6140 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6141 if (GET_CODE (operands[2]) == CONST_INT
6142 && (INTVAL (operands[2]) == 128
6143 || (INTVAL (operands[2]) < 0
6144 && INTVAL (operands[2]) != -128)))
6145 {
6146 operands[2] = GEN_INT (-INTVAL (operands[2]));
6147 if (widen)
6148 return "sub{l}\t{%2, %k0|%k0, %2}";
6149 else
6150 return "sub{b}\t{%2, %0|%0, %2}";
6151 }
6152 if (widen)
6153 return "add{l}\t{%k2, %k0|%k0, %k2}";
6154 else
6155 return "add{b}\t{%2, %0|%0, %2}";
6156 }
6157}
6158 [(set (attr "type")
6159 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6160 (const_string "incdec")
6161 (const_string "alu")))
6162 (set_attr "mode" "QI,QI,SI")])
6163
6164(define_insn "*addqi_1_slp"
6165 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6166 (plus:QI (match_dup 0)
6167 (match_operand:QI 1 "general_operand" "qn,qnm")))
6168 (clobber (reg:CC FLAGS_REG))]
6169 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6170 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6171{
6172 switch (get_attr_type (insn))
6173 {
6174 case TYPE_INCDEC:
6175 if (operands[1] == const1_rtx)
6176 return "inc{b}\t%0";
6177 else
6178 {
6179 gcc_assert (operands[1] == constm1_rtx);
6180 return "dec{b}\t%0";
6181 }
6182
6183 default:
6184 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6185 if (GET_CODE (operands[1]) == CONST_INT
6186 && INTVAL (operands[1]) < 0)
6187 {
6188 operands[1] = GEN_INT (-INTVAL (operands[1]));
6189 return "sub{b}\t{%1, %0|%0, %1}";
6190 }
6191 return "add{b}\t{%1, %0|%0, %1}";
6192 }
6193}
6194 [(set (attr "type")
6195 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6196 (const_string "incdec")
6197 (const_string "alu1")))
6198 (set (attr "memory")
6199 (if_then_else (match_operand 1 "memory_operand" "")
6200 (const_string "load")
6201 (const_string "none")))
6202 (set_attr "mode" "QI")])
6203
6204(define_insn "*addqi_2"
6205 [(set (reg FLAGS_REG)
6206 (compare
6207 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6208 (match_operand:QI 2 "general_operand" "qmni,qni"))
6209 (const_int 0)))
6210 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6211 (plus:QI (match_dup 1) (match_dup 2)))]
6212 "ix86_match_ccmode (insn, CCGOCmode)
6213 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6214{
6215 switch (get_attr_type (insn))
6216 {
6217 case TYPE_INCDEC:
6218 if (operands[2] == const1_rtx)
6219 return "inc{b}\t%0";
6220 else
6221 {
6222 gcc_assert (operands[2] == constm1_rtx
6223 || (GET_CODE (operands[2]) == CONST_INT
6224 && INTVAL (operands[2]) == 255));
6225 return "dec{b}\t%0";
6226 }
6227
6228 default:
6229 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6230 if (GET_CODE (operands[2]) == CONST_INT
6231 && INTVAL (operands[2]) < 0)
6232 {
6233 operands[2] = GEN_INT (-INTVAL (operands[2]));
6234 return "sub{b}\t{%2, %0|%0, %2}";
6235 }
6236 return "add{b}\t{%2, %0|%0, %2}";
6237 }
6238}
6239 [(set (attr "type")
6240 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6241 (const_string "incdec")
6242 (const_string "alu")))
6243 (set_attr "mode" "QI")])
6244
6245(define_insn "*addqi_3"
6246 [(set (reg FLAGS_REG)
6247 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6248 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6249 (clobber (match_scratch:QI 0 "=q"))]
6250 "ix86_match_ccmode (insn, CCZmode)
6251 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6252{
6253 switch (get_attr_type (insn))
6254 {
6255 case TYPE_INCDEC:
6256 if (operands[2] == const1_rtx)
6257 return "inc{b}\t%0";
6258 else
6259 {
6260 gcc_assert (operands[2] == constm1_rtx
6261 || (GET_CODE (operands[2]) == CONST_INT
6262 && INTVAL (operands[2]) == 255));
6263 return "dec{b}\t%0";
6264 }
6265
6266 default:
6267 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6268 if (GET_CODE (operands[2]) == CONST_INT
6269 && INTVAL (operands[2]) < 0)
6270 {
6271 operands[2] = GEN_INT (-INTVAL (operands[2]));
6272 return "sub{b}\t{%2, %0|%0, %2}";
6273 }
6274 return "add{b}\t{%2, %0|%0, %2}";
6275 }
6276}
6277 [(set (attr "type")
6278 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6279 (const_string "incdec")
6280 (const_string "alu")))
6281 (set_attr "mode" "QI")])
6282
6283; See comments above addsi_4 for details.
6284(define_insn "*addqi_4"
6285 [(set (reg FLAGS_REG)
6286 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6287 (match_operand:QI 2 "const_int_operand" "n")))
6288 (clobber (match_scratch:QI 0 "=qm"))]
6289 "ix86_match_ccmode (insn, CCGCmode)
6290 && (INTVAL (operands[2]) & 0xff) != 0x80"
6291{
6292 switch (get_attr_type (insn))
6293 {
6294 case TYPE_INCDEC:
6295 if (operands[2] == constm1_rtx
6296 || (GET_CODE (operands[2]) == CONST_INT
6297 && INTVAL (operands[2]) == 255))
6298 return "inc{b}\t%0";
6299 else
6300 {
6301 gcc_assert (operands[2] == const1_rtx);
6302 return "dec{b}\t%0";
6303 }
6304
6305 default:
6306 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6307 if (INTVAL (operands[2]) < 0)
6308 {
6309 operands[2] = GEN_INT (-INTVAL (operands[2]));
6310 return "add{b}\t{%2, %0|%0, %2}";
6311 }
6312 return "sub{b}\t{%2, %0|%0, %2}";
6313 }
6314}
6315 [(set (attr "type")
6316 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6317 (const_string "incdec")
6318 (const_string "alu")))
6319 (set_attr "mode" "QI")])
6320
6321
6322(define_insn "*addqi_5"
6323 [(set (reg FLAGS_REG)
6324 (compare
6325 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6326 (match_operand:QI 2 "general_operand" "qmni"))
6327 (const_int 0)))
6328 (clobber (match_scratch:QI 0 "=q"))]
6329 "ix86_match_ccmode (insn, CCGOCmode)
6330 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6331{
6332 switch (get_attr_type (insn))
6333 {
6334 case TYPE_INCDEC:
6335 if (operands[2] == const1_rtx)
6336 return "inc{b}\t%0";
6337 else
6338 {
6339 gcc_assert (operands[2] == constm1_rtx
6340 || (GET_CODE (operands[2]) == CONST_INT
6341 && INTVAL (operands[2]) == 255));
6342 return "dec{b}\t%0";
6343 }
6344
6345 default:
6346 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6347 if (GET_CODE (operands[2]) == CONST_INT
6348 && INTVAL (operands[2]) < 0)
6349 {
6350 operands[2] = GEN_INT (-INTVAL (operands[2]));
6351 return "sub{b}\t{%2, %0|%0, %2}";
6352 }
6353 return "add{b}\t{%2, %0|%0, %2}";
6354 }
6355}
6356 [(set (attr "type")
6357 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6358 (const_string "incdec")
6359 (const_string "alu")))
6360 (set_attr "mode" "QI")])
6361
6362
6363(define_insn "addqi_ext_1"
6364 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6365 (const_int 8)
6366 (const_int 8))
6367 (plus:SI
6368 (zero_extract:SI
6369 (match_operand 1 "ext_register_operand" "0")
6370 (const_int 8)
6371 (const_int 8))
6372 (match_operand:QI 2 "general_operand" "Qmn")))
6373 (clobber (reg:CC FLAGS_REG))]
6374 "!TARGET_64BIT"
6375{
6376 switch (get_attr_type (insn))
6377 {
6378 case TYPE_INCDEC:
6379 if (operands[2] == const1_rtx)
6380 return "inc{b}\t%h0";
6381 else
6382 {
6383 gcc_assert (operands[2] == constm1_rtx
6384 || (GET_CODE (operands[2]) == CONST_INT
6385 && INTVAL (operands[2]) == 255));
6386 return "dec{b}\t%h0";
6387 }
6388
6389 default:
6390 return "add{b}\t{%2, %h0|%h0, %2}";
6391 }
6392}
6393 [(set (attr "type")
6394 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6395 (const_string "incdec")
6396 (const_string "alu")))
6397 (set_attr "mode" "QI")])
6398
6399(define_insn "*addqi_ext_1_rex64"
6400 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6401 (const_int 8)
6402 (const_int 8))
6403 (plus:SI
6404 (zero_extract:SI
6405 (match_operand 1 "ext_register_operand" "0")
6406 (const_int 8)
6407 (const_int 8))
6408 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6409 (clobber (reg:CC FLAGS_REG))]
6410 "TARGET_64BIT"
6411{
6412 switch (get_attr_type (insn))
6413 {
6414 case TYPE_INCDEC:
6415 if (operands[2] == const1_rtx)
6416 return "inc{b}\t%h0";
6417 else
6418 {
6419 gcc_assert (operands[2] == constm1_rtx
6420 || (GET_CODE (operands[2]) == CONST_INT
6421 && INTVAL (operands[2]) == 255));
6422 return "dec{b}\t%h0";
6423 }
6424
6425 default:
6426 return "add{b}\t{%2, %h0|%h0, %2}";
6427 }
6428}
6429 [(set (attr "type")
6430 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6431 (const_string "incdec")
6432 (const_string "alu")))
6433 (set_attr "mode" "QI")])
6434
6435(define_insn "*addqi_ext_2"
6436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6437 (const_int 8)
6438 (const_int 8))
6439 (plus:SI
6440 (zero_extract:SI
6441 (match_operand 1 "ext_register_operand" "%0")
6442 (const_int 8)
6443 (const_int 8))
6444 (zero_extract:SI
6445 (match_operand 2 "ext_register_operand" "Q")
6446 (const_int 8)
6447 (const_int 8))))
6448 (clobber (reg:CC FLAGS_REG))]
6449 ""
6450 "add{b}\t{%h2, %h0|%h0, %h2}"
6451 [(set_attr "type" "alu")
6452 (set_attr "mode" "QI")])
6453
6454;; The patterns that match these are at the end of this file.
6455
6456(define_expand "addxf3"
6457 [(set (match_operand:XF 0 "register_operand" "")
6458 (plus:XF (match_operand:XF 1 "register_operand" "")
6459 (match_operand:XF 2 "register_operand" "")))]
6460 "TARGET_80387"
6461 "")
6462
6463(define_expand "adddf3"
6464 [(set (match_operand:DF 0 "register_operand" "")
6465 (plus:DF (match_operand:DF 1 "register_operand" "")
6466 (match_operand:DF 2 "nonimmediate_operand" "")))]
6467 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6468 "")
6469
6470(define_expand "addsf3"
6471 [(set (match_operand:SF 0 "register_operand" "")
6472 (plus:SF (match_operand:SF 1 "register_operand" "")
6473 (match_operand:SF 2 "nonimmediate_operand" "")))]
6474 "TARGET_80387 || TARGET_SSE_MATH"
6475 "")
6476
6477;; Subtract instructions
6478
6479;; %%% splits for subditi3
6480
6481(define_expand "subti3"
6482 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6483 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6484 (match_operand:TI 2 "x86_64_general_operand" "")))
6485 (clobber (reg:CC FLAGS_REG))])]
6486 "TARGET_64BIT"
6487 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6488
6489(define_insn "*subti3_1"
6490 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6491 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6492 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6493 (clobber (reg:CC FLAGS_REG))]
6494 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6495 "#")
6496
6497(define_split
6498 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6499 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6500 (match_operand:TI 2 "x86_64_general_operand" "")))
6501 (clobber (reg:CC FLAGS_REG))]
6502 "TARGET_64BIT && reload_completed"
6503 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6505 (parallel [(set (match_dup 3)
6506 (minus:DI (match_dup 4)
6507 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6508 (match_dup 5))))
6509 (clobber (reg:CC FLAGS_REG))])]
6510 "split_ti (operands+0, 1, operands+0, operands+3);
6511 split_ti (operands+1, 1, operands+1, operands+4);
6512 split_ti (operands+2, 1, operands+2, operands+5);")
6513
6514;; %%% splits for subsidi3
6515
6516(define_expand "subdi3"
6517 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6518 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6519 (match_operand:DI 2 "x86_64_general_operand" "")))
6520 (clobber (reg:CC FLAGS_REG))])]
6521 ""
6522 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6523
6524(define_insn "*subdi3_1"
6525 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6526 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6527 (match_operand:DI 2 "general_operand" "roiF,riF")))
6528 (clobber (reg:CC FLAGS_REG))]
6529 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6530 "#")
6531
6532(define_split
6533 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6534 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6535 (match_operand:DI 2 "general_operand" "")))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "!TARGET_64BIT && reload_completed"
6538 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6539 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6540 (parallel [(set (match_dup 3)
6541 (minus:SI (match_dup 4)
6542 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6543 (match_dup 5))))
6544 (clobber (reg:CC FLAGS_REG))])]
6545 "split_di (operands+0, 1, operands+0, operands+3);
6546 split_di (operands+1, 1, operands+1, operands+4);
6547 split_di (operands+2, 1, operands+2, operands+5);")
6548
6549(define_insn "subdi3_carry_rex64"
6550 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6552 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6553 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6554 (clobber (reg:CC FLAGS_REG))]
6555 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6556 "sbb{q}\t{%2, %0|%0, %2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "pent_pair" "pu")
6559 (set_attr "mode" "DI")])
6560
6561(define_insn "*subdi_1_rex64"
6562 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6563 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6564 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6565 (clobber (reg:CC FLAGS_REG))]
6566 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6567 "sub{q}\t{%2, %0|%0, %2}"
6568 [(set_attr "type" "alu")
6569 (set_attr "mode" "DI")])
6570
6571(define_insn "*subdi_2_rex64"
6572 [(set (reg FLAGS_REG)
6573 (compare
6574 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6575 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6576 (const_int 0)))
6577 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6578 (minus:DI (match_dup 1) (match_dup 2)))]
6579 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6580 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6581 "sub{q}\t{%2, %0|%0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "mode" "DI")])
6584
6585(define_insn "*subdi_3_rex63"
6586 [(set (reg FLAGS_REG)
6587 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6588 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6589 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6590 (minus:DI (match_dup 1) (match_dup 2)))]
6591 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6592 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6593 "sub{q}\t{%2, %0|%0, %2}"
6594 [(set_attr "type" "alu")
6595 (set_attr "mode" "DI")])
6596
6597(define_insn "subqi3_carry"
6598 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6599 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6600 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6601 (match_operand:QI 2 "general_operand" "qi,qm"))))
6602 (clobber (reg:CC FLAGS_REG))]
6603 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6604 "sbb{b}\t{%2, %0|%0, %2}"
6605 [(set_attr "type" "alu")
6606 (set_attr "pent_pair" "pu")
6607 (set_attr "mode" "QI")])
6608
6609(define_insn "subhi3_carry"
6610 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6611 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6612 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6613 (match_operand:HI 2 "general_operand" "ri,rm"))))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6616 "sbb{w}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "pent_pair" "pu")
6619 (set_attr "mode" "HI")])
6620
6621(define_insn "subsi3_carry"
6622 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6623 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6624 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6625 (match_operand:SI 2 "general_operand" "ri,rm"))))
6626 (clobber (reg:CC FLAGS_REG))]
6627 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6628 "sbb{l}\t{%2, %0|%0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "pent_pair" "pu")
6631 (set_attr "mode" "SI")])
6632
6633(define_insn "subsi3_carry_zext"
6634 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6635 (zero_extend:DI
6636 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6637 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6638 (match_operand:SI 2 "general_operand" "ri,rm")))))
6639 (clobber (reg:CC FLAGS_REG))]
6640 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6641 "sbb{l}\t{%2, %k0|%k0, %2}"
6642 [(set_attr "type" "alu")
6643 (set_attr "pent_pair" "pu")
6644 (set_attr "mode" "SI")])
6645
6646(define_expand "subsi3"
6647 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6648 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6649 (match_operand:SI 2 "general_operand" "")))
6650 (clobber (reg:CC FLAGS_REG))])]
6651 ""
6652 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6653
6654(define_insn "*subsi_1"
6655 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6656 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6657 (match_operand:SI 2 "general_operand" "ri,rm")))
6658 (clobber (reg:CC FLAGS_REG))]
6659 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6660 "sub{l}\t{%2, %0|%0, %2}"
6661 [(set_attr "type" "alu")
6662 (set_attr "mode" "SI")])
6663
6664(define_insn "*subsi_1_zext"
6665 [(set (match_operand:DI 0 "register_operand" "=r")
6666 (zero_extend:DI
6667 (minus:SI (match_operand:SI 1 "register_operand" "0")
6668 (match_operand:SI 2 "general_operand" "rim"))))
6669 (clobber (reg:CC FLAGS_REG))]
6670 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6671 "sub{l}\t{%2, %k0|%k0, %2}"
6672 [(set_attr "type" "alu")
6673 (set_attr "mode" "SI")])
6674
6675(define_insn "*subsi_2"
6676 [(set (reg FLAGS_REG)
6677 (compare
6678 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6679 (match_operand:SI 2 "general_operand" "ri,rm"))
6680 (const_int 0)))
6681 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6682 (minus:SI (match_dup 1) (match_dup 2)))]
6683 "ix86_match_ccmode (insn, CCGOCmode)
6684 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685 "sub{l}\t{%2, %0|%0, %2}"
6686 [(set_attr "type" "alu")
6687 (set_attr "mode" "SI")])
6688
6689(define_insn "*subsi_2_zext"
6690 [(set (reg FLAGS_REG)
6691 (compare
6692 (minus:SI (match_operand:SI 1 "register_operand" "0")
6693 (match_operand:SI 2 "general_operand" "rim"))
6694 (const_int 0)))
6695 (set (match_operand:DI 0 "register_operand" "=r")
6696 (zero_extend:DI
6697 (minus:SI (match_dup 1)
6698 (match_dup 2))))]
6699 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6700 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6701 "sub{l}\t{%2, %k0|%k0, %2}"
6702 [(set_attr "type" "alu")
6703 (set_attr "mode" "SI")])
6704
6705(define_insn "*subsi_3"
6706 [(set (reg FLAGS_REG)
6707 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6708 (match_operand:SI 2 "general_operand" "ri,rm")))
6709 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6710 (minus:SI (match_dup 1) (match_dup 2)))]
6711 "ix86_match_ccmode (insn, CCmode)
6712 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6713 "sub{l}\t{%2, %0|%0, %2}"
6714 [(set_attr "type" "alu")
6715 (set_attr "mode" "SI")])
6716
6717(define_insn "*subsi_3_zext"
6718 [(set (reg FLAGS_REG)
6719 (compare (match_operand:SI 1 "register_operand" "0")
6720 (match_operand:SI 2 "general_operand" "rim")))
6721 (set (match_operand:DI 0 "register_operand" "=r")
6722 (zero_extend:DI
6723 (minus:SI (match_dup 1)
6724 (match_dup 2))))]
6725 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6726 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6727 "sub{l}\t{%2, %1|%1, %2}"
6728 [(set_attr "type" "alu")
6729 (set_attr "mode" "DI")])
6730
6731(define_expand "subhi3"
6732 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6733 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6734 (match_operand:HI 2 "general_operand" "")))
6735 (clobber (reg:CC FLAGS_REG))])]
6736 "TARGET_HIMODE_MATH"
6737 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6738
6739(define_insn "*subhi_1"
6740 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6741 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6742 (match_operand:HI 2 "general_operand" "ri,rm")))
6743 (clobber (reg:CC FLAGS_REG))]
6744 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6745 "sub{w}\t{%2, %0|%0, %2}"
6746 [(set_attr "type" "alu")
6747 (set_attr "mode" "HI")])
6748
6749(define_insn "*subhi_2"
6750 [(set (reg FLAGS_REG)
6751 (compare
6752 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6753 (match_operand:HI 2 "general_operand" "ri,rm"))
6754 (const_int 0)))
6755 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6756 (minus:HI (match_dup 1) (match_dup 2)))]
6757 "ix86_match_ccmode (insn, CCGOCmode)
6758 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6759 "sub{w}\t{%2, %0|%0, %2}"
6760 [(set_attr "type" "alu")
6761 (set_attr "mode" "HI")])
6762
6763(define_insn "*subhi_3"
6764 [(set (reg FLAGS_REG)
6765 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6766 (match_operand:HI 2 "general_operand" "ri,rm")))
6767 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6768 (minus:HI (match_dup 1) (match_dup 2)))]
6769 "ix86_match_ccmode (insn, CCmode)
6770 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6771 "sub{w}\t{%2, %0|%0, %2}"
6772 [(set_attr "type" "alu")
6773 (set_attr "mode" "HI")])
6774
6775(define_expand "subqi3"
6776 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6777 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6778 (match_operand:QI 2 "general_operand" "")))
6779 (clobber (reg:CC FLAGS_REG))])]
6780 "TARGET_QIMODE_MATH"
6781 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6782
6783(define_insn "*subqi_1"
6784 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6785 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:QI 2 "general_operand" "qn,qmn")))
6787 (clobber (reg:CC FLAGS_REG))]
6788 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6789 "sub{b}\t{%2, %0|%0, %2}"
6790 [(set_attr "type" "alu")
6791 (set_attr "mode" "QI")])
6792
6793(define_insn "*subqi_1_slp"
6794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6795 (minus:QI (match_dup 0)
6796 (match_operand:QI 1 "general_operand" "qn,qmn")))
6797 (clobber (reg:CC FLAGS_REG))]
6798 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6799 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6800 "sub{b}\t{%1, %0|%0, %1}"
6801 [(set_attr "type" "alu1")
6802 (set_attr "mode" "QI")])
6803
6804(define_insn "*subqi_2"
6805 [(set (reg FLAGS_REG)
6806 (compare
6807 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6808 (match_operand:QI 2 "general_operand" "qi,qm"))
6809 (const_int 0)))
6810 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6811 (minus:HI (match_dup 1) (match_dup 2)))]
6812 "ix86_match_ccmode (insn, CCGOCmode)
6813 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6814 "sub{b}\t{%2, %0|%0, %2}"
6815 [(set_attr "type" "alu")
6816 (set_attr "mode" "QI")])
6817
6818(define_insn "*subqi_3"
6819 [(set (reg FLAGS_REG)
6820 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6821 (match_operand:QI 2 "general_operand" "qi,qm")))
6822 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6823 (minus:HI (match_dup 1) (match_dup 2)))]
6824 "ix86_match_ccmode (insn, CCmode)
6825 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6826 "sub{b}\t{%2, %0|%0, %2}"
6827 [(set_attr "type" "alu")
6828 (set_attr "mode" "QI")])
6829
6830;; The patterns that match these are at the end of this file.
6831
6832(define_expand "subxf3"
6833 [(set (match_operand:XF 0 "register_operand" "")
6834 (minus:XF (match_operand:XF 1 "register_operand" "")
6835 (match_operand:XF 2 "register_operand" "")))]
6836 "TARGET_80387"
6837 "")
6838
6839(define_expand "subdf3"
6840 [(set (match_operand:DF 0 "register_operand" "")
6841 (minus:DF (match_operand:DF 1 "register_operand" "")
6842 (match_operand:DF 2 "nonimmediate_operand" "")))]
6843 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6844 "")
6845
6846(define_expand "subsf3"
6847 [(set (match_operand:SF 0 "register_operand" "")
6848 (minus:SF (match_operand:SF 1 "register_operand" "")
6849 (match_operand:SF 2 "nonimmediate_operand" "")))]
6850 "TARGET_80387 || TARGET_SSE_MATH"
6851 "")
6852
6853;; Multiply instructions
6854
6855(define_expand "muldi3"
6856 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6857 (mult:DI (match_operand:DI 1 "register_operand" "")
6858 (match_operand:DI 2 "x86_64_general_operand" "")))
6859 (clobber (reg:CC FLAGS_REG))])]
6860 "TARGET_64BIT"
6861 "")
6862
4690 (set_attr "fp_int_src" "true")])
4691
4692(define_insn "*floatdidf2_i387"
4693 [(set (match_operand:DF 0 "register_operand" "=f,f")
4694 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4695 "TARGET_80387"
4696 "@
4697 fild%z1\t%1
4698 #"
4699 [(set_attr "type" "fmov,multi")
4700 (set_attr "mode" "DF")
4701 (set_attr "unit" "*,i387")
4702 (set_attr "fp_int_src" "true")])
4703
4704(define_insn "floathixf2"
4705 [(set (match_operand:XF 0 "register_operand" "=f,f")
4706 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4707 "TARGET_80387"
4708 "@
4709 fild%z1\t%1
4710 #"
4711 [(set_attr "type" "fmov,multi")
4712 (set_attr "mode" "XF")
4713 (set_attr "unit" "*,i387")
4714 (set_attr "fp_int_src" "true")])
4715
4716(define_insn "floatsixf2"
4717 [(set (match_operand:XF 0 "register_operand" "=f,f")
4718 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4719 "TARGET_80387"
4720 "@
4721 fild%z1\t%1
4722 #"
4723 [(set_attr "type" "fmov,multi")
4724 (set_attr "mode" "XF")
4725 (set_attr "unit" "*,i387")
4726 (set_attr "fp_int_src" "true")])
4727
4728(define_insn "floatdixf2"
4729 [(set (match_operand:XF 0 "register_operand" "=f,f")
4730 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4731 "TARGET_80387"
4732 "@
4733 fild%z1\t%1
4734 #"
4735 [(set_attr "type" "fmov,multi")
4736 (set_attr "mode" "XF")
4737 (set_attr "unit" "*,i387")
4738 (set_attr "fp_int_src" "true")])
4739
4740;; %%% Kill these when reload knows how to do it.
4741(define_split
4742 [(set (match_operand 0 "fp_register_operand" "")
4743 (float (match_operand 1 "register_operand" "")))]
4744 "reload_completed
4745 && TARGET_80387
4746 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4747 [(const_int 0)]
4748{
4749 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4750 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4751 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4752 ix86_free_from_memory (GET_MODE (operands[1]));
4753 DONE;
4754})
4755
4756(define_expand "floatunssisf2"
4757 [(use (match_operand:SF 0 "register_operand" ""))
4758 (use (match_operand:SI 1 "register_operand" ""))]
4759 "!TARGET_64BIT && TARGET_SSE_MATH"
4760 "x86_emit_floatuns (operands); DONE;")
4761
4762(define_expand "floatunsdisf2"
4763 [(use (match_operand:SF 0 "register_operand" ""))
4764 (use (match_operand:DI 1 "register_operand" ""))]
4765 "TARGET_64BIT && TARGET_SSE_MATH"
4766 "x86_emit_floatuns (operands); DONE;")
4767
4768(define_expand "floatunsdidf2"
4769 [(use (match_operand:DF 0 "register_operand" ""))
4770 (use (match_operand:DI 1 "register_operand" ""))]
4771 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4772 "x86_emit_floatuns (operands); DONE;")
4773
4774;; SSE extract/set expanders
4775
4776
4777;; Add instructions
4778
4779;; %%% splits for addditi3
4780
4781(define_expand "addti3"
4782 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4783 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4784 (match_operand:TI 2 "x86_64_general_operand" "")))
4785 (clobber (reg:CC FLAGS_REG))]
4786 "TARGET_64BIT"
4787 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4788
4789(define_insn "*addti3_1"
4790 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4791 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4792 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4793 (clobber (reg:CC FLAGS_REG))]
4794 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4795 "#")
4796
4797(define_split
4798 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4799 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4800 (match_operand:TI 2 "x86_64_general_operand" "")))
4801 (clobber (reg:CC FLAGS_REG))]
4802 "TARGET_64BIT && reload_completed"
4803 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4804 UNSPEC_ADD_CARRY))
4805 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4806 (parallel [(set (match_dup 3)
4807 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4808 (match_dup 4))
4809 (match_dup 5)))
4810 (clobber (reg:CC FLAGS_REG))])]
4811 "split_ti (operands+0, 1, operands+0, operands+3);
4812 split_ti (operands+1, 1, operands+1, operands+4);
4813 split_ti (operands+2, 1, operands+2, operands+5);")
4814
4815;; %%% splits for addsidi3
4816; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817; (plus:DI (match_operand:DI 1 "general_operand" "")
4818; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4819
4820(define_expand "adddi3"
4821 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4822 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4823 (match_operand:DI 2 "x86_64_general_operand" "")))
4824 (clobber (reg:CC FLAGS_REG))]
4825 ""
4826 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4827
4828(define_insn "*adddi3_1"
4829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4830 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4831 (match_operand:DI 2 "general_operand" "roiF,riF")))
4832 (clobber (reg:CC FLAGS_REG))]
4833 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834 "#")
4835
4836(define_split
4837 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4838 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4839 (match_operand:DI 2 "general_operand" "")))
4840 (clobber (reg:CC FLAGS_REG))]
4841 "!TARGET_64BIT && reload_completed"
4842 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4843 UNSPEC_ADD_CARRY))
4844 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4845 (parallel [(set (match_dup 3)
4846 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4847 (match_dup 4))
4848 (match_dup 5)))
4849 (clobber (reg:CC FLAGS_REG))])]
4850 "split_di (operands+0, 1, operands+0, operands+3);
4851 split_di (operands+1, 1, operands+1, operands+4);
4852 split_di (operands+2, 1, operands+2, operands+5);")
4853
4854(define_insn "adddi3_carry_rex64"
4855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4856 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4857 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4858 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4859 (clobber (reg:CC FLAGS_REG))]
4860 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4861 "adc{q}\t{%2, %0|%0, %2}"
4862 [(set_attr "type" "alu")
4863 (set_attr "pent_pair" "pu")
4864 (set_attr "mode" "DI")])
4865
4866(define_insn "*adddi3_cc_rex64"
4867 [(set (reg:CC FLAGS_REG)
4868 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4869 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4870 UNSPEC_ADD_CARRY))
4871 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4872 (plus:DI (match_dup 1) (match_dup 2)))]
4873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4874 "add{q}\t{%2, %0|%0, %2}"
4875 [(set_attr "type" "alu")
4876 (set_attr "mode" "DI")])
4877
4878(define_insn "addqi3_carry"
4879 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4880 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4881 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4882 (match_operand:QI 2 "general_operand" "qi,qm")))
4883 (clobber (reg:CC FLAGS_REG))]
4884 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4885 "adc{b}\t{%2, %0|%0, %2}"
4886 [(set_attr "type" "alu")
4887 (set_attr "pent_pair" "pu")
4888 (set_attr "mode" "QI")])
4889
4890(define_insn "addhi3_carry"
4891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4892 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4893 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4894 (match_operand:HI 2 "general_operand" "ri,rm")))
4895 (clobber (reg:CC FLAGS_REG))]
4896 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4897 "adc{w}\t{%2, %0|%0, %2}"
4898 [(set_attr "type" "alu")
4899 (set_attr "pent_pair" "pu")
4900 (set_attr "mode" "HI")])
4901
4902(define_insn "addsi3_carry"
4903 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4904 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4905 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4906 (match_operand:SI 2 "general_operand" "ri,rm")))
4907 (clobber (reg:CC FLAGS_REG))]
4908 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4909 "adc{l}\t{%2, %0|%0, %2}"
4910 [(set_attr "type" "alu")
4911 (set_attr "pent_pair" "pu")
4912 (set_attr "mode" "SI")])
4913
4914(define_insn "*addsi3_carry_zext"
4915 [(set (match_operand:DI 0 "register_operand" "=r")
4916 (zero_extend:DI
4917 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4918 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4919 (match_operand:SI 2 "general_operand" "rim"))))
4920 (clobber (reg:CC FLAGS_REG))]
4921 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4922 "adc{l}\t{%2, %k0|%k0, %2}"
4923 [(set_attr "type" "alu")
4924 (set_attr "pent_pair" "pu")
4925 (set_attr "mode" "SI")])
4926
4927(define_insn "*addsi3_cc"
4928 [(set (reg:CC FLAGS_REG)
4929 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4930 (match_operand:SI 2 "general_operand" "ri,rm")]
4931 UNSPEC_ADD_CARRY))
4932 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4933 (plus:SI (match_dup 1) (match_dup 2)))]
4934 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4935 "add{l}\t{%2, %0|%0, %2}"
4936 [(set_attr "type" "alu")
4937 (set_attr "mode" "SI")])
4938
4939(define_insn "addqi3_cc"
4940 [(set (reg:CC FLAGS_REG)
4941 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4942 (match_operand:QI 2 "general_operand" "qi,qm")]
4943 UNSPEC_ADD_CARRY))
4944 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4945 (plus:QI (match_dup 1) (match_dup 2)))]
4946 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4947 "add{b}\t{%2, %0|%0, %2}"
4948 [(set_attr "type" "alu")
4949 (set_attr "mode" "QI")])
4950
4951(define_expand "addsi3"
4952 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4953 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4954 (match_operand:SI 2 "general_operand" "")))
4955 (clobber (reg:CC FLAGS_REG))])]
4956 ""
4957 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4958
4959(define_insn "*lea_1"
4960 [(set (match_operand:SI 0 "register_operand" "=r")
4961 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4962 "!TARGET_64BIT"
4963 "lea{l}\t{%a1, %0|%0, %a1}"
4964 [(set_attr "type" "lea")
4965 (set_attr "mode" "SI")])
4966
4967(define_insn "*lea_1_rex64"
4968 [(set (match_operand:SI 0 "register_operand" "=r")
4969 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4970 "TARGET_64BIT"
4971 "lea{l}\t{%a1, %0|%0, %a1}"
4972 [(set_attr "type" "lea")
4973 (set_attr "mode" "SI")])
4974
4975(define_insn "*lea_1_zext"
4976 [(set (match_operand:DI 0 "register_operand" "=r")
4977 (zero_extend:DI
4978 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4979 "TARGET_64BIT"
4980 "lea{l}\t{%a1, %k0|%k0, %a1}"
4981 [(set_attr "type" "lea")
4982 (set_attr "mode" "SI")])
4983
4984(define_insn "*lea_2_rex64"
4985 [(set (match_operand:DI 0 "register_operand" "=r")
4986 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4987 "TARGET_64BIT"
4988 "lea{q}\t{%a1, %0|%0, %a1}"
4989 [(set_attr "type" "lea")
4990 (set_attr "mode" "DI")])
4991
4992;; The lea patterns for non-Pmodes needs to be matched by several
4993;; insns converted to real lea by splitters.
4994
4995(define_insn_and_split "*lea_general_1"
4996 [(set (match_operand 0 "register_operand" "=r")
4997 (plus (plus (match_operand 1 "index_register_operand" "l")
4998 (match_operand 2 "register_operand" "r"))
4999 (match_operand 3 "immediate_operand" "i")))]
5000 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5001 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5002 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5003 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5004 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5005 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5006 || GET_MODE (operands[3]) == VOIDmode)"
5007 "#"
5008 "&& reload_completed"
5009 [(const_int 0)]
5010{
5011 rtx pat;
5012 operands[0] = gen_lowpart (SImode, operands[0]);
5013 operands[1] = gen_lowpart (Pmode, operands[1]);
5014 operands[2] = gen_lowpart (Pmode, operands[2]);
5015 operands[3] = gen_lowpart (Pmode, operands[3]);
5016 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5017 operands[3]);
5018 if (Pmode != SImode)
5019 pat = gen_rtx_SUBREG (SImode, pat, 0);
5020 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5021 DONE;
5022}
5023 [(set_attr "type" "lea")
5024 (set_attr "mode" "SI")])
5025
5026(define_insn_and_split "*lea_general_1_zext"
5027 [(set (match_operand:DI 0 "register_operand" "=r")
5028 (zero_extend:DI
5029 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5030 (match_operand:SI 2 "register_operand" "r"))
5031 (match_operand:SI 3 "immediate_operand" "i"))))]
5032 "TARGET_64BIT"
5033 "#"
5034 "&& reload_completed"
5035 [(set (match_dup 0)
5036 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5037 (match_dup 2))
5038 (match_dup 3)) 0)))]
5039{
5040 operands[1] = gen_lowpart (Pmode, operands[1]);
5041 operands[2] = gen_lowpart (Pmode, operands[2]);
5042 operands[3] = gen_lowpart (Pmode, operands[3]);
5043}
5044 [(set_attr "type" "lea")
5045 (set_attr "mode" "SI")])
5046
5047(define_insn_and_split "*lea_general_2"
5048 [(set (match_operand 0 "register_operand" "=r")
5049 (plus (mult (match_operand 1 "index_register_operand" "l")
5050 (match_operand 2 "const248_operand" "i"))
5051 (match_operand 3 "nonmemory_operand" "ri")))]
5052 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5053 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5054 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5055 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5056 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5057 || GET_MODE (operands[3]) == VOIDmode)"
5058 "#"
5059 "&& reload_completed"
5060 [(const_int 0)]
5061{
5062 rtx pat;
5063 operands[0] = gen_lowpart (SImode, operands[0]);
5064 operands[1] = gen_lowpart (Pmode, operands[1]);
5065 operands[3] = gen_lowpart (Pmode, operands[3]);
5066 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5067 operands[3]);
5068 if (Pmode != SImode)
5069 pat = gen_rtx_SUBREG (SImode, pat, 0);
5070 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5071 DONE;
5072}
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
5075
5076(define_insn_and_split "*lea_general_2_zext"
5077 [(set (match_operand:DI 0 "register_operand" "=r")
5078 (zero_extend:DI
5079 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5080 (match_operand:SI 2 "const248_operand" "n"))
5081 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5082 "TARGET_64BIT"
5083 "#"
5084 "&& reload_completed"
5085 [(set (match_dup 0)
5086 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5087 (match_dup 2))
5088 (match_dup 3)) 0)))]
5089{
5090 operands[1] = gen_lowpart (Pmode, operands[1]);
5091 operands[3] = gen_lowpart (Pmode, operands[3]);
5092}
5093 [(set_attr "type" "lea")
5094 (set_attr "mode" "SI")])
5095
5096(define_insn_and_split "*lea_general_3"
5097 [(set (match_operand 0 "register_operand" "=r")
5098 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5099 (match_operand 2 "const248_operand" "i"))
5100 (match_operand 3 "register_operand" "r"))
5101 (match_operand 4 "immediate_operand" "i")))]
5102 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5107 "#"
5108 "&& reload_completed"
5109 [(const_int 0)]
5110{
5111 rtx pat;
5112 operands[0] = gen_lowpart (SImode, operands[0]);
5113 operands[1] = gen_lowpart (Pmode, operands[1]);
5114 operands[3] = gen_lowpart (Pmode, operands[3]);
5115 operands[4] = gen_lowpart (Pmode, operands[4]);
5116 pat = gen_rtx_PLUS (Pmode,
5117 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5118 operands[2]),
5119 operands[3]),
5120 operands[4]);
5121 if (Pmode != SImode)
5122 pat = gen_rtx_SUBREG (SImode, pat, 0);
5123 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5124 DONE;
5125}
5126 [(set_attr "type" "lea")
5127 (set_attr "mode" "SI")])
5128
5129(define_insn_and_split "*lea_general_3_zext"
5130 [(set (match_operand:DI 0 "register_operand" "=r")
5131 (zero_extend:DI
5132 (plus:SI (plus:SI (mult:SI
5133 (match_operand:SI 1 "index_register_operand" "l")
5134 (match_operand:SI 2 "const248_operand" "n"))
5135 (match_operand:SI 3 "register_operand" "r"))
5136 (match_operand:SI 4 "immediate_operand" "i"))))]
5137 "TARGET_64BIT"
5138 "#"
5139 "&& reload_completed"
5140 [(set (match_dup 0)
5141 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5142 (match_dup 2))
5143 (match_dup 3))
5144 (match_dup 4)) 0)))]
5145{
5146 operands[1] = gen_lowpart (Pmode, operands[1]);
5147 operands[3] = gen_lowpart (Pmode, operands[3]);
5148 operands[4] = gen_lowpart (Pmode, operands[4]);
5149}
5150 [(set_attr "type" "lea")
5151 (set_attr "mode" "SI")])
5152
5153(define_insn "*adddi_1_rex64"
5154 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5155 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5156 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5157 (clobber (reg:CC FLAGS_REG))]
5158 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5159{
5160 switch (get_attr_type (insn))
5161 {
5162 case TYPE_LEA:
5163 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5164 return "lea{q}\t{%a2, %0|%0, %a2}";
5165
5166 case TYPE_INCDEC:
5167 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168 if (operands[2] == const1_rtx)
5169 return "inc{q}\t%0";
5170 else
5171 {
5172 gcc_assert (operands[2] == constm1_rtx);
5173 return "dec{q}\t%0";
5174 }
5175
5176 default:
5177 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5178
5179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5180 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5181 if (GET_CODE (operands[2]) == CONST_INT
5182 /* Avoid overflows. */
5183 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5184 && (INTVAL (operands[2]) == 128
5185 || (INTVAL (operands[2]) < 0
5186 && INTVAL (operands[2]) != -128)))
5187 {
5188 operands[2] = GEN_INT (-INTVAL (operands[2]));
5189 return "sub{q}\t{%2, %0|%0, %2}";
5190 }
5191 return "add{q}\t{%2, %0|%0, %2}";
5192 }
5193}
5194 [(set (attr "type")
5195 (cond [(eq_attr "alternative" "2")
5196 (const_string "lea")
5197 ; Current assemblers are broken and do not allow @GOTOFF in
5198 ; ought but a memory context.
5199 (match_operand:DI 2 "pic_symbolic_operand" "")
5200 (const_string "lea")
5201 (match_operand:DI 2 "incdec_operand" "")
5202 (const_string "incdec")
5203 ]
5204 (const_string "alu")))
5205 (set_attr "mode" "DI")])
5206
5207;; Convert lea to the lea pattern to avoid flags dependency.
5208(define_split
5209 [(set (match_operand:DI 0 "register_operand" "")
5210 (plus:DI (match_operand:DI 1 "register_operand" "")
5211 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5212 (clobber (reg:CC FLAGS_REG))]
5213 "TARGET_64BIT && reload_completed
5214 && true_regnum (operands[0]) != true_regnum (operands[1])"
5215 [(set (match_dup 0)
5216 (plus:DI (match_dup 1)
5217 (match_dup 2)))]
5218 "")
5219
5220(define_insn "*adddi_2_rex64"
5221 [(set (reg FLAGS_REG)
5222 (compare
5223 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5224 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5225 (const_int 0)))
5226 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5227 (plus:DI (match_dup 1) (match_dup 2)))]
5228 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5229 && ix86_binary_operator_ok (PLUS, DImode, operands)
5230 /* Current assemblers are broken and do not allow @GOTOFF in
5231 ought but a memory context. */
5232 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5233{
5234 switch (get_attr_type (insn))
5235 {
5236 case TYPE_INCDEC:
5237 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238 if (operands[2] == const1_rtx)
5239 return "inc{q}\t%0";
5240 else
5241 {
5242 gcc_assert (operands[2] == constm1_rtx);
5243 return "dec{q}\t%0";
5244 }
5245
5246 default:
5247 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248 /* ???? We ought to handle there the 32bit case too
5249 - do we need new constraint? */
5250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5251 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5252 if (GET_CODE (operands[2]) == CONST_INT
5253 /* Avoid overflows. */
5254 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5255 && (INTVAL (operands[2]) == 128
5256 || (INTVAL (operands[2]) < 0
5257 && INTVAL (operands[2]) != -128)))
5258 {
5259 operands[2] = GEN_INT (-INTVAL (operands[2]));
5260 return "sub{q}\t{%2, %0|%0, %2}";
5261 }
5262 return "add{q}\t{%2, %0|%0, %2}";
5263 }
5264}
5265 [(set (attr "type")
5266 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5267 (const_string "incdec")
5268 (const_string "alu")))
5269 (set_attr "mode" "DI")])
5270
5271(define_insn "*adddi_3_rex64"
5272 [(set (reg FLAGS_REG)
5273 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5274 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5275 (clobber (match_scratch:DI 0 "=r"))]
5276 "TARGET_64BIT
5277 && ix86_match_ccmode (insn, CCZmode)
5278 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5279 /* Current assemblers are broken and do not allow @GOTOFF in
5280 ought but a memory context. */
5281 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5282{
5283 switch (get_attr_type (insn))
5284 {
5285 case TYPE_INCDEC:
5286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5287 if (operands[2] == const1_rtx)
5288 return "inc{q}\t%0";
5289 else
5290 {
5291 gcc_assert (operands[2] == constm1_rtx);
5292 return "dec{q}\t%0";
5293 }
5294
5295 default:
5296 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5297 /* ???? We ought to handle there the 32bit case too
5298 - do we need new constraint? */
5299 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5300 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5301 if (GET_CODE (operands[2]) == CONST_INT
5302 /* Avoid overflows. */
5303 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5304 && (INTVAL (operands[2]) == 128
5305 || (INTVAL (operands[2]) < 0
5306 && INTVAL (operands[2]) != -128)))
5307 {
5308 operands[2] = GEN_INT (-INTVAL (operands[2]));
5309 return "sub{q}\t{%2, %0|%0, %2}";
5310 }
5311 return "add{q}\t{%2, %0|%0, %2}";
5312 }
5313}
5314 [(set (attr "type")
5315 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5316 (const_string "incdec")
5317 (const_string "alu")))
5318 (set_attr "mode" "DI")])
5319
5320; For comparisons against 1, -1 and 128, we may generate better code
5321; by converting cmp to add, inc or dec as done by peephole2. This pattern
5322; is matched then. We can't accept general immediate, because for
5323; case of overflows, the result is messed up.
5324; This pattern also don't hold of 0x8000000000000000, since the value overflows
5325; when negated.
5326; Also carry flag is reversed compared to cmp, so this conversion is valid
5327; only for comparisons not depending on it.
5328(define_insn "*adddi_4_rex64"
5329 [(set (reg FLAGS_REG)
5330 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5331 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5332 (clobber (match_scratch:DI 0 "=rm"))]
5333 "TARGET_64BIT
5334 && ix86_match_ccmode (insn, CCGCmode)"
5335{
5336 switch (get_attr_type (insn))
5337 {
5338 case TYPE_INCDEC:
5339 if (operands[2] == constm1_rtx)
5340 return "inc{q}\t%0";
5341 else
5342 {
5343 gcc_assert (operands[2] == const1_rtx);
5344 return "dec{q}\t%0";
5345 }
5346
5347 default:
5348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5349 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5350 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5351 if ((INTVAL (operands[2]) == -128
5352 || (INTVAL (operands[2]) > 0
5353 && INTVAL (operands[2]) != 128))
5354 /* Avoid overflows. */
5355 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5356 return "sub{q}\t{%2, %0|%0, %2}";
5357 operands[2] = GEN_INT (-INTVAL (operands[2]));
5358 return "add{q}\t{%2, %0|%0, %2}";
5359 }
5360}
5361 [(set (attr "type")
5362 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5363 (const_string "incdec")
5364 (const_string "alu")))
5365 (set_attr "mode" "DI")])
5366
5367(define_insn "*adddi_5_rex64"
5368 [(set (reg FLAGS_REG)
5369 (compare
5370 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5371 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5372 (const_int 0)))
5373 (clobber (match_scratch:DI 0 "=r"))]
5374 "TARGET_64BIT
5375 && ix86_match_ccmode (insn, CCGOCmode)
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 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5385 if (operands[2] == const1_rtx)
5386 return "inc{q}\t%0";
5387 else
5388 {
5389 gcc_assert (operands[2] == constm1_rtx);
5390 return "dec{q}\t%0";
5391 }
5392
5393 default:
5394 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5395 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5397 if (GET_CODE (operands[2]) == CONST_INT
5398 /* Avoid overflows. */
5399 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5400 && (INTVAL (operands[2]) == 128
5401 || (INTVAL (operands[2]) < 0
5402 && INTVAL (operands[2]) != -128)))
5403 {
5404 operands[2] = GEN_INT (-INTVAL (operands[2]));
5405 return "sub{q}\t{%2, %0|%0, %2}";
5406 }
5407 return "add{q}\t{%2, %0|%0, %2}";
5408 }
5409}
5410 [(set (attr "type")
5411 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5412 (const_string "incdec")
5413 (const_string "alu")))
5414 (set_attr "mode" "DI")])
5415
5416
5417(define_insn "*addsi_1"
5418 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5419 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5420 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5421 (clobber (reg:CC FLAGS_REG))]
5422 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5423{
5424 switch (get_attr_type (insn))
5425 {
5426 case TYPE_LEA:
5427 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5428 return "lea{l}\t{%a2, %0|%0, %a2}";
5429
5430 case TYPE_INCDEC:
5431 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5432 if (operands[2] == const1_rtx)
5433 return "inc{l}\t%0";
5434 else
5435 {
5436 gcc_assert (operands[2] == constm1_rtx);
5437 return "dec{l}\t%0";
5438 }
5439
5440 default:
5441 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5442
5443 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5445 if (GET_CODE (operands[2]) == CONST_INT
5446 && (INTVAL (operands[2]) == 128
5447 || (INTVAL (operands[2]) < 0
5448 && INTVAL (operands[2]) != -128)))
5449 {
5450 operands[2] = GEN_INT (-INTVAL (operands[2]));
5451 return "sub{l}\t{%2, %0|%0, %2}";
5452 }
5453 return "add{l}\t{%2, %0|%0, %2}";
5454 }
5455}
5456 [(set (attr "type")
5457 (cond [(eq_attr "alternative" "2")
5458 (const_string "lea")
5459 ; Current assemblers are broken and do not allow @GOTOFF in
5460 ; ought but a memory context.
5461 (match_operand:SI 2 "pic_symbolic_operand" "")
5462 (const_string "lea")
5463 (match_operand:SI 2 "incdec_operand" "")
5464 (const_string "incdec")
5465 ]
5466 (const_string "alu")))
5467 (set_attr "mode" "SI")])
5468
5469;; Convert lea to the lea pattern to avoid flags dependency.
5470(define_split
5471 [(set (match_operand 0 "register_operand" "")
5472 (plus (match_operand 1 "register_operand" "")
5473 (match_operand 2 "nonmemory_operand" "")))
5474 (clobber (reg:CC FLAGS_REG))]
5475 "reload_completed
5476 && true_regnum (operands[0]) != true_regnum (operands[1])"
5477 [(const_int 0)]
5478{
5479 rtx pat;
5480 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5481 may confuse gen_lowpart. */
5482 if (GET_MODE (operands[0]) != Pmode)
5483 {
5484 operands[1] = gen_lowpart (Pmode, operands[1]);
5485 operands[2] = gen_lowpart (Pmode, operands[2]);
5486 }
5487 operands[0] = gen_lowpart (SImode, operands[0]);
5488 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5489 if (Pmode != SImode)
5490 pat = gen_rtx_SUBREG (SImode, pat, 0);
5491 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5492 DONE;
5493})
5494
5495;; It may seem that nonimmediate operand is proper one for operand 1.
5496;; The addsi_1 pattern allows nonimmediate operand at that place and
5497;; we take care in ix86_binary_operator_ok to not allow two memory
5498;; operands so proper swapping will be done in reload. This allow
5499;; patterns constructed from addsi_1 to match.
5500(define_insn "addsi_1_zext"
5501 [(set (match_operand:DI 0 "register_operand" "=r,r")
5502 (zero_extend:DI
5503 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5504 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5507{
5508 switch (get_attr_type (insn))
5509 {
5510 case TYPE_LEA:
5511 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5512 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5513
5514 case TYPE_INCDEC:
5515 if (operands[2] == const1_rtx)
5516 return "inc{l}\t%k0";
5517 else
5518 {
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{l}\t%k0";
5521 }
5522
5523 default:
5524 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5525 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5526 if (GET_CODE (operands[2]) == CONST_INT
5527 && (INTVAL (operands[2]) == 128
5528 || (INTVAL (operands[2]) < 0
5529 && INTVAL (operands[2]) != -128)))
5530 {
5531 operands[2] = GEN_INT (-INTVAL (operands[2]));
5532 return "sub{l}\t{%2, %k0|%k0, %2}";
5533 }
5534 return "add{l}\t{%2, %k0|%k0, %2}";
5535 }
5536}
5537 [(set (attr "type")
5538 (cond [(eq_attr "alternative" "1")
5539 (const_string "lea")
5540 ; Current assemblers are broken and do not allow @GOTOFF in
5541 ; ought but a memory context.
5542 (match_operand:SI 2 "pic_symbolic_operand" "")
5543 (const_string "lea")
5544 (match_operand:SI 2 "incdec_operand" "")
5545 (const_string "incdec")
5546 ]
5547 (const_string "alu")))
5548 (set_attr "mode" "SI")])
5549
5550;; Convert lea to the lea pattern to avoid flags dependency.
5551(define_split
5552 [(set (match_operand:DI 0 "register_operand" "")
5553 (zero_extend:DI
5554 (plus:SI (match_operand:SI 1 "register_operand" "")
5555 (match_operand:SI 2 "nonmemory_operand" ""))))
5556 (clobber (reg:CC FLAGS_REG))]
5557 "TARGET_64BIT && reload_completed
5558 && true_regnum (operands[0]) != true_regnum (operands[1])"
5559 [(set (match_dup 0)
5560 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5561{
5562 operands[1] = gen_lowpart (Pmode, operands[1]);
5563 operands[2] = gen_lowpart (Pmode, operands[2]);
5564})
5565
5566(define_insn "*addsi_2"
5567 [(set (reg FLAGS_REG)
5568 (compare
5569 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5570 (match_operand:SI 2 "general_operand" "rmni,rni"))
5571 (const_int 0)))
5572 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5573 (plus:SI (match_dup 1) (match_dup 2)))]
5574 "ix86_match_ccmode (insn, CCGOCmode)
5575 && ix86_binary_operator_ok (PLUS, SImode, operands)
5576 /* Current assemblers are broken and do not allow @GOTOFF in
5577 ought but a memory context. */
5578 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5579{
5580 switch (get_attr_type (insn))
5581 {
5582 case TYPE_INCDEC:
5583 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584 if (operands[2] == const1_rtx)
5585 return "inc{l}\t%0";
5586 else
5587 {
5588 gcc_assert (operands[2] == constm1_rtx);
5589 return "dec{l}\t%0";
5590 }
5591
5592 default:
5593 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5594 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5595 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5596 if (GET_CODE (operands[2]) == CONST_INT
5597 && (INTVAL (operands[2]) == 128
5598 || (INTVAL (operands[2]) < 0
5599 && INTVAL (operands[2]) != -128)))
5600 {
5601 operands[2] = GEN_INT (-INTVAL (operands[2]));
5602 return "sub{l}\t{%2, %0|%0, %2}";
5603 }
5604 return "add{l}\t{%2, %0|%0, %2}";
5605 }
5606}
5607 [(set (attr "type")
5608 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5609 (const_string "incdec")
5610 (const_string "alu")))
5611 (set_attr "mode" "SI")])
5612
5613;; See comment for addsi_1_zext why we do use nonimmediate_operand
5614(define_insn "*addsi_2_zext"
5615 [(set (reg FLAGS_REG)
5616 (compare
5617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5618 (match_operand:SI 2 "general_operand" "rmni"))
5619 (const_int 0)))
5620 (set (match_operand:DI 0 "register_operand" "=r")
5621 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5622 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5623 && ix86_binary_operator_ok (PLUS, SImode, operands)
5624 /* Current assemblers are broken and do not allow @GOTOFF in
5625 ought but a memory context. */
5626 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5627{
5628 switch (get_attr_type (insn))
5629 {
5630 case TYPE_INCDEC:
5631 if (operands[2] == const1_rtx)
5632 return "inc{l}\t%k0";
5633 else
5634 {
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return "dec{l}\t%k0";
5637 }
5638
5639 default:
5640 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5641 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5642 if (GET_CODE (operands[2]) == CONST_INT
5643 && (INTVAL (operands[2]) == 128
5644 || (INTVAL (operands[2]) < 0
5645 && INTVAL (operands[2]) != -128)))
5646 {
5647 operands[2] = GEN_INT (-INTVAL (operands[2]));
5648 return "sub{l}\t{%2, %k0|%k0, %2}";
5649 }
5650 return "add{l}\t{%2, %k0|%k0, %2}";
5651 }
5652}
5653 [(set (attr "type")
5654 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5655 (const_string "incdec")
5656 (const_string "alu")))
5657 (set_attr "mode" "SI")])
5658
5659(define_insn "*addsi_3"
5660 [(set (reg FLAGS_REG)
5661 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5662 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5663 (clobber (match_scratch:SI 0 "=r"))]
5664 "ix86_match_ccmode (insn, CCZmode)
5665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5666 /* Current assemblers are broken and do not allow @GOTOFF in
5667 ought but a memory context. */
5668 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5669{
5670 switch (get_attr_type (insn))
5671 {
5672 case TYPE_INCDEC:
5673 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5674 if (operands[2] == const1_rtx)
5675 return "inc{l}\t%0";
5676 else
5677 {
5678 gcc_assert (operands[2] == constm1_rtx);
5679 return "dec{l}\t%0";
5680 }
5681
5682 default:
5683 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5685 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5686 if (GET_CODE (operands[2]) == CONST_INT
5687 && (INTVAL (operands[2]) == 128
5688 || (INTVAL (operands[2]) < 0
5689 && INTVAL (operands[2]) != -128)))
5690 {
5691 operands[2] = GEN_INT (-INTVAL (operands[2]));
5692 return "sub{l}\t{%2, %0|%0, %2}";
5693 }
5694 return "add{l}\t{%2, %0|%0, %2}";
5695 }
5696}
5697 [(set (attr "type")
5698 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5699 (const_string "incdec")
5700 (const_string "alu")))
5701 (set_attr "mode" "SI")])
5702
5703;; See comment for addsi_1_zext why we do use nonimmediate_operand
5704(define_insn "*addsi_3_zext"
5705 [(set (reg FLAGS_REG)
5706 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5707 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5708 (set (match_operand:DI 0 "register_operand" "=r")
5709 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5710 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5711 && ix86_binary_operator_ok (PLUS, SImode, operands)
5712 /* Current assemblers are broken and do not allow @GOTOFF in
5713 ought but a memory context. */
5714 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5715{
5716 switch (get_attr_type (insn))
5717 {
5718 case TYPE_INCDEC:
5719 if (operands[2] == const1_rtx)
5720 return "inc{l}\t%k0";
5721 else
5722 {
5723 gcc_assert (operands[2] == constm1_rtx);
5724 return "dec{l}\t%k0";
5725 }
5726
5727 default:
5728 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5729 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5730 if (GET_CODE (operands[2]) == CONST_INT
5731 && (INTVAL (operands[2]) == 128
5732 || (INTVAL (operands[2]) < 0
5733 && INTVAL (operands[2]) != -128)))
5734 {
5735 operands[2] = GEN_INT (-INTVAL (operands[2]));
5736 return "sub{l}\t{%2, %k0|%k0, %2}";
5737 }
5738 return "add{l}\t{%2, %k0|%k0, %2}";
5739 }
5740}
5741 [(set (attr "type")
5742 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5743 (const_string "incdec")
5744 (const_string "alu")))
5745 (set_attr "mode" "SI")])
5746
5747; For comparisons against 1, -1 and 128, we may generate better code
5748; by converting cmp to add, inc or dec as done by peephole2. This pattern
5749; is matched then. We can't accept general immediate, because for
5750; case of overflows, the result is messed up.
5751; This pattern also don't hold of 0x80000000, since the value overflows
5752; when negated.
5753; Also carry flag is reversed compared to cmp, so this conversion is valid
5754; only for comparisons not depending on it.
5755(define_insn "*addsi_4"
5756 [(set (reg FLAGS_REG)
5757 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5758 (match_operand:SI 2 "const_int_operand" "n")))
5759 (clobber (match_scratch:SI 0 "=rm"))]
5760 "ix86_match_ccmode (insn, CCGCmode)
5761 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5762{
5763 switch (get_attr_type (insn))
5764 {
5765 case TYPE_INCDEC:
5766 if (operands[2] == constm1_rtx)
5767 return "inc{l}\t%0";
5768 else
5769 {
5770 gcc_assert (operands[2] == const1_rtx);
5771 return "dec{l}\t%0";
5772 }
5773
5774 default:
5775 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5777 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5778 if ((INTVAL (operands[2]) == -128
5779 || (INTVAL (operands[2]) > 0
5780 && INTVAL (operands[2]) != 128)))
5781 return "sub{l}\t{%2, %0|%0, %2}";
5782 operands[2] = GEN_INT (-INTVAL (operands[2]));
5783 return "add{l}\t{%2, %0|%0, %2}";
5784 }
5785}
5786 [(set (attr "type")
5787 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5788 (const_string "incdec")
5789 (const_string "alu")))
5790 (set_attr "mode" "SI")])
5791
5792(define_insn "*addsi_5"
5793 [(set (reg FLAGS_REG)
5794 (compare
5795 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5796 (match_operand:SI 2 "general_operand" "rmni"))
5797 (const_int 0)))
5798 (clobber (match_scratch:SI 0 "=r"))]
5799 "ix86_match_ccmode (insn, CCGOCmode)
5800 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5801 /* Current assemblers are broken and do not allow @GOTOFF in
5802 ought but a memory context. */
5803 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5804{
5805 switch (get_attr_type (insn))
5806 {
5807 case TYPE_INCDEC:
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (operands[2] == const1_rtx)
5810 return "inc{l}\t%0";
5811 else
5812 {
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{l}\t%0";
5815 }
5816
5817 default:
5818 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5819 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5820 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5821 if (GET_CODE (operands[2]) == CONST_INT
5822 && (INTVAL (operands[2]) == 128
5823 || (INTVAL (operands[2]) < 0
5824 && INTVAL (operands[2]) != -128)))
5825 {
5826 operands[2] = GEN_INT (-INTVAL (operands[2]));
5827 return "sub{l}\t{%2, %0|%0, %2}";
5828 }
5829 return "add{l}\t{%2, %0|%0, %2}";
5830 }
5831}
5832 [(set (attr "type")
5833 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5834 (const_string "incdec")
5835 (const_string "alu")))
5836 (set_attr "mode" "SI")])
5837
5838(define_expand "addhi3"
5839 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5840 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5841 (match_operand:HI 2 "general_operand" "")))
5842 (clobber (reg:CC FLAGS_REG))])]
5843 "TARGET_HIMODE_MATH"
5844 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5845
5846;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5847;; type optimizations enabled by define-splits. This is not important
5848;; for PII, and in fact harmful because of partial register stalls.
5849
5850(define_insn "*addhi_1_lea"
5851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5852 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5853 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "!TARGET_PARTIAL_REG_STALL
5856 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5857{
5858 switch (get_attr_type (insn))
5859 {
5860 case TYPE_LEA:
5861 return "#";
5862 case TYPE_INCDEC:
5863 if (operands[2] == const1_rtx)
5864 return "inc{w}\t%0";
5865 else
5866 {
5867 gcc_assert (operands[2] == constm1_rtx);
5868 return "dec{w}\t%0";
5869 }
5870
5871 default:
5872 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5874 if (GET_CODE (operands[2]) == CONST_INT
5875 && (INTVAL (operands[2]) == 128
5876 || (INTVAL (operands[2]) < 0
5877 && INTVAL (operands[2]) != -128)))
5878 {
5879 operands[2] = GEN_INT (-INTVAL (operands[2]));
5880 return "sub{w}\t{%2, %0|%0, %2}";
5881 }
5882 return "add{w}\t{%2, %0|%0, %2}";
5883 }
5884}
5885 [(set (attr "type")
5886 (if_then_else (eq_attr "alternative" "2")
5887 (const_string "lea")
5888 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5889 (const_string "incdec")
5890 (const_string "alu"))))
5891 (set_attr "mode" "HI,HI,SI")])
5892
5893(define_insn "*addhi_1"
5894 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5895 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896 (match_operand:HI 2 "general_operand" "ri,rm")))
5897 (clobber (reg:CC FLAGS_REG))]
5898 "TARGET_PARTIAL_REG_STALL
5899 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5900{
5901 switch (get_attr_type (insn))
5902 {
5903 case TYPE_INCDEC:
5904 if (operands[2] == const1_rtx)
5905 return "inc{w}\t%0";
5906 else
5907 {
5908 gcc_assert (operands[2] == constm1_rtx);
5909 return "dec{w}\t%0";
5910 }
5911
5912 default:
5913 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5915 if (GET_CODE (operands[2]) == CONST_INT
5916 && (INTVAL (operands[2]) == 128
5917 || (INTVAL (operands[2]) < 0
5918 && INTVAL (operands[2]) != -128)))
5919 {
5920 operands[2] = GEN_INT (-INTVAL (operands[2]));
5921 return "sub{w}\t{%2, %0|%0, %2}";
5922 }
5923 return "add{w}\t{%2, %0|%0, %2}";
5924 }
5925}
5926 [(set (attr "type")
5927 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5928 (const_string "incdec")
5929 (const_string "alu")))
5930 (set_attr "mode" "HI")])
5931
5932(define_insn "*addhi_2"
5933 [(set (reg FLAGS_REG)
5934 (compare
5935 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5936 (match_operand:HI 2 "general_operand" "rmni,rni"))
5937 (const_int 0)))
5938 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5939 (plus:HI (match_dup 1) (match_dup 2)))]
5940 "ix86_match_ccmode (insn, CCGOCmode)
5941 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5942{
5943 switch (get_attr_type (insn))
5944 {
5945 case TYPE_INCDEC:
5946 if (operands[2] == const1_rtx)
5947 return "inc{w}\t%0";
5948 else
5949 {
5950 gcc_assert (operands[2] == constm1_rtx);
5951 return "dec{w}\t%0";
5952 }
5953
5954 default:
5955 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5957 if (GET_CODE (operands[2]) == CONST_INT
5958 && (INTVAL (operands[2]) == 128
5959 || (INTVAL (operands[2]) < 0
5960 && INTVAL (operands[2]) != -128)))
5961 {
5962 operands[2] = GEN_INT (-INTVAL (operands[2]));
5963 return "sub{w}\t{%2, %0|%0, %2}";
5964 }
5965 return "add{w}\t{%2, %0|%0, %2}";
5966 }
5967}
5968 [(set (attr "type")
5969 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set_attr "mode" "HI")])
5973
5974(define_insn "*addhi_3"
5975 [(set (reg FLAGS_REG)
5976 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5977 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5978 (clobber (match_scratch:HI 0 "=r"))]
5979 "ix86_match_ccmode (insn, CCZmode)
5980 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5981{
5982 switch (get_attr_type (insn))
5983 {
5984 case TYPE_INCDEC:
5985 if (operands[2] == const1_rtx)
5986 return "inc{w}\t%0";
5987 else
5988 {
5989 gcc_assert (operands[2] == constm1_rtx);
5990 return "dec{w}\t%0";
5991 }
5992
5993 default:
5994 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5995 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5996 if (GET_CODE (operands[2]) == CONST_INT
5997 && (INTVAL (operands[2]) == 128
5998 || (INTVAL (operands[2]) < 0
5999 && INTVAL (operands[2]) != -128)))
6000 {
6001 operands[2] = GEN_INT (-INTVAL (operands[2]));
6002 return "sub{w}\t{%2, %0|%0, %2}";
6003 }
6004 return "add{w}\t{%2, %0|%0, %2}";
6005 }
6006}
6007 [(set (attr "type")
6008 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6009 (const_string "incdec")
6010 (const_string "alu")))
6011 (set_attr "mode" "HI")])
6012
6013; See comments above addsi_4 for details.
6014(define_insn "*addhi_4"
6015 [(set (reg FLAGS_REG)
6016 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6017 (match_operand:HI 2 "const_int_operand" "n")))
6018 (clobber (match_scratch:HI 0 "=rm"))]
6019 "ix86_match_ccmode (insn, CCGCmode)
6020 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6021{
6022 switch (get_attr_type (insn))
6023 {
6024 case TYPE_INCDEC:
6025 if (operands[2] == constm1_rtx)
6026 return "inc{w}\t%0";
6027 else
6028 {
6029 gcc_assert (operands[2] == const1_rtx);
6030 return "dec{w}\t%0";
6031 }
6032
6033 default:
6034 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6037 if ((INTVAL (operands[2]) == -128
6038 || (INTVAL (operands[2]) > 0
6039 && INTVAL (operands[2]) != 128)))
6040 return "sub{w}\t{%2, %0|%0, %2}";
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "add{w}\t{%2, %0|%0, %2}";
6043 }
6044}
6045 [(set (attr "type")
6046 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047 (const_string "incdec")
6048 (const_string "alu")))
6049 (set_attr "mode" "SI")])
6050
6051
6052(define_insn "*addhi_5"
6053 [(set (reg FLAGS_REG)
6054 (compare
6055 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6056 (match_operand:HI 2 "general_operand" "rmni"))
6057 (const_int 0)))
6058 (clobber (match_scratch:HI 0 "=r"))]
6059 "ix86_match_ccmode (insn, CCGOCmode)
6060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6061{
6062 switch (get_attr_type (insn))
6063 {
6064 case TYPE_INCDEC:
6065 if (operands[2] == const1_rtx)
6066 return "inc{w}\t%0";
6067 else
6068 {
6069 gcc_assert (operands[2] == constm1_rtx);
6070 return "dec{w}\t%0";
6071 }
6072
6073 default:
6074 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6075 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6076 if (GET_CODE (operands[2]) == CONST_INT
6077 && (INTVAL (operands[2]) == 128
6078 || (INTVAL (operands[2]) < 0
6079 && INTVAL (operands[2]) != -128)))
6080 {
6081 operands[2] = GEN_INT (-INTVAL (operands[2]));
6082 return "sub{w}\t{%2, %0|%0, %2}";
6083 }
6084 return "add{w}\t{%2, %0|%0, %2}";
6085 }
6086}
6087 [(set (attr "type")
6088 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6089 (const_string "incdec")
6090 (const_string "alu")))
6091 (set_attr "mode" "HI")])
6092
6093(define_expand "addqi3"
6094 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6095 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6096 (match_operand:QI 2 "general_operand" "")))
6097 (clobber (reg:CC FLAGS_REG))])]
6098 "TARGET_QIMODE_MATH"
6099 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6100
6101;; %%% Potential partial reg stall on alternative 2. What to do?
6102(define_insn "*addqi_1_lea"
6103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6104 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6105 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6106 (clobber (reg:CC FLAGS_REG))]
6107 "!TARGET_PARTIAL_REG_STALL
6108 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6109{
6110 int widen = (which_alternative == 2);
6111 switch (get_attr_type (insn))
6112 {
6113 case TYPE_LEA:
6114 return "#";
6115 case TYPE_INCDEC:
6116 if (operands[2] == const1_rtx)
6117 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6118 else
6119 {
6120 gcc_assert (operands[2] == constm1_rtx);
6121 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6122 }
6123
6124 default:
6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if (GET_CODE (operands[2]) == CONST_INT
6128 && (INTVAL (operands[2]) == 128
6129 || (INTVAL (operands[2]) < 0
6130 && INTVAL (operands[2]) != -128)))
6131 {
6132 operands[2] = GEN_INT (-INTVAL (operands[2]));
6133 if (widen)
6134 return "sub{l}\t{%2, %k0|%k0, %2}";
6135 else
6136 return "sub{b}\t{%2, %0|%0, %2}";
6137 }
6138 if (widen)
6139 return "add{l}\t{%k2, %k0|%k0, %k2}";
6140 else
6141 return "add{b}\t{%2, %0|%0, %2}";
6142 }
6143}
6144 [(set (attr "type")
6145 (if_then_else (eq_attr "alternative" "3")
6146 (const_string "lea")
6147 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu"))))
6150 (set_attr "mode" "QI,QI,SI,SI")])
6151
6152(define_insn "*addqi_1"
6153 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6154 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6155 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6156 (clobber (reg:CC FLAGS_REG))]
6157 "TARGET_PARTIAL_REG_STALL
6158 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6159{
6160 int widen = (which_alternative == 2);
6161 switch (get_attr_type (insn))
6162 {
6163 case TYPE_INCDEC:
6164 if (operands[2] == const1_rtx)
6165 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6166 else
6167 {
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6170 }
6171
6172 default:
6173 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6174 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6175 if (GET_CODE (operands[2]) == CONST_INT
6176 && (INTVAL (operands[2]) == 128
6177 || (INTVAL (operands[2]) < 0
6178 && INTVAL (operands[2]) != -128)))
6179 {
6180 operands[2] = GEN_INT (-INTVAL (operands[2]));
6181 if (widen)
6182 return "sub{l}\t{%2, %k0|%k0, %2}";
6183 else
6184 return "sub{b}\t{%2, %0|%0, %2}";
6185 }
6186 if (widen)
6187 return "add{l}\t{%k2, %k0|%k0, %k2}";
6188 else
6189 return "add{b}\t{%2, %0|%0, %2}";
6190 }
6191}
6192 [(set (attr "type")
6193 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6194 (const_string "incdec")
6195 (const_string "alu")))
6196 (set_attr "mode" "QI,QI,SI")])
6197
6198(define_insn "*addqi_1_slp"
6199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6200 (plus:QI (match_dup 0)
6201 (match_operand:QI 1 "general_operand" "qn,qnm")))
6202 (clobber (reg:CC FLAGS_REG))]
6203 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6205{
6206 switch (get_attr_type (insn))
6207 {
6208 case TYPE_INCDEC:
6209 if (operands[1] == const1_rtx)
6210 return "inc{b}\t%0";
6211 else
6212 {
6213 gcc_assert (operands[1] == constm1_rtx);
6214 return "dec{b}\t%0";
6215 }
6216
6217 default:
6218 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6219 if (GET_CODE (operands[1]) == CONST_INT
6220 && INTVAL (operands[1]) < 0)
6221 {
6222 operands[1] = GEN_INT (-INTVAL (operands[1]));
6223 return "sub{b}\t{%1, %0|%0, %1}";
6224 }
6225 return "add{b}\t{%1, %0|%0, %1}";
6226 }
6227}
6228 [(set (attr "type")
6229 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6230 (const_string "incdec")
6231 (const_string "alu1")))
6232 (set (attr "memory")
6233 (if_then_else (match_operand 1 "memory_operand" "")
6234 (const_string "load")
6235 (const_string "none")))
6236 (set_attr "mode" "QI")])
6237
6238(define_insn "*addqi_2"
6239 [(set (reg FLAGS_REG)
6240 (compare
6241 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6242 (match_operand:QI 2 "general_operand" "qmni,qni"))
6243 (const_int 0)))
6244 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6245 (plus:QI (match_dup 1) (match_dup 2)))]
6246 "ix86_match_ccmode (insn, CCGOCmode)
6247 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6248{
6249 switch (get_attr_type (insn))
6250 {
6251 case TYPE_INCDEC:
6252 if (operands[2] == const1_rtx)
6253 return "inc{b}\t%0";
6254 else
6255 {
6256 gcc_assert (operands[2] == constm1_rtx
6257 || (GET_CODE (operands[2]) == CONST_INT
6258 && INTVAL (operands[2]) == 255));
6259 return "dec{b}\t%0";
6260 }
6261
6262 default:
6263 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6264 if (GET_CODE (operands[2]) == CONST_INT
6265 && INTVAL (operands[2]) < 0)
6266 {
6267 operands[2] = GEN_INT (-INTVAL (operands[2]));
6268 return "sub{b}\t{%2, %0|%0, %2}";
6269 }
6270 return "add{b}\t{%2, %0|%0, %2}";
6271 }
6272}
6273 [(set (attr "type")
6274 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6275 (const_string "incdec")
6276 (const_string "alu")))
6277 (set_attr "mode" "QI")])
6278
6279(define_insn "*addqi_3"
6280 [(set (reg FLAGS_REG)
6281 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6282 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6283 (clobber (match_scratch:QI 0 "=q"))]
6284 "ix86_match_ccmode (insn, CCZmode)
6285 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6286{
6287 switch (get_attr_type (insn))
6288 {
6289 case TYPE_INCDEC:
6290 if (operands[2] == const1_rtx)
6291 return "inc{b}\t%0";
6292 else
6293 {
6294 gcc_assert (operands[2] == constm1_rtx
6295 || (GET_CODE (operands[2]) == CONST_INT
6296 && INTVAL (operands[2]) == 255));
6297 return "dec{b}\t%0";
6298 }
6299
6300 default:
6301 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6302 if (GET_CODE (operands[2]) == CONST_INT
6303 && INTVAL (operands[2]) < 0)
6304 {
6305 operands[2] = GEN_INT (-INTVAL (operands[2]));
6306 return "sub{b}\t{%2, %0|%0, %2}";
6307 }
6308 return "add{b}\t{%2, %0|%0, %2}";
6309 }
6310}
6311 [(set (attr "type")
6312 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6313 (const_string "incdec")
6314 (const_string "alu")))
6315 (set_attr "mode" "QI")])
6316
6317; See comments above addsi_4 for details.
6318(define_insn "*addqi_4"
6319 [(set (reg FLAGS_REG)
6320 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6321 (match_operand:QI 2 "const_int_operand" "n")))
6322 (clobber (match_scratch:QI 0 "=qm"))]
6323 "ix86_match_ccmode (insn, CCGCmode)
6324 && (INTVAL (operands[2]) & 0xff) != 0x80"
6325{
6326 switch (get_attr_type (insn))
6327 {
6328 case TYPE_INCDEC:
6329 if (operands[2] == constm1_rtx
6330 || (GET_CODE (operands[2]) == CONST_INT
6331 && INTVAL (operands[2]) == 255))
6332 return "inc{b}\t%0";
6333 else
6334 {
6335 gcc_assert (operands[2] == const1_rtx);
6336 return "dec{b}\t%0";
6337 }
6338
6339 default:
6340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6341 if (INTVAL (operands[2]) < 0)
6342 {
6343 operands[2] = GEN_INT (-INTVAL (operands[2]));
6344 return "add{b}\t{%2, %0|%0, %2}";
6345 }
6346 return "sub{b}\t{%2, %0|%0, %2}";
6347 }
6348}
6349 [(set (attr "type")
6350 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6351 (const_string "incdec")
6352 (const_string "alu")))
6353 (set_attr "mode" "QI")])
6354
6355
6356(define_insn "*addqi_5"
6357 [(set (reg FLAGS_REG)
6358 (compare
6359 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6360 (match_operand:QI 2 "general_operand" "qmni"))
6361 (const_int 0)))
6362 (clobber (match_scratch:QI 0 "=q"))]
6363 "ix86_match_ccmode (insn, CCGOCmode)
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
6372 {
6373 gcc_assert (operands[2] == constm1_rtx
6374 || (GET_CODE (operands[2]) == CONST_INT
6375 && INTVAL (operands[2]) == 255));
6376 return "dec{b}\t%0";
6377 }
6378
6379 default:
6380 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6381 if (GET_CODE (operands[2]) == CONST_INT
6382 && INTVAL (operands[2]) < 0)
6383 {
6384 operands[2] = GEN_INT (-INTVAL (operands[2]));
6385 return "sub{b}\t{%2, %0|%0, %2}";
6386 }
6387 return "add{b}\t{%2, %0|%0, %2}";
6388 }
6389}
6390 [(set (attr "type")
6391 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392 (const_string "incdec")
6393 (const_string "alu")))
6394 (set_attr "mode" "QI")])
6395
6396
6397(define_insn "addqi_ext_1"
6398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399 (const_int 8)
6400 (const_int 8))
6401 (plus:SI
6402 (zero_extract:SI
6403 (match_operand 1 "ext_register_operand" "0")
6404 (const_int 8)
6405 (const_int 8))
6406 (match_operand:QI 2 "general_operand" "Qmn")))
6407 (clobber (reg:CC FLAGS_REG))]
6408 "!TARGET_64BIT"
6409{
6410 switch (get_attr_type (insn))
6411 {
6412 case TYPE_INCDEC:
6413 if (operands[2] == const1_rtx)
6414 return "inc{b}\t%h0";
6415 else
6416 {
6417 gcc_assert (operands[2] == constm1_rtx
6418 || (GET_CODE (operands[2]) == CONST_INT
6419 && INTVAL (operands[2]) == 255));
6420 return "dec{b}\t%h0";
6421 }
6422
6423 default:
6424 return "add{b}\t{%2, %h0|%h0, %2}";
6425 }
6426}
6427 [(set (attr "type")
6428 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "QI")])
6432
6433(define_insn "*addqi_ext_1_rex64"
6434 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435 (const_int 8)
6436 (const_int 8))
6437 (plus:SI
6438 (zero_extract:SI
6439 (match_operand 1 "ext_register_operand" "0")
6440 (const_int 8)
6441 (const_int 8))
6442 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6443 (clobber (reg:CC FLAGS_REG))]
6444 "TARGET_64BIT"
6445{
6446 switch (get_attr_type (insn))
6447 {
6448 case TYPE_INCDEC:
6449 if (operands[2] == const1_rtx)
6450 return "inc{b}\t%h0";
6451 else
6452 {
6453 gcc_assert (operands[2] == constm1_rtx
6454 || (GET_CODE (operands[2]) == CONST_INT
6455 && INTVAL (operands[2]) == 255));
6456 return "dec{b}\t%h0";
6457 }
6458
6459 default:
6460 return "add{b}\t{%2, %h0|%h0, %2}";
6461 }
6462}
6463 [(set (attr "type")
6464 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465 (const_string "incdec")
6466 (const_string "alu")))
6467 (set_attr "mode" "QI")])
6468
6469(define_insn "*addqi_ext_2"
6470 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6471 (const_int 8)
6472 (const_int 8))
6473 (plus:SI
6474 (zero_extract:SI
6475 (match_operand 1 "ext_register_operand" "%0")
6476 (const_int 8)
6477 (const_int 8))
6478 (zero_extract:SI
6479 (match_operand 2 "ext_register_operand" "Q")
6480 (const_int 8)
6481 (const_int 8))))
6482 (clobber (reg:CC FLAGS_REG))]
6483 ""
6484 "add{b}\t{%h2, %h0|%h0, %h2}"
6485 [(set_attr "type" "alu")
6486 (set_attr "mode" "QI")])
6487
6488;; The patterns that match these are at the end of this file.
6489
6490(define_expand "addxf3"
6491 [(set (match_operand:XF 0 "register_operand" "")
6492 (plus:XF (match_operand:XF 1 "register_operand" "")
6493 (match_operand:XF 2 "register_operand" "")))]
6494 "TARGET_80387"
6495 "")
6496
6497(define_expand "adddf3"
6498 [(set (match_operand:DF 0 "register_operand" "")
6499 (plus:DF (match_operand:DF 1 "register_operand" "")
6500 (match_operand:DF 2 "nonimmediate_operand" "")))]
6501 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6502 "")
6503
6504(define_expand "addsf3"
6505 [(set (match_operand:SF 0 "register_operand" "")
6506 (plus:SF (match_operand:SF 1 "register_operand" "")
6507 (match_operand:SF 2 "nonimmediate_operand" "")))]
6508 "TARGET_80387 || TARGET_SSE_MATH"
6509 "")
6510
6511;; Subtract instructions
6512
6513;; %%% splits for subditi3
6514
6515(define_expand "subti3"
6516 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6517 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6518 (match_operand:TI 2 "x86_64_general_operand" "")))
6519 (clobber (reg:CC FLAGS_REG))])]
6520 "TARGET_64BIT"
6521 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6522
6523(define_insn "*subti3_1"
6524 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6525 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6526 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6527 (clobber (reg:CC FLAGS_REG))]
6528 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6529 "#")
6530
6531(define_split
6532 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6533 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6534 (match_operand:TI 2 "x86_64_general_operand" "")))
6535 (clobber (reg:CC FLAGS_REG))]
6536 "TARGET_64BIT && reload_completed"
6537 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6538 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6539 (parallel [(set (match_dup 3)
6540 (minus:DI (match_dup 4)
6541 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6542 (match_dup 5))))
6543 (clobber (reg:CC FLAGS_REG))])]
6544 "split_ti (operands+0, 1, operands+0, operands+3);
6545 split_ti (operands+1, 1, operands+1, operands+4);
6546 split_ti (operands+2, 1, operands+2, operands+5);")
6547
6548;; %%% splits for subsidi3
6549
6550(define_expand "subdi3"
6551 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6552 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6553 (match_operand:DI 2 "x86_64_general_operand" "")))
6554 (clobber (reg:CC FLAGS_REG))])]
6555 ""
6556 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6557
6558(define_insn "*subdi3_1"
6559 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6560 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561 (match_operand:DI 2 "general_operand" "roiF,riF")))
6562 (clobber (reg:CC FLAGS_REG))]
6563 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6564 "#")
6565
6566(define_split
6567 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6569 (match_operand:DI 2 "general_operand" "")))
6570 (clobber (reg:CC FLAGS_REG))]
6571 "!TARGET_64BIT && reload_completed"
6572 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6573 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6574 (parallel [(set (match_dup 3)
6575 (minus:SI (match_dup 4)
6576 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6577 (match_dup 5))))
6578 (clobber (reg:CC FLAGS_REG))])]
6579 "split_di (operands+0, 1, operands+0, operands+3);
6580 split_di (operands+1, 1, operands+1, operands+4);
6581 split_di (operands+2, 1, operands+2, operands+5);")
6582
6583(define_insn "subdi3_carry_rex64"
6584 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6585 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6586 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6587 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590 "sbb{q}\t{%2, %0|%0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "pent_pair" "pu")
6593 (set_attr "mode" "DI")])
6594
6595(define_insn "*subdi_1_rex64"
6596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6597 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6599 (clobber (reg:CC FLAGS_REG))]
6600 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6601 "sub{q}\t{%2, %0|%0, %2}"
6602 [(set_attr "type" "alu")
6603 (set_attr "mode" "DI")])
6604
6605(define_insn "*subdi_2_rex64"
6606 [(set (reg FLAGS_REG)
6607 (compare
6608 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6610 (const_int 0)))
6611 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612 (minus:DI (match_dup 1) (match_dup 2)))]
6613 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6614 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6615 "sub{q}\t{%2, %0|%0, %2}"
6616 [(set_attr "type" "alu")
6617 (set_attr "mode" "DI")])
6618
6619(define_insn "*subdi_3_rex63"
6620 [(set (reg FLAGS_REG)
6621 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6623 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624 (minus:DI (match_dup 1) (match_dup 2)))]
6625 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6626 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6627 "sub{q}\t{%2, %0|%0, %2}"
6628 [(set_attr "type" "alu")
6629 (set_attr "mode" "DI")])
6630
6631(define_insn "subqi3_carry"
6632 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6633 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6634 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6635 (match_operand:QI 2 "general_operand" "qi,qm"))))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6638 "sbb{b}\t{%2, %0|%0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "pent_pair" "pu")
6641 (set_attr "mode" "QI")])
6642
6643(define_insn "subhi3_carry"
6644 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6645 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6646 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6647 (match_operand:HI 2 "general_operand" "ri,rm"))))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6650 "sbb{w}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "pent_pair" "pu")
6653 (set_attr "mode" "HI")])
6654
6655(define_insn "subsi3_carry"
6656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6657 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6658 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6659 (match_operand:SI 2 "general_operand" "ri,rm"))))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6662 "sbb{l}\t{%2, %0|%0, %2}"
6663 [(set_attr "type" "alu")
6664 (set_attr "pent_pair" "pu")
6665 (set_attr "mode" "SI")])
6666
6667(define_insn "subsi3_carry_zext"
6668 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6669 (zero_extend:DI
6670 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6671 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6672 (match_operand:SI 2 "general_operand" "ri,rm")))))
6673 (clobber (reg:CC FLAGS_REG))]
6674 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675 "sbb{l}\t{%2, %k0|%k0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "pent_pair" "pu")
6678 (set_attr "mode" "SI")])
6679
6680(define_expand "subsi3"
6681 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6682 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6683 (match_operand:SI 2 "general_operand" "")))
6684 (clobber (reg:CC FLAGS_REG))])]
6685 ""
6686 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6687
6688(define_insn "*subsi_1"
6689 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6691 (match_operand:SI 2 "general_operand" "ri,rm")))
6692 (clobber (reg:CC FLAGS_REG))]
6693 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6694 "sub{l}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "SI")])
6697
6698(define_insn "*subsi_1_zext"
6699 [(set (match_operand:DI 0 "register_operand" "=r")
6700 (zero_extend:DI
6701 (minus:SI (match_operand:SI 1 "register_operand" "0")
6702 (match_operand:SI 2 "general_operand" "rim"))))
6703 (clobber (reg:CC FLAGS_REG))]
6704 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705 "sub{l}\t{%2, %k0|%k0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "mode" "SI")])
6708
6709(define_insn "*subsi_2"
6710 [(set (reg FLAGS_REG)
6711 (compare
6712 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6713 (match_operand:SI 2 "general_operand" "ri,rm"))
6714 (const_int 0)))
6715 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6716 (minus:SI (match_dup 1) (match_dup 2)))]
6717 "ix86_match_ccmode (insn, CCGOCmode)
6718 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719 "sub{l}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "alu")
6721 (set_attr "mode" "SI")])
6722
6723(define_insn "*subsi_2_zext"
6724 [(set (reg FLAGS_REG)
6725 (compare
6726 (minus:SI (match_operand:SI 1 "register_operand" "0")
6727 (match_operand:SI 2 "general_operand" "rim"))
6728 (const_int 0)))
6729 (set (match_operand:DI 0 "register_operand" "=r")
6730 (zero_extend:DI
6731 (minus:SI (match_dup 1)
6732 (match_dup 2))))]
6733 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6734 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6738
6739(define_insn "*subsi_3"
6740 [(set (reg FLAGS_REG)
6741 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6742 (match_operand:SI 2 "general_operand" "ri,rm")))
6743 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6744 (minus:SI (match_dup 1) (match_dup 2)))]
6745 "ix86_match_ccmode (insn, CCmode)
6746 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747 "sub{l}\t{%2, %0|%0, %2}"
6748 [(set_attr "type" "alu")
6749 (set_attr "mode" "SI")])
6750
6751(define_insn "*subsi_3_zext"
6752 [(set (reg FLAGS_REG)
6753 (compare (match_operand:SI 1 "register_operand" "0")
6754 (match_operand:SI 2 "general_operand" "rim")))
6755 (set (match_operand:DI 0 "register_operand" "=r")
6756 (zero_extend:DI
6757 (minus:SI (match_dup 1)
6758 (match_dup 2))))]
6759 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6760 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6761 "sub{l}\t{%2, %1|%1, %2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "mode" "DI")])
6764
6765(define_expand "subhi3"
6766 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6767 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6768 (match_operand:HI 2 "general_operand" "")))
6769 (clobber (reg:CC FLAGS_REG))])]
6770 "TARGET_HIMODE_MATH"
6771 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6772
6773(define_insn "*subhi_1"
6774 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6775 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6776 (match_operand:HI 2 "general_operand" "ri,rm")))
6777 (clobber (reg:CC FLAGS_REG))]
6778 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6779 "sub{w}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "HI")])
6782
6783(define_insn "*subhi_2"
6784 [(set (reg FLAGS_REG)
6785 (compare
6786 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6787 (match_operand:HI 2 "general_operand" "ri,rm"))
6788 (const_int 0)))
6789 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790 (minus:HI (match_dup 1) (match_dup 2)))]
6791 "ix86_match_ccmode (insn, CCGOCmode)
6792 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6793 "sub{w}\t{%2, %0|%0, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "mode" "HI")])
6796
6797(define_insn "*subhi_3"
6798 [(set (reg FLAGS_REG)
6799 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6800 (match_operand:HI 2 "general_operand" "ri,rm")))
6801 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6802 (minus:HI (match_dup 1) (match_dup 2)))]
6803 "ix86_match_ccmode (insn, CCmode)
6804 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6805 "sub{w}\t{%2, %0|%0, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "HI")])
6808
6809(define_expand "subqi3"
6810 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6811 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6812 (match_operand:QI 2 "general_operand" "")))
6813 (clobber (reg:CC FLAGS_REG))])]
6814 "TARGET_QIMODE_MATH"
6815 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6816
6817(define_insn "*subqi_1"
6818 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6819 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6820 (match_operand:QI 2 "general_operand" "qn,qmn")))
6821 (clobber (reg:CC FLAGS_REG))]
6822 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6823 "sub{b}\t{%2, %0|%0, %2}"
6824 [(set_attr "type" "alu")
6825 (set_attr "mode" "QI")])
6826
6827(define_insn "*subqi_1_slp"
6828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6829 (minus:QI (match_dup 0)
6830 (match_operand:QI 1 "general_operand" "qn,qmn")))
6831 (clobber (reg:CC FLAGS_REG))]
6832 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6834 "sub{b}\t{%1, %0|%0, %1}"
6835 [(set_attr "type" "alu1")
6836 (set_attr "mode" "QI")])
6837
6838(define_insn "*subqi_2"
6839 [(set (reg FLAGS_REG)
6840 (compare
6841 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6842 (match_operand:QI 2 "general_operand" "qi,qm"))
6843 (const_int 0)))
6844 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6845 (minus:HI (match_dup 1) (match_dup 2)))]
6846 "ix86_match_ccmode (insn, CCGOCmode)
6847 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6848 "sub{b}\t{%2, %0|%0, %2}"
6849 [(set_attr "type" "alu")
6850 (set_attr "mode" "QI")])
6851
6852(define_insn "*subqi_3"
6853 [(set (reg FLAGS_REG)
6854 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855 (match_operand:QI 2 "general_operand" "qi,qm")))
6856 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6857 (minus:HI (match_dup 1) (match_dup 2)))]
6858 "ix86_match_ccmode (insn, CCmode)
6859 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6860 "sub{b}\t{%2, %0|%0, %2}"
6861 [(set_attr "type" "alu")
6862 (set_attr "mode" "QI")])
6863
6864;; The patterns that match these are at the end of this file.
6865
6866(define_expand "subxf3"
6867 [(set (match_operand:XF 0 "register_operand" "")
6868 (minus:XF (match_operand:XF 1 "register_operand" "")
6869 (match_operand:XF 2 "register_operand" "")))]
6870 "TARGET_80387"
6871 "")
6872
6873(define_expand "subdf3"
6874 [(set (match_operand:DF 0 "register_operand" "")
6875 (minus:DF (match_operand:DF 1 "register_operand" "")
6876 (match_operand:DF 2 "nonimmediate_operand" "")))]
6877 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6878 "")
6879
6880(define_expand "subsf3"
6881 [(set (match_operand:SF 0 "register_operand" "")
6882 (minus:SF (match_operand:SF 1 "register_operand" "")
6883 (match_operand:SF 2 "nonimmediate_operand" "")))]
6884 "TARGET_80387 || TARGET_SSE_MATH"
6885 "")
6886
6887;; Multiply instructions
6888
6889(define_expand "muldi3"
6890 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6891 (mult:DI (match_operand:DI 1 "register_operand" "")
6892 (match_operand:DI 2 "x86_64_general_operand" "")))
6893 (clobber (reg:CC FLAGS_REG))])]
6894 "TARGET_64BIT"
6895 "")
6896
6897;; On AMDFAM10
6898;; IMUL reg64, reg64, imm8 Direct
6899;; IMUL reg64, mem64, imm8 VectorPath
6900;; IMUL reg64, reg64, imm32 Direct
6901;; IMUL reg64, mem64, imm32 VectorPath
6902;; IMUL reg64, reg64 Direct
6903;; IMUL reg64, mem64 Direct
6904
6863(define_insn "*muldi3_1_rex64"
6864 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6865 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6866 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6867 (clobber (reg:CC FLAGS_REG))]
6868 "TARGET_64BIT
6869 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6870 "@
6871 imul{q}\t{%2, %1, %0|%0, %1, %2}
6872 imul{q}\t{%2, %1, %0|%0, %1, %2}
6873 imul{q}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "imul")
6875 (set_attr "prefix_0f" "0,0,1")
6876 (set (attr "athlon_decode")
6877 (cond [(eq_attr "cpu" "athlon")
6878 (const_string "vector")
6879 (eq_attr "alternative" "1")
6880 (const_string "vector")
6881 (and (eq_attr "alternative" "2")
6882 (match_operand 1 "memory_operand" ""))
6883 (const_string "vector")]
6884 (const_string "direct")))
6905(define_insn "*muldi3_1_rex64"
6906 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6907 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6908 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6909 (clobber (reg:CC FLAGS_REG))]
6910 "TARGET_64BIT
6911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6912 "@
6913 imul{q}\t{%2, %1, %0|%0, %1, %2}
6914 imul{q}\t{%2, %1, %0|%0, %1, %2}
6915 imul{q}\t{%2, %0|%0, %2}"
6916 [(set_attr "type" "imul")
6917 (set_attr "prefix_0f" "0,0,1")
6918 (set (attr "athlon_decode")
6919 (cond [(eq_attr "cpu" "athlon")
6920 (const_string "vector")
6921 (eq_attr "alternative" "1")
6922 (const_string "vector")
6923 (and (eq_attr "alternative" "2")
6924 (match_operand 1 "memory_operand" ""))
6925 (const_string "vector")]
6926 (const_string "direct")))
6927 (set (attr "amdfam10_decode")
6928 (cond [(and (eq_attr "alternative" "0,1")
6929 (match_operand 1 "memory_operand" ""))
6930 (const_string "vector")]
6931 (const_string "direct")))
6885 (set_attr "mode" "DI")])
6886
6887(define_expand "mulsi3"
6888 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6889 (mult:SI (match_operand:SI 1 "register_operand" "")
6890 (match_operand:SI 2 "general_operand" "")))
6891 (clobber (reg:CC FLAGS_REG))])]
6892 ""
6893 "")
6894
6932 (set_attr "mode" "DI")])
6933
6934(define_expand "mulsi3"
6935 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6936 (mult:SI (match_operand:SI 1 "register_operand" "")
6937 (match_operand:SI 2 "general_operand" "")))
6938 (clobber (reg:CC FLAGS_REG))])]
6939 ""
6940 "")
6941
6942;; On AMDFAM10
6943;; IMUL reg32, reg32, imm8 Direct
6944;; IMUL reg32, mem32, imm8 VectorPath
6945;; IMUL reg32, reg32, imm32 Direct
6946;; IMUL reg32, mem32, imm32 VectorPath
6947;; IMUL reg32, reg32 Direct
6948;; IMUL reg32, mem32 Direct
6949
6895(define_insn "*mulsi3_1"
6896 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6897 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6898 (match_operand:SI 2 "general_operand" "K,i,mr")))
6899 (clobber (reg:CC FLAGS_REG))]
6900 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6901 "@
6902 imul{l}\t{%2, %1, %0|%0, %1, %2}
6903 imul{l}\t{%2, %1, %0|%0, %1, %2}
6904 imul{l}\t{%2, %0|%0, %2}"
6905 [(set_attr "type" "imul")
6906 (set_attr "prefix_0f" "0,0,1")
6907 (set (attr "athlon_decode")
6908 (cond [(eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (eq_attr "alternative" "1")
6911 (const_string "vector")
6912 (and (eq_attr "alternative" "2")
6913 (match_operand 1 "memory_operand" ""))
6914 (const_string "vector")]
6915 (const_string "direct")))
6950(define_insn "*mulsi3_1"
6951 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6952 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6953 (match_operand:SI 2 "general_operand" "K,i,mr")))
6954 (clobber (reg:CC FLAGS_REG))]
6955 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6956 "@
6957 imul{l}\t{%2, %1, %0|%0, %1, %2}
6958 imul{l}\t{%2, %1, %0|%0, %1, %2}
6959 imul{l}\t{%2, %0|%0, %2}"
6960 [(set_attr "type" "imul")
6961 (set_attr "prefix_0f" "0,0,1")
6962 (set (attr "athlon_decode")
6963 (cond [(eq_attr "cpu" "athlon")
6964 (const_string "vector")
6965 (eq_attr "alternative" "1")
6966 (const_string "vector")
6967 (and (eq_attr "alternative" "2")
6968 (match_operand 1 "memory_operand" ""))
6969 (const_string "vector")]
6970 (const_string "direct")))
6971 (set (attr "amdfam10_decode")
6972 (cond [(and (eq_attr "alternative" "0,1")
6973 (match_operand 1 "memory_operand" ""))
6974 (const_string "vector")]
6975 (const_string "direct")))
6916 (set_attr "mode" "SI")])
6917
6918(define_insn "*mulsi3_1_zext"
6919 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6920 (zero_extend:DI
6921 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6922 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6923 (clobber (reg:CC FLAGS_REG))]
6924 "TARGET_64BIT
6925 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6926 "@
6927 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6928 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6929 imul{l}\t{%2, %k0|%k0, %2}"
6930 [(set_attr "type" "imul")
6931 (set_attr "prefix_0f" "0,0,1")
6932 (set (attr "athlon_decode")
6933 (cond [(eq_attr "cpu" "athlon")
6934 (const_string "vector")
6935 (eq_attr "alternative" "1")
6936 (const_string "vector")
6937 (and (eq_attr "alternative" "2")
6938 (match_operand 1 "memory_operand" ""))
6939 (const_string "vector")]
6940 (const_string "direct")))
6976 (set_attr "mode" "SI")])
6977
6978(define_insn "*mulsi3_1_zext"
6979 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6980 (zero_extend:DI
6981 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6982 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6983 (clobber (reg:CC FLAGS_REG))]
6984 "TARGET_64BIT
6985 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6986 "@
6987 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6988 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6989 imul{l}\t{%2, %k0|%k0, %2}"
6990 [(set_attr "type" "imul")
6991 (set_attr "prefix_0f" "0,0,1")
6992 (set (attr "athlon_decode")
6993 (cond [(eq_attr "cpu" "athlon")
6994 (const_string "vector")
6995 (eq_attr "alternative" "1")
6996 (const_string "vector")
6997 (and (eq_attr "alternative" "2")
6998 (match_operand 1 "memory_operand" ""))
6999 (const_string "vector")]
7000 (const_string "direct")))
7001 (set (attr "amdfam10_decode")
7002 (cond [(and (eq_attr "alternative" "0,1")
7003 (match_operand 1 "memory_operand" ""))
7004 (const_string "vector")]
7005 (const_string "direct")))
6941 (set_attr "mode" "SI")])
6942
6943(define_expand "mulhi3"
6944 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6945 (mult:HI (match_operand:HI 1 "register_operand" "")
6946 (match_operand:HI 2 "general_operand" "")))
6947 (clobber (reg:CC FLAGS_REG))])]
6948 "TARGET_HIMODE_MATH"
6949 "")
6950
7006 (set_attr "mode" "SI")])
7007
7008(define_expand "mulhi3"
7009 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7010 (mult:HI (match_operand:HI 1 "register_operand" "")
7011 (match_operand:HI 2 "general_operand" "")))
7012 (clobber (reg:CC FLAGS_REG))])]
7013 "TARGET_HIMODE_MATH"
7014 "")
7015
7016;; On AMDFAM10
7017;; IMUL reg16, reg16, imm8 VectorPath
7018;; IMUL reg16, mem16, imm8 VectorPath
7019;; IMUL reg16, reg16, imm16 VectorPath
7020;; IMUL reg16, mem16, imm16 VectorPath
7021;; IMUL reg16, reg16 Direct
7022;; IMUL reg16, mem16 Direct
6951(define_insn "*mulhi3_1"
6952 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6953 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6954 (match_operand:HI 2 "general_operand" "K,i,mr")))
6955 (clobber (reg:CC FLAGS_REG))]
6956 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6957 "@
6958 imul{w}\t{%2, %1, %0|%0, %1, %2}
6959 imul{w}\t{%2, %1, %0|%0, %1, %2}
6960 imul{w}\t{%2, %0|%0, %2}"
6961 [(set_attr "type" "imul")
6962 (set_attr "prefix_0f" "0,0,1")
6963 (set (attr "athlon_decode")
6964 (cond [(eq_attr "cpu" "athlon")
6965 (const_string "vector")
6966 (eq_attr "alternative" "1,2")
6967 (const_string "vector")]
6968 (const_string "direct")))
7023(define_insn "*mulhi3_1"
7024 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7025 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7026 (match_operand:HI 2 "general_operand" "K,i,mr")))
7027 (clobber (reg:CC FLAGS_REG))]
7028 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7029 "@
7030 imul{w}\t{%2, %1, %0|%0, %1, %2}
7031 imul{w}\t{%2, %1, %0|%0, %1, %2}
7032 imul{w}\t{%2, %0|%0, %2}"
7033 [(set_attr "type" "imul")
7034 (set_attr "prefix_0f" "0,0,1")
7035 (set (attr "athlon_decode")
7036 (cond [(eq_attr "cpu" "athlon")
7037 (const_string "vector")
7038 (eq_attr "alternative" "1,2")
7039 (const_string "vector")]
7040 (const_string "direct")))
7041 (set (attr "amdfam10_decode")
7042 (cond [(eq_attr "alternative" "0,1")
7043 (const_string "vector")]
7044 (const_string "direct")))
6969 (set_attr "mode" "HI")])
6970
6971(define_expand "mulqi3"
6972 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6973 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6974 (match_operand:QI 2 "register_operand" "")))
6975 (clobber (reg:CC FLAGS_REG))])]
6976 "TARGET_QIMODE_MATH"
6977 "")
6978
7045 (set_attr "mode" "HI")])
7046
7047(define_expand "mulqi3"
7048 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7049 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7050 (match_operand:QI 2 "register_operand" "")))
7051 (clobber (reg:CC FLAGS_REG))])]
7052 "TARGET_QIMODE_MATH"
7053 "")
7054
7055;;On AMDFAM10
7056;; MUL reg8 Direct
7057;; MUL mem8 Direct
7058
6979(define_insn "*mulqi3_1"
6980 [(set (match_operand:QI 0 "register_operand" "=a")
6981 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6982 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6983 (clobber (reg:CC FLAGS_REG))]
6984 "TARGET_QIMODE_MATH
6985 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6986 "mul{b}\t%2"
6987 [(set_attr "type" "imul")
6988 (set_attr "length_immediate" "0")
6989 (set (attr "athlon_decode")
6990 (if_then_else (eq_attr "cpu" "athlon")
6991 (const_string "vector")
6992 (const_string "direct")))
7059(define_insn "*mulqi3_1"
7060 [(set (match_operand:QI 0 "register_operand" "=a")
7061 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7062 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7063 (clobber (reg:CC FLAGS_REG))]
7064 "TARGET_QIMODE_MATH
7065 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7066 "mul{b}\t%2"
7067 [(set_attr "type" "imul")
7068 (set_attr "length_immediate" "0")
7069 (set (attr "athlon_decode")
7070 (if_then_else (eq_attr "cpu" "athlon")
7071 (const_string "vector")
7072 (const_string "direct")))
7073 (set_attr "amdfam10_decode" "direct")
6993 (set_attr "mode" "QI")])
6994
6995(define_expand "umulqihi3"
6996 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6997 (mult:HI (zero_extend:HI
6998 (match_operand:QI 1 "nonimmediate_operand" ""))
6999 (zero_extend:HI
7000 (match_operand:QI 2 "register_operand" ""))))
7001 (clobber (reg:CC FLAGS_REG))])]
7002 "TARGET_QIMODE_MATH"
7003 "")
7004
7005(define_insn "*umulqihi3_1"
7006 [(set (match_operand:HI 0 "register_operand" "=a")
7007 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7008 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7009 (clobber (reg:CC FLAGS_REG))]
7010 "TARGET_QIMODE_MATH
7011 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7012 "mul{b}\t%2"
7013 [(set_attr "type" "imul")
7014 (set_attr "length_immediate" "0")
7015 (set (attr "athlon_decode")
7016 (if_then_else (eq_attr "cpu" "athlon")
7017 (const_string "vector")
7018 (const_string "direct")))
7074 (set_attr "mode" "QI")])
7075
7076(define_expand "umulqihi3"
7077 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7078 (mult:HI (zero_extend:HI
7079 (match_operand:QI 1 "nonimmediate_operand" ""))
7080 (zero_extend:HI
7081 (match_operand:QI 2 "register_operand" ""))))
7082 (clobber (reg:CC FLAGS_REG))])]
7083 "TARGET_QIMODE_MATH"
7084 "")
7085
7086(define_insn "*umulqihi3_1"
7087 [(set (match_operand:HI 0 "register_operand" "=a")
7088 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090 (clobber (reg:CC FLAGS_REG))]
7091 "TARGET_QIMODE_MATH
7092 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093 "mul{b}\t%2"
7094 [(set_attr "type" "imul")
7095 (set_attr "length_immediate" "0")
7096 (set (attr "athlon_decode")
7097 (if_then_else (eq_attr "cpu" "athlon")
7098 (const_string "vector")
7099 (const_string "direct")))
7100 (set_attr "amdfam10_decode" "direct")
7019 (set_attr "mode" "QI")])
7020
7021(define_expand "mulqihi3"
7022 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7023 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7024 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7025 (clobber (reg:CC FLAGS_REG))])]
7026 "TARGET_QIMODE_MATH"
7027 "")
7028
7029(define_insn "*mulqihi3_insn"
7030 [(set (match_operand:HI 0 "register_operand" "=a")
7031 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7032 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7033 (clobber (reg:CC FLAGS_REG))]
7034 "TARGET_QIMODE_MATH
7035 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7036 "imul{b}\t%2"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "direct")))
7101 (set_attr "mode" "QI")])
7102
7103(define_expand "mulqihi3"
7104 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7105 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7106 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7107 (clobber (reg:CC FLAGS_REG))])]
7108 "TARGET_QIMODE_MATH"
7109 "")
7110
7111(define_insn "*mulqihi3_insn"
7112 [(set (match_operand:HI 0 "register_operand" "=a")
7113 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7114 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7115 (clobber (reg:CC FLAGS_REG))]
7116 "TARGET_QIMODE_MATH
7117 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7118 "imul{b}\t%2"
7119 [(set_attr "type" "imul")
7120 (set_attr "length_immediate" "0")
7121 (set (attr "athlon_decode")
7122 (if_then_else (eq_attr "cpu" "athlon")
7123 (const_string "vector")
7124 (const_string "direct")))
7125 (set_attr "amdfam10_decode" "direct")
7043 (set_attr "mode" "QI")])
7044
7045(define_expand "umulditi3"
7046 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7047 (mult:TI (zero_extend:TI
7048 (match_operand:DI 1 "nonimmediate_operand" ""))
7049 (zero_extend:TI
7050 (match_operand:DI 2 "register_operand" ""))))
7051 (clobber (reg:CC FLAGS_REG))])]
7052 "TARGET_64BIT"
7053 "")
7054
7055(define_insn "*umulditi3_insn"
7056 [(set (match_operand:TI 0 "register_operand" "=A")
7057 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7058 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7059 (clobber (reg:CC FLAGS_REG))]
7060 "TARGET_64BIT
7061 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7062 "mul{q}\t%2"
7063 [(set_attr "type" "imul")
7064 (set_attr "length_immediate" "0")
7065 (set (attr "athlon_decode")
7066 (if_then_else (eq_attr "cpu" "athlon")
7067 (const_string "vector")
7068 (const_string "double")))
7126 (set_attr "mode" "QI")])
7127
7128(define_expand "umulditi3"
7129 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130 (mult:TI (zero_extend:TI
7131 (match_operand:DI 1 "nonimmediate_operand" ""))
7132 (zero_extend:TI
7133 (match_operand:DI 2 "register_operand" ""))))
7134 (clobber (reg:CC FLAGS_REG))])]
7135 "TARGET_64BIT"
7136 "")
7137
7138(define_insn "*umulditi3_insn"
7139 [(set (match_operand:TI 0 "register_operand" "=A")
7140 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7141 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7142 (clobber (reg:CC FLAGS_REG))]
7143 "TARGET_64BIT
7144 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145 "mul{q}\t%2"
7146 [(set_attr "type" "imul")
7147 (set_attr "length_immediate" "0")
7148 (set (attr "athlon_decode")
7149 (if_then_else (eq_attr "cpu" "athlon")
7150 (const_string "vector")
7151 (const_string "double")))
7152 (set_attr "amdfam10_decode" "double")
7069 (set_attr "mode" "DI")])
7070
7071;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7072(define_expand "umulsidi3"
7073 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7074 (mult:DI (zero_extend:DI
7075 (match_operand:SI 1 "nonimmediate_operand" ""))
7076 (zero_extend:DI
7077 (match_operand:SI 2 "register_operand" ""))))
7078 (clobber (reg:CC FLAGS_REG))])]
7079 "!TARGET_64BIT"
7080 "")
7081
7082(define_insn "*umulsidi3_insn"
7083 [(set (match_operand:DI 0 "register_operand" "=A")
7084 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7085 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7086 (clobber (reg:CC FLAGS_REG))]
7087 "!TARGET_64BIT
7088 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7089 "mul{l}\t%2"
7090 [(set_attr "type" "imul")
7091 (set_attr "length_immediate" "0")
7092 (set (attr "athlon_decode")
7093 (if_then_else (eq_attr "cpu" "athlon")
7094 (const_string "vector")
7095 (const_string "double")))
7153 (set_attr "mode" "DI")])
7154
7155;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7156(define_expand "umulsidi3"
7157 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7158 (mult:DI (zero_extend:DI
7159 (match_operand:SI 1 "nonimmediate_operand" ""))
7160 (zero_extend:DI
7161 (match_operand:SI 2 "register_operand" ""))))
7162 (clobber (reg:CC FLAGS_REG))])]
7163 "!TARGET_64BIT"
7164 "")
7165
7166(define_insn "*umulsidi3_insn"
7167 [(set (match_operand:DI 0 "register_operand" "=A")
7168 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7169 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7170 (clobber (reg:CC FLAGS_REG))]
7171 "!TARGET_64BIT
7172 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7173 "mul{l}\t%2"
7174 [(set_attr "type" "imul")
7175 (set_attr "length_immediate" "0")
7176 (set (attr "athlon_decode")
7177 (if_then_else (eq_attr "cpu" "athlon")
7178 (const_string "vector")
7179 (const_string "double")))
7180 (set_attr "amdfam10_decode" "double")
7096 (set_attr "mode" "SI")])
7097
7098(define_expand "mulditi3"
7099 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7100 (mult:TI (sign_extend:TI
7101 (match_operand:DI 1 "nonimmediate_operand" ""))
7102 (sign_extend:TI
7103 (match_operand:DI 2 "register_operand" ""))))
7104 (clobber (reg:CC FLAGS_REG))])]
7105 "TARGET_64BIT"
7106 "")
7107
7108(define_insn "*mulditi3_insn"
7109 [(set (match_operand:TI 0 "register_operand" "=A")
7110 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7111 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7112 (clobber (reg:CC FLAGS_REG))]
7113 "TARGET_64BIT
7114 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7115 "imul{q}\t%2"
7116 [(set_attr "type" "imul")
7117 (set_attr "length_immediate" "0")
7118 (set (attr "athlon_decode")
7119 (if_then_else (eq_attr "cpu" "athlon")
7120 (const_string "vector")
7121 (const_string "double")))
7181 (set_attr "mode" "SI")])
7182
7183(define_expand "mulditi3"
7184 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7185 (mult:TI (sign_extend:TI
7186 (match_operand:DI 1 "nonimmediate_operand" ""))
7187 (sign_extend:TI
7188 (match_operand:DI 2 "register_operand" ""))))
7189 (clobber (reg:CC FLAGS_REG))])]
7190 "TARGET_64BIT"
7191 "")
7192
7193(define_insn "*mulditi3_insn"
7194 [(set (match_operand:TI 0 "register_operand" "=A")
7195 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7196 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7197 (clobber (reg:CC FLAGS_REG))]
7198 "TARGET_64BIT
7199 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200 "imul{q}\t%2"
7201 [(set_attr "type" "imul")
7202 (set_attr "length_immediate" "0")
7203 (set (attr "athlon_decode")
7204 (if_then_else (eq_attr "cpu" "athlon")
7205 (const_string "vector")
7206 (const_string "double")))
7207 (set_attr "amdfam10_decode" "double")
7122 (set_attr "mode" "DI")])
7123
7124(define_expand "mulsidi3"
7125 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7126 (mult:DI (sign_extend:DI
7127 (match_operand:SI 1 "nonimmediate_operand" ""))
7128 (sign_extend:DI
7129 (match_operand:SI 2 "register_operand" ""))))
7130 (clobber (reg:CC FLAGS_REG))])]
7131 "!TARGET_64BIT"
7132 "")
7133
7134(define_insn "*mulsidi3_insn"
7135 [(set (match_operand:DI 0 "register_operand" "=A")
7136 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7137 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7138 (clobber (reg:CC FLAGS_REG))]
7139 "!TARGET_64BIT
7140 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7141 "imul{l}\t%2"
7142 [(set_attr "type" "imul")
7143 (set_attr "length_immediate" "0")
7144 (set (attr "athlon_decode")
7145 (if_then_else (eq_attr "cpu" "athlon")
7146 (const_string "vector")
7147 (const_string "double")))
7208 (set_attr "mode" "DI")])
7209
7210(define_expand "mulsidi3"
7211 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7212 (mult:DI (sign_extend:DI
7213 (match_operand:SI 1 "nonimmediate_operand" ""))
7214 (sign_extend:DI
7215 (match_operand:SI 2 "register_operand" ""))))
7216 (clobber (reg:CC FLAGS_REG))])]
7217 "!TARGET_64BIT"
7218 "")
7219
7220(define_insn "*mulsidi3_insn"
7221 [(set (match_operand:DI 0 "register_operand" "=A")
7222 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7223 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7224 (clobber (reg:CC FLAGS_REG))]
7225 "!TARGET_64BIT
7226 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7227 "imul{l}\t%2"
7228 [(set_attr "type" "imul")
7229 (set_attr "length_immediate" "0")
7230 (set (attr "athlon_decode")
7231 (if_then_else (eq_attr "cpu" "athlon")
7232 (const_string "vector")
7233 (const_string "double")))
7234 (set_attr "amdfam10_decode" "double")
7148 (set_attr "mode" "SI")])
7149
7150(define_expand "umuldi3_highpart"
7151 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7152 (truncate:DI
7153 (lshiftrt:TI
7154 (mult:TI (zero_extend:TI
7155 (match_operand:DI 1 "nonimmediate_operand" ""))
7156 (zero_extend:TI
7157 (match_operand:DI 2 "register_operand" "")))
7158 (const_int 64))))
7159 (clobber (match_scratch:DI 3 ""))
7160 (clobber (reg:CC FLAGS_REG))])]
7161 "TARGET_64BIT"
7162 "")
7163
7164(define_insn "*umuldi3_highpart_rex64"
7165 [(set (match_operand:DI 0 "register_operand" "=d")
7166 (truncate:DI
7167 (lshiftrt:TI
7168 (mult:TI (zero_extend:TI
7169 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7170 (zero_extend:TI
7171 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7172 (const_int 64))))
7173 (clobber (match_scratch:DI 3 "=1"))
7174 (clobber (reg:CC FLAGS_REG))]
7175 "TARGET_64BIT
7176 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7177 "mul{q}\t%2"
7178 [(set_attr "type" "imul")
7179 (set_attr "length_immediate" "0")
7180 (set (attr "athlon_decode")
7181 (if_then_else (eq_attr "cpu" "athlon")
7182 (const_string "vector")
7183 (const_string "double")))
7235 (set_attr "mode" "SI")])
7236
7237(define_expand "umuldi3_highpart"
7238 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7239 (truncate:DI
7240 (lshiftrt:TI
7241 (mult:TI (zero_extend:TI
7242 (match_operand:DI 1 "nonimmediate_operand" ""))
7243 (zero_extend:TI
7244 (match_operand:DI 2 "register_operand" "")))
7245 (const_int 64))))
7246 (clobber (match_scratch:DI 3 ""))
7247 (clobber (reg:CC FLAGS_REG))])]
7248 "TARGET_64BIT"
7249 "")
7250
7251(define_insn "*umuldi3_highpart_rex64"
7252 [(set (match_operand:DI 0 "register_operand" "=d")
7253 (truncate:DI
7254 (lshiftrt:TI
7255 (mult:TI (zero_extend:TI
7256 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7257 (zero_extend:TI
7258 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7259 (const_int 64))))
7260 (clobber (match_scratch:DI 3 "=1"))
7261 (clobber (reg:CC FLAGS_REG))]
7262 "TARGET_64BIT
7263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264 "mul{q}\t%2"
7265 [(set_attr "type" "imul")
7266 (set_attr "length_immediate" "0")
7267 (set (attr "athlon_decode")
7268 (if_then_else (eq_attr "cpu" "athlon")
7269 (const_string "vector")
7270 (const_string "double")))
7271 (set_attr "amdfam10_decode" "double")
7184 (set_attr "mode" "DI")])
7185
7186(define_expand "umulsi3_highpart"
7187 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7188 (truncate:SI
7189 (lshiftrt:DI
7190 (mult:DI (zero_extend:DI
7191 (match_operand:SI 1 "nonimmediate_operand" ""))
7192 (zero_extend:DI
7193 (match_operand:SI 2 "register_operand" "")))
7194 (const_int 32))))
7195 (clobber (match_scratch:SI 3 ""))
7196 (clobber (reg:CC FLAGS_REG))])]
7197 ""
7198 "")
7199
7200(define_insn "*umulsi3_highpart_insn"
7201 [(set (match_operand:SI 0 "register_operand" "=d")
7202 (truncate:SI
7203 (lshiftrt:DI
7204 (mult:DI (zero_extend:DI
7205 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7206 (zero_extend:DI
7207 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7208 (const_int 32))))
7209 (clobber (match_scratch:SI 3 "=1"))
7210 (clobber (reg:CC FLAGS_REG))]
7211 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7212 "mul{l}\t%2"
7213 [(set_attr "type" "imul")
7214 (set_attr "length_immediate" "0")
7215 (set (attr "athlon_decode")
7216 (if_then_else (eq_attr "cpu" "athlon")
7217 (const_string "vector")
7218 (const_string "double")))
7272 (set_attr "mode" "DI")])
7273
7274(define_expand "umulsi3_highpart"
7275 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7276 (truncate:SI
7277 (lshiftrt:DI
7278 (mult:DI (zero_extend:DI
7279 (match_operand:SI 1 "nonimmediate_operand" ""))
7280 (zero_extend:DI
7281 (match_operand:SI 2 "register_operand" "")))
7282 (const_int 32))))
7283 (clobber (match_scratch:SI 3 ""))
7284 (clobber (reg:CC FLAGS_REG))])]
7285 ""
7286 "")
7287
7288(define_insn "*umulsi3_highpart_insn"
7289 [(set (match_operand:SI 0 "register_operand" "=d")
7290 (truncate:SI
7291 (lshiftrt:DI
7292 (mult:DI (zero_extend:DI
7293 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7294 (zero_extend:DI
7295 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7296 (const_int 32))))
7297 (clobber (match_scratch:SI 3 "=1"))
7298 (clobber (reg:CC FLAGS_REG))]
7299 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7300 "mul{l}\t%2"
7301 [(set_attr "type" "imul")
7302 (set_attr "length_immediate" "0")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "double")))
7307 (set_attr "amdfam10_decode" "double")
7219 (set_attr "mode" "SI")])
7220
7221(define_insn "*umulsi3_highpart_zext"
7222 [(set (match_operand:DI 0 "register_operand" "=d")
7223 (zero_extend:DI (truncate:SI
7224 (lshiftrt:DI
7225 (mult:DI (zero_extend:DI
7226 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7227 (zero_extend:DI
7228 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7229 (const_int 32)))))
7230 (clobber (match_scratch:SI 3 "=1"))
7231 (clobber (reg:CC FLAGS_REG))]
7232 "TARGET_64BIT
7233 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234 "mul{l}\t%2"
7235 [(set_attr "type" "imul")
7236 (set_attr "length_immediate" "0")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7308 (set_attr "mode" "SI")])
7309
7310(define_insn "*umulsi3_highpart_zext"
7311 [(set (match_operand:DI 0 "register_operand" "=d")
7312 (zero_extend:DI (truncate:SI
7313 (lshiftrt:DI
7314 (mult:DI (zero_extend:DI
7315 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7316 (zero_extend:DI
7317 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7318 (const_int 32)))))
7319 (clobber (match_scratch:SI 3 "=1"))
7320 (clobber (reg:CC FLAGS_REG))]
7321 "TARGET_64BIT
7322 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7323 "mul{l}\t%2"
7324 [(set_attr "type" "imul")
7325 (set_attr "length_immediate" "0")
7326 (set (attr "athlon_decode")
7327 (if_then_else (eq_attr "cpu" "athlon")
7328 (const_string "vector")
7329 (const_string "double")))
7330 (set_attr "amdfam10_decode" "double")
7241 (set_attr "mode" "SI")])
7242
7243(define_expand "smuldi3_highpart"
7244 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7245 (truncate:DI
7246 (lshiftrt:TI
7247 (mult:TI (sign_extend:TI
7248 (match_operand:DI 1 "nonimmediate_operand" ""))
7249 (sign_extend:TI
7250 (match_operand:DI 2 "register_operand" "")))
7251 (const_int 64))))
7252 (clobber (match_scratch:DI 3 ""))
7253 (clobber (reg:CC FLAGS_REG))])]
7254 "TARGET_64BIT"
7255 "")
7256
7257(define_insn "*smuldi3_highpart_rex64"
7258 [(set (match_operand:DI 0 "register_operand" "=d")
7259 (truncate:DI
7260 (lshiftrt:TI
7261 (mult:TI (sign_extend:TI
7262 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7263 (sign_extend:TI
7264 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7265 (const_int 64))))
7266 (clobber (match_scratch:DI 3 "=1"))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "TARGET_64BIT
7269 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7270 "imul{q}\t%2"
7271 [(set_attr "type" "imul")
7272 (set (attr "athlon_decode")
7273 (if_then_else (eq_attr "cpu" "athlon")
7274 (const_string "vector")
7275 (const_string "double")))
7331 (set_attr "mode" "SI")])
7332
7333(define_expand "smuldi3_highpart"
7334 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7335 (truncate:DI
7336 (lshiftrt:TI
7337 (mult:TI (sign_extend:TI
7338 (match_operand:DI 1 "nonimmediate_operand" ""))
7339 (sign_extend:TI
7340 (match_operand:DI 2 "register_operand" "")))
7341 (const_int 64))))
7342 (clobber (match_scratch:DI 3 ""))
7343 (clobber (reg:CC FLAGS_REG))])]
7344 "TARGET_64BIT"
7345 "")
7346
7347(define_insn "*smuldi3_highpart_rex64"
7348 [(set (match_operand:DI 0 "register_operand" "=d")
7349 (truncate:DI
7350 (lshiftrt:TI
7351 (mult:TI (sign_extend:TI
7352 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7353 (sign_extend:TI
7354 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7355 (const_int 64))))
7356 (clobber (match_scratch:DI 3 "=1"))
7357 (clobber (reg:CC FLAGS_REG))]
7358 "TARGET_64BIT
7359 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7360 "imul{q}\t%2"
7361 [(set_attr "type" "imul")
7362 (set (attr "athlon_decode")
7363 (if_then_else (eq_attr "cpu" "athlon")
7364 (const_string "vector")
7365 (const_string "double")))
7366 (set_attr "amdfam10_decode" "double")
7276 (set_attr "mode" "DI")])
7277
7278(define_expand "smulsi3_highpart"
7279 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7280 (truncate:SI
7281 (lshiftrt:DI
7282 (mult:DI (sign_extend:DI
7283 (match_operand:SI 1 "nonimmediate_operand" ""))
7284 (sign_extend:DI
7285 (match_operand:SI 2 "register_operand" "")))
7286 (const_int 32))))
7287 (clobber (match_scratch:SI 3 ""))
7288 (clobber (reg:CC FLAGS_REG))])]
7289 ""
7290 "")
7291
7292(define_insn "*smulsi3_highpart_insn"
7293 [(set (match_operand:SI 0 "register_operand" "=d")
7294 (truncate:SI
7295 (lshiftrt:DI
7296 (mult:DI (sign_extend:DI
7297 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298 (sign_extend:DI
7299 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300 (const_int 32))))
7301 (clobber (match_scratch:SI 3 "=1"))
7302 (clobber (reg:CC FLAGS_REG))]
7303 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7304 "imul{l}\t%2"
7305 [(set_attr "type" "imul")
7306 (set (attr "athlon_decode")
7307 (if_then_else (eq_attr "cpu" "athlon")
7308 (const_string "vector")
7309 (const_string "double")))
7367 (set_attr "mode" "DI")])
7368
7369(define_expand "smulsi3_highpart"
7370 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7371 (truncate:SI
7372 (lshiftrt:DI
7373 (mult:DI (sign_extend:DI
7374 (match_operand:SI 1 "nonimmediate_operand" ""))
7375 (sign_extend:DI
7376 (match_operand:SI 2 "register_operand" "")))
7377 (const_int 32))))
7378 (clobber (match_scratch:SI 3 ""))
7379 (clobber (reg:CC FLAGS_REG))])]
7380 ""
7381 "")
7382
7383(define_insn "*smulsi3_highpart_insn"
7384 [(set (match_operand:SI 0 "register_operand" "=d")
7385 (truncate:SI
7386 (lshiftrt:DI
7387 (mult:DI (sign_extend:DI
7388 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7389 (sign_extend:DI
7390 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7391 (const_int 32))))
7392 (clobber (match_scratch:SI 3 "=1"))
7393 (clobber (reg:CC FLAGS_REG))]
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 "amdfam10_decode" "double")
7310 (set_attr "mode" "SI")])
7311
7312(define_insn "*smulsi3_highpart_zext"
7313 [(set (match_operand:DI 0 "register_operand" "=d")
7314 (zero_extend:DI (truncate:SI
7315 (lshiftrt:DI
7316 (mult:DI (sign_extend:DI
7317 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7318 (sign_extend:DI
7319 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7320 (const_int 32)))))
7321 (clobber (match_scratch:SI 3 "=1"))
7322 (clobber (reg:CC FLAGS_REG))]
7323 "TARGET_64BIT
7324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7325 "imul{l}\t%2"
7326 [(set_attr "type" "imul")
7327 (set (attr "athlon_decode")
7328 (if_then_else (eq_attr "cpu" "athlon")
7329 (const_string "vector")
7330 (const_string "double")))
7402 (set_attr "mode" "SI")])
7403
7404(define_insn "*smulsi3_highpart_zext"
7405 [(set (match_operand:DI 0 "register_operand" "=d")
7406 (zero_extend:DI (truncate:SI
7407 (lshiftrt:DI
7408 (mult:DI (sign_extend:DI
7409 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7410 (sign_extend:DI
7411 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7412 (const_int 32)))))
7413 (clobber (match_scratch:SI 3 "=1"))
7414 (clobber (reg:CC FLAGS_REG))]
7415 "TARGET_64BIT
7416 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7417 "imul{l}\t%2"
7418 [(set_attr "type" "imul")
7419 (set (attr "athlon_decode")
7420 (if_then_else (eq_attr "cpu" "athlon")
7421 (const_string "vector")
7422 (const_string "double")))
7423 (set_attr "amdfam10_decode" "double")
7331 (set_attr "mode" "SI")])
7332
7333;; The patterns that match these are at the end of this file.
7334
7335(define_expand "mulxf3"
7336 [(set (match_operand:XF 0 "register_operand" "")
7337 (mult:XF (match_operand:XF 1 "register_operand" "")
7338 (match_operand:XF 2 "register_operand" "")))]
7339 "TARGET_80387"
7340 "")
7341
7342(define_expand "muldf3"
7343 [(set (match_operand:DF 0 "register_operand" "")
7344 (mult:DF (match_operand:DF 1 "register_operand" "")
7345 (match_operand:DF 2 "nonimmediate_operand" "")))]
7346 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7347 "")
7348
7349(define_expand "mulsf3"
7350 [(set (match_operand:SF 0 "register_operand" "")
7351 (mult:SF (match_operand:SF 1 "register_operand" "")
7352 (match_operand:SF 2 "nonimmediate_operand" "")))]
7353 "TARGET_80387 || TARGET_SSE_MATH"
7354 "")
7355
7356;; Divide instructions
7357
7358(define_insn "divqi3"
7359 [(set (match_operand:QI 0 "register_operand" "=a")
7360 (div:QI (match_operand:HI 1 "register_operand" "0")
7361 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7362 (clobber (reg:CC FLAGS_REG))]
7363 "TARGET_QIMODE_MATH"
7364 "idiv{b}\t%2"
7365 [(set_attr "type" "idiv")
7366 (set_attr "mode" "QI")])
7367
7368(define_insn "udivqi3"
7369 [(set (match_operand:QI 0 "register_operand" "=a")
7370 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7371 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "TARGET_QIMODE_MATH"
7374 "div{b}\t%2"
7375 [(set_attr "type" "idiv")
7376 (set_attr "mode" "QI")])
7377
7378;; The patterns that match these are at the end of this file.
7379
7380(define_expand "divxf3"
7381 [(set (match_operand:XF 0 "register_operand" "")
7382 (div:XF (match_operand:XF 1 "register_operand" "")
7383 (match_operand:XF 2 "register_operand" "")))]
7384 "TARGET_80387"
7385 "")
7386
7387(define_expand "divdf3"
7388 [(set (match_operand:DF 0 "register_operand" "")
7389 (div:DF (match_operand:DF 1 "register_operand" "")
7390 (match_operand:DF 2 "nonimmediate_operand" "")))]
7391 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7392 "")
7393
7394(define_expand "divsf3"
7395 [(set (match_operand:SF 0 "register_operand" "")
7396 (div:SF (match_operand:SF 1 "register_operand" "")
7397 (match_operand:SF 2 "nonimmediate_operand" "")))]
7398 "TARGET_80387 || TARGET_SSE_MATH"
7399 "")
7400
7401;; Remainder instructions.
7402
7403(define_expand "divmoddi4"
7404 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7405 (div:DI (match_operand:DI 1 "register_operand" "")
7406 (match_operand:DI 2 "nonimmediate_operand" "")))
7407 (set (match_operand:DI 3 "register_operand" "")
7408 (mod:DI (match_dup 1) (match_dup 2)))
7409 (clobber (reg:CC FLAGS_REG))])]
7410 "TARGET_64BIT"
7411 "")
7412
7413;; Allow to come the parameter in eax or edx to avoid extra moves.
7414;; Penalize eax case slightly because it results in worse scheduling
7415;; of code.
7416(define_insn "*divmoddi4_nocltd_rex64"
7417 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7418 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7419 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7420 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7421 (mod:DI (match_dup 2) (match_dup 3)))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7424 "#"
7425 [(set_attr "type" "multi")])
7426
7427(define_insn "*divmoddi4_cltd_rex64"
7428 [(set (match_operand:DI 0 "register_operand" "=a")
7429 (div:DI (match_operand:DI 2 "register_operand" "a")
7430 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7431 (set (match_operand:DI 1 "register_operand" "=&d")
7432 (mod:DI (match_dup 2) (match_dup 3)))
7433 (clobber (reg:CC FLAGS_REG))]
7434 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7435 "#"
7436 [(set_attr "type" "multi")])
7437
7438(define_insn "*divmoddi_noext_rex64"
7439 [(set (match_operand:DI 0 "register_operand" "=a")
7440 (div:DI (match_operand:DI 1 "register_operand" "0")
7441 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7442 (set (match_operand:DI 3 "register_operand" "=d")
7443 (mod:DI (match_dup 1) (match_dup 2)))
7444 (use (match_operand:DI 4 "register_operand" "3"))
7445 (clobber (reg:CC FLAGS_REG))]
7446 "TARGET_64BIT"
7447 "idiv{q}\t%2"
7448 [(set_attr "type" "idiv")
7449 (set_attr "mode" "DI")])
7450
7451(define_split
7452 [(set (match_operand:DI 0 "register_operand" "")
7453 (div:DI (match_operand:DI 1 "register_operand" "")
7454 (match_operand:DI 2 "nonimmediate_operand" "")))
7455 (set (match_operand:DI 3 "register_operand" "")
7456 (mod:DI (match_dup 1) (match_dup 2)))
7457 (clobber (reg:CC FLAGS_REG))]
7458 "TARGET_64BIT && reload_completed"
7459 [(parallel [(set (match_dup 3)
7460 (ashiftrt:DI (match_dup 4) (const_int 63)))
7461 (clobber (reg:CC FLAGS_REG))])
7462 (parallel [(set (match_dup 0)
7463 (div:DI (reg:DI 0) (match_dup 2)))
7464 (set (match_dup 3)
7465 (mod:DI (reg:DI 0) (match_dup 2)))
7466 (use (match_dup 3))
7467 (clobber (reg:CC FLAGS_REG))])]
7468{
7469 /* Avoid use of cltd in favor of a mov+shift. */
7470 if (!TARGET_USE_CLTD && !optimize_size)
7471 {
7472 if (true_regnum (operands[1]))
7473 emit_move_insn (operands[0], operands[1]);
7474 else
7475 emit_move_insn (operands[3], operands[1]);
7476 operands[4] = operands[3];
7477 }
7478 else
7479 {
7480 gcc_assert (!true_regnum (operands[1]));
7481 operands[4] = operands[1];
7482 }
7483})
7484
7485
7486(define_expand "divmodsi4"
7487 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7488 (div:SI (match_operand:SI 1 "register_operand" "")
7489 (match_operand:SI 2 "nonimmediate_operand" "")))
7490 (set (match_operand:SI 3 "register_operand" "")
7491 (mod:SI (match_dup 1) (match_dup 2)))
7492 (clobber (reg:CC FLAGS_REG))])]
7493 ""
7494 "")
7495
7496;; Allow to come the parameter in eax or edx to avoid extra moves.
7497;; Penalize eax case slightly because it results in worse scheduling
7498;; of code.
7499(define_insn "*divmodsi4_nocltd"
7500 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7501 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7502 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7503 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7504 (mod:SI (match_dup 2) (match_dup 3)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "!optimize_size && !TARGET_USE_CLTD"
7507 "#"
7508 [(set_attr "type" "multi")])
7509
7510(define_insn "*divmodsi4_cltd"
7511 [(set (match_operand:SI 0 "register_operand" "=a")
7512 (div:SI (match_operand:SI 2 "register_operand" "a")
7513 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7514 (set (match_operand:SI 1 "register_operand" "=&d")
7515 (mod:SI (match_dup 2) (match_dup 3)))
7516 (clobber (reg:CC FLAGS_REG))]
7517 "optimize_size || TARGET_USE_CLTD"
7518 "#"
7519 [(set_attr "type" "multi")])
7520
7521(define_insn "*divmodsi_noext"
7522 [(set (match_operand:SI 0 "register_operand" "=a")
7523 (div:SI (match_operand:SI 1 "register_operand" "0")
7524 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7525 (set (match_operand:SI 3 "register_operand" "=d")
7526 (mod:SI (match_dup 1) (match_dup 2)))
7527 (use (match_operand:SI 4 "register_operand" "3"))
7528 (clobber (reg:CC FLAGS_REG))]
7529 ""
7530 "idiv{l}\t%2"
7531 [(set_attr "type" "idiv")
7532 (set_attr "mode" "SI")])
7533
7534(define_split
7535 [(set (match_operand:SI 0 "register_operand" "")
7536 (div:SI (match_operand:SI 1 "register_operand" "")
7537 (match_operand:SI 2 "nonimmediate_operand" "")))
7538 (set (match_operand:SI 3 "register_operand" "")
7539 (mod:SI (match_dup 1) (match_dup 2)))
7540 (clobber (reg:CC FLAGS_REG))]
7541 "reload_completed"
7542 [(parallel [(set (match_dup 3)
7543 (ashiftrt:SI (match_dup 4) (const_int 31)))
7544 (clobber (reg:CC FLAGS_REG))])
7545 (parallel [(set (match_dup 0)
7546 (div:SI (reg:SI 0) (match_dup 2)))
7547 (set (match_dup 3)
7548 (mod:SI (reg:SI 0) (match_dup 2)))
7549 (use (match_dup 3))
7550 (clobber (reg:CC FLAGS_REG))])]
7551{
7552 /* Avoid use of cltd in favor of a mov+shift. */
7553 if (!TARGET_USE_CLTD && !optimize_size)
7554 {
7555 if (true_regnum (operands[1]))
7556 emit_move_insn (operands[0], operands[1]);
7557 else
7558 emit_move_insn (operands[3], operands[1]);
7559 operands[4] = operands[3];
7560 }
7561 else
7562 {
7563 gcc_assert (!true_regnum (operands[1]));
7564 operands[4] = operands[1];
7565 }
7566})
7567;; %%% Split me.
7568(define_insn "divmodhi4"
7569 [(set (match_operand:HI 0 "register_operand" "=a")
7570 (div:HI (match_operand:HI 1 "register_operand" "0")
7571 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7572 (set (match_operand:HI 3 "register_operand" "=&d")
7573 (mod:HI (match_dup 1) (match_dup 2)))
7574 (clobber (reg:CC FLAGS_REG))]
7575 "TARGET_HIMODE_MATH"
7576 "cwtd\;idiv{w}\t%2"
7577 [(set_attr "type" "multi")
7578 (set_attr "length_immediate" "0")
7579 (set_attr "mode" "SI")])
7580
7581(define_insn "udivmoddi4"
7582 [(set (match_operand:DI 0 "register_operand" "=a")
7583 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7584 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7585 (set (match_operand:DI 3 "register_operand" "=&d")
7586 (umod:DI (match_dup 1) (match_dup 2)))
7587 (clobber (reg:CC FLAGS_REG))]
7588 "TARGET_64BIT"
7589 "xor{q}\t%3, %3\;div{q}\t%2"
7590 [(set_attr "type" "multi")
7591 (set_attr "length_immediate" "0")
7592 (set_attr "mode" "DI")])
7593
7594(define_insn "*udivmoddi4_noext"
7595 [(set (match_operand:DI 0 "register_operand" "=a")
7596 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7597 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7598 (set (match_operand:DI 3 "register_operand" "=d")
7599 (umod:DI (match_dup 1) (match_dup 2)))
7600 (use (match_dup 3))
7601 (clobber (reg:CC FLAGS_REG))]
7602 "TARGET_64BIT"
7603 "div{q}\t%2"
7604 [(set_attr "type" "idiv")
7605 (set_attr "mode" "DI")])
7606
7607(define_split
7608 [(set (match_operand:DI 0 "register_operand" "")
7609 (udiv:DI (match_operand:DI 1 "register_operand" "")
7610 (match_operand:DI 2 "nonimmediate_operand" "")))
7611 (set (match_operand:DI 3 "register_operand" "")
7612 (umod:DI (match_dup 1) (match_dup 2)))
7613 (clobber (reg:CC FLAGS_REG))]
7614 "TARGET_64BIT && reload_completed"
7615 [(set (match_dup 3) (const_int 0))
7616 (parallel [(set (match_dup 0)
7617 (udiv:DI (match_dup 1) (match_dup 2)))
7618 (set (match_dup 3)
7619 (umod:DI (match_dup 1) (match_dup 2)))
7620 (use (match_dup 3))
7621 (clobber (reg:CC FLAGS_REG))])]
7622 "")
7623
7624(define_insn "udivmodsi4"
7625 [(set (match_operand:SI 0 "register_operand" "=a")
7626 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7627 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7628 (set (match_operand:SI 3 "register_operand" "=&d")
7629 (umod:SI (match_dup 1) (match_dup 2)))
7630 (clobber (reg:CC FLAGS_REG))]
7631 ""
7632 "xor{l}\t%3, %3\;div{l}\t%2"
7633 [(set_attr "type" "multi")
7634 (set_attr "length_immediate" "0")
7635 (set_attr "mode" "SI")])
7636
7637(define_insn "*udivmodsi4_noext"
7638 [(set (match_operand:SI 0 "register_operand" "=a")
7639 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7640 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7641 (set (match_operand:SI 3 "register_operand" "=d")
7642 (umod:SI (match_dup 1) (match_dup 2)))
7643 (use (match_dup 3))
7644 (clobber (reg:CC FLAGS_REG))]
7645 ""
7646 "div{l}\t%2"
7647 [(set_attr "type" "idiv")
7648 (set_attr "mode" "SI")])
7649
7650(define_split
7651 [(set (match_operand:SI 0 "register_operand" "")
7652 (udiv:SI (match_operand:SI 1 "register_operand" "")
7653 (match_operand:SI 2 "nonimmediate_operand" "")))
7654 (set (match_operand:SI 3 "register_operand" "")
7655 (umod:SI (match_dup 1) (match_dup 2)))
7656 (clobber (reg:CC FLAGS_REG))]
7657 "reload_completed"
7658 [(set (match_dup 3) (const_int 0))
7659 (parallel [(set (match_dup 0)
7660 (udiv:SI (match_dup 1) (match_dup 2)))
7661 (set (match_dup 3)
7662 (umod:SI (match_dup 1) (match_dup 2)))
7663 (use (match_dup 3))
7664 (clobber (reg:CC FLAGS_REG))])]
7665 "")
7666
7667(define_expand "udivmodhi4"
7668 [(set (match_dup 4) (const_int 0))
7669 (parallel [(set (match_operand:HI 0 "register_operand" "")
7670 (udiv:HI (match_operand:HI 1 "register_operand" "")
7671 (match_operand:HI 2 "nonimmediate_operand" "")))
7672 (set (match_operand:HI 3 "register_operand" "")
7673 (umod:HI (match_dup 1) (match_dup 2)))
7674 (use (match_dup 4))
7675 (clobber (reg:CC FLAGS_REG))])]
7676 "TARGET_HIMODE_MATH"
7677 "operands[4] = gen_reg_rtx (HImode);")
7678
7679(define_insn "*udivmodhi_noext"
7680 [(set (match_operand:HI 0 "register_operand" "=a")
7681 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7682 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7683 (set (match_operand:HI 3 "register_operand" "=d")
7684 (umod:HI (match_dup 1) (match_dup 2)))
7685 (use (match_operand:HI 4 "register_operand" "3"))
7686 (clobber (reg:CC FLAGS_REG))]
7687 ""
7688 "div{w}\t%2"
7689 [(set_attr "type" "idiv")
7690 (set_attr "mode" "HI")])
7691
7692;; We cannot use div/idiv for double division, because it causes
7693;; "division by zero" on the overflow and that's not what we expect
7694;; from truncate. Because true (non truncating) double division is
7695;; never generated, we can't create this insn anyway.
7696;
7697;(define_insn ""
7698; [(set (match_operand:SI 0 "register_operand" "=a")
7699; (truncate:SI
7700; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7701; (zero_extend:DI
7702; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7703; (set (match_operand:SI 3 "register_operand" "=d")
7704; (truncate:SI
7705; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7706; (clobber (reg:CC FLAGS_REG))]
7707; ""
7708; "div{l}\t{%2, %0|%0, %2}"
7709; [(set_attr "type" "idiv")])
7710
7711;;- Logical AND instructions
7712
7713;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7714;; Note that this excludes ah.
7715
7716(define_insn "*testdi_1_rex64"
7717 [(set (reg FLAGS_REG)
7718 (compare
7719 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7720 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7721 (const_int 0)))]
7722 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7723 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724 "@
7725 test{l}\t{%k1, %k0|%k0, %k1}
7726 test{l}\t{%k1, %k0|%k0, %k1}
7727 test{q}\t{%1, %0|%0, %1}
7728 test{q}\t{%1, %0|%0, %1}
7729 test{q}\t{%1, %0|%0, %1}"
7730 [(set_attr "type" "test")
7731 (set_attr "modrm" "0,1,0,1,1")
7732 (set_attr "mode" "SI,SI,DI,DI,DI")
7733 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7734
7735(define_insn "testsi_1"
7736 [(set (reg FLAGS_REG)
7737 (compare
7738 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7739 (match_operand:SI 1 "general_operand" "in,in,rin"))
7740 (const_int 0)))]
7741 "ix86_match_ccmode (insn, CCNOmode)
7742 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7743 "test{l}\t{%1, %0|%0, %1}"
7744 [(set_attr "type" "test")
7745 (set_attr "modrm" "0,1,1")
7746 (set_attr "mode" "SI")
7747 (set_attr "pent_pair" "uv,np,uv")])
7748
7749(define_expand "testsi_ccno_1"
7750 [(set (reg:CCNO FLAGS_REG)
7751 (compare:CCNO
7752 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7753 (match_operand:SI 1 "nonmemory_operand" ""))
7754 (const_int 0)))]
7755 ""
7756 "")
7757
7758(define_insn "*testhi_1"
7759 [(set (reg FLAGS_REG)
7760 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7761 (match_operand:HI 1 "general_operand" "n,n,rn"))
7762 (const_int 0)))]
7763 "ix86_match_ccmode (insn, CCNOmode)
7764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7765 "test{w}\t{%1, %0|%0, %1}"
7766 [(set_attr "type" "test")
7767 (set_attr "modrm" "0,1,1")
7768 (set_attr "mode" "HI")
7769 (set_attr "pent_pair" "uv,np,uv")])
7770
7771(define_expand "testqi_ccz_1"
7772 [(set (reg:CCZ FLAGS_REG)
7773 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7774 (match_operand:QI 1 "nonmemory_operand" ""))
7775 (const_int 0)))]
7776 ""
7777 "")
7778
7779(define_insn "*testqi_1_maybe_si"
7780 [(set (reg FLAGS_REG)
7781 (compare
7782 (and:QI
7783 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7784 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7785 (const_int 0)))]
7786 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7787 && ix86_match_ccmode (insn,
7788 GET_CODE (operands[1]) == CONST_INT
7789 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7790{
7791 if (which_alternative == 3)
7792 {
7793 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7794 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7795 return "test{l}\t{%1, %k0|%k0, %1}";
7796 }
7797 return "test{b}\t{%1, %0|%0, %1}";
7798}
7799 [(set_attr "type" "test")
7800 (set_attr "modrm" "0,1,1,1")
7801 (set_attr "mode" "QI,QI,QI,SI")
7802 (set_attr "pent_pair" "uv,np,uv,np")])
7803
7804(define_insn "*testqi_1"
7805 [(set (reg FLAGS_REG)
7806 (compare
7807 (and:QI
7808 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7809 (match_operand:QI 1 "general_operand" "n,n,qn"))
7810 (const_int 0)))]
7811 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7812 && ix86_match_ccmode (insn, CCNOmode)"
7813 "test{b}\t{%1, %0|%0, %1}"
7814 [(set_attr "type" "test")
7815 (set_attr "modrm" "0,1,1")
7816 (set_attr "mode" "QI")
7817 (set_attr "pent_pair" "uv,np,uv")])
7818
7819(define_expand "testqi_ext_ccno_0"
7820 [(set (reg:CCNO FLAGS_REG)
7821 (compare:CCNO
7822 (and:SI
7823 (zero_extract:SI
7824 (match_operand 0 "ext_register_operand" "")
7825 (const_int 8)
7826 (const_int 8))
7827 (match_operand 1 "const_int_operand" ""))
7828 (const_int 0)))]
7829 ""
7830 "")
7831
7832(define_insn "*testqi_ext_0"
7833 [(set (reg FLAGS_REG)
7834 (compare
7835 (and:SI
7836 (zero_extract:SI
7837 (match_operand 0 "ext_register_operand" "Q")
7838 (const_int 8)
7839 (const_int 8))
7840 (match_operand 1 "const_int_operand" "n"))
7841 (const_int 0)))]
7842 "ix86_match_ccmode (insn, CCNOmode)"
7843 "test{b}\t{%1, %h0|%h0, %1}"
7844 [(set_attr "type" "test")
7845 (set_attr "mode" "QI")
7846 (set_attr "length_immediate" "1")
7847 (set_attr "pent_pair" "np")])
7848
7849(define_insn "*testqi_ext_1"
7850 [(set (reg FLAGS_REG)
7851 (compare
7852 (and:SI
7853 (zero_extract:SI
7854 (match_operand 0 "ext_register_operand" "Q")
7855 (const_int 8)
7856 (const_int 8))
7857 (zero_extend:SI
7858 (match_operand:QI 1 "general_operand" "Qm")))
7859 (const_int 0)))]
7860 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7861 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7862 "test{b}\t{%1, %h0|%h0, %1}"
7863 [(set_attr "type" "test")
7864 (set_attr "mode" "QI")])
7865
7866(define_insn "*testqi_ext_1_rex64"
7867 [(set (reg FLAGS_REG)
7868 (compare
7869 (and:SI
7870 (zero_extract:SI
7871 (match_operand 0 "ext_register_operand" "Q")
7872 (const_int 8)
7873 (const_int 8))
7874 (zero_extend:SI
7875 (match_operand:QI 1 "register_operand" "Q")))
7876 (const_int 0)))]
7877 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7878 "test{b}\t{%1, %h0|%h0, %1}"
7879 [(set_attr "type" "test")
7880 (set_attr "mode" "QI")])
7881
7882(define_insn "*testqi_ext_2"
7883 [(set (reg FLAGS_REG)
7884 (compare
7885 (and:SI
7886 (zero_extract:SI
7887 (match_operand 0 "ext_register_operand" "Q")
7888 (const_int 8)
7889 (const_int 8))
7890 (zero_extract:SI
7891 (match_operand 1 "ext_register_operand" "Q")
7892 (const_int 8)
7893 (const_int 8)))
7894 (const_int 0)))]
7895 "ix86_match_ccmode (insn, CCNOmode)"
7896 "test{b}\t{%h1, %h0|%h0, %h1}"
7897 [(set_attr "type" "test")
7898 (set_attr "mode" "QI")])
7899
7900;; Combine likes to form bit extractions for some tests. Humor it.
7901(define_insn "*testqi_ext_3"
7902 [(set (reg FLAGS_REG)
7903 (compare (zero_extract:SI
7904 (match_operand 0 "nonimmediate_operand" "rm")
7905 (match_operand:SI 1 "const_int_operand" "")
7906 (match_operand:SI 2 "const_int_operand" ""))
7907 (const_int 0)))]
7908 "ix86_match_ccmode (insn, CCNOmode)
7909 && INTVAL (operands[1]) > 0
7910 && INTVAL (operands[2]) >= 0
7911 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7912 && (GET_MODE (operands[0]) == SImode
7913 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7914 || GET_MODE (operands[0]) == HImode
7915 || GET_MODE (operands[0]) == QImode)"
7916 "#")
7917
7918(define_insn "*testqi_ext_3_rex64"
7919 [(set (reg FLAGS_REG)
7920 (compare (zero_extract:DI
7921 (match_operand 0 "nonimmediate_operand" "rm")
7922 (match_operand:DI 1 "const_int_operand" "")
7923 (match_operand:DI 2 "const_int_operand" ""))
7924 (const_int 0)))]
7925 "TARGET_64BIT
7926 && ix86_match_ccmode (insn, CCNOmode)
7927 && INTVAL (operands[1]) > 0
7928 && INTVAL (operands[2]) >= 0
7929 /* Ensure that resulting mask is zero or sign extended operand. */
7930 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7931 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7932 && INTVAL (operands[1]) > 32))
7933 && (GET_MODE (operands[0]) == SImode
7934 || GET_MODE (operands[0]) == DImode
7935 || GET_MODE (operands[0]) == HImode
7936 || GET_MODE (operands[0]) == QImode)"
7937 "#")
7938
7939(define_split
7940 [(set (match_operand 0 "flags_reg_operand" "")
7941 (match_operator 1 "compare_operator"
7942 [(zero_extract
7943 (match_operand 2 "nonimmediate_operand" "")
7944 (match_operand 3 "const_int_operand" "")
7945 (match_operand 4 "const_int_operand" ""))
7946 (const_int 0)]))]
7947 "ix86_match_ccmode (insn, CCNOmode)"
7948 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7949{
7950 rtx val = operands[2];
7951 HOST_WIDE_INT len = INTVAL (operands[3]);
7952 HOST_WIDE_INT pos = INTVAL (operands[4]);
7953 HOST_WIDE_INT mask;
7954 enum machine_mode mode, submode;
7955
7956 mode = GET_MODE (val);
7957 if (GET_CODE (val) == MEM)
7958 {
7959 /* ??? Combine likes to put non-volatile mem extractions in QImode
7960 no matter the size of the test. So find a mode that works. */
7961 if (! MEM_VOLATILE_P (val))
7962 {
7963 mode = smallest_mode_for_size (pos + len, MODE_INT);
7964 val = adjust_address (val, mode, 0);
7965 }
7966 }
7967 else if (GET_CODE (val) == SUBREG
7968 && (submode = GET_MODE (SUBREG_REG (val)),
7969 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7970 && pos + len <= GET_MODE_BITSIZE (submode))
7971 {
7972 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7973 mode = submode;
7974 val = SUBREG_REG (val);
7975 }
7976 else if (mode == HImode && pos + len <= 8)
7977 {
7978 /* Small HImode tests can be converted to QImode. */
7979 mode = QImode;
7980 val = gen_lowpart (QImode, val);
7981 }
7982
7983 if (len == HOST_BITS_PER_WIDE_INT)
7984 mask = -1;
7985 else
7986 mask = ((HOST_WIDE_INT)1 << len) - 1;
7987 mask <<= pos;
7988
7989 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7990})
7991
7992;; Convert HImode/SImode test instructions with immediate to QImode ones.
7993;; i386 does not allow to encode test with 8bit sign extended immediate, so
7994;; this is relatively important trick.
7995;; Do the conversion only post-reload to avoid limiting of the register class
7996;; to QI regs.
7997(define_split
7998 [(set (match_operand 0 "flags_reg_operand" "")
7999 (match_operator 1 "compare_operator"
8000 [(and (match_operand 2 "register_operand" "")
8001 (match_operand 3 "const_int_operand" ""))
8002 (const_int 0)]))]
8003 "reload_completed
8004 && QI_REG_P (operands[2])
8005 && GET_MODE (operands[2]) != QImode
8006 && ((ix86_match_ccmode (insn, CCZmode)
8007 && !(INTVAL (operands[3]) & ~(255 << 8)))
8008 || (ix86_match_ccmode (insn, CCNOmode)
8009 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8010 [(set (match_dup 0)
8011 (match_op_dup 1
8012 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8013 (match_dup 3))
8014 (const_int 0)]))]
8015 "operands[2] = gen_lowpart (SImode, operands[2]);
8016 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8017
8018(define_split
8019 [(set (match_operand 0 "flags_reg_operand" "")
8020 (match_operator 1 "compare_operator"
8021 [(and (match_operand 2 "nonimmediate_operand" "")
8022 (match_operand 3 "const_int_operand" ""))
8023 (const_int 0)]))]
8024 "reload_completed
8025 && GET_MODE (operands[2]) != QImode
8026 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8027 && ((ix86_match_ccmode (insn, CCZmode)
8028 && !(INTVAL (operands[3]) & ~255))
8029 || (ix86_match_ccmode (insn, CCNOmode)
8030 && !(INTVAL (operands[3]) & ~127)))"
8031 [(set (match_dup 0)
8032 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8033 (const_int 0)]))]
8034 "operands[2] = gen_lowpart (QImode, operands[2]);
8035 operands[3] = gen_lowpart (QImode, operands[3]);")
8036
8037
8038;; %%% This used to optimize known byte-wide and operations to memory,
8039;; and sometimes to QImode registers. If this is considered useful,
8040;; it should be done with splitters.
8041
8042(define_expand "anddi3"
8043 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8044 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8045 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8046 (clobber (reg:CC FLAGS_REG))]
8047 "TARGET_64BIT"
8048 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8049
8050(define_insn "*anddi_1_rex64"
8051 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8052 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8053 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8054 (clobber (reg:CC FLAGS_REG))]
8055 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8056{
8057 switch (get_attr_type (insn))
8058 {
8059 case TYPE_IMOVX:
8060 {
8061 enum machine_mode mode;
8062
8063 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8064 if (INTVAL (operands[2]) == 0xff)
8065 mode = QImode;
8066 else
8067 {
8068 gcc_assert (INTVAL (operands[2]) == 0xffff);
8069 mode = HImode;
8070 }
8071
8072 operands[1] = gen_lowpart (mode, operands[1]);
8073 if (mode == QImode)
8074 return "movz{bq|x}\t{%1,%0|%0, %1}";
8075 else
8076 return "movz{wq|x}\t{%1,%0|%0, %1}";
8077 }
8078
8079 default:
8080 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8081 if (get_attr_mode (insn) == MODE_SI)
8082 return "and{l}\t{%k2, %k0|%k0, %k2}";
8083 else
8084 return "and{q}\t{%2, %0|%0, %2}";
8085 }
8086}
8087 [(set_attr "type" "alu,alu,alu,imovx")
8088 (set_attr "length_immediate" "*,*,*,0")
8089 (set_attr "mode" "SI,DI,DI,DI")])
8090
8091(define_insn "*anddi_2"
8092 [(set (reg FLAGS_REG)
8093 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8094 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8095 (const_int 0)))
8096 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8097 (and:DI (match_dup 1) (match_dup 2)))]
8098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8099 && ix86_binary_operator_ok (AND, DImode, operands)"
8100 "@
8101 and{l}\t{%k2, %k0|%k0, %k2}
8102 and{q}\t{%2, %0|%0, %2}
8103 and{q}\t{%2, %0|%0, %2}"
8104 [(set_attr "type" "alu")
8105 (set_attr "mode" "SI,DI,DI")])
8106
8107(define_expand "andsi3"
8108 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8109 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8110 (match_operand:SI 2 "general_operand" "")))
8111 (clobber (reg:CC FLAGS_REG))]
8112 ""
8113 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8114
8115(define_insn "*andsi_1"
8116 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8117 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8118 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8119 (clobber (reg:CC FLAGS_REG))]
8120 "ix86_binary_operator_ok (AND, SImode, operands)"
8121{
8122 switch (get_attr_type (insn))
8123 {
8124 case TYPE_IMOVX:
8125 {
8126 enum machine_mode mode;
8127
8128 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8129 if (INTVAL (operands[2]) == 0xff)
8130 mode = QImode;
8131 else
8132 {
8133 gcc_assert (INTVAL (operands[2]) == 0xffff);
8134 mode = HImode;
8135 }
8136
8137 operands[1] = gen_lowpart (mode, operands[1]);
8138 if (mode == QImode)
8139 return "movz{bl|x}\t{%1,%0|%0, %1}";
8140 else
8141 return "movz{wl|x}\t{%1,%0|%0, %1}";
8142 }
8143
8144 default:
8145 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8146 return "and{l}\t{%2, %0|%0, %2}";
8147 }
8148}
8149 [(set_attr "type" "alu,alu,imovx")
8150 (set_attr "length_immediate" "*,*,0")
8151 (set_attr "mode" "SI")])
8152
8153(define_split
8154 [(set (match_operand 0 "register_operand" "")
8155 (and (match_dup 0)
8156 (const_int -65536)))
8157 (clobber (reg:CC FLAGS_REG))]
8158 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8159 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8160 "operands[1] = gen_lowpart (HImode, operands[0]);")
8161
8162(define_split
8163 [(set (match_operand 0 "ext_register_operand" "")
8164 (and (match_dup 0)
8165 (const_int -256)))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8168 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8169 "operands[1] = gen_lowpart (QImode, operands[0]);")
8170
8171(define_split
8172 [(set (match_operand 0 "ext_register_operand" "")
8173 (and (match_dup 0)
8174 (const_int -65281)))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8177 [(parallel [(set (zero_extract:SI (match_dup 0)
8178 (const_int 8)
8179 (const_int 8))
8180 (xor:SI
8181 (zero_extract:SI (match_dup 0)
8182 (const_int 8)
8183 (const_int 8))
8184 (zero_extract:SI (match_dup 0)
8185 (const_int 8)
8186 (const_int 8))))
8187 (clobber (reg:CC FLAGS_REG))])]
8188 "operands[0] = gen_lowpart (SImode, operands[0]);")
8189
8190;; See comment for addsi_1_zext why we do use nonimmediate_operand
8191(define_insn "*andsi_1_zext"
8192 [(set (match_operand:DI 0 "register_operand" "=r")
8193 (zero_extend:DI
8194 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8195 (match_operand:SI 2 "general_operand" "rim"))))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8198 "and{l}\t{%2, %k0|%k0, %2}"
8199 [(set_attr "type" "alu")
8200 (set_attr "mode" "SI")])
8201
8202(define_insn "*andsi_2"
8203 [(set (reg FLAGS_REG)
8204 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8205 (match_operand:SI 2 "general_operand" "rim,ri"))
8206 (const_int 0)))
8207 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8208 (and:SI (match_dup 1) (match_dup 2)))]
8209 "ix86_match_ccmode (insn, CCNOmode)
8210 && ix86_binary_operator_ok (AND, SImode, operands)"
8211 "and{l}\t{%2, %0|%0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "SI")])
8214
8215;; See comment for addsi_1_zext why we do use nonimmediate_operand
8216(define_insn "*andsi_2_zext"
8217 [(set (reg FLAGS_REG)
8218 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8219 (match_operand:SI 2 "general_operand" "rim"))
8220 (const_int 0)))
8221 (set (match_operand:DI 0 "register_operand" "=r")
8222 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8223 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8224 && ix86_binary_operator_ok (AND, SImode, operands)"
8225 "and{l}\t{%2, %k0|%k0, %2}"
8226 [(set_attr "type" "alu")
8227 (set_attr "mode" "SI")])
8228
8229(define_expand "andhi3"
8230 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8231 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8232 (match_operand:HI 2 "general_operand" "")))
8233 (clobber (reg:CC FLAGS_REG))]
8234 "TARGET_HIMODE_MATH"
8235 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8236
8237(define_insn "*andhi_1"
8238 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8239 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8240 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8241 (clobber (reg:CC FLAGS_REG))]
8242 "ix86_binary_operator_ok (AND, HImode, operands)"
8243{
8244 switch (get_attr_type (insn))
8245 {
8246 case TYPE_IMOVX:
8247 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8248 gcc_assert (INTVAL (operands[2]) == 0xff);
8249 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8250
8251 default:
8252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8253
8254 return "and{w}\t{%2, %0|%0, %2}";
8255 }
8256}
8257 [(set_attr "type" "alu,alu,imovx")
8258 (set_attr "length_immediate" "*,*,0")
8259 (set_attr "mode" "HI,HI,SI")])
8260
8261(define_insn "*andhi_2"
8262 [(set (reg FLAGS_REG)
8263 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8264 (match_operand:HI 2 "general_operand" "rim,ri"))
8265 (const_int 0)))
8266 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8267 (and:HI (match_dup 1) (match_dup 2)))]
8268 "ix86_match_ccmode (insn, CCNOmode)
8269 && ix86_binary_operator_ok (AND, HImode, operands)"
8270 "and{w}\t{%2, %0|%0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "mode" "HI")])
8273
8274(define_expand "andqi3"
8275 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8276 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8277 (match_operand:QI 2 "general_operand" "")))
8278 (clobber (reg:CC FLAGS_REG))]
8279 "TARGET_QIMODE_MATH"
8280 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8281
8282;; %%% Potential partial reg stall on alternative 2. What to do?
8283(define_insn "*andqi_1"
8284 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8285 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8286 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8287 (clobber (reg:CC FLAGS_REG))]
8288 "ix86_binary_operator_ok (AND, QImode, operands)"
8289 "@
8290 and{b}\t{%2, %0|%0, %2}
8291 and{b}\t{%2, %0|%0, %2}
8292 and{l}\t{%k2, %k0|%k0, %k2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "QI,QI,SI")])
8295
8296(define_insn "*andqi_1_slp"
8297 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8298 (and:QI (match_dup 0)
8299 (match_operand:QI 1 "general_operand" "qi,qmi")))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8302 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8303 "and{b}\t{%1, %0|%0, %1}"
8304 [(set_attr "type" "alu1")
8305 (set_attr "mode" "QI")])
8306
8307(define_insn "*andqi_2_maybe_si"
8308 [(set (reg FLAGS_REG)
8309 (compare (and:QI
8310 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8311 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8312 (const_int 0)))
8313 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8314 (and:QI (match_dup 1) (match_dup 2)))]
8315 "ix86_binary_operator_ok (AND, QImode, operands)
8316 && ix86_match_ccmode (insn,
8317 GET_CODE (operands[2]) == CONST_INT
8318 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8319{
8320 if (which_alternative == 2)
8321 {
8322 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8323 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8324 return "and{l}\t{%2, %k0|%k0, %2}";
8325 }
8326 return "and{b}\t{%2, %0|%0, %2}";
8327}
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "QI,QI,SI")])
8330
8331(define_insn "*andqi_2"
8332 [(set (reg FLAGS_REG)
8333 (compare (and:QI
8334 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8335 (match_operand:QI 2 "general_operand" "qim,qi"))
8336 (const_int 0)))
8337 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8338 (and:QI (match_dup 1) (match_dup 2)))]
8339 "ix86_match_ccmode (insn, CCNOmode)
8340 && ix86_binary_operator_ok (AND, QImode, operands)"
8341 "and{b}\t{%2, %0|%0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "mode" "QI")])
8344
8345(define_insn "*andqi_2_slp"
8346 [(set (reg FLAGS_REG)
8347 (compare (and:QI
8348 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8349 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8350 (const_int 0)))
8351 (set (strict_low_part (match_dup 0))
8352 (and:QI (match_dup 0) (match_dup 1)))]
8353 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8354 && ix86_match_ccmode (insn, CCNOmode)
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;; ??? A bug in recog prevents it from recognizing a const_int as an
8361;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8362;; for a QImode operand, which of course failed.
8363
8364(define_insn "andqi_ext_0"
8365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366 (const_int 8)
8367 (const_int 8))
8368 (and:SI
8369 (zero_extract:SI
8370 (match_operand 1 "ext_register_operand" "0")
8371 (const_int 8)
8372 (const_int 8))
8373 (match_operand 2 "const_int_operand" "n")))
8374 (clobber (reg:CC FLAGS_REG))]
8375 ""
8376 "and{b}\t{%2, %h0|%h0, %2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "length_immediate" "1")
8379 (set_attr "mode" "QI")])
8380
8381;; Generated by peephole translating test to and. This shows up
8382;; often in fp comparisons.
8383
8384(define_insn "*andqi_ext_0_cc"
8385 [(set (reg FLAGS_REG)
8386 (compare
8387 (and:SI
8388 (zero_extract:SI
8389 (match_operand 1 "ext_register_operand" "0")
8390 (const_int 8)
8391 (const_int 8))
8392 (match_operand 2 "const_int_operand" "n"))
8393 (const_int 0)))
8394 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8395 (const_int 8)
8396 (const_int 8))
8397 (and:SI
8398 (zero_extract:SI
8399 (match_dup 1)
8400 (const_int 8)
8401 (const_int 8))
8402 (match_dup 2)))]
8403 "ix86_match_ccmode (insn, CCNOmode)"
8404 "and{b}\t{%2, %h0|%h0, %2}"
8405 [(set_attr "type" "alu")
8406 (set_attr "length_immediate" "1")
8407 (set_attr "mode" "QI")])
8408
8409(define_insn "*andqi_ext_1"
8410 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8411 (const_int 8)
8412 (const_int 8))
8413 (and:SI
8414 (zero_extract:SI
8415 (match_operand 1 "ext_register_operand" "0")
8416 (const_int 8)
8417 (const_int 8))
8418 (zero_extend:SI
8419 (match_operand:QI 2 "general_operand" "Qm"))))
8420 (clobber (reg:CC FLAGS_REG))]
8421 "!TARGET_64BIT"
8422 "and{b}\t{%2, %h0|%h0, %2}"
8423 [(set_attr "type" "alu")
8424 (set_attr "length_immediate" "0")
8425 (set_attr "mode" "QI")])
8426
8427(define_insn "*andqi_ext_1_rex64"
8428 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8429 (const_int 8)
8430 (const_int 8))
8431 (and:SI
8432 (zero_extract:SI
8433 (match_operand 1 "ext_register_operand" "0")
8434 (const_int 8)
8435 (const_int 8))
8436 (zero_extend:SI
8437 (match_operand 2 "ext_register_operand" "Q"))))
8438 (clobber (reg:CC FLAGS_REG))]
8439 "TARGET_64BIT"
8440 "and{b}\t{%2, %h0|%h0, %2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "length_immediate" "0")
8443 (set_attr "mode" "QI")])
8444
8445(define_insn "*andqi_ext_2"
8446 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8447 (const_int 8)
8448 (const_int 8))
8449 (and:SI
8450 (zero_extract:SI
8451 (match_operand 1 "ext_register_operand" "%0")
8452 (const_int 8)
8453 (const_int 8))
8454 (zero_extract:SI
8455 (match_operand 2 "ext_register_operand" "Q")
8456 (const_int 8)
8457 (const_int 8))))
8458 (clobber (reg:CC FLAGS_REG))]
8459 ""
8460 "and{b}\t{%h2, %h0|%h0, %h2}"
8461 [(set_attr "type" "alu")
8462 (set_attr "length_immediate" "0")
8463 (set_attr "mode" "QI")])
8464
8465;; Convert wide AND instructions with immediate operand to shorter QImode
8466;; equivalents when possible.
8467;; Don't do the splitting with memory operands, since it introduces risk
8468;; of memory mismatch stalls. We may want to do the splitting for optimizing
8469;; for size, but that can (should?) be handled by generic code instead.
8470(define_split
8471 [(set (match_operand 0 "register_operand" "")
8472 (and (match_operand 1 "register_operand" "")
8473 (match_operand 2 "const_int_operand" "")))
8474 (clobber (reg:CC FLAGS_REG))]
8475 "reload_completed
8476 && QI_REG_P (operands[0])
8477 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8478 && !(~INTVAL (operands[2]) & ~(255 << 8))
8479 && GET_MODE (operands[0]) != QImode"
8480 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8481 (and:SI (zero_extract:SI (match_dup 1)
8482 (const_int 8) (const_int 8))
8483 (match_dup 2)))
8484 (clobber (reg:CC FLAGS_REG))])]
8485 "operands[0] = gen_lowpart (SImode, operands[0]);
8486 operands[1] = gen_lowpart (SImode, operands[1]);
8487 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8488
8489;; Since AND can be encoded with sign extended immediate, this is only
8490;; profitable when 7th bit is not set.
8491(define_split
8492 [(set (match_operand 0 "register_operand" "")
8493 (and (match_operand 1 "general_operand" "")
8494 (match_operand 2 "const_int_operand" "")))
8495 (clobber (reg:CC FLAGS_REG))]
8496 "reload_completed
8497 && ANY_QI_REG_P (operands[0])
8498 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8499 && !(~INTVAL (operands[2]) & ~255)
8500 && !(INTVAL (operands[2]) & 128)
8501 && GET_MODE (operands[0]) != QImode"
8502 [(parallel [(set (strict_low_part (match_dup 0))
8503 (and:QI (match_dup 1)
8504 (match_dup 2)))
8505 (clobber (reg:CC FLAGS_REG))])]
8506 "operands[0] = gen_lowpart (QImode, operands[0]);
8507 operands[1] = gen_lowpart (QImode, operands[1]);
8508 operands[2] = gen_lowpart (QImode, operands[2]);")
8509
8510;; Logical inclusive OR instructions
8511
8512;; %%% This used to optimize known byte-wide and operations to memory.
8513;; If this is considered useful, it should be done with splitters.
8514
8515(define_expand "iordi3"
8516 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8517 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8518 (match_operand:DI 2 "x86_64_general_operand" "")))
8519 (clobber (reg:CC FLAGS_REG))]
8520 "TARGET_64BIT"
8521 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8522
8523(define_insn "*iordi_1_rex64"
8524 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8525 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8526 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8527 (clobber (reg:CC FLAGS_REG))]
8528 "TARGET_64BIT
8529 && ix86_binary_operator_ok (IOR, DImode, operands)"
8530 "or{q}\t{%2, %0|%0, %2}"
8531 [(set_attr "type" "alu")
8532 (set_attr "mode" "DI")])
8533
8534(define_insn "*iordi_2_rex64"
8535 [(set (reg FLAGS_REG)
8536 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8537 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8538 (const_int 0)))
8539 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8540 (ior:DI (match_dup 1) (match_dup 2)))]
8541 "TARGET_64BIT
8542 && ix86_match_ccmode (insn, CCNOmode)
8543 && ix86_binary_operator_ok (IOR, DImode, operands)"
8544 "or{q}\t{%2, %0|%0, %2}"
8545 [(set_attr "type" "alu")
8546 (set_attr "mode" "DI")])
8547
8548(define_insn "*iordi_3_rex64"
8549 [(set (reg FLAGS_REG)
8550 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8551 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8552 (const_int 0)))
8553 (clobber (match_scratch:DI 0 "=r"))]
8554 "TARGET_64BIT
8555 && ix86_match_ccmode (insn, CCNOmode)
8556 && ix86_binary_operator_ok (IOR, DImode, operands)"
8557 "or{q}\t{%2, %0|%0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "mode" "DI")])
8560
8561
8562(define_expand "iorsi3"
8563 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8564 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8565 (match_operand:SI 2 "general_operand" "")))
8566 (clobber (reg:CC FLAGS_REG))]
8567 ""
8568 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8569
8570(define_insn "*iorsi_1"
8571 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8572 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8573 (match_operand:SI 2 "general_operand" "ri,rmi")))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "ix86_binary_operator_ok (IOR, SImode, operands)"
8576 "or{l}\t{%2, %0|%0, %2}"
8577 [(set_attr "type" "alu")
8578 (set_attr "mode" "SI")])
8579
8580;; See comment for addsi_1_zext why we do use nonimmediate_operand
8581(define_insn "*iorsi_1_zext"
8582 [(set (match_operand:DI 0 "register_operand" "=rm")
8583 (zero_extend:DI
8584 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585 (match_operand:SI 2 "general_operand" "rim"))))
8586 (clobber (reg:CC FLAGS_REG))]
8587 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8588 "or{l}\t{%2, %k0|%k0, %2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "mode" "SI")])
8591
8592(define_insn "*iorsi_1_zext_imm"
8593 [(set (match_operand:DI 0 "register_operand" "=rm")
8594 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8595 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8596 (clobber (reg:CC FLAGS_REG))]
8597 "TARGET_64BIT"
8598 "or{l}\t{%2, %k0|%k0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "mode" "SI")])
8601
8602(define_insn "*iorsi_2"
8603 [(set (reg FLAGS_REG)
8604 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8605 (match_operand:SI 2 "general_operand" "rim,ri"))
8606 (const_int 0)))
8607 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8608 (ior:SI (match_dup 1) (match_dup 2)))]
8609 "ix86_match_ccmode (insn, CCNOmode)
8610 && ix86_binary_operator_ok (IOR, SImode, operands)"
8611 "or{l}\t{%2, %0|%0, %2}"
8612 [(set_attr "type" "alu")
8613 (set_attr "mode" "SI")])
8614
8615;; See comment for addsi_1_zext why we do use nonimmediate_operand
8616;; ??? Special case for immediate operand is missing - it is tricky.
8617(define_insn "*iorsi_2_zext"
8618 [(set (reg FLAGS_REG)
8619 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8620 (match_operand:SI 2 "general_operand" "rim"))
8621 (const_int 0)))
8622 (set (match_operand:DI 0 "register_operand" "=r")
8623 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8624 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8625 && 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_2_zext_imm"
8631 [(set (reg FLAGS_REG)
8632 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8633 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8634 (const_int 0)))
8635 (set (match_operand:DI 0 "register_operand" "=r")
8636 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8637 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8638 && ix86_binary_operator_ok (IOR, SImode, operands)"
8639 "or{l}\t{%2, %k0|%k0, %2}"
8640 [(set_attr "type" "alu")
8641 (set_attr "mode" "SI")])
8642
8643(define_insn "*iorsi_3"
8644 [(set (reg FLAGS_REG)
8645 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8646 (match_operand:SI 2 "general_operand" "rim"))
8647 (const_int 0)))
8648 (clobber (match_scratch:SI 0 "=r"))]
8649 "ix86_match_ccmode (insn, CCNOmode)
8650 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8651 "or{l}\t{%2, %0|%0, %2}"
8652 [(set_attr "type" "alu")
8653 (set_attr "mode" "SI")])
8654
8655(define_expand "iorhi3"
8656 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8657 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8658 (match_operand:HI 2 "general_operand" "")))
8659 (clobber (reg:CC FLAGS_REG))]
8660 "TARGET_HIMODE_MATH"
8661 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8662
8663(define_insn "*iorhi_1"
8664 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8665 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8666 (match_operand:HI 2 "general_operand" "rmi,ri")))
8667 (clobber (reg:CC FLAGS_REG))]
8668 "ix86_binary_operator_ok (IOR, HImode, operands)"
8669 "or{w}\t{%2, %0|%0, %2}"
8670 [(set_attr "type" "alu")
8671 (set_attr "mode" "HI")])
8672
8673(define_insn "*iorhi_2"
8674 [(set (reg FLAGS_REG)
8675 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8676 (match_operand:HI 2 "general_operand" "rim,ri"))
8677 (const_int 0)))
8678 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8679 (ior:HI (match_dup 1) (match_dup 2)))]
8680 "ix86_match_ccmode (insn, CCNOmode)
8681 && ix86_binary_operator_ok (IOR, HImode, operands)"
8682 "or{w}\t{%2, %0|%0, %2}"
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "HI")])
8685
8686(define_insn "*iorhi_3"
8687 [(set (reg FLAGS_REG)
8688 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8689 (match_operand:HI 2 "general_operand" "rim"))
8690 (const_int 0)))
8691 (clobber (match_scratch:HI 0 "=r"))]
8692 "ix86_match_ccmode (insn, CCNOmode)
8693 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8694 "or{w}\t{%2, %0|%0, %2}"
8695 [(set_attr "type" "alu")
8696 (set_attr "mode" "HI")])
8697
8698(define_expand "iorqi3"
8699 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8700 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8701 (match_operand:QI 2 "general_operand" "")))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "TARGET_QIMODE_MATH"
8704 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8705
8706;; %%% Potential partial reg stall on alternative 2. What to do?
8707(define_insn "*iorqi_1"
8708 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8709 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8710 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "ix86_binary_operator_ok (IOR, QImode, operands)"
8713 "@
8714 or{b}\t{%2, %0|%0, %2}
8715 or{b}\t{%2, %0|%0, %2}
8716 or{l}\t{%k2, %k0|%k0, %k2}"
8717 [(set_attr "type" "alu")
8718 (set_attr "mode" "QI,QI,SI")])
8719
8720(define_insn "*iorqi_1_slp"
8721 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8722 (ior:QI (match_dup 0)
8723 (match_operand:QI 1 "general_operand" "qmi,qi")))
8724 (clobber (reg:CC FLAGS_REG))]
8725 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8726 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8727 "or{b}\t{%1, %0|%0, %1}"
8728 [(set_attr "type" "alu1")
8729 (set_attr "mode" "QI")])
8730
8731(define_insn "*iorqi_2"
8732 [(set (reg FLAGS_REG)
8733 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8734 (match_operand:QI 2 "general_operand" "qim,qi"))
8735 (const_int 0)))
8736 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8737 (ior:QI (match_dup 1) (match_dup 2)))]
8738 "ix86_match_ccmode (insn, CCNOmode)
8739 && ix86_binary_operator_ok (IOR, QImode, operands)"
8740 "or{b}\t{%2, %0|%0, %2}"
8741 [(set_attr "type" "alu")
8742 (set_attr "mode" "QI")])
8743
8744(define_insn "*iorqi_2_slp"
8745 [(set (reg FLAGS_REG)
8746 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8747 (match_operand:QI 1 "general_operand" "qim,qi"))
8748 (const_int 0)))
8749 (set (strict_low_part (match_dup 0))
8750 (ior:QI (match_dup 0) (match_dup 1)))]
8751 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8752 && ix86_match_ccmode (insn, CCNOmode)
8753 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8754 "or{b}\t{%1, %0|%0, %1}"
8755 [(set_attr "type" "alu1")
8756 (set_attr "mode" "QI")])
8757
8758(define_insn "*iorqi_3"
8759 [(set (reg FLAGS_REG)
8760 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8761 (match_operand:QI 2 "general_operand" "qim"))
8762 (const_int 0)))
8763 (clobber (match_scratch:QI 0 "=q"))]
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8766 "or{b}\t{%2, %0|%0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "QI")])
8769
8770(define_insn "iorqi_ext_0"
8771 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772 (const_int 8)
8773 (const_int 8))
8774 (ior:SI
8775 (zero_extract:SI
8776 (match_operand 1 "ext_register_operand" "0")
8777 (const_int 8)
8778 (const_int 8))
8779 (match_operand 2 "const_int_operand" "n")))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8782 "or{b}\t{%2, %h0|%h0, %2}"
8783 [(set_attr "type" "alu")
8784 (set_attr "length_immediate" "1")
8785 (set_attr "mode" "QI")])
8786
8787(define_insn "*iorqi_ext_1"
8788 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8789 (const_int 8)
8790 (const_int 8))
8791 (ior:SI
8792 (zero_extract:SI
8793 (match_operand 1 "ext_register_operand" "0")
8794 (const_int 8)
8795 (const_int 8))
8796 (zero_extend:SI
8797 (match_operand:QI 2 "general_operand" "Qm"))))
8798 (clobber (reg:CC FLAGS_REG))]
8799 "!TARGET_64BIT
8800 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8801 "or{b}\t{%2, %h0|%h0, %2}"
8802 [(set_attr "type" "alu")
8803 (set_attr "length_immediate" "0")
8804 (set_attr "mode" "QI")])
8805
8806(define_insn "*iorqi_ext_1_rex64"
8807 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8808 (const_int 8)
8809 (const_int 8))
8810 (ior:SI
8811 (zero_extract:SI
8812 (match_operand 1 "ext_register_operand" "0")
8813 (const_int 8)
8814 (const_int 8))
8815 (zero_extend:SI
8816 (match_operand 2 "ext_register_operand" "Q"))))
8817 (clobber (reg:CC FLAGS_REG))]
8818 "TARGET_64BIT
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" "0")
8823 (set_attr "mode" "QI")])
8824
8825(define_insn "*iorqi_ext_2"
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 (match_operand 1 "ext_register_operand" "0")
8831 (const_int 8)
8832 (const_int 8))
8833 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8834 (const_int 8)
8835 (const_int 8))))
8836 (clobber (reg:CC FLAGS_REG))]
8837 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8838 "ior{b}\t{%h2, %h0|%h0, %h2}"
8839 [(set_attr "type" "alu")
8840 (set_attr "length_immediate" "0")
8841 (set_attr "mode" "QI")])
8842
8843(define_split
8844 [(set (match_operand 0 "register_operand" "")
8845 (ior (match_operand 1 "register_operand" "")
8846 (match_operand 2 "const_int_operand" "")))
8847 (clobber (reg:CC FLAGS_REG))]
8848 "reload_completed
8849 && QI_REG_P (operands[0])
8850 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8851 && !(INTVAL (operands[2]) & ~(255 << 8))
8852 && GET_MODE (operands[0]) != QImode"
8853 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8854 (ior:SI (zero_extract:SI (match_dup 1)
8855 (const_int 8) (const_int 8))
8856 (match_dup 2)))
8857 (clobber (reg:CC FLAGS_REG))])]
8858 "operands[0] = gen_lowpart (SImode, operands[0]);
8859 operands[1] = gen_lowpart (SImode, operands[1]);
8860 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8861
8862;; Since OR can be encoded with sign extended immediate, this is only
8863;; profitable when 7th bit is set.
8864(define_split
8865 [(set (match_operand 0 "register_operand" "")
8866 (ior (match_operand 1 "general_operand" "")
8867 (match_operand 2 "const_int_operand" "")))
8868 (clobber (reg:CC FLAGS_REG))]
8869 "reload_completed
8870 && ANY_QI_REG_P (operands[0])
8871 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8872 && !(INTVAL (operands[2]) & ~255)
8873 && (INTVAL (operands[2]) & 128)
8874 && GET_MODE (operands[0]) != QImode"
8875 [(parallel [(set (strict_low_part (match_dup 0))
8876 (ior:QI (match_dup 1)
8877 (match_dup 2)))
8878 (clobber (reg:CC FLAGS_REG))])]
8879 "operands[0] = gen_lowpart (QImode, operands[0]);
8880 operands[1] = gen_lowpart (QImode, operands[1]);
8881 operands[2] = gen_lowpart (QImode, operands[2]);")
8882
8883;; Logical XOR instructions
8884
8885;; %%% This used to optimize known byte-wide and operations to memory.
8886;; If this is considered useful, it should be done with splitters.
8887
8888(define_expand "xordi3"
8889 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8890 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8891 (match_operand:DI 2 "x86_64_general_operand" "")))
8892 (clobber (reg:CC FLAGS_REG))]
8893 "TARGET_64BIT"
8894 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8895
8896(define_insn "*xordi_1_rex64"
8897 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8898 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8899 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8900 (clobber (reg:CC FLAGS_REG))]
8901 "TARGET_64BIT
8902 && ix86_binary_operator_ok (XOR, DImode, operands)"
8903 "@
8904 xor{q}\t{%2, %0|%0, %2}
8905 xor{q}\t{%2, %0|%0, %2}"
8906 [(set_attr "type" "alu")
8907 (set_attr "mode" "DI,DI")])
8908
8909(define_insn "*xordi_2_rex64"
8910 [(set (reg FLAGS_REG)
8911 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8912 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8913 (const_int 0)))
8914 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8915 (xor:DI (match_dup 1) (match_dup 2)))]
8916 "TARGET_64BIT
8917 && ix86_match_ccmode (insn, CCNOmode)
8918 && ix86_binary_operator_ok (XOR, DImode, operands)"
8919 "@
8920 xor{q}\t{%2, %0|%0, %2}
8921 xor{q}\t{%2, %0|%0, %2}"
8922 [(set_attr "type" "alu")
8923 (set_attr "mode" "DI,DI")])
8924
8925(define_insn "*xordi_3_rex64"
8926 [(set (reg FLAGS_REG)
8927 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8928 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8929 (const_int 0)))
8930 (clobber (match_scratch:DI 0 "=r"))]
8931 "TARGET_64BIT
8932 && ix86_match_ccmode (insn, CCNOmode)
8933 && ix86_binary_operator_ok (XOR, DImode, operands)"
8934 "xor{q}\t{%2, %0|%0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "DI")])
8937
8938(define_expand "xorsi3"
8939 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8940 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8941 (match_operand:SI 2 "general_operand" "")))
8942 (clobber (reg:CC FLAGS_REG))]
8943 ""
8944 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8945
8946(define_insn "*xorsi_1"
8947 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8948 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8949 (match_operand:SI 2 "general_operand" "ri,rm")))
8950 (clobber (reg:CC FLAGS_REG))]
8951 "ix86_binary_operator_ok (XOR, SImode, operands)"
8952 "xor{l}\t{%2, %0|%0, %2}"
8953 [(set_attr "type" "alu")
8954 (set_attr "mode" "SI")])
8955
8956;; See comment for addsi_1_zext why we do use nonimmediate_operand
8957;; Add speccase for immediates
8958(define_insn "*xorsi_1_zext"
8959 [(set (match_operand:DI 0 "register_operand" "=r")
8960 (zero_extend:DI
8961 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8962 (match_operand:SI 2 "general_operand" "rim"))))
8963 (clobber (reg:CC FLAGS_REG))]
8964 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8965 "xor{l}\t{%2, %k0|%k0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "SI")])
8968
8969(define_insn "*xorsi_1_zext_imm"
8970 [(set (match_operand:DI 0 "register_operand" "=r")
8971 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8972 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8973 (clobber (reg:CC FLAGS_REG))]
8974 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8975 "xor{l}\t{%2, %k0|%k0, %2}"
8976 [(set_attr "type" "alu")
8977 (set_attr "mode" "SI")])
8978
8979(define_insn "*xorsi_2"
8980 [(set (reg FLAGS_REG)
8981 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8982 (match_operand:SI 2 "general_operand" "rim,ri"))
8983 (const_int 0)))
8984 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8985 (xor:SI (match_dup 1) (match_dup 2)))]
8986 "ix86_match_ccmode (insn, CCNOmode)
8987 && ix86_binary_operator_ok (XOR, SImode, operands)"
8988 "xor{l}\t{%2, %0|%0, %2}"
8989 [(set_attr "type" "alu")
8990 (set_attr "mode" "SI")])
8991
8992;; See comment for addsi_1_zext why we do use nonimmediate_operand
8993;; ??? Special case for immediate operand is missing - it is tricky.
8994(define_insn "*xorsi_2_zext"
8995 [(set (reg FLAGS_REG)
8996 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8997 (match_operand:SI 2 "general_operand" "rim"))
8998 (const_int 0)))
8999 (set (match_operand:DI 0 "register_operand" "=r")
9000 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9001 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9002 && 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_2_zext_imm"
9008 [(set (reg FLAGS_REG)
9009 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9010 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9011 (const_int 0)))
9012 (set (match_operand:DI 0 "register_operand" "=r")
9013 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9014 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9015 && ix86_binary_operator_ok (XOR, SImode, operands)"
9016 "xor{l}\t{%2, %k0|%k0, %2}"
9017 [(set_attr "type" "alu")
9018 (set_attr "mode" "SI")])
9019
9020(define_insn "*xorsi_3"
9021 [(set (reg FLAGS_REG)
9022 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9023 (match_operand:SI 2 "general_operand" "rim"))
9024 (const_int 0)))
9025 (clobber (match_scratch:SI 0 "=r"))]
9026 "ix86_match_ccmode (insn, CCNOmode)
9027 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9028 "xor{l}\t{%2, %0|%0, %2}"
9029 [(set_attr "type" "alu")
9030 (set_attr "mode" "SI")])
9031
9032(define_expand "xorhi3"
9033 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9034 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9035 (match_operand:HI 2 "general_operand" "")))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "TARGET_HIMODE_MATH"
9038 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9039
9040(define_insn "*xorhi_1"
9041 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9042 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9043 (match_operand:HI 2 "general_operand" "rmi,ri")))
9044 (clobber (reg:CC FLAGS_REG))]
9045 "ix86_binary_operator_ok (XOR, HImode, operands)"
9046 "xor{w}\t{%2, %0|%0, %2}"
9047 [(set_attr "type" "alu")
9048 (set_attr "mode" "HI")])
9049
9050(define_insn "*xorhi_2"
9051 [(set (reg FLAGS_REG)
9052 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9053 (match_operand:HI 2 "general_operand" "rim,ri"))
9054 (const_int 0)))
9055 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9056 (xor:HI (match_dup 1) (match_dup 2)))]
9057 "ix86_match_ccmode (insn, CCNOmode)
9058 && ix86_binary_operator_ok (XOR, HImode, operands)"
9059 "xor{w}\t{%2, %0|%0, %2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "HI")])
9062
9063(define_insn "*xorhi_3"
9064 [(set (reg FLAGS_REG)
9065 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9066 (match_operand:HI 2 "general_operand" "rim"))
9067 (const_int 0)))
9068 (clobber (match_scratch:HI 0 "=r"))]
9069 "ix86_match_ccmode (insn, CCNOmode)
9070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9071 "xor{w}\t{%2, %0|%0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "mode" "HI")])
9074
9075(define_expand "xorqi3"
9076 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9077 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9078 (match_operand:QI 2 "general_operand" "")))
9079 (clobber (reg:CC FLAGS_REG))]
9080 "TARGET_QIMODE_MATH"
9081 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9082
9083;; %%% Potential partial reg stall on alternative 2. What to do?
9084(define_insn "*xorqi_1"
9085 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9086 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9087 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9088 (clobber (reg:CC FLAGS_REG))]
9089 "ix86_binary_operator_ok (XOR, QImode, operands)"
9090 "@
9091 xor{b}\t{%2, %0|%0, %2}
9092 xor{b}\t{%2, %0|%0, %2}
9093 xor{l}\t{%k2, %k0|%k0, %k2}"
9094 [(set_attr "type" "alu")
9095 (set_attr "mode" "QI,QI,SI")])
9096
9097(define_insn "*xorqi_1_slp"
9098 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9099 (xor:QI (match_dup 0)
9100 (match_operand:QI 1 "general_operand" "qi,qmi")))
9101 (clobber (reg:CC FLAGS_REG))]
9102 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9103 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9104 "xor{b}\t{%1, %0|%0, %1}"
9105 [(set_attr "type" "alu1")
9106 (set_attr "mode" "QI")])
9107
9108(define_insn "xorqi_ext_0"
9109 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9110 (const_int 8)
9111 (const_int 8))
9112 (xor:SI
9113 (zero_extract:SI
9114 (match_operand 1 "ext_register_operand" "0")
9115 (const_int 8)
9116 (const_int 8))
9117 (match_operand 2 "const_int_operand" "n")))
9118 (clobber (reg:CC FLAGS_REG))]
9119 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120 "xor{b}\t{%2, %h0|%h0, %2}"
9121 [(set_attr "type" "alu")
9122 (set_attr "length_immediate" "1")
9123 (set_attr "mode" "QI")])
9124
9125(define_insn "*xorqi_ext_1"
9126 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127 (const_int 8)
9128 (const_int 8))
9129 (xor:SI
9130 (zero_extract:SI
9131 (match_operand 1 "ext_register_operand" "0")
9132 (const_int 8)
9133 (const_int 8))
9134 (zero_extend:SI
9135 (match_operand:QI 2 "general_operand" "Qm"))))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "!TARGET_64BIT
9138 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9139 "xor{b}\t{%2, %h0|%h0, %2}"
9140 [(set_attr "type" "alu")
9141 (set_attr "length_immediate" "0")
9142 (set_attr "mode" "QI")])
9143
9144(define_insn "*xorqi_ext_1_rex64"
9145 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9146 (const_int 8)
9147 (const_int 8))
9148 (xor:SI
9149 (zero_extract:SI
9150 (match_operand 1 "ext_register_operand" "0")
9151 (const_int 8)
9152 (const_int 8))
9153 (zero_extend:SI
9154 (match_operand 2 "ext_register_operand" "Q"))))
9155 (clobber (reg:CC FLAGS_REG))]
9156 "TARGET_64BIT
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" "0")
9161 (set_attr "mode" "QI")])
9162
9163(define_insn "*xorqi_ext_2"
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 (match_operand 1 "ext_register_operand" "0")
9169 (const_int 8)
9170 (const_int 8))
9171 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9172 (const_int 8)
9173 (const_int 8))))
9174 (clobber (reg:CC FLAGS_REG))]
9175 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9176 "xor{b}\t{%h2, %h0|%h0, %h2}"
9177 [(set_attr "type" "alu")
9178 (set_attr "length_immediate" "0")
9179 (set_attr "mode" "QI")])
9180
9181(define_insn "*xorqi_cc_1"
9182 [(set (reg FLAGS_REG)
9183 (compare
9184 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9185 (match_operand:QI 2 "general_operand" "qim,qi"))
9186 (const_int 0)))
9187 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9188 (xor:QI (match_dup 1) (match_dup 2)))]
9189 "ix86_match_ccmode (insn, CCNOmode)
9190 && ix86_binary_operator_ok (XOR, QImode, operands)"
9191 "xor{b}\t{%2, %0|%0, %2}"
9192 [(set_attr "type" "alu")
9193 (set_attr "mode" "QI")])
9194
9195(define_insn "*xorqi_2_slp"
9196 [(set (reg FLAGS_REG)
9197 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9198 (match_operand:QI 1 "general_operand" "qim,qi"))
9199 (const_int 0)))
9200 (set (strict_low_part (match_dup 0))
9201 (xor:QI (match_dup 0) (match_dup 1)))]
9202 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9203 && ix86_match_ccmode (insn, CCNOmode)
9204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9205 "xor{b}\t{%1, %0|%0, %1}"
9206 [(set_attr "type" "alu1")
9207 (set_attr "mode" "QI")])
9208
9209(define_insn "*xorqi_cc_2"
9210 [(set (reg FLAGS_REG)
9211 (compare
9212 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9213 (match_operand:QI 2 "general_operand" "qim"))
9214 (const_int 0)))
9215 (clobber (match_scratch:QI 0 "=q"))]
9216 "ix86_match_ccmode (insn, CCNOmode)
9217 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9218 "xor{b}\t{%2, %0|%0, %2}"
9219 [(set_attr "type" "alu")
9220 (set_attr "mode" "QI")])
9221
9222(define_insn "*xorqi_cc_ext_1"
9223 [(set (reg FLAGS_REG)
9224 (compare
9225 (xor:SI
9226 (zero_extract:SI
9227 (match_operand 1 "ext_register_operand" "0")
9228 (const_int 8)
9229 (const_int 8))
9230 (match_operand:QI 2 "general_operand" "qmn"))
9231 (const_int 0)))
9232 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9233 (const_int 8)
9234 (const_int 8))
9235 (xor:SI
9236 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9237 (match_dup 2)))]
9238 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9239 "xor{b}\t{%2, %h0|%h0, %2}"
9240 [(set_attr "type" "alu")
9241 (set_attr "mode" "QI")])
9242
9243(define_insn "*xorqi_cc_ext_1_rex64"
9244 [(set (reg FLAGS_REG)
9245 (compare
9246 (xor:SI
9247 (zero_extract:SI
9248 (match_operand 1 "ext_register_operand" "0")
9249 (const_int 8)
9250 (const_int 8))
9251 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9252 (const_int 0)))
9253 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9254 (const_int 8)
9255 (const_int 8))
9256 (xor:SI
9257 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9258 (match_dup 2)))]
9259 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9260 "xor{b}\t{%2, %h0|%h0, %2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "mode" "QI")])
9263
9264(define_expand "xorqi_cc_ext_1"
9265 [(parallel [
9266 (set (reg:CCNO FLAGS_REG)
9267 (compare:CCNO
9268 (xor:SI
9269 (zero_extract:SI
9270 (match_operand 1 "ext_register_operand" "")
9271 (const_int 8)
9272 (const_int 8))
9273 (match_operand:QI 2 "general_operand" ""))
9274 (const_int 0)))
9275 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9276 (const_int 8)
9277 (const_int 8))
9278 (xor:SI
9279 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9280 (match_dup 2)))])]
9281 ""
9282 "")
9283
9284(define_split
9285 [(set (match_operand 0 "register_operand" "")
9286 (xor (match_operand 1 "register_operand" "")
9287 (match_operand 2 "const_int_operand" "")))
9288 (clobber (reg:CC FLAGS_REG))]
9289 "reload_completed
9290 && QI_REG_P (operands[0])
9291 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9292 && !(INTVAL (operands[2]) & ~(255 << 8))
9293 && GET_MODE (operands[0]) != QImode"
9294 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9295 (xor:SI (zero_extract:SI (match_dup 1)
9296 (const_int 8) (const_int 8))
9297 (match_dup 2)))
9298 (clobber (reg:CC FLAGS_REG))])]
9299 "operands[0] = gen_lowpart (SImode, operands[0]);
9300 operands[1] = gen_lowpart (SImode, operands[1]);
9301 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9302
9303;; Since XOR can be encoded with sign extended immediate, this is only
9304;; profitable when 7th bit is set.
9305(define_split
9306 [(set (match_operand 0 "register_operand" "")
9307 (xor (match_operand 1 "general_operand" "")
9308 (match_operand 2 "const_int_operand" "")))
9309 (clobber (reg:CC FLAGS_REG))]
9310 "reload_completed
9311 && ANY_QI_REG_P (operands[0])
9312 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9313 && !(INTVAL (operands[2]) & ~255)
9314 && (INTVAL (operands[2]) & 128)
9315 && GET_MODE (operands[0]) != QImode"
9316 [(parallel [(set (strict_low_part (match_dup 0))
9317 (xor:QI (match_dup 1)
9318 (match_dup 2)))
9319 (clobber (reg:CC FLAGS_REG))])]
9320 "operands[0] = gen_lowpart (QImode, operands[0]);
9321 operands[1] = gen_lowpart (QImode, operands[1]);
9322 operands[2] = gen_lowpart (QImode, operands[2]);")
9323
9324;; Negation instructions
9325
9326(define_expand "negti2"
9327 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9328 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9329 (clobber (reg:CC FLAGS_REG))])]
9330 "TARGET_64BIT"
9331 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9332
9333(define_insn "*negti2_1"
9334 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9335 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9336 (clobber (reg:CC FLAGS_REG))]
9337 "TARGET_64BIT
9338 && ix86_unary_operator_ok (NEG, TImode, operands)"
9339 "#")
9340
9341(define_split
9342 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9343 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9344 (clobber (reg:CC FLAGS_REG))]
9345 "TARGET_64BIT && reload_completed"
9346 [(parallel
9347 [(set (reg:CCZ FLAGS_REG)
9348 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9349 (set (match_dup 0) (neg:DI (match_dup 2)))])
9350 (parallel
9351 [(set (match_dup 1)
9352 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9353 (match_dup 3))
9354 (const_int 0)))
9355 (clobber (reg:CC FLAGS_REG))])
9356 (parallel
9357 [(set (match_dup 1)
9358 (neg:DI (match_dup 1)))
9359 (clobber (reg:CC FLAGS_REG))])]
9360 "split_ti (operands+1, 1, operands+2, operands+3);
9361 split_ti (operands+0, 1, operands+0, operands+1);")
9362
9363(define_expand "negdi2"
9364 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9365 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9366 (clobber (reg:CC FLAGS_REG))])]
9367 ""
9368 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9369
9370(define_insn "*negdi2_1"
9371 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9372 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9373 (clobber (reg:CC FLAGS_REG))]
9374 "!TARGET_64BIT
9375 && ix86_unary_operator_ok (NEG, DImode, operands)"
9376 "#")
9377
9378(define_split
9379 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9380 (neg:DI (match_operand:DI 1 "general_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "!TARGET_64BIT && reload_completed"
9383 [(parallel
9384 [(set (reg:CCZ FLAGS_REG)
9385 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9386 (set (match_dup 0) (neg:SI (match_dup 2)))])
9387 (parallel
9388 [(set (match_dup 1)
9389 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9390 (match_dup 3))
9391 (const_int 0)))
9392 (clobber (reg:CC FLAGS_REG))])
9393 (parallel
9394 [(set (match_dup 1)
9395 (neg:SI (match_dup 1)))
9396 (clobber (reg:CC FLAGS_REG))])]
9397 "split_di (operands+1, 1, operands+2, operands+3);
9398 split_di (operands+0, 1, operands+0, operands+1);")
9399
9400(define_insn "*negdi2_1_rex64"
9401 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9402 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9403 (clobber (reg:CC FLAGS_REG))]
9404 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9405 "neg{q}\t%0"
9406 [(set_attr "type" "negnot")
9407 (set_attr "mode" "DI")])
9408
9409;; The problem with neg is that it does not perform (compare x 0),
9410;; it really performs (compare 0 x), which leaves us with the zero
9411;; flag being the only useful item.
9412
9413(define_insn "*negdi2_cmpz_rex64"
9414 [(set (reg:CCZ FLAGS_REG)
9415 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9416 (const_int 0)))
9417 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9418 (neg:DI (match_dup 1)))]
9419 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9420 "neg{q}\t%0"
9421 [(set_attr "type" "negnot")
9422 (set_attr "mode" "DI")])
9423
9424
9425(define_expand "negsi2"
9426 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9427 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9428 (clobber (reg:CC FLAGS_REG))])]
9429 ""
9430 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9431
9432(define_insn "*negsi2_1"
9433 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9434 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9435 (clobber (reg:CC FLAGS_REG))]
9436 "ix86_unary_operator_ok (NEG, SImode, operands)"
9437 "neg{l}\t%0"
9438 [(set_attr "type" "negnot")
9439 (set_attr "mode" "SI")])
9440
9441;; Combine is quite creative about this pattern.
9442(define_insn "*negsi2_1_zext"
9443 [(set (match_operand:DI 0 "register_operand" "=r")
9444 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9445 (const_int 32)))
9446 (const_int 32)))
9447 (clobber (reg:CC FLAGS_REG))]
9448 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9449 "neg{l}\t%k0"
9450 [(set_attr "type" "negnot")
9451 (set_attr "mode" "SI")])
9452
9453;; The problem with neg is that it does not perform (compare x 0),
9454;; it really performs (compare 0 x), which leaves us with the zero
9455;; flag being the only useful item.
9456
9457(define_insn "*negsi2_cmpz"
9458 [(set (reg:CCZ FLAGS_REG)
9459 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9460 (const_int 0)))
9461 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9462 (neg:SI (match_dup 1)))]
9463 "ix86_unary_operator_ok (NEG, SImode, operands)"
9464 "neg{l}\t%0"
9465 [(set_attr "type" "negnot")
9466 (set_attr "mode" "SI")])
9467
9468(define_insn "*negsi2_cmpz_zext"
9469 [(set (reg:CCZ FLAGS_REG)
9470 (compare:CCZ (lshiftrt:DI
9471 (neg:DI (ashift:DI
9472 (match_operand:DI 1 "register_operand" "0")
9473 (const_int 32)))
9474 (const_int 32))
9475 (const_int 0)))
9476 (set (match_operand:DI 0 "register_operand" "=r")
9477 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9478 (const_int 32)))
9479 (const_int 32)))]
9480 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9481 "neg{l}\t%k0"
9482 [(set_attr "type" "negnot")
9483 (set_attr "mode" "SI")])
9484
9485(define_expand "neghi2"
9486 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9487 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9488 (clobber (reg:CC FLAGS_REG))])]
9489 "TARGET_HIMODE_MATH"
9490 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9491
9492(define_insn "*neghi2_1"
9493 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9494 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9495 (clobber (reg:CC FLAGS_REG))]
9496 "ix86_unary_operator_ok (NEG, HImode, operands)"
9497 "neg{w}\t%0"
9498 [(set_attr "type" "negnot")
9499 (set_attr "mode" "HI")])
9500
9501(define_insn "*neghi2_cmpz"
9502 [(set (reg:CCZ FLAGS_REG)
9503 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9504 (const_int 0)))
9505 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9506 (neg:HI (match_dup 1)))]
9507 "ix86_unary_operator_ok (NEG, HImode, operands)"
9508 "neg{w}\t%0"
9509 [(set_attr "type" "negnot")
9510 (set_attr "mode" "HI")])
9511
9512(define_expand "negqi2"
9513 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9514 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9515 (clobber (reg:CC FLAGS_REG))])]
9516 "TARGET_QIMODE_MATH"
9517 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9518
9519(define_insn "*negqi2_1"
9520 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9521 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9522 (clobber (reg:CC FLAGS_REG))]
9523 "ix86_unary_operator_ok (NEG, QImode, operands)"
9524 "neg{b}\t%0"
9525 [(set_attr "type" "negnot")
9526 (set_attr "mode" "QI")])
9527
9528(define_insn "*negqi2_cmpz"
9529 [(set (reg:CCZ FLAGS_REG)
9530 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9531 (const_int 0)))
9532 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9533 (neg:QI (match_dup 1)))]
9534 "ix86_unary_operator_ok (NEG, QImode, operands)"
9535 "neg{b}\t%0"
9536 [(set_attr "type" "negnot")
9537 (set_attr "mode" "QI")])
9538
9539;; Changing of sign for FP values is doable using integer unit too.
9540
9541(define_expand "negsf2"
9542 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544 "TARGET_80387 || TARGET_SSE_MATH"
9545 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9546
9547(define_expand "abssf2"
9548 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9549 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9550 "TARGET_80387 || TARGET_SSE_MATH"
9551 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9552
9553(define_insn "*absnegsf2_mixed"
9554 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9555 (match_operator:SF 3 "absneg_operator"
9556 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9557 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9558 (clobber (reg:CC FLAGS_REG))]
9559 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9560 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9561 "#")
9562
9563(define_insn "*absnegsf2_sse"
9564 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9565 (match_operator:SF 3 "absneg_operator"
9566 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9567 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9568 (clobber (reg:CC FLAGS_REG))]
9569 "TARGET_SSE_MATH
9570 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9571 "#")
9572
9573(define_insn "*absnegsf2_i387"
9574 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9575 (match_operator:SF 3 "absneg_operator"
9576 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9577 (use (match_operand 2 "" ""))
9578 (clobber (reg:CC FLAGS_REG))]
9579 "TARGET_80387 && !TARGET_SSE_MATH
9580 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9581 "#")
9582
9583(define_expand "copysignsf3"
9584 [(match_operand:SF 0 "register_operand" "")
9585 (match_operand:SF 1 "nonmemory_operand" "")
9586 (match_operand:SF 2 "register_operand" "")]
9587 "TARGET_SSE_MATH"
9588{
9589 ix86_expand_copysign (operands);
9590 DONE;
9591})
9592
9593(define_insn_and_split "copysignsf3_const"
9594 [(set (match_operand:SF 0 "register_operand" "=x")
9595 (unspec:SF
9596 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9597 (match_operand:SF 2 "register_operand" "0")
9598 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9599 UNSPEC_COPYSIGN))]
9600 "TARGET_SSE_MATH"
9601 "#"
9602 "&& reload_completed"
9603 [(const_int 0)]
9604{
9605 ix86_split_copysign_const (operands);
9606 DONE;
9607})
9608
9609(define_insn "copysignsf3_var"
9610 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9611 (unspec:SF
9612 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9613 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9614 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9615 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9616 UNSPEC_COPYSIGN))
9617 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9618 "TARGET_SSE_MATH"
9619 "#")
9620
9621(define_split
9622 [(set (match_operand:SF 0 "register_operand" "")
9623 (unspec:SF
9624 [(match_operand:SF 2 "register_operand" "")
9625 (match_operand:SF 3 "register_operand" "")
9626 (match_operand:V4SF 4 "" "")
9627 (match_operand:V4SF 5 "" "")]
9628 UNSPEC_COPYSIGN))
9629 (clobber (match_scratch:V4SF 1 ""))]
9630 "TARGET_SSE_MATH && reload_completed"
9631 [(const_int 0)]
9632{
9633 ix86_split_copysign_var (operands);
9634 DONE;
9635})
9636
9637(define_expand "negdf2"
9638 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9642
9643(define_expand "absdf2"
9644 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9645 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9646 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9647 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9648
9649(define_insn "*absnegdf2_mixed"
9650 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9651 (match_operator:DF 3 "absneg_operator"
9652 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9653 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9654 (clobber (reg:CC FLAGS_REG))]
9655 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9656 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9657 "#")
9658
9659(define_insn "*absnegdf2_sse"
9660 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9661 (match_operator:DF 3 "absneg_operator"
9662 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9663 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9664 (clobber (reg:CC FLAGS_REG))]
9665 "TARGET_SSE2 && TARGET_SSE_MATH
9666 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9667 "#")
9668
9669(define_insn "*absnegdf2_i387"
9670 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9671 (match_operator:DF 3 "absneg_operator"
9672 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9673 (use (match_operand 2 "" ""))
9674 (clobber (reg:CC FLAGS_REG))]
9675 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9676 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9677 "#")
9678
9679(define_expand "copysigndf3"
9680 [(match_operand:DF 0 "register_operand" "")
9681 (match_operand:DF 1 "nonmemory_operand" "")
9682 (match_operand:DF 2 "register_operand" "")]
9683 "TARGET_SSE2 && TARGET_SSE_MATH"
9684{
9685 ix86_expand_copysign (operands);
9686 DONE;
9687})
9688
9689(define_insn_and_split "copysigndf3_const"
9690 [(set (match_operand:DF 0 "register_operand" "=x")
9691 (unspec:DF
9692 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9693 (match_operand:DF 2 "register_operand" "0")
9694 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9695 UNSPEC_COPYSIGN))]
9696 "TARGET_SSE2 && TARGET_SSE_MATH"
9697 "#"
9698 "&& reload_completed"
9699 [(const_int 0)]
9700{
9701 ix86_split_copysign_const (operands);
9702 DONE;
9703})
9704
9705(define_insn "copysigndf3_var"
9706 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9707 (unspec:DF
9708 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9709 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9710 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9711 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9712 UNSPEC_COPYSIGN))
9713 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9714 "TARGET_SSE2 && TARGET_SSE_MATH"
9715 "#")
9716
9717(define_split
9718 [(set (match_operand:DF 0 "register_operand" "")
9719 (unspec:DF
9720 [(match_operand:DF 2 "register_operand" "")
9721 (match_operand:DF 3 "register_operand" "")
9722 (match_operand:V2DF 4 "" "")
9723 (match_operand:V2DF 5 "" "")]
9724 UNSPEC_COPYSIGN))
9725 (clobber (match_scratch:V2DF 1 ""))]
9726 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9727 [(const_int 0)]
9728{
9729 ix86_split_copysign_var (operands);
9730 DONE;
9731})
9732
9733(define_expand "negxf2"
9734 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9736 "TARGET_80387"
9737 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9738
9739(define_expand "absxf2"
9740 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9741 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9742 "TARGET_80387"
9743 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9744
9745(define_insn "*absnegxf2_i387"
9746 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9747 (match_operator:XF 3 "absneg_operator"
9748 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9749 (use (match_operand 2 "" ""))
9750 (clobber (reg:CC FLAGS_REG))]
9751 "TARGET_80387
9752 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9753 "#")
9754
9755;; Splitters for fp abs and neg.
9756
9757(define_split
9758 [(set (match_operand 0 "fp_register_operand" "")
9759 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9760 (use (match_operand 2 "" ""))
9761 (clobber (reg:CC FLAGS_REG))]
9762 "reload_completed"
9763 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9764
9765(define_split
9766 [(set (match_operand 0 "register_operand" "")
9767 (match_operator 3 "absneg_operator"
9768 [(match_operand 1 "register_operand" "")]))
9769 (use (match_operand 2 "nonimmediate_operand" ""))
9770 (clobber (reg:CC FLAGS_REG))]
9771 "reload_completed && SSE_REG_P (operands[0])"
9772 [(set (match_dup 0) (match_dup 3))]
9773{
9774 enum machine_mode mode = GET_MODE (operands[0]);
9775 enum machine_mode vmode = GET_MODE (operands[2]);
9776 rtx tmp;
9777
9778 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9779 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9780 if (operands_match_p (operands[0], operands[2]))
9781 {
9782 tmp = operands[1];
9783 operands[1] = operands[2];
9784 operands[2] = tmp;
9785 }
9786 if (GET_CODE (operands[3]) == ABS)
9787 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9788 else
9789 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9790 operands[3] = tmp;
9791})
9792
9793(define_split
9794 [(set (match_operand:SF 0 "register_operand" "")
9795 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9796 (use (match_operand:V4SF 2 "" ""))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "reload_completed"
9799 [(parallel [(set (match_dup 0) (match_dup 1))
9800 (clobber (reg:CC FLAGS_REG))])]
9801{
9802 rtx tmp;
9803 operands[0] = gen_lowpart (SImode, operands[0]);
9804 if (GET_CODE (operands[1]) == ABS)
9805 {
9806 tmp = gen_int_mode (0x7fffffff, SImode);
9807 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9808 }
9809 else
9810 {
9811 tmp = gen_int_mode (0x80000000, SImode);
9812 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9813 }
9814 operands[1] = tmp;
9815})
9816
9817(define_split
9818 [(set (match_operand:DF 0 "register_operand" "")
9819 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9820 (use (match_operand 2 "" ""))
9821 (clobber (reg:CC FLAGS_REG))]
9822 "reload_completed"
9823 [(parallel [(set (match_dup 0) (match_dup 1))
9824 (clobber (reg:CC FLAGS_REG))])]
9825{
9826 rtx tmp;
9827 if (TARGET_64BIT)
9828 {
9829 tmp = gen_lowpart (DImode, operands[0]);
9830 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9831 operands[0] = tmp;
9832
9833 if (GET_CODE (operands[1]) == ABS)
9834 tmp = const0_rtx;
9835 else
9836 tmp = gen_rtx_NOT (DImode, tmp);
9837 }
9838 else
9839 {
9840 operands[0] = gen_highpart (SImode, operands[0]);
9841 if (GET_CODE (operands[1]) == ABS)
9842 {
9843 tmp = gen_int_mode (0x7fffffff, SImode);
9844 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9845 }
9846 else
9847 {
9848 tmp = gen_int_mode (0x80000000, SImode);
9849 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9850 }
9851 }
9852 operands[1] = tmp;
9853})
9854
9855(define_split
9856 [(set (match_operand:XF 0 "register_operand" "")
9857 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9858 (use (match_operand 2 "" ""))
9859 (clobber (reg:CC FLAGS_REG))]
9860 "reload_completed"
9861 [(parallel [(set (match_dup 0) (match_dup 1))
9862 (clobber (reg:CC FLAGS_REG))])]
9863{
9864 rtx tmp;
9865 operands[0] = gen_rtx_REG (SImode,
9866 true_regnum (operands[0])
9867 + (TARGET_64BIT ? 1 : 2));
9868 if (GET_CODE (operands[1]) == ABS)
9869 {
9870 tmp = GEN_INT (0x7fff);
9871 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9872 }
9873 else
9874 {
9875 tmp = GEN_INT (0x8000);
9876 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9877 }
9878 operands[1] = tmp;
9879})
9880
9881(define_split
9882 [(set (match_operand 0 "memory_operand" "")
9883 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9884 (use (match_operand 2 "" ""))
9885 (clobber (reg:CC FLAGS_REG))]
9886 "reload_completed"
9887 [(parallel [(set (match_dup 0) (match_dup 1))
9888 (clobber (reg:CC FLAGS_REG))])]
9889{
9890 enum machine_mode mode = GET_MODE (operands[0]);
9891 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9892 rtx tmp;
9893
9894 operands[0] = adjust_address (operands[0], QImode, size - 1);
9895 if (GET_CODE (operands[1]) == ABS)
9896 {
9897 tmp = gen_int_mode (0x7f, QImode);
9898 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9899 }
9900 else
9901 {
9902 tmp = gen_int_mode (0x80, QImode);
9903 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9904 }
9905 operands[1] = tmp;
9906})
9907
9908;; Conditionalize these after reload. If they match before reload, we
9909;; lose the clobber and ability to use integer instructions.
9910
9911(define_insn "*negsf2_1"
9912 [(set (match_operand:SF 0 "register_operand" "=f")
9913 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9914 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9915 "fchs"
9916 [(set_attr "type" "fsgn")
9917 (set_attr "mode" "SF")])
9918
9919(define_insn "*negdf2_1"
9920 [(set (match_operand:DF 0 "register_operand" "=f")
9921 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9922 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9923 "fchs"
9924 [(set_attr "type" "fsgn")
9925 (set_attr "mode" "DF")])
9926
9927(define_insn "*negxf2_1"
9928 [(set (match_operand:XF 0 "register_operand" "=f")
9929 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9930 "TARGET_80387"
9931 "fchs"
9932 [(set_attr "type" "fsgn")
9933 (set_attr "mode" "XF")])
9934
9935(define_insn "*abssf2_1"
9936 [(set (match_operand:SF 0 "register_operand" "=f")
9937 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9938 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9939 "fabs"
9940 [(set_attr "type" "fsgn")
9941 (set_attr "mode" "SF")])
9942
9943(define_insn "*absdf2_1"
9944 [(set (match_operand:DF 0 "register_operand" "=f")
9945 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9946 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9947 "fabs"
9948 [(set_attr "type" "fsgn")
9949 (set_attr "mode" "DF")])
9950
9951(define_insn "*absxf2_1"
9952 [(set (match_operand:XF 0 "register_operand" "=f")
9953 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9954 "TARGET_80387"
9955 "fabs"
9956 [(set_attr "type" "fsgn")
9957 (set_attr "mode" "DF")])
9958
9959(define_insn "*negextendsfdf2"
9960 [(set (match_operand:DF 0 "register_operand" "=f")
9961 (neg:DF (float_extend:DF
9962 (match_operand:SF 1 "register_operand" "0"))))]
9963 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9964 "fchs"
9965 [(set_attr "type" "fsgn")
9966 (set_attr "mode" "DF")])
9967
9968(define_insn "*negextenddfxf2"
9969 [(set (match_operand:XF 0 "register_operand" "=f")
9970 (neg:XF (float_extend:XF
9971 (match_operand:DF 1 "register_operand" "0"))))]
9972 "TARGET_80387"
9973 "fchs"
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "XF")])
9976
9977(define_insn "*negextendsfxf2"
9978 [(set (match_operand:XF 0 "register_operand" "=f")
9979 (neg:XF (float_extend:XF
9980 (match_operand:SF 1 "register_operand" "0"))))]
9981 "TARGET_80387"
9982 "fchs"
9983 [(set_attr "type" "fsgn")
9984 (set_attr "mode" "XF")])
9985
9986(define_insn "*absextendsfdf2"
9987 [(set (match_operand:DF 0 "register_operand" "=f")
9988 (abs:DF (float_extend:DF
9989 (match_operand:SF 1 "register_operand" "0"))))]
9990 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9991 "fabs"
9992 [(set_attr "type" "fsgn")
9993 (set_attr "mode" "DF")])
9994
9995(define_insn "*absextenddfxf2"
9996 [(set (match_operand:XF 0 "register_operand" "=f")
9997 (abs:XF (float_extend:XF
9998 (match_operand:DF 1 "register_operand" "0"))))]
9999 "TARGET_80387"
10000 "fabs"
10001 [(set_attr "type" "fsgn")
10002 (set_attr "mode" "XF")])
10003
10004(define_insn "*absextendsfxf2"
10005 [(set (match_operand:XF 0 "register_operand" "=f")
10006 (abs:XF (float_extend:XF
10007 (match_operand:SF 1 "register_operand" "0"))))]
10008 "TARGET_80387"
10009 "fabs"
10010 [(set_attr "type" "fsgn")
10011 (set_attr "mode" "XF")])
10012
10013;; One complement instructions
10014
10015(define_expand "one_cmpldi2"
10016 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10017 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10018 "TARGET_64BIT"
10019 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10020
10021(define_insn "*one_cmpldi2_1_rex64"
10022 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10023 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10024 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10025 "not{q}\t%0"
10026 [(set_attr "type" "negnot")
10027 (set_attr "mode" "DI")])
10028
10029(define_insn "*one_cmpldi2_2_rex64"
10030 [(set (reg FLAGS_REG)
10031 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10032 (const_int 0)))
10033 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10034 (not:DI (match_dup 1)))]
10035 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10036 && ix86_unary_operator_ok (NOT, DImode, operands)"
10037 "#"
10038 [(set_attr "type" "alu1")
10039 (set_attr "mode" "DI")])
10040
10041(define_split
10042 [(set (match_operand 0 "flags_reg_operand" "")
10043 (match_operator 2 "compare_operator"
10044 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10045 (const_int 0)]))
10046 (set (match_operand:DI 1 "nonimmediate_operand" "")
10047 (not:DI (match_dup 3)))]
10048 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10049 [(parallel [(set (match_dup 0)
10050 (match_op_dup 2
10051 [(xor:DI (match_dup 3) (const_int -1))
10052 (const_int 0)]))
10053 (set (match_dup 1)
10054 (xor:DI (match_dup 3) (const_int -1)))])]
10055 "")
10056
10057(define_expand "one_cmplsi2"
10058 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10059 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10060 ""
10061 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10062
10063(define_insn "*one_cmplsi2_1"
10064 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10065 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10066 "ix86_unary_operator_ok (NOT, SImode, operands)"
10067 "not{l}\t%0"
10068 [(set_attr "type" "negnot")
10069 (set_attr "mode" "SI")])
10070
10071;; ??? Currently never generated - xor is used instead.
10072(define_insn "*one_cmplsi2_1_zext"
10073 [(set (match_operand:DI 0 "register_operand" "=r")
10074 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10075 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10076 "not{l}\t%k0"
10077 [(set_attr "type" "negnot")
10078 (set_attr "mode" "SI")])
10079
10080(define_insn "*one_cmplsi2_2"
10081 [(set (reg FLAGS_REG)
10082 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10083 (const_int 0)))
10084 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10085 (not:SI (match_dup 1)))]
10086 "ix86_match_ccmode (insn, CCNOmode)
10087 && ix86_unary_operator_ok (NOT, SImode, operands)"
10088 "#"
10089 [(set_attr "type" "alu1")
10090 (set_attr "mode" "SI")])
10091
10092(define_split
10093 [(set (match_operand 0 "flags_reg_operand" "")
10094 (match_operator 2 "compare_operator"
10095 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10096 (const_int 0)]))
10097 (set (match_operand:SI 1 "nonimmediate_operand" "")
10098 (not:SI (match_dup 3)))]
10099 "ix86_match_ccmode (insn, CCNOmode)"
10100 [(parallel [(set (match_dup 0)
10101 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10102 (const_int 0)]))
10103 (set (match_dup 1)
10104 (xor:SI (match_dup 3) (const_int -1)))])]
10105 "")
10106
10107;; ??? Currently never generated - xor is used instead.
10108(define_insn "*one_cmplsi2_2_zext"
10109 [(set (reg FLAGS_REG)
10110 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10111 (const_int 0)))
10112 (set (match_operand:DI 0 "register_operand" "=r")
10113 (zero_extend:DI (not:SI (match_dup 1))))]
10114 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10115 && ix86_unary_operator_ok (NOT, SImode, operands)"
10116 "#"
10117 [(set_attr "type" "alu1")
10118 (set_attr "mode" "SI")])
10119
10120(define_split
10121 [(set (match_operand 0 "flags_reg_operand" "")
10122 (match_operator 2 "compare_operator"
10123 [(not:SI (match_operand:SI 3 "register_operand" ""))
10124 (const_int 0)]))
10125 (set (match_operand:DI 1 "register_operand" "")
10126 (zero_extend:DI (not:SI (match_dup 3))))]
10127 "ix86_match_ccmode (insn, CCNOmode)"
10128 [(parallel [(set (match_dup 0)
10129 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10130 (const_int 0)]))
10131 (set (match_dup 1)
10132 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10133 "")
10134
10135(define_expand "one_cmplhi2"
10136 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10137 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10138 "TARGET_HIMODE_MATH"
10139 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10140
10141(define_insn "*one_cmplhi2_1"
10142 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10143 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10144 "ix86_unary_operator_ok (NOT, HImode, operands)"
10145 "not{w}\t%0"
10146 [(set_attr "type" "negnot")
10147 (set_attr "mode" "HI")])
10148
10149(define_insn "*one_cmplhi2_2"
10150 [(set (reg FLAGS_REG)
10151 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10152 (const_int 0)))
10153 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10154 (not:HI (match_dup 1)))]
10155 "ix86_match_ccmode (insn, CCNOmode)
10156 && ix86_unary_operator_ok (NEG, HImode, operands)"
10157 "#"
10158 [(set_attr "type" "alu1")
10159 (set_attr "mode" "HI")])
10160
10161(define_split
10162 [(set (match_operand 0 "flags_reg_operand" "")
10163 (match_operator 2 "compare_operator"
10164 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10165 (const_int 0)]))
10166 (set (match_operand:HI 1 "nonimmediate_operand" "")
10167 (not:HI (match_dup 3)))]
10168 "ix86_match_ccmode (insn, CCNOmode)"
10169 [(parallel [(set (match_dup 0)
10170 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10171 (const_int 0)]))
10172 (set (match_dup 1)
10173 (xor:HI (match_dup 3) (const_int -1)))])]
10174 "")
10175
10176;; %%% Potential partial reg stall on alternative 1. What to do?
10177(define_expand "one_cmplqi2"
10178 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10179 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10180 "TARGET_QIMODE_MATH"
10181 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10182
10183(define_insn "*one_cmplqi2_1"
10184 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10185 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10186 "ix86_unary_operator_ok (NOT, QImode, operands)"
10187 "@
10188 not{b}\t%0
10189 not{l}\t%k0"
10190 [(set_attr "type" "negnot")
10191 (set_attr "mode" "QI,SI")])
10192
10193(define_insn "*one_cmplqi2_2"
10194 [(set (reg FLAGS_REG)
10195 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10196 (const_int 0)))
10197 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10198 (not:QI (match_dup 1)))]
10199 "ix86_match_ccmode (insn, CCNOmode)
10200 && ix86_unary_operator_ok (NOT, QImode, operands)"
10201 "#"
10202 [(set_attr "type" "alu1")
10203 (set_attr "mode" "QI")])
10204
10205(define_split
10206 [(set (match_operand 0 "flags_reg_operand" "")
10207 (match_operator 2 "compare_operator"
10208 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10209 (const_int 0)]))
10210 (set (match_operand:QI 1 "nonimmediate_operand" "")
10211 (not:QI (match_dup 3)))]
10212 "ix86_match_ccmode (insn, CCNOmode)"
10213 [(parallel [(set (match_dup 0)
10214 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10215 (const_int 0)]))
10216 (set (match_dup 1)
10217 (xor:QI (match_dup 3) (const_int -1)))])]
10218 "")
10219
10220;; Arithmetic shift instructions
10221
10222;; DImode shifts are implemented using the i386 "shift double" opcode,
10223;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10224;; is variable, then the count is in %cl and the "imm" operand is dropped
10225;; from the assembler input.
10226;;
10227;; This instruction shifts the target reg/mem as usual, but instead of
10228;; shifting in zeros, bits are shifted in from reg operand. If the insn
10229;; is a left shift double, bits are taken from the high order bits of
10230;; reg, else if the insn is a shift right double, bits are taken from the
10231;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10232;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10233;;
10234;; Since sh[lr]d does not change the `reg' operand, that is done
10235;; separately, making all shifts emit pairs of shift double and normal
10236;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10237;; support a 63 bit shift, each shift where the count is in a reg expands
10238;; to a pair of shifts, a branch, a shift by 32 and a label.
10239;;
10240;; If the shift count is a constant, we need never emit more than one
10241;; shift pair, instead using moves and sign extension for counts greater
10242;; than 31.
10243
10244(define_expand "ashlti3"
10245 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10246 (ashift:TI (match_operand:TI 1 "register_operand" "")
10247 (match_operand:QI 2 "nonmemory_operand" "")))
10248 (clobber (reg:CC FLAGS_REG))])]
10249 "TARGET_64BIT"
10250{
10251 if (! immediate_operand (operands[2], QImode))
10252 {
10253 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10254 DONE;
10255 }
10256 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10257 DONE;
10258})
10259
10260(define_insn "ashlti3_1"
10261 [(set (match_operand:TI 0 "register_operand" "=r")
10262 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10263 (match_operand:QI 2 "register_operand" "c")))
10264 (clobber (match_scratch:DI 3 "=&r"))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "TARGET_64BIT"
10267 "#"
10268 [(set_attr "type" "multi")])
10269
10270(define_insn "*ashlti3_2"
10271 [(set (match_operand:TI 0 "register_operand" "=r")
10272 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10273 (match_operand:QI 2 "immediate_operand" "O")))
10274 (clobber (reg:CC FLAGS_REG))]
10275 "TARGET_64BIT"
10276 "#"
10277 [(set_attr "type" "multi")])
10278
10279(define_split
10280 [(set (match_operand:TI 0 "register_operand" "")
10281 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10282 (match_operand:QI 2 "register_operand" "")))
10283 (clobber (match_scratch:DI 3 ""))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "TARGET_64BIT && reload_completed"
10286 [(const_int 0)]
10287 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10288
10289(define_split
10290 [(set (match_operand:TI 0 "register_operand" "")
10291 (ashift:TI (match_operand:TI 1 "register_operand" "")
10292 (match_operand:QI 2 "immediate_operand" "")))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "TARGET_64BIT && reload_completed"
10295 [(const_int 0)]
10296 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10297
10298(define_insn "x86_64_shld"
10299 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10300 (ior:DI (ashift:DI (match_dup 0)
10301 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10302 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10303 (minus:QI (const_int 64) (match_dup 2)))))
10304 (clobber (reg:CC FLAGS_REG))]
10305 "TARGET_64BIT"
10306 "@
10307 shld{q}\t{%2, %1, %0|%0, %1, %2}
10308 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10309 [(set_attr "type" "ishift")
10310 (set_attr "prefix_0f" "1")
10311 (set_attr "mode" "DI")
7424 (set_attr "mode" "SI")])
7425
7426;; The patterns that match these are at the end of this file.
7427
7428(define_expand "mulxf3"
7429 [(set (match_operand:XF 0 "register_operand" "")
7430 (mult:XF (match_operand:XF 1 "register_operand" "")
7431 (match_operand:XF 2 "register_operand" "")))]
7432 "TARGET_80387"
7433 "")
7434
7435(define_expand "muldf3"
7436 [(set (match_operand:DF 0 "register_operand" "")
7437 (mult:DF (match_operand:DF 1 "register_operand" "")
7438 (match_operand:DF 2 "nonimmediate_operand" "")))]
7439 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7440 "")
7441
7442(define_expand "mulsf3"
7443 [(set (match_operand:SF 0 "register_operand" "")
7444 (mult:SF (match_operand:SF 1 "register_operand" "")
7445 (match_operand:SF 2 "nonimmediate_operand" "")))]
7446 "TARGET_80387 || TARGET_SSE_MATH"
7447 "")
7448
7449;; Divide instructions
7450
7451(define_insn "divqi3"
7452 [(set (match_operand:QI 0 "register_operand" "=a")
7453 (div:QI (match_operand:HI 1 "register_operand" "0")
7454 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7455 (clobber (reg:CC FLAGS_REG))]
7456 "TARGET_QIMODE_MATH"
7457 "idiv{b}\t%2"
7458 [(set_attr "type" "idiv")
7459 (set_attr "mode" "QI")])
7460
7461(define_insn "udivqi3"
7462 [(set (match_operand:QI 0 "register_operand" "=a")
7463 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7464 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7465 (clobber (reg:CC FLAGS_REG))]
7466 "TARGET_QIMODE_MATH"
7467 "div{b}\t%2"
7468 [(set_attr "type" "idiv")
7469 (set_attr "mode" "QI")])
7470
7471;; The patterns that match these are at the end of this file.
7472
7473(define_expand "divxf3"
7474 [(set (match_operand:XF 0 "register_operand" "")
7475 (div:XF (match_operand:XF 1 "register_operand" "")
7476 (match_operand:XF 2 "register_operand" "")))]
7477 "TARGET_80387"
7478 "")
7479
7480(define_expand "divdf3"
7481 [(set (match_operand:DF 0 "register_operand" "")
7482 (div:DF (match_operand:DF 1 "register_operand" "")
7483 (match_operand:DF 2 "nonimmediate_operand" "")))]
7484 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7485 "")
7486
7487(define_expand "divsf3"
7488 [(set (match_operand:SF 0 "register_operand" "")
7489 (div:SF (match_operand:SF 1 "register_operand" "")
7490 (match_operand:SF 2 "nonimmediate_operand" "")))]
7491 "TARGET_80387 || TARGET_SSE_MATH"
7492 "")
7493
7494;; Remainder instructions.
7495
7496(define_expand "divmoddi4"
7497 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7498 (div:DI (match_operand:DI 1 "register_operand" "")
7499 (match_operand:DI 2 "nonimmediate_operand" "")))
7500 (set (match_operand:DI 3 "register_operand" "")
7501 (mod:DI (match_dup 1) (match_dup 2)))
7502 (clobber (reg:CC FLAGS_REG))])]
7503 "TARGET_64BIT"
7504 "")
7505
7506;; Allow to come the parameter in eax or edx to avoid extra moves.
7507;; Penalize eax case slightly because it results in worse scheduling
7508;; of code.
7509(define_insn "*divmoddi4_nocltd_rex64"
7510 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7511 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7512 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7513 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7514 (mod:DI (match_dup 2) (match_dup 3)))
7515 (clobber (reg:CC FLAGS_REG))]
7516 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7517 "#"
7518 [(set_attr "type" "multi")])
7519
7520(define_insn "*divmoddi4_cltd_rex64"
7521 [(set (match_operand:DI 0 "register_operand" "=a")
7522 (div:DI (match_operand:DI 2 "register_operand" "a")
7523 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7524 (set (match_operand:DI 1 "register_operand" "=&d")
7525 (mod:DI (match_dup 2) (match_dup 3)))
7526 (clobber (reg:CC FLAGS_REG))]
7527 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7528 "#"
7529 [(set_attr "type" "multi")])
7530
7531(define_insn "*divmoddi_noext_rex64"
7532 [(set (match_operand:DI 0 "register_operand" "=a")
7533 (div:DI (match_operand:DI 1 "register_operand" "0")
7534 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7535 (set (match_operand:DI 3 "register_operand" "=d")
7536 (mod:DI (match_dup 1) (match_dup 2)))
7537 (use (match_operand:DI 4 "register_operand" "3"))
7538 (clobber (reg:CC FLAGS_REG))]
7539 "TARGET_64BIT"
7540 "idiv{q}\t%2"
7541 [(set_attr "type" "idiv")
7542 (set_attr "mode" "DI")])
7543
7544(define_split
7545 [(set (match_operand:DI 0 "register_operand" "")
7546 (div:DI (match_operand:DI 1 "register_operand" "")
7547 (match_operand:DI 2 "nonimmediate_operand" "")))
7548 (set (match_operand:DI 3 "register_operand" "")
7549 (mod:DI (match_dup 1) (match_dup 2)))
7550 (clobber (reg:CC FLAGS_REG))]
7551 "TARGET_64BIT && reload_completed"
7552 [(parallel [(set (match_dup 3)
7553 (ashiftrt:DI (match_dup 4) (const_int 63)))
7554 (clobber (reg:CC FLAGS_REG))])
7555 (parallel [(set (match_dup 0)
7556 (div:DI (reg:DI 0) (match_dup 2)))
7557 (set (match_dup 3)
7558 (mod:DI (reg:DI 0) (match_dup 2)))
7559 (use (match_dup 3))
7560 (clobber (reg:CC FLAGS_REG))])]
7561{
7562 /* Avoid use of cltd in favor of a mov+shift. */
7563 if (!TARGET_USE_CLTD && !optimize_size)
7564 {
7565 if (true_regnum (operands[1]))
7566 emit_move_insn (operands[0], operands[1]);
7567 else
7568 emit_move_insn (operands[3], operands[1]);
7569 operands[4] = operands[3];
7570 }
7571 else
7572 {
7573 gcc_assert (!true_regnum (operands[1]));
7574 operands[4] = operands[1];
7575 }
7576})
7577
7578
7579(define_expand "divmodsi4"
7580 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581 (div:SI (match_operand:SI 1 "register_operand" "")
7582 (match_operand:SI 2 "nonimmediate_operand" "")))
7583 (set (match_operand:SI 3 "register_operand" "")
7584 (mod:SI (match_dup 1) (match_dup 2)))
7585 (clobber (reg:CC FLAGS_REG))])]
7586 ""
7587 "")
7588
7589;; Allow to come the parameter in eax or edx to avoid extra moves.
7590;; Penalize eax case slightly because it results in worse scheduling
7591;; of code.
7592(define_insn "*divmodsi4_nocltd"
7593 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7594 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7595 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7596 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7597 (mod:SI (match_dup 2) (match_dup 3)))
7598 (clobber (reg:CC FLAGS_REG))]
7599 "!optimize_size && !TARGET_USE_CLTD"
7600 "#"
7601 [(set_attr "type" "multi")])
7602
7603(define_insn "*divmodsi4_cltd"
7604 [(set (match_operand:SI 0 "register_operand" "=a")
7605 (div:SI (match_operand:SI 2 "register_operand" "a")
7606 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7607 (set (match_operand:SI 1 "register_operand" "=&d")
7608 (mod:SI (match_dup 2) (match_dup 3)))
7609 (clobber (reg:CC FLAGS_REG))]
7610 "optimize_size || TARGET_USE_CLTD"
7611 "#"
7612 [(set_attr "type" "multi")])
7613
7614(define_insn "*divmodsi_noext"
7615 [(set (match_operand:SI 0 "register_operand" "=a")
7616 (div:SI (match_operand:SI 1 "register_operand" "0")
7617 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7618 (set (match_operand:SI 3 "register_operand" "=d")
7619 (mod:SI (match_dup 1) (match_dup 2)))
7620 (use (match_operand:SI 4 "register_operand" "3"))
7621 (clobber (reg:CC FLAGS_REG))]
7622 ""
7623 "idiv{l}\t%2"
7624 [(set_attr "type" "idiv")
7625 (set_attr "mode" "SI")])
7626
7627(define_split
7628 [(set (match_operand:SI 0 "register_operand" "")
7629 (div:SI (match_operand:SI 1 "register_operand" "")
7630 (match_operand:SI 2 "nonimmediate_operand" "")))
7631 (set (match_operand:SI 3 "register_operand" "")
7632 (mod:SI (match_dup 1) (match_dup 2)))
7633 (clobber (reg:CC FLAGS_REG))]
7634 "reload_completed"
7635 [(parallel [(set (match_dup 3)
7636 (ashiftrt:SI (match_dup 4) (const_int 31)))
7637 (clobber (reg:CC FLAGS_REG))])
7638 (parallel [(set (match_dup 0)
7639 (div:SI (reg:SI 0) (match_dup 2)))
7640 (set (match_dup 3)
7641 (mod:SI (reg:SI 0) (match_dup 2)))
7642 (use (match_dup 3))
7643 (clobber (reg:CC FLAGS_REG))])]
7644{
7645 /* Avoid use of cltd in favor of a mov+shift. */
7646 if (!TARGET_USE_CLTD && !optimize_size)
7647 {
7648 if (true_regnum (operands[1]))
7649 emit_move_insn (operands[0], operands[1]);
7650 else
7651 emit_move_insn (operands[3], operands[1]);
7652 operands[4] = operands[3];
7653 }
7654 else
7655 {
7656 gcc_assert (!true_regnum (operands[1]));
7657 operands[4] = operands[1];
7658 }
7659})
7660;; %%% Split me.
7661(define_insn "divmodhi4"
7662 [(set (match_operand:HI 0 "register_operand" "=a")
7663 (div:HI (match_operand:HI 1 "register_operand" "0")
7664 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7665 (set (match_operand:HI 3 "register_operand" "=&d")
7666 (mod:HI (match_dup 1) (match_dup 2)))
7667 (clobber (reg:CC FLAGS_REG))]
7668 "TARGET_HIMODE_MATH"
7669 "cwtd\;idiv{w}\t%2"
7670 [(set_attr "type" "multi")
7671 (set_attr "length_immediate" "0")
7672 (set_attr "mode" "SI")])
7673
7674(define_insn "udivmoddi4"
7675 [(set (match_operand:DI 0 "register_operand" "=a")
7676 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7677 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7678 (set (match_operand:DI 3 "register_operand" "=&d")
7679 (umod:DI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC FLAGS_REG))]
7681 "TARGET_64BIT"
7682 "xor{q}\t%3, %3\;div{q}\t%2"
7683 [(set_attr "type" "multi")
7684 (set_attr "length_immediate" "0")
7685 (set_attr "mode" "DI")])
7686
7687(define_insn "*udivmoddi4_noext"
7688 [(set (match_operand:DI 0 "register_operand" "=a")
7689 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7690 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7691 (set (match_operand:DI 3 "register_operand" "=d")
7692 (umod:DI (match_dup 1) (match_dup 2)))
7693 (use (match_dup 3))
7694 (clobber (reg:CC FLAGS_REG))]
7695 "TARGET_64BIT"
7696 "div{q}\t%2"
7697 [(set_attr "type" "idiv")
7698 (set_attr "mode" "DI")])
7699
7700(define_split
7701 [(set (match_operand:DI 0 "register_operand" "")
7702 (udiv:DI (match_operand:DI 1 "register_operand" "")
7703 (match_operand:DI 2 "nonimmediate_operand" "")))
7704 (set (match_operand:DI 3 "register_operand" "")
7705 (umod:DI (match_dup 1) (match_dup 2)))
7706 (clobber (reg:CC FLAGS_REG))]
7707 "TARGET_64BIT && reload_completed"
7708 [(set (match_dup 3) (const_int 0))
7709 (parallel [(set (match_dup 0)
7710 (udiv:DI (match_dup 1) (match_dup 2)))
7711 (set (match_dup 3)
7712 (umod:DI (match_dup 1) (match_dup 2)))
7713 (use (match_dup 3))
7714 (clobber (reg:CC FLAGS_REG))])]
7715 "")
7716
7717(define_insn "udivmodsi4"
7718 [(set (match_operand:SI 0 "register_operand" "=a")
7719 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7720 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7721 (set (match_operand:SI 3 "register_operand" "=&d")
7722 (umod:SI (match_dup 1) (match_dup 2)))
7723 (clobber (reg:CC FLAGS_REG))]
7724 ""
7725 "xor{l}\t%3, %3\;div{l}\t%2"
7726 [(set_attr "type" "multi")
7727 (set_attr "length_immediate" "0")
7728 (set_attr "mode" "SI")])
7729
7730(define_insn "*udivmodsi4_noext"
7731 [(set (match_operand:SI 0 "register_operand" "=a")
7732 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7733 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7734 (set (match_operand:SI 3 "register_operand" "=d")
7735 (umod:SI (match_dup 1) (match_dup 2)))
7736 (use (match_dup 3))
7737 (clobber (reg:CC FLAGS_REG))]
7738 ""
7739 "div{l}\t%2"
7740 [(set_attr "type" "idiv")
7741 (set_attr "mode" "SI")])
7742
7743(define_split
7744 [(set (match_operand:SI 0 "register_operand" "")
7745 (udiv:SI (match_operand:SI 1 "register_operand" "")
7746 (match_operand:SI 2 "nonimmediate_operand" "")))
7747 (set (match_operand:SI 3 "register_operand" "")
7748 (umod:SI (match_dup 1) (match_dup 2)))
7749 (clobber (reg:CC FLAGS_REG))]
7750 "reload_completed"
7751 [(set (match_dup 3) (const_int 0))
7752 (parallel [(set (match_dup 0)
7753 (udiv:SI (match_dup 1) (match_dup 2)))
7754 (set (match_dup 3)
7755 (umod:SI (match_dup 1) (match_dup 2)))
7756 (use (match_dup 3))
7757 (clobber (reg:CC FLAGS_REG))])]
7758 "")
7759
7760(define_expand "udivmodhi4"
7761 [(set (match_dup 4) (const_int 0))
7762 (parallel [(set (match_operand:HI 0 "register_operand" "")
7763 (udiv:HI (match_operand:HI 1 "register_operand" "")
7764 (match_operand:HI 2 "nonimmediate_operand" "")))
7765 (set (match_operand:HI 3 "register_operand" "")
7766 (umod:HI (match_dup 1) (match_dup 2)))
7767 (use (match_dup 4))
7768 (clobber (reg:CC FLAGS_REG))])]
7769 "TARGET_HIMODE_MATH"
7770 "operands[4] = gen_reg_rtx (HImode);")
7771
7772(define_insn "*udivmodhi_noext"
7773 [(set (match_operand:HI 0 "register_operand" "=a")
7774 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7775 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7776 (set (match_operand:HI 3 "register_operand" "=d")
7777 (umod:HI (match_dup 1) (match_dup 2)))
7778 (use (match_operand:HI 4 "register_operand" "3"))
7779 (clobber (reg:CC FLAGS_REG))]
7780 ""
7781 "div{w}\t%2"
7782 [(set_attr "type" "idiv")
7783 (set_attr "mode" "HI")])
7784
7785;; We cannot use div/idiv for double division, because it causes
7786;; "division by zero" on the overflow and that's not what we expect
7787;; from truncate. Because true (non truncating) double division is
7788;; never generated, we can't create this insn anyway.
7789;
7790;(define_insn ""
7791; [(set (match_operand:SI 0 "register_operand" "=a")
7792; (truncate:SI
7793; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7794; (zero_extend:DI
7795; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7796; (set (match_operand:SI 3 "register_operand" "=d")
7797; (truncate:SI
7798; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7799; (clobber (reg:CC FLAGS_REG))]
7800; ""
7801; "div{l}\t{%2, %0|%0, %2}"
7802; [(set_attr "type" "idiv")])
7803
7804;;- Logical AND instructions
7805
7806;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7807;; Note that this excludes ah.
7808
7809(define_insn "*testdi_1_rex64"
7810 [(set (reg FLAGS_REG)
7811 (compare
7812 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7813 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7814 (const_int 0)))]
7815 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7816 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7817 "@
7818 test{l}\t{%k1, %k0|%k0, %k1}
7819 test{l}\t{%k1, %k0|%k0, %k1}
7820 test{q}\t{%1, %0|%0, %1}
7821 test{q}\t{%1, %0|%0, %1}
7822 test{q}\t{%1, %0|%0, %1}"
7823 [(set_attr "type" "test")
7824 (set_attr "modrm" "0,1,0,1,1")
7825 (set_attr "mode" "SI,SI,DI,DI,DI")
7826 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7827
7828(define_insn "testsi_1"
7829 [(set (reg FLAGS_REG)
7830 (compare
7831 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7832 (match_operand:SI 1 "general_operand" "in,in,rin"))
7833 (const_int 0)))]
7834 "ix86_match_ccmode (insn, CCNOmode)
7835 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7836 "test{l}\t{%1, %0|%0, %1}"
7837 [(set_attr "type" "test")
7838 (set_attr "modrm" "0,1,1")
7839 (set_attr "mode" "SI")
7840 (set_attr "pent_pair" "uv,np,uv")])
7841
7842(define_expand "testsi_ccno_1"
7843 [(set (reg:CCNO FLAGS_REG)
7844 (compare:CCNO
7845 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7846 (match_operand:SI 1 "nonmemory_operand" ""))
7847 (const_int 0)))]
7848 ""
7849 "")
7850
7851(define_insn "*testhi_1"
7852 [(set (reg FLAGS_REG)
7853 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7854 (match_operand:HI 1 "general_operand" "n,n,rn"))
7855 (const_int 0)))]
7856 "ix86_match_ccmode (insn, CCNOmode)
7857 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7858 "test{w}\t{%1, %0|%0, %1}"
7859 [(set_attr "type" "test")
7860 (set_attr "modrm" "0,1,1")
7861 (set_attr "mode" "HI")
7862 (set_attr "pent_pair" "uv,np,uv")])
7863
7864(define_expand "testqi_ccz_1"
7865 [(set (reg:CCZ FLAGS_REG)
7866 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7867 (match_operand:QI 1 "nonmemory_operand" ""))
7868 (const_int 0)))]
7869 ""
7870 "")
7871
7872(define_insn "*testqi_1_maybe_si"
7873 [(set (reg FLAGS_REG)
7874 (compare
7875 (and:QI
7876 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7877 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7878 (const_int 0)))]
7879 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7880 && ix86_match_ccmode (insn,
7881 GET_CODE (operands[1]) == CONST_INT
7882 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7883{
7884 if (which_alternative == 3)
7885 {
7886 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7887 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7888 return "test{l}\t{%1, %k0|%k0, %1}";
7889 }
7890 return "test{b}\t{%1, %0|%0, %1}";
7891}
7892 [(set_attr "type" "test")
7893 (set_attr "modrm" "0,1,1,1")
7894 (set_attr "mode" "QI,QI,QI,SI")
7895 (set_attr "pent_pair" "uv,np,uv,np")])
7896
7897(define_insn "*testqi_1"
7898 [(set (reg FLAGS_REG)
7899 (compare
7900 (and:QI
7901 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7902 (match_operand:QI 1 "general_operand" "n,n,qn"))
7903 (const_int 0)))]
7904 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7905 && ix86_match_ccmode (insn, CCNOmode)"
7906 "test{b}\t{%1, %0|%0, %1}"
7907 [(set_attr "type" "test")
7908 (set_attr "modrm" "0,1,1")
7909 (set_attr "mode" "QI")
7910 (set_attr "pent_pair" "uv,np,uv")])
7911
7912(define_expand "testqi_ext_ccno_0"
7913 [(set (reg:CCNO FLAGS_REG)
7914 (compare:CCNO
7915 (and:SI
7916 (zero_extract:SI
7917 (match_operand 0 "ext_register_operand" "")
7918 (const_int 8)
7919 (const_int 8))
7920 (match_operand 1 "const_int_operand" ""))
7921 (const_int 0)))]
7922 ""
7923 "")
7924
7925(define_insn "*testqi_ext_0"
7926 [(set (reg FLAGS_REG)
7927 (compare
7928 (and:SI
7929 (zero_extract:SI
7930 (match_operand 0 "ext_register_operand" "Q")
7931 (const_int 8)
7932 (const_int 8))
7933 (match_operand 1 "const_int_operand" "n"))
7934 (const_int 0)))]
7935 "ix86_match_ccmode (insn, CCNOmode)"
7936 "test{b}\t{%1, %h0|%h0, %1}"
7937 [(set_attr "type" "test")
7938 (set_attr "mode" "QI")
7939 (set_attr "length_immediate" "1")
7940 (set_attr "pent_pair" "np")])
7941
7942(define_insn "*testqi_ext_1"
7943 [(set (reg FLAGS_REG)
7944 (compare
7945 (and:SI
7946 (zero_extract:SI
7947 (match_operand 0 "ext_register_operand" "Q")
7948 (const_int 8)
7949 (const_int 8))
7950 (zero_extend:SI
7951 (match_operand:QI 1 "general_operand" "Qm")))
7952 (const_int 0)))]
7953 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7954 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7955 "test{b}\t{%1, %h0|%h0, %1}"
7956 [(set_attr "type" "test")
7957 (set_attr "mode" "QI")])
7958
7959(define_insn "*testqi_ext_1_rex64"
7960 [(set (reg FLAGS_REG)
7961 (compare
7962 (and:SI
7963 (zero_extract:SI
7964 (match_operand 0 "ext_register_operand" "Q")
7965 (const_int 8)
7966 (const_int 8))
7967 (zero_extend:SI
7968 (match_operand:QI 1 "register_operand" "Q")))
7969 (const_int 0)))]
7970 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7971 "test{b}\t{%1, %h0|%h0, %1}"
7972 [(set_attr "type" "test")
7973 (set_attr "mode" "QI")])
7974
7975(define_insn "*testqi_ext_2"
7976 [(set (reg FLAGS_REG)
7977 (compare
7978 (and:SI
7979 (zero_extract:SI
7980 (match_operand 0 "ext_register_operand" "Q")
7981 (const_int 8)
7982 (const_int 8))
7983 (zero_extract:SI
7984 (match_operand 1 "ext_register_operand" "Q")
7985 (const_int 8)
7986 (const_int 8)))
7987 (const_int 0)))]
7988 "ix86_match_ccmode (insn, CCNOmode)"
7989 "test{b}\t{%h1, %h0|%h0, %h1}"
7990 [(set_attr "type" "test")
7991 (set_attr "mode" "QI")])
7992
7993;; Combine likes to form bit extractions for some tests. Humor it.
7994(define_insn "*testqi_ext_3"
7995 [(set (reg FLAGS_REG)
7996 (compare (zero_extract:SI
7997 (match_operand 0 "nonimmediate_operand" "rm")
7998 (match_operand:SI 1 "const_int_operand" "")
7999 (match_operand:SI 2 "const_int_operand" ""))
8000 (const_int 0)))]
8001 "ix86_match_ccmode (insn, CCNOmode)
8002 && INTVAL (operands[1]) > 0
8003 && INTVAL (operands[2]) >= 0
8004 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8005 && (GET_MODE (operands[0]) == SImode
8006 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8007 || GET_MODE (operands[0]) == HImode
8008 || GET_MODE (operands[0]) == QImode)"
8009 "#")
8010
8011(define_insn "*testqi_ext_3_rex64"
8012 [(set (reg FLAGS_REG)
8013 (compare (zero_extract:DI
8014 (match_operand 0 "nonimmediate_operand" "rm")
8015 (match_operand:DI 1 "const_int_operand" "")
8016 (match_operand:DI 2 "const_int_operand" ""))
8017 (const_int 0)))]
8018 "TARGET_64BIT
8019 && ix86_match_ccmode (insn, CCNOmode)
8020 && INTVAL (operands[1]) > 0
8021 && INTVAL (operands[2]) >= 0
8022 /* Ensure that resulting mask is zero or sign extended operand. */
8023 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8024 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8025 && INTVAL (operands[1]) > 32))
8026 && (GET_MODE (operands[0]) == SImode
8027 || GET_MODE (operands[0]) == DImode
8028 || GET_MODE (operands[0]) == HImode
8029 || GET_MODE (operands[0]) == QImode)"
8030 "#")
8031
8032(define_split
8033 [(set (match_operand 0 "flags_reg_operand" "")
8034 (match_operator 1 "compare_operator"
8035 [(zero_extract
8036 (match_operand 2 "nonimmediate_operand" "")
8037 (match_operand 3 "const_int_operand" "")
8038 (match_operand 4 "const_int_operand" ""))
8039 (const_int 0)]))]
8040 "ix86_match_ccmode (insn, CCNOmode)"
8041 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8042{
8043 rtx val = operands[2];
8044 HOST_WIDE_INT len = INTVAL (operands[3]);
8045 HOST_WIDE_INT pos = INTVAL (operands[4]);
8046 HOST_WIDE_INT mask;
8047 enum machine_mode mode, submode;
8048
8049 mode = GET_MODE (val);
8050 if (GET_CODE (val) == MEM)
8051 {
8052 /* ??? Combine likes to put non-volatile mem extractions in QImode
8053 no matter the size of the test. So find a mode that works. */
8054 if (! MEM_VOLATILE_P (val))
8055 {
8056 mode = smallest_mode_for_size (pos + len, MODE_INT);
8057 val = adjust_address (val, mode, 0);
8058 }
8059 }
8060 else if (GET_CODE (val) == SUBREG
8061 && (submode = GET_MODE (SUBREG_REG (val)),
8062 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8063 && pos + len <= GET_MODE_BITSIZE (submode))
8064 {
8065 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8066 mode = submode;
8067 val = SUBREG_REG (val);
8068 }
8069 else if (mode == HImode && pos + len <= 8)
8070 {
8071 /* Small HImode tests can be converted to QImode. */
8072 mode = QImode;
8073 val = gen_lowpart (QImode, val);
8074 }
8075
8076 if (len == HOST_BITS_PER_WIDE_INT)
8077 mask = -1;
8078 else
8079 mask = ((HOST_WIDE_INT)1 << len) - 1;
8080 mask <<= pos;
8081
8082 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8083})
8084
8085;; Convert HImode/SImode test instructions with immediate to QImode ones.
8086;; i386 does not allow to encode test with 8bit sign extended immediate, so
8087;; this is relatively important trick.
8088;; Do the conversion only post-reload to avoid limiting of the register class
8089;; to QI regs.
8090(define_split
8091 [(set (match_operand 0 "flags_reg_operand" "")
8092 (match_operator 1 "compare_operator"
8093 [(and (match_operand 2 "register_operand" "")
8094 (match_operand 3 "const_int_operand" ""))
8095 (const_int 0)]))]
8096 "reload_completed
8097 && QI_REG_P (operands[2])
8098 && GET_MODE (operands[2]) != QImode
8099 && ((ix86_match_ccmode (insn, CCZmode)
8100 && !(INTVAL (operands[3]) & ~(255 << 8)))
8101 || (ix86_match_ccmode (insn, CCNOmode)
8102 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8103 [(set (match_dup 0)
8104 (match_op_dup 1
8105 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8106 (match_dup 3))
8107 (const_int 0)]))]
8108 "operands[2] = gen_lowpart (SImode, operands[2]);
8109 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8110
8111(define_split
8112 [(set (match_operand 0 "flags_reg_operand" "")
8113 (match_operator 1 "compare_operator"
8114 [(and (match_operand 2 "nonimmediate_operand" "")
8115 (match_operand 3 "const_int_operand" ""))
8116 (const_int 0)]))]
8117 "reload_completed
8118 && GET_MODE (operands[2]) != QImode
8119 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8120 && ((ix86_match_ccmode (insn, CCZmode)
8121 && !(INTVAL (operands[3]) & ~255))
8122 || (ix86_match_ccmode (insn, CCNOmode)
8123 && !(INTVAL (operands[3]) & ~127)))"
8124 [(set (match_dup 0)
8125 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8126 (const_int 0)]))]
8127 "operands[2] = gen_lowpart (QImode, operands[2]);
8128 operands[3] = gen_lowpart (QImode, operands[3]);")
8129
8130
8131;; %%% This used to optimize known byte-wide and operations to memory,
8132;; and sometimes to QImode registers. If this is considered useful,
8133;; it should be done with splitters.
8134
8135(define_expand "anddi3"
8136 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8137 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8138 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8139 (clobber (reg:CC FLAGS_REG))]
8140 "TARGET_64BIT"
8141 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8142
8143(define_insn "*anddi_1_rex64"
8144 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8145 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8146 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8147 (clobber (reg:CC FLAGS_REG))]
8148 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8149{
8150 switch (get_attr_type (insn))
8151 {
8152 case TYPE_IMOVX:
8153 {
8154 enum machine_mode mode;
8155
8156 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8157 if (INTVAL (operands[2]) == 0xff)
8158 mode = QImode;
8159 else
8160 {
8161 gcc_assert (INTVAL (operands[2]) == 0xffff);
8162 mode = HImode;
8163 }
8164
8165 operands[1] = gen_lowpart (mode, operands[1]);
8166 if (mode == QImode)
8167 return "movz{bq|x}\t{%1,%0|%0, %1}";
8168 else
8169 return "movz{wq|x}\t{%1,%0|%0, %1}";
8170 }
8171
8172 default:
8173 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8174 if (get_attr_mode (insn) == MODE_SI)
8175 return "and{l}\t{%k2, %k0|%k0, %k2}";
8176 else
8177 return "and{q}\t{%2, %0|%0, %2}";
8178 }
8179}
8180 [(set_attr "type" "alu,alu,alu,imovx")
8181 (set_attr "length_immediate" "*,*,*,0")
8182 (set_attr "mode" "SI,DI,DI,DI")])
8183
8184(define_insn "*anddi_2"
8185 [(set (reg FLAGS_REG)
8186 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8187 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8188 (const_int 0)))
8189 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8190 (and:DI (match_dup 1) (match_dup 2)))]
8191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192 && ix86_binary_operator_ok (AND, DImode, operands)"
8193 "@
8194 and{l}\t{%k2, %k0|%k0, %k2}
8195 and{q}\t{%2, %0|%0, %2}
8196 and{q}\t{%2, %0|%0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "mode" "SI,DI,DI")])
8199
8200(define_expand "andsi3"
8201 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8202 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8203 (match_operand:SI 2 "general_operand" "")))
8204 (clobber (reg:CC FLAGS_REG))]
8205 ""
8206 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8207
8208(define_insn "*andsi_1"
8209 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8210 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8211 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8212 (clobber (reg:CC FLAGS_REG))]
8213 "ix86_binary_operator_ok (AND, SImode, operands)"
8214{
8215 switch (get_attr_type (insn))
8216 {
8217 case TYPE_IMOVX:
8218 {
8219 enum machine_mode mode;
8220
8221 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8222 if (INTVAL (operands[2]) == 0xff)
8223 mode = QImode;
8224 else
8225 {
8226 gcc_assert (INTVAL (operands[2]) == 0xffff);
8227 mode = HImode;
8228 }
8229
8230 operands[1] = gen_lowpart (mode, operands[1]);
8231 if (mode == QImode)
8232 return "movz{bl|x}\t{%1,%0|%0, %1}";
8233 else
8234 return "movz{wl|x}\t{%1,%0|%0, %1}";
8235 }
8236
8237 default:
8238 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8239 return "and{l}\t{%2, %0|%0, %2}";
8240 }
8241}
8242 [(set_attr "type" "alu,alu,imovx")
8243 (set_attr "length_immediate" "*,*,0")
8244 (set_attr "mode" "SI")])
8245
8246(define_split
8247 [(set (match_operand 0 "register_operand" "")
8248 (and (match_dup 0)
8249 (const_int -65536)))
8250 (clobber (reg:CC FLAGS_REG))]
8251 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8252 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8253 "operands[1] = gen_lowpart (HImode, operands[0]);")
8254
8255(define_split
8256 [(set (match_operand 0 "ext_register_operand" "")
8257 (and (match_dup 0)
8258 (const_int -256)))
8259 (clobber (reg:CC FLAGS_REG))]
8260 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8261 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8262 "operands[1] = gen_lowpart (QImode, operands[0]);")
8263
8264(define_split
8265 [(set (match_operand 0 "ext_register_operand" "")
8266 (and (match_dup 0)
8267 (const_int -65281)))
8268 (clobber (reg:CC FLAGS_REG))]
8269 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8270 [(parallel [(set (zero_extract:SI (match_dup 0)
8271 (const_int 8)
8272 (const_int 8))
8273 (xor:SI
8274 (zero_extract:SI (match_dup 0)
8275 (const_int 8)
8276 (const_int 8))
8277 (zero_extract:SI (match_dup 0)
8278 (const_int 8)
8279 (const_int 8))))
8280 (clobber (reg:CC FLAGS_REG))])]
8281 "operands[0] = gen_lowpart (SImode, operands[0]);")
8282
8283;; See comment for addsi_1_zext why we do use nonimmediate_operand
8284(define_insn "*andsi_1_zext"
8285 [(set (match_operand:DI 0 "register_operand" "=r")
8286 (zero_extend:DI
8287 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288 (match_operand:SI 2 "general_operand" "rim"))))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8291 "and{l}\t{%2, %k0|%k0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "mode" "SI")])
8294
8295(define_insn "*andsi_2"
8296 [(set (reg FLAGS_REG)
8297 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8298 (match_operand:SI 2 "general_operand" "rim,ri"))
8299 (const_int 0)))
8300 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8301 (and:SI (match_dup 1) (match_dup 2)))]
8302 "ix86_match_ccmode (insn, CCNOmode)
8303 && ix86_binary_operator_ok (AND, SImode, operands)"
8304 "and{l}\t{%2, %0|%0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "SI")])
8307
8308;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309(define_insn "*andsi_2_zext"
8310 [(set (reg FLAGS_REG)
8311 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8312 (match_operand:SI 2 "general_operand" "rim"))
8313 (const_int 0)))
8314 (set (match_operand:DI 0 "register_operand" "=r")
8315 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8316 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8317 && ix86_binary_operator_ok (AND, SImode, operands)"
8318 "and{l}\t{%2, %k0|%k0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "SI")])
8321
8322(define_expand "andhi3"
8323 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8324 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8325 (match_operand:HI 2 "general_operand" "")))
8326 (clobber (reg:CC FLAGS_REG))]
8327 "TARGET_HIMODE_MATH"
8328 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8329
8330(define_insn "*andhi_1"
8331 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8332 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8333 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8334 (clobber (reg:CC FLAGS_REG))]
8335 "ix86_binary_operator_ok (AND, HImode, operands)"
8336{
8337 switch (get_attr_type (insn))
8338 {
8339 case TYPE_IMOVX:
8340 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8341 gcc_assert (INTVAL (operands[2]) == 0xff);
8342 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8343
8344 default:
8345 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8346
8347 return "and{w}\t{%2, %0|%0, %2}";
8348 }
8349}
8350 [(set_attr "type" "alu,alu,imovx")
8351 (set_attr "length_immediate" "*,*,0")
8352 (set_attr "mode" "HI,HI,SI")])
8353
8354(define_insn "*andhi_2"
8355 [(set (reg FLAGS_REG)
8356 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8357 (match_operand:HI 2 "general_operand" "rim,ri"))
8358 (const_int 0)))
8359 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8360 (and:HI (match_dup 1) (match_dup 2)))]
8361 "ix86_match_ccmode (insn, CCNOmode)
8362 && ix86_binary_operator_ok (AND, HImode, operands)"
8363 "and{w}\t{%2, %0|%0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "mode" "HI")])
8366
8367(define_expand "andqi3"
8368 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8369 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8370 (match_operand:QI 2 "general_operand" "")))
8371 (clobber (reg:CC FLAGS_REG))]
8372 "TARGET_QIMODE_MATH"
8373 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8374
8375;; %%% Potential partial reg stall on alternative 2. What to do?
8376(define_insn "*andqi_1"
8377 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8378 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8379 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8380 (clobber (reg:CC FLAGS_REG))]
8381 "ix86_binary_operator_ok (AND, QImode, operands)"
8382 "@
8383 and{b}\t{%2, %0|%0, %2}
8384 and{b}\t{%2, %0|%0, %2}
8385 and{l}\t{%k2, %k0|%k0, %k2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "mode" "QI,QI,SI")])
8388
8389(define_insn "*andqi_1_slp"
8390 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8391 (and:QI (match_dup 0)
8392 (match_operand:QI 1 "general_operand" "qi,qmi")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8395 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8396 "and{b}\t{%1, %0|%0, %1}"
8397 [(set_attr "type" "alu1")
8398 (set_attr "mode" "QI")])
8399
8400(define_insn "*andqi_2_maybe_si"
8401 [(set (reg FLAGS_REG)
8402 (compare (and:QI
8403 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8404 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8405 (const_int 0)))
8406 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8407 (and:QI (match_dup 1) (match_dup 2)))]
8408 "ix86_binary_operator_ok (AND, QImode, operands)
8409 && ix86_match_ccmode (insn,
8410 GET_CODE (operands[2]) == CONST_INT
8411 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8412{
8413 if (which_alternative == 2)
8414 {
8415 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8416 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8417 return "and{l}\t{%2, %k0|%k0, %2}";
8418 }
8419 return "and{b}\t{%2, %0|%0, %2}";
8420}
8421 [(set_attr "type" "alu")
8422 (set_attr "mode" "QI,QI,SI")])
8423
8424(define_insn "*andqi_2"
8425 [(set (reg FLAGS_REG)
8426 (compare (and:QI
8427 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8428 (match_operand:QI 2 "general_operand" "qim,qi"))
8429 (const_int 0)))
8430 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8431 (and:QI (match_dup 1) (match_dup 2)))]
8432 "ix86_match_ccmode (insn, CCNOmode)
8433 && ix86_binary_operator_ok (AND, QImode, operands)"
8434 "and{b}\t{%2, %0|%0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "mode" "QI")])
8437
8438(define_insn "*andqi_2_slp"
8439 [(set (reg FLAGS_REG)
8440 (compare (and:QI
8441 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8442 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8443 (const_int 0)))
8444 (set (strict_low_part (match_dup 0))
8445 (and:QI (match_dup 0) (match_dup 1)))]
8446 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8447 && ix86_match_ccmode (insn, CCNOmode)
8448 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8449 "and{b}\t{%1, %0|%0, %1}"
8450 [(set_attr "type" "alu1")
8451 (set_attr "mode" "QI")])
8452
8453;; ??? A bug in recog prevents it from recognizing a const_int as an
8454;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8455;; for a QImode operand, which of course failed.
8456
8457(define_insn "andqi_ext_0"
8458 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459 (const_int 8)
8460 (const_int 8))
8461 (and:SI
8462 (zero_extract:SI
8463 (match_operand 1 "ext_register_operand" "0")
8464 (const_int 8)
8465 (const_int 8))
8466 (match_operand 2 "const_int_operand" "n")))
8467 (clobber (reg:CC FLAGS_REG))]
8468 ""
8469 "and{b}\t{%2, %h0|%h0, %2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "length_immediate" "1")
8472 (set_attr "mode" "QI")])
8473
8474;; Generated by peephole translating test to and. This shows up
8475;; often in fp comparisons.
8476
8477(define_insn "*andqi_ext_0_cc"
8478 [(set (reg FLAGS_REG)
8479 (compare
8480 (and:SI
8481 (zero_extract:SI
8482 (match_operand 1 "ext_register_operand" "0")
8483 (const_int 8)
8484 (const_int 8))
8485 (match_operand 2 "const_int_operand" "n"))
8486 (const_int 0)))
8487 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8488 (const_int 8)
8489 (const_int 8))
8490 (and:SI
8491 (zero_extract:SI
8492 (match_dup 1)
8493 (const_int 8)
8494 (const_int 8))
8495 (match_dup 2)))]
8496 "ix86_match_ccmode (insn, CCNOmode)"
8497 "and{b}\t{%2, %h0|%h0, %2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "length_immediate" "1")
8500 (set_attr "mode" "QI")])
8501
8502(define_insn "*andqi_ext_1"
8503 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504 (const_int 8)
8505 (const_int 8))
8506 (and:SI
8507 (zero_extract:SI
8508 (match_operand 1 "ext_register_operand" "0")
8509 (const_int 8)
8510 (const_int 8))
8511 (zero_extend:SI
8512 (match_operand:QI 2 "general_operand" "Qm"))))
8513 (clobber (reg:CC FLAGS_REG))]
8514 "!TARGET_64BIT"
8515 "and{b}\t{%2, %h0|%h0, %2}"
8516 [(set_attr "type" "alu")
8517 (set_attr "length_immediate" "0")
8518 (set_attr "mode" "QI")])
8519
8520(define_insn "*andqi_ext_1_rex64"
8521 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8522 (const_int 8)
8523 (const_int 8))
8524 (and:SI
8525 (zero_extract:SI
8526 (match_operand 1 "ext_register_operand" "0")
8527 (const_int 8)
8528 (const_int 8))
8529 (zero_extend:SI
8530 (match_operand 2 "ext_register_operand" "Q"))))
8531 (clobber (reg:CC FLAGS_REG))]
8532 "TARGET_64BIT"
8533 "and{b}\t{%2, %h0|%h0, %2}"
8534 [(set_attr "type" "alu")
8535 (set_attr "length_immediate" "0")
8536 (set_attr "mode" "QI")])
8537
8538(define_insn "*andqi_ext_2"
8539 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8540 (const_int 8)
8541 (const_int 8))
8542 (and:SI
8543 (zero_extract:SI
8544 (match_operand 1 "ext_register_operand" "%0")
8545 (const_int 8)
8546 (const_int 8))
8547 (zero_extract:SI
8548 (match_operand 2 "ext_register_operand" "Q")
8549 (const_int 8)
8550 (const_int 8))))
8551 (clobber (reg:CC FLAGS_REG))]
8552 ""
8553 "and{b}\t{%h2, %h0|%h0, %h2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "length_immediate" "0")
8556 (set_attr "mode" "QI")])
8557
8558;; Convert wide AND instructions with immediate operand to shorter QImode
8559;; equivalents when possible.
8560;; Don't do the splitting with memory operands, since it introduces risk
8561;; of memory mismatch stalls. We may want to do the splitting for optimizing
8562;; for size, but that can (should?) be handled by generic code instead.
8563(define_split
8564 [(set (match_operand 0 "register_operand" "")
8565 (and (match_operand 1 "register_operand" "")
8566 (match_operand 2 "const_int_operand" "")))
8567 (clobber (reg:CC FLAGS_REG))]
8568 "reload_completed
8569 && QI_REG_P (operands[0])
8570 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571 && !(~INTVAL (operands[2]) & ~(255 << 8))
8572 && GET_MODE (operands[0]) != QImode"
8573 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8574 (and:SI (zero_extract:SI (match_dup 1)
8575 (const_int 8) (const_int 8))
8576 (match_dup 2)))
8577 (clobber (reg:CC FLAGS_REG))])]
8578 "operands[0] = gen_lowpart (SImode, operands[0]);
8579 operands[1] = gen_lowpart (SImode, operands[1]);
8580 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8581
8582;; Since AND can be encoded with sign extended immediate, this is only
8583;; profitable when 7th bit is not set.
8584(define_split
8585 [(set (match_operand 0 "register_operand" "")
8586 (and (match_operand 1 "general_operand" "")
8587 (match_operand 2 "const_int_operand" "")))
8588 (clobber (reg:CC FLAGS_REG))]
8589 "reload_completed
8590 && ANY_QI_REG_P (operands[0])
8591 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8592 && !(~INTVAL (operands[2]) & ~255)
8593 && !(INTVAL (operands[2]) & 128)
8594 && GET_MODE (operands[0]) != QImode"
8595 [(parallel [(set (strict_low_part (match_dup 0))
8596 (and:QI (match_dup 1)
8597 (match_dup 2)))
8598 (clobber (reg:CC FLAGS_REG))])]
8599 "operands[0] = gen_lowpart (QImode, operands[0]);
8600 operands[1] = gen_lowpart (QImode, operands[1]);
8601 operands[2] = gen_lowpart (QImode, operands[2]);")
8602
8603;; Logical inclusive OR instructions
8604
8605;; %%% This used to optimize known byte-wide and operations to memory.
8606;; If this is considered useful, it should be done with splitters.
8607
8608(define_expand "iordi3"
8609 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8610 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8611 (match_operand:DI 2 "x86_64_general_operand" "")))
8612 (clobber (reg:CC FLAGS_REG))]
8613 "TARGET_64BIT"
8614 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8615
8616(define_insn "*iordi_1_rex64"
8617 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8618 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8619 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8620 (clobber (reg:CC FLAGS_REG))]
8621 "TARGET_64BIT
8622 && ix86_binary_operator_ok (IOR, DImode, operands)"
8623 "or{q}\t{%2, %0|%0, %2}"
8624 [(set_attr "type" "alu")
8625 (set_attr "mode" "DI")])
8626
8627(define_insn "*iordi_2_rex64"
8628 [(set (reg FLAGS_REG)
8629 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8630 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8631 (const_int 0)))
8632 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8633 (ior:DI (match_dup 1) (match_dup 2)))]
8634 "TARGET_64BIT
8635 && ix86_match_ccmode (insn, CCNOmode)
8636 && ix86_binary_operator_ok (IOR, DImode, operands)"
8637 "or{q}\t{%2, %0|%0, %2}"
8638 [(set_attr "type" "alu")
8639 (set_attr "mode" "DI")])
8640
8641(define_insn "*iordi_3_rex64"
8642 [(set (reg FLAGS_REG)
8643 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8644 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8645 (const_int 0)))
8646 (clobber (match_scratch:DI 0 "=r"))]
8647 "TARGET_64BIT
8648 && ix86_match_ccmode (insn, CCNOmode)
8649 && ix86_binary_operator_ok (IOR, DImode, operands)"
8650 "or{q}\t{%2, %0|%0, %2}"
8651 [(set_attr "type" "alu")
8652 (set_attr "mode" "DI")])
8653
8654
8655(define_expand "iorsi3"
8656 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8657 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8658 (match_operand:SI 2 "general_operand" "")))
8659 (clobber (reg:CC FLAGS_REG))]
8660 ""
8661 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8662
8663(define_insn "*iorsi_1"
8664 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8665 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8666 (match_operand:SI 2 "general_operand" "ri,rmi")))
8667 (clobber (reg:CC FLAGS_REG))]
8668 "ix86_binary_operator_ok (IOR, SImode, operands)"
8669 "or{l}\t{%2, %0|%0, %2}"
8670 [(set_attr "type" "alu")
8671 (set_attr "mode" "SI")])
8672
8673;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674(define_insn "*iorsi_1_zext"
8675 [(set (match_operand:DI 0 "register_operand" "=rm")
8676 (zero_extend:DI
8677 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678 (match_operand:SI 2 "general_operand" "rim"))))
8679 (clobber (reg:CC FLAGS_REG))]
8680 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8681 "or{l}\t{%2, %k0|%k0, %2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "mode" "SI")])
8684
8685(define_insn "*iorsi_1_zext_imm"
8686 [(set (match_operand:DI 0 "register_operand" "=rm")
8687 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8688 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8689 (clobber (reg:CC FLAGS_REG))]
8690 "TARGET_64BIT"
8691 "or{l}\t{%2, %k0|%k0, %2}"
8692 [(set_attr "type" "alu")
8693 (set_attr "mode" "SI")])
8694
8695(define_insn "*iorsi_2"
8696 [(set (reg FLAGS_REG)
8697 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8698 (match_operand:SI 2 "general_operand" "rim,ri"))
8699 (const_int 0)))
8700 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8701 (ior:SI (match_dup 1) (match_dup 2)))]
8702 "ix86_match_ccmode (insn, CCNOmode)
8703 && ix86_binary_operator_ok (IOR, SImode, operands)"
8704 "or{l}\t{%2, %0|%0, %2}"
8705 [(set_attr "type" "alu")
8706 (set_attr "mode" "SI")])
8707
8708;; See comment for addsi_1_zext why we do use nonimmediate_operand
8709;; ??? Special case for immediate operand is missing - it is tricky.
8710(define_insn "*iorsi_2_zext"
8711 [(set (reg FLAGS_REG)
8712 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713 (match_operand:SI 2 "general_operand" "rim"))
8714 (const_int 0)))
8715 (set (match_operand:DI 0 "register_operand" "=r")
8716 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8717 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8718 && ix86_binary_operator_ok (IOR, SImode, operands)"
8719 "or{l}\t{%2, %k0|%k0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "mode" "SI")])
8722
8723(define_insn "*iorsi_2_zext_imm"
8724 [(set (reg FLAGS_REG)
8725 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8726 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8727 (const_int 0)))
8728 (set (match_operand:DI 0 "register_operand" "=r")
8729 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8730 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8731 && ix86_binary_operator_ok (IOR, SImode, operands)"
8732 "or{l}\t{%2, %k0|%k0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "mode" "SI")])
8735
8736(define_insn "*iorsi_3"
8737 [(set (reg FLAGS_REG)
8738 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8739 (match_operand:SI 2 "general_operand" "rim"))
8740 (const_int 0)))
8741 (clobber (match_scratch:SI 0 "=r"))]
8742 "ix86_match_ccmode (insn, CCNOmode)
8743 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8744 "or{l}\t{%2, %0|%0, %2}"
8745 [(set_attr "type" "alu")
8746 (set_attr "mode" "SI")])
8747
8748(define_expand "iorhi3"
8749 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8750 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8751 (match_operand:HI 2 "general_operand" "")))
8752 (clobber (reg:CC FLAGS_REG))]
8753 "TARGET_HIMODE_MATH"
8754 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8755
8756(define_insn "*iorhi_1"
8757 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8758 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8759 (match_operand:HI 2 "general_operand" "rmi,ri")))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "ix86_binary_operator_ok (IOR, HImode, operands)"
8762 "or{w}\t{%2, %0|%0, %2}"
8763 [(set_attr "type" "alu")
8764 (set_attr "mode" "HI")])
8765
8766(define_insn "*iorhi_2"
8767 [(set (reg FLAGS_REG)
8768 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8769 (match_operand:HI 2 "general_operand" "rim,ri"))
8770 (const_int 0)))
8771 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8772 (ior:HI (match_dup 1) (match_dup 2)))]
8773 "ix86_match_ccmode (insn, CCNOmode)
8774 && ix86_binary_operator_ok (IOR, HImode, operands)"
8775 "or{w}\t{%2, %0|%0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "mode" "HI")])
8778
8779(define_insn "*iorhi_3"
8780 [(set (reg FLAGS_REG)
8781 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8782 (match_operand:HI 2 "general_operand" "rim"))
8783 (const_int 0)))
8784 (clobber (match_scratch:HI 0 "=r"))]
8785 "ix86_match_ccmode (insn, CCNOmode)
8786 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8787 "or{w}\t{%2, %0|%0, %2}"
8788 [(set_attr "type" "alu")
8789 (set_attr "mode" "HI")])
8790
8791(define_expand "iorqi3"
8792 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8793 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8794 (match_operand:QI 2 "general_operand" "")))
8795 (clobber (reg:CC FLAGS_REG))]
8796 "TARGET_QIMODE_MATH"
8797 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8798
8799;; %%% Potential partial reg stall on alternative 2. What to do?
8800(define_insn "*iorqi_1"
8801 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8802 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8803 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8804 (clobber (reg:CC FLAGS_REG))]
8805 "ix86_binary_operator_ok (IOR, QImode, operands)"
8806 "@
8807 or{b}\t{%2, %0|%0, %2}
8808 or{b}\t{%2, %0|%0, %2}
8809 or{l}\t{%k2, %k0|%k0, %k2}"
8810 [(set_attr "type" "alu")
8811 (set_attr "mode" "QI,QI,SI")])
8812
8813(define_insn "*iorqi_1_slp"
8814 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8815 (ior:QI (match_dup 0)
8816 (match_operand:QI 1 "general_operand" "qmi,qi")))
8817 (clobber (reg:CC FLAGS_REG))]
8818 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8820 "or{b}\t{%1, %0|%0, %1}"
8821 [(set_attr "type" "alu1")
8822 (set_attr "mode" "QI")])
8823
8824(define_insn "*iorqi_2"
8825 [(set (reg FLAGS_REG)
8826 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8827 (match_operand:QI 2 "general_operand" "qim,qi"))
8828 (const_int 0)))
8829 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8830 (ior:QI (match_dup 1) (match_dup 2)))]
8831 "ix86_match_ccmode (insn, CCNOmode)
8832 && ix86_binary_operator_ok (IOR, QImode, operands)"
8833 "or{b}\t{%2, %0|%0, %2}"
8834 [(set_attr "type" "alu")
8835 (set_attr "mode" "QI")])
8836
8837(define_insn "*iorqi_2_slp"
8838 [(set (reg FLAGS_REG)
8839 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8840 (match_operand:QI 1 "general_operand" "qim,qi"))
8841 (const_int 0)))
8842 (set (strict_low_part (match_dup 0))
8843 (ior:QI (match_dup 0) (match_dup 1)))]
8844 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8845 && ix86_match_ccmode (insn, CCNOmode)
8846 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8847 "or{b}\t{%1, %0|%0, %1}"
8848 [(set_attr "type" "alu1")
8849 (set_attr "mode" "QI")])
8850
8851(define_insn "*iorqi_3"
8852 [(set (reg FLAGS_REG)
8853 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8854 (match_operand:QI 2 "general_operand" "qim"))
8855 (const_int 0)))
8856 (clobber (match_scratch:QI 0 "=q"))]
8857 "ix86_match_ccmode (insn, CCNOmode)
8858 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8859 "or{b}\t{%2, %0|%0, %2}"
8860 [(set_attr "type" "alu")
8861 (set_attr "mode" "QI")])
8862
8863(define_insn "iorqi_ext_0"
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
8869 (match_operand 1 "ext_register_operand" "0")
8870 (const_int 8)
8871 (const_int 8))
8872 (match_operand 2 "const_int_operand" "n")))
8873 (clobber (reg:CC FLAGS_REG))]
8874 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8875 "or{b}\t{%2, %h0|%h0, %2}"
8876 [(set_attr "type" "alu")
8877 (set_attr "length_immediate" "1")
8878 (set_attr "mode" "QI")])
8879
8880(define_insn "*iorqi_ext_1"
8881 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8882 (const_int 8)
8883 (const_int 8))
8884 (ior:SI
8885 (zero_extract:SI
8886 (match_operand 1 "ext_register_operand" "0")
8887 (const_int 8)
8888 (const_int 8))
8889 (zero_extend:SI
8890 (match_operand:QI 2 "general_operand" "Qm"))))
8891 (clobber (reg:CC FLAGS_REG))]
8892 "!TARGET_64BIT
8893 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8894 "or{b}\t{%2, %h0|%h0, %2}"
8895 [(set_attr "type" "alu")
8896 (set_attr "length_immediate" "0")
8897 (set_attr "mode" "QI")])
8898
8899(define_insn "*iorqi_ext_1_rex64"
8900 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8901 (const_int 8)
8902 (const_int 8))
8903 (ior:SI
8904 (zero_extract:SI
8905 (match_operand 1 "ext_register_operand" "0")
8906 (const_int 8)
8907 (const_int 8))
8908 (zero_extend:SI
8909 (match_operand 2 "ext_register_operand" "Q"))))
8910 (clobber (reg:CC FLAGS_REG))]
8911 "TARGET_64BIT
8912 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8913 "or{b}\t{%2, %h0|%h0, %2}"
8914 [(set_attr "type" "alu")
8915 (set_attr "length_immediate" "0")
8916 (set_attr "mode" "QI")])
8917
8918(define_insn "*iorqi_ext_2"
8919 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8920 (const_int 8)
8921 (const_int 8))
8922 (ior:SI
8923 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8924 (const_int 8)
8925 (const_int 8))
8926 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8927 (const_int 8)
8928 (const_int 8))))
8929 (clobber (reg:CC FLAGS_REG))]
8930 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8931 "ior{b}\t{%h2, %h0|%h0, %h2}"
8932 [(set_attr "type" "alu")
8933 (set_attr "length_immediate" "0")
8934 (set_attr "mode" "QI")])
8935
8936(define_split
8937 [(set (match_operand 0 "register_operand" "")
8938 (ior (match_operand 1 "register_operand" "")
8939 (match_operand 2 "const_int_operand" "")))
8940 (clobber (reg:CC FLAGS_REG))]
8941 "reload_completed
8942 && QI_REG_P (operands[0])
8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944 && !(INTVAL (operands[2]) & ~(255 << 8))
8945 && GET_MODE (operands[0]) != QImode"
8946 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8947 (ior:SI (zero_extract:SI (match_dup 1)
8948 (const_int 8) (const_int 8))
8949 (match_dup 2)))
8950 (clobber (reg:CC FLAGS_REG))])]
8951 "operands[0] = gen_lowpart (SImode, operands[0]);
8952 operands[1] = gen_lowpart (SImode, operands[1]);
8953 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8954
8955;; Since OR can be encoded with sign extended immediate, this is only
8956;; profitable when 7th bit is set.
8957(define_split
8958 [(set (match_operand 0 "register_operand" "")
8959 (ior (match_operand 1 "general_operand" "")
8960 (match_operand 2 "const_int_operand" "")))
8961 (clobber (reg:CC FLAGS_REG))]
8962 "reload_completed
8963 && ANY_QI_REG_P (operands[0])
8964 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8965 && !(INTVAL (operands[2]) & ~255)
8966 && (INTVAL (operands[2]) & 128)
8967 && GET_MODE (operands[0]) != QImode"
8968 [(parallel [(set (strict_low_part (match_dup 0))
8969 (ior:QI (match_dup 1)
8970 (match_dup 2)))
8971 (clobber (reg:CC FLAGS_REG))])]
8972 "operands[0] = gen_lowpart (QImode, operands[0]);
8973 operands[1] = gen_lowpart (QImode, operands[1]);
8974 operands[2] = gen_lowpart (QImode, operands[2]);")
8975
8976;; Logical XOR instructions
8977
8978;; %%% This used to optimize known byte-wide and operations to memory.
8979;; If this is considered useful, it should be done with splitters.
8980
8981(define_expand "xordi3"
8982 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8983 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8984 (match_operand:DI 2 "x86_64_general_operand" "")))
8985 (clobber (reg:CC FLAGS_REG))]
8986 "TARGET_64BIT"
8987 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8988
8989(define_insn "*xordi_1_rex64"
8990 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8991 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8992 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8993 (clobber (reg:CC FLAGS_REG))]
8994 "TARGET_64BIT
8995 && ix86_binary_operator_ok (XOR, DImode, operands)"
8996 "@
8997 xor{q}\t{%2, %0|%0, %2}
8998 xor{q}\t{%2, %0|%0, %2}"
8999 [(set_attr "type" "alu")
9000 (set_attr "mode" "DI,DI")])
9001
9002(define_insn "*xordi_2_rex64"
9003 [(set (reg FLAGS_REG)
9004 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9005 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9006 (const_int 0)))
9007 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9008 (xor:DI (match_dup 1) (match_dup 2)))]
9009 "TARGET_64BIT
9010 && ix86_match_ccmode (insn, CCNOmode)
9011 && ix86_binary_operator_ok (XOR, DImode, operands)"
9012 "@
9013 xor{q}\t{%2, %0|%0, %2}
9014 xor{q}\t{%2, %0|%0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "DI,DI")])
9017
9018(define_insn "*xordi_3_rex64"
9019 [(set (reg FLAGS_REG)
9020 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9021 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9022 (const_int 0)))
9023 (clobber (match_scratch:DI 0 "=r"))]
9024 "TARGET_64BIT
9025 && ix86_match_ccmode (insn, CCNOmode)
9026 && ix86_binary_operator_ok (XOR, DImode, operands)"
9027 "xor{q}\t{%2, %0|%0, %2}"
9028 [(set_attr "type" "alu")
9029 (set_attr "mode" "DI")])
9030
9031(define_expand "xorsi3"
9032 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9033 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9034 (match_operand:SI 2 "general_operand" "")))
9035 (clobber (reg:CC FLAGS_REG))]
9036 ""
9037 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9038
9039(define_insn "*xorsi_1"
9040 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9041 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042 (match_operand:SI 2 "general_operand" "ri,rm")))
9043 (clobber (reg:CC FLAGS_REG))]
9044 "ix86_binary_operator_ok (XOR, SImode, operands)"
9045 "xor{l}\t{%2, %0|%0, %2}"
9046 [(set_attr "type" "alu")
9047 (set_attr "mode" "SI")])
9048
9049;; See comment for addsi_1_zext why we do use nonimmediate_operand
9050;; Add speccase for immediates
9051(define_insn "*xorsi_1_zext"
9052 [(set (match_operand:DI 0 "register_operand" "=r")
9053 (zero_extend:DI
9054 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055 (match_operand:SI 2 "general_operand" "rim"))))
9056 (clobber (reg:CC FLAGS_REG))]
9057 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9058 "xor{l}\t{%2, %k0|%k0, %2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "SI")])
9061
9062(define_insn "*xorsi_1_zext_imm"
9063 [(set (match_operand:DI 0 "register_operand" "=r")
9064 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9065 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9066 (clobber (reg:CC FLAGS_REG))]
9067 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9068 "xor{l}\t{%2, %k0|%k0, %2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "mode" "SI")])
9071
9072(define_insn "*xorsi_2"
9073 [(set (reg FLAGS_REG)
9074 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9075 (match_operand:SI 2 "general_operand" "rim,ri"))
9076 (const_int 0)))
9077 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9078 (xor:SI (match_dup 1) (match_dup 2)))]
9079 "ix86_match_ccmode (insn, CCNOmode)
9080 && ix86_binary_operator_ok (XOR, SImode, operands)"
9081 "xor{l}\t{%2, %0|%0, %2}"
9082 [(set_attr "type" "alu")
9083 (set_attr "mode" "SI")])
9084
9085;; See comment for addsi_1_zext why we do use nonimmediate_operand
9086;; ??? Special case for immediate operand is missing - it is tricky.
9087(define_insn "*xorsi_2_zext"
9088 [(set (reg FLAGS_REG)
9089 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090 (match_operand:SI 2 "general_operand" "rim"))
9091 (const_int 0)))
9092 (set (match_operand:DI 0 "register_operand" "=r")
9093 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9094 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9095 && ix86_binary_operator_ok (XOR, SImode, operands)"
9096 "xor{l}\t{%2, %k0|%k0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "SI")])
9099
9100(define_insn "*xorsi_2_zext_imm"
9101 [(set (reg FLAGS_REG)
9102 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9103 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9104 (const_int 0)))
9105 (set (match_operand:DI 0 "register_operand" "=r")
9106 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9107 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9108 && ix86_binary_operator_ok (XOR, SImode, operands)"
9109 "xor{l}\t{%2, %k0|%k0, %2}"
9110 [(set_attr "type" "alu")
9111 (set_attr "mode" "SI")])
9112
9113(define_insn "*xorsi_3"
9114 [(set (reg FLAGS_REG)
9115 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9116 (match_operand:SI 2 "general_operand" "rim"))
9117 (const_int 0)))
9118 (clobber (match_scratch:SI 0 "=r"))]
9119 "ix86_match_ccmode (insn, CCNOmode)
9120 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9121 "xor{l}\t{%2, %0|%0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "mode" "SI")])
9124
9125(define_expand "xorhi3"
9126 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9127 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9128 (match_operand:HI 2 "general_operand" "")))
9129 (clobber (reg:CC FLAGS_REG))]
9130 "TARGET_HIMODE_MATH"
9131 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9132
9133(define_insn "*xorhi_1"
9134 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9135 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136 (match_operand:HI 2 "general_operand" "rmi,ri")))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "ix86_binary_operator_ok (XOR, HImode, operands)"
9139 "xor{w}\t{%2, %0|%0, %2}"
9140 [(set_attr "type" "alu")
9141 (set_attr "mode" "HI")])
9142
9143(define_insn "*xorhi_2"
9144 [(set (reg FLAGS_REG)
9145 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9146 (match_operand:HI 2 "general_operand" "rim,ri"))
9147 (const_int 0)))
9148 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9149 (xor:HI (match_dup 1) (match_dup 2)))]
9150 "ix86_match_ccmode (insn, CCNOmode)
9151 && ix86_binary_operator_ok (XOR, HImode, operands)"
9152 "xor{w}\t{%2, %0|%0, %2}"
9153 [(set_attr "type" "alu")
9154 (set_attr "mode" "HI")])
9155
9156(define_insn "*xorhi_3"
9157 [(set (reg FLAGS_REG)
9158 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9159 (match_operand:HI 2 "general_operand" "rim"))
9160 (const_int 0)))
9161 (clobber (match_scratch:HI 0 "=r"))]
9162 "ix86_match_ccmode (insn, CCNOmode)
9163 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9164 "xor{w}\t{%2, %0|%0, %2}"
9165 [(set_attr "type" "alu")
9166 (set_attr "mode" "HI")])
9167
9168(define_expand "xorqi3"
9169 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9170 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9171 (match_operand:QI 2 "general_operand" "")))
9172 (clobber (reg:CC FLAGS_REG))]
9173 "TARGET_QIMODE_MATH"
9174 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9175
9176;; %%% Potential partial reg stall on alternative 2. What to do?
9177(define_insn "*xorqi_1"
9178 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9179 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9180 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "ix86_binary_operator_ok (XOR, QImode, operands)"
9183 "@
9184 xor{b}\t{%2, %0|%0, %2}
9185 xor{b}\t{%2, %0|%0, %2}
9186 xor{l}\t{%k2, %k0|%k0, %k2}"
9187 [(set_attr "type" "alu")
9188 (set_attr "mode" "QI,QI,SI")])
9189
9190(define_insn "*xorqi_1_slp"
9191 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9192 (xor:QI (match_dup 0)
9193 (match_operand:QI 1 "general_operand" "qi,qmi")))
9194 (clobber (reg:CC FLAGS_REG))]
9195 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9197 "xor{b}\t{%1, %0|%0, %1}"
9198 [(set_attr "type" "alu1")
9199 (set_attr "mode" "QI")])
9200
9201(define_insn "xorqi_ext_0"
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
9207 (match_operand 1 "ext_register_operand" "0")
9208 (const_int 8)
9209 (const_int 8))
9210 (match_operand 2 "const_int_operand" "n")))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9213 "xor{b}\t{%2, %h0|%h0, %2}"
9214 [(set_attr "type" "alu")
9215 (set_attr "length_immediate" "1")
9216 (set_attr "mode" "QI")])
9217
9218(define_insn "*xorqi_ext_1"
9219 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9220 (const_int 8)
9221 (const_int 8))
9222 (xor:SI
9223 (zero_extract:SI
9224 (match_operand 1 "ext_register_operand" "0")
9225 (const_int 8)
9226 (const_int 8))
9227 (zero_extend:SI
9228 (match_operand:QI 2 "general_operand" "Qm"))))
9229 (clobber (reg:CC FLAGS_REG))]
9230 "!TARGET_64BIT
9231 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9232 "xor{b}\t{%2, %h0|%h0, %2}"
9233 [(set_attr "type" "alu")
9234 (set_attr "length_immediate" "0")
9235 (set_attr "mode" "QI")])
9236
9237(define_insn "*xorqi_ext_1_rex64"
9238 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9239 (const_int 8)
9240 (const_int 8))
9241 (xor:SI
9242 (zero_extract:SI
9243 (match_operand 1 "ext_register_operand" "0")
9244 (const_int 8)
9245 (const_int 8))
9246 (zero_extend:SI
9247 (match_operand 2 "ext_register_operand" "Q"))))
9248 (clobber (reg:CC FLAGS_REG))]
9249 "TARGET_64BIT
9250 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9251 "xor{b}\t{%2, %h0|%h0, %2}"
9252 [(set_attr "type" "alu")
9253 (set_attr "length_immediate" "0")
9254 (set_attr "mode" "QI")])
9255
9256(define_insn "*xorqi_ext_2"
9257 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9258 (const_int 8)
9259 (const_int 8))
9260 (xor:SI
9261 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9262 (const_int 8)
9263 (const_int 8))
9264 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9265 (const_int 8)
9266 (const_int 8))))
9267 (clobber (reg:CC FLAGS_REG))]
9268 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9269 "xor{b}\t{%h2, %h0|%h0, %h2}"
9270 [(set_attr "type" "alu")
9271 (set_attr "length_immediate" "0")
9272 (set_attr "mode" "QI")])
9273
9274(define_insn "*xorqi_cc_1"
9275 [(set (reg FLAGS_REG)
9276 (compare
9277 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9278 (match_operand:QI 2 "general_operand" "qim,qi"))
9279 (const_int 0)))
9280 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9281 (xor:QI (match_dup 1) (match_dup 2)))]
9282 "ix86_match_ccmode (insn, CCNOmode)
9283 && ix86_binary_operator_ok (XOR, QImode, operands)"
9284 "xor{b}\t{%2, %0|%0, %2}"
9285 [(set_attr "type" "alu")
9286 (set_attr "mode" "QI")])
9287
9288(define_insn "*xorqi_2_slp"
9289 [(set (reg FLAGS_REG)
9290 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9291 (match_operand:QI 1 "general_operand" "qim,qi"))
9292 (const_int 0)))
9293 (set (strict_low_part (match_dup 0))
9294 (xor:QI (match_dup 0) (match_dup 1)))]
9295 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9296 && ix86_match_ccmode (insn, CCNOmode)
9297 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9298 "xor{b}\t{%1, %0|%0, %1}"
9299 [(set_attr "type" "alu1")
9300 (set_attr "mode" "QI")])
9301
9302(define_insn "*xorqi_cc_2"
9303 [(set (reg FLAGS_REG)
9304 (compare
9305 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9306 (match_operand:QI 2 "general_operand" "qim"))
9307 (const_int 0)))
9308 (clobber (match_scratch:QI 0 "=q"))]
9309 "ix86_match_ccmode (insn, CCNOmode)
9310 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9311 "xor{b}\t{%2, %0|%0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "QI")])
9314
9315(define_insn "*xorqi_cc_ext_1"
9316 [(set (reg FLAGS_REG)
9317 (compare
9318 (xor:SI
9319 (zero_extract:SI
9320 (match_operand 1 "ext_register_operand" "0")
9321 (const_int 8)
9322 (const_int 8))
9323 (match_operand:QI 2 "general_operand" "qmn"))
9324 (const_int 0)))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9326 (const_int 8)
9327 (const_int 8))
9328 (xor:SI
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330 (match_dup 2)))]
9331 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332 "xor{b}\t{%2, %h0|%h0, %2}"
9333 [(set_attr "type" "alu")
9334 (set_attr "mode" "QI")])
9335
9336(define_insn "*xorqi_cc_ext_1_rex64"
9337 [(set (reg FLAGS_REG)
9338 (compare
9339 (xor:SI
9340 (zero_extract:SI
9341 (match_operand 1 "ext_register_operand" "0")
9342 (const_int 8)
9343 (const_int 8))
9344 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9345 (const_int 0)))
9346 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9347 (const_int 8)
9348 (const_int 8))
9349 (xor:SI
9350 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9351 (match_dup 2)))]
9352 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9353 "xor{b}\t{%2, %h0|%h0, %2}"
9354 [(set_attr "type" "alu")
9355 (set_attr "mode" "QI")])
9356
9357(define_expand "xorqi_cc_ext_1"
9358 [(parallel [
9359 (set (reg:CCNO FLAGS_REG)
9360 (compare:CCNO
9361 (xor:SI
9362 (zero_extract:SI
9363 (match_operand 1 "ext_register_operand" "")
9364 (const_int 8)
9365 (const_int 8))
9366 (match_operand:QI 2 "general_operand" ""))
9367 (const_int 0)))
9368 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9369 (const_int 8)
9370 (const_int 8))
9371 (xor:SI
9372 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9373 (match_dup 2)))])]
9374 ""
9375 "")
9376
9377(define_split
9378 [(set (match_operand 0 "register_operand" "")
9379 (xor (match_operand 1 "register_operand" "")
9380 (match_operand 2 "const_int_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "reload_completed
9383 && QI_REG_P (operands[0])
9384 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385 && !(INTVAL (operands[2]) & ~(255 << 8))
9386 && GET_MODE (operands[0]) != QImode"
9387 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9388 (xor:SI (zero_extract:SI (match_dup 1)
9389 (const_int 8) (const_int 8))
9390 (match_dup 2)))
9391 (clobber (reg:CC FLAGS_REG))])]
9392 "operands[0] = gen_lowpart (SImode, operands[0]);
9393 operands[1] = gen_lowpart (SImode, operands[1]);
9394 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9395
9396;; Since XOR can be encoded with sign extended immediate, this is only
9397;; profitable when 7th bit is set.
9398(define_split
9399 [(set (match_operand 0 "register_operand" "")
9400 (xor (match_operand 1 "general_operand" "")
9401 (match_operand 2 "const_int_operand" "")))
9402 (clobber (reg:CC FLAGS_REG))]
9403 "reload_completed
9404 && ANY_QI_REG_P (operands[0])
9405 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9406 && !(INTVAL (operands[2]) & ~255)
9407 && (INTVAL (operands[2]) & 128)
9408 && GET_MODE (operands[0]) != QImode"
9409 [(parallel [(set (strict_low_part (match_dup 0))
9410 (xor:QI (match_dup 1)
9411 (match_dup 2)))
9412 (clobber (reg:CC FLAGS_REG))])]
9413 "operands[0] = gen_lowpart (QImode, operands[0]);
9414 operands[1] = gen_lowpart (QImode, operands[1]);
9415 operands[2] = gen_lowpart (QImode, operands[2]);")
9416
9417;; Negation instructions
9418
9419(define_expand "negti2"
9420 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9421 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9422 (clobber (reg:CC FLAGS_REG))])]
9423 "TARGET_64BIT"
9424 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9425
9426(define_insn "*negti2_1"
9427 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9428 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9429 (clobber (reg:CC FLAGS_REG))]
9430 "TARGET_64BIT
9431 && ix86_unary_operator_ok (NEG, TImode, operands)"
9432 "#")
9433
9434(define_split
9435 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9436 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9437 (clobber (reg:CC FLAGS_REG))]
9438 "TARGET_64BIT && reload_completed"
9439 [(parallel
9440 [(set (reg:CCZ FLAGS_REG)
9441 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9442 (set (match_dup 0) (neg:DI (match_dup 2)))])
9443 (parallel
9444 [(set (match_dup 1)
9445 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9446 (match_dup 3))
9447 (const_int 0)))
9448 (clobber (reg:CC FLAGS_REG))])
9449 (parallel
9450 [(set (match_dup 1)
9451 (neg:DI (match_dup 1)))
9452 (clobber (reg:CC FLAGS_REG))])]
9453 "split_ti (operands+1, 1, operands+2, operands+3);
9454 split_ti (operands+0, 1, operands+0, operands+1);")
9455
9456(define_expand "negdi2"
9457 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9458 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9459 (clobber (reg:CC FLAGS_REG))])]
9460 ""
9461 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9462
9463(define_insn "*negdi2_1"
9464 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9465 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "!TARGET_64BIT
9468 && ix86_unary_operator_ok (NEG, DImode, operands)"
9469 "#")
9470
9471(define_split
9472 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9473 (neg:DI (match_operand:DI 1 "general_operand" "")))
9474 (clobber (reg:CC FLAGS_REG))]
9475 "!TARGET_64BIT && reload_completed"
9476 [(parallel
9477 [(set (reg:CCZ FLAGS_REG)
9478 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9479 (set (match_dup 0) (neg:SI (match_dup 2)))])
9480 (parallel
9481 [(set (match_dup 1)
9482 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9483 (match_dup 3))
9484 (const_int 0)))
9485 (clobber (reg:CC FLAGS_REG))])
9486 (parallel
9487 [(set (match_dup 1)
9488 (neg:SI (match_dup 1)))
9489 (clobber (reg:CC FLAGS_REG))])]
9490 "split_di (operands+1, 1, operands+2, operands+3);
9491 split_di (operands+0, 1, operands+0, operands+1);")
9492
9493(define_insn "*negdi2_1_rex64"
9494 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9495 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9496 (clobber (reg:CC FLAGS_REG))]
9497 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9498 "neg{q}\t%0"
9499 [(set_attr "type" "negnot")
9500 (set_attr "mode" "DI")])
9501
9502;; The problem with neg is that it does not perform (compare x 0),
9503;; it really performs (compare 0 x), which leaves us with the zero
9504;; flag being the only useful item.
9505
9506(define_insn "*negdi2_cmpz_rex64"
9507 [(set (reg:CCZ FLAGS_REG)
9508 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9509 (const_int 0)))
9510 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9511 (neg:DI (match_dup 1)))]
9512 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9513 "neg{q}\t%0"
9514 [(set_attr "type" "negnot")
9515 (set_attr "mode" "DI")])
9516
9517
9518(define_expand "negsi2"
9519 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9520 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9521 (clobber (reg:CC FLAGS_REG))])]
9522 ""
9523 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9524
9525(define_insn "*negsi2_1"
9526 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9527 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "ix86_unary_operator_ok (NEG, SImode, operands)"
9530 "neg{l}\t%0"
9531 [(set_attr "type" "negnot")
9532 (set_attr "mode" "SI")])
9533
9534;; Combine is quite creative about this pattern.
9535(define_insn "*negsi2_1_zext"
9536 [(set (match_operand:DI 0 "register_operand" "=r")
9537 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9538 (const_int 32)))
9539 (const_int 32)))
9540 (clobber (reg:CC FLAGS_REG))]
9541 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9542 "neg{l}\t%k0"
9543 [(set_attr "type" "negnot")
9544 (set_attr "mode" "SI")])
9545
9546;; The problem with neg is that it does not perform (compare x 0),
9547;; it really performs (compare 0 x), which leaves us with the zero
9548;; flag being the only useful item.
9549
9550(define_insn "*negsi2_cmpz"
9551 [(set (reg:CCZ FLAGS_REG)
9552 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9553 (const_int 0)))
9554 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9555 (neg:SI (match_dup 1)))]
9556 "ix86_unary_operator_ok (NEG, SImode, operands)"
9557 "neg{l}\t%0"
9558 [(set_attr "type" "negnot")
9559 (set_attr "mode" "SI")])
9560
9561(define_insn "*negsi2_cmpz_zext"
9562 [(set (reg:CCZ FLAGS_REG)
9563 (compare:CCZ (lshiftrt:DI
9564 (neg:DI (ashift:DI
9565 (match_operand:DI 1 "register_operand" "0")
9566 (const_int 32)))
9567 (const_int 32))
9568 (const_int 0)))
9569 (set (match_operand:DI 0 "register_operand" "=r")
9570 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9571 (const_int 32)))
9572 (const_int 32)))]
9573 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9574 "neg{l}\t%k0"
9575 [(set_attr "type" "negnot")
9576 (set_attr "mode" "SI")])
9577
9578(define_expand "neghi2"
9579 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9580 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9581 (clobber (reg:CC FLAGS_REG))])]
9582 "TARGET_HIMODE_MATH"
9583 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9584
9585(define_insn "*neghi2_1"
9586 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9587 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9588 (clobber (reg:CC FLAGS_REG))]
9589 "ix86_unary_operator_ok (NEG, HImode, operands)"
9590 "neg{w}\t%0"
9591 [(set_attr "type" "negnot")
9592 (set_attr "mode" "HI")])
9593
9594(define_insn "*neghi2_cmpz"
9595 [(set (reg:CCZ FLAGS_REG)
9596 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9597 (const_int 0)))
9598 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9599 (neg:HI (match_dup 1)))]
9600 "ix86_unary_operator_ok (NEG, HImode, operands)"
9601 "neg{w}\t%0"
9602 [(set_attr "type" "negnot")
9603 (set_attr "mode" "HI")])
9604
9605(define_expand "negqi2"
9606 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9607 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9608 (clobber (reg:CC FLAGS_REG))])]
9609 "TARGET_QIMODE_MATH"
9610 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9611
9612(define_insn "*negqi2_1"
9613 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9614 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9615 (clobber (reg:CC FLAGS_REG))]
9616 "ix86_unary_operator_ok (NEG, QImode, operands)"
9617 "neg{b}\t%0"
9618 [(set_attr "type" "negnot")
9619 (set_attr "mode" "QI")])
9620
9621(define_insn "*negqi2_cmpz"
9622 [(set (reg:CCZ FLAGS_REG)
9623 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9624 (const_int 0)))
9625 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9626 (neg:QI (match_dup 1)))]
9627 "ix86_unary_operator_ok (NEG, QImode, operands)"
9628 "neg{b}\t%0"
9629 [(set_attr "type" "negnot")
9630 (set_attr "mode" "QI")])
9631
9632;; Changing of sign for FP values is doable using integer unit too.
9633
9634(define_expand "negsf2"
9635 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9636 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9637 "TARGET_80387 || TARGET_SSE_MATH"
9638 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9639
9640(define_expand "abssf2"
9641 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9642 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9643 "TARGET_80387 || TARGET_SSE_MATH"
9644 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9645
9646(define_insn "*absnegsf2_mixed"
9647 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9648 (match_operator:SF 3 "absneg_operator"
9649 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9650 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9653 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9654 "#")
9655
9656(define_insn "*absnegsf2_sse"
9657 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9658 (match_operator:SF 3 "absneg_operator"
9659 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9660 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9661 (clobber (reg:CC FLAGS_REG))]
9662 "TARGET_SSE_MATH
9663 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9664 "#")
9665
9666(define_insn "*absnegsf2_i387"
9667 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9668 (match_operator:SF 3 "absneg_operator"
9669 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9670 (use (match_operand 2 "" ""))
9671 (clobber (reg:CC FLAGS_REG))]
9672 "TARGET_80387 && !TARGET_SSE_MATH
9673 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9674 "#")
9675
9676(define_expand "copysignsf3"
9677 [(match_operand:SF 0 "register_operand" "")
9678 (match_operand:SF 1 "nonmemory_operand" "")
9679 (match_operand:SF 2 "register_operand" "")]
9680 "TARGET_SSE_MATH"
9681{
9682 ix86_expand_copysign (operands);
9683 DONE;
9684})
9685
9686(define_insn_and_split "copysignsf3_const"
9687 [(set (match_operand:SF 0 "register_operand" "=x")
9688 (unspec:SF
9689 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9690 (match_operand:SF 2 "register_operand" "0")
9691 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9692 UNSPEC_COPYSIGN))]
9693 "TARGET_SSE_MATH"
9694 "#"
9695 "&& reload_completed"
9696 [(const_int 0)]
9697{
9698 ix86_split_copysign_const (operands);
9699 DONE;
9700})
9701
9702(define_insn "copysignsf3_var"
9703 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9704 (unspec:SF
9705 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9706 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9707 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9708 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9709 UNSPEC_COPYSIGN))
9710 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9711 "TARGET_SSE_MATH"
9712 "#")
9713
9714(define_split
9715 [(set (match_operand:SF 0 "register_operand" "")
9716 (unspec:SF
9717 [(match_operand:SF 2 "register_operand" "")
9718 (match_operand:SF 3 "register_operand" "")
9719 (match_operand:V4SF 4 "" "")
9720 (match_operand:V4SF 5 "" "")]
9721 UNSPEC_COPYSIGN))
9722 (clobber (match_scratch:V4SF 1 ""))]
9723 "TARGET_SSE_MATH && reload_completed"
9724 [(const_int 0)]
9725{
9726 ix86_split_copysign_var (operands);
9727 DONE;
9728})
9729
9730(define_expand "negdf2"
9731 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9732 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9733 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9734 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9735
9736(define_expand "absdf2"
9737 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9738 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9739 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9740 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9741
9742(define_insn "*absnegdf2_mixed"
9743 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9744 (match_operator:DF 3 "absneg_operator"
9745 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9746 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9747 (clobber (reg:CC FLAGS_REG))]
9748 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9749 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9750 "#")
9751
9752(define_insn "*absnegdf2_sse"
9753 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9754 (match_operator:DF 3 "absneg_operator"
9755 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9756 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9757 (clobber (reg:CC FLAGS_REG))]
9758 "TARGET_SSE2 && TARGET_SSE_MATH
9759 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9760 "#")
9761
9762(define_insn "*absnegdf2_i387"
9763 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9764 (match_operator:DF 3 "absneg_operator"
9765 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9766 (use (match_operand 2 "" ""))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9769 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9770 "#")
9771
9772(define_expand "copysigndf3"
9773 [(match_operand:DF 0 "register_operand" "")
9774 (match_operand:DF 1 "nonmemory_operand" "")
9775 (match_operand:DF 2 "register_operand" "")]
9776 "TARGET_SSE2 && TARGET_SSE_MATH"
9777{
9778 ix86_expand_copysign (operands);
9779 DONE;
9780})
9781
9782(define_insn_and_split "copysigndf3_const"
9783 [(set (match_operand:DF 0 "register_operand" "=x")
9784 (unspec:DF
9785 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9786 (match_operand:DF 2 "register_operand" "0")
9787 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9788 UNSPEC_COPYSIGN))]
9789 "TARGET_SSE2 && TARGET_SSE_MATH"
9790 "#"
9791 "&& reload_completed"
9792 [(const_int 0)]
9793{
9794 ix86_split_copysign_const (operands);
9795 DONE;
9796})
9797
9798(define_insn "copysigndf3_var"
9799 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9800 (unspec:DF
9801 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9802 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9803 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9804 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9805 UNSPEC_COPYSIGN))
9806 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9807 "TARGET_SSE2 && TARGET_SSE_MATH"
9808 "#")
9809
9810(define_split
9811 [(set (match_operand:DF 0 "register_operand" "")
9812 (unspec:DF
9813 [(match_operand:DF 2 "register_operand" "")
9814 (match_operand:DF 3 "register_operand" "")
9815 (match_operand:V2DF 4 "" "")
9816 (match_operand:V2DF 5 "" "")]
9817 UNSPEC_COPYSIGN))
9818 (clobber (match_scratch:V2DF 1 ""))]
9819 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9820 [(const_int 0)]
9821{
9822 ix86_split_copysign_var (operands);
9823 DONE;
9824})
9825
9826(define_expand "negxf2"
9827 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9828 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9829 "TARGET_80387"
9830 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9831
9832(define_expand "absxf2"
9833 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9834 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9835 "TARGET_80387"
9836 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9837
9838(define_insn "*absnegxf2_i387"
9839 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9840 (match_operator:XF 3 "absneg_operator"
9841 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9842 (use (match_operand 2 "" ""))
9843 (clobber (reg:CC FLAGS_REG))]
9844 "TARGET_80387
9845 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9846 "#")
9847
9848;; Splitters for fp abs and neg.
9849
9850(define_split
9851 [(set (match_operand 0 "fp_register_operand" "")
9852 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9853 (use (match_operand 2 "" ""))
9854 (clobber (reg:CC FLAGS_REG))]
9855 "reload_completed"
9856 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9857
9858(define_split
9859 [(set (match_operand 0 "register_operand" "")
9860 (match_operator 3 "absneg_operator"
9861 [(match_operand 1 "register_operand" "")]))
9862 (use (match_operand 2 "nonimmediate_operand" ""))
9863 (clobber (reg:CC FLAGS_REG))]
9864 "reload_completed && SSE_REG_P (operands[0])"
9865 [(set (match_dup 0) (match_dup 3))]
9866{
9867 enum machine_mode mode = GET_MODE (operands[0]);
9868 enum machine_mode vmode = GET_MODE (operands[2]);
9869 rtx tmp;
9870
9871 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9872 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9873 if (operands_match_p (operands[0], operands[2]))
9874 {
9875 tmp = operands[1];
9876 operands[1] = operands[2];
9877 operands[2] = tmp;
9878 }
9879 if (GET_CODE (operands[3]) == ABS)
9880 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9881 else
9882 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9883 operands[3] = tmp;
9884})
9885
9886(define_split
9887 [(set (match_operand:SF 0 "register_operand" "")
9888 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9889 (use (match_operand:V4SF 2 "" ""))
9890 (clobber (reg:CC FLAGS_REG))]
9891 "reload_completed"
9892 [(parallel [(set (match_dup 0) (match_dup 1))
9893 (clobber (reg:CC FLAGS_REG))])]
9894{
9895 rtx tmp;
9896 operands[0] = gen_lowpart (SImode, operands[0]);
9897 if (GET_CODE (operands[1]) == ABS)
9898 {
9899 tmp = gen_int_mode (0x7fffffff, SImode);
9900 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9901 }
9902 else
9903 {
9904 tmp = gen_int_mode (0x80000000, SImode);
9905 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9906 }
9907 operands[1] = tmp;
9908})
9909
9910(define_split
9911 [(set (match_operand:DF 0 "register_operand" "")
9912 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9913 (use (match_operand 2 "" ""))
9914 (clobber (reg:CC FLAGS_REG))]
9915 "reload_completed"
9916 [(parallel [(set (match_dup 0) (match_dup 1))
9917 (clobber (reg:CC FLAGS_REG))])]
9918{
9919 rtx tmp;
9920 if (TARGET_64BIT)
9921 {
9922 tmp = gen_lowpart (DImode, operands[0]);
9923 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9924 operands[0] = tmp;
9925
9926 if (GET_CODE (operands[1]) == ABS)
9927 tmp = const0_rtx;
9928 else
9929 tmp = gen_rtx_NOT (DImode, tmp);
9930 }
9931 else
9932 {
9933 operands[0] = gen_highpart (SImode, operands[0]);
9934 if (GET_CODE (operands[1]) == ABS)
9935 {
9936 tmp = gen_int_mode (0x7fffffff, SImode);
9937 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9938 }
9939 else
9940 {
9941 tmp = gen_int_mode (0x80000000, SImode);
9942 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9943 }
9944 }
9945 operands[1] = tmp;
9946})
9947
9948(define_split
9949 [(set (match_operand:XF 0 "register_operand" "")
9950 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9951 (use (match_operand 2 "" ""))
9952 (clobber (reg:CC FLAGS_REG))]
9953 "reload_completed"
9954 [(parallel [(set (match_dup 0) (match_dup 1))
9955 (clobber (reg:CC FLAGS_REG))])]
9956{
9957 rtx tmp;
9958 operands[0] = gen_rtx_REG (SImode,
9959 true_regnum (operands[0])
9960 + (TARGET_64BIT ? 1 : 2));
9961 if (GET_CODE (operands[1]) == ABS)
9962 {
9963 tmp = GEN_INT (0x7fff);
9964 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9965 }
9966 else
9967 {
9968 tmp = GEN_INT (0x8000);
9969 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9970 }
9971 operands[1] = tmp;
9972})
9973
9974(define_split
9975 [(set (match_operand 0 "memory_operand" "")
9976 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9977 (use (match_operand 2 "" ""))
9978 (clobber (reg:CC FLAGS_REG))]
9979 "reload_completed"
9980 [(parallel [(set (match_dup 0) (match_dup 1))
9981 (clobber (reg:CC FLAGS_REG))])]
9982{
9983 enum machine_mode mode = GET_MODE (operands[0]);
9984 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9985 rtx tmp;
9986
9987 operands[0] = adjust_address (operands[0], QImode, size - 1);
9988 if (GET_CODE (operands[1]) == ABS)
9989 {
9990 tmp = gen_int_mode (0x7f, QImode);
9991 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9992 }
9993 else
9994 {
9995 tmp = gen_int_mode (0x80, QImode);
9996 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9997 }
9998 operands[1] = tmp;
9999})
10000
10001;; Conditionalize these after reload. If they match before reload, we
10002;; lose the clobber and ability to use integer instructions.
10003
10004(define_insn "*negsf2_1"
10005 [(set (match_operand:SF 0 "register_operand" "=f")
10006 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10007 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10008 "fchs"
10009 [(set_attr "type" "fsgn")
10010 (set_attr "mode" "SF")])
10011
10012(define_insn "*negdf2_1"
10013 [(set (match_operand:DF 0 "register_operand" "=f")
10014 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10015 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10016 "fchs"
10017 [(set_attr "type" "fsgn")
10018 (set_attr "mode" "DF")])
10019
10020(define_insn "*negxf2_1"
10021 [(set (match_operand:XF 0 "register_operand" "=f")
10022 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10023 "TARGET_80387"
10024 "fchs"
10025 [(set_attr "type" "fsgn")
10026 (set_attr "mode" "XF")])
10027
10028(define_insn "*abssf2_1"
10029 [(set (match_operand:SF 0 "register_operand" "=f")
10030 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10031 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10032 "fabs"
10033 [(set_attr "type" "fsgn")
10034 (set_attr "mode" "SF")])
10035
10036(define_insn "*absdf2_1"
10037 [(set (match_operand:DF 0 "register_operand" "=f")
10038 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10039 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10040 "fabs"
10041 [(set_attr "type" "fsgn")
10042 (set_attr "mode" "DF")])
10043
10044(define_insn "*absxf2_1"
10045 [(set (match_operand:XF 0 "register_operand" "=f")
10046 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10047 "TARGET_80387"
10048 "fabs"
10049 [(set_attr "type" "fsgn")
10050 (set_attr "mode" "DF")])
10051
10052(define_insn "*negextendsfdf2"
10053 [(set (match_operand:DF 0 "register_operand" "=f")
10054 (neg:DF (float_extend:DF
10055 (match_operand:SF 1 "register_operand" "0"))))]
10056 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10057 "fchs"
10058 [(set_attr "type" "fsgn")
10059 (set_attr "mode" "DF")])
10060
10061(define_insn "*negextenddfxf2"
10062 [(set (match_operand:XF 0 "register_operand" "=f")
10063 (neg:XF (float_extend:XF
10064 (match_operand:DF 1 "register_operand" "0"))))]
10065 "TARGET_80387"
10066 "fchs"
10067 [(set_attr "type" "fsgn")
10068 (set_attr "mode" "XF")])
10069
10070(define_insn "*negextendsfxf2"
10071 [(set (match_operand:XF 0 "register_operand" "=f")
10072 (neg:XF (float_extend:XF
10073 (match_operand:SF 1 "register_operand" "0"))))]
10074 "TARGET_80387"
10075 "fchs"
10076 [(set_attr "type" "fsgn")
10077 (set_attr "mode" "XF")])
10078
10079(define_insn "*absextendsfdf2"
10080 [(set (match_operand:DF 0 "register_operand" "=f")
10081 (abs:DF (float_extend:DF
10082 (match_operand:SF 1 "register_operand" "0"))))]
10083 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10084 "fabs"
10085 [(set_attr "type" "fsgn")
10086 (set_attr "mode" "DF")])
10087
10088(define_insn "*absextenddfxf2"
10089 [(set (match_operand:XF 0 "register_operand" "=f")
10090 (abs:XF (float_extend:XF
10091 (match_operand:DF 1 "register_operand" "0"))))]
10092 "TARGET_80387"
10093 "fabs"
10094 [(set_attr "type" "fsgn")
10095 (set_attr "mode" "XF")])
10096
10097(define_insn "*absextendsfxf2"
10098 [(set (match_operand:XF 0 "register_operand" "=f")
10099 (abs:XF (float_extend:XF
10100 (match_operand:SF 1 "register_operand" "0"))))]
10101 "TARGET_80387"
10102 "fabs"
10103 [(set_attr "type" "fsgn")
10104 (set_attr "mode" "XF")])
10105
10106;; One complement instructions
10107
10108(define_expand "one_cmpldi2"
10109 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10110 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10111 "TARGET_64BIT"
10112 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10113
10114(define_insn "*one_cmpldi2_1_rex64"
10115 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10116 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10117 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10118 "not{q}\t%0"
10119 [(set_attr "type" "negnot")
10120 (set_attr "mode" "DI")])
10121
10122(define_insn "*one_cmpldi2_2_rex64"
10123 [(set (reg FLAGS_REG)
10124 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10125 (const_int 0)))
10126 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10127 (not:DI (match_dup 1)))]
10128 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10129 && ix86_unary_operator_ok (NOT, DImode, operands)"
10130 "#"
10131 [(set_attr "type" "alu1")
10132 (set_attr "mode" "DI")])
10133
10134(define_split
10135 [(set (match_operand 0 "flags_reg_operand" "")
10136 (match_operator 2 "compare_operator"
10137 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10138 (const_int 0)]))
10139 (set (match_operand:DI 1 "nonimmediate_operand" "")
10140 (not:DI (match_dup 3)))]
10141 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10142 [(parallel [(set (match_dup 0)
10143 (match_op_dup 2
10144 [(xor:DI (match_dup 3) (const_int -1))
10145 (const_int 0)]))
10146 (set (match_dup 1)
10147 (xor:DI (match_dup 3) (const_int -1)))])]
10148 "")
10149
10150(define_expand "one_cmplsi2"
10151 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10152 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10153 ""
10154 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10155
10156(define_insn "*one_cmplsi2_1"
10157 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10158 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10159 "ix86_unary_operator_ok (NOT, SImode, operands)"
10160 "not{l}\t%0"
10161 [(set_attr "type" "negnot")
10162 (set_attr "mode" "SI")])
10163
10164;; ??? Currently never generated - xor is used instead.
10165(define_insn "*one_cmplsi2_1_zext"
10166 [(set (match_operand:DI 0 "register_operand" "=r")
10167 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10168 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10169 "not{l}\t%k0"
10170 [(set_attr "type" "negnot")
10171 (set_attr "mode" "SI")])
10172
10173(define_insn "*one_cmplsi2_2"
10174 [(set (reg FLAGS_REG)
10175 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10176 (const_int 0)))
10177 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10178 (not:SI (match_dup 1)))]
10179 "ix86_match_ccmode (insn, CCNOmode)
10180 && ix86_unary_operator_ok (NOT, SImode, operands)"
10181 "#"
10182 [(set_attr "type" "alu1")
10183 (set_attr "mode" "SI")])
10184
10185(define_split
10186 [(set (match_operand 0 "flags_reg_operand" "")
10187 (match_operator 2 "compare_operator"
10188 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10189 (const_int 0)]))
10190 (set (match_operand:SI 1 "nonimmediate_operand" "")
10191 (not:SI (match_dup 3)))]
10192 "ix86_match_ccmode (insn, CCNOmode)"
10193 [(parallel [(set (match_dup 0)
10194 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10195 (const_int 0)]))
10196 (set (match_dup 1)
10197 (xor:SI (match_dup 3) (const_int -1)))])]
10198 "")
10199
10200;; ??? Currently never generated - xor is used instead.
10201(define_insn "*one_cmplsi2_2_zext"
10202 [(set (reg FLAGS_REG)
10203 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10204 (const_int 0)))
10205 (set (match_operand:DI 0 "register_operand" "=r")
10206 (zero_extend:DI (not:SI (match_dup 1))))]
10207 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10208 && ix86_unary_operator_ok (NOT, SImode, operands)"
10209 "#"
10210 [(set_attr "type" "alu1")
10211 (set_attr "mode" "SI")])
10212
10213(define_split
10214 [(set (match_operand 0 "flags_reg_operand" "")
10215 (match_operator 2 "compare_operator"
10216 [(not:SI (match_operand:SI 3 "register_operand" ""))
10217 (const_int 0)]))
10218 (set (match_operand:DI 1 "register_operand" "")
10219 (zero_extend:DI (not:SI (match_dup 3))))]
10220 "ix86_match_ccmode (insn, CCNOmode)"
10221 [(parallel [(set (match_dup 0)
10222 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10223 (const_int 0)]))
10224 (set (match_dup 1)
10225 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10226 "")
10227
10228(define_expand "one_cmplhi2"
10229 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10230 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10231 "TARGET_HIMODE_MATH"
10232 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10233
10234(define_insn "*one_cmplhi2_1"
10235 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10236 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10237 "ix86_unary_operator_ok (NOT, HImode, operands)"
10238 "not{w}\t%0"
10239 [(set_attr "type" "negnot")
10240 (set_attr "mode" "HI")])
10241
10242(define_insn "*one_cmplhi2_2"
10243 [(set (reg FLAGS_REG)
10244 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10245 (const_int 0)))
10246 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10247 (not:HI (match_dup 1)))]
10248 "ix86_match_ccmode (insn, CCNOmode)
10249 && ix86_unary_operator_ok (NEG, HImode, operands)"
10250 "#"
10251 [(set_attr "type" "alu1")
10252 (set_attr "mode" "HI")])
10253
10254(define_split
10255 [(set (match_operand 0 "flags_reg_operand" "")
10256 (match_operator 2 "compare_operator"
10257 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10258 (const_int 0)]))
10259 (set (match_operand:HI 1 "nonimmediate_operand" "")
10260 (not:HI (match_dup 3)))]
10261 "ix86_match_ccmode (insn, CCNOmode)"
10262 [(parallel [(set (match_dup 0)
10263 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10264 (const_int 0)]))
10265 (set (match_dup 1)
10266 (xor:HI (match_dup 3) (const_int -1)))])]
10267 "")
10268
10269;; %%% Potential partial reg stall on alternative 1. What to do?
10270(define_expand "one_cmplqi2"
10271 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10272 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10273 "TARGET_QIMODE_MATH"
10274 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10275
10276(define_insn "*one_cmplqi2_1"
10277 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10278 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10279 "ix86_unary_operator_ok (NOT, QImode, operands)"
10280 "@
10281 not{b}\t%0
10282 not{l}\t%k0"
10283 [(set_attr "type" "negnot")
10284 (set_attr "mode" "QI,SI")])
10285
10286(define_insn "*one_cmplqi2_2"
10287 [(set (reg FLAGS_REG)
10288 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10289 (const_int 0)))
10290 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10291 (not:QI (match_dup 1)))]
10292 "ix86_match_ccmode (insn, CCNOmode)
10293 && ix86_unary_operator_ok (NOT, QImode, operands)"
10294 "#"
10295 [(set_attr "type" "alu1")
10296 (set_attr "mode" "QI")])
10297
10298(define_split
10299 [(set (match_operand 0 "flags_reg_operand" "")
10300 (match_operator 2 "compare_operator"
10301 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10302 (const_int 0)]))
10303 (set (match_operand:QI 1 "nonimmediate_operand" "")
10304 (not:QI (match_dup 3)))]
10305 "ix86_match_ccmode (insn, CCNOmode)"
10306 [(parallel [(set (match_dup 0)
10307 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10308 (const_int 0)]))
10309 (set (match_dup 1)
10310 (xor:QI (match_dup 3) (const_int -1)))])]
10311 "")
10312
10313;; Arithmetic shift instructions
10314
10315;; DImode shifts are implemented using the i386 "shift double" opcode,
10316;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10317;; is variable, then the count is in %cl and the "imm" operand is dropped
10318;; from the assembler input.
10319;;
10320;; This instruction shifts the target reg/mem as usual, but instead of
10321;; shifting in zeros, bits are shifted in from reg operand. If the insn
10322;; is a left shift double, bits are taken from the high order bits of
10323;; reg, else if the insn is a shift right double, bits are taken from the
10324;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10325;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10326;;
10327;; Since sh[lr]d does not change the `reg' operand, that is done
10328;; separately, making all shifts emit pairs of shift double and normal
10329;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10330;; support a 63 bit shift, each shift where the count is in a reg expands
10331;; to a pair of shifts, a branch, a shift by 32 and a label.
10332;;
10333;; If the shift count is a constant, we need never emit more than one
10334;; shift pair, instead using moves and sign extension for counts greater
10335;; than 31.
10336
10337(define_expand "ashlti3"
10338 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10339 (ashift:TI (match_operand:TI 1 "register_operand" "")
10340 (match_operand:QI 2 "nonmemory_operand" "")))
10341 (clobber (reg:CC FLAGS_REG))])]
10342 "TARGET_64BIT"
10343{
10344 if (! immediate_operand (operands[2], QImode))
10345 {
10346 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10347 DONE;
10348 }
10349 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10350 DONE;
10351})
10352
10353(define_insn "ashlti3_1"
10354 [(set (match_operand:TI 0 "register_operand" "=r")
10355 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10356 (match_operand:QI 2 "register_operand" "c")))
10357 (clobber (match_scratch:DI 3 "=&r"))
10358 (clobber (reg:CC FLAGS_REG))]
10359 "TARGET_64BIT"
10360 "#"
10361 [(set_attr "type" "multi")])
10362
10363(define_insn "*ashlti3_2"
10364 [(set (match_operand:TI 0 "register_operand" "=r")
10365 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10366 (match_operand:QI 2 "immediate_operand" "O")))
10367 (clobber (reg:CC FLAGS_REG))]
10368 "TARGET_64BIT"
10369 "#"
10370 [(set_attr "type" "multi")])
10371
10372(define_split
10373 [(set (match_operand:TI 0 "register_operand" "")
10374 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10375 (match_operand:QI 2 "register_operand" "")))
10376 (clobber (match_scratch:DI 3 ""))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "TARGET_64BIT && reload_completed"
10379 [(const_int 0)]
10380 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10381
10382(define_split
10383 [(set (match_operand:TI 0 "register_operand" "")
10384 (ashift:TI (match_operand:TI 1 "register_operand" "")
10385 (match_operand:QI 2 "immediate_operand" "")))
10386 (clobber (reg:CC FLAGS_REG))]
10387 "TARGET_64BIT && reload_completed"
10388 [(const_int 0)]
10389 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10390
10391(define_insn "x86_64_shld"
10392 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10393 (ior:DI (ashift:DI (match_dup 0)
10394 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10395 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10396 (minus:QI (const_int 64) (match_dup 2)))))
10397 (clobber (reg:CC FLAGS_REG))]
10398 "TARGET_64BIT"
10399 "@
10400 shld{q}\t{%2, %1, %0|%0, %1, %2}
10401 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10402 [(set_attr "type" "ishift")
10403 (set_attr "prefix_0f" "1")
10404 (set_attr "mode" "DI")
10312 (set_attr "athlon_decode" "vector")])
10405 (set_attr "athlon_decode" "vector")
10406 (set_attr "amdfam10_decode" "vector")])
10313
10314(define_expand "x86_64_shift_adj"
10315 [(set (reg:CCZ FLAGS_REG)
10316 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10317 (const_int 64))
10318 (const_int 0)))
10319 (set (match_operand:DI 0 "register_operand" "")
10320 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10321 (match_operand:DI 1 "register_operand" "")
10322 (match_dup 0)))
10323 (set (match_dup 1)
10324 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10325 (match_operand:DI 3 "register_operand" "r")
10326 (match_dup 1)))]
10327 "TARGET_64BIT"
10328 "")
10329
10330(define_expand "ashldi3"
10331 [(set (match_operand:DI 0 "shiftdi_operand" "")
10332 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10333 (match_operand:QI 2 "nonmemory_operand" "")))]
10334 ""
10335 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10336
10337(define_insn "*ashldi3_1_rex64"
10338 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10339 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10340 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10341 (clobber (reg:CC FLAGS_REG))]
10342 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10343{
10344 switch (get_attr_type (insn))
10345 {
10346 case TYPE_ALU:
10347 gcc_assert (operands[2] == const1_rtx);
10348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10349 return "add{q}\t{%0, %0|%0, %0}";
10350
10351 case TYPE_LEA:
10352 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10353 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10354 operands[1] = gen_rtx_MULT (DImode, operands[1],
10355 GEN_INT (1 << INTVAL (operands[2])));
10356 return "lea{q}\t{%a1, %0|%0, %a1}";
10357
10358 default:
10359 if (REG_P (operands[2]))
10360 return "sal{q}\t{%b2, %0|%0, %b2}";
10361 else if (operands[2] == const1_rtx
10362 && (TARGET_SHIFT1 || optimize_size))
10363 return "sal{q}\t%0";
10364 else
10365 return "sal{q}\t{%2, %0|%0, %2}";
10366 }
10367}
10368 [(set (attr "type")
10369 (cond [(eq_attr "alternative" "1")
10370 (const_string "lea")
10371 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10372 (const_int 0))
10373 (match_operand 0 "register_operand" ""))
10374 (match_operand 2 "const1_operand" ""))
10375 (const_string "alu")
10376 ]
10377 (const_string "ishift")))
10378 (set_attr "mode" "DI")])
10379
10380;; Convert lea to the lea pattern to avoid flags dependency.
10381(define_split
10382 [(set (match_operand:DI 0 "register_operand" "")
10383 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10384 (match_operand:QI 2 "immediate_operand" "")))
10385 (clobber (reg:CC FLAGS_REG))]
10386 "TARGET_64BIT && reload_completed
10387 && true_regnum (operands[0]) != true_regnum (operands[1])"
10388 [(set (match_dup 0)
10389 (mult:DI (match_dup 1)
10390 (match_dup 2)))]
10391 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10392
10393;; This pattern can't accept a variable shift count, since shifts by
10394;; zero don't affect the flags. We assume that shifts by constant
10395;; zero are optimized away.
10396(define_insn "*ashldi3_cmp_rex64"
10397 [(set (reg FLAGS_REG)
10398 (compare
10399 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10400 (match_operand:QI 2 "immediate_operand" "e"))
10401 (const_int 0)))
10402 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10403 (ashift:DI (match_dup 1) (match_dup 2)))]
10404 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10405 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10406 && (optimize_size
10407 || !TARGET_PARTIAL_FLAG_REG_STALL
10408 || (operands[2] == const1_rtx
10409 && (TARGET_SHIFT1
10410 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10411{
10412 switch (get_attr_type (insn))
10413 {
10414 case TYPE_ALU:
10415 gcc_assert (operands[2] == const1_rtx);
10416 return "add{q}\t{%0, %0|%0, %0}";
10417
10418 default:
10419 if (REG_P (operands[2]))
10420 return "sal{q}\t{%b2, %0|%0, %b2}";
10421 else if (operands[2] == const1_rtx
10422 && (TARGET_SHIFT1 || optimize_size))
10423 return "sal{q}\t%0";
10424 else
10425 return "sal{q}\t{%2, %0|%0, %2}";
10426 }
10427}
10428 [(set (attr "type")
10429 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10430 (const_int 0))
10431 (match_operand 0 "register_operand" ""))
10432 (match_operand 2 "const1_operand" ""))
10433 (const_string "alu")
10434 ]
10435 (const_string "ishift")))
10436 (set_attr "mode" "DI")])
10437
10438(define_insn "*ashldi3_cconly_rex64"
10439 [(set (reg FLAGS_REG)
10440 (compare
10441 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10442 (match_operand:QI 2 "immediate_operand" "e"))
10443 (const_int 0)))
10444 (clobber (match_scratch:DI 0 "=r"))]
10445 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10446 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10447 && (optimize_size
10448 || !TARGET_PARTIAL_FLAG_REG_STALL
10449 || (operands[2] == const1_rtx
10450 && (TARGET_SHIFT1
10451 || TARGET_DOUBLE_WITH_ADD)))"
10452{
10453 switch (get_attr_type (insn))
10454 {
10455 case TYPE_ALU:
10456 gcc_assert (operands[2] == const1_rtx);
10457 return "add{q}\t{%0, %0|%0, %0}";
10458
10459 default:
10460 if (REG_P (operands[2]))
10461 return "sal{q}\t{%b2, %0|%0, %b2}";
10462 else if (operands[2] == const1_rtx
10463 && (TARGET_SHIFT1 || optimize_size))
10464 return "sal{q}\t%0";
10465 else
10466 return "sal{q}\t{%2, %0|%0, %2}";
10467 }
10468}
10469 [(set (attr "type")
10470 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10471 (const_int 0))
10472 (match_operand 0 "register_operand" ""))
10473 (match_operand 2 "const1_operand" ""))
10474 (const_string "alu")
10475 ]
10476 (const_string "ishift")))
10477 (set_attr "mode" "DI")])
10478
10479(define_insn "*ashldi3_1"
10480 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10481 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10482 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10483 (clobber (reg:CC FLAGS_REG))]
10484 "!TARGET_64BIT"
10485 "#"
10486 [(set_attr "type" "multi")])
10487
10488;; By default we don't ask for a scratch register, because when DImode
10489;; values are manipulated, registers are already at a premium. But if
10490;; we have one handy, we won't turn it away.
10491(define_peephole2
10492 [(match_scratch:SI 3 "r")
10493 (parallel [(set (match_operand:DI 0 "register_operand" "")
10494 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10495 (match_operand:QI 2 "nonmemory_operand" "")))
10496 (clobber (reg:CC FLAGS_REG))])
10497 (match_dup 3)]
10498 "!TARGET_64BIT && TARGET_CMOVE"
10499 [(const_int 0)]
10500 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10501
10502(define_split
10503 [(set (match_operand:DI 0 "register_operand" "")
10504 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10505 (match_operand:QI 2 "nonmemory_operand" "")))
10506 (clobber (reg:CC FLAGS_REG))]
10507 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10508 ? flow2_completed : reload_completed)"
10509 [(const_int 0)]
10510 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10511
10512(define_insn "x86_shld_1"
10513 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10514 (ior:SI (ashift:SI (match_dup 0)
10515 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10516 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10517 (minus:QI (const_int 32) (match_dup 2)))))
10518 (clobber (reg:CC FLAGS_REG))]
10519 ""
10520 "@
10521 shld{l}\t{%2, %1, %0|%0, %1, %2}
10522 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10523 [(set_attr "type" "ishift")
10524 (set_attr "prefix_0f" "1")
10525 (set_attr "mode" "SI")
10526 (set_attr "pent_pair" "np")
10407
10408(define_expand "x86_64_shift_adj"
10409 [(set (reg:CCZ FLAGS_REG)
10410 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10411 (const_int 64))
10412 (const_int 0)))
10413 (set (match_operand:DI 0 "register_operand" "")
10414 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10415 (match_operand:DI 1 "register_operand" "")
10416 (match_dup 0)))
10417 (set (match_dup 1)
10418 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10419 (match_operand:DI 3 "register_operand" "r")
10420 (match_dup 1)))]
10421 "TARGET_64BIT"
10422 "")
10423
10424(define_expand "ashldi3"
10425 [(set (match_operand:DI 0 "shiftdi_operand" "")
10426 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10427 (match_operand:QI 2 "nonmemory_operand" "")))]
10428 ""
10429 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10430
10431(define_insn "*ashldi3_1_rex64"
10432 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10433 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10434 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10437{
10438 switch (get_attr_type (insn))
10439 {
10440 case TYPE_ALU:
10441 gcc_assert (operands[2] == const1_rtx);
10442 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10443 return "add{q}\t{%0, %0|%0, %0}";
10444
10445 case TYPE_LEA:
10446 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10447 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10448 operands[1] = gen_rtx_MULT (DImode, operands[1],
10449 GEN_INT (1 << INTVAL (operands[2])));
10450 return "lea{q}\t{%a1, %0|%0, %a1}";
10451
10452 default:
10453 if (REG_P (operands[2]))
10454 return "sal{q}\t{%b2, %0|%0, %b2}";
10455 else if (operands[2] == const1_rtx
10456 && (TARGET_SHIFT1 || optimize_size))
10457 return "sal{q}\t%0";
10458 else
10459 return "sal{q}\t{%2, %0|%0, %2}";
10460 }
10461}
10462 [(set (attr "type")
10463 (cond [(eq_attr "alternative" "1")
10464 (const_string "lea")
10465 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10466 (const_int 0))
10467 (match_operand 0 "register_operand" ""))
10468 (match_operand 2 "const1_operand" ""))
10469 (const_string "alu")
10470 ]
10471 (const_string "ishift")))
10472 (set_attr "mode" "DI")])
10473
10474;; Convert lea to the lea pattern to avoid flags dependency.
10475(define_split
10476 [(set (match_operand:DI 0 "register_operand" "")
10477 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10478 (match_operand:QI 2 "immediate_operand" "")))
10479 (clobber (reg:CC FLAGS_REG))]
10480 "TARGET_64BIT && reload_completed
10481 && true_regnum (operands[0]) != true_regnum (operands[1])"
10482 [(set (match_dup 0)
10483 (mult:DI (match_dup 1)
10484 (match_dup 2)))]
10485 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10486
10487;; This pattern can't accept a variable shift count, since shifts by
10488;; zero don't affect the flags. We assume that shifts by constant
10489;; zero are optimized away.
10490(define_insn "*ashldi3_cmp_rex64"
10491 [(set (reg FLAGS_REG)
10492 (compare
10493 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10494 (match_operand:QI 2 "immediate_operand" "e"))
10495 (const_int 0)))
10496 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10497 (ashift:DI (match_dup 1) (match_dup 2)))]
10498 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10499 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10500 && (optimize_size
10501 || !TARGET_PARTIAL_FLAG_REG_STALL
10502 || (operands[2] == const1_rtx
10503 && (TARGET_SHIFT1
10504 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10505{
10506 switch (get_attr_type (insn))
10507 {
10508 case TYPE_ALU:
10509 gcc_assert (operands[2] == const1_rtx);
10510 return "add{q}\t{%0, %0|%0, %0}";
10511
10512 default:
10513 if (REG_P (operands[2]))
10514 return "sal{q}\t{%b2, %0|%0, %b2}";
10515 else if (operands[2] == const1_rtx
10516 && (TARGET_SHIFT1 || optimize_size))
10517 return "sal{q}\t%0";
10518 else
10519 return "sal{q}\t{%2, %0|%0, %2}";
10520 }
10521}
10522 [(set (attr "type")
10523 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10524 (const_int 0))
10525 (match_operand 0 "register_operand" ""))
10526 (match_operand 2 "const1_operand" ""))
10527 (const_string "alu")
10528 ]
10529 (const_string "ishift")))
10530 (set_attr "mode" "DI")])
10531
10532(define_insn "*ashldi3_cconly_rex64"
10533 [(set (reg FLAGS_REG)
10534 (compare
10535 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10536 (match_operand:QI 2 "immediate_operand" "e"))
10537 (const_int 0)))
10538 (clobber (match_scratch:DI 0 "=r"))]
10539 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10540 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10541 && (optimize_size
10542 || !TARGET_PARTIAL_FLAG_REG_STALL
10543 || (operands[2] == const1_rtx
10544 && (TARGET_SHIFT1
10545 || TARGET_DOUBLE_WITH_ADD)))"
10546{
10547 switch (get_attr_type (insn))
10548 {
10549 case TYPE_ALU:
10550 gcc_assert (operands[2] == const1_rtx);
10551 return "add{q}\t{%0, %0|%0, %0}";
10552
10553 default:
10554 if (REG_P (operands[2]))
10555 return "sal{q}\t{%b2, %0|%0, %b2}";
10556 else if (operands[2] == const1_rtx
10557 && (TARGET_SHIFT1 || optimize_size))
10558 return "sal{q}\t%0";
10559 else
10560 return "sal{q}\t{%2, %0|%0, %2}";
10561 }
10562}
10563 [(set (attr "type")
10564 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10565 (const_int 0))
10566 (match_operand 0 "register_operand" ""))
10567 (match_operand 2 "const1_operand" ""))
10568 (const_string "alu")
10569 ]
10570 (const_string "ishift")))
10571 (set_attr "mode" "DI")])
10572
10573(define_insn "*ashldi3_1"
10574 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10575 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10576 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10577 (clobber (reg:CC FLAGS_REG))]
10578 "!TARGET_64BIT"
10579 "#"
10580 [(set_attr "type" "multi")])
10581
10582;; By default we don't ask for a scratch register, because when DImode
10583;; values are manipulated, registers are already at a premium. But if
10584;; we have one handy, we won't turn it away.
10585(define_peephole2
10586 [(match_scratch:SI 3 "r")
10587 (parallel [(set (match_operand:DI 0 "register_operand" "")
10588 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10589 (match_operand:QI 2 "nonmemory_operand" "")))
10590 (clobber (reg:CC FLAGS_REG))])
10591 (match_dup 3)]
10592 "!TARGET_64BIT && TARGET_CMOVE"
10593 [(const_int 0)]
10594 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10595
10596(define_split
10597 [(set (match_operand:DI 0 "register_operand" "")
10598 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10599 (match_operand:QI 2 "nonmemory_operand" "")))
10600 (clobber (reg:CC FLAGS_REG))]
10601 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10602 ? flow2_completed : reload_completed)"
10603 [(const_int 0)]
10604 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10605
10606(define_insn "x86_shld_1"
10607 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10608 (ior:SI (ashift:SI (match_dup 0)
10609 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10610 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10611 (minus:QI (const_int 32) (match_dup 2)))))
10612 (clobber (reg:CC FLAGS_REG))]
10613 ""
10614 "@
10615 shld{l}\t{%2, %1, %0|%0, %1, %2}
10616 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10617 [(set_attr "type" "ishift")
10618 (set_attr "prefix_0f" "1")
10619 (set_attr "mode" "SI")
10620 (set_attr "pent_pair" "np")
10527 (set_attr "athlon_decode" "vector")])
10621 (set_attr "athlon_decode" "vector")
10622 (set_attr "amdfam10_decode" "vector")])
10528
10529(define_expand "x86_shift_adj_1"
10530 [(set (reg:CCZ FLAGS_REG)
10531 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10532 (const_int 32))
10533 (const_int 0)))
10534 (set (match_operand:SI 0 "register_operand" "")
10535 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10536 (match_operand:SI 1 "register_operand" "")
10537 (match_dup 0)))
10538 (set (match_dup 1)
10539 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10540 (match_operand:SI 3 "register_operand" "r")
10541 (match_dup 1)))]
10542 "TARGET_CMOVE"
10543 "")
10544
10545(define_expand "x86_shift_adj_2"
10546 [(use (match_operand:SI 0 "register_operand" ""))
10547 (use (match_operand:SI 1 "register_operand" ""))
10548 (use (match_operand:QI 2 "register_operand" ""))]
10549 ""
10550{
10551 rtx label = gen_label_rtx ();
10552 rtx tmp;
10553
10554 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10555
10556 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10557 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10558 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10559 gen_rtx_LABEL_REF (VOIDmode, label),
10560 pc_rtx);
10561 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10562 JUMP_LABEL (tmp) = label;
10563
10564 emit_move_insn (operands[0], operands[1]);
10565 ix86_expand_clear (operands[1]);
10566
10567 emit_label (label);
10568 LABEL_NUSES (label) = 1;
10569
10570 DONE;
10571})
10572
10573(define_expand "ashlsi3"
10574 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10575 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10576 (match_operand:QI 2 "nonmemory_operand" "")))
10577 (clobber (reg:CC FLAGS_REG))]
10578 ""
10579 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10580
10581(define_insn "*ashlsi3_1"
10582 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10583 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10584 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10585 (clobber (reg:CC FLAGS_REG))]
10586 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10587{
10588 switch (get_attr_type (insn))
10589 {
10590 case TYPE_ALU:
10591 gcc_assert (operands[2] == const1_rtx);
10592 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10593 return "add{l}\t{%0, %0|%0, %0}";
10594
10595 case TYPE_LEA:
10596 return "#";
10597
10598 default:
10599 if (REG_P (operands[2]))
10600 return "sal{l}\t{%b2, %0|%0, %b2}";
10601 else if (operands[2] == const1_rtx
10602 && (TARGET_SHIFT1 || optimize_size))
10603 return "sal{l}\t%0";
10604 else
10605 return "sal{l}\t{%2, %0|%0, %2}";
10606 }
10607}
10608 [(set (attr "type")
10609 (cond [(eq_attr "alternative" "1")
10610 (const_string "lea")
10611 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10612 (const_int 0))
10613 (match_operand 0 "register_operand" ""))
10614 (match_operand 2 "const1_operand" ""))
10615 (const_string "alu")
10616 ]
10617 (const_string "ishift")))
10618 (set_attr "mode" "SI")])
10619
10620;; Convert lea to the lea pattern to avoid flags dependency.
10621(define_split
10622 [(set (match_operand 0 "register_operand" "")
10623 (ashift (match_operand 1 "index_register_operand" "")
10624 (match_operand:QI 2 "const_int_operand" "")))
10625 (clobber (reg:CC FLAGS_REG))]
10626 "reload_completed
10627 && true_regnum (operands[0]) != true_regnum (operands[1])
10628 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10629 [(const_int 0)]
10630{
10631 rtx pat;
10632 enum machine_mode mode = GET_MODE (operands[0]);
10633
10634 if (GET_MODE_SIZE (mode) < 4)
10635 operands[0] = gen_lowpart (SImode, operands[0]);
10636 if (mode != Pmode)
10637 operands[1] = gen_lowpart (Pmode, operands[1]);
10638 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10639
10640 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10641 if (Pmode != SImode)
10642 pat = gen_rtx_SUBREG (SImode, pat, 0);
10643 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10644 DONE;
10645})
10646
10647;; Rare case of shifting RSP is handled by generating move and shift
10648(define_split
10649 [(set (match_operand 0 "register_operand" "")
10650 (ashift (match_operand 1 "register_operand" "")
10651 (match_operand:QI 2 "const_int_operand" "")))
10652 (clobber (reg:CC FLAGS_REG))]
10653 "reload_completed
10654 && true_regnum (operands[0]) != true_regnum (operands[1])"
10655 [(const_int 0)]
10656{
10657 rtx pat, clob;
10658 emit_move_insn (operands[0], operands[1]);
10659 pat = gen_rtx_SET (VOIDmode, operands[0],
10660 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10661 operands[0], operands[2]));
10662 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10663 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10664 DONE;
10665})
10666
10667(define_insn "*ashlsi3_1_zext"
10668 [(set (match_operand:DI 0 "register_operand" "=r,r")
10669 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10670 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10671 (clobber (reg:CC FLAGS_REG))]
10672 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10673{
10674 switch (get_attr_type (insn))
10675 {
10676 case TYPE_ALU:
10677 gcc_assert (operands[2] == const1_rtx);
10678 return "add{l}\t{%k0, %k0|%k0, %k0}";
10679
10680 case TYPE_LEA:
10681 return "#";
10682
10683 default:
10684 if (REG_P (operands[2]))
10685 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10686 else if (operands[2] == const1_rtx
10687 && (TARGET_SHIFT1 || optimize_size))
10688 return "sal{l}\t%k0";
10689 else
10690 return "sal{l}\t{%2, %k0|%k0, %2}";
10691 }
10692}
10693 [(set (attr "type")
10694 (cond [(eq_attr "alternative" "1")
10695 (const_string "lea")
10696 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10697 (const_int 0))
10698 (match_operand 2 "const1_operand" ""))
10699 (const_string "alu")
10700 ]
10701 (const_string "ishift")))
10702 (set_attr "mode" "SI")])
10703
10704;; Convert lea to the lea pattern to avoid flags dependency.
10705(define_split
10706 [(set (match_operand:DI 0 "register_operand" "")
10707 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10708 (match_operand:QI 2 "const_int_operand" ""))))
10709 (clobber (reg:CC FLAGS_REG))]
10710 "TARGET_64BIT && reload_completed
10711 && true_regnum (operands[0]) != true_regnum (operands[1])"
10712 [(set (match_dup 0) (zero_extend:DI
10713 (subreg:SI (mult:SI (match_dup 1)
10714 (match_dup 2)) 0)))]
10715{
10716 operands[1] = gen_lowpart (Pmode, operands[1]);
10717 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10718})
10719
10720;; This pattern can't accept a variable shift count, since shifts by
10721;; zero don't affect the flags. We assume that shifts by constant
10722;; zero are optimized away.
10723(define_insn "*ashlsi3_cmp"
10724 [(set (reg FLAGS_REG)
10725 (compare
10726 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10727 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10728 (const_int 0)))
10729 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10730 (ashift:SI (match_dup 1) (match_dup 2)))]
10731 "ix86_match_ccmode (insn, CCGOCmode)
10732 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10733 && (optimize_size
10734 || !TARGET_PARTIAL_FLAG_REG_STALL
10735 || (operands[2] == const1_rtx
10736 && (TARGET_SHIFT1
10737 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10738{
10739 switch (get_attr_type (insn))
10740 {
10741 case TYPE_ALU:
10742 gcc_assert (operands[2] == const1_rtx);
10743 return "add{l}\t{%0, %0|%0, %0}";
10744
10745 default:
10746 if (REG_P (operands[2]))
10747 return "sal{l}\t{%b2, %0|%0, %b2}";
10748 else if (operands[2] == const1_rtx
10749 && (TARGET_SHIFT1 || optimize_size))
10750 return "sal{l}\t%0";
10751 else
10752 return "sal{l}\t{%2, %0|%0, %2}";
10753 }
10754}
10755 [(set (attr "type")
10756 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10757 (const_int 0))
10758 (match_operand 0 "register_operand" ""))
10759 (match_operand 2 "const1_operand" ""))
10760 (const_string "alu")
10761 ]
10762 (const_string "ishift")))
10763 (set_attr "mode" "SI")])
10764
10765(define_insn "*ashlsi3_cconly"
10766 [(set (reg FLAGS_REG)
10767 (compare
10768 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10769 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10770 (const_int 0)))
10771 (clobber (match_scratch:SI 0 "=r"))]
10772 "ix86_match_ccmode (insn, CCGOCmode)
10773 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10774 && (optimize_size
10775 || !TARGET_PARTIAL_FLAG_REG_STALL
10776 || (operands[2] == const1_rtx
10777 && (TARGET_SHIFT1
10778 || TARGET_DOUBLE_WITH_ADD)))"
10779{
10780 switch (get_attr_type (insn))
10781 {
10782 case TYPE_ALU:
10783 gcc_assert (operands[2] == const1_rtx);
10784 return "add{l}\t{%0, %0|%0, %0}";
10785
10786 default:
10787 if (REG_P (operands[2]))
10788 return "sal{l}\t{%b2, %0|%0, %b2}";
10789 else if (operands[2] == const1_rtx
10790 && (TARGET_SHIFT1 || optimize_size))
10791 return "sal{l}\t%0";
10792 else
10793 return "sal{l}\t{%2, %0|%0, %2}";
10794 }
10795}
10796 [(set (attr "type")
10797 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10798 (const_int 0))
10799 (match_operand 0 "register_operand" ""))
10800 (match_operand 2 "const1_operand" ""))
10801 (const_string "alu")
10802 ]
10803 (const_string "ishift")))
10804 (set_attr "mode" "SI")])
10805
10806(define_insn "*ashlsi3_cmp_zext"
10807 [(set (reg FLAGS_REG)
10808 (compare
10809 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10810 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10811 (const_int 0)))
10812 (set (match_operand:DI 0 "register_operand" "=r")
10813 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10814 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10815 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10816 && (optimize_size
10817 || !TARGET_PARTIAL_FLAG_REG_STALL
10818 || (operands[2] == const1_rtx
10819 && (TARGET_SHIFT1
10820 || TARGET_DOUBLE_WITH_ADD)))"
10821{
10822 switch (get_attr_type (insn))
10823 {
10824 case TYPE_ALU:
10825 gcc_assert (operands[2] == const1_rtx);
10826 return "add{l}\t{%k0, %k0|%k0, %k0}";
10827
10828 default:
10829 if (REG_P (operands[2]))
10830 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10831 else if (operands[2] == const1_rtx
10832 && (TARGET_SHIFT1 || optimize_size))
10833 return "sal{l}\t%k0";
10834 else
10835 return "sal{l}\t{%2, %k0|%k0, %2}";
10836 }
10837}
10838 [(set (attr "type")
10839 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10840 (const_int 0))
10841 (match_operand 2 "const1_operand" ""))
10842 (const_string "alu")
10843 ]
10844 (const_string "ishift")))
10845 (set_attr "mode" "SI")])
10846
10847(define_expand "ashlhi3"
10848 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10849 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10850 (match_operand:QI 2 "nonmemory_operand" "")))
10851 (clobber (reg:CC FLAGS_REG))]
10852 "TARGET_HIMODE_MATH"
10853 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10854
10855(define_insn "*ashlhi3_1_lea"
10856 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10857 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10858 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10859 (clobber (reg:CC FLAGS_REG))]
10860 "!TARGET_PARTIAL_REG_STALL
10861 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10862{
10863 switch (get_attr_type (insn))
10864 {
10865 case TYPE_LEA:
10866 return "#";
10867 case TYPE_ALU:
10868 gcc_assert (operands[2] == const1_rtx);
10869 return "add{w}\t{%0, %0|%0, %0}";
10870
10871 default:
10872 if (REG_P (operands[2]))
10873 return "sal{w}\t{%b2, %0|%0, %b2}";
10874 else if (operands[2] == const1_rtx
10875 && (TARGET_SHIFT1 || optimize_size))
10876 return "sal{w}\t%0";
10877 else
10878 return "sal{w}\t{%2, %0|%0, %2}";
10879 }
10880}
10881 [(set (attr "type")
10882 (cond [(eq_attr "alternative" "1")
10883 (const_string "lea")
10884 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10885 (const_int 0))
10886 (match_operand 0 "register_operand" ""))
10887 (match_operand 2 "const1_operand" ""))
10888 (const_string "alu")
10889 ]
10890 (const_string "ishift")))
10891 (set_attr "mode" "HI,SI")])
10892
10893(define_insn "*ashlhi3_1"
10894 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10895 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10896 (match_operand:QI 2 "nonmemory_operand" "cI")))
10897 (clobber (reg:CC FLAGS_REG))]
10898 "TARGET_PARTIAL_REG_STALL
10899 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10900{
10901 switch (get_attr_type (insn))
10902 {
10903 case TYPE_ALU:
10904 gcc_assert (operands[2] == const1_rtx);
10905 return "add{w}\t{%0, %0|%0, %0}";
10906
10907 default:
10908 if (REG_P (operands[2]))
10909 return "sal{w}\t{%b2, %0|%0, %b2}";
10910 else if (operands[2] == const1_rtx
10911 && (TARGET_SHIFT1 || optimize_size))
10912 return "sal{w}\t%0";
10913 else
10914 return "sal{w}\t{%2, %0|%0, %2}";
10915 }
10916}
10917 [(set (attr "type")
10918 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10919 (const_int 0))
10920 (match_operand 0 "register_operand" ""))
10921 (match_operand 2 "const1_operand" ""))
10922 (const_string "alu")
10923 ]
10924 (const_string "ishift")))
10925 (set_attr "mode" "HI")])
10926
10927;; This pattern can't accept a variable shift count, since shifts by
10928;; zero don't affect the flags. We assume that shifts by constant
10929;; zero are optimized away.
10930(define_insn "*ashlhi3_cmp"
10931 [(set (reg FLAGS_REG)
10932 (compare
10933 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10934 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10935 (const_int 0)))
10936 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10937 (ashift:HI (match_dup 1) (match_dup 2)))]
10938 "ix86_match_ccmode (insn, CCGOCmode)
10939 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10940 && (optimize_size
10941 || !TARGET_PARTIAL_FLAG_REG_STALL
10942 || (operands[2] == const1_rtx
10943 && (TARGET_SHIFT1
10944 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10945{
10946 switch (get_attr_type (insn))
10947 {
10948 case TYPE_ALU:
10949 gcc_assert (operands[2] == const1_rtx);
10950 return "add{w}\t{%0, %0|%0, %0}";
10951
10952 default:
10953 if (REG_P (operands[2]))
10954 return "sal{w}\t{%b2, %0|%0, %b2}";
10955 else if (operands[2] == const1_rtx
10956 && (TARGET_SHIFT1 || optimize_size))
10957 return "sal{w}\t%0";
10958 else
10959 return "sal{w}\t{%2, %0|%0, %2}";
10960 }
10961}
10962 [(set (attr "type")
10963 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10964 (const_int 0))
10965 (match_operand 0 "register_operand" ""))
10966 (match_operand 2 "const1_operand" ""))
10967 (const_string "alu")
10968 ]
10969 (const_string "ishift")))
10970 (set_attr "mode" "HI")])
10971
10972(define_insn "*ashlhi3_cconly"
10973 [(set (reg FLAGS_REG)
10974 (compare
10975 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10976 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10977 (const_int 0)))
10978 (clobber (match_scratch:HI 0 "=r"))]
10979 "ix86_match_ccmode (insn, CCGOCmode)
10980 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10981 && (optimize_size
10982 || !TARGET_PARTIAL_FLAG_REG_STALL
10983 || (operands[2] == const1_rtx
10984 && (TARGET_SHIFT1
10985 || TARGET_DOUBLE_WITH_ADD)))"
10986{
10987 switch (get_attr_type (insn))
10988 {
10989 case TYPE_ALU:
10990 gcc_assert (operands[2] == const1_rtx);
10991 return "add{w}\t{%0, %0|%0, %0}";
10992
10993 default:
10994 if (REG_P (operands[2]))
10995 return "sal{w}\t{%b2, %0|%0, %b2}";
10996 else if (operands[2] == const1_rtx
10997 && (TARGET_SHIFT1 || optimize_size))
10998 return "sal{w}\t%0";
10999 else
11000 return "sal{w}\t{%2, %0|%0, %2}";
11001 }
11002}
11003 [(set (attr "type")
11004 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11005 (const_int 0))
11006 (match_operand 0 "register_operand" ""))
11007 (match_operand 2 "const1_operand" ""))
11008 (const_string "alu")
11009 ]
11010 (const_string "ishift")))
11011 (set_attr "mode" "HI")])
11012
11013(define_expand "ashlqi3"
11014 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11015 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11016 (match_operand:QI 2 "nonmemory_operand" "")))
11017 (clobber (reg:CC FLAGS_REG))]
11018 "TARGET_QIMODE_MATH"
11019 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11020
11021;; %%% Potential partial reg stall on alternative 2. What to do?
11022
11023(define_insn "*ashlqi3_1_lea"
11024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11025 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11026 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11027 (clobber (reg:CC FLAGS_REG))]
11028 "!TARGET_PARTIAL_REG_STALL
11029 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11030{
11031 switch (get_attr_type (insn))
11032 {
11033 case TYPE_LEA:
11034 return "#";
11035 case TYPE_ALU:
11036 gcc_assert (operands[2] == const1_rtx);
11037 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11038 return "add{l}\t{%k0, %k0|%k0, %k0}";
11039 else
11040 return "add{b}\t{%0, %0|%0, %0}";
11041
11042 default:
11043 if (REG_P (operands[2]))
11044 {
11045 if (get_attr_mode (insn) == MODE_SI)
11046 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11047 else
11048 return "sal{b}\t{%b2, %0|%0, %b2}";
11049 }
11050 else if (operands[2] == const1_rtx
11051 && (TARGET_SHIFT1 || optimize_size))
11052 {
11053 if (get_attr_mode (insn) == MODE_SI)
11054 return "sal{l}\t%0";
11055 else
11056 return "sal{b}\t%0";
11057 }
11058 else
11059 {
11060 if (get_attr_mode (insn) == MODE_SI)
11061 return "sal{l}\t{%2, %k0|%k0, %2}";
11062 else
11063 return "sal{b}\t{%2, %0|%0, %2}";
11064 }
11065 }
11066}
11067 [(set (attr "type")
11068 (cond [(eq_attr "alternative" "2")
11069 (const_string "lea")
11070 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11071 (const_int 0))
11072 (match_operand 0 "register_operand" ""))
11073 (match_operand 2 "const1_operand" ""))
11074 (const_string "alu")
11075 ]
11076 (const_string "ishift")))
11077 (set_attr "mode" "QI,SI,SI")])
11078
11079(define_insn "*ashlqi3_1"
11080 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11081 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11082 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11083 (clobber (reg:CC FLAGS_REG))]
11084 "TARGET_PARTIAL_REG_STALL
11085 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11086{
11087 switch (get_attr_type (insn))
11088 {
11089 case TYPE_ALU:
11090 gcc_assert (operands[2] == const1_rtx);
11091 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11092 return "add{l}\t{%k0, %k0|%k0, %k0}";
11093 else
11094 return "add{b}\t{%0, %0|%0, %0}";
11095
11096 default:
11097 if (REG_P (operands[2]))
11098 {
11099 if (get_attr_mode (insn) == MODE_SI)
11100 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11101 else
11102 return "sal{b}\t{%b2, %0|%0, %b2}";
11103 }
11104 else if (operands[2] == const1_rtx
11105 && (TARGET_SHIFT1 || optimize_size))
11106 {
11107 if (get_attr_mode (insn) == MODE_SI)
11108 return "sal{l}\t%0";
11109 else
11110 return "sal{b}\t%0";
11111 }
11112 else
11113 {
11114 if (get_attr_mode (insn) == MODE_SI)
11115 return "sal{l}\t{%2, %k0|%k0, %2}";
11116 else
11117 return "sal{b}\t{%2, %0|%0, %2}";
11118 }
11119 }
11120}
11121 [(set (attr "type")
11122 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11123 (const_int 0))
11124 (match_operand 0 "register_operand" ""))
11125 (match_operand 2 "const1_operand" ""))
11126 (const_string "alu")
11127 ]
11128 (const_string "ishift")))
11129 (set_attr "mode" "QI,SI")])
11130
11131;; This pattern can't accept a variable shift count, since shifts by
11132;; zero don't affect the flags. We assume that shifts by constant
11133;; zero are optimized away.
11134(define_insn "*ashlqi3_cmp"
11135 [(set (reg FLAGS_REG)
11136 (compare
11137 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11138 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11139 (const_int 0)))
11140 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11141 (ashift:QI (match_dup 1) (match_dup 2)))]
11142 "ix86_match_ccmode (insn, CCGOCmode)
11143 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11144 && (optimize_size
11145 || !TARGET_PARTIAL_FLAG_REG_STALL
11146 || (operands[2] == const1_rtx
11147 && (TARGET_SHIFT1
11148 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11149{
11150 switch (get_attr_type (insn))
11151 {
11152 case TYPE_ALU:
11153 gcc_assert (operands[2] == const1_rtx);
11154 return "add{b}\t{%0, %0|%0, %0}";
11155
11156 default:
11157 if (REG_P (operands[2]))
11158 return "sal{b}\t{%b2, %0|%0, %b2}";
11159 else if (operands[2] == const1_rtx
11160 && (TARGET_SHIFT1 || optimize_size))
11161 return "sal{b}\t%0";
11162 else
11163 return "sal{b}\t{%2, %0|%0, %2}";
11164 }
11165}
11166 [(set (attr "type")
11167 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11168 (const_int 0))
11169 (match_operand 0 "register_operand" ""))
11170 (match_operand 2 "const1_operand" ""))
11171 (const_string "alu")
11172 ]
11173 (const_string "ishift")))
11174 (set_attr "mode" "QI")])
11175
11176(define_insn "*ashlqi3_cconly"
11177 [(set (reg FLAGS_REG)
11178 (compare
11179 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11180 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11181 (const_int 0)))
11182 (clobber (match_scratch:QI 0 "=q"))]
11183 "ix86_match_ccmode (insn, CCGOCmode)
11184 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11185 && (optimize_size
11186 || !TARGET_PARTIAL_FLAG_REG_STALL
11187 || (operands[2] == const1_rtx
11188 && (TARGET_SHIFT1
11189 || TARGET_DOUBLE_WITH_ADD)))"
11190{
11191 switch (get_attr_type (insn))
11192 {
11193 case TYPE_ALU:
11194 gcc_assert (operands[2] == const1_rtx);
11195 return "add{b}\t{%0, %0|%0, %0}";
11196
11197 default:
11198 if (REG_P (operands[2]))
11199 return "sal{b}\t{%b2, %0|%0, %b2}";
11200 else if (operands[2] == const1_rtx
11201 && (TARGET_SHIFT1 || optimize_size))
11202 return "sal{b}\t%0";
11203 else
11204 return "sal{b}\t{%2, %0|%0, %2}";
11205 }
11206}
11207 [(set (attr "type")
11208 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11209 (const_int 0))
11210 (match_operand 0 "register_operand" ""))
11211 (match_operand 2 "const1_operand" ""))
11212 (const_string "alu")
11213 ]
11214 (const_string "ishift")))
11215 (set_attr "mode" "QI")])
11216
11217;; See comment above `ashldi3' about how this works.
11218
11219(define_expand "ashrti3"
11220 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11221 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11222 (match_operand:QI 2 "nonmemory_operand" "")))
11223 (clobber (reg:CC FLAGS_REG))])]
11224 "TARGET_64BIT"
11225{
11226 if (! immediate_operand (operands[2], QImode))
11227 {
11228 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11229 DONE;
11230 }
11231 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11232 DONE;
11233})
11234
11235(define_insn "ashrti3_1"
11236 [(set (match_operand:TI 0 "register_operand" "=r")
11237 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11238 (match_operand:QI 2 "register_operand" "c")))
11239 (clobber (match_scratch:DI 3 "=&r"))
11240 (clobber (reg:CC FLAGS_REG))]
11241 "TARGET_64BIT"
11242 "#"
11243 [(set_attr "type" "multi")])
11244
11245(define_insn "*ashrti3_2"
11246 [(set (match_operand:TI 0 "register_operand" "=r")
11247 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11248 (match_operand:QI 2 "immediate_operand" "O")))
11249 (clobber (reg:CC FLAGS_REG))]
11250 "TARGET_64BIT"
11251 "#"
11252 [(set_attr "type" "multi")])
11253
11254(define_split
11255 [(set (match_operand:TI 0 "register_operand" "")
11256 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11257 (match_operand:QI 2 "register_operand" "")))
11258 (clobber (match_scratch:DI 3 ""))
11259 (clobber (reg:CC FLAGS_REG))]
11260 "TARGET_64BIT && reload_completed"
11261 [(const_int 0)]
11262 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11263
11264(define_split
11265 [(set (match_operand:TI 0 "register_operand" "")
11266 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11267 (match_operand:QI 2 "immediate_operand" "")))
11268 (clobber (reg:CC FLAGS_REG))]
11269 "TARGET_64BIT && reload_completed"
11270 [(const_int 0)]
11271 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11272
11273(define_insn "x86_64_shrd"
11274 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11275 (ior:DI (ashiftrt:DI (match_dup 0)
11276 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11277 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11278 (minus:QI (const_int 64) (match_dup 2)))))
11279 (clobber (reg:CC FLAGS_REG))]
11280 "TARGET_64BIT"
11281 "@
11282 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11283 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11284 [(set_attr "type" "ishift")
11285 (set_attr "prefix_0f" "1")
11286 (set_attr "mode" "DI")
10623
10624(define_expand "x86_shift_adj_1"
10625 [(set (reg:CCZ FLAGS_REG)
10626 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10627 (const_int 32))
10628 (const_int 0)))
10629 (set (match_operand:SI 0 "register_operand" "")
10630 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10631 (match_operand:SI 1 "register_operand" "")
10632 (match_dup 0)))
10633 (set (match_dup 1)
10634 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10635 (match_operand:SI 3 "register_operand" "r")
10636 (match_dup 1)))]
10637 "TARGET_CMOVE"
10638 "")
10639
10640(define_expand "x86_shift_adj_2"
10641 [(use (match_operand:SI 0 "register_operand" ""))
10642 (use (match_operand:SI 1 "register_operand" ""))
10643 (use (match_operand:QI 2 "register_operand" ""))]
10644 ""
10645{
10646 rtx label = gen_label_rtx ();
10647 rtx tmp;
10648
10649 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10650
10651 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10652 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10653 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10654 gen_rtx_LABEL_REF (VOIDmode, label),
10655 pc_rtx);
10656 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10657 JUMP_LABEL (tmp) = label;
10658
10659 emit_move_insn (operands[0], operands[1]);
10660 ix86_expand_clear (operands[1]);
10661
10662 emit_label (label);
10663 LABEL_NUSES (label) = 1;
10664
10665 DONE;
10666})
10667
10668(define_expand "ashlsi3"
10669 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10670 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10671 (match_operand:QI 2 "nonmemory_operand" "")))
10672 (clobber (reg:CC FLAGS_REG))]
10673 ""
10674 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10675
10676(define_insn "*ashlsi3_1"
10677 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10678 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10679 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10680 (clobber (reg:CC FLAGS_REG))]
10681 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682{
10683 switch (get_attr_type (insn))
10684 {
10685 case TYPE_ALU:
10686 gcc_assert (operands[2] == const1_rtx);
10687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10688 return "add{l}\t{%0, %0|%0, %0}";
10689
10690 case TYPE_LEA:
10691 return "#";
10692
10693 default:
10694 if (REG_P (operands[2]))
10695 return "sal{l}\t{%b2, %0|%0, %b2}";
10696 else if (operands[2] == const1_rtx
10697 && (TARGET_SHIFT1 || optimize_size))
10698 return "sal{l}\t%0";
10699 else
10700 return "sal{l}\t{%2, %0|%0, %2}";
10701 }
10702}
10703 [(set (attr "type")
10704 (cond [(eq_attr "alternative" "1")
10705 (const_string "lea")
10706 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10707 (const_int 0))
10708 (match_operand 0 "register_operand" ""))
10709 (match_operand 2 "const1_operand" ""))
10710 (const_string "alu")
10711 ]
10712 (const_string "ishift")))
10713 (set_attr "mode" "SI")])
10714
10715;; Convert lea to the lea pattern to avoid flags dependency.
10716(define_split
10717 [(set (match_operand 0 "register_operand" "")
10718 (ashift (match_operand 1 "index_register_operand" "")
10719 (match_operand:QI 2 "const_int_operand" "")))
10720 (clobber (reg:CC FLAGS_REG))]
10721 "reload_completed
10722 && true_regnum (operands[0]) != true_regnum (operands[1])
10723 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10724 [(const_int 0)]
10725{
10726 rtx pat;
10727 enum machine_mode mode = GET_MODE (operands[0]);
10728
10729 if (GET_MODE_SIZE (mode) < 4)
10730 operands[0] = gen_lowpart (SImode, operands[0]);
10731 if (mode != Pmode)
10732 operands[1] = gen_lowpart (Pmode, operands[1]);
10733 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10734
10735 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10736 if (Pmode != SImode)
10737 pat = gen_rtx_SUBREG (SImode, pat, 0);
10738 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10739 DONE;
10740})
10741
10742;; Rare case of shifting RSP is handled by generating move and shift
10743(define_split
10744 [(set (match_operand 0 "register_operand" "")
10745 (ashift (match_operand 1 "register_operand" "")
10746 (match_operand:QI 2 "const_int_operand" "")))
10747 (clobber (reg:CC FLAGS_REG))]
10748 "reload_completed
10749 && true_regnum (operands[0]) != true_regnum (operands[1])"
10750 [(const_int 0)]
10751{
10752 rtx pat, clob;
10753 emit_move_insn (operands[0], operands[1]);
10754 pat = gen_rtx_SET (VOIDmode, operands[0],
10755 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10756 operands[0], operands[2]));
10757 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10758 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10759 DONE;
10760})
10761
10762(define_insn "*ashlsi3_1_zext"
10763 [(set (match_operand:DI 0 "register_operand" "=r,r")
10764 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10765 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10766 (clobber (reg:CC FLAGS_REG))]
10767 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10768{
10769 switch (get_attr_type (insn))
10770 {
10771 case TYPE_ALU:
10772 gcc_assert (operands[2] == const1_rtx);
10773 return "add{l}\t{%k0, %k0|%k0, %k0}";
10774
10775 case TYPE_LEA:
10776 return "#";
10777
10778 default:
10779 if (REG_P (operands[2]))
10780 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10781 else if (operands[2] == const1_rtx
10782 && (TARGET_SHIFT1 || optimize_size))
10783 return "sal{l}\t%k0";
10784 else
10785 return "sal{l}\t{%2, %k0|%k0, %2}";
10786 }
10787}
10788 [(set (attr "type")
10789 (cond [(eq_attr "alternative" "1")
10790 (const_string "lea")
10791 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10792 (const_int 0))
10793 (match_operand 2 "const1_operand" ""))
10794 (const_string "alu")
10795 ]
10796 (const_string "ishift")))
10797 (set_attr "mode" "SI")])
10798
10799;; Convert lea to the lea pattern to avoid flags dependency.
10800(define_split
10801 [(set (match_operand:DI 0 "register_operand" "")
10802 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10803 (match_operand:QI 2 "const_int_operand" ""))))
10804 (clobber (reg:CC FLAGS_REG))]
10805 "TARGET_64BIT && reload_completed
10806 && true_regnum (operands[0]) != true_regnum (operands[1])"
10807 [(set (match_dup 0) (zero_extend:DI
10808 (subreg:SI (mult:SI (match_dup 1)
10809 (match_dup 2)) 0)))]
10810{
10811 operands[1] = gen_lowpart (Pmode, operands[1]);
10812 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10813})
10814
10815;; This pattern can't accept a variable shift count, since shifts by
10816;; zero don't affect the flags. We assume that shifts by constant
10817;; zero are optimized away.
10818(define_insn "*ashlsi3_cmp"
10819 [(set (reg FLAGS_REG)
10820 (compare
10821 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10822 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10823 (const_int 0)))
10824 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10825 (ashift:SI (match_dup 1) (match_dup 2)))]
10826 "ix86_match_ccmode (insn, CCGOCmode)
10827 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10828 && (optimize_size
10829 || !TARGET_PARTIAL_FLAG_REG_STALL
10830 || (operands[2] == const1_rtx
10831 && (TARGET_SHIFT1
10832 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10833{
10834 switch (get_attr_type (insn))
10835 {
10836 case TYPE_ALU:
10837 gcc_assert (operands[2] == const1_rtx);
10838 return "add{l}\t{%0, %0|%0, %0}";
10839
10840 default:
10841 if (REG_P (operands[2]))
10842 return "sal{l}\t{%b2, %0|%0, %b2}";
10843 else if (operands[2] == const1_rtx
10844 && (TARGET_SHIFT1 || optimize_size))
10845 return "sal{l}\t%0";
10846 else
10847 return "sal{l}\t{%2, %0|%0, %2}";
10848 }
10849}
10850 [(set (attr "type")
10851 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10852 (const_int 0))
10853 (match_operand 0 "register_operand" ""))
10854 (match_operand 2 "const1_operand" ""))
10855 (const_string "alu")
10856 ]
10857 (const_string "ishift")))
10858 (set_attr "mode" "SI")])
10859
10860(define_insn "*ashlsi3_cconly"
10861 [(set (reg FLAGS_REG)
10862 (compare
10863 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10864 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10865 (const_int 0)))
10866 (clobber (match_scratch:SI 0 "=r"))]
10867 "ix86_match_ccmode (insn, CCGOCmode)
10868 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10869 && (optimize_size
10870 || !TARGET_PARTIAL_FLAG_REG_STALL
10871 || (operands[2] == const1_rtx
10872 && (TARGET_SHIFT1
10873 || TARGET_DOUBLE_WITH_ADD)))"
10874{
10875 switch (get_attr_type (insn))
10876 {
10877 case TYPE_ALU:
10878 gcc_assert (operands[2] == const1_rtx);
10879 return "add{l}\t{%0, %0|%0, %0}";
10880
10881 default:
10882 if (REG_P (operands[2]))
10883 return "sal{l}\t{%b2, %0|%0, %b2}";
10884 else if (operands[2] == const1_rtx
10885 && (TARGET_SHIFT1 || optimize_size))
10886 return "sal{l}\t%0";
10887 else
10888 return "sal{l}\t{%2, %0|%0, %2}";
10889 }
10890}
10891 [(set (attr "type")
10892 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893 (const_int 0))
10894 (match_operand 0 "register_operand" ""))
10895 (match_operand 2 "const1_operand" ""))
10896 (const_string "alu")
10897 ]
10898 (const_string "ishift")))
10899 (set_attr "mode" "SI")])
10900
10901(define_insn "*ashlsi3_cmp_zext"
10902 [(set (reg FLAGS_REG)
10903 (compare
10904 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10905 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10906 (const_int 0)))
10907 (set (match_operand:DI 0 "register_operand" "=r")
10908 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10909 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10910 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10911 && (optimize_size
10912 || !TARGET_PARTIAL_FLAG_REG_STALL
10913 || (operands[2] == const1_rtx
10914 && (TARGET_SHIFT1
10915 || TARGET_DOUBLE_WITH_ADD)))"
10916{
10917 switch (get_attr_type (insn))
10918 {
10919 case TYPE_ALU:
10920 gcc_assert (operands[2] == const1_rtx);
10921 return "add{l}\t{%k0, %k0|%k0, %k0}";
10922
10923 default:
10924 if (REG_P (operands[2]))
10925 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10926 else if (operands[2] == const1_rtx
10927 && (TARGET_SHIFT1 || optimize_size))
10928 return "sal{l}\t%k0";
10929 else
10930 return "sal{l}\t{%2, %k0|%k0, %2}";
10931 }
10932}
10933 [(set (attr "type")
10934 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10935 (const_int 0))
10936 (match_operand 2 "const1_operand" ""))
10937 (const_string "alu")
10938 ]
10939 (const_string "ishift")))
10940 (set_attr "mode" "SI")])
10941
10942(define_expand "ashlhi3"
10943 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10944 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10945 (match_operand:QI 2 "nonmemory_operand" "")))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "TARGET_HIMODE_MATH"
10948 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10949
10950(define_insn "*ashlhi3_1_lea"
10951 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10952 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10953 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10954 (clobber (reg:CC FLAGS_REG))]
10955 "!TARGET_PARTIAL_REG_STALL
10956 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10957{
10958 switch (get_attr_type (insn))
10959 {
10960 case TYPE_LEA:
10961 return "#";
10962 case TYPE_ALU:
10963 gcc_assert (operands[2] == const1_rtx);
10964 return "add{w}\t{%0, %0|%0, %0}";
10965
10966 default:
10967 if (REG_P (operands[2]))
10968 return "sal{w}\t{%b2, %0|%0, %b2}";
10969 else if (operands[2] == const1_rtx
10970 && (TARGET_SHIFT1 || optimize_size))
10971 return "sal{w}\t%0";
10972 else
10973 return "sal{w}\t{%2, %0|%0, %2}";
10974 }
10975}
10976 [(set (attr "type")
10977 (cond [(eq_attr "alternative" "1")
10978 (const_string "lea")
10979 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980 (const_int 0))
10981 (match_operand 0 "register_operand" ""))
10982 (match_operand 2 "const1_operand" ""))
10983 (const_string "alu")
10984 ]
10985 (const_string "ishift")))
10986 (set_attr "mode" "HI,SI")])
10987
10988(define_insn "*ashlhi3_1"
10989 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10990 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10991 (match_operand:QI 2 "nonmemory_operand" "cI")))
10992 (clobber (reg:CC FLAGS_REG))]
10993 "TARGET_PARTIAL_REG_STALL
10994 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10995{
10996 switch (get_attr_type (insn))
10997 {
10998 case TYPE_ALU:
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{w}\t{%0, %0|%0, %0}";
11001
11002 default:
11003 if (REG_P (operands[2]))
11004 return "sal{w}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_size))
11007 return "sal{w}\t%0";
11008 else
11009 return "sal{w}\t{%2, %0|%0, %2}";
11010 }
11011}
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014 (const_int 0))
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11018 ]
11019 (const_string "ishift")))
11020 (set_attr "mode" "HI")])
11021
11022;; This pattern can't accept a variable shift count, since shifts by
11023;; zero don't affect the flags. We assume that shifts by constant
11024;; zero are optimized away.
11025(define_insn "*ashlhi3_cmp"
11026 [(set (reg FLAGS_REG)
11027 (compare
11028 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11029 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11030 (const_int 0)))
11031 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11032 (ashift:HI (match_dup 1) (match_dup 2)))]
11033 "ix86_match_ccmode (insn, CCGOCmode)
11034 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11035 && (optimize_size
11036 || !TARGET_PARTIAL_FLAG_REG_STALL
11037 || (operands[2] == const1_rtx
11038 && (TARGET_SHIFT1
11039 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11040{
11041 switch (get_attr_type (insn))
11042 {
11043 case TYPE_ALU:
11044 gcc_assert (operands[2] == const1_rtx);
11045 return "add{w}\t{%0, %0|%0, %0}";
11046
11047 default:
11048 if (REG_P (operands[2]))
11049 return "sal{w}\t{%b2, %0|%0, %b2}";
11050 else if (operands[2] == const1_rtx
11051 && (TARGET_SHIFT1 || optimize_size))
11052 return "sal{w}\t%0";
11053 else
11054 return "sal{w}\t{%2, %0|%0, %2}";
11055 }
11056}
11057 [(set (attr "type")
11058 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11059 (const_int 0))
11060 (match_operand 0 "register_operand" ""))
11061 (match_operand 2 "const1_operand" ""))
11062 (const_string "alu")
11063 ]
11064 (const_string "ishift")))
11065 (set_attr "mode" "HI")])
11066
11067(define_insn "*ashlhi3_cconly"
11068 [(set (reg FLAGS_REG)
11069 (compare
11070 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11071 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11072 (const_int 0)))
11073 (clobber (match_scratch:HI 0 "=r"))]
11074 "ix86_match_ccmode (insn, CCGOCmode)
11075 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11076 && (optimize_size
11077 || !TARGET_PARTIAL_FLAG_REG_STALL
11078 || (operands[2] == const1_rtx
11079 && (TARGET_SHIFT1
11080 || TARGET_DOUBLE_WITH_ADD)))"
11081{
11082 switch (get_attr_type (insn))
11083 {
11084 case TYPE_ALU:
11085 gcc_assert (operands[2] == const1_rtx);
11086 return "add{w}\t{%0, %0|%0, %0}";
11087
11088 default:
11089 if (REG_P (operands[2]))
11090 return "sal{w}\t{%b2, %0|%0, %b2}";
11091 else if (operands[2] == const1_rtx
11092 && (TARGET_SHIFT1 || optimize_size))
11093 return "sal{w}\t%0";
11094 else
11095 return "sal{w}\t{%2, %0|%0, %2}";
11096 }
11097}
11098 [(set (attr "type")
11099 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11100 (const_int 0))
11101 (match_operand 0 "register_operand" ""))
11102 (match_operand 2 "const1_operand" ""))
11103 (const_string "alu")
11104 ]
11105 (const_string "ishift")))
11106 (set_attr "mode" "HI")])
11107
11108(define_expand "ashlqi3"
11109 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11110 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11111 (match_operand:QI 2 "nonmemory_operand" "")))
11112 (clobber (reg:CC FLAGS_REG))]
11113 "TARGET_QIMODE_MATH"
11114 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11115
11116;; %%% Potential partial reg stall on alternative 2. What to do?
11117
11118(define_insn "*ashlqi3_1_lea"
11119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11120 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11121 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11122 (clobber (reg:CC FLAGS_REG))]
11123 "!TARGET_PARTIAL_REG_STALL
11124 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11125{
11126 switch (get_attr_type (insn))
11127 {
11128 case TYPE_LEA:
11129 return "#";
11130 case TYPE_ALU:
11131 gcc_assert (operands[2] == const1_rtx);
11132 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11133 return "add{l}\t{%k0, %k0|%k0, %k0}";
11134 else
11135 return "add{b}\t{%0, %0|%0, %0}";
11136
11137 default:
11138 if (REG_P (operands[2]))
11139 {
11140 if (get_attr_mode (insn) == MODE_SI)
11141 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11142 else
11143 return "sal{b}\t{%b2, %0|%0, %b2}";
11144 }
11145 else if (operands[2] == const1_rtx
11146 && (TARGET_SHIFT1 || optimize_size))
11147 {
11148 if (get_attr_mode (insn) == MODE_SI)
11149 return "sal{l}\t%0";
11150 else
11151 return "sal{b}\t%0";
11152 }
11153 else
11154 {
11155 if (get_attr_mode (insn) == MODE_SI)
11156 return "sal{l}\t{%2, %k0|%k0, %2}";
11157 else
11158 return "sal{b}\t{%2, %0|%0, %2}";
11159 }
11160 }
11161}
11162 [(set (attr "type")
11163 (cond [(eq_attr "alternative" "2")
11164 (const_string "lea")
11165 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11166 (const_int 0))
11167 (match_operand 0 "register_operand" ""))
11168 (match_operand 2 "const1_operand" ""))
11169 (const_string "alu")
11170 ]
11171 (const_string "ishift")))
11172 (set_attr "mode" "QI,SI,SI")])
11173
11174(define_insn "*ashlqi3_1"
11175 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11176 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11177 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11178 (clobber (reg:CC FLAGS_REG))]
11179 "TARGET_PARTIAL_REG_STALL
11180 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11181{
11182 switch (get_attr_type (insn))
11183 {
11184 case TYPE_ALU:
11185 gcc_assert (operands[2] == const1_rtx);
11186 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11187 return "add{l}\t{%k0, %k0|%k0, %k0}";
11188 else
11189 return "add{b}\t{%0, %0|%0, %0}";
11190
11191 default:
11192 if (REG_P (operands[2]))
11193 {
11194 if (get_attr_mode (insn) == MODE_SI)
11195 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11196 else
11197 return "sal{b}\t{%b2, %0|%0, %b2}";
11198 }
11199 else if (operands[2] == const1_rtx
11200 && (TARGET_SHIFT1 || optimize_size))
11201 {
11202 if (get_attr_mode (insn) == MODE_SI)
11203 return "sal{l}\t%0";
11204 else
11205 return "sal{b}\t%0";
11206 }
11207 else
11208 {
11209 if (get_attr_mode (insn) == MODE_SI)
11210 return "sal{l}\t{%2, %k0|%k0, %2}";
11211 else
11212 return "sal{b}\t{%2, %0|%0, %2}";
11213 }
11214 }
11215}
11216 [(set (attr "type")
11217 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218 (const_int 0))
11219 (match_operand 0 "register_operand" ""))
11220 (match_operand 2 "const1_operand" ""))
11221 (const_string "alu")
11222 ]
11223 (const_string "ishift")))
11224 (set_attr "mode" "QI,SI")])
11225
11226;; This pattern can't accept a variable shift count, since shifts by
11227;; zero don't affect the flags. We assume that shifts by constant
11228;; zero are optimized away.
11229(define_insn "*ashlqi3_cmp"
11230 [(set (reg FLAGS_REG)
11231 (compare
11232 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11233 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11234 (const_int 0)))
11235 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11236 (ashift:QI (match_dup 1) (match_dup 2)))]
11237 "ix86_match_ccmode (insn, CCGOCmode)
11238 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11239 && (optimize_size
11240 || !TARGET_PARTIAL_FLAG_REG_STALL
11241 || (operands[2] == const1_rtx
11242 && (TARGET_SHIFT1
11243 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11244{
11245 switch (get_attr_type (insn))
11246 {
11247 case TYPE_ALU:
11248 gcc_assert (operands[2] == const1_rtx);
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(define_insn "*ashlqi3_cconly"
11272 [(set (reg FLAGS_REG)
11273 (compare
11274 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11276 (const_int 0)))
11277 (clobber (match_scratch:QI 0 "=q"))]
11278 "ix86_match_ccmode (insn, CCGOCmode)
11279 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11280 && (optimize_size
11281 || !TARGET_PARTIAL_FLAG_REG_STALL
11282 || (operands[2] == const1_rtx
11283 && (TARGET_SHIFT1
11284 || TARGET_DOUBLE_WITH_ADD)))"
11285{
11286 switch (get_attr_type (insn))
11287 {
11288 case TYPE_ALU:
11289 gcc_assert (operands[2] == const1_rtx);
11290 return "add{b}\t{%0, %0|%0, %0}";
11291
11292 default:
11293 if (REG_P (operands[2]))
11294 return "sal{b}\t{%b2, %0|%0, %b2}";
11295 else if (operands[2] == const1_rtx
11296 && (TARGET_SHIFT1 || optimize_size))
11297 return "sal{b}\t%0";
11298 else
11299 return "sal{b}\t{%2, %0|%0, %2}";
11300 }
11301}
11302 [(set (attr "type")
11303 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11304 (const_int 0))
11305 (match_operand 0 "register_operand" ""))
11306 (match_operand 2 "const1_operand" ""))
11307 (const_string "alu")
11308 ]
11309 (const_string "ishift")))
11310 (set_attr "mode" "QI")])
11311
11312;; See comment above `ashldi3' about how this works.
11313
11314(define_expand "ashrti3"
11315 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11316 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11317 (match_operand:QI 2 "nonmemory_operand" "")))
11318 (clobber (reg:CC FLAGS_REG))])]
11319 "TARGET_64BIT"
11320{
11321 if (! immediate_operand (operands[2], QImode))
11322 {
11323 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11324 DONE;
11325 }
11326 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11327 DONE;
11328})
11329
11330(define_insn "ashrti3_1"
11331 [(set (match_operand:TI 0 "register_operand" "=r")
11332 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11333 (match_operand:QI 2 "register_operand" "c")))
11334 (clobber (match_scratch:DI 3 "=&r"))
11335 (clobber (reg:CC FLAGS_REG))]
11336 "TARGET_64BIT"
11337 "#"
11338 [(set_attr "type" "multi")])
11339
11340(define_insn "*ashrti3_2"
11341 [(set (match_operand:TI 0 "register_operand" "=r")
11342 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11343 (match_operand:QI 2 "immediate_operand" "O")))
11344 (clobber (reg:CC FLAGS_REG))]
11345 "TARGET_64BIT"
11346 "#"
11347 [(set_attr "type" "multi")])
11348
11349(define_split
11350 [(set (match_operand:TI 0 "register_operand" "")
11351 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11352 (match_operand:QI 2 "register_operand" "")))
11353 (clobber (match_scratch:DI 3 ""))
11354 (clobber (reg:CC FLAGS_REG))]
11355 "TARGET_64BIT && reload_completed"
11356 [(const_int 0)]
11357 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11358
11359(define_split
11360 [(set (match_operand:TI 0 "register_operand" "")
11361 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11362 (match_operand:QI 2 "immediate_operand" "")))
11363 (clobber (reg:CC FLAGS_REG))]
11364 "TARGET_64BIT && reload_completed"
11365 [(const_int 0)]
11366 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11367
11368(define_insn "x86_64_shrd"
11369 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11370 (ior:DI (ashiftrt:DI (match_dup 0)
11371 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11372 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11373 (minus:QI (const_int 64) (match_dup 2)))))
11374 (clobber (reg:CC FLAGS_REG))]
11375 "TARGET_64BIT"
11376 "@
11377 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11378 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11379 [(set_attr "type" "ishift")
11380 (set_attr "prefix_0f" "1")
11381 (set_attr "mode" "DI")
11287 (set_attr "athlon_decode" "vector")])
11382 (set_attr "athlon_decode" "vector")
11383 (set_attr "amdfam10_decode" "vector")])
11288
11289(define_expand "ashrdi3"
11290 [(set (match_operand:DI 0 "shiftdi_operand" "")
11291 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11292 (match_operand:QI 2 "nonmemory_operand" "")))]
11293 ""
11294 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11295
11296(define_insn "*ashrdi3_63_rex64"
11297 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11298 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11299 (match_operand:DI 2 "const_int_operand" "i,i")))
11300 (clobber (reg:CC FLAGS_REG))]
11301 "TARGET_64BIT && INTVAL (operands[2]) == 63
11302 && (TARGET_USE_CLTD || optimize_size)
11303 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11304 "@
11305 {cqto|cqo}
11306 sar{q}\t{%2, %0|%0, %2}"
11307 [(set_attr "type" "imovx,ishift")
11308 (set_attr "prefix_0f" "0,*")
11309 (set_attr "length_immediate" "0,*")
11310 (set_attr "modrm" "0,1")
11311 (set_attr "mode" "DI")])
11312
11313(define_insn "*ashrdi3_1_one_bit_rex64"
11314 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11315 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11316 (match_operand:QI 2 "const1_operand" "")))
11317 (clobber (reg:CC FLAGS_REG))]
11318 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11319 && (TARGET_SHIFT1 || optimize_size)"
11320 "sar{q}\t%0"
11321 [(set_attr "type" "ishift")
11322 (set (attr "length")
11323 (if_then_else (match_operand:DI 0 "register_operand" "")
11324 (const_string "2")
11325 (const_string "*")))])
11326
11327(define_insn "*ashrdi3_1_rex64"
11328 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11329 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11330 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11331 (clobber (reg:CC FLAGS_REG))]
11332 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11333 "@
11334 sar{q}\t{%2, %0|%0, %2}
11335 sar{q}\t{%b2, %0|%0, %b2}"
11336 [(set_attr "type" "ishift")
11337 (set_attr "mode" "DI")])
11338
11339;; This pattern can't accept a variable shift count, since shifts by
11340;; zero don't affect the flags. We assume that shifts by constant
11341;; zero are optimized away.
11342(define_insn "*ashrdi3_one_bit_cmp_rex64"
11343 [(set (reg FLAGS_REG)
11344 (compare
11345 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11346 (match_operand:QI 2 "const1_operand" ""))
11347 (const_int 0)))
11348 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11349 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11350 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11351 && (TARGET_SHIFT1 || optimize_size)
11352 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353 "sar{q}\t%0"
11354 [(set_attr "type" "ishift")
11355 (set (attr "length")
11356 (if_then_else (match_operand:DI 0 "register_operand" "")
11357 (const_string "2")
11358 (const_string "*")))])
11359
11360(define_insn "*ashrdi3_one_bit_cconly_rex64"
11361 [(set (reg FLAGS_REG)
11362 (compare
11363 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11364 (match_operand:QI 2 "const1_operand" ""))
11365 (const_int 0)))
11366 (clobber (match_scratch:DI 0 "=r"))]
11367 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11368 && (TARGET_SHIFT1 || optimize_size)
11369 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11370 "sar{q}\t%0"
11371 [(set_attr "type" "ishift")
11372 (set_attr "length" "2")])
11373
11374;; This pattern can't accept a variable shift count, since shifts by
11375;; zero don't affect the flags. We assume that shifts by constant
11376;; zero are optimized away.
11377(define_insn "*ashrdi3_cmp_rex64"
11378 [(set (reg FLAGS_REG)
11379 (compare
11380 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11381 (match_operand:QI 2 "const_int_operand" "n"))
11382 (const_int 0)))
11383 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11385 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11386 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11387 && (optimize_size
11388 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11389 "sar{q}\t{%2, %0|%0, %2}"
11390 [(set_attr "type" "ishift")
11391 (set_attr "mode" "DI")])
11392
11393(define_insn "*ashrdi3_cconly_rex64"
11394 [(set (reg FLAGS_REG)
11395 (compare
11396 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11397 (match_operand:QI 2 "const_int_operand" "n"))
11398 (const_int 0)))
11399 (clobber (match_scratch:DI 0 "=r"))]
11400 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11401 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11402 && (optimize_size
11403 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11404 "sar{q}\t{%2, %0|%0, %2}"
11405 [(set_attr "type" "ishift")
11406 (set_attr "mode" "DI")])
11407
11408(define_insn "*ashrdi3_1"
11409 [(set (match_operand:DI 0 "register_operand" "=r")
11410 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11411 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11412 (clobber (reg:CC FLAGS_REG))]
11413 "!TARGET_64BIT"
11414 "#"
11415 [(set_attr "type" "multi")])
11416
11417;; By default we don't ask for a scratch register, because when DImode
11418;; values are manipulated, registers are already at a premium. But if
11419;; we have one handy, we won't turn it away.
11420(define_peephole2
11421 [(match_scratch:SI 3 "r")
11422 (parallel [(set (match_operand:DI 0 "register_operand" "")
11423 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11424 (match_operand:QI 2 "nonmemory_operand" "")))
11425 (clobber (reg:CC FLAGS_REG))])
11426 (match_dup 3)]
11427 "!TARGET_64BIT && TARGET_CMOVE"
11428 [(const_int 0)]
11429 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11430
11431(define_split
11432 [(set (match_operand:DI 0 "register_operand" "")
11433 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11434 (match_operand:QI 2 "nonmemory_operand" "")))
11435 (clobber (reg:CC FLAGS_REG))]
11436 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11437 ? flow2_completed : reload_completed)"
11438 [(const_int 0)]
11439 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11440
11441(define_insn "x86_shrd_1"
11442 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11443 (ior:SI (ashiftrt:SI (match_dup 0)
11444 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11445 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11446 (minus:QI (const_int 32) (match_dup 2)))))
11447 (clobber (reg:CC FLAGS_REG))]
11448 ""
11449 "@
11450 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11451 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11452 [(set_attr "type" "ishift")
11453 (set_attr "prefix_0f" "1")
11454 (set_attr "pent_pair" "np")
11455 (set_attr "mode" "SI")])
11456
11457(define_expand "x86_shift_adj_3"
11458 [(use (match_operand:SI 0 "register_operand" ""))
11459 (use (match_operand:SI 1 "register_operand" ""))
11460 (use (match_operand:QI 2 "register_operand" ""))]
11461 ""
11462{
11463 rtx label = gen_label_rtx ();
11464 rtx tmp;
11465
11466 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11467
11468 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11469 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11470 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11471 gen_rtx_LABEL_REF (VOIDmode, label),
11472 pc_rtx);
11473 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11474 JUMP_LABEL (tmp) = label;
11475
11476 emit_move_insn (operands[0], operands[1]);
11477 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11478
11479 emit_label (label);
11480 LABEL_NUSES (label) = 1;
11481
11482 DONE;
11483})
11484
11485(define_insn "ashrsi3_31"
11486 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11487 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11488 (match_operand:SI 2 "const_int_operand" "i,i")))
11489 (clobber (reg:CC FLAGS_REG))]
11490 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11491 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11492 "@
11493 {cltd|cdq}
11494 sar{l}\t{%2, %0|%0, %2}"
11495 [(set_attr "type" "imovx,ishift")
11496 (set_attr "prefix_0f" "0,*")
11497 (set_attr "length_immediate" "0,*")
11498 (set_attr "modrm" "0,1")
11499 (set_attr "mode" "SI")])
11500
11501(define_insn "*ashrsi3_31_zext"
11502 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11503 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11504 (match_operand:SI 2 "const_int_operand" "i,i"))))
11505 (clobber (reg:CC FLAGS_REG))]
11506 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11507 && INTVAL (operands[2]) == 31
11508 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11509 "@
11510 {cltd|cdq}
11511 sar{l}\t{%2, %k0|%k0, %2}"
11512 [(set_attr "type" "imovx,ishift")
11513 (set_attr "prefix_0f" "0,*")
11514 (set_attr "length_immediate" "0,*")
11515 (set_attr "modrm" "0,1")
11516 (set_attr "mode" "SI")])
11517
11518(define_expand "ashrsi3"
11519 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11520 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11521 (match_operand:QI 2 "nonmemory_operand" "")))
11522 (clobber (reg:CC FLAGS_REG))]
11523 ""
11524 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11525
11526(define_insn "*ashrsi3_1_one_bit"
11527 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11528 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11529 (match_operand:QI 2 "const1_operand" "")))
11530 (clobber (reg:CC FLAGS_REG))]
11531 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11532 && (TARGET_SHIFT1 || optimize_size)"
11533 "sar{l}\t%0"
11534 [(set_attr "type" "ishift")
11535 (set (attr "length")
11536 (if_then_else (match_operand:SI 0 "register_operand" "")
11537 (const_string "2")
11538 (const_string "*")))])
11539
11540(define_insn "*ashrsi3_1_one_bit_zext"
11541 [(set (match_operand:DI 0 "register_operand" "=r")
11542 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11543 (match_operand:QI 2 "const1_operand" ""))))
11544 (clobber (reg:CC FLAGS_REG))]
11545 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11546 && (TARGET_SHIFT1 || optimize_size)"
11547 "sar{l}\t%k0"
11548 [(set_attr "type" "ishift")
11549 (set_attr "length" "2")])
11550
11551(define_insn "*ashrsi3_1"
11552 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11553 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11554 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11555 (clobber (reg:CC FLAGS_REG))]
11556 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11557 "@
11558 sar{l}\t{%2, %0|%0, %2}
11559 sar{l}\t{%b2, %0|%0, %b2}"
11560 [(set_attr "type" "ishift")
11561 (set_attr "mode" "SI")])
11562
11563(define_insn "*ashrsi3_1_zext"
11564 [(set (match_operand:DI 0 "register_operand" "=r,r")
11565 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11566 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11567 (clobber (reg:CC FLAGS_REG))]
11568 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569 "@
11570 sar{l}\t{%2, %k0|%k0, %2}
11571 sar{l}\t{%b2, %k0|%k0, %b2}"
11572 [(set_attr "type" "ishift")
11573 (set_attr "mode" "SI")])
11574
11575;; This pattern can't accept a variable shift count, since shifts by
11576;; zero don't affect the flags. We assume that shifts by constant
11577;; zero are optimized away.
11578(define_insn "*ashrsi3_one_bit_cmp"
11579 [(set (reg FLAGS_REG)
11580 (compare
11581 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11582 (match_operand:QI 2 "const1_operand" ""))
11583 (const_int 0)))
11584 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11585 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11586 "ix86_match_ccmode (insn, CCGOCmode)
11587 && (TARGET_SHIFT1 || optimize_size)
11588 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11589 "sar{l}\t%0"
11590 [(set_attr "type" "ishift")
11591 (set (attr "length")
11592 (if_then_else (match_operand:SI 0 "register_operand" "")
11593 (const_string "2")
11594 (const_string "*")))])
11595
11596(define_insn "*ashrsi3_one_bit_cconly"
11597 [(set (reg FLAGS_REG)
11598 (compare
11599 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11600 (match_operand:QI 2 "const1_operand" ""))
11601 (const_int 0)))
11602 (clobber (match_scratch:SI 0 "=r"))]
11603 "ix86_match_ccmode (insn, CCGOCmode)
11604 && (TARGET_SHIFT1 || optimize_size)
11605 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606 "sar{l}\t%0"
11607 [(set_attr "type" "ishift")
11608 (set_attr "length" "2")])
11609
11610(define_insn "*ashrsi3_one_bit_cmp_zext"
11611 [(set (reg FLAGS_REG)
11612 (compare
11613 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11614 (match_operand:QI 2 "const1_operand" ""))
11615 (const_int 0)))
11616 (set (match_operand:DI 0 "register_operand" "=r")
11617 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11618 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11619 && (TARGET_SHIFT1 || optimize_size)
11620 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11621 "sar{l}\t%k0"
11622 [(set_attr "type" "ishift")
11623 (set_attr "length" "2")])
11624
11625;; This pattern can't accept a variable shift count, since shifts by
11626;; zero don't affect the flags. We assume that shifts by constant
11627;; zero are optimized away.
11628(define_insn "*ashrsi3_cmp"
11629 [(set (reg FLAGS_REG)
11630 (compare
11631 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11632 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11633 (const_int 0)))
11634 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11635 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11636 "ix86_match_ccmode (insn, CCGOCmode)
11637 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11638 && (optimize_size
11639 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11640 "sar{l}\t{%2, %0|%0, %2}"
11641 [(set_attr "type" "ishift")
11642 (set_attr "mode" "SI")])
11643
11644(define_insn "*ashrsi3_cconly"
11645 [(set (reg FLAGS_REG)
11646 (compare
11647 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11648 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11649 (const_int 0)))
11650 (clobber (match_scratch:SI 0 "=r"))]
11651 "ix86_match_ccmode (insn, CCGOCmode)
11652 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11653 && (optimize_size
11654 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11655 "sar{l}\t{%2, %0|%0, %2}"
11656 [(set_attr "type" "ishift")
11657 (set_attr "mode" "SI")])
11658
11659(define_insn "*ashrsi3_cmp_zext"
11660 [(set (reg FLAGS_REG)
11661 (compare
11662 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11664 (const_int 0)))
11665 (set (match_operand:DI 0 "register_operand" "=r")
11666 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11668 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11669 && (optimize_size
11670 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11671 "sar{l}\t{%2, %k0|%k0, %2}"
11672 [(set_attr "type" "ishift")
11673 (set_attr "mode" "SI")])
11674
11675(define_expand "ashrhi3"
11676 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11677 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11678 (match_operand:QI 2 "nonmemory_operand" "")))
11679 (clobber (reg:CC FLAGS_REG))]
11680 "TARGET_HIMODE_MATH"
11681 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11682
11683(define_insn "*ashrhi3_1_one_bit"
11684 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11685 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11686 (match_operand:QI 2 "const1_operand" "")))
11687 (clobber (reg:CC FLAGS_REG))]
11688 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11689 && (TARGET_SHIFT1 || optimize_size)"
11690 "sar{w}\t%0"
11691 [(set_attr "type" "ishift")
11692 (set (attr "length")
11693 (if_then_else (match_operand 0 "register_operand" "")
11694 (const_string "2")
11695 (const_string "*")))])
11696
11697(define_insn "*ashrhi3_1"
11698 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11699 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11700 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11701 (clobber (reg:CC FLAGS_REG))]
11702 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11703 "@
11704 sar{w}\t{%2, %0|%0, %2}
11705 sar{w}\t{%b2, %0|%0, %b2}"
11706 [(set_attr "type" "ishift")
11707 (set_attr "mode" "HI")])
11708
11709;; This pattern can't accept a variable shift count, since shifts by
11710;; zero don't affect the flags. We assume that shifts by constant
11711;; zero are optimized away.
11712(define_insn "*ashrhi3_one_bit_cmp"
11713 [(set (reg FLAGS_REG)
11714 (compare
11715 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11716 (match_operand:QI 2 "const1_operand" ""))
11717 (const_int 0)))
11718 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11719 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11720 "ix86_match_ccmode (insn, CCGOCmode)
11721 && (TARGET_SHIFT1 || optimize_size)
11722 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11723 "sar{w}\t%0"
11724 [(set_attr "type" "ishift")
11725 (set (attr "length")
11726 (if_then_else (match_operand 0 "register_operand" "")
11727 (const_string "2")
11728 (const_string "*")))])
11729
11730(define_insn "*ashrhi3_one_bit_cconly"
11731 [(set (reg FLAGS_REG)
11732 (compare
11733 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11734 (match_operand:QI 2 "const1_operand" ""))
11735 (const_int 0)))
11736 (clobber (match_scratch:HI 0 "=r"))]
11737 "ix86_match_ccmode (insn, CCGOCmode)
11738 && (TARGET_SHIFT1 || optimize_size)
11739 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11740 "sar{w}\t%0"
11741 [(set_attr "type" "ishift")
11742 (set_attr "length" "2")])
11743
11744;; This pattern can't accept a variable shift count, since shifts by
11745;; zero don't affect the flags. We assume that shifts by constant
11746;; zero are optimized away.
11747(define_insn "*ashrhi3_cmp"
11748 [(set (reg FLAGS_REG)
11749 (compare
11750 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11751 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11752 (const_int 0)))
11753 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11754 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11755 "ix86_match_ccmode (insn, CCGOCmode)
11756 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11757 && (optimize_size
11758 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11759 "sar{w}\t{%2, %0|%0, %2}"
11760 [(set_attr "type" "ishift")
11761 (set_attr "mode" "HI")])
11762
11763(define_insn "*ashrhi3_cconly"
11764 [(set (reg FLAGS_REG)
11765 (compare
11766 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11767 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11768 (const_int 0)))
11769 (clobber (match_scratch:HI 0 "=r"))]
11770 "ix86_match_ccmode (insn, CCGOCmode)
11771 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11772 && (optimize_size
11773 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11774 "sar{w}\t{%2, %0|%0, %2}"
11775 [(set_attr "type" "ishift")
11776 (set_attr "mode" "HI")])
11777
11778(define_expand "ashrqi3"
11779 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11780 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11781 (match_operand:QI 2 "nonmemory_operand" "")))
11782 (clobber (reg:CC FLAGS_REG))]
11783 "TARGET_QIMODE_MATH"
11784 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11785
11786(define_insn "*ashrqi3_1_one_bit"
11787 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789 (match_operand:QI 2 "const1_operand" "")))
11790 (clobber (reg:CC FLAGS_REG))]
11791 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11792 && (TARGET_SHIFT1 || optimize_size)"
11793 "sar{b}\t%0"
11794 [(set_attr "type" "ishift")
11795 (set (attr "length")
11796 (if_then_else (match_operand 0 "register_operand" "")
11797 (const_string "2")
11798 (const_string "*")))])
11799
11800(define_insn "*ashrqi3_1_one_bit_slp"
11801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11802 (ashiftrt:QI (match_dup 0)
11803 (match_operand:QI 1 "const1_operand" "")))
11804 (clobber (reg:CC FLAGS_REG))]
11805 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11806 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11807 && (TARGET_SHIFT1 || optimize_size)"
11808 "sar{b}\t%0"
11809 [(set_attr "type" "ishift1")
11810 (set (attr "length")
11811 (if_then_else (match_operand 0 "register_operand" "")
11812 (const_string "2")
11813 (const_string "*")))])
11814
11815(define_insn "*ashrqi3_1"
11816 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11817 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11818 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11819 (clobber (reg:CC FLAGS_REG))]
11820 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11821 "@
11822 sar{b}\t{%2, %0|%0, %2}
11823 sar{b}\t{%b2, %0|%0, %b2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "QI")])
11826
11827(define_insn "*ashrqi3_1_slp"
11828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11829 (ashiftrt:QI (match_dup 0)
11830 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11831 (clobber (reg:CC FLAGS_REG))]
11832 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11834 "@
11835 sar{b}\t{%1, %0|%0, %1}
11836 sar{b}\t{%b1, %0|%0, %b1}"
11837 [(set_attr "type" "ishift1")
11838 (set_attr "mode" "QI")])
11839
11840;; This pattern can't accept a variable shift count, since shifts by
11841;; zero don't affect the flags. We assume that shifts by constant
11842;; zero are optimized away.
11843(define_insn "*ashrqi3_one_bit_cmp"
11844 [(set (reg FLAGS_REG)
11845 (compare
11846 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11847 (match_operand:QI 2 "const1_operand" "I"))
11848 (const_int 0)))
11849 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11850 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11851 "ix86_match_ccmode (insn, CCGOCmode)
11852 && (TARGET_SHIFT1 || optimize_size)
11853 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11854 "sar{b}\t%0"
11855 [(set_attr "type" "ishift")
11856 (set (attr "length")
11857 (if_then_else (match_operand 0 "register_operand" "")
11858 (const_string "2")
11859 (const_string "*")))])
11860
11861(define_insn "*ashrqi3_one_bit_cconly"
11862 [(set (reg FLAGS_REG)
11863 (compare
11864 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11865 (match_operand:QI 2 "const1_operand" "I"))
11866 (const_int 0)))
11867 (clobber (match_scratch:QI 0 "=q"))]
11868 "ix86_match_ccmode (insn, CCGOCmode)
11869 && (TARGET_SHIFT1 || optimize_size)
11870 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11871 "sar{b}\t%0"
11872 [(set_attr "type" "ishift")
11873 (set_attr "length" "2")])
11874
11875;; This pattern can't accept a variable shift count, since shifts by
11876;; zero don't affect the flags. We assume that shifts by constant
11877;; zero are optimized away.
11878(define_insn "*ashrqi3_cmp"
11879 [(set (reg FLAGS_REG)
11880 (compare
11881 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11882 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11883 (const_int 0)))
11884 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11885 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11886 "ix86_match_ccmode (insn, CCGOCmode)
11887 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11888 && (optimize_size
11889 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11890 "sar{b}\t{%2, %0|%0, %2}"
11891 [(set_attr "type" "ishift")
11892 (set_attr "mode" "QI")])
11893
11894(define_insn "*ashrqi3_cconly"
11895 [(set (reg FLAGS_REG)
11896 (compare
11897 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11898 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11899 (const_int 0)))
11900 (clobber (match_scratch:QI 0 "=q"))]
11901 "ix86_match_ccmode (insn, CCGOCmode)
11902 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11903 && (optimize_size
11904 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11905 "sar{b}\t{%2, %0|%0, %2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "QI")])
11908
11909
11910;; Logical shift instructions
11911
11912;; See comment above `ashldi3' about how this works.
11913
11914(define_expand "lshrti3"
11915 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11916 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11917 (match_operand:QI 2 "nonmemory_operand" "")))
11918 (clobber (reg:CC FLAGS_REG))])]
11919 "TARGET_64BIT"
11920{
11921 if (! immediate_operand (operands[2], QImode))
11922 {
11923 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11924 DONE;
11925 }
11926 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11927 DONE;
11928})
11929
11930(define_insn "lshrti3_1"
11931 [(set (match_operand:TI 0 "register_operand" "=r")
11932 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11933 (match_operand:QI 2 "register_operand" "c")))
11934 (clobber (match_scratch:DI 3 "=&r"))
11935 (clobber (reg:CC FLAGS_REG))]
11936 "TARGET_64BIT"
11937 "#"
11938 [(set_attr "type" "multi")])
11939
11940(define_insn "*lshrti3_2"
11941 [(set (match_operand:TI 0 "register_operand" "=r")
11942 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11943 (match_operand:QI 2 "immediate_operand" "O")))
11944 (clobber (reg:CC FLAGS_REG))]
11945 "TARGET_64BIT"
11946 "#"
11947 [(set_attr "type" "multi")])
11948
11949(define_split
11950 [(set (match_operand:TI 0 "register_operand" "")
11951 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11952 (match_operand:QI 2 "register_operand" "")))
11953 (clobber (match_scratch:DI 3 ""))
11954 (clobber (reg:CC FLAGS_REG))]
11955 "TARGET_64BIT && reload_completed"
11956 [(const_int 0)]
11957 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11958
11959(define_split
11960 [(set (match_operand:TI 0 "register_operand" "")
11961 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11962 (match_operand:QI 2 "immediate_operand" "")))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "TARGET_64BIT && reload_completed"
11965 [(const_int 0)]
11966 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11967
11968(define_expand "lshrdi3"
11969 [(set (match_operand:DI 0 "shiftdi_operand" "")
11970 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11971 (match_operand:QI 2 "nonmemory_operand" "")))]
11972 ""
11973 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11974
11975(define_insn "*lshrdi3_1_one_bit_rex64"
11976 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11977 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11978 (match_operand:QI 2 "const1_operand" "")))
11979 (clobber (reg:CC FLAGS_REG))]
11980 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11981 && (TARGET_SHIFT1 || optimize_size)"
11982 "shr{q}\t%0"
11983 [(set_attr "type" "ishift")
11984 (set (attr "length")
11985 (if_then_else (match_operand:DI 0 "register_operand" "")
11986 (const_string "2")
11987 (const_string "*")))])
11988
11989(define_insn "*lshrdi3_1_rex64"
11990 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11991 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11992 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11993 (clobber (reg:CC FLAGS_REG))]
11994 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11995 "@
11996 shr{q}\t{%2, %0|%0, %2}
11997 shr{q}\t{%b2, %0|%0, %b2}"
11998 [(set_attr "type" "ishift")
11999 (set_attr "mode" "DI")])
12000
12001;; This pattern can't accept a variable shift count, since shifts by
12002;; zero don't affect the flags. We assume that shifts by constant
12003;; zero are optimized away.
12004(define_insn "*lshrdi3_cmp_one_bit_rex64"
12005 [(set (reg FLAGS_REG)
12006 (compare
12007 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12008 (match_operand:QI 2 "const1_operand" ""))
12009 (const_int 0)))
12010 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12011 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12012 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12013 && (TARGET_SHIFT1 || optimize_size)
12014 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12015 "shr{q}\t%0"
12016 [(set_attr "type" "ishift")
12017 (set (attr "length")
12018 (if_then_else (match_operand:DI 0 "register_operand" "")
12019 (const_string "2")
12020 (const_string "*")))])
12021
12022(define_insn "*lshrdi3_cconly_one_bit_rex64"
12023 [(set (reg FLAGS_REG)
12024 (compare
12025 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12026 (match_operand:QI 2 "const1_operand" ""))
12027 (const_int 0)))
12028 (clobber (match_scratch:DI 0 "=r"))]
12029 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12030 && (TARGET_SHIFT1 || optimize_size)
12031 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12032 "shr{q}\t%0"
12033 [(set_attr "type" "ishift")
12034 (set_attr "length" "2")])
12035
12036;; This pattern can't accept a variable shift count, since shifts by
12037;; zero don't affect the flags. We assume that shifts by constant
12038;; zero are optimized away.
12039(define_insn "*lshrdi3_cmp_rex64"
12040 [(set (reg FLAGS_REG)
12041 (compare
12042 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12043 (match_operand:QI 2 "const_int_operand" "e"))
12044 (const_int 0)))
12045 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12046 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12047 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12048 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12049 && (optimize_size
12050 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12051 "shr{q}\t{%2, %0|%0, %2}"
12052 [(set_attr "type" "ishift")
12053 (set_attr "mode" "DI")])
12054
12055(define_insn "*lshrdi3_cconly_rex64"
12056 [(set (reg FLAGS_REG)
12057 (compare
12058 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12059 (match_operand:QI 2 "const_int_operand" "e"))
12060 (const_int 0)))
12061 (clobber (match_scratch:DI 0 "=r"))]
12062 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12063 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12064 && (optimize_size
12065 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12066 "shr{q}\t{%2, %0|%0, %2}"
12067 [(set_attr "type" "ishift")
12068 (set_attr "mode" "DI")])
12069
12070(define_insn "*lshrdi3_1"
12071 [(set (match_operand:DI 0 "register_operand" "=r")
12072 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12073 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12074 (clobber (reg:CC FLAGS_REG))]
12075 "!TARGET_64BIT"
12076 "#"
12077 [(set_attr "type" "multi")])
12078
12079;; By default we don't ask for a scratch register, because when DImode
12080;; values are manipulated, registers are already at a premium. But if
12081;; we have one handy, we won't turn it away.
12082(define_peephole2
12083 [(match_scratch:SI 3 "r")
12084 (parallel [(set (match_operand:DI 0 "register_operand" "")
12085 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12086 (match_operand:QI 2 "nonmemory_operand" "")))
12087 (clobber (reg:CC FLAGS_REG))])
12088 (match_dup 3)]
12089 "!TARGET_64BIT && TARGET_CMOVE"
12090 [(const_int 0)]
12091 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12092
12093(define_split
12094 [(set (match_operand:DI 0 "register_operand" "")
12095 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12096 (match_operand:QI 2 "nonmemory_operand" "")))
12097 (clobber (reg:CC FLAGS_REG))]
12098 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12099 ? flow2_completed : reload_completed)"
12100 [(const_int 0)]
12101 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12102
12103(define_expand "lshrsi3"
12104 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12105 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12106 (match_operand:QI 2 "nonmemory_operand" "")))
12107 (clobber (reg:CC FLAGS_REG))]
12108 ""
12109 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12110
12111(define_insn "*lshrsi3_1_one_bit"
12112 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12113 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12114 (match_operand:QI 2 "const1_operand" "")))
12115 (clobber (reg:CC FLAGS_REG))]
12116 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12117 && (TARGET_SHIFT1 || optimize_size)"
12118 "shr{l}\t%0"
12119 [(set_attr "type" "ishift")
12120 (set (attr "length")
12121 (if_then_else (match_operand:SI 0 "register_operand" "")
12122 (const_string "2")
12123 (const_string "*")))])
12124
12125(define_insn "*lshrsi3_1_one_bit_zext"
12126 [(set (match_operand:DI 0 "register_operand" "=r")
12127 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12128 (match_operand:QI 2 "const1_operand" "")))
12129 (clobber (reg:CC FLAGS_REG))]
12130 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12131 && (TARGET_SHIFT1 || optimize_size)"
12132 "shr{l}\t%k0"
12133 [(set_attr "type" "ishift")
12134 (set_attr "length" "2")])
12135
12136(define_insn "*lshrsi3_1"
12137 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12138 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12140 (clobber (reg:CC FLAGS_REG))]
12141 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12142 "@
12143 shr{l}\t{%2, %0|%0, %2}
12144 shr{l}\t{%b2, %0|%0, %b2}"
12145 [(set_attr "type" "ishift")
12146 (set_attr "mode" "SI")])
12147
12148(define_insn "*lshrsi3_1_zext"
12149 [(set (match_operand:DI 0 "register_operand" "=r,r")
12150 (zero_extend:DI
12151 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12152 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12153 (clobber (reg:CC FLAGS_REG))]
12154 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12155 "@
12156 shr{l}\t{%2, %k0|%k0, %2}
12157 shr{l}\t{%b2, %k0|%k0, %b2}"
12158 [(set_attr "type" "ishift")
12159 (set_attr "mode" "SI")])
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 "*lshrsi3_one_bit_cmp"
12165 [(set (reg FLAGS_REG)
12166 (compare
12167 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12168 (match_operand:QI 2 "const1_operand" ""))
12169 (const_int 0)))
12170 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12171 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12172 "ix86_match_ccmode (insn, CCGOCmode)
12173 && (TARGET_SHIFT1 || optimize_size)
12174 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12175 "shr{l}\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(define_insn "*lshrsi3_one_bit_cconly"
12183 [(set (reg FLAGS_REG)
12184 (compare
12185 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12186 (match_operand:QI 2 "const1_operand" ""))
12187 (const_int 0)))
12188 (clobber (match_scratch:SI 0 "=r"))]
12189 "ix86_match_ccmode (insn, CCGOCmode)
12190 && (TARGET_SHIFT1 || optimize_size)
12191 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12192 "shr{l}\t%0"
12193 [(set_attr "type" "ishift")
12194 (set_attr "length" "2")])
12195
12196(define_insn "*lshrsi3_cmp_one_bit_zext"
12197 [(set (reg FLAGS_REG)
12198 (compare
12199 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12200 (match_operand:QI 2 "const1_operand" ""))
12201 (const_int 0)))
12202 (set (match_operand:DI 0 "register_operand" "=r")
12203 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12204 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12205 && (TARGET_SHIFT1 || optimize_size)
12206 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12207 "shr{l}\t%k0"
12208 [(set_attr "type" "ishift")
12209 (set_attr "length" "2")])
12210
12211;; This pattern can't accept a variable shift count, since shifts by
12212;; zero don't affect the flags. We assume that shifts by constant
12213;; zero are optimized away.
12214(define_insn "*lshrsi3_cmp"
12215 [(set (reg FLAGS_REG)
12216 (compare
12217 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12219 (const_int 0)))
12220 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12221 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12222 "ix86_match_ccmode (insn, CCGOCmode)
12223 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12224 && (optimize_size
12225 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12226 "shr{l}\t{%2, %0|%0, %2}"
12227 [(set_attr "type" "ishift")
12228 (set_attr "mode" "SI")])
12229
12230(define_insn "*lshrsi3_cconly"
12231 [(set (reg FLAGS_REG)
12232 (compare
12233 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12235 (const_int 0)))
12236 (clobber (match_scratch:SI 0 "=r"))]
12237 "ix86_match_ccmode (insn, CCGOCmode)
12238 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12239 && (optimize_size
12240 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12241 "shr{l}\t{%2, %0|%0, %2}"
12242 [(set_attr "type" "ishift")
12243 (set_attr "mode" "SI")])
12244
12245(define_insn "*lshrsi3_cmp_zext"
12246 [(set (reg FLAGS_REG)
12247 (compare
12248 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12250 (const_int 0)))
12251 (set (match_operand:DI 0 "register_operand" "=r")
12252 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12255 && (optimize_size
12256 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12257 "shr{l}\t{%2, %k0|%k0, %2}"
12258 [(set_attr "type" "ishift")
12259 (set_attr "mode" "SI")])
12260
12261(define_expand "lshrhi3"
12262 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12263 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12264 (match_operand:QI 2 "nonmemory_operand" "")))
12265 (clobber (reg:CC FLAGS_REG))]
12266 "TARGET_HIMODE_MATH"
12267 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12268
12269(define_insn "*lshrhi3_1_one_bit"
12270 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12271 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12272 (match_operand:QI 2 "const1_operand" "")))
12273 (clobber (reg:CC FLAGS_REG))]
12274 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12275 && (TARGET_SHIFT1 || optimize_size)"
12276 "shr{w}\t%0"
12277 [(set_attr "type" "ishift")
12278 (set (attr "length")
12279 (if_then_else (match_operand 0 "register_operand" "")
12280 (const_string "2")
12281 (const_string "*")))])
12282
12283(define_insn "*lshrhi3_1"
12284 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12285 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12286 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12287 (clobber (reg:CC FLAGS_REG))]
12288 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289 "@
12290 shr{w}\t{%2, %0|%0, %2}
12291 shr{w}\t{%b2, %0|%0, %b2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "HI")])
12294
12295;; This pattern can't accept a variable shift count, since shifts by
12296;; zero don't affect the flags. We assume that shifts by constant
12297;; zero are optimized away.
12298(define_insn "*lshrhi3_one_bit_cmp"
12299 [(set (reg FLAGS_REG)
12300 (compare
12301 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const1_operand" ""))
12303 (const_int 0)))
12304 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12305 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12306 "ix86_match_ccmode (insn, CCGOCmode)
12307 && (TARGET_SHIFT1 || optimize_size)
12308 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12309 "shr{w}\t%0"
12310 [(set_attr "type" "ishift")
12311 (set (attr "length")
12312 (if_then_else (match_operand:SI 0 "register_operand" "")
12313 (const_string "2")
12314 (const_string "*")))])
12315
12316(define_insn "*lshrhi3_one_bit_cconly"
12317 [(set (reg FLAGS_REG)
12318 (compare
12319 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" ""))
12321 (const_int 0)))
12322 (clobber (match_scratch:HI 0 "=r"))]
12323 "ix86_match_ccmode (insn, CCGOCmode)
12324 && (TARGET_SHIFT1 || optimize_size)
12325 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12326 "shr{w}\t%0"
12327 [(set_attr "type" "ishift")
12328 (set_attr "length" "2")])
12329
12330;; This pattern can't accept a variable shift count, since shifts by
12331;; zero don't affect the flags. We assume that shifts by constant
12332;; zero are optimized away.
12333(define_insn "*lshrhi3_cmp"
12334 [(set (reg FLAGS_REG)
12335 (compare
12336 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12337 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12338 (const_int 0)))
12339 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12340 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12341 "ix86_match_ccmode (insn, CCGOCmode)
12342 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12343 && (optimize_size
12344 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12345 "shr{w}\t{%2, %0|%0, %2}"
12346 [(set_attr "type" "ishift")
12347 (set_attr "mode" "HI")])
12348
12349(define_insn "*lshrhi3_cconly"
12350 [(set (reg FLAGS_REG)
12351 (compare
12352 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12354 (const_int 0)))
12355 (clobber (match_scratch:HI 0 "=r"))]
12356 "ix86_match_ccmode (insn, CCGOCmode)
12357 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12358 && (optimize_size
12359 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12360 "shr{w}\t{%2, %0|%0, %2}"
12361 [(set_attr "type" "ishift")
12362 (set_attr "mode" "HI")])
12363
12364(define_expand "lshrqi3"
12365 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12366 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12367 (match_operand:QI 2 "nonmemory_operand" "")))
12368 (clobber (reg:CC FLAGS_REG))]
12369 "TARGET_QIMODE_MATH"
12370 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12371
12372(define_insn "*lshrqi3_1_one_bit"
12373 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12374 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12375 (match_operand:QI 2 "const1_operand" "")))
12376 (clobber (reg:CC FLAGS_REG))]
12377 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12378 && (TARGET_SHIFT1 || optimize_size)"
12379 "shr{b}\t%0"
12380 [(set_attr "type" "ishift")
12381 (set (attr "length")
12382 (if_then_else (match_operand 0 "register_operand" "")
12383 (const_string "2")
12384 (const_string "*")))])
12385
12386(define_insn "*lshrqi3_1_one_bit_slp"
12387 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12388 (lshiftrt:QI (match_dup 0)
12389 (match_operand:QI 1 "const1_operand" "")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12392 && (TARGET_SHIFT1 || optimize_size)"
12393 "shr{b}\t%0"
12394 [(set_attr "type" "ishift1")
12395 (set (attr "length")
12396 (if_then_else (match_operand 0 "register_operand" "")
12397 (const_string "2")
12398 (const_string "*")))])
12399
12400(define_insn "*lshrqi3_1"
12401 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12402 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12403 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12404 (clobber (reg:CC FLAGS_REG))]
12405 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12406 "@
12407 shr{b}\t{%2, %0|%0, %2}
12408 shr{b}\t{%b2, %0|%0, %b2}"
12409 [(set_attr "type" "ishift")
12410 (set_attr "mode" "QI")])
12411
12412(define_insn "*lshrqi3_1_slp"
12413 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12414 (lshiftrt:QI (match_dup 0)
12415 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12416 (clobber (reg:CC FLAGS_REG))]
12417 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12418 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12419 "@
12420 shr{b}\t{%1, %0|%0, %1}
12421 shr{b}\t{%b1, %0|%0, %b1}"
12422 [(set_attr "type" "ishift1")
12423 (set_attr "mode" "QI")])
12424
12425;; This pattern can't accept a variable shift count, since shifts by
12426;; zero don't affect the flags. We assume that shifts by constant
12427;; zero are optimized away.
12428(define_insn "*lshrqi2_one_bit_cmp"
12429 [(set (reg FLAGS_REG)
12430 (compare
12431 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12432 (match_operand:QI 2 "const1_operand" ""))
12433 (const_int 0)))
12434 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12435 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12436 "ix86_match_ccmode (insn, CCGOCmode)
12437 && (TARGET_SHIFT1 || optimize_size)
12438 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12439 "shr{b}\t%0"
12440 [(set_attr "type" "ishift")
12441 (set (attr "length")
12442 (if_then_else (match_operand:SI 0 "register_operand" "")
12443 (const_string "2")
12444 (const_string "*")))])
12445
12446(define_insn "*lshrqi2_one_bit_cconly"
12447 [(set (reg FLAGS_REG)
12448 (compare
12449 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450 (match_operand:QI 2 "const1_operand" ""))
12451 (const_int 0)))
12452 (clobber (match_scratch:QI 0 "=q"))]
12453 "ix86_match_ccmode (insn, CCGOCmode)
12454 && (TARGET_SHIFT1 || optimize_size)
12455 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12456 "shr{b}\t%0"
12457 [(set_attr "type" "ishift")
12458 (set_attr "length" "2")])
12459
12460;; This pattern can't accept a variable shift count, since shifts by
12461;; zero don't affect the flags. We assume that shifts by constant
12462;; zero are optimized away.
12463(define_insn "*lshrqi2_cmp"
12464 [(set (reg FLAGS_REG)
12465 (compare
12466 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12467 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12468 (const_int 0)))
12469 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12471 "ix86_match_ccmode (insn, CCGOCmode)
12472 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12473 && (optimize_size
12474 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12475 "shr{b}\t{%2, %0|%0, %2}"
12476 [(set_attr "type" "ishift")
12477 (set_attr "mode" "QI")])
12478
12479(define_insn "*lshrqi2_cconly"
12480 [(set (reg FLAGS_REG)
12481 (compare
12482 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12483 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12484 (const_int 0)))
12485 (clobber (match_scratch:QI 0 "=q"))]
12486 "ix86_match_ccmode (insn, CCGOCmode)
12487 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12488 && (optimize_size
12489 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12490 "shr{b}\t{%2, %0|%0, %2}"
12491 [(set_attr "type" "ishift")
12492 (set_attr "mode" "QI")])
12493
12494;; Rotate instructions
12495
12496(define_expand "rotldi3"
12497 [(set (match_operand:DI 0 "shiftdi_operand" "")
12498 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12499 (match_operand:QI 2 "nonmemory_operand" "")))
12500 (clobber (reg:CC FLAGS_REG))]
12501 ""
12502{
12503 if (TARGET_64BIT)
12504 {
12505 ix86_expand_binary_operator (ROTATE, DImode, operands);
12506 DONE;
12507 }
12508 if (!const_1_to_31_operand (operands[2], VOIDmode))
12509 FAIL;
12510 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12511 DONE;
12512})
12513
12514;; Implement rotation using two double-precision shift instructions
12515;; and a scratch register.
12516(define_insn_and_split "ix86_rotldi3"
12517 [(set (match_operand:DI 0 "register_operand" "=r")
12518 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12519 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12520 (clobber (reg:CC FLAGS_REG))
12521 (clobber (match_scratch:SI 3 "=&r"))]
12522 "!TARGET_64BIT"
12523 ""
12524 "&& reload_completed"
12525 [(set (match_dup 3) (match_dup 4))
12526 (parallel
12527 [(set (match_dup 4)
12528 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12529 (lshiftrt:SI (match_dup 5)
12530 (minus:QI (const_int 32) (match_dup 2)))))
12531 (clobber (reg:CC FLAGS_REG))])
12532 (parallel
12533 [(set (match_dup 5)
12534 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12535 (lshiftrt:SI (match_dup 3)
12536 (minus:QI (const_int 32) (match_dup 2)))))
12537 (clobber (reg:CC FLAGS_REG))])]
12538 "split_di (operands, 1, operands + 4, operands + 5);")
12539
12540(define_insn "*rotlsi3_1_one_bit_rex64"
12541 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12542 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12543 (match_operand:QI 2 "const1_operand" "")))
12544 (clobber (reg:CC FLAGS_REG))]
12545 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12546 && (TARGET_SHIFT1 || optimize_size)"
12547 "rol{q}\t%0"
12548 [(set_attr "type" "rotate")
12549 (set (attr "length")
12550 (if_then_else (match_operand:DI 0 "register_operand" "")
12551 (const_string "2")
12552 (const_string "*")))])
12553
12554(define_insn "*rotldi3_1_rex64"
12555 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12556 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12557 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12558 (clobber (reg:CC FLAGS_REG))]
12559 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12560 "@
12561 rol{q}\t{%2, %0|%0, %2}
12562 rol{q}\t{%b2, %0|%0, %b2}"
12563 [(set_attr "type" "rotate")
12564 (set_attr "mode" "DI")])
12565
12566(define_expand "rotlsi3"
12567 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12568 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12569 (match_operand:QI 2 "nonmemory_operand" "")))
12570 (clobber (reg:CC FLAGS_REG))]
12571 ""
12572 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12573
12574(define_insn "*rotlsi3_1_one_bit"
12575 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12576 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12577 (match_operand:QI 2 "const1_operand" "")))
12578 (clobber (reg:CC FLAGS_REG))]
12579 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12580 && (TARGET_SHIFT1 || optimize_size)"
12581 "rol{l}\t%0"
12582 [(set_attr "type" "rotate")
12583 (set (attr "length")
12584 (if_then_else (match_operand:SI 0 "register_operand" "")
12585 (const_string "2")
12586 (const_string "*")))])
12587
12588(define_insn "*rotlsi3_1_one_bit_zext"
12589 [(set (match_operand:DI 0 "register_operand" "=r")
12590 (zero_extend:DI
12591 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12592 (match_operand:QI 2 "const1_operand" ""))))
12593 (clobber (reg:CC FLAGS_REG))]
12594 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12595 && (TARGET_SHIFT1 || optimize_size)"
12596 "rol{l}\t%k0"
12597 [(set_attr "type" "rotate")
12598 (set_attr "length" "2")])
12599
12600(define_insn "*rotlsi3_1"
12601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12602 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12603 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12604 (clobber (reg:CC FLAGS_REG))]
12605 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12606 "@
12607 rol{l}\t{%2, %0|%0, %2}
12608 rol{l}\t{%b2, %0|%0, %b2}"
12609 [(set_attr "type" "rotate")
12610 (set_attr "mode" "SI")])
12611
12612(define_insn "*rotlsi3_1_zext"
12613 [(set (match_operand:DI 0 "register_operand" "=r,r")
12614 (zero_extend:DI
12615 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12616 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12617 (clobber (reg:CC FLAGS_REG))]
12618 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12619 "@
12620 rol{l}\t{%2, %k0|%k0, %2}
12621 rol{l}\t{%b2, %k0|%k0, %b2}"
12622 [(set_attr "type" "rotate")
12623 (set_attr "mode" "SI")])
12624
12625(define_expand "rotlhi3"
12626 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12627 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12628 (match_operand:QI 2 "nonmemory_operand" "")))
12629 (clobber (reg:CC FLAGS_REG))]
12630 "TARGET_HIMODE_MATH"
12631 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12632
12633(define_insn "*rotlhi3_1_one_bit"
12634 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12635 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12636 (match_operand:QI 2 "const1_operand" "")))
12637 (clobber (reg:CC FLAGS_REG))]
12638 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12639 && (TARGET_SHIFT1 || optimize_size)"
12640 "rol{w}\t%0"
12641 [(set_attr "type" "rotate")
12642 (set (attr "length")
12643 (if_then_else (match_operand 0 "register_operand" "")
12644 (const_string "2")
12645 (const_string "*")))])
12646
12647(define_insn "*rotlhi3_1"
12648 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12649 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12650 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12651 (clobber (reg:CC FLAGS_REG))]
12652 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12653 "@
12654 rol{w}\t{%2, %0|%0, %2}
12655 rol{w}\t{%b2, %0|%0, %b2}"
12656 [(set_attr "type" "rotate")
12657 (set_attr "mode" "HI")])
12658
12659(define_expand "rotlqi3"
12660 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12661 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12662 (match_operand:QI 2 "nonmemory_operand" "")))
12663 (clobber (reg:CC FLAGS_REG))]
12664 "TARGET_QIMODE_MATH"
12665 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12666
12667(define_insn "*rotlqi3_1_one_bit_slp"
12668 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12669 (rotate:QI (match_dup 0)
12670 (match_operand:QI 1 "const1_operand" "")))
12671 (clobber (reg:CC FLAGS_REG))]
12672 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12673 && (TARGET_SHIFT1 || optimize_size)"
12674 "rol{b}\t%0"
12675 [(set_attr "type" "rotate1")
12676 (set (attr "length")
12677 (if_then_else (match_operand 0 "register_operand" "")
12678 (const_string "2")
12679 (const_string "*")))])
12680
12681(define_insn "*rotlqi3_1_one_bit"
12682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12683 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12684 (match_operand:QI 2 "const1_operand" "")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12687 && (TARGET_SHIFT1 || optimize_size)"
12688 "rol{b}\t%0"
12689 [(set_attr "type" "rotate")
12690 (set (attr "length")
12691 (if_then_else (match_operand 0 "register_operand" "")
12692 (const_string "2")
12693 (const_string "*")))])
12694
12695(define_insn "*rotlqi3_1_slp"
12696 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12697 (rotate:QI (match_dup 0)
12698 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12699 (clobber (reg:CC FLAGS_REG))]
12700 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12702 "@
12703 rol{b}\t{%1, %0|%0, %1}
12704 rol{b}\t{%b1, %0|%0, %b1}"
12705 [(set_attr "type" "rotate1")
12706 (set_attr "mode" "QI")])
12707
12708(define_insn "*rotlqi3_1"
12709 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12710 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12711 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12712 (clobber (reg:CC FLAGS_REG))]
12713 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12714 "@
12715 rol{b}\t{%2, %0|%0, %2}
12716 rol{b}\t{%b2, %0|%0, %b2}"
12717 [(set_attr "type" "rotate")
12718 (set_attr "mode" "QI")])
12719
12720(define_expand "rotrdi3"
12721 [(set (match_operand:DI 0 "shiftdi_operand" "")
12722 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12723 (match_operand:QI 2 "nonmemory_operand" "")))
12724 (clobber (reg:CC FLAGS_REG))]
12725 ""
12726{
12727 if (TARGET_64BIT)
12728 {
12729 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12730 DONE;
12731 }
12732 if (!const_1_to_31_operand (operands[2], VOIDmode))
12733 FAIL;
12734 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12735 DONE;
12736})
12737
12738;; Implement rotation using two double-precision shift instructions
12739;; and a scratch register.
12740(define_insn_and_split "ix86_rotrdi3"
12741 [(set (match_operand:DI 0 "register_operand" "=r")
12742 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12743 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12744 (clobber (reg:CC FLAGS_REG))
12745 (clobber (match_scratch:SI 3 "=&r"))]
12746 "!TARGET_64BIT"
12747 ""
12748 "&& reload_completed"
12749 [(set (match_dup 3) (match_dup 4))
12750 (parallel
12751 [(set (match_dup 4)
12752 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12753 (ashift:SI (match_dup 5)
12754 (minus:QI (const_int 32) (match_dup 2)))))
12755 (clobber (reg:CC FLAGS_REG))])
12756 (parallel
12757 [(set (match_dup 5)
12758 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12759 (ashift:SI (match_dup 3)
12760 (minus:QI (const_int 32) (match_dup 2)))))
12761 (clobber (reg:CC FLAGS_REG))])]
12762 "split_di (operands, 1, operands + 4, operands + 5);")
12763
12764(define_insn "*rotrdi3_1_one_bit_rex64"
12765 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12766 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12767 (match_operand:QI 2 "const1_operand" "")))
12768 (clobber (reg:CC FLAGS_REG))]
12769 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12770 && (TARGET_SHIFT1 || optimize_size)"
12771 "ror{q}\t%0"
12772 [(set_attr "type" "rotate")
12773 (set (attr "length")
12774 (if_then_else (match_operand:DI 0 "register_operand" "")
12775 (const_string "2")
12776 (const_string "*")))])
12777
12778(define_insn "*rotrdi3_1_rex64"
12779 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12780 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12781 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12782 (clobber (reg:CC FLAGS_REG))]
12783 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12784 "@
12785 ror{q}\t{%2, %0|%0, %2}
12786 ror{q}\t{%b2, %0|%0, %b2}"
12787 [(set_attr "type" "rotate")
12788 (set_attr "mode" "DI")])
12789
12790(define_expand "rotrsi3"
12791 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12792 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12793 (match_operand:QI 2 "nonmemory_operand" "")))
12794 (clobber (reg:CC FLAGS_REG))]
12795 ""
12796 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12797
12798(define_insn "*rotrsi3_1_one_bit"
12799 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12800 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12801 (match_operand:QI 2 "const1_operand" "")))
12802 (clobber (reg:CC FLAGS_REG))]
12803 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12804 && (TARGET_SHIFT1 || optimize_size)"
12805 "ror{l}\t%0"
12806 [(set_attr "type" "rotate")
12807 (set (attr "length")
12808 (if_then_else (match_operand:SI 0 "register_operand" "")
12809 (const_string "2")
12810 (const_string "*")))])
12811
12812(define_insn "*rotrsi3_1_one_bit_zext"
12813 [(set (match_operand:DI 0 "register_operand" "=r")
12814 (zero_extend:DI
12815 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12816 (match_operand:QI 2 "const1_operand" ""))))
12817 (clobber (reg:CC FLAGS_REG))]
12818 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12819 && (TARGET_SHIFT1 || optimize_size)"
12820 "ror{l}\t%k0"
12821 [(set_attr "type" "rotate")
12822 (set (attr "length")
12823 (if_then_else (match_operand:SI 0 "register_operand" "")
12824 (const_string "2")
12825 (const_string "*")))])
12826
12827(define_insn "*rotrsi3_1"
12828 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12829 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12830 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12831 (clobber (reg:CC FLAGS_REG))]
12832 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12833 "@
12834 ror{l}\t{%2, %0|%0, %2}
12835 ror{l}\t{%b2, %0|%0, %b2}"
12836 [(set_attr "type" "rotate")
12837 (set_attr "mode" "SI")])
12838
12839(define_insn "*rotrsi3_1_zext"
12840 [(set (match_operand:DI 0 "register_operand" "=r,r")
12841 (zero_extend:DI
12842 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12843 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12844 (clobber (reg:CC FLAGS_REG))]
12845 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12846 "@
12847 ror{l}\t{%2, %k0|%k0, %2}
12848 ror{l}\t{%b2, %k0|%k0, %b2}"
12849 [(set_attr "type" "rotate")
12850 (set_attr "mode" "SI")])
12851
12852(define_expand "rotrhi3"
12853 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12854 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12855 (match_operand:QI 2 "nonmemory_operand" "")))
12856 (clobber (reg:CC FLAGS_REG))]
12857 "TARGET_HIMODE_MATH"
12858 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12859
12860(define_insn "*rotrhi3_one_bit"
12861 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12862 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12863 (match_operand:QI 2 "const1_operand" "")))
12864 (clobber (reg:CC FLAGS_REG))]
12865 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12866 && (TARGET_SHIFT1 || optimize_size)"
12867 "ror{w}\t%0"
12868 [(set_attr "type" "rotate")
12869 (set (attr "length")
12870 (if_then_else (match_operand 0 "register_operand" "")
12871 (const_string "2")
12872 (const_string "*")))])
12873
12874(define_insn "*rotrhi3"
12875 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12876 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12877 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12880 "@
12881 ror{w}\t{%2, %0|%0, %2}
12882 ror{w}\t{%b2, %0|%0, %b2}"
12883 [(set_attr "type" "rotate")
12884 (set_attr "mode" "HI")])
12885
12886(define_expand "rotrqi3"
12887 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12888 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12889 (match_operand:QI 2 "nonmemory_operand" "")))
12890 (clobber (reg:CC FLAGS_REG))]
12891 "TARGET_QIMODE_MATH"
12892 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12893
12894(define_insn "*rotrqi3_1_one_bit"
12895 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12896 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12897 (match_operand:QI 2 "const1_operand" "")))
12898 (clobber (reg:CC FLAGS_REG))]
12899 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12900 && (TARGET_SHIFT1 || optimize_size)"
12901 "ror{b}\t%0"
12902 [(set_attr "type" "rotate")
12903 (set (attr "length")
12904 (if_then_else (match_operand 0 "register_operand" "")
12905 (const_string "2")
12906 (const_string "*")))])
12907
12908(define_insn "*rotrqi3_1_one_bit_slp"
12909 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12910 (rotatert:QI (match_dup 0)
12911 (match_operand:QI 1 "const1_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12914 && (TARGET_SHIFT1 || optimize_size)"
12915 "ror{b}\t%0"
12916 [(set_attr "type" "rotate1")
12917 (set (attr "length")
12918 (if_then_else (match_operand 0 "register_operand" "")
12919 (const_string "2")
12920 (const_string "*")))])
12921
12922(define_insn "*rotrqi3_1"
12923 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12924 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12925 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12926 (clobber (reg:CC FLAGS_REG))]
12927 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12928 "@
12929 ror{b}\t{%2, %0|%0, %2}
12930 ror{b}\t{%b2, %0|%0, %b2}"
12931 [(set_attr "type" "rotate")
12932 (set_attr "mode" "QI")])
12933
12934(define_insn "*rotrqi3_1_slp"
12935 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12936 (rotatert:QI (match_dup 0)
12937 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12940 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12941 "@
12942 ror{b}\t{%1, %0|%0, %1}
12943 ror{b}\t{%b1, %0|%0, %b1}"
12944 [(set_attr "type" "rotate1")
12945 (set_attr "mode" "QI")])
12946
12947;; Bit set / bit test instructions
12948
12949(define_expand "extv"
12950 [(set (match_operand:SI 0 "register_operand" "")
12951 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12952 (match_operand:SI 2 "const8_operand" "")
12953 (match_operand:SI 3 "const8_operand" "")))]
12954 ""
12955{
12956 /* Handle extractions from %ah et al. */
12957 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12958 FAIL;
12959
12960 /* From mips.md: extract_bit_field doesn't verify that our source
12961 matches the predicate, so check it again here. */
12962 if (! ext_register_operand (operands[1], VOIDmode))
12963 FAIL;
12964})
12965
12966(define_expand "extzv"
12967 [(set (match_operand:SI 0 "register_operand" "")
12968 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12969 (match_operand:SI 2 "const8_operand" "")
12970 (match_operand:SI 3 "const8_operand" "")))]
12971 ""
12972{
12973 /* Handle extractions from %ah et al. */
12974 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12975 FAIL;
12976
12977 /* From mips.md: extract_bit_field doesn't verify that our source
12978 matches the predicate, so check it again here. */
12979 if (! ext_register_operand (operands[1], VOIDmode))
12980 FAIL;
12981})
12982
12983(define_expand "insv"
12984 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12985 (match_operand 1 "const8_operand" "")
12986 (match_operand 2 "const8_operand" ""))
12987 (match_operand 3 "register_operand" ""))]
12988 ""
12989{
12990 /* Handle insertions to %ah et al. */
12991 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12992 FAIL;
12993
12994 /* From mips.md: insert_bit_field doesn't verify that our source
12995 matches the predicate, so check it again here. */
12996 if (! ext_register_operand (operands[0], VOIDmode))
12997 FAIL;
12998
12999 if (TARGET_64BIT)
13000 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13001 else
13002 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13003
13004 DONE;
13005})
13006
13007;; %%% bts, btr, btc, bt.
13008;; In general these instructions are *slow* when applied to memory,
13009;; since they enforce atomic operation. When applied to registers,
13010;; it depends on the cpu implementation. They're never faster than
13011;; the corresponding and/ior/xor operations, so with 32-bit there's
13012;; no point. But in 64-bit, we can't hold the relevant immediates
13013;; within the instruction itself, so operating on bits in the high
13014;; 32-bits of a register becomes easier.
13015;;
13016;; These are slow on Nocona, but fast on Athlon64. We do require the use
13017;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13018;; negdf respectively, so they can never be disabled entirely.
13019
13020(define_insn "*btsq"
13021 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13022 (const_int 1)
13023 (match_operand:DI 1 "const_0_to_63_operand" ""))
13024 (const_int 1))
13025 (clobber (reg:CC FLAGS_REG))]
13026 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13027 "bts{q} %1,%0"
13028 [(set_attr "type" "alu1")])
13029
13030(define_insn "*btrq"
13031 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13032 (const_int 1)
13033 (match_operand:DI 1 "const_0_to_63_operand" ""))
13034 (const_int 0))
13035 (clobber (reg:CC FLAGS_REG))]
13036 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13037 "btr{q} %1,%0"
13038 [(set_attr "type" "alu1")])
13039
13040(define_insn "*btcq"
13041 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13042 (const_int 1)
13043 (match_operand:DI 1 "const_0_to_63_operand" ""))
13044 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13045 (clobber (reg:CC FLAGS_REG))]
13046 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13047 "btc{q} %1,%0"
13048 [(set_attr "type" "alu1")])
13049
13050;; Allow Nocona to avoid these instructions if a register is available.
13051
13052(define_peephole2
13053 [(match_scratch:DI 2 "r")
13054 (parallel [(set (zero_extract:DI
13055 (match_operand:DI 0 "register_operand" "")
13056 (const_int 1)
13057 (match_operand:DI 1 "const_0_to_63_operand" ""))
13058 (const_int 1))
13059 (clobber (reg:CC FLAGS_REG))])]
13060 "TARGET_64BIT && !TARGET_USE_BT"
13061 [(const_int 0)]
13062{
13063 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13064 rtx op1;
13065
13066 if (HOST_BITS_PER_WIDE_INT >= 64)
13067 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13068 else if (i < HOST_BITS_PER_WIDE_INT)
13069 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13070 else
13071 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13072
13073 op1 = immed_double_const (lo, hi, DImode);
13074 if (i >= 31)
13075 {
13076 emit_move_insn (operands[2], op1);
13077 op1 = operands[2];
13078 }
13079
13080 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13081 DONE;
13082})
13083
13084(define_peephole2
13085 [(match_scratch:DI 2 "r")
13086 (parallel [(set (zero_extract:DI
13087 (match_operand:DI 0 "register_operand" "")
13088 (const_int 1)
13089 (match_operand:DI 1 "const_0_to_63_operand" ""))
13090 (const_int 0))
13091 (clobber (reg:CC FLAGS_REG))])]
13092 "TARGET_64BIT && !TARGET_USE_BT"
13093 [(const_int 0)]
13094{
13095 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13096 rtx op1;
13097
13098 if (HOST_BITS_PER_WIDE_INT >= 64)
13099 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13100 else if (i < HOST_BITS_PER_WIDE_INT)
13101 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13102 else
13103 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13104
13105 op1 = immed_double_const (~lo, ~hi, DImode);
13106 if (i >= 32)
13107 {
13108 emit_move_insn (operands[2], op1);
13109 op1 = operands[2];
13110 }
13111
13112 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13113 DONE;
13114})
13115
13116(define_peephole2
13117 [(match_scratch:DI 2 "r")
13118 (parallel [(set (zero_extract:DI
13119 (match_operand:DI 0 "register_operand" "")
13120 (const_int 1)
13121 (match_operand:DI 1 "const_0_to_63_operand" ""))
13122 (not:DI (zero_extract:DI
13123 (match_dup 0) (const_int 1) (match_dup 1))))
13124 (clobber (reg:CC FLAGS_REG))])]
13125 "TARGET_64BIT && !TARGET_USE_BT"
13126 [(const_int 0)]
13127{
13128 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13129 rtx op1;
13130
13131 if (HOST_BITS_PER_WIDE_INT >= 64)
13132 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13133 else if (i < HOST_BITS_PER_WIDE_INT)
13134 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13135 else
13136 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13137
13138 op1 = immed_double_const (lo, hi, DImode);
13139 if (i >= 31)
13140 {
13141 emit_move_insn (operands[2], op1);
13142 op1 = operands[2];
13143 }
13144
13145 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13146 DONE;
13147})
13148
13149;; Store-flag instructions.
13150
13151;; For all sCOND expanders, also expand the compare or test insn that
13152;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13153
13154;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13155;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13156;; way, which can later delete the movzx if only QImode is needed.
13157
13158(define_expand "seq"
13159 [(set (match_operand:QI 0 "register_operand" "")
13160 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13161 ""
13162 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13163
13164(define_expand "sne"
13165 [(set (match_operand:QI 0 "register_operand" "")
13166 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13167 ""
13168 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13169
13170(define_expand "sgt"
13171 [(set (match_operand:QI 0 "register_operand" "")
13172 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13173 ""
13174 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13175
13176(define_expand "sgtu"
13177 [(set (match_operand:QI 0 "register_operand" "")
13178 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13179 ""
13180 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13181
13182(define_expand "slt"
13183 [(set (match_operand:QI 0 "register_operand" "")
13184 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13185 ""
13186 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13187
13188(define_expand "sltu"
13189 [(set (match_operand:QI 0 "register_operand" "")
13190 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13191 ""
13192 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13193
13194(define_expand "sge"
13195 [(set (match_operand:QI 0 "register_operand" "")
13196 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13197 ""
13198 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13199
13200(define_expand "sgeu"
13201 [(set (match_operand:QI 0 "register_operand" "")
13202 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13203 ""
13204 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13205
13206(define_expand "sle"
13207 [(set (match_operand:QI 0 "register_operand" "")
13208 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13209 ""
13210 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13211
13212(define_expand "sleu"
13213 [(set (match_operand:QI 0 "register_operand" "")
13214 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215 ""
13216 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13217
13218(define_expand "sunordered"
13219 [(set (match_operand:QI 0 "register_operand" "")
13220 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221 "TARGET_80387 || TARGET_SSE"
13222 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13223
13224(define_expand "sordered"
13225 [(set (match_operand:QI 0 "register_operand" "")
13226 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227 "TARGET_80387"
13228 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13229
13230(define_expand "suneq"
13231 [(set (match_operand:QI 0 "register_operand" "")
13232 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233 "TARGET_80387 || TARGET_SSE"
13234 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13235
13236(define_expand "sunge"
13237 [(set (match_operand:QI 0 "register_operand" "")
13238 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239 "TARGET_80387 || TARGET_SSE"
13240 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13241
13242(define_expand "sungt"
13243 [(set (match_operand:QI 0 "register_operand" "")
13244 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245 "TARGET_80387 || TARGET_SSE"
13246 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13247
13248(define_expand "sunle"
13249 [(set (match_operand:QI 0 "register_operand" "")
13250 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251 "TARGET_80387 || TARGET_SSE"
13252 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13253
13254(define_expand "sunlt"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257 "TARGET_80387 || TARGET_SSE"
13258 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13259
13260(define_expand "sltgt"
13261 [(set (match_operand:QI 0 "register_operand" "")
13262 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263 "TARGET_80387 || TARGET_SSE"
13264 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13265
13266(define_insn "*setcc_1"
13267 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13268 (match_operator:QI 1 "ix86_comparison_operator"
13269 [(reg FLAGS_REG) (const_int 0)]))]
13270 ""
13271 "set%C1\t%0"
13272 [(set_attr "type" "setcc")
13273 (set_attr "mode" "QI")])
13274
13275(define_insn "*setcc_2"
13276 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13277 (match_operator:QI 1 "ix86_comparison_operator"
13278 [(reg FLAGS_REG) (const_int 0)]))]
13279 ""
13280 "set%C1\t%0"
13281 [(set_attr "type" "setcc")
13282 (set_attr "mode" "QI")])
13283
13284;; In general it is not safe to assume too much about CCmode registers,
13285;; so simplify-rtx stops when it sees a second one. Under certain
13286;; conditions this is safe on x86, so help combine not create
13287;;
13288;; seta %al
13289;; testb %al, %al
13290;; sete %al
13291
13292(define_split
13293 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13294 (ne:QI (match_operator 1 "ix86_comparison_operator"
13295 [(reg FLAGS_REG) (const_int 0)])
13296 (const_int 0)))]
13297 ""
13298 [(set (match_dup 0) (match_dup 1))]
13299{
13300 PUT_MODE (operands[1], QImode);
13301})
13302
13303(define_split
13304 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13305 (ne:QI (match_operator 1 "ix86_comparison_operator"
13306 [(reg FLAGS_REG) (const_int 0)])
13307 (const_int 0)))]
13308 ""
13309 [(set (match_dup 0) (match_dup 1))]
13310{
13311 PUT_MODE (operands[1], QImode);
13312})
13313
13314(define_split
13315 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13316 (eq:QI (match_operator 1 "ix86_comparison_operator"
13317 [(reg FLAGS_REG) (const_int 0)])
13318 (const_int 0)))]
13319 ""
13320 [(set (match_dup 0) (match_dup 1))]
13321{
13322 rtx new_op1 = copy_rtx (operands[1]);
13323 operands[1] = new_op1;
13324 PUT_MODE (new_op1, QImode);
13325 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13326 GET_MODE (XEXP (new_op1, 0))));
13327
13328 /* Make sure that (a) the CCmode we have for the flags is strong
13329 enough for the reversed compare or (b) we have a valid FP compare. */
13330 if (! ix86_comparison_operator (new_op1, VOIDmode))
13331 FAIL;
13332})
13333
13334(define_split
13335 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13336 (eq:QI (match_operator 1 "ix86_comparison_operator"
13337 [(reg FLAGS_REG) (const_int 0)])
13338 (const_int 0)))]
13339 ""
13340 [(set (match_dup 0) (match_dup 1))]
13341{
13342 rtx new_op1 = copy_rtx (operands[1]);
13343 operands[1] = new_op1;
13344 PUT_MODE (new_op1, QImode);
13345 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13346 GET_MODE (XEXP (new_op1, 0))));
13347
13348 /* Make sure that (a) the CCmode we have for the flags is strong
13349 enough for the reversed compare or (b) we have a valid FP compare. */
13350 if (! ix86_comparison_operator (new_op1, VOIDmode))
13351 FAIL;
13352})
13353
13354;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13355;; subsequent logical operations are used to imitate conditional moves.
13356;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13357;; it directly.
13358
13359(define_insn "*sse_setccsf"
13360 [(set (match_operand:SF 0 "register_operand" "=x")
13361 (match_operator:SF 1 "sse_comparison_operator"
13362 [(match_operand:SF 2 "register_operand" "0")
13363 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13364 "TARGET_SSE"
13365 "cmp%D1ss\t{%3, %0|%0, %3}"
13366 [(set_attr "type" "ssecmp")
13367 (set_attr "mode" "SF")])
13368
13369(define_insn "*sse_setccdf"
13370 [(set (match_operand:DF 0 "register_operand" "=Y")
13371 (match_operator:DF 1 "sse_comparison_operator"
13372 [(match_operand:DF 2 "register_operand" "0")
13373 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13374 "TARGET_SSE2"
13375 "cmp%D1sd\t{%3, %0|%0, %3}"
13376 [(set_attr "type" "ssecmp")
13377 (set_attr "mode" "DF")])
13378
13379;; Basic conditional jump instructions.
13380;; We ignore the overflow flag for signed branch instructions.
13381
13382;; For all bCOND expanders, also expand the compare or test insn that
13383;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13384
13385(define_expand "beq"
13386 [(set (pc)
13387 (if_then_else (match_dup 1)
13388 (label_ref (match_operand 0 "" ""))
13389 (pc)))]
13390 ""
13391 "ix86_expand_branch (EQ, operands[0]); DONE;")
13392
13393(define_expand "bne"
13394 [(set (pc)
13395 (if_then_else (match_dup 1)
13396 (label_ref (match_operand 0 "" ""))
13397 (pc)))]
13398 ""
13399 "ix86_expand_branch (NE, operands[0]); DONE;")
13400
13401(define_expand "bgt"
13402 [(set (pc)
13403 (if_then_else (match_dup 1)
13404 (label_ref (match_operand 0 "" ""))
13405 (pc)))]
13406 ""
13407 "ix86_expand_branch (GT, operands[0]); DONE;")
13408
13409(define_expand "bgtu"
13410 [(set (pc)
13411 (if_then_else (match_dup 1)
13412 (label_ref (match_operand 0 "" ""))
13413 (pc)))]
13414 ""
13415 "ix86_expand_branch (GTU, operands[0]); DONE;")
13416
13417(define_expand "blt"
13418 [(set (pc)
13419 (if_then_else (match_dup 1)
13420 (label_ref (match_operand 0 "" ""))
13421 (pc)))]
13422 ""
13423 "ix86_expand_branch (LT, operands[0]); DONE;")
13424
13425(define_expand "bltu"
13426 [(set (pc)
13427 (if_then_else (match_dup 1)
13428 (label_ref (match_operand 0 "" ""))
13429 (pc)))]
13430 ""
13431 "ix86_expand_branch (LTU, operands[0]); DONE;")
13432
13433(define_expand "bge"
13434 [(set (pc)
13435 (if_then_else (match_dup 1)
13436 (label_ref (match_operand 0 "" ""))
13437 (pc)))]
13438 ""
13439 "ix86_expand_branch (GE, operands[0]); DONE;")
13440
13441(define_expand "bgeu"
13442 [(set (pc)
13443 (if_then_else (match_dup 1)
13444 (label_ref (match_operand 0 "" ""))
13445 (pc)))]
13446 ""
13447 "ix86_expand_branch (GEU, operands[0]); DONE;")
13448
13449(define_expand "ble"
13450 [(set (pc)
13451 (if_then_else (match_dup 1)
13452 (label_ref (match_operand 0 "" ""))
13453 (pc)))]
13454 ""
13455 "ix86_expand_branch (LE, operands[0]); DONE;")
13456
13457(define_expand "bleu"
13458 [(set (pc)
13459 (if_then_else (match_dup 1)
13460 (label_ref (match_operand 0 "" ""))
13461 (pc)))]
13462 ""
13463 "ix86_expand_branch (LEU, operands[0]); DONE;")
13464
13465(define_expand "bunordered"
13466 [(set (pc)
13467 (if_then_else (match_dup 1)
13468 (label_ref (match_operand 0 "" ""))
13469 (pc)))]
13470 "TARGET_80387 || TARGET_SSE_MATH"
13471 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13472
13473(define_expand "bordered"
13474 [(set (pc)
13475 (if_then_else (match_dup 1)
13476 (label_ref (match_operand 0 "" ""))
13477 (pc)))]
13478 "TARGET_80387 || TARGET_SSE_MATH"
13479 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13480
13481(define_expand "buneq"
13482 [(set (pc)
13483 (if_then_else (match_dup 1)
13484 (label_ref (match_operand 0 "" ""))
13485 (pc)))]
13486 "TARGET_80387 || TARGET_SSE_MATH"
13487 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13488
13489(define_expand "bunge"
13490 [(set (pc)
13491 (if_then_else (match_dup 1)
13492 (label_ref (match_operand 0 "" ""))
13493 (pc)))]
13494 "TARGET_80387 || TARGET_SSE_MATH"
13495 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13496
13497(define_expand "bungt"
13498 [(set (pc)
13499 (if_then_else (match_dup 1)
13500 (label_ref (match_operand 0 "" ""))
13501 (pc)))]
13502 "TARGET_80387 || TARGET_SSE_MATH"
13503 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13504
13505(define_expand "bunle"
13506 [(set (pc)
13507 (if_then_else (match_dup 1)
13508 (label_ref (match_operand 0 "" ""))
13509 (pc)))]
13510 "TARGET_80387 || TARGET_SSE_MATH"
13511 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13512
13513(define_expand "bunlt"
13514 [(set (pc)
13515 (if_then_else (match_dup 1)
13516 (label_ref (match_operand 0 "" ""))
13517 (pc)))]
13518 "TARGET_80387 || TARGET_SSE_MATH"
13519 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13520
13521(define_expand "bltgt"
13522 [(set (pc)
13523 (if_then_else (match_dup 1)
13524 (label_ref (match_operand 0 "" ""))
13525 (pc)))]
13526 "TARGET_80387 || TARGET_SSE_MATH"
13527 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13528
13529(define_insn "*jcc_1"
13530 [(set (pc)
13531 (if_then_else (match_operator 1 "ix86_comparison_operator"
13532 [(reg FLAGS_REG) (const_int 0)])
13533 (label_ref (match_operand 0 "" ""))
13534 (pc)))]
13535 ""
13536 "%+j%C1\t%l0"
13537 [(set_attr "type" "ibr")
13538 (set_attr "modrm" "0")
13539 (set (attr "length")
13540 (if_then_else (and (ge (minus (match_dup 0) (pc))
13541 (const_int -126))
13542 (lt (minus (match_dup 0) (pc))
13543 (const_int 128)))
13544 (const_int 2)
13545 (const_int 6)))])
13546
13547(define_insn "*jcc_2"
13548 [(set (pc)
13549 (if_then_else (match_operator 1 "ix86_comparison_operator"
13550 [(reg FLAGS_REG) (const_int 0)])
13551 (pc)
13552 (label_ref (match_operand 0 "" ""))))]
13553 ""
13554 "%+j%c1\t%l0"
13555 [(set_attr "type" "ibr")
13556 (set_attr "modrm" "0")
13557 (set (attr "length")
13558 (if_then_else (and (ge (minus (match_dup 0) (pc))
13559 (const_int -126))
13560 (lt (minus (match_dup 0) (pc))
13561 (const_int 128)))
13562 (const_int 2)
13563 (const_int 6)))])
13564
13565;; In general it is not safe to assume too much about CCmode registers,
13566;; so simplify-rtx stops when it sees a second one. Under certain
13567;; conditions this is safe on x86, so help combine not create
13568;;
13569;; seta %al
13570;; testb %al, %al
13571;; je Lfoo
13572
13573(define_split
13574 [(set (pc)
13575 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13576 [(reg FLAGS_REG) (const_int 0)])
13577 (const_int 0))
13578 (label_ref (match_operand 1 "" ""))
13579 (pc)))]
13580 ""
13581 [(set (pc)
13582 (if_then_else (match_dup 0)
13583 (label_ref (match_dup 1))
13584 (pc)))]
13585{
13586 PUT_MODE (operands[0], VOIDmode);
13587})
13588
13589(define_split
13590 [(set (pc)
13591 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13592 [(reg FLAGS_REG) (const_int 0)])
13593 (const_int 0))
13594 (label_ref (match_operand 1 "" ""))
13595 (pc)))]
13596 ""
13597 [(set (pc)
13598 (if_then_else (match_dup 0)
13599 (label_ref (match_dup 1))
13600 (pc)))]
13601{
13602 rtx new_op0 = copy_rtx (operands[0]);
13603 operands[0] = new_op0;
13604 PUT_MODE (new_op0, VOIDmode);
13605 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13606 GET_MODE (XEXP (new_op0, 0))));
13607
13608 /* Make sure that (a) the CCmode we have for the flags is strong
13609 enough for the reversed compare or (b) we have a valid FP compare. */
13610 if (! ix86_comparison_operator (new_op0, VOIDmode))
13611 FAIL;
13612})
13613
13614;; Define combination compare-and-branch fp compare instructions to use
13615;; during early optimization. Splitting the operation apart early makes
13616;; for bad code when we want to reverse the operation.
13617
13618(define_insn "*fp_jcc_1_mixed"
13619 [(set (pc)
13620 (if_then_else (match_operator 0 "comparison_operator"
13621 [(match_operand 1 "register_operand" "f,x")
13622 (match_operand 2 "nonimmediate_operand" "f,xm")])
13623 (label_ref (match_operand 3 "" ""))
13624 (pc)))
13625 (clobber (reg:CCFP FPSR_REG))
13626 (clobber (reg:CCFP FLAGS_REG))]
13627 "TARGET_MIX_SSE_I387
13628 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13629 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13630 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13631 "#")
13632
13633(define_insn "*fp_jcc_1_sse"
13634 [(set (pc)
13635 (if_then_else (match_operator 0 "comparison_operator"
13636 [(match_operand 1 "register_operand" "x")
13637 (match_operand 2 "nonimmediate_operand" "xm")])
13638 (label_ref (match_operand 3 "" ""))
13639 (pc)))
13640 (clobber (reg:CCFP FPSR_REG))
13641 (clobber (reg:CCFP FLAGS_REG))]
13642 "TARGET_SSE_MATH
13643 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13644 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13645 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13646 "#")
13647
13648(define_insn "*fp_jcc_1_387"
13649 [(set (pc)
13650 (if_then_else (match_operator 0 "comparison_operator"
13651 [(match_operand 1 "register_operand" "f")
13652 (match_operand 2 "register_operand" "f")])
13653 (label_ref (match_operand 3 "" ""))
13654 (pc)))
13655 (clobber (reg:CCFP FPSR_REG))
13656 (clobber (reg:CCFP FLAGS_REG))]
13657 "TARGET_CMOVE && TARGET_80387
13658 && FLOAT_MODE_P (GET_MODE (operands[1]))
13659 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13660 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13661 "#")
13662
13663(define_insn "*fp_jcc_2_mixed"
13664 [(set (pc)
13665 (if_then_else (match_operator 0 "comparison_operator"
13666 [(match_operand 1 "register_operand" "f,x")
13667 (match_operand 2 "nonimmediate_operand" "f,xm")])
13668 (pc)
13669 (label_ref (match_operand 3 "" ""))))
13670 (clobber (reg:CCFP FPSR_REG))
13671 (clobber (reg:CCFP FLAGS_REG))]
13672 "TARGET_MIX_SSE_I387
13673 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13674 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13675 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13676 "#")
13677
13678(define_insn "*fp_jcc_2_sse"
13679 [(set (pc)
13680 (if_then_else (match_operator 0 "comparison_operator"
13681 [(match_operand 1 "register_operand" "x")
13682 (match_operand 2 "nonimmediate_operand" "xm")])
13683 (pc)
13684 (label_ref (match_operand 3 "" ""))))
13685 (clobber (reg:CCFP FPSR_REG))
13686 (clobber (reg:CCFP FLAGS_REG))]
13687 "TARGET_SSE_MATH
13688 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13689 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13690 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13691 "#")
13692
13693(define_insn "*fp_jcc_2_387"
13694 [(set (pc)
13695 (if_then_else (match_operator 0 "comparison_operator"
13696 [(match_operand 1 "register_operand" "f")
13697 (match_operand 2 "register_operand" "f")])
13698 (pc)
13699 (label_ref (match_operand 3 "" ""))))
13700 (clobber (reg:CCFP FPSR_REG))
13701 (clobber (reg:CCFP FLAGS_REG))]
13702 "TARGET_CMOVE && TARGET_80387
13703 && FLOAT_MODE_P (GET_MODE (operands[1]))
13704 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13705 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13706 "#")
13707
13708(define_insn "*fp_jcc_3_387"
13709 [(set (pc)
13710 (if_then_else (match_operator 0 "comparison_operator"
13711 [(match_operand 1 "register_operand" "f")
13712 (match_operand 2 "nonimmediate_operand" "fm")])
13713 (label_ref (match_operand 3 "" ""))
13714 (pc)))
13715 (clobber (reg:CCFP FPSR_REG))
13716 (clobber (reg:CCFP FLAGS_REG))
13717 (clobber (match_scratch:HI 4 "=a"))]
13718 "TARGET_80387
13719 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13720 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13721 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13722 && SELECT_CC_MODE (GET_CODE (operands[0]),
13723 operands[1], operands[2]) == CCFPmode
13724 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725 "#")
13726
13727(define_insn "*fp_jcc_4_387"
13728 [(set (pc)
13729 (if_then_else (match_operator 0 "comparison_operator"
13730 [(match_operand 1 "register_operand" "f")
13731 (match_operand 2 "nonimmediate_operand" "fm")])
13732 (pc)
13733 (label_ref (match_operand 3 "" ""))))
13734 (clobber (reg:CCFP FPSR_REG))
13735 (clobber (reg:CCFP FLAGS_REG))
13736 (clobber (match_scratch:HI 4 "=a"))]
13737 "TARGET_80387
13738 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13739 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13740 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13741 && SELECT_CC_MODE (GET_CODE (operands[0]),
13742 operands[1], operands[2]) == CCFPmode
13743 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13744 "#")
13745
13746(define_insn "*fp_jcc_5_387"
13747 [(set (pc)
13748 (if_then_else (match_operator 0 "comparison_operator"
13749 [(match_operand 1 "register_operand" "f")
13750 (match_operand 2 "register_operand" "f")])
13751 (label_ref (match_operand 3 "" ""))
13752 (pc)))
13753 (clobber (reg:CCFP FPSR_REG))
13754 (clobber (reg:CCFP FLAGS_REG))
13755 (clobber (match_scratch:HI 4 "=a"))]
13756 "TARGET_80387
13757 && FLOAT_MODE_P (GET_MODE (operands[1]))
13758 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13759 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13760 "#")
13761
13762(define_insn "*fp_jcc_6_387"
13763 [(set (pc)
13764 (if_then_else (match_operator 0 "comparison_operator"
13765 [(match_operand 1 "register_operand" "f")
13766 (match_operand 2 "register_operand" "f")])
13767 (pc)
13768 (label_ref (match_operand 3 "" ""))))
13769 (clobber (reg:CCFP FPSR_REG))
13770 (clobber (reg:CCFP FLAGS_REG))
13771 (clobber (match_scratch:HI 4 "=a"))]
13772 "TARGET_80387
13773 && FLOAT_MODE_P (GET_MODE (operands[1]))
13774 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13775 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13776 "#")
13777
13778(define_insn "*fp_jcc_7_387"
13779 [(set (pc)
13780 (if_then_else (match_operator 0 "comparison_operator"
13781 [(match_operand 1 "register_operand" "f")
13782 (match_operand 2 "const0_operand" "X")])
13783 (label_ref (match_operand 3 "" ""))
13784 (pc)))
13785 (clobber (reg:CCFP FPSR_REG))
13786 (clobber (reg:CCFP FLAGS_REG))
13787 (clobber (match_scratch:HI 4 "=a"))]
13788 "TARGET_80387
13789 && FLOAT_MODE_P (GET_MODE (operands[1]))
13790 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13791 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13792 && SELECT_CC_MODE (GET_CODE (operands[0]),
13793 operands[1], operands[2]) == CCFPmode
13794 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13795 "#")
13796
13797;; The order of operands in *fp_jcc_8_387 is forced by combine in
13798;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13799;; with a precedence over other operators and is always put in the first
13800;; place. Swap condition and operands to match ficom instruction.
13801
13802(define_insn "*fp_jcc_8<mode>_387"
13803 [(set (pc)
13804 (if_then_else (match_operator 0 "comparison_operator"
13805 [(match_operator 1 "float_operator"
13806 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13807 (match_operand 3 "register_operand" "f,f")])
13808 (label_ref (match_operand 4 "" ""))
13809 (pc)))
13810 (clobber (reg:CCFP FPSR_REG))
13811 (clobber (reg:CCFP FLAGS_REG))
13812 (clobber (match_scratch:HI 5 "=a,a"))]
13813 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13814 && FLOAT_MODE_P (GET_MODE (operands[3]))
13815 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13816 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13817 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13818 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13819 "#")
13820
13821(define_split
13822 [(set (pc)
13823 (if_then_else (match_operator 0 "comparison_operator"
13824 [(match_operand 1 "register_operand" "")
13825 (match_operand 2 "nonimmediate_operand" "")])
13826 (match_operand 3 "" "")
13827 (match_operand 4 "" "")))
13828 (clobber (reg:CCFP FPSR_REG))
13829 (clobber (reg:CCFP FLAGS_REG))]
13830 "reload_completed"
13831 [(const_int 0)]
13832{
13833 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13834 operands[3], operands[4], NULL_RTX, NULL_RTX);
13835 DONE;
13836})
13837
13838(define_split
13839 [(set (pc)
13840 (if_then_else (match_operator 0 "comparison_operator"
13841 [(match_operand 1 "register_operand" "")
13842 (match_operand 2 "general_operand" "")])
13843 (match_operand 3 "" "")
13844 (match_operand 4 "" "")))
13845 (clobber (reg:CCFP FPSR_REG))
13846 (clobber (reg:CCFP FLAGS_REG))
13847 (clobber (match_scratch:HI 5 "=a"))]
13848 "reload_completed"
13849 [(const_int 0)]
13850{
13851 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13852 operands[3], operands[4], operands[5], NULL_RTX);
13853 DONE;
13854})
13855
13856(define_split
13857 [(set (pc)
13858 (if_then_else (match_operator 0 "comparison_operator"
13859 [(match_operator 1 "float_operator"
13860 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13861 (match_operand 3 "register_operand" "")])
13862 (match_operand 4 "" "")
13863 (match_operand 5 "" "")))
13864 (clobber (reg:CCFP FPSR_REG))
13865 (clobber (reg:CCFP FLAGS_REG))
13866 (clobber (match_scratch:HI 6 "=a"))]
13867 "reload_completed"
13868 [(const_int 0)]
13869{
13870 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13871 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13872 operands[3], operands[7],
13873 operands[4], operands[5], operands[6], NULL_RTX);
13874 DONE;
13875})
13876
13877;; %%% Kill this when reload knows how to do it.
13878(define_split
13879 [(set (pc)
13880 (if_then_else (match_operator 0 "comparison_operator"
13881 [(match_operator 1 "float_operator"
13882 [(match_operand:X87MODEI12 2 "register_operand" "")])
13883 (match_operand 3 "register_operand" "")])
13884 (match_operand 4 "" "")
13885 (match_operand 5 "" "")))
13886 (clobber (reg:CCFP FPSR_REG))
13887 (clobber (reg:CCFP FLAGS_REG))
13888 (clobber (match_scratch:HI 6 "=a"))]
13889 "reload_completed"
13890 [(const_int 0)]
13891{
13892 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13893 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13894 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13895 operands[3], operands[7],
13896 operands[4], operands[5], operands[6], operands[2]);
13897 DONE;
13898})
13899
13900;; Unconditional and other jump instructions
13901
13902(define_insn "jump"
13903 [(set (pc)
13904 (label_ref (match_operand 0 "" "")))]
13905 ""
13906 "jmp\t%l0"
13907 [(set_attr "type" "ibr")
13908 (set (attr "length")
13909 (if_then_else (and (ge (minus (match_dup 0) (pc))
13910 (const_int -126))
13911 (lt (minus (match_dup 0) (pc))
13912 (const_int 128)))
13913 (const_int 2)
13914 (const_int 5)))
13915 (set_attr "modrm" "0")])
13916
13917(define_expand "indirect_jump"
13918 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13919 ""
13920 "")
13921
13922(define_insn "*indirect_jump"
13923 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13924 "!TARGET_64BIT"
13925 "jmp\t%A0"
13926 [(set_attr "type" "ibr")
13927 (set_attr "length_immediate" "0")])
13928
13929(define_insn "*indirect_jump_rtx64"
13930 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13931 "TARGET_64BIT"
13932 "jmp\t%A0"
13933 [(set_attr "type" "ibr")
13934 (set_attr "length_immediate" "0")])
13935
13936(define_expand "tablejump"
13937 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13938 (use (label_ref (match_operand 1 "" "")))])]
13939 ""
13940{
13941 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13942 relative. Convert the relative address to an absolute address. */
13943 if (flag_pic)
13944 {
13945 rtx op0, op1;
13946 enum rtx_code code;
13947
13948 if (TARGET_64BIT)
13949 {
13950 code = PLUS;
13951 op0 = operands[0];
13952 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13953 }
13954 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13955 {
13956 code = PLUS;
13957 op0 = operands[0];
13958 op1 = pic_offset_table_rtx;
13959 }
13960 else
13961 {
13962 code = MINUS;
13963 op0 = pic_offset_table_rtx;
13964 op1 = operands[0];
13965 }
13966
13967 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13968 OPTAB_DIRECT);
13969 }
13970})
13971
13972(define_insn "*tablejump_1"
13973 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13974 (use (label_ref (match_operand 1 "" "")))]
13975 "!TARGET_64BIT"
13976 "jmp\t%A0"
13977 [(set_attr "type" "ibr")
13978 (set_attr "length_immediate" "0")])
13979
13980(define_insn "*tablejump_1_rtx64"
13981 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13982 (use (label_ref (match_operand 1 "" "")))]
13983 "TARGET_64BIT"
13984 "jmp\t%A0"
13985 [(set_attr "type" "ibr")
13986 (set_attr "length_immediate" "0")])
13987
13988;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13989
13990(define_peephole2
13991 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13992 (set (match_operand:QI 1 "register_operand" "")
13993 (match_operator:QI 2 "ix86_comparison_operator"
13994 [(reg FLAGS_REG) (const_int 0)]))
13995 (set (match_operand 3 "q_regs_operand" "")
13996 (zero_extend (match_dup 1)))]
13997 "(peep2_reg_dead_p (3, operands[1])
13998 || operands_match_p (operands[1], operands[3]))
13999 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14000 [(set (match_dup 4) (match_dup 0))
14001 (set (strict_low_part (match_dup 5))
14002 (match_dup 2))]
14003{
14004 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14005 operands[5] = gen_lowpart (QImode, operands[3]);
14006 ix86_expand_clear (operands[3]);
14007})
14008
14009;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14010
14011(define_peephole2
14012 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14013 (set (match_operand:QI 1 "register_operand" "")
14014 (match_operator:QI 2 "ix86_comparison_operator"
14015 [(reg FLAGS_REG) (const_int 0)]))
14016 (parallel [(set (match_operand 3 "q_regs_operand" "")
14017 (zero_extend (match_dup 1)))
14018 (clobber (reg:CC FLAGS_REG))])]
14019 "(peep2_reg_dead_p (3, operands[1])
14020 || operands_match_p (operands[1], operands[3]))
14021 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14022 [(set (match_dup 4) (match_dup 0))
14023 (set (strict_low_part (match_dup 5))
14024 (match_dup 2))]
14025{
14026 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14027 operands[5] = gen_lowpart (QImode, operands[3]);
14028 ix86_expand_clear (operands[3]);
14029})
14030
14031;; Call instructions.
14032
14033;; The predicates normally associated with named expanders are not properly
14034;; checked for calls. This is a bug in the generic code, but it isn't that
14035;; easy to fix. Ignore it for now and be prepared to fix things up.
14036
14037;; Call subroutine returning no value.
14038
14039(define_expand "call_pop"
14040 [(parallel [(call (match_operand:QI 0 "" "")
14041 (match_operand:SI 1 "" ""))
14042 (set (reg:SI SP_REG)
14043 (plus:SI (reg:SI SP_REG)
14044 (match_operand:SI 3 "" "")))])]
14045 "!TARGET_64BIT"
14046{
14047 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14048 DONE;
14049})
14050
14051(define_insn "*call_pop_0"
14052 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14053 (match_operand:SI 1 "" ""))
14054 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14055 (match_operand:SI 2 "immediate_operand" "")))]
14056 "!TARGET_64BIT"
14057{
14058 if (SIBLING_CALL_P (insn))
14059 return "jmp\t%P0";
14060 else
14061 return "call\t%P0";
14062}
14063 [(set_attr "type" "call")])
14064
14065(define_insn "*call_pop_1"
14066 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14067 (match_operand:SI 1 "" ""))
14068 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14069 (match_operand:SI 2 "immediate_operand" "i")))]
14070 "!TARGET_64BIT"
14071{
14072 if (constant_call_address_operand (operands[0], Pmode))
14073 {
14074 if (SIBLING_CALL_P (insn))
14075 return "jmp\t%P0";
14076 else
14077 return "call\t%P0";
14078 }
14079 if (SIBLING_CALL_P (insn))
14080 return "jmp\t%A0";
14081 else
14082 return "call\t%A0";
14083}
14084 [(set_attr "type" "call")])
14085
14086(define_expand "call"
14087 [(call (match_operand:QI 0 "" "")
14088 (match_operand 1 "" ""))
14089 (use (match_operand 2 "" ""))]
14090 ""
14091{
14092 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14093 DONE;
14094})
14095
14096(define_expand "sibcall"
14097 [(call (match_operand:QI 0 "" "")
14098 (match_operand 1 "" ""))
14099 (use (match_operand 2 "" ""))]
14100 ""
14101{
14102 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14103 DONE;
14104})
14105
14106(define_insn "*call_0"
14107 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14108 (match_operand 1 "" ""))]
14109 ""
14110{
14111 if (SIBLING_CALL_P (insn))
14112 return "jmp\t%P0";
14113 else
14114 return "call\t%P0";
14115}
14116 [(set_attr "type" "call")])
14117
14118(define_insn "*call_1"
14119 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14120 (match_operand 1 "" ""))]
14121 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14122{
14123 if (constant_call_address_operand (operands[0], Pmode))
14124 return "call\t%P0";
14125 return "call\t%A0";
14126}
14127 [(set_attr "type" "call")])
14128
14129(define_insn "*sibcall_1"
14130 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14131 (match_operand 1 "" ""))]
14132 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14133{
14134 if (constant_call_address_operand (operands[0], Pmode))
14135 return "jmp\t%P0";
14136 return "jmp\t%A0";
14137}
14138 [(set_attr "type" "call")])
14139
14140(define_insn "*call_1_rex64"
14141 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14142 (match_operand 1 "" ""))]
14143 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14144{
14145 if (constant_call_address_operand (operands[0], Pmode))
14146 return "call\t%P0";
14147 return "call\t%A0";
14148}
14149 [(set_attr "type" "call")])
14150
14151(define_insn "*sibcall_1_rex64"
14152 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14153 (match_operand 1 "" ""))]
14154 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14155 "jmp\t%P0"
14156 [(set_attr "type" "call")])
14157
14158(define_insn "*sibcall_1_rex64_v"
14159 [(call (mem:QI (reg:DI 40))
14160 (match_operand 0 "" ""))]
14161 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14162 "jmp\t*%%r11"
14163 [(set_attr "type" "call")])
14164
14165
14166;; Call subroutine, returning value in operand 0
14167
14168(define_expand "call_value_pop"
14169 [(parallel [(set (match_operand 0 "" "")
14170 (call (match_operand:QI 1 "" "")
14171 (match_operand:SI 2 "" "")))
14172 (set (reg:SI SP_REG)
14173 (plus:SI (reg:SI SP_REG)
14174 (match_operand:SI 4 "" "")))])]
14175 "!TARGET_64BIT"
14176{
14177 ix86_expand_call (operands[0], operands[1], operands[2],
14178 operands[3], operands[4], 0);
14179 DONE;
14180})
14181
14182(define_expand "call_value"
14183 [(set (match_operand 0 "" "")
14184 (call (match_operand:QI 1 "" "")
14185 (match_operand:SI 2 "" "")))
14186 (use (match_operand:SI 3 "" ""))]
14187 ;; Operand 2 not used on the i386.
14188 ""
14189{
14190 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14191 DONE;
14192})
14193
14194(define_expand "sibcall_value"
14195 [(set (match_operand 0 "" "")
14196 (call (match_operand:QI 1 "" "")
14197 (match_operand:SI 2 "" "")))
14198 (use (match_operand:SI 3 "" ""))]
14199 ;; Operand 2 not used on the i386.
14200 ""
14201{
14202 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14203 DONE;
14204})
14205
14206;; Call subroutine returning any type.
14207
14208(define_expand "untyped_call"
14209 [(parallel [(call (match_operand 0 "" "")
14210 (const_int 0))
14211 (match_operand 1 "" "")
14212 (match_operand 2 "" "")])]
14213 ""
14214{
14215 int i;
14216
14217 /* In order to give reg-stack an easier job in validating two
14218 coprocessor registers as containing a possible return value,
14219 simply pretend the untyped call returns a complex long double
14220 value. */
14221
14222 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14223 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14224 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14225 NULL, 0);
14226
14227 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14228 {
14229 rtx set = XVECEXP (operands[2], 0, i);
14230 emit_move_insn (SET_DEST (set), SET_SRC (set));
14231 }
14232
14233 /* The optimizer does not know that the call sets the function value
14234 registers we stored in the result block. We avoid problems by
14235 claiming that all hard registers are used and clobbered at this
14236 point. */
14237 emit_insn (gen_blockage (const0_rtx));
14238
14239 DONE;
14240})
14241
14242;; Prologue and epilogue instructions
14243
14244;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14245;; all of memory. This blocks insns from being moved across this point.
14246
14247(define_insn "blockage"
14248 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14249 ""
14250 ""
14251 [(set_attr "length" "0")])
14252
14253;; Insn emitted into the body of a function to return from a function.
14254;; This is only done if the function's epilogue is known to be simple.
14255;; See comments for ix86_can_use_return_insn_p in i386.c.
14256
14257(define_expand "return"
14258 [(return)]
14259 "ix86_can_use_return_insn_p ()"
14260{
14261 if (current_function_pops_args)
14262 {
14263 rtx popc = GEN_INT (current_function_pops_args);
14264 emit_jump_insn (gen_return_pop_internal (popc));
14265 DONE;
14266 }
14267})
14268
14269(define_insn "return_internal"
14270 [(return)]
14271 "reload_completed"
14272 "ret"
14273 [(set_attr "length" "1")
14274 (set_attr "length_immediate" "0")
14275 (set_attr "modrm" "0")])
14276
14277;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14278;; instruction Athlon and K8 have.
14279
14280(define_insn "return_internal_long"
14281 [(return)
14282 (unspec [(const_int 0)] UNSPEC_REP)]
14283 "reload_completed"
14284 "rep {;} ret"
14285 [(set_attr "length" "1")
14286 (set_attr "length_immediate" "0")
14287 (set_attr "prefix_rep" "1")
14288 (set_attr "modrm" "0")])
14289
14290(define_insn "return_pop_internal"
14291 [(return)
14292 (use (match_operand:SI 0 "const_int_operand" ""))]
14293 "reload_completed"
14294 "ret\t%0"
14295 [(set_attr "length" "3")
14296 (set_attr "length_immediate" "2")
14297 (set_attr "modrm" "0")])
14298
14299(define_insn "return_indirect_internal"
14300 [(return)
14301 (use (match_operand:SI 0 "register_operand" "r"))]
14302 "reload_completed"
14303 "jmp\t%A0"
14304 [(set_attr "type" "ibr")
14305 (set_attr "length_immediate" "0")])
14306
14307(define_insn "nop"
14308 [(const_int 0)]
14309 ""
14310 "nop"
14311 [(set_attr "length" "1")
14312 (set_attr "length_immediate" "0")
14313 (set_attr "modrm" "0")])
14314
14315;; Align to 16-byte boundary, max skip in op0. Used to avoid
14316;; branch prediction penalty for the third jump in a 16-byte
14317;; block on K8.
14318
14319(define_insn "align"
14320 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14321 ""
14322{
14323#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14324 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14325#else
14326 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14327 The align insn is used to avoid 3 jump instructions in the row to improve
14328 branch prediction and the benefits hardly outweigh the cost of extra 8
14329 nops on the average inserted by full alignment pseudo operation. */
14330#endif
14331 return "";
14332}
14333 [(set_attr "length" "16")])
14334
14335(define_expand "prologue"
14336 [(const_int 1)]
14337 ""
14338 "ix86_expand_prologue (); DONE;")
14339
14340(define_insn "set_got"
14341 [(set (match_operand:SI 0 "register_operand" "=r")
14342 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14343 (clobber (reg:CC FLAGS_REG))]
14344 "!TARGET_64BIT"
14345 { return output_set_got (operands[0], NULL_RTX); }
14346 [(set_attr "type" "multi")
14347 (set_attr "length" "12")])
14348
14349(define_insn "set_got_labelled"
14350 [(set (match_operand:SI 0 "register_operand" "=r")
14351 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14352 UNSPEC_SET_GOT))
14353 (clobber (reg:CC FLAGS_REG))]
14354 "!TARGET_64BIT"
14355 { return output_set_got (operands[0], operands[1]); }
14356 [(set_attr "type" "multi")
14357 (set_attr "length" "12")])
14358
14359(define_insn "set_got_rex64"
14360 [(set (match_operand:DI 0 "register_operand" "=r")
14361 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14362 "TARGET_64BIT"
14363 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14364 [(set_attr "type" "lea")
14365 (set_attr "length" "6")])
14366
14367(define_expand "epilogue"
14368 [(const_int 1)]
14369 ""
14370 "ix86_expand_epilogue (1); DONE;")
14371
14372(define_expand "sibcall_epilogue"
14373 [(const_int 1)]
14374 ""
14375 "ix86_expand_epilogue (0); DONE;")
14376
14377(define_expand "eh_return"
14378 [(use (match_operand 0 "register_operand" ""))]
14379 ""
14380{
14381 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14382
14383 /* Tricky bit: we write the address of the handler to which we will
14384 be returning into someone else's stack frame, one word below the
14385 stack address we wish to restore. */
14386 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14387 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14388 tmp = gen_rtx_MEM (Pmode, tmp);
14389 emit_move_insn (tmp, ra);
14390
14391 if (Pmode == SImode)
14392 emit_jump_insn (gen_eh_return_si (sa));
14393 else
14394 emit_jump_insn (gen_eh_return_di (sa));
14395 emit_barrier ();
14396 DONE;
14397})
14398
14399(define_insn_and_split "eh_return_si"
14400 [(set (pc)
14401 (unspec [(match_operand:SI 0 "register_operand" "c")]
14402 UNSPEC_EH_RETURN))]
14403 "!TARGET_64BIT"
14404 "#"
14405 "reload_completed"
14406 [(const_int 1)]
14407 "ix86_expand_epilogue (2); DONE;")
14408
14409(define_insn_and_split "eh_return_di"
14410 [(set (pc)
14411 (unspec [(match_operand:DI 0 "register_operand" "c")]
14412 UNSPEC_EH_RETURN))]
14413 "TARGET_64BIT"
14414 "#"
14415 "reload_completed"
14416 [(const_int 1)]
14417 "ix86_expand_epilogue (2); DONE;")
14418
14419(define_insn "leave"
14420 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14421 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14422 (clobber (mem:BLK (scratch)))]
14423 "!TARGET_64BIT"
14424 "leave"
14425 [(set_attr "type" "leave")])
14426
14427(define_insn "leave_rex64"
14428 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14429 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14430 (clobber (mem:BLK (scratch)))]
14431 "TARGET_64BIT"
14432 "leave"
14433 [(set_attr "type" "leave")])
14434
14435(define_expand "ffssi2"
14436 [(parallel
14437 [(set (match_operand:SI 0 "register_operand" "")
14438 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14439 (clobber (match_scratch:SI 2 ""))
14440 (clobber (reg:CC FLAGS_REG))])]
14441 ""
14442 "")
14443
14444(define_insn_and_split "*ffs_cmove"
14445 [(set (match_operand:SI 0 "register_operand" "=r")
14446 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14447 (clobber (match_scratch:SI 2 "=&r"))
14448 (clobber (reg:CC FLAGS_REG))]
14449 "TARGET_CMOVE"
14450 "#"
14451 "&& reload_completed"
14452 [(set (match_dup 2) (const_int -1))
14453 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14454 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14455 (set (match_dup 0) (if_then_else:SI
14456 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14457 (match_dup 2)
14458 (match_dup 0)))
14459 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14460 (clobber (reg:CC FLAGS_REG))])]
14461 "")
14462
14463(define_insn_and_split "*ffs_no_cmove"
14464 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14465 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14466 (clobber (match_scratch:SI 2 "=&q"))
14467 (clobber (reg:CC FLAGS_REG))]
14468 ""
14469 "#"
14470 "reload_completed"
14471 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14472 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14473 (set (strict_low_part (match_dup 3))
14474 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14475 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14476 (clobber (reg:CC FLAGS_REG))])
14477 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14478 (clobber (reg:CC FLAGS_REG))])
14479 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14480 (clobber (reg:CC FLAGS_REG))])]
14481{
14482 operands[3] = gen_lowpart (QImode, operands[2]);
14483 ix86_expand_clear (operands[2]);
14484})
14485
14486(define_insn "*ffssi_1"
14487 [(set (reg:CCZ FLAGS_REG)
14488 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14489 (const_int 0)))
14490 (set (match_operand:SI 0 "register_operand" "=r")
14491 (ctz:SI (match_dup 1)))]
14492 ""
14493 "bsf{l}\t{%1, %0|%0, %1}"
14494 [(set_attr "prefix_0f" "1")])
14495
14496(define_expand "ffsdi2"
14497 [(parallel
14498 [(set (match_operand:DI 0 "register_operand" "")
14499 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14500 (clobber (match_scratch:DI 2 ""))
14501 (clobber (reg:CC FLAGS_REG))])]
14502 "TARGET_64BIT && TARGET_CMOVE"
14503 "")
14504
14505(define_insn_and_split "*ffs_rex64"
14506 [(set (match_operand:DI 0 "register_operand" "=r")
14507 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14508 (clobber (match_scratch:DI 2 "=&r"))
14509 (clobber (reg:CC FLAGS_REG))]
14510 "TARGET_64BIT && TARGET_CMOVE"
14511 "#"
14512 "&& reload_completed"
14513 [(set (match_dup 2) (const_int -1))
14514 (parallel [(set (reg:CCZ FLAGS_REG)
14515 (compare:CCZ (match_dup 1) (const_int 0)))
14516 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14517 (set (match_dup 0) (if_then_else:DI
14518 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14519 (match_dup 2)
14520 (match_dup 0)))
14521 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14522 (clobber (reg:CC FLAGS_REG))])]
14523 "")
14524
14525(define_insn "*ffsdi_1"
14526 [(set (reg:CCZ FLAGS_REG)
14527 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14528 (const_int 0)))
14529 (set (match_operand:DI 0 "register_operand" "=r")
14530 (ctz:DI (match_dup 1)))]
14531 "TARGET_64BIT"
14532 "bsf{q}\t{%1, %0|%0, %1}"
14533 [(set_attr "prefix_0f" "1")])
14534
14535(define_insn "ctzsi2"
14536 [(set (match_operand:SI 0 "register_operand" "=r")
14537 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14538 (clobber (reg:CC FLAGS_REG))]
14539 ""
14540 "bsf{l}\t{%1, %0|%0, %1}"
14541 [(set_attr "prefix_0f" "1")])
14542
14543(define_insn "ctzdi2"
14544 [(set (match_operand:DI 0 "register_operand" "=r")
14545 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14546 (clobber (reg:CC FLAGS_REG))]
14547 "TARGET_64BIT"
14548 "bsf{q}\t{%1, %0|%0, %1}"
14549 [(set_attr "prefix_0f" "1")])
14550
14551(define_expand "clzsi2"
14552 [(parallel
14553 [(set (match_operand:SI 0 "register_operand" "")
14554 (minus:SI (const_int 31)
14555 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14556 (clobber (reg:CC FLAGS_REG))])
14557 (parallel
14558 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14559 (clobber (reg:CC FLAGS_REG))])]
14560 ""
11384
11385(define_expand "ashrdi3"
11386 [(set (match_operand:DI 0 "shiftdi_operand" "")
11387 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11388 (match_operand:QI 2 "nonmemory_operand" "")))]
11389 ""
11390 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11391
11392(define_insn "*ashrdi3_63_rex64"
11393 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11394 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11395 (match_operand:DI 2 "const_int_operand" "i,i")))
11396 (clobber (reg:CC FLAGS_REG))]
11397 "TARGET_64BIT && INTVAL (operands[2]) == 63
11398 && (TARGET_USE_CLTD || optimize_size)
11399 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11400 "@
11401 {cqto|cqo}
11402 sar{q}\t{%2, %0|%0, %2}"
11403 [(set_attr "type" "imovx,ishift")
11404 (set_attr "prefix_0f" "0,*")
11405 (set_attr "length_immediate" "0,*")
11406 (set_attr "modrm" "0,1")
11407 (set_attr "mode" "DI")])
11408
11409(define_insn "*ashrdi3_1_one_bit_rex64"
11410 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412 (match_operand:QI 2 "const1_operand" "")))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11415 && (TARGET_SHIFT1 || optimize_size)"
11416 "sar{q}\t%0"
11417 [(set_attr "type" "ishift")
11418 (set (attr "length")
11419 (if_then_else (match_operand:DI 0 "register_operand" "")
11420 (const_string "2")
11421 (const_string "*")))])
11422
11423(define_insn "*ashrdi3_1_rex64"
11424 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11425 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11426 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11427 (clobber (reg:CC FLAGS_REG))]
11428 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11429 "@
11430 sar{q}\t{%2, %0|%0, %2}
11431 sar{q}\t{%b2, %0|%0, %b2}"
11432 [(set_attr "type" "ishift")
11433 (set_attr "mode" "DI")])
11434
11435;; This pattern can't accept a variable shift count, since shifts by
11436;; zero don't affect the flags. We assume that shifts by constant
11437;; zero are optimized away.
11438(define_insn "*ashrdi3_one_bit_cmp_rex64"
11439 [(set (reg FLAGS_REG)
11440 (compare
11441 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11442 (match_operand:QI 2 "const1_operand" ""))
11443 (const_int 0)))
11444 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11445 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11446 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11447 && (TARGET_SHIFT1 || optimize_size)
11448 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11449 "sar{q}\t%0"
11450 [(set_attr "type" "ishift")
11451 (set (attr "length")
11452 (if_then_else (match_operand:DI 0 "register_operand" "")
11453 (const_string "2")
11454 (const_string "*")))])
11455
11456(define_insn "*ashrdi3_one_bit_cconly_rex64"
11457 [(set (reg FLAGS_REG)
11458 (compare
11459 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11460 (match_operand:QI 2 "const1_operand" ""))
11461 (const_int 0)))
11462 (clobber (match_scratch:DI 0 "=r"))]
11463 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11464 && (TARGET_SHIFT1 || optimize_size)
11465 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11466 "sar{q}\t%0"
11467 [(set_attr "type" "ishift")
11468 (set_attr "length" "2")])
11469
11470;; This pattern can't accept a variable shift count, since shifts by
11471;; zero don't affect the flags. We assume that shifts by constant
11472;; zero are optimized away.
11473(define_insn "*ashrdi3_cmp_rex64"
11474 [(set (reg FLAGS_REG)
11475 (compare
11476 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477 (match_operand:QI 2 "const_int_operand" "n"))
11478 (const_int 0)))
11479 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11480 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11481 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11482 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11483 && (optimize_size
11484 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11485 "sar{q}\t{%2, %0|%0, %2}"
11486 [(set_attr "type" "ishift")
11487 (set_attr "mode" "DI")])
11488
11489(define_insn "*ashrdi3_cconly_rex64"
11490 [(set (reg FLAGS_REG)
11491 (compare
11492 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11493 (match_operand:QI 2 "const_int_operand" "n"))
11494 (const_int 0)))
11495 (clobber (match_scratch:DI 0 "=r"))]
11496 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11497 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11498 && (optimize_size
11499 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11500 "sar{q}\t{%2, %0|%0, %2}"
11501 [(set_attr "type" "ishift")
11502 (set_attr "mode" "DI")])
11503
11504(define_insn "*ashrdi3_1"
11505 [(set (match_operand:DI 0 "register_operand" "=r")
11506 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11507 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11508 (clobber (reg:CC FLAGS_REG))]
11509 "!TARGET_64BIT"
11510 "#"
11511 [(set_attr "type" "multi")])
11512
11513;; By default we don't ask for a scratch register, because when DImode
11514;; values are manipulated, registers are already at a premium. But if
11515;; we have one handy, we won't turn it away.
11516(define_peephole2
11517 [(match_scratch:SI 3 "r")
11518 (parallel [(set (match_operand:DI 0 "register_operand" "")
11519 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11520 (match_operand:QI 2 "nonmemory_operand" "")))
11521 (clobber (reg:CC FLAGS_REG))])
11522 (match_dup 3)]
11523 "!TARGET_64BIT && TARGET_CMOVE"
11524 [(const_int 0)]
11525 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11526
11527(define_split
11528 [(set (match_operand:DI 0 "register_operand" "")
11529 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11530 (match_operand:QI 2 "nonmemory_operand" "")))
11531 (clobber (reg:CC FLAGS_REG))]
11532 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11533 ? flow2_completed : reload_completed)"
11534 [(const_int 0)]
11535 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11536
11537(define_insn "x86_shrd_1"
11538 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11539 (ior:SI (ashiftrt:SI (match_dup 0)
11540 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11541 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11542 (minus:QI (const_int 32) (match_dup 2)))))
11543 (clobber (reg:CC FLAGS_REG))]
11544 ""
11545 "@
11546 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11547 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11548 [(set_attr "type" "ishift")
11549 (set_attr "prefix_0f" "1")
11550 (set_attr "pent_pair" "np")
11551 (set_attr "mode" "SI")])
11552
11553(define_expand "x86_shift_adj_3"
11554 [(use (match_operand:SI 0 "register_operand" ""))
11555 (use (match_operand:SI 1 "register_operand" ""))
11556 (use (match_operand:QI 2 "register_operand" ""))]
11557 ""
11558{
11559 rtx label = gen_label_rtx ();
11560 rtx tmp;
11561
11562 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11563
11564 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11565 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11566 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11567 gen_rtx_LABEL_REF (VOIDmode, label),
11568 pc_rtx);
11569 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11570 JUMP_LABEL (tmp) = label;
11571
11572 emit_move_insn (operands[0], operands[1]);
11573 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11574
11575 emit_label (label);
11576 LABEL_NUSES (label) = 1;
11577
11578 DONE;
11579})
11580
11581(define_insn "ashrsi3_31"
11582 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11583 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11584 (match_operand:SI 2 "const_int_operand" "i,i")))
11585 (clobber (reg:CC FLAGS_REG))]
11586 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11587 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11588 "@
11589 {cltd|cdq}
11590 sar{l}\t{%2, %0|%0, %2}"
11591 [(set_attr "type" "imovx,ishift")
11592 (set_attr "prefix_0f" "0,*")
11593 (set_attr "length_immediate" "0,*")
11594 (set_attr "modrm" "0,1")
11595 (set_attr "mode" "SI")])
11596
11597(define_insn "*ashrsi3_31_zext"
11598 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11599 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11600 (match_operand:SI 2 "const_int_operand" "i,i"))))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11603 && INTVAL (operands[2]) == 31
11604 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11605 "@
11606 {cltd|cdq}
11607 sar{l}\t{%2, %k0|%k0, %2}"
11608 [(set_attr "type" "imovx,ishift")
11609 (set_attr "prefix_0f" "0,*")
11610 (set_attr "length_immediate" "0,*")
11611 (set_attr "modrm" "0,1")
11612 (set_attr "mode" "SI")])
11613
11614(define_expand "ashrsi3"
11615 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11616 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11617 (match_operand:QI 2 "nonmemory_operand" "")))
11618 (clobber (reg:CC FLAGS_REG))]
11619 ""
11620 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11621
11622(define_insn "*ashrsi3_1_one_bit"
11623 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11624 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11625 (match_operand:QI 2 "const1_operand" "")))
11626 (clobber (reg:CC FLAGS_REG))]
11627 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11628 && (TARGET_SHIFT1 || optimize_size)"
11629 "sar{l}\t%0"
11630 [(set_attr "type" "ishift")
11631 (set (attr "length")
11632 (if_then_else (match_operand:SI 0 "register_operand" "")
11633 (const_string "2")
11634 (const_string "*")))])
11635
11636(define_insn "*ashrsi3_1_one_bit_zext"
11637 [(set (match_operand:DI 0 "register_operand" "=r")
11638 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11639 (match_operand:QI 2 "const1_operand" ""))))
11640 (clobber (reg:CC FLAGS_REG))]
11641 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11642 && (TARGET_SHIFT1 || optimize_size)"
11643 "sar{l}\t%k0"
11644 [(set_attr "type" "ishift")
11645 (set_attr "length" "2")])
11646
11647(define_insn "*ashrsi3_1"
11648 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11649 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11650 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11651 (clobber (reg:CC FLAGS_REG))]
11652 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653 "@
11654 sar{l}\t{%2, %0|%0, %2}
11655 sar{l}\t{%b2, %0|%0, %b2}"
11656 [(set_attr "type" "ishift")
11657 (set_attr "mode" "SI")])
11658
11659(define_insn "*ashrsi3_1_zext"
11660 [(set (match_operand:DI 0 "register_operand" "=r,r")
11661 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11662 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11663 (clobber (reg:CC FLAGS_REG))]
11664 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11665 "@
11666 sar{l}\t{%2, %k0|%k0, %2}
11667 sar{l}\t{%b2, %k0|%k0, %b2}"
11668 [(set_attr "type" "ishift")
11669 (set_attr "mode" "SI")])
11670
11671;; This pattern can't accept a variable shift count, since shifts by
11672;; zero don't affect the flags. We assume that shifts by constant
11673;; zero are optimized away.
11674(define_insn "*ashrsi3_one_bit_cmp"
11675 [(set (reg FLAGS_REG)
11676 (compare
11677 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11678 (match_operand:QI 2 "const1_operand" ""))
11679 (const_int 0)))
11680 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11681 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11682 "ix86_match_ccmode (insn, CCGOCmode)
11683 && (TARGET_SHIFT1 || optimize_size)
11684 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11685 "sar{l}\t%0"
11686 [(set_attr "type" "ishift")
11687 (set (attr "length")
11688 (if_then_else (match_operand:SI 0 "register_operand" "")
11689 (const_string "2")
11690 (const_string "*")))])
11691
11692(define_insn "*ashrsi3_one_bit_cconly"
11693 [(set (reg FLAGS_REG)
11694 (compare
11695 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11696 (match_operand:QI 2 "const1_operand" ""))
11697 (const_int 0)))
11698 (clobber (match_scratch:SI 0 "=r"))]
11699 "ix86_match_ccmode (insn, CCGOCmode)
11700 && (TARGET_SHIFT1 || optimize_size)
11701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11702 "sar{l}\t%0"
11703 [(set_attr "type" "ishift")
11704 (set_attr "length" "2")])
11705
11706(define_insn "*ashrsi3_one_bit_cmp_zext"
11707 [(set (reg FLAGS_REG)
11708 (compare
11709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11710 (match_operand:QI 2 "const1_operand" ""))
11711 (const_int 0)))
11712 (set (match_operand:DI 0 "register_operand" "=r")
11713 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11714 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11715 && (TARGET_SHIFT1 || optimize_size)
11716 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11717 "sar{l}\t%k0"
11718 [(set_attr "type" "ishift")
11719 (set_attr "length" "2")])
11720
11721;; This pattern can't accept a variable shift count, since shifts by
11722;; zero don't affect the flags. We assume that shifts by constant
11723;; zero are optimized away.
11724(define_insn "*ashrsi3_cmp"
11725 [(set (reg FLAGS_REG)
11726 (compare
11727 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11729 (const_int 0)))
11730 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11732 "ix86_match_ccmode (insn, CCGOCmode)
11733 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11734 && (optimize_size
11735 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11736 "sar{l}\t{%2, %0|%0, %2}"
11737 [(set_attr "type" "ishift")
11738 (set_attr "mode" "SI")])
11739
11740(define_insn "*ashrsi3_cconly"
11741 [(set (reg FLAGS_REG)
11742 (compare
11743 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11744 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11745 (const_int 0)))
11746 (clobber (match_scratch:SI 0 "=r"))]
11747 "ix86_match_ccmode (insn, CCGOCmode)
11748 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11749 && (optimize_size
11750 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11751 "sar{l}\t{%2, %0|%0, %2}"
11752 [(set_attr "type" "ishift")
11753 (set_attr "mode" "SI")])
11754
11755(define_insn "*ashrsi3_cmp_zext"
11756 [(set (reg FLAGS_REG)
11757 (compare
11758 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11759 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11760 (const_int 0)))
11761 (set (match_operand:DI 0 "register_operand" "=r")
11762 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11763 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11764 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11765 && (optimize_size
11766 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11767 "sar{l}\t{%2, %k0|%k0, %2}"
11768 [(set_attr "type" "ishift")
11769 (set_attr "mode" "SI")])
11770
11771(define_expand "ashrhi3"
11772 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11773 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11774 (match_operand:QI 2 "nonmemory_operand" "")))
11775 (clobber (reg:CC FLAGS_REG))]
11776 "TARGET_HIMODE_MATH"
11777 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11778
11779(define_insn "*ashrhi3_1_one_bit"
11780 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11781 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782 (match_operand:QI 2 "const1_operand" "")))
11783 (clobber (reg:CC FLAGS_REG))]
11784 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11785 && (TARGET_SHIFT1 || optimize_size)"
11786 "sar{w}\t%0"
11787 [(set_attr "type" "ishift")
11788 (set (attr "length")
11789 (if_then_else (match_operand 0 "register_operand" "")
11790 (const_string "2")
11791 (const_string "*")))])
11792
11793(define_insn "*ashrhi3_1"
11794 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11795 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11796 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11797 (clobber (reg:CC FLAGS_REG))]
11798 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11799 "@
11800 sar{w}\t{%2, %0|%0, %2}
11801 sar{w}\t{%b2, %0|%0, %b2}"
11802 [(set_attr "type" "ishift")
11803 (set_attr "mode" "HI")])
11804
11805;; This pattern can't accept a variable shift count, since shifts by
11806;; zero don't affect the flags. We assume that shifts by constant
11807;; zero are optimized away.
11808(define_insn "*ashrhi3_one_bit_cmp"
11809 [(set (reg FLAGS_REG)
11810 (compare
11811 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11812 (match_operand:QI 2 "const1_operand" ""))
11813 (const_int 0)))
11814 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11815 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11816 "ix86_match_ccmode (insn, CCGOCmode)
11817 && (TARGET_SHIFT1 || optimize_size)
11818 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11819 "sar{w}\t%0"
11820 [(set_attr "type" "ishift")
11821 (set (attr "length")
11822 (if_then_else (match_operand 0 "register_operand" "")
11823 (const_string "2")
11824 (const_string "*")))])
11825
11826(define_insn "*ashrhi3_one_bit_cconly"
11827 [(set (reg FLAGS_REG)
11828 (compare
11829 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11830 (match_operand:QI 2 "const1_operand" ""))
11831 (const_int 0)))
11832 (clobber (match_scratch:HI 0 "=r"))]
11833 "ix86_match_ccmode (insn, CCGOCmode)
11834 && (TARGET_SHIFT1 || optimize_size)
11835 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11836 "sar{w}\t%0"
11837 [(set_attr "type" "ishift")
11838 (set_attr "length" "2")])
11839
11840;; This pattern can't accept a variable shift count, since shifts by
11841;; zero don't affect the flags. We assume that shifts by constant
11842;; zero are optimized away.
11843(define_insn "*ashrhi3_cmp"
11844 [(set (reg FLAGS_REG)
11845 (compare
11846 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11847 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11848 (const_int 0)))
11849 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11851 "ix86_match_ccmode (insn, CCGOCmode)
11852 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11853 && (optimize_size
11854 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11855 "sar{w}\t{%2, %0|%0, %2}"
11856 [(set_attr "type" "ishift")
11857 (set_attr "mode" "HI")])
11858
11859(define_insn "*ashrhi3_cconly"
11860 [(set (reg FLAGS_REG)
11861 (compare
11862 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11863 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11864 (const_int 0)))
11865 (clobber (match_scratch:HI 0 "=r"))]
11866 "ix86_match_ccmode (insn, CCGOCmode)
11867 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11868 && (optimize_size
11869 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11870 "sar{w}\t{%2, %0|%0, %2}"
11871 [(set_attr "type" "ishift")
11872 (set_attr "mode" "HI")])
11873
11874(define_expand "ashrqi3"
11875 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11876 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11877 (match_operand:QI 2 "nonmemory_operand" "")))
11878 (clobber (reg:CC FLAGS_REG))]
11879 "TARGET_QIMODE_MATH"
11880 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11881
11882(define_insn "*ashrqi3_1_one_bit"
11883 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11884 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "const1_operand" "")))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11888 && (TARGET_SHIFT1 || optimize_size)"
11889 "sar{b}\t%0"
11890 [(set_attr "type" "ishift")
11891 (set (attr "length")
11892 (if_then_else (match_operand 0 "register_operand" "")
11893 (const_string "2")
11894 (const_string "*")))])
11895
11896(define_insn "*ashrqi3_1_one_bit_slp"
11897 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11898 (ashiftrt:QI (match_dup 0)
11899 (match_operand:QI 1 "const1_operand" "")))
11900 (clobber (reg:CC FLAGS_REG))]
11901 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11902 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11903 && (TARGET_SHIFT1 || optimize_size)"
11904 "sar{b}\t%0"
11905 [(set_attr "type" "ishift1")
11906 (set (attr "length")
11907 (if_then_else (match_operand 0 "register_operand" "")
11908 (const_string "2")
11909 (const_string "*")))])
11910
11911(define_insn "*ashrqi3_1"
11912 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11913 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11914 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11915 (clobber (reg:CC FLAGS_REG))]
11916 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11917 "@
11918 sar{b}\t{%2, %0|%0, %2}
11919 sar{b}\t{%b2, %0|%0, %b2}"
11920 [(set_attr "type" "ishift")
11921 (set_attr "mode" "QI")])
11922
11923(define_insn "*ashrqi3_1_slp"
11924 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11925 (ashiftrt:QI (match_dup 0)
11926 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11927 (clobber (reg:CC FLAGS_REG))]
11928 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11929 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11930 "@
11931 sar{b}\t{%1, %0|%0, %1}
11932 sar{b}\t{%b1, %0|%0, %b1}"
11933 [(set_attr "type" "ishift1")
11934 (set_attr "mode" "QI")])
11935
11936;; This pattern can't accept a variable shift count, since shifts by
11937;; zero don't affect the flags. We assume that shifts by constant
11938;; zero are optimized away.
11939(define_insn "*ashrqi3_one_bit_cmp"
11940 [(set (reg FLAGS_REG)
11941 (compare
11942 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11943 (match_operand:QI 2 "const1_operand" "I"))
11944 (const_int 0)))
11945 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11947 "ix86_match_ccmode (insn, CCGOCmode)
11948 && (TARGET_SHIFT1 || optimize_size)
11949 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11950 "sar{b}\t%0"
11951 [(set_attr "type" "ishift")
11952 (set (attr "length")
11953 (if_then_else (match_operand 0 "register_operand" "")
11954 (const_string "2")
11955 (const_string "*")))])
11956
11957(define_insn "*ashrqi3_one_bit_cconly"
11958 [(set (reg FLAGS_REG)
11959 (compare
11960 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11961 (match_operand:QI 2 "const1_operand" "I"))
11962 (const_int 0)))
11963 (clobber (match_scratch:QI 0 "=q"))]
11964 "ix86_match_ccmode (insn, CCGOCmode)
11965 && (TARGET_SHIFT1 || optimize_size)
11966 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11967 "sar{b}\t%0"
11968 [(set_attr "type" "ishift")
11969 (set_attr "length" "2")])
11970
11971;; This pattern can't accept a variable shift count, since shifts by
11972;; zero don't affect the flags. We assume that shifts by constant
11973;; zero are optimized away.
11974(define_insn "*ashrqi3_cmp"
11975 [(set (reg FLAGS_REG)
11976 (compare
11977 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11978 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11979 (const_int 0)))
11980 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11981 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11982 "ix86_match_ccmode (insn, CCGOCmode)
11983 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11984 && (optimize_size
11985 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11986 "sar{b}\t{%2, %0|%0, %2}"
11987 [(set_attr "type" "ishift")
11988 (set_attr "mode" "QI")])
11989
11990(define_insn "*ashrqi3_cconly"
11991 [(set (reg FLAGS_REG)
11992 (compare
11993 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11994 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11995 (const_int 0)))
11996 (clobber (match_scratch:QI 0 "=q"))]
11997 "ix86_match_ccmode (insn, CCGOCmode)
11998 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11999 && (optimize_size
12000 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12001 "sar{b}\t{%2, %0|%0, %2}"
12002 [(set_attr "type" "ishift")
12003 (set_attr "mode" "QI")])
12004
12005
12006;; Logical shift instructions
12007
12008;; See comment above `ashldi3' about how this works.
12009
12010(define_expand "lshrti3"
12011 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12012 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12013 (match_operand:QI 2 "nonmemory_operand" "")))
12014 (clobber (reg:CC FLAGS_REG))])]
12015 "TARGET_64BIT"
12016{
12017 if (! immediate_operand (operands[2], QImode))
12018 {
12019 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12020 DONE;
12021 }
12022 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12023 DONE;
12024})
12025
12026(define_insn "lshrti3_1"
12027 [(set (match_operand:TI 0 "register_operand" "=r")
12028 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12029 (match_operand:QI 2 "register_operand" "c")))
12030 (clobber (match_scratch:DI 3 "=&r"))
12031 (clobber (reg:CC FLAGS_REG))]
12032 "TARGET_64BIT"
12033 "#"
12034 [(set_attr "type" "multi")])
12035
12036(define_insn "*lshrti3_2"
12037 [(set (match_operand:TI 0 "register_operand" "=r")
12038 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12039 (match_operand:QI 2 "immediate_operand" "O")))
12040 (clobber (reg:CC FLAGS_REG))]
12041 "TARGET_64BIT"
12042 "#"
12043 [(set_attr "type" "multi")])
12044
12045(define_split
12046 [(set (match_operand:TI 0 "register_operand" "")
12047 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12048 (match_operand:QI 2 "register_operand" "")))
12049 (clobber (match_scratch:DI 3 ""))
12050 (clobber (reg:CC FLAGS_REG))]
12051 "TARGET_64BIT && reload_completed"
12052 [(const_int 0)]
12053 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12054
12055(define_split
12056 [(set (match_operand:TI 0 "register_operand" "")
12057 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12058 (match_operand:QI 2 "immediate_operand" "")))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "TARGET_64BIT && reload_completed"
12061 [(const_int 0)]
12062 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12063
12064(define_expand "lshrdi3"
12065 [(set (match_operand:DI 0 "shiftdi_operand" "")
12066 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12067 (match_operand:QI 2 "nonmemory_operand" "")))]
12068 ""
12069 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12070
12071(define_insn "*lshrdi3_1_one_bit_rex64"
12072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12073 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const1_operand" "")))
12075 (clobber (reg:CC FLAGS_REG))]
12076 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12077 && (TARGET_SHIFT1 || optimize_size)"
12078 "shr{q}\t%0"
12079 [(set_attr "type" "ishift")
12080 (set (attr "length")
12081 (if_then_else (match_operand:DI 0 "register_operand" "")
12082 (const_string "2")
12083 (const_string "*")))])
12084
12085(define_insn "*lshrdi3_1_rex64"
12086 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12087 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12088 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12089 (clobber (reg:CC FLAGS_REG))]
12090 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12091 "@
12092 shr{q}\t{%2, %0|%0, %2}
12093 shr{q}\t{%b2, %0|%0, %b2}"
12094 [(set_attr "type" "ishift")
12095 (set_attr "mode" "DI")])
12096
12097;; This pattern can't accept a variable shift count, since shifts by
12098;; zero don't affect the flags. We assume that shifts by constant
12099;; zero are optimized away.
12100(define_insn "*lshrdi3_cmp_one_bit_rex64"
12101 [(set (reg FLAGS_REG)
12102 (compare
12103 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12104 (match_operand:QI 2 "const1_operand" ""))
12105 (const_int 0)))
12106 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12107 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12108 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12109 && (TARGET_SHIFT1 || optimize_size)
12110 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12111 "shr{q}\t%0"
12112 [(set_attr "type" "ishift")
12113 (set (attr "length")
12114 (if_then_else (match_operand:DI 0 "register_operand" "")
12115 (const_string "2")
12116 (const_string "*")))])
12117
12118(define_insn "*lshrdi3_cconly_one_bit_rex64"
12119 [(set (reg FLAGS_REG)
12120 (compare
12121 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12122 (match_operand:QI 2 "const1_operand" ""))
12123 (const_int 0)))
12124 (clobber (match_scratch:DI 0 "=r"))]
12125 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12126 && (TARGET_SHIFT1 || optimize_size)
12127 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12128 "shr{q}\t%0"
12129 [(set_attr "type" "ishift")
12130 (set_attr "length" "2")])
12131
12132;; This pattern can't accept a variable shift count, since shifts by
12133;; zero don't affect the flags. We assume that shifts by constant
12134;; zero are optimized away.
12135(define_insn "*lshrdi3_cmp_rex64"
12136 [(set (reg FLAGS_REG)
12137 (compare
12138 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12139 (match_operand:QI 2 "const_int_operand" "e"))
12140 (const_int 0)))
12141 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12142 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12143 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12144 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12145 && (optimize_size
12146 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12147 "shr{q}\t{%2, %0|%0, %2}"
12148 [(set_attr "type" "ishift")
12149 (set_attr "mode" "DI")])
12150
12151(define_insn "*lshrdi3_cconly_rex64"
12152 [(set (reg FLAGS_REG)
12153 (compare
12154 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12155 (match_operand:QI 2 "const_int_operand" "e"))
12156 (const_int 0)))
12157 (clobber (match_scratch:DI 0 "=r"))]
12158 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12159 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12160 && (optimize_size
12161 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12162 "shr{q}\t{%2, %0|%0, %2}"
12163 [(set_attr "type" "ishift")
12164 (set_attr "mode" "DI")])
12165
12166(define_insn "*lshrdi3_1"
12167 [(set (match_operand:DI 0 "register_operand" "=r")
12168 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12169 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12170 (clobber (reg:CC FLAGS_REG))]
12171 "!TARGET_64BIT"
12172 "#"
12173 [(set_attr "type" "multi")])
12174
12175;; By default we don't ask for a scratch register, because when DImode
12176;; values are manipulated, registers are already at a premium. But if
12177;; we have one handy, we won't turn it away.
12178(define_peephole2
12179 [(match_scratch:SI 3 "r")
12180 (parallel [(set (match_operand:DI 0 "register_operand" "")
12181 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12182 (match_operand:QI 2 "nonmemory_operand" "")))
12183 (clobber (reg:CC FLAGS_REG))])
12184 (match_dup 3)]
12185 "!TARGET_64BIT && TARGET_CMOVE"
12186 [(const_int 0)]
12187 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12188
12189(define_split
12190 [(set (match_operand:DI 0 "register_operand" "")
12191 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12192 (match_operand:QI 2 "nonmemory_operand" "")))
12193 (clobber (reg:CC FLAGS_REG))]
12194 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12195 ? flow2_completed : reload_completed)"
12196 [(const_int 0)]
12197 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12198
12199(define_expand "lshrsi3"
12200 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12201 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12202 (match_operand:QI 2 "nonmemory_operand" "")))
12203 (clobber (reg:CC FLAGS_REG))]
12204 ""
12205 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12206
12207(define_insn "*lshrsi3_1_one_bit"
12208 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12210 (match_operand:QI 2 "const1_operand" "")))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12213 && (TARGET_SHIFT1 || optimize_size)"
12214 "shr{l}\t%0"
12215 [(set_attr "type" "ishift")
12216 (set (attr "length")
12217 (if_then_else (match_operand:SI 0 "register_operand" "")
12218 (const_string "2")
12219 (const_string "*")))])
12220
12221(define_insn "*lshrsi3_1_one_bit_zext"
12222 [(set (match_operand:DI 0 "register_operand" "=r")
12223 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12224 (match_operand:QI 2 "const1_operand" "")))
12225 (clobber (reg:CC FLAGS_REG))]
12226 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12227 && (TARGET_SHIFT1 || optimize_size)"
12228 "shr{l}\t%k0"
12229 [(set_attr "type" "ishift")
12230 (set_attr "length" "2")])
12231
12232(define_insn "*lshrsi3_1"
12233 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12234 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12235 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12236 (clobber (reg:CC FLAGS_REG))]
12237 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12238 "@
12239 shr{l}\t{%2, %0|%0, %2}
12240 shr{l}\t{%b2, %0|%0, %b2}"
12241 [(set_attr "type" "ishift")
12242 (set_attr "mode" "SI")])
12243
12244(define_insn "*lshrsi3_1_zext"
12245 [(set (match_operand:DI 0 "register_operand" "=r,r")
12246 (zero_extend:DI
12247 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12248 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12249 (clobber (reg:CC FLAGS_REG))]
12250 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12251 "@
12252 shr{l}\t{%2, %k0|%k0, %2}
12253 shr{l}\t{%b2, %k0|%k0, %b2}"
12254 [(set_attr "type" "ishift")
12255 (set_attr "mode" "SI")])
12256
12257;; This pattern can't accept a variable shift count, since shifts by
12258;; zero don't affect the flags. We assume that shifts by constant
12259;; zero are optimized away.
12260(define_insn "*lshrsi3_one_bit_cmp"
12261 [(set (reg FLAGS_REG)
12262 (compare
12263 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12264 (match_operand:QI 2 "const1_operand" ""))
12265 (const_int 0)))
12266 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12267 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12268 "ix86_match_ccmode (insn, CCGOCmode)
12269 && (TARGET_SHIFT1 || optimize_size)
12270 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12271 "shr{l}\t%0"
12272 [(set_attr "type" "ishift")
12273 (set (attr "length")
12274 (if_then_else (match_operand:SI 0 "register_operand" "")
12275 (const_string "2")
12276 (const_string "*")))])
12277
12278(define_insn "*lshrsi3_one_bit_cconly"
12279 [(set (reg FLAGS_REG)
12280 (compare
12281 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282 (match_operand:QI 2 "const1_operand" ""))
12283 (const_int 0)))
12284 (clobber (match_scratch:SI 0 "=r"))]
12285 "ix86_match_ccmode (insn, CCGOCmode)
12286 && (TARGET_SHIFT1 || optimize_size)
12287 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12288 "shr{l}\t%0"
12289 [(set_attr "type" "ishift")
12290 (set_attr "length" "2")])
12291
12292(define_insn "*lshrsi3_cmp_one_bit_zext"
12293 [(set (reg FLAGS_REG)
12294 (compare
12295 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296 (match_operand:QI 2 "const1_operand" ""))
12297 (const_int 0)))
12298 (set (match_operand:DI 0 "register_operand" "=r")
12299 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12300 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12301 && (TARGET_SHIFT1 || optimize_size)
12302 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12303 "shr{l}\t%k0"
12304 [(set_attr "type" "ishift")
12305 (set_attr "length" "2")])
12306
12307;; This pattern can't accept a variable shift count, since shifts by
12308;; zero don't affect the flags. We assume that shifts by constant
12309;; zero are optimized away.
12310(define_insn "*lshrsi3_cmp"
12311 [(set (reg FLAGS_REG)
12312 (compare
12313 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12315 (const_int 0)))
12316 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12318 "ix86_match_ccmode (insn, CCGOCmode)
12319 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12320 && (optimize_size
12321 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12322 "shr{l}\t{%2, %0|%0, %2}"
12323 [(set_attr "type" "ishift")
12324 (set_attr "mode" "SI")])
12325
12326(define_insn "*lshrsi3_cconly"
12327 [(set (reg FLAGS_REG)
12328 (compare
12329 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12330 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331 (const_int 0)))
12332 (clobber (match_scratch:SI 0 "=r"))]
12333 "ix86_match_ccmode (insn, CCGOCmode)
12334 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12335 && (optimize_size
12336 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12337 "shr{l}\t{%2, %0|%0, %2}"
12338 [(set_attr "type" "ishift")
12339 (set_attr "mode" "SI")])
12340
12341(define_insn "*lshrsi3_cmp_zext"
12342 [(set (reg FLAGS_REG)
12343 (compare
12344 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12345 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12346 (const_int 0)))
12347 (set (match_operand:DI 0 "register_operand" "=r")
12348 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12349 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12350 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12351 && (optimize_size
12352 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12353 "shr{l}\t{%2, %k0|%k0, %2}"
12354 [(set_attr "type" "ishift")
12355 (set_attr "mode" "SI")])
12356
12357(define_expand "lshrhi3"
12358 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12359 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12360 (match_operand:QI 2 "nonmemory_operand" "")))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "TARGET_HIMODE_MATH"
12363 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12364
12365(define_insn "*lshrhi3_1_one_bit"
12366 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" "")))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12371 && (TARGET_SHIFT1 || optimize_size)"
12372 "shr{w}\t%0"
12373 [(set_attr "type" "ishift")
12374 (set (attr "length")
12375 (if_then_else (match_operand 0 "register_operand" "")
12376 (const_string "2")
12377 (const_string "*")))])
12378
12379(define_insn "*lshrhi3_1"
12380 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12381 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12382 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383 (clobber (reg:CC FLAGS_REG))]
12384 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12385 "@
12386 shr{w}\t{%2, %0|%0, %2}
12387 shr{w}\t{%b2, %0|%0, %b2}"
12388 [(set_attr "type" "ishift")
12389 (set_attr "mode" "HI")])
12390
12391;; This pattern can't accept a variable shift count, since shifts by
12392;; zero don't affect the flags. We assume that shifts by constant
12393;; zero are optimized away.
12394(define_insn "*lshrhi3_one_bit_cmp"
12395 [(set (reg FLAGS_REG)
12396 (compare
12397 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const1_operand" ""))
12399 (const_int 0)))
12400 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12402 "ix86_match_ccmode (insn, CCGOCmode)
12403 && (TARGET_SHIFT1 || optimize_size)
12404 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12405 "shr{w}\t%0"
12406 [(set_attr "type" "ishift")
12407 (set (attr "length")
12408 (if_then_else (match_operand:SI 0 "register_operand" "")
12409 (const_string "2")
12410 (const_string "*")))])
12411
12412(define_insn "*lshrhi3_one_bit_cconly"
12413 [(set (reg FLAGS_REG)
12414 (compare
12415 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12416 (match_operand:QI 2 "const1_operand" ""))
12417 (const_int 0)))
12418 (clobber (match_scratch:HI 0 "=r"))]
12419 "ix86_match_ccmode (insn, CCGOCmode)
12420 && (TARGET_SHIFT1 || optimize_size)
12421 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12422 "shr{w}\t%0"
12423 [(set_attr "type" "ishift")
12424 (set_attr "length" "2")])
12425
12426;; This pattern can't accept a variable shift count, since shifts by
12427;; zero don't affect the flags. We assume that shifts by constant
12428;; zero are optimized away.
12429(define_insn "*lshrhi3_cmp"
12430 [(set (reg FLAGS_REG)
12431 (compare
12432 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12433 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12434 (const_int 0)))
12435 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12436 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12437 "ix86_match_ccmode (insn, CCGOCmode)
12438 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12439 && (optimize_size
12440 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12441 "shr{w}\t{%2, %0|%0, %2}"
12442 [(set_attr "type" "ishift")
12443 (set_attr "mode" "HI")])
12444
12445(define_insn "*lshrhi3_cconly"
12446 [(set (reg FLAGS_REG)
12447 (compare
12448 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12449 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12450 (const_int 0)))
12451 (clobber (match_scratch:HI 0 "=r"))]
12452 "ix86_match_ccmode (insn, CCGOCmode)
12453 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12454 && (optimize_size
12455 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12456 "shr{w}\t{%2, %0|%0, %2}"
12457 [(set_attr "type" "ishift")
12458 (set_attr "mode" "HI")])
12459
12460(define_expand "lshrqi3"
12461 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12462 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12463 (match_operand:QI 2 "nonmemory_operand" "")))
12464 (clobber (reg:CC FLAGS_REG))]
12465 "TARGET_QIMODE_MATH"
12466 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12467
12468(define_insn "*lshrqi3_1_one_bit"
12469 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12471 (match_operand:QI 2 "const1_operand" "")))
12472 (clobber (reg:CC FLAGS_REG))]
12473 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474 && (TARGET_SHIFT1 || optimize_size)"
12475 "shr{b}\t%0"
12476 [(set_attr "type" "ishift")
12477 (set (attr "length")
12478 (if_then_else (match_operand 0 "register_operand" "")
12479 (const_string "2")
12480 (const_string "*")))])
12481
12482(define_insn "*lshrqi3_1_one_bit_slp"
12483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12484 (lshiftrt:QI (match_dup 0)
12485 (match_operand:QI 1 "const1_operand" "")))
12486 (clobber (reg:CC FLAGS_REG))]
12487 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12488 && (TARGET_SHIFT1 || optimize_size)"
12489 "shr{b}\t%0"
12490 [(set_attr "type" "ishift1")
12491 (set (attr "length")
12492 (if_then_else (match_operand 0 "register_operand" "")
12493 (const_string "2")
12494 (const_string "*")))])
12495
12496(define_insn "*lshrqi3_1"
12497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12498 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12499 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12500 (clobber (reg:CC FLAGS_REG))]
12501 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12502 "@
12503 shr{b}\t{%2, %0|%0, %2}
12504 shr{b}\t{%b2, %0|%0, %b2}"
12505 [(set_attr "type" "ishift")
12506 (set_attr "mode" "QI")])
12507
12508(define_insn "*lshrqi3_1_slp"
12509 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12510 (lshiftrt:QI (match_dup 0)
12511 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12512 (clobber (reg:CC FLAGS_REG))]
12513 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12514 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12515 "@
12516 shr{b}\t{%1, %0|%0, %1}
12517 shr{b}\t{%b1, %0|%0, %b1}"
12518 [(set_attr "type" "ishift1")
12519 (set_attr "mode" "QI")])
12520
12521;; This pattern can't accept a variable shift count, since shifts by
12522;; zero don't affect the flags. We assume that shifts by constant
12523;; zero are optimized away.
12524(define_insn "*lshrqi2_one_bit_cmp"
12525 [(set (reg FLAGS_REG)
12526 (compare
12527 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const1_operand" ""))
12529 (const_int 0)))
12530 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12531 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12532 "ix86_match_ccmode (insn, CCGOCmode)
12533 && (TARGET_SHIFT1 || optimize_size)
12534 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12535 "shr{b}\t%0"
12536 [(set_attr "type" "ishift")
12537 (set (attr "length")
12538 (if_then_else (match_operand:SI 0 "register_operand" "")
12539 (const_string "2")
12540 (const_string "*")))])
12541
12542(define_insn "*lshrqi2_one_bit_cconly"
12543 [(set (reg FLAGS_REG)
12544 (compare
12545 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12546 (match_operand:QI 2 "const1_operand" ""))
12547 (const_int 0)))
12548 (clobber (match_scratch:QI 0 "=q"))]
12549 "ix86_match_ccmode (insn, CCGOCmode)
12550 && (TARGET_SHIFT1 || optimize_size)
12551 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12552 "shr{b}\t%0"
12553 [(set_attr "type" "ishift")
12554 (set_attr "length" "2")])
12555
12556;; This pattern can't accept a variable shift count, since shifts by
12557;; zero don't affect the flags. We assume that shifts by constant
12558;; zero are optimized away.
12559(define_insn "*lshrqi2_cmp"
12560 [(set (reg FLAGS_REG)
12561 (compare
12562 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12563 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12564 (const_int 0)))
12565 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12566 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12567 "ix86_match_ccmode (insn, CCGOCmode)
12568 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12569 && (optimize_size
12570 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12571 "shr{b}\t{%2, %0|%0, %2}"
12572 [(set_attr "type" "ishift")
12573 (set_attr "mode" "QI")])
12574
12575(define_insn "*lshrqi2_cconly"
12576 [(set (reg FLAGS_REG)
12577 (compare
12578 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12580 (const_int 0)))
12581 (clobber (match_scratch:QI 0 "=q"))]
12582 "ix86_match_ccmode (insn, CCGOCmode)
12583 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12584 && (optimize_size
12585 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12586 "shr{b}\t{%2, %0|%0, %2}"
12587 [(set_attr "type" "ishift")
12588 (set_attr "mode" "QI")])
12589
12590;; Rotate instructions
12591
12592(define_expand "rotldi3"
12593 [(set (match_operand:DI 0 "shiftdi_operand" "")
12594 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12595 (match_operand:QI 2 "nonmemory_operand" "")))
12596 (clobber (reg:CC FLAGS_REG))]
12597 ""
12598{
12599 if (TARGET_64BIT)
12600 {
12601 ix86_expand_binary_operator (ROTATE, DImode, operands);
12602 DONE;
12603 }
12604 if (!const_1_to_31_operand (operands[2], VOIDmode))
12605 FAIL;
12606 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12607 DONE;
12608})
12609
12610;; Implement rotation using two double-precision shift instructions
12611;; and a scratch register.
12612(define_insn_and_split "ix86_rotldi3"
12613 [(set (match_operand:DI 0 "register_operand" "=r")
12614 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12615 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12616 (clobber (reg:CC FLAGS_REG))
12617 (clobber (match_scratch:SI 3 "=&r"))]
12618 "!TARGET_64BIT"
12619 ""
12620 "&& reload_completed"
12621 [(set (match_dup 3) (match_dup 4))
12622 (parallel
12623 [(set (match_dup 4)
12624 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12625 (lshiftrt:SI (match_dup 5)
12626 (minus:QI (const_int 32) (match_dup 2)))))
12627 (clobber (reg:CC FLAGS_REG))])
12628 (parallel
12629 [(set (match_dup 5)
12630 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12631 (lshiftrt:SI (match_dup 3)
12632 (minus:QI (const_int 32) (match_dup 2)))))
12633 (clobber (reg:CC FLAGS_REG))])]
12634 "split_di (operands, 1, operands + 4, operands + 5);")
12635
12636(define_insn "*rotlsi3_1_one_bit_rex64"
12637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12638 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12639 (match_operand:QI 2 "const1_operand" "")))
12640 (clobber (reg:CC FLAGS_REG))]
12641 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12642 && (TARGET_SHIFT1 || optimize_size)"
12643 "rol{q}\t%0"
12644 [(set_attr "type" "rotate")
12645 (set (attr "length")
12646 (if_then_else (match_operand:DI 0 "register_operand" "")
12647 (const_string "2")
12648 (const_string "*")))])
12649
12650(define_insn "*rotldi3_1_rex64"
12651 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12652 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12653 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12656 "@
12657 rol{q}\t{%2, %0|%0, %2}
12658 rol{q}\t{%b2, %0|%0, %b2}"
12659 [(set_attr "type" "rotate")
12660 (set_attr "mode" "DI")])
12661
12662(define_expand "rotlsi3"
12663 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12664 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12665 (match_operand:QI 2 "nonmemory_operand" "")))
12666 (clobber (reg:CC FLAGS_REG))]
12667 ""
12668 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12669
12670(define_insn "*rotlsi3_1_one_bit"
12671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12672 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12673 (match_operand:QI 2 "const1_operand" "")))
12674 (clobber (reg:CC FLAGS_REG))]
12675 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12676 && (TARGET_SHIFT1 || optimize_size)"
12677 "rol{l}\t%0"
12678 [(set_attr "type" "rotate")
12679 (set (attr "length")
12680 (if_then_else (match_operand:SI 0 "register_operand" "")
12681 (const_string "2")
12682 (const_string "*")))])
12683
12684(define_insn "*rotlsi3_1_one_bit_zext"
12685 [(set (match_operand:DI 0 "register_operand" "=r")
12686 (zero_extend:DI
12687 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12688 (match_operand:QI 2 "const1_operand" ""))))
12689 (clobber (reg:CC FLAGS_REG))]
12690 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12691 && (TARGET_SHIFT1 || optimize_size)"
12692 "rol{l}\t%k0"
12693 [(set_attr "type" "rotate")
12694 (set_attr "length" "2")])
12695
12696(define_insn "*rotlsi3_1"
12697 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12698 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12699 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700 (clobber (reg:CC FLAGS_REG))]
12701 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12702 "@
12703 rol{l}\t{%2, %0|%0, %2}
12704 rol{l}\t{%b2, %0|%0, %b2}"
12705 [(set_attr "type" "rotate")
12706 (set_attr "mode" "SI")])
12707
12708(define_insn "*rotlsi3_1_zext"
12709 [(set (match_operand:DI 0 "register_operand" "=r,r")
12710 (zero_extend:DI
12711 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12712 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12713 (clobber (reg:CC FLAGS_REG))]
12714 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12715 "@
12716 rol{l}\t{%2, %k0|%k0, %2}
12717 rol{l}\t{%b2, %k0|%k0, %b2}"
12718 [(set_attr "type" "rotate")
12719 (set_attr "mode" "SI")])
12720
12721(define_expand "rotlhi3"
12722 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12723 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12724 (match_operand:QI 2 "nonmemory_operand" "")))
12725 (clobber (reg:CC FLAGS_REG))]
12726 "TARGET_HIMODE_MATH"
12727 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12728
12729(define_insn "*rotlhi3_1_one_bit"
12730 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12731 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12732 (match_operand:QI 2 "const1_operand" "")))
12733 (clobber (reg:CC FLAGS_REG))]
12734 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12735 && (TARGET_SHIFT1 || optimize_size)"
12736 "rol{w}\t%0"
12737 [(set_attr "type" "rotate")
12738 (set (attr "length")
12739 (if_then_else (match_operand 0 "register_operand" "")
12740 (const_string "2")
12741 (const_string "*")))])
12742
12743(define_insn "*rotlhi3_1"
12744 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12745 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12746 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12747 (clobber (reg:CC FLAGS_REG))]
12748 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12749 "@
12750 rol{w}\t{%2, %0|%0, %2}
12751 rol{w}\t{%b2, %0|%0, %b2}"
12752 [(set_attr "type" "rotate")
12753 (set_attr "mode" "HI")])
12754
12755(define_expand "rotlqi3"
12756 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12757 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12758 (match_operand:QI 2 "nonmemory_operand" "")))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "TARGET_QIMODE_MATH"
12761 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12762
12763(define_insn "*rotlqi3_1_one_bit_slp"
12764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12765 (rotate:QI (match_dup 0)
12766 (match_operand:QI 1 "const1_operand" "")))
12767 (clobber (reg:CC FLAGS_REG))]
12768 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12769 && (TARGET_SHIFT1 || optimize_size)"
12770 "rol{b}\t%0"
12771 [(set_attr "type" "rotate1")
12772 (set (attr "length")
12773 (if_then_else (match_operand 0 "register_operand" "")
12774 (const_string "2")
12775 (const_string "*")))])
12776
12777(define_insn "*rotlqi3_1_one_bit"
12778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12779 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12780 (match_operand:QI 2 "const1_operand" "")))
12781 (clobber (reg:CC FLAGS_REG))]
12782 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12783 && (TARGET_SHIFT1 || optimize_size)"
12784 "rol{b}\t%0"
12785 [(set_attr "type" "rotate")
12786 (set (attr "length")
12787 (if_then_else (match_operand 0 "register_operand" "")
12788 (const_string "2")
12789 (const_string "*")))])
12790
12791(define_insn "*rotlqi3_1_slp"
12792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12793 (rotate:QI (match_dup 0)
12794 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12795 (clobber (reg:CC FLAGS_REG))]
12796 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12797 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12798 "@
12799 rol{b}\t{%1, %0|%0, %1}
12800 rol{b}\t{%b1, %0|%0, %b1}"
12801 [(set_attr "type" "rotate1")
12802 (set_attr "mode" "QI")])
12803
12804(define_insn "*rotlqi3_1"
12805 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12806 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12807 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12808 (clobber (reg:CC FLAGS_REG))]
12809 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12810 "@
12811 rol{b}\t{%2, %0|%0, %2}
12812 rol{b}\t{%b2, %0|%0, %b2}"
12813 [(set_attr "type" "rotate")
12814 (set_attr "mode" "QI")])
12815
12816(define_expand "rotrdi3"
12817 [(set (match_operand:DI 0 "shiftdi_operand" "")
12818 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12819 (match_operand:QI 2 "nonmemory_operand" "")))
12820 (clobber (reg:CC FLAGS_REG))]
12821 ""
12822{
12823 if (TARGET_64BIT)
12824 {
12825 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12826 DONE;
12827 }
12828 if (!const_1_to_31_operand (operands[2], VOIDmode))
12829 FAIL;
12830 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12831 DONE;
12832})
12833
12834;; Implement rotation using two double-precision shift instructions
12835;; and a scratch register.
12836(define_insn_and_split "ix86_rotrdi3"
12837 [(set (match_operand:DI 0 "register_operand" "=r")
12838 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12839 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12840 (clobber (reg:CC FLAGS_REG))
12841 (clobber (match_scratch:SI 3 "=&r"))]
12842 "!TARGET_64BIT"
12843 ""
12844 "&& reload_completed"
12845 [(set (match_dup 3) (match_dup 4))
12846 (parallel
12847 [(set (match_dup 4)
12848 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12849 (ashift:SI (match_dup 5)
12850 (minus:QI (const_int 32) (match_dup 2)))))
12851 (clobber (reg:CC FLAGS_REG))])
12852 (parallel
12853 [(set (match_dup 5)
12854 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12855 (ashift:SI (match_dup 3)
12856 (minus:QI (const_int 32) (match_dup 2)))))
12857 (clobber (reg:CC FLAGS_REG))])]
12858 "split_di (operands, 1, operands + 4, operands + 5);")
12859
12860(define_insn "*rotrdi3_1_one_bit_rex64"
12861 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12862 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12863 (match_operand:QI 2 "const1_operand" "")))
12864 (clobber (reg:CC FLAGS_REG))]
12865 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12866 && (TARGET_SHIFT1 || optimize_size)"
12867 "ror{q}\t%0"
12868 [(set_attr "type" "rotate")
12869 (set (attr "length")
12870 (if_then_else (match_operand:DI 0 "register_operand" "")
12871 (const_string "2")
12872 (const_string "*")))])
12873
12874(define_insn "*rotrdi3_1_rex64"
12875 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12876 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12877 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12880 "@
12881 ror{q}\t{%2, %0|%0, %2}
12882 ror{q}\t{%b2, %0|%0, %b2}"
12883 [(set_attr "type" "rotate")
12884 (set_attr "mode" "DI")])
12885
12886(define_expand "rotrsi3"
12887 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12888 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12889 (match_operand:QI 2 "nonmemory_operand" "")))
12890 (clobber (reg:CC FLAGS_REG))]
12891 ""
12892 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12893
12894(define_insn "*rotrsi3_1_one_bit"
12895 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12896 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12897 (match_operand:QI 2 "const1_operand" "")))
12898 (clobber (reg:CC FLAGS_REG))]
12899 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12900 && (TARGET_SHIFT1 || optimize_size)"
12901 "ror{l}\t%0"
12902 [(set_attr "type" "rotate")
12903 (set (attr "length")
12904 (if_then_else (match_operand:SI 0 "register_operand" "")
12905 (const_string "2")
12906 (const_string "*")))])
12907
12908(define_insn "*rotrsi3_1_one_bit_zext"
12909 [(set (match_operand:DI 0 "register_operand" "=r")
12910 (zero_extend:DI
12911 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12912 (match_operand:QI 2 "const1_operand" ""))))
12913 (clobber (reg:CC FLAGS_REG))]
12914 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12915 && (TARGET_SHIFT1 || optimize_size)"
12916 "ror{l}\t%k0"
12917 [(set_attr "type" "rotate")
12918 (set (attr "length")
12919 (if_then_else (match_operand:SI 0 "register_operand" "")
12920 (const_string "2")
12921 (const_string "*")))])
12922
12923(define_insn "*rotrsi3_1"
12924 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12925 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12926 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927 (clobber (reg:CC FLAGS_REG))]
12928 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12929 "@
12930 ror{l}\t{%2, %0|%0, %2}
12931 ror{l}\t{%b2, %0|%0, %b2}"
12932 [(set_attr "type" "rotate")
12933 (set_attr "mode" "SI")])
12934
12935(define_insn "*rotrsi3_1_zext"
12936 [(set (match_operand:DI 0 "register_operand" "=r,r")
12937 (zero_extend:DI
12938 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12939 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12940 (clobber (reg:CC FLAGS_REG))]
12941 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12942 "@
12943 ror{l}\t{%2, %k0|%k0, %2}
12944 ror{l}\t{%b2, %k0|%k0, %b2}"
12945 [(set_attr "type" "rotate")
12946 (set_attr "mode" "SI")])
12947
12948(define_expand "rotrhi3"
12949 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12950 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12951 (match_operand:QI 2 "nonmemory_operand" "")))
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_HIMODE_MATH"
12954 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12955
12956(define_insn "*rotrhi3_one_bit"
12957 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12958 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12959 (match_operand:QI 2 "const1_operand" "")))
12960 (clobber (reg:CC FLAGS_REG))]
12961 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12962 && (TARGET_SHIFT1 || optimize_size)"
12963 "ror{w}\t%0"
12964 [(set_attr "type" "rotate")
12965 (set (attr "length")
12966 (if_then_else (match_operand 0 "register_operand" "")
12967 (const_string "2")
12968 (const_string "*")))])
12969
12970(define_insn "*rotrhi3"
12971 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12972 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12973 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12974 (clobber (reg:CC FLAGS_REG))]
12975 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12976 "@
12977 ror{w}\t{%2, %0|%0, %2}
12978 ror{w}\t{%b2, %0|%0, %b2}"
12979 [(set_attr "type" "rotate")
12980 (set_attr "mode" "HI")])
12981
12982(define_expand "rotrqi3"
12983 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12984 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12985 (match_operand:QI 2 "nonmemory_operand" "")))
12986 (clobber (reg:CC FLAGS_REG))]
12987 "TARGET_QIMODE_MATH"
12988 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12989
12990(define_insn "*rotrqi3_1_one_bit"
12991 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12992 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12993 (match_operand:QI 2 "const1_operand" "")))
12994 (clobber (reg:CC FLAGS_REG))]
12995 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12996 && (TARGET_SHIFT1 || optimize_size)"
12997 "ror{b}\t%0"
12998 [(set_attr "type" "rotate")
12999 (set (attr "length")
13000 (if_then_else (match_operand 0 "register_operand" "")
13001 (const_string "2")
13002 (const_string "*")))])
13003
13004(define_insn "*rotrqi3_1_one_bit_slp"
13005 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13006 (rotatert:QI (match_dup 0)
13007 (match_operand:QI 1 "const1_operand" "")))
13008 (clobber (reg:CC FLAGS_REG))]
13009 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13010 && (TARGET_SHIFT1 || optimize_size)"
13011 "ror{b}\t%0"
13012 [(set_attr "type" "rotate1")
13013 (set (attr "length")
13014 (if_then_else (match_operand 0 "register_operand" "")
13015 (const_string "2")
13016 (const_string "*")))])
13017
13018(define_insn "*rotrqi3_1"
13019 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13020 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13021 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022 (clobber (reg:CC FLAGS_REG))]
13023 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13024 "@
13025 ror{b}\t{%2, %0|%0, %2}
13026 ror{b}\t{%b2, %0|%0, %b2}"
13027 [(set_attr "type" "rotate")
13028 (set_attr "mode" "QI")])
13029
13030(define_insn "*rotrqi3_1_slp"
13031 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13032 (rotatert:QI (match_dup 0)
13033 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13034 (clobber (reg:CC FLAGS_REG))]
13035 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13036 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13037 "@
13038 ror{b}\t{%1, %0|%0, %1}
13039 ror{b}\t{%b1, %0|%0, %b1}"
13040 [(set_attr "type" "rotate1")
13041 (set_attr "mode" "QI")])
13042
13043;; Bit set / bit test instructions
13044
13045(define_expand "extv"
13046 [(set (match_operand:SI 0 "register_operand" "")
13047 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13048 (match_operand:SI 2 "const8_operand" "")
13049 (match_operand:SI 3 "const8_operand" "")))]
13050 ""
13051{
13052 /* Handle extractions from %ah et al. */
13053 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13054 FAIL;
13055
13056 /* From mips.md: extract_bit_field doesn't verify that our source
13057 matches the predicate, so check it again here. */
13058 if (! ext_register_operand (operands[1], VOIDmode))
13059 FAIL;
13060})
13061
13062(define_expand "extzv"
13063 [(set (match_operand:SI 0 "register_operand" "")
13064 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13065 (match_operand:SI 2 "const8_operand" "")
13066 (match_operand:SI 3 "const8_operand" "")))]
13067 ""
13068{
13069 /* Handle extractions from %ah et al. */
13070 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13071 FAIL;
13072
13073 /* From mips.md: extract_bit_field doesn't verify that our source
13074 matches the predicate, so check it again here. */
13075 if (! ext_register_operand (operands[1], VOIDmode))
13076 FAIL;
13077})
13078
13079(define_expand "insv"
13080 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13081 (match_operand 1 "const8_operand" "")
13082 (match_operand 2 "const8_operand" ""))
13083 (match_operand 3 "register_operand" ""))]
13084 ""
13085{
13086 /* Handle insertions to %ah et al. */
13087 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13088 FAIL;
13089
13090 /* From mips.md: insert_bit_field doesn't verify that our source
13091 matches the predicate, so check it again here. */
13092 if (! ext_register_operand (operands[0], VOIDmode))
13093 FAIL;
13094
13095 if (TARGET_64BIT)
13096 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13097 else
13098 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13099
13100 DONE;
13101})
13102
13103;; %%% bts, btr, btc, bt.
13104;; In general these instructions are *slow* when applied to memory,
13105;; since they enforce atomic operation. When applied to registers,
13106;; it depends on the cpu implementation. They're never faster than
13107;; the corresponding and/ior/xor operations, so with 32-bit there's
13108;; no point. But in 64-bit, we can't hold the relevant immediates
13109;; within the instruction itself, so operating on bits in the high
13110;; 32-bits of a register becomes easier.
13111;;
13112;; These are slow on Nocona, but fast on Athlon64. We do require the use
13113;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13114;; negdf respectively, so they can never be disabled entirely.
13115
13116(define_insn "*btsq"
13117 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13118 (const_int 1)
13119 (match_operand:DI 1 "const_0_to_63_operand" ""))
13120 (const_int 1))
13121 (clobber (reg:CC FLAGS_REG))]
13122 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13123 "bts{q} %1,%0"
13124 [(set_attr "type" "alu1")])
13125
13126(define_insn "*btrq"
13127 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13128 (const_int 1)
13129 (match_operand:DI 1 "const_0_to_63_operand" ""))
13130 (const_int 0))
13131 (clobber (reg:CC FLAGS_REG))]
13132 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13133 "btr{q} %1,%0"
13134 [(set_attr "type" "alu1")])
13135
13136(define_insn "*btcq"
13137 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13138 (const_int 1)
13139 (match_operand:DI 1 "const_0_to_63_operand" ""))
13140 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13141 (clobber (reg:CC FLAGS_REG))]
13142 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13143 "btc{q} %1,%0"
13144 [(set_attr "type" "alu1")])
13145
13146;; Allow Nocona to avoid these instructions if a register is available.
13147
13148(define_peephole2
13149 [(match_scratch:DI 2 "r")
13150 (parallel [(set (zero_extract:DI
13151 (match_operand:DI 0 "register_operand" "")
13152 (const_int 1)
13153 (match_operand:DI 1 "const_0_to_63_operand" ""))
13154 (const_int 1))
13155 (clobber (reg:CC FLAGS_REG))])]
13156 "TARGET_64BIT && !TARGET_USE_BT"
13157 [(const_int 0)]
13158{
13159 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13160 rtx op1;
13161
13162 if (HOST_BITS_PER_WIDE_INT >= 64)
13163 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13164 else if (i < HOST_BITS_PER_WIDE_INT)
13165 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166 else
13167 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13168
13169 op1 = immed_double_const (lo, hi, DImode);
13170 if (i >= 31)
13171 {
13172 emit_move_insn (operands[2], op1);
13173 op1 = operands[2];
13174 }
13175
13176 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13177 DONE;
13178})
13179
13180(define_peephole2
13181 [(match_scratch:DI 2 "r")
13182 (parallel [(set (zero_extract:DI
13183 (match_operand:DI 0 "register_operand" "")
13184 (const_int 1)
13185 (match_operand:DI 1 "const_0_to_63_operand" ""))
13186 (const_int 0))
13187 (clobber (reg:CC FLAGS_REG))])]
13188 "TARGET_64BIT && !TARGET_USE_BT"
13189 [(const_int 0)]
13190{
13191 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13192 rtx op1;
13193
13194 if (HOST_BITS_PER_WIDE_INT >= 64)
13195 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13196 else if (i < HOST_BITS_PER_WIDE_INT)
13197 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13198 else
13199 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13200
13201 op1 = immed_double_const (~lo, ~hi, DImode);
13202 if (i >= 32)
13203 {
13204 emit_move_insn (operands[2], op1);
13205 op1 = operands[2];
13206 }
13207
13208 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13209 DONE;
13210})
13211
13212(define_peephole2
13213 [(match_scratch:DI 2 "r")
13214 (parallel [(set (zero_extract:DI
13215 (match_operand:DI 0 "register_operand" "")
13216 (const_int 1)
13217 (match_operand:DI 1 "const_0_to_63_operand" ""))
13218 (not:DI (zero_extract:DI
13219 (match_dup 0) (const_int 1) (match_dup 1))))
13220 (clobber (reg:CC FLAGS_REG))])]
13221 "TARGET_64BIT && !TARGET_USE_BT"
13222 [(const_int 0)]
13223{
13224 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13225 rtx op1;
13226
13227 if (HOST_BITS_PER_WIDE_INT >= 64)
13228 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13229 else if (i < HOST_BITS_PER_WIDE_INT)
13230 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13231 else
13232 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13233
13234 op1 = immed_double_const (lo, hi, DImode);
13235 if (i >= 31)
13236 {
13237 emit_move_insn (operands[2], op1);
13238 op1 = operands[2];
13239 }
13240
13241 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13242 DONE;
13243})
13244
13245;; Store-flag instructions.
13246
13247;; For all sCOND expanders, also expand the compare or test insn that
13248;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13249
13250;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13251;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13252;; way, which can later delete the movzx if only QImode is needed.
13253
13254(define_expand "seq"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257 ""
13258 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13259
13260(define_expand "sne"
13261 [(set (match_operand:QI 0 "register_operand" "")
13262 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263 ""
13264 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13265
13266(define_expand "sgt"
13267 [(set (match_operand:QI 0 "register_operand" "")
13268 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269 ""
13270 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13271
13272(define_expand "sgtu"
13273 [(set (match_operand:QI 0 "register_operand" "")
13274 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275 ""
13276 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13277
13278(define_expand "slt"
13279 [(set (match_operand:QI 0 "register_operand" "")
13280 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281 ""
13282 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13283
13284(define_expand "sltu"
13285 [(set (match_operand:QI 0 "register_operand" "")
13286 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287 ""
13288 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13289
13290(define_expand "sge"
13291 [(set (match_operand:QI 0 "register_operand" "")
13292 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293 ""
13294 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13295
13296(define_expand "sgeu"
13297 [(set (match_operand:QI 0 "register_operand" "")
13298 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299 ""
13300 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13301
13302(define_expand "sle"
13303 [(set (match_operand:QI 0 "register_operand" "")
13304 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305 ""
13306 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13307
13308(define_expand "sleu"
13309 [(set (match_operand:QI 0 "register_operand" "")
13310 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311 ""
13312 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13313
13314(define_expand "sunordered"
13315 [(set (match_operand:QI 0 "register_operand" "")
13316 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13317 "TARGET_80387 || TARGET_SSE"
13318 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13319
13320(define_expand "sordered"
13321 [(set (match_operand:QI 0 "register_operand" "")
13322 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323 "TARGET_80387"
13324 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13325
13326(define_expand "suneq"
13327 [(set (match_operand:QI 0 "register_operand" "")
13328 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329 "TARGET_80387 || TARGET_SSE"
13330 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13331
13332(define_expand "sunge"
13333 [(set (match_operand:QI 0 "register_operand" "")
13334 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13335 "TARGET_80387 || TARGET_SSE"
13336 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13337
13338(define_expand "sungt"
13339 [(set (match_operand:QI 0 "register_operand" "")
13340 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13341 "TARGET_80387 || TARGET_SSE"
13342 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13343
13344(define_expand "sunle"
13345 [(set (match_operand:QI 0 "register_operand" "")
13346 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13347 "TARGET_80387 || TARGET_SSE"
13348 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13349
13350(define_expand "sunlt"
13351 [(set (match_operand:QI 0 "register_operand" "")
13352 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13353 "TARGET_80387 || TARGET_SSE"
13354 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13355
13356(define_expand "sltgt"
13357 [(set (match_operand:QI 0 "register_operand" "")
13358 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13359 "TARGET_80387 || TARGET_SSE"
13360 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13361
13362(define_insn "*setcc_1"
13363 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13364 (match_operator:QI 1 "ix86_comparison_operator"
13365 [(reg FLAGS_REG) (const_int 0)]))]
13366 ""
13367 "set%C1\t%0"
13368 [(set_attr "type" "setcc")
13369 (set_attr "mode" "QI")])
13370
13371(define_insn "*setcc_2"
13372 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13373 (match_operator:QI 1 "ix86_comparison_operator"
13374 [(reg FLAGS_REG) (const_int 0)]))]
13375 ""
13376 "set%C1\t%0"
13377 [(set_attr "type" "setcc")
13378 (set_attr "mode" "QI")])
13379
13380;; In general it is not safe to assume too much about CCmode registers,
13381;; so simplify-rtx stops when it sees a second one. Under certain
13382;; conditions this is safe on x86, so help combine not create
13383;;
13384;; seta %al
13385;; testb %al, %al
13386;; sete %al
13387
13388(define_split
13389 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13390 (ne:QI (match_operator 1 "ix86_comparison_operator"
13391 [(reg FLAGS_REG) (const_int 0)])
13392 (const_int 0)))]
13393 ""
13394 [(set (match_dup 0) (match_dup 1))]
13395{
13396 PUT_MODE (operands[1], QImode);
13397})
13398
13399(define_split
13400 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13401 (ne:QI (match_operator 1 "ix86_comparison_operator"
13402 [(reg FLAGS_REG) (const_int 0)])
13403 (const_int 0)))]
13404 ""
13405 [(set (match_dup 0) (match_dup 1))]
13406{
13407 PUT_MODE (operands[1], QImode);
13408})
13409
13410(define_split
13411 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13412 (eq:QI (match_operator 1 "ix86_comparison_operator"
13413 [(reg FLAGS_REG) (const_int 0)])
13414 (const_int 0)))]
13415 ""
13416 [(set (match_dup 0) (match_dup 1))]
13417{
13418 rtx new_op1 = copy_rtx (operands[1]);
13419 operands[1] = new_op1;
13420 PUT_MODE (new_op1, QImode);
13421 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13422 GET_MODE (XEXP (new_op1, 0))));
13423
13424 /* Make sure that (a) the CCmode we have for the flags is strong
13425 enough for the reversed compare or (b) we have a valid FP compare. */
13426 if (! ix86_comparison_operator (new_op1, VOIDmode))
13427 FAIL;
13428})
13429
13430(define_split
13431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13432 (eq:QI (match_operator 1 "ix86_comparison_operator"
13433 [(reg FLAGS_REG) (const_int 0)])
13434 (const_int 0)))]
13435 ""
13436 [(set (match_dup 0) (match_dup 1))]
13437{
13438 rtx new_op1 = copy_rtx (operands[1]);
13439 operands[1] = new_op1;
13440 PUT_MODE (new_op1, QImode);
13441 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13442 GET_MODE (XEXP (new_op1, 0))));
13443
13444 /* Make sure that (a) the CCmode we have for the flags is strong
13445 enough for the reversed compare or (b) we have a valid FP compare. */
13446 if (! ix86_comparison_operator (new_op1, VOIDmode))
13447 FAIL;
13448})
13449
13450;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13451;; subsequent logical operations are used to imitate conditional moves.
13452;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13453;; it directly.
13454
13455(define_insn "*sse_setccsf"
13456 [(set (match_operand:SF 0 "register_operand" "=x")
13457 (match_operator:SF 1 "sse_comparison_operator"
13458 [(match_operand:SF 2 "register_operand" "0")
13459 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13460 "TARGET_SSE"
13461 "cmp%D1ss\t{%3, %0|%0, %3}"
13462 [(set_attr "type" "ssecmp")
13463 (set_attr "mode" "SF")])
13464
13465(define_insn "*sse_setccdf"
13466 [(set (match_operand:DF 0 "register_operand" "=Y")
13467 (match_operator:DF 1 "sse_comparison_operator"
13468 [(match_operand:DF 2 "register_operand" "0")
13469 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13470 "TARGET_SSE2"
13471 "cmp%D1sd\t{%3, %0|%0, %3}"
13472 [(set_attr "type" "ssecmp")
13473 (set_attr "mode" "DF")])
13474
13475;; Basic conditional jump instructions.
13476;; We ignore the overflow flag for signed branch instructions.
13477
13478;; For all bCOND expanders, also expand the compare or test insn that
13479;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13480
13481(define_expand "beq"
13482 [(set (pc)
13483 (if_then_else (match_dup 1)
13484 (label_ref (match_operand 0 "" ""))
13485 (pc)))]
13486 ""
13487 "ix86_expand_branch (EQ, operands[0]); DONE;")
13488
13489(define_expand "bne"
13490 [(set (pc)
13491 (if_then_else (match_dup 1)
13492 (label_ref (match_operand 0 "" ""))
13493 (pc)))]
13494 ""
13495 "ix86_expand_branch (NE, operands[0]); DONE;")
13496
13497(define_expand "bgt"
13498 [(set (pc)
13499 (if_then_else (match_dup 1)
13500 (label_ref (match_operand 0 "" ""))
13501 (pc)))]
13502 ""
13503 "ix86_expand_branch (GT, operands[0]); DONE;")
13504
13505(define_expand "bgtu"
13506 [(set (pc)
13507 (if_then_else (match_dup 1)
13508 (label_ref (match_operand 0 "" ""))
13509 (pc)))]
13510 ""
13511 "ix86_expand_branch (GTU, operands[0]); DONE;")
13512
13513(define_expand "blt"
13514 [(set (pc)
13515 (if_then_else (match_dup 1)
13516 (label_ref (match_operand 0 "" ""))
13517 (pc)))]
13518 ""
13519 "ix86_expand_branch (LT, operands[0]); DONE;")
13520
13521(define_expand "bltu"
13522 [(set (pc)
13523 (if_then_else (match_dup 1)
13524 (label_ref (match_operand 0 "" ""))
13525 (pc)))]
13526 ""
13527 "ix86_expand_branch (LTU, operands[0]); DONE;")
13528
13529(define_expand "bge"
13530 [(set (pc)
13531 (if_then_else (match_dup 1)
13532 (label_ref (match_operand 0 "" ""))
13533 (pc)))]
13534 ""
13535 "ix86_expand_branch (GE, operands[0]); DONE;")
13536
13537(define_expand "bgeu"
13538 [(set (pc)
13539 (if_then_else (match_dup 1)
13540 (label_ref (match_operand 0 "" ""))
13541 (pc)))]
13542 ""
13543 "ix86_expand_branch (GEU, operands[0]); DONE;")
13544
13545(define_expand "ble"
13546 [(set (pc)
13547 (if_then_else (match_dup 1)
13548 (label_ref (match_operand 0 "" ""))
13549 (pc)))]
13550 ""
13551 "ix86_expand_branch (LE, operands[0]); DONE;")
13552
13553(define_expand "bleu"
13554 [(set (pc)
13555 (if_then_else (match_dup 1)
13556 (label_ref (match_operand 0 "" ""))
13557 (pc)))]
13558 ""
13559 "ix86_expand_branch (LEU, operands[0]); DONE;")
13560
13561(define_expand "bunordered"
13562 [(set (pc)
13563 (if_then_else (match_dup 1)
13564 (label_ref (match_operand 0 "" ""))
13565 (pc)))]
13566 "TARGET_80387 || TARGET_SSE_MATH"
13567 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13568
13569(define_expand "bordered"
13570 [(set (pc)
13571 (if_then_else (match_dup 1)
13572 (label_ref (match_operand 0 "" ""))
13573 (pc)))]
13574 "TARGET_80387 || TARGET_SSE_MATH"
13575 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13576
13577(define_expand "buneq"
13578 [(set (pc)
13579 (if_then_else (match_dup 1)
13580 (label_ref (match_operand 0 "" ""))
13581 (pc)))]
13582 "TARGET_80387 || TARGET_SSE_MATH"
13583 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13584
13585(define_expand "bunge"
13586 [(set (pc)
13587 (if_then_else (match_dup 1)
13588 (label_ref (match_operand 0 "" ""))
13589 (pc)))]
13590 "TARGET_80387 || TARGET_SSE_MATH"
13591 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13592
13593(define_expand "bungt"
13594 [(set (pc)
13595 (if_then_else (match_dup 1)
13596 (label_ref (match_operand 0 "" ""))
13597 (pc)))]
13598 "TARGET_80387 || TARGET_SSE_MATH"
13599 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13600
13601(define_expand "bunle"
13602 [(set (pc)
13603 (if_then_else (match_dup 1)
13604 (label_ref (match_operand 0 "" ""))
13605 (pc)))]
13606 "TARGET_80387 || TARGET_SSE_MATH"
13607 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13608
13609(define_expand "bunlt"
13610 [(set (pc)
13611 (if_then_else (match_dup 1)
13612 (label_ref (match_operand 0 "" ""))
13613 (pc)))]
13614 "TARGET_80387 || TARGET_SSE_MATH"
13615 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13616
13617(define_expand "bltgt"
13618 [(set (pc)
13619 (if_then_else (match_dup 1)
13620 (label_ref (match_operand 0 "" ""))
13621 (pc)))]
13622 "TARGET_80387 || TARGET_SSE_MATH"
13623 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13624
13625(define_insn "*jcc_1"
13626 [(set (pc)
13627 (if_then_else (match_operator 1 "ix86_comparison_operator"
13628 [(reg FLAGS_REG) (const_int 0)])
13629 (label_ref (match_operand 0 "" ""))
13630 (pc)))]
13631 ""
13632 "%+j%C1\t%l0"
13633 [(set_attr "type" "ibr")
13634 (set_attr "modrm" "0")
13635 (set (attr "length")
13636 (if_then_else (and (ge (minus (match_dup 0) (pc))
13637 (const_int -126))
13638 (lt (minus (match_dup 0) (pc))
13639 (const_int 128)))
13640 (const_int 2)
13641 (const_int 6)))])
13642
13643(define_insn "*jcc_2"
13644 [(set (pc)
13645 (if_then_else (match_operator 1 "ix86_comparison_operator"
13646 [(reg FLAGS_REG) (const_int 0)])
13647 (pc)
13648 (label_ref (match_operand 0 "" ""))))]
13649 ""
13650 "%+j%c1\t%l0"
13651 [(set_attr "type" "ibr")
13652 (set_attr "modrm" "0")
13653 (set (attr "length")
13654 (if_then_else (and (ge (minus (match_dup 0) (pc))
13655 (const_int -126))
13656 (lt (minus (match_dup 0) (pc))
13657 (const_int 128)))
13658 (const_int 2)
13659 (const_int 6)))])
13660
13661;; In general it is not safe to assume too much about CCmode registers,
13662;; so simplify-rtx stops when it sees a second one. Under certain
13663;; conditions this is safe on x86, so help combine not create
13664;;
13665;; seta %al
13666;; testb %al, %al
13667;; je Lfoo
13668
13669(define_split
13670 [(set (pc)
13671 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13672 [(reg FLAGS_REG) (const_int 0)])
13673 (const_int 0))
13674 (label_ref (match_operand 1 "" ""))
13675 (pc)))]
13676 ""
13677 [(set (pc)
13678 (if_then_else (match_dup 0)
13679 (label_ref (match_dup 1))
13680 (pc)))]
13681{
13682 PUT_MODE (operands[0], VOIDmode);
13683})
13684
13685(define_split
13686 [(set (pc)
13687 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13688 [(reg FLAGS_REG) (const_int 0)])
13689 (const_int 0))
13690 (label_ref (match_operand 1 "" ""))
13691 (pc)))]
13692 ""
13693 [(set (pc)
13694 (if_then_else (match_dup 0)
13695 (label_ref (match_dup 1))
13696 (pc)))]
13697{
13698 rtx new_op0 = copy_rtx (operands[0]);
13699 operands[0] = new_op0;
13700 PUT_MODE (new_op0, VOIDmode);
13701 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13702 GET_MODE (XEXP (new_op0, 0))));
13703
13704 /* Make sure that (a) the CCmode we have for the flags is strong
13705 enough for the reversed compare or (b) we have a valid FP compare. */
13706 if (! ix86_comparison_operator (new_op0, VOIDmode))
13707 FAIL;
13708})
13709
13710;; Define combination compare-and-branch fp compare instructions to use
13711;; during early optimization. Splitting the operation apart early makes
13712;; for bad code when we want to reverse the operation.
13713
13714(define_insn "*fp_jcc_1_mixed"
13715 [(set (pc)
13716 (if_then_else (match_operator 0 "comparison_operator"
13717 [(match_operand 1 "register_operand" "f,x")
13718 (match_operand 2 "nonimmediate_operand" "f,xm")])
13719 (label_ref (match_operand 3 "" ""))
13720 (pc)))
13721 (clobber (reg:CCFP FPSR_REG))
13722 (clobber (reg:CCFP FLAGS_REG))]
13723 "TARGET_MIX_SSE_I387
13724 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13725 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13726 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13727 "#")
13728
13729(define_insn "*fp_jcc_1_sse"
13730 [(set (pc)
13731 (if_then_else (match_operator 0 "comparison_operator"
13732 [(match_operand 1 "register_operand" "x")
13733 (match_operand 2 "nonimmediate_operand" "xm")])
13734 (label_ref (match_operand 3 "" ""))
13735 (pc)))
13736 (clobber (reg:CCFP FPSR_REG))
13737 (clobber (reg:CCFP FLAGS_REG))]
13738 "TARGET_SSE_MATH
13739 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13740 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13742 "#")
13743
13744(define_insn "*fp_jcc_1_387"
13745 [(set (pc)
13746 (if_then_else (match_operator 0 "comparison_operator"
13747 [(match_operand 1 "register_operand" "f")
13748 (match_operand 2 "register_operand" "f")])
13749 (label_ref (match_operand 3 "" ""))
13750 (pc)))
13751 (clobber (reg:CCFP FPSR_REG))
13752 (clobber (reg:CCFP FLAGS_REG))]
13753 "TARGET_CMOVE && TARGET_80387
13754 && FLOAT_MODE_P (GET_MODE (operands[1]))
13755 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13756 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13757 "#")
13758
13759(define_insn "*fp_jcc_2_mixed"
13760 [(set (pc)
13761 (if_then_else (match_operator 0 "comparison_operator"
13762 [(match_operand 1 "register_operand" "f,x")
13763 (match_operand 2 "nonimmediate_operand" "f,xm")])
13764 (pc)
13765 (label_ref (match_operand 3 "" ""))))
13766 (clobber (reg:CCFP FPSR_REG))
13767 (clobber (reg:CCFP FLAGS_REG))]
13768 "TARGET_MIX_SSE_I387
13769 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13772 "#")
13773
13774(define_insn "*fp_jcc_2_sse"
13775 [(set (pc)
13776 (if_then_else (match_operator 0 "comparison_operator"
13777 [(match_operand 1 "register_operand" "x")
13778 (match_operand 2 "nonimmediate_operand" "xm")])
13779 (pc)
13780 (label_ref (match_operand 3 "" ""))))
13781 (clobber (reg:CCFP FPSR_REG))
13782 (clobber (reg:CCFP FLAGS_REG))]
13783 "TARGET_SSE_MATH
13784 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13785 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13786 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13787 "#")
13788
13789(define_insn "*fp_jcc_2_387"
13790 [(set (pc)
13791 (if_then_else (match_operator 0 "comparison_operator"
13792 [(match_operand 1 "register_operand" "f")
13793 (match_operand 2 "register_operand" "f")])
13794 (pc)
13795 (label_ref (match_operand 3 "" ""))))
13796 (clobber (reg:CCFP FPSR_REG))
13797 (clobber (reg:CCFP FLAGS_REG))]
13798 "TARGET_CMOVE && TARGET_80387
13799 && FLOAT_MODE_P (GET_MODE (operands[1]))
13800 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13801 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13802 "#")
13803
13804(define_insn "*fp_jcc_3_387"
13805 [(set (pc)
13806 (if_then_else (match_operator 0 "comparison_operator"
13807 [(match_operand 1 "register_operand" "f")
13808 (match_operand 2 "nonimmediate_operand" "fm")])
13809 (label_ref (match_operand 3 "" ""))
13810 (pc)))
13811 (clobber (reg:CCFP FPSR_REG))
13812 (clobber (reg:CCFP FLAGS_REG))
13813 (clobber (match_scratch:HI 4 "=a"))]
13814 "TARGET_80387
13815 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13816 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13817 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13818 && SELECT_CC_MODE (GET_CODE (operands[0]),
13819 operands[1], operands[2]) == CCFPmode
13820 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13821 "#")
13822
13823(define_insn "*fp_jcc_4_387"
13824 [(set (pc)
13825 (if_then_else (match_operator 0 "comparison_operator"
13826 [(match_operand 1 "register_operand" "f")
13827 (match_operand 2 "nonimmediate_operand" "fm")])
13828 (pc)
13829 (label_ref (match_operand 3 "" ""))))
13830 (clobber (reg:CCFP FPSR_REG))
13831 (clobber (reg:CCFP FLAGS_REG))
13832 (clobber (match_scratch:HI 4 "=a"))]
13833 "TARGET_80387
13834 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13835 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13836 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13837 && SELECT_CC_MODE (GET_CODE (operands[0]),
13838 operands[1], operands[2]) == CCFPmode
13839 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13840 "#")
13841
13842(define_insn "*fp_jcc_5_387"
13843 [(set (pc)
13844 (if_then_else (match_operator 0 "comparison_operator"
13845 [(match_operand 1 "register_operand" "f")
13846 (match_operand 2 "register_operand" "f")])
13847 (label_ref (match_operand 3 "" ""))
13848 (pc)))
13849 (clobber (reg:CCFP FPSR_REG))
13850 (clobber (reg:CCFP FLAGS_REG))
13851 (clobber (match_scratch:HI 4 "=a"))]
13852 "TARGET_80387
13853 && FLOAT_MODE_P (GET_MODE (operands[1]))
13854 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13855 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13856 "#")
13857
13858(define_insn "*fp_jcc_6_387"
13859 [(set (pc)
13860 (if_then_else (match_operator 0 "comparison_operator"
13861 [(match_operand 1 "register_operand" "f")
13862 (match_operand 2 "register_operand" "f")])
13863 (pc)
13864 (label_ref (match_operand 3 "" ""))))
13865 (clobber (reg:CCFP FPSR_REG))
13866 (clobber (reg:CCFP FLAGS_REG))
13867 (clobber (match_scratch:HI 4 "=a"))]
13868 "TARGET_80387
13869 && FLOAT_MODE_P (GET_MODE (operands[1]))
13870 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13871 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13872 "#")
13873
13874(define_insn "*fp_jcc_7_387"
13875 [(set (pc)
13876 (if_then_else (match_operator 0 "comparison_operator"
13877 [(match_operand 1 "register_operand" "f")
13878 (match_operand 2 "const0_operand" "X")])
13879 (label_ref (match_operand 3 "" ""))
13880 (pc)))
13881 (clobber (reg:CCFP FPSR_REG))
13882 (clobber (reg:CCFP FLAGS_REG))
13883 (clobber (match_scratch:HI 4 "=a"))]
13884 "TARGET_80387
13885 && FLOAT_MODE_P (GET_MODE (operands[1]))
13886 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13887 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13888 && SELECT_CC_MODE (GET_CODE (operands[0]),
13889 operands[1], operands[2]) == CCFPmode
13890 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13891 "#")
13892
13893;; The order of operands in *fp_jcc_8_387 is forced by combine in
13894;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13895;; with a precedence over other operators and is always put in the first
13896;; place. Swap condition and operands to match ficom instruction.
13897
13898(define_insn "*fp_jcc_8<mode>_387"
13899 [(set (pc)
13900 (if_then_else (match_operator 0 "comparison_operator"
13901 [(match_operator 1 "float_operator"
13902 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13903 (match_operand 3 "register_operand" "f,f")])
13904 (label_ref (match_operand 4 "" ""))
13905 (pc)))
13906 (clobber (reg:CCFP FPSR_REG))
13907 (clobber (reg:CCFP FLAGS_REG))
13908 (clobber (match_scratch:HI 5 "=a,a"))]
13909 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13910 && FLOAT_MODE_P (GET_MODE (operands[3]))
13911 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13912 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13913 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13914 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13915 "#")
13916
13917(define_split
13918 [(set (pc)
13919 (if_then_else (match_operator 0 "comparison_operator"
13920 [(match_operand 1 "register_operand" "")
13921 (match_operand 2 "nonimmediate_operand" "")])
13922 (match_operand 3 "" "")
13923 (match_operand 4 "" "")))
13924 (clobber (reg:CCFP FPSR_REG))
13925 (clobber (reg:CCFP FLAGS_REG))]
13926 "reload_completed"
13927 [(const_int 0)]
13928{
13929 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13930 operands[3], operands[4], NULL_RTX, NULL_RTX);
13931 DONE;
13932})
13933
13934(define_split
13935 [(set (pc)
13936 (if_then_else (match_operator 0 "comparison_operator"
13937 [(match_operand 1 "register_operand" "")
13938 (match_operand 2 "general_operand" "")])
13939 (match_operand 3 "" "")
13940 (match_operand 4 "" "")))
13941 (clobber (reg:CCFP FPSR_REG))
13942 (clobber (reg:CCFP FLAGS_REG))
13943 (clobber (match_scratch:HI 5 "=a"))]
13944 "reload_completed"
13945 [(const_int 0)]
13946{
13947 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13948 operands[3], operands[4], operands[5], NULL_RTX);
13949 DONE;
13950})
13951
13952(define_split
13953 [(set (pc)
13954 (if_then_else (match_operator 0 "comparison_operator"
13955 [(match_operator 1 "float_operator"
13956 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13957 (match_operand 3 "register_operand" "")])
13958 (match_operand 4 "" "")
13959 (match_operand 5 "" "")))
13960 (clobber (reg:CCFP FPSR_REG))
13961 (clobber (reg:CCFP FLAGS_REG))
13962 (clobber (match_scratch:HI 6 "=a"))]
13963 "reload_completed"
13964 [(const_int 0)]
13965{
13966 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13967 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13968 operands[3], operands[7],
13969 operands[4], operands[5], operands[6], NULL_RTX);
13970 DONE;
13971})
13972
13973;; %%% Kill this when reload knows how to do it.
13974(define_split
13975 [(set (pc)
13976 (if_then_else (match_operator 0 "comparison_operator"
13977 [(match_operator 1 "float_operator"
13978 [(match_operand:X87MODEI12 2 "register_operand" "")])
13979 (match_operand 3 "register_operand" "")])
13980 (match_operand 4 "" "")
13981 (match_operand 5 "" "")))
13982 (clobber (reg:CCFP FPSR_REG))
13983 (clobber (reg:CCFP FLAGS_REG))
13984 (clobber (match_scratch:HI 6 "=a"))]
13985 "reload_completed"
13986 [(const_int 0)]
13987{
13988 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13989 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13990 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13991 operands[3], operands[7],
13992 operands[4], operands[5], operands[6], operands[2]);
13993 DONE;
13994})
13995
13996;; Unconditional and other jump instructions
13997
13998(define_insn "jump"
13999 [(set (pc)
14000 (label_ref (match_operand 0 "" "")))]
14001 ""
14002 "jmp\t%l0"
14003 [(set_attr "type" "ibr")
14004 (set (attr "length")
14005 (if_then_else (and (ge (minus (match_dup 0) (pc))
14006 (const_int -126))
14007 (lt (minus (match_dup 0) (pc))
14008 (const_int 128)))
14009 (const_int 2)
14010 (const_int 5)))
14011 (set_attr "modrm" "0")])
14012
14013(define_expand "indirect_jump"
14014 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14015 ""
14016 "")
14017
14018(define_insn "*indirect_jump"
14019 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14020 "!TARGET_64BIT"
14021 "jmp\t%A0"
14022 [(set_attr "type" "ibr")
14023 (set_attr "length_immediate" "0")])
14024
14025(define_insn "*indirect_jump_rtx64"
14026 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14027 "TARGET_64BIT"
14028 "jmp\t%A0"
14029 [(set_attr "type" "ibr")
14030 (set_attr "length_immediate" "0")])
14031
14032(define_expand "tablejump"
14033 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14034 (use (label_ref (match_operand 1 "" "")))])]
14035 ""
14036{
14037 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14038 relative. Convert the relative address to an absolute address. */
14039 if (flag_pic)
14040 {
14041 rtx op0, op1;
14042 enum rtx_code code;
14043
14044 if (TARGET_64BIT)
14045 {
14046 code = PLUS;
14047 op0 = operands[0];
14048 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14049 }
14050 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14051 {
14052 code = PLUS;
14053 op0 = operands[0];
14054 op1 = pic_offset_table_rtx;
14055 }
14056 else
14057 {
14058 code = MINUS;
14059 op0 = pic_offset_table_rtx;
14060 op1 = operands[0];
14061 }
14062
14063 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14064 OPTAB_DIRECT);
14065 }
14066})
14067
14068(define_insn "*tablejump_1"
14069 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14070 (use (label_ref (match_operand 1 "" "")))]
14071 "!TARGET_64BIT"
14072 "jmp\t%A0"
14073 [(set_attr "type" "ibr")
14074 (set_attr "length_immediate" "0")])
14075
14076(define_insn "*tablejump_1_rtx64"
14077 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14078 (use (label_ref (match_operand 1 "" "")))]
14079 "TARGET_64BIT"
14080 "jmp\t%A0"
14081 [(set_attr "type" "ibr")
14082 (set_attr "length_immediate" "0")])
14083
14084;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14085
14086(define_peephole2
14087 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14088 (set (match_operand:QI 1 "register_operand" "")
14089 (match_operator:QI 2 "ix86_comparison_operator"
14090 [(reg FLAGS_REG) (const_int 0)]))
14091 (set (match_operand 3 "q_regs_operand" "")
14092 (zero_extend (match_dup 1)))]
14093 "(peep2_reg_dead_p (3, operands[1])
14094 || operands_match_p (operands[1], operands[3]))
14095 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14096 [(set (match_dup 4) (match_dup 0))
14097 (set (strict_low_part (match_dup 5))
14098 (match_dup 2))]
14099{
14100 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14101 operands[5] = gen_lowpart (QImode, operands[3]);
14102 ix86_expand_clear (operands[3]);
14103})
14104
14105;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14106
14107(define_peephole2
14108 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14109 (set (match_operand:QI 1 "register_operand" "")
14110 (match_operator:QI 2 "ix86_comparison_operator"
14111 [(reg FLAGS_REG) (const_int 0)]))
14112 (parallel [(set (match_operand 3 "q_regs_operand" "")
14113 (zero_extend (match_dup 1)))
14114 (clobber (reg:CC FLAGS_REG))])]
14115 "(peep2_reg_dead_p (3, operands[1])
14116 || operands_match_p (operands[1], operands[3]))
14117 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14118 [(set (match_dup 4) (match_dup 0))
14119 (set (strict_low_part (match_dup 5))
14120 (match_dup 2))]
14121{
14122 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14123 operands[5] = gen_lowpart (QImode, operands[3]);
14124 ix86_expand_clear (operands[3]);
14125})
14126
14127;; Call instructions.
14128
14129;; The predicates normally associated with named expanders are not properly
14130;; checked for calls. This is a bug in the generic code, but it isn't that
14131;; easy to fix. Ignore it for now and be prepared to fix things up.
14132
14133;; Call subroutine returning no value.
14134
14135(define_expand "call_pop"
14136 [(parallel [(call (match_operand:QI 0 "" "")
14137 (match_operand:SI 1 "" ""))
14138 (set (reg:SI SP_REG)
14139 (plus:SI (reg:SI SP_REG)
14140 (match_operand:SI 3 "" "")))])]
14141 "!TARGET_64BIT"
14142{
14143 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14144 DONE;
14145})
14146
14147(define_insn "*call_pop_0"
14148 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14149 (match_operand:SI 1 "" ""))
14150 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14151 (match_operand:SI 2 "immediate_operand" "")))]
14152 "!TARGET_64BIT"
14153{
14154 if (SIBLING_CALL_P (insn))
14155 return "jmp\t%P0";
14156 else
14157 return "call\t%P0";
14158}
14159 [(set_attr "type" "call")])
14160
14161(define_insn "*call_pop_1"
14162 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14163 (match_operand:SI 1 "" ""))
14164 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14165 (match_operand:SI 2 "immediate_operand" "i")))]
14166 "!TARGET_64BIT"
14167{
14168 if (constant_call_address_operand (operands[0], Pmode))
14169 {
14170 if (SIBLING_CALL_P (insn))
14171 return "jmp\t%P0";
14172 else
14173 return "call\t%P0";
14174 }
14175 if (SIBLING_CALL_P (insn))
14176 return "jmp\t%A0";
14177 else
14178 return "call\t%A0";
14179}
14180 [(set_attr "type" "call")])
14181
14182(define_expand "call"
14183 [(call (match_operand:QI 0 "" "")
14184 (match_operand 1 "" ""))
14185 (use (match_operand 2 "" ""))]
14186 ""
14187{
14188 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14189 DONE;
14190})
14191
14192(define_expand "sibcall"
14193 [(call (match_operand:QI 0 "" "")
14194 (match_operand 1 "" ""))
14195 (use (match_operand 2 "" ""))]
14196 ""
14197{
14198 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14199 DONE;
14200})
14201
14202(define_insn "*call_0"
14203 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14204 (match_operand 1 "" ""))]
14205 ""
14206{
14207 if (SIBLING_CALL_P (insn))
14208 return "jmp\t%P0";
14209 else
14210 return "call\t%P0";
14211}
14212 [(set_attr "type" "call")])
14213
14214(define_insn "*call_1"
14215 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14216 (match_operand 1 "" ""))]
14217 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14218{
14219 if (constant_call_address_operand (operands[0], Pmode))
14220 return "call\t%P0";
14221 return "call\t%A0";
14222}
14223 [(set_attr "type" "call")])
14224
14225(define_insn "*sibcall_1"
14226 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14227 (match_operand 1 "" ""))]
14228 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14229{
14230 if (constant_call_address_operand (operands[0], Pmode))
14231 return "jmp\t%P0";
14232 return "jmp\t%A0";
14233}
14234 [(set_attr "type" "call")])
14235
14236(define_insn "*call_1_rex64"
14237 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14238 (match_operand 1 "" ""))]
14239 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14240{
14241 if (constant_call_address_operand (operands[0], Pmode))
14242 return "call\t%P0";
14243 return "call\t%A0";
14244}
14245 [(set_attr "type" "call")])
14246
14247(define_insn "*sibcall_1_rex64"
14248 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14249 (match_operand 1 "" ""))]
14250 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14251 "jmp\t%P0"
14252 [(set_attr "type" "call")])
14253
14254(define_insn "*sibcall_1_rex64_v"
14255 [(call (mem:QI (reg:DI 40))
14256 (match_operand 0 "" ""))]
14257 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14258 "jmp\t*%%r11"
14259 [(set_attr "type" "call")])
14260
14261
14262;; Call subroutine, returning value in operand 0
14263
14264(define_expand "call_value_pop"
14265 [(parallel [(set (match_operand 0 "" "")
14266 (call (match_operand:QI 1 "" "")
14267 (match_operand:SI 2 "" "")))
14268 (set (reg:SI SP_REG)
14269 (plus:SI (reg:SI SP_REG)
14270 (match_operand:SI 4 "" "")))])]
14271 "!TARGET_64BIT"
14272{
14273 ix86_expand_call (operands[0], operands[1], operands[2],
14274 operands[3], operands[4], 0);
14275 DONE;
14276})
14277
14278(define_expand "call_value"
14279 [(set (match_operand 0 "" "")
14280 (call (match_operand:QI 1 "" "")
14281 (match_operand:SI 2 "" "")))
14282 (use (match_operand:SI 3 "" ""))]
14283 ;; Operand 2 not used on the i386.
14284 ""
14285{
14286 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14287 DONE;
14288})
14289
14290(define_expand "sibcall_value"
14291 [(set (match_operand 0 "" "")
14292 (call (match_operand:QI 1 "" "")
14293 (match_operand:SI 2 "" "")))
14294 (use (match_operand:SI 3 "" ""))]
14295 ;; Operand 2 not used on the i386.
14296 ""
14297{
14298 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14299 DONE;
14300})
14301
14302;; Call subroutine returning any type.
14303
14304(define_expand "untyped_call"
14305 [(parallel [(call (match_operand 0 "" "")
14306 (const_int 0))
14307 (match_operand 1 "" "")
14308 (match_operand 2 "" "")])]
14309 ""
14310{
14311 int i;
14312
14313 /* In order to give reg-stack an easier job in validating two
14314 coprocessor registers as containing a possible return value,
14315 simply pretend the untyped call returns a complex long double
14316 value. */
14317
14318 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14319 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14320 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14321 NULL, 0);
14322
14323 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14324 {
14325 rtx set = XVECEXP (operands[2], 0, i);
14326 emit_move_insn (SET_DEST (set), SET_SRC (set));
14327 }
14328
14329 /* The optimizer does not know that the call sets the function value
14330 registers we stored in the result block. We avoid problems by
14331 claiming that all hard registers are used and clobbered at this
14332 point. */
14333 emit_insn (gen_blockage (const0_rtx));
14334
14335 DONE;
14336})
14337
14338;; Prologue and epilogue instructions
14339
14340;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14341;; all of memory. This blocks insns from being moved across this point.
14342
14343(define_insn "blockage"
14344 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14345 ""
14346 ""
14347 [(set_attr "length" "0")])
14348
14349;; Insn emitted into the body of a function to return from a function.
14350;; This is only done if the function's epilogue is known to be simple.
14351;; See comments for ix86_can_use_return_insn_p in i386.c.
14352
14353(define_expand "return"
14354 [(return)]
14355 "ix86_can_use_return_insn_p ()"
14356{
14357 if (current_function_pops_args)
14358 {
14359 rtx popc = GEN_INT (current_function_pops_args);
14360 emit_jump_insn (gen_return_pop_internal (popc));
14361 DONE;
14362 }
14363})
14364
14365(define_insn "return_internal"
14366 [(return)]
14367 "reload_completed"
14368 "ret"
14369 [(set_attr "length" "1")
14370 (set_attr "length_immediate" "0")
14371 (set_attr "modrm" "0")])
14372
14373;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14374;; instruction Athlon and K8 have.
14375
14376(define_insn "return_internal_long"
14377 [(return)
14378 (unspec [(const_int 0)] UNSPEC_REP)]
14379 "reload_completed"
14380 "rep {;} ret"
14381 [(set_attr "length" "1")
14382 (set_attr "length_immediate" "0")
14383 (set_attr "prefix_rep" "1")
14384 (set_attr "modrm" "0")])
14385
14386(define_insn "return_pop_internal"
14387 [(return)
14388 (use (match_operand:SI 0 "const_int_operand" ""))]
14389 "reload_completed"
14390 "ret\t%0"
14391 [(set_attr "length" "3")
14392 (set_attr "length_immediate" "2")
14393 (set_attr "modrm" "0")])
14394
14395(define_insn "return_indirect_internal"
14396 [(return)
14397 (use (match_operand:SI 0 "register_operand" "r"))]
14398 "reload_completed"
14399 "jmp\t%A0"
14400 [(set_attr "type" "ibr")
14401 (set_attr "length_immediate" "0")])
14402
14403(define_insn "nop"
14404 [(const_int 0)]
14405 ""
14406 "nop"
14407 [(set_attr "length" "1")
14408 (set_attr "length_immediate" "0")
14409 (set_attr "modrm" "0")])
14410
14411;; Align to 16-byte boundary, max skip in op0. Used to avoid
14412;; branch prediction penalty for the third jump in a 16-byte
14413;; block on K8.
14414
14415(define_insn "align"
14416 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14417 ""
14418{
14419#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14420 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14421#else
14422 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14423 The align insn is used to avoid 3 jump instructions in the row to improve
14424 branch prediction and the benefits hardly outweigh the cost of extra 8
14425 nops on the average inserted by full alignment pseudo operation. */
14426#endif
14427 return "";
14428}
14429 [(set_attr "length" "16")])
14430
14431(define_expand "prologue"
14432 [(const_int 1)]
14433 ""
14434 "ix86_expand_prologue (); DONE;")
14435
14436(define_insn "set_got"
14437 [(set (match_operand:SI 0 "register_operand" "=r")
14438 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14439 (clobber (reg:CC FLAGS_REG))]
14440 "!TARGET_64BIT"
14441 { return output_set_got (operands[0], NULL_RTX); }
14442 [(set_attr "type" "multi")
14443 (set_attr "length" "12")])
14444
14445(define_insn "set_got_labelled"
14446 [(set (match_operand:SI 0 "register_operand" "=r")
14447 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14448 UNSPEC_SET_GOT))
14449 (clobber (reg:CC FLAGS_REG))]
14450 "!TARGET_64BIT"
14451 { return output_set_got (operands[0], operands[1]); }
14452 [(set_attr "type" "multi")
14453 (set_attr "length" "12")])
14454
14455(define_insn "set_got_rex64"
14456 [(set (match_operand:DI 0 "register_operand" "=r")
14457 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14458 "TARGET_64BIT"
14459 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14460 [(set_attr "type" "lea")
14461 (set_attr "length" "6")])
14462
14463(define_expand "epilogue"
14464 [(const_int 1)]
14465 ""
14466 "ix86_expand_epilogue (1); DONE;")
14467
14468(define_expand "sibcall_epilogue"
14469 [(const_int 1)]
14470 ""
14471 "ix86_expand_epilogue (0); DONE;")
14472
14473(define_expand "eh_return"
14474 [(use (match_operand 0 "register_operand" ""))]
14475 ""
14476{
14477 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14478
14479 /* Tricky bit: we write the address of the handler to which we will
14480 be returning into someone else's stack frame, one word below the
14481 stack address we wish to restore. */
14482 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14483 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14484 tmp = gen_rtx_MEM (Pmode, tmp);
14485 emit_move_insn (tmp, ra);
14486
14487 if (Pmode == SImode)
14488 emit_jump_insn (gen_eh_return_si (sa));
14489 else
14490 emit_jump_insn (gen_eh_return_di (sa));
14491 emit_barrier ();
14492 DONE;
14493})
14494
14495(define_insn_and_split "eh_return_si"
14496 [(set (pc)
14497 (unspec [(match_operand:SI 0 "register_operand" "c")]
14498 UNSPEC_EH_RETURN))]
14499 "!TARGET_64BIT"
14500 "#"
14501 "reload_completed"
14502 [(const_int 1)]
14503 "ix86_expand_epilogue (2); DONE;")
14504
14505(define_insn_and_split "eh_return_di"
14506 [(set (pc)
14507 (unspec [(match_operand:DI 0 "register_operand" "c")]
14508 UNSPEC_EH_RETURN))]
14509 "TARGET_64BIT"
14510 "#"
14511 "reload_completed"
14512 [(const_int 1)]
14513 "ix86_expand_epilogue (2); DONE;")
14514
14515(define_insn "leave"
14516 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14517 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14518 (clobber (mem:BLK (scratch)))]
14519 "!TARGET_64BIT"
14520 "leave"
14521 [(set_attr "type" "leave")])
14522
14523(define_insn "leave_rex64"
14524 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14525 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14526 (clobber (mem:BLK (scratch)))]
14527 "TARGET_64BIT"
14528 "leave"
14529 [(set_attr "type" "leave")])
14530
14531(define_expand "ffssi2"
14532 [(parallel
14533 [(set (match_operand:SI 0 "register_operand" "")
14534 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14535 (clobber (match_scratch:SI 2 ""))
14536 (clobber (reg:CC FLAGS_REG))])]
14537 ""
14538 "")
14539
14540(define_insn_and_split "*ffs_cmove"
14541 [(set (match_operand:SI 0 "register_operand" "=r")
14542 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14543 (clobber (match_scratch:SI 2 "=&r"))
14544 (clobber (reg:CC FLAGS_REG))]
14545 "TARGET_CMOVE"
14546 "#"
14547 "&& reload_completed"
14548 [(set (match_dup 2) (const_int -1))
14549 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14550 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14551 (set (match_dup 0) (if_then_else:SI
14552 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14553 (match_dup 2)
14554 (match_dup 0)))
14555 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14556 (clobber (reg:CC FLAGS_REG))])]
14557 "")
14558
14559(define_insn_and_split "*ffs_no_cmove"
14560 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14561 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14562 (clobber (match_scratch:SI 2 "=&q"))
14563 (clobber (reg:CC FLAGS_REG))]
14564 ""
14565 "#"
14566 "reload_completed"
14567 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14568 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14569 (set (strict_low_part (match_dup 3))
14570 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14571 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14572 (clobber (reg:CC FLAGS_REG))])
14573 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14574 (clobber (reg:CC FLAGS_REG))])
14575 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14576 (clobber (reg:CC FLAGS_REG))])]
14577{
14578 operands[3] = gen_lowpart (QImode, operands[2]);
14579 ix86_expand_clear (operands[2]);
14580})
14581
14582(define_insn "*ffssi_1"
14583 [(set (reg:CCZ FLAGS_REG)
14584 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14585 (const_int 0)))
14586 (set (match_operand:SI 0 "register_operand" "=r")
14587 (ctz:SI (match_dup 1)))]
14588 ""
14589 "bsf{l}\t{%1, %0|%0, %1}"
14590 [(set_attr "prefix_0f" "1")])
14591
14592(define_expand "ffsdi2"
14593 [(parallel
14594 [(set (match_operand:DI 0 "register_operand" "")
14595 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14596 (clobber (match_scratch:DI 2 ""))
14597 (clobber (reg:CC FLAGS_REG))])]
14598 "TARGET_64BIT && TARGET_CMOVE"
14599 "")
14600
14601(define_insn_and_split "*ffs_rex64"
14602 [(set (match_operand:DI 0 "register_operand" "=r")
14603 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14604 (clobber (match_scratch:DI 2 "=&r"))
14605 (clobber (reg:CC FLAGS_REG))]
14606 "TARGET_64BIT && TARGET_CMOVE"
14607 "#"
14608 "&& reload_completed"
14609 [(set (match_dup 2) (const_int -1))
14610 (parallel [(set (reg:CCZ FLAGS_REG)
14611 (compare:CCZ (match_dup 1) (const_int 0)))
14612 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14613 (set (match_dup 0) (if_then_else:DI
14614 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14615 (match_dup 2)
14616 (match_dup 0)))
14617 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14618 (clobber (reg:CC FLAGS_REG))])]
14619 "")
14620
14621(define_insn "*ffsdi_1"
14622 [(set (reg:CCZ FLAGS_REG)
14623 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14624 (const_int 0)))
14625 (set (match_operand:DI 0 "register_operand" "=r")
14626 (ctz:DI (match_dup 1)))]
14627 "TARGET_64BIT"
14628 "bsf{q}\t{%1, %0|%0, %1}"
14629 [(set_attr "prefix_0f" "1")])
14630
14631(define_insn "ctzsi2"
14632 [(set (match_operand:SI 0 "register_operand" "=r")
14633 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14634 (clobber (reg:CC FLAGS_REG))]
14635 ""
14636 "bsf{l}\t{%1, %0|%0, %1}"
14637 [(set_attr "prefix_0f" "1")])
14638
14639(define_insn "ctzdi2"
14640 [(set (match_operand:DI 0 "register_operand" "=r")
14641 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14642 (clobber (reg:CC FLAGS_REG))]
14643 "TARGET_64BIT"
14644 "bsf{q}\t{%1, %0|%0, %1}"
14645 [(set_attr "prefix_0f" "1")])
14646
14647(define_expand "clzsi2"
14648 [(parallel
14649 [(set (match_operand:SI 0 "register_operand" "")
14650 (minus:SI (const_int 31)
14651 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14652 (clobber (reg:CC FLAGS_REG))])
14653 (parallel
14654 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14655 (clobber (reg:CC FLAGS_REG))])]
14656 ""
14561 "")
14657{
14658 if (TARGET_ABM)
14659 {
14660 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14661 DONE;
14662 }
14663})
14562
14664
14665(define_insn "clzsi2_abm"
14666 [(set (match_operand:SI 0 "register_operand" "=r")
14667 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14668 (clobber (reg:CC FLAGS_REG))]
14669 "TARGET_ABM"
14670 "lzcnt{l}\t{%1, %0|%0, %1}"
14671 [(set_attr "prefix_rep" "1")
14672 (set_attr "type" "bitmanip")
14673 (set_attr "mode" "SI")])
14674
14563(define_insn "*bsr"
14564 [(set (match_operand:SI 0 "register_operand" "=r")
14565 (minus:SI (const_int 31)
14566 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14567 (clobber (reg:CC FLAGS_REG))]
14568 ""
14569 "bsr{l}\t{%1, %0|%0, %1}"
14675(define_insn "*bsr"
14676 [(set (match_operand:SI 0 "register_operand" "=r")
14677 (minus:SI (const_int 31)
14678 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14679 (clobber (reg:CC FLAGS_REG))]
14680 ""
14681 "bsr{l}\t{%1, %0|%0, %1}"
14570 [(set_attr "prefix_0f" "1")])
14682 [(set_attr "prefix_0f" "1")
14683 (set_attr "mode" "SI")])
14571
14684
14685(define_insn "popcountsi2"
14686 [(set (match_operand:SI 0 "register_operand" "=r")
14687 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14688 (clobber (reg:CC FLAGS_REG))]
14689 "TARGET_POPCNT"
14690 "popcnt{l}\t{%1, %0|%0, %1}"
14691 [(set_attr "prefix_rep" "1")
14692 (set_attr "type" "bitmanip")
14693 (set_attr "mode" "SI")])
14694
14695(define_insn "*popcountsi2_cmp"
14696 [(set (reg FLAGS_REG)
14697 (compare
14698 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14699 (const_int 0)))
14700 (set (match_operand:SI 0 "register_operand" "=r")
14701 (popcount:SI (match_dup 1)))]
14702 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14703 "popcnt{l}\t{%1, %0|%0, %1}"
14704 [(set_attr "prefix_rep" "1")
14705 (set_attr "type" "bitmanip")
14706 (set_attr "mode" "SI")])
14707
14708(define_insn "*popcountsi2_cmp_zext"
14709 [(set (reg FLAGS_REG)
14710 (compare
14711 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14712 (const_int 0)))
14713 (set (match_operand:DI 0 "register_operand" "=r")
14714 (zero_extend:DI(popcount:SI (match_dup 1))))]
14715 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14716 "popcnt{l}\t{%1, %0|%0, %1}"
14717 [(set_attr "prefix_rep" "1")
14718 (set_attr "type" "bitmanip")
14719 (set_attr "mode" "SI")])
14720
14572(define_expand "clzdi2"
14573 [(parallel
14574 [(set (match_operand:DI 0 "register_operand" "")
14575 (minus:DI (const_int 63)
14576 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14577 (clobber (reg:CC FLAGS_REG))])
14578 (parallel
14579 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14580 (clobber (reg:CC FLAGS_REG))])]
14581 "TARGET_64BIT"
14721(define_expand "clzdi2"
14722 [(parallel
14723 [(set (match_operand:DI 0 "register_operand" "")
14724 (minus:DI (const_int 63)
14725 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14726 (clobber (reg:CC FLAGS_REG))])
14727 (parallel
14728 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14729 (clobber (reg:CC FLAGS_REG))])]
14730 "TARGET_64BIT"
14582 "")
14731{
14732 if (TARGET_ABM)
14733 {
14734 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14735 DONE;
14736 }
14737})
14583
14738
14739(define_insn "clzdi2_abm"
14740 [(set (match_operand:DI 0 "register_operand" "=r")
14741 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14742 (clobber (reg:CC FLAGS_REG))]
14743 "TARGET_64BIT && TARGET_ABM"
14744 "lzcnt{q}\t{%1, %0|%0, %1}"
14745 [(set_attr "prefix_rep" "1")
14746 (set_attr "type" "bitmanip")
14747 (set_attr "mode" "DI")])
14748
14584(define_insn "*bsr_rex64"
14585 [(set (match_operand:DI 0 "register_operand" "=r")
14586 (minus:DI (const_int 63)
14587 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14588 (clobber (reg:CC FLAGS_REG))]
14589 "TARGET_64BIT"
14590 "bsr{q}\t{%1, %0|%0, %1}"
14749(define_insn "*bsr_rex64"
14750 [(set (match_operand:DI 0 "register_operand" "=r")
14751 (minus:DI (const_int 63)
14752 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14753 (clobber (reg:CC FLAGS_REG))]
14754 "TARGET_64BIT"
14755 "bsr{q}\t{%1, %0|%0, %1}"
14591 [(set_attr "prefix_0f" "1")])
14756 [(set_attr "prefix_0f" "1")
14757 (set_attr "mode" "DI")])
14758
14759(define_insn "popcountdi2"
14760 [(set (match_operand:DI 0 "register_operand" "=r")
14761 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14762 (clobber (reg:CC FLAGS_REG))]
14763 "TARGET_64BIT && TARGET_POPCNT"
14764 "popcnt{q}\t{%1, %0|%0, %1}"
14765 [(set_attr "prefix_rep" "1")
14766 (set_attr "type" "bitmanip")
14767 (set_attr "mode" "DI")])
14768
14769(define_insn "*popcountdi2_cmp"
14770 [(set (reg FLAGS_REG)
14771 (compare
14772 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14773 (const_int 0)))
14774 (set (match_operand:DI 0 "register_operand" "=r")
14775 (popcount:DI (match_dup 1)))]
14776 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14777 "popcnt{q}\t{%1, %0|%0, %1}"
14778 [(set_attr "prefix_rep" "1")
14779 (set_attr "type" "bitmanip")
14780 (set_attr "mode" "DI")])
14781
14782(define_expand "clzhi2"
14783 [(parallel
14784 [(set (match_operand:HI 0 "register_operand" "")
14785 (minus:HI (const_int 15)
14786 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14787 (clobber (reg:CC FLAGS_REG))])
14788 (parallel
14789 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14790 (clobber (reg:CC FLAGS_REG))])]
14791 ""
14792{
14793 if (TARGET_ABM)
14794 {
14795 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14796 DONE;
14797 }
14798})
14799
14800(define_insn "clzhi2_abm"
14801 [(set (match_operand:HI 0 "register_operand" "=r")
14802 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14803 (clobber (reg:CC FLAGS_REG))]
14804 "TARGET_ABM"
14805 "lzcnt{w}\t{%1, %0|%0, %1}"
14806 [(set_attr "prefix_rep" "1")
14807 (set_attr "type" "bitmanip")
14808 (set_attr "mode" "HI")])
14809
14810(define_insn "*bsrhi"
14811 [(set (match_operand:HI 0 "register_operand" "=r")
14812 (minus:HI (const_int 15)
14813 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14814 (clobber (reg:CC FLAGS_REG))]
14815 ""
14816 "bsr{w}\t{%1, %0|%0, %1}"
14817 [(set_attr "prefix_0f" "1")
14818 (set_attr "mode" "HI")])
14819
14820(define_insn "popcounthi2"
14821 [(set (match_operand:HI 0 "register_operand" "=r")
14822 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14823 (clobber (reg:CC FLAGS_REG))]
14824 "TARGET_POPCNT"
14825 "popcnt{w}\t{%1, %0|%0, %1}"
14826 [(set_attr "prefix_rep" "1")
14827 (set_attr "type" "bitmanip")
14828 (set_attr "mode" "HI")])
14829
14830(define_insn "*popcounthi2_cmp"
14831 [(set (reg FLAGS_REG)
14832 (compare
14833 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14834 (const_int 0)))
14835 (set (match_operand:HI 0 "register_operand" "=r")
14836 (popcount:HI (match_dup 1)))]
14837 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14838 "popcnt{w}\t{%1, %0|%0, %1}"
14839 [(set_attr "prefix_rep" "1")
14840 (set_attr "type" "bitmanip")
14841 (set_attr "mode" "HI")])
14592
14593;; Thread-local storage patterns for ELF.
14594;;
14595;; Note that these code sequences must appear exactly as shown
14596;; in order to allow linker relaxation.
14597
14598(define_insn "*tls_global_dynamic_32_gnu"
14599 [(set (match_operand:SI 0 "register_operand" "=a")
14600 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14601 (match_operand:SI 2 "tls_symbolic_operand" "")
14602 (match_operand:SI 3 "call_insn_operand" "")]
14603 UNSPEC_TLS_GD))
14604 (clobber (match_scratch:SI 4 "=d"))
14605 (clobber (match_scratch:SI 5 "=c"))
14606 (clobber (reg:CC FLAGS_REG))]
14607 "!TARGET_64BIT && TARGET_GNU_TLS"
14608 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14609 [(set_attr "type" "multi")
14610 (set_attr "length" "12")])
14611
14612(define_insn "*tls_global_dynamic_32_sun"
14613 [(set (match_operand:SI 0 "register_operand" "=a")
14614 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14615 (match_operand:SI 2 "tls_symbolic_operand" "")
14616 (match_operand:SI 3 "call_insn_operand" "")]
14617 UNSPEC_TLS_GD))
14618 (clobber (match_scratch:SI 4 "=d"))
14619 (clobber (match_scratch:SI 5 "=c"))
14620 (clobber (reg:CC FLAGS_REG))]
14621 "!TARGET_64BIT && TARGET_SUN_TLS"
14622 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14623 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14624 [(set_attr "type" "multi")
14625 (set_attr "length" "14")])
14626
14627(define_expand "tls_global_dynamic_32"
14628 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14629 (unspec:SI
14630 [(match_dup 2)
14631 (match_operand:SI 1 "tls_symbolic_operand" "")
14632 (match_dup 3)]
14633 UNSPEC_TLS_GD))
14634 (clobber (match_scratch:SI 4 ""))
14635 (clobber (match_scratch:SI 5 ""))
14636 (clobber (reg:CC FLAGS_REG))])]
14637 ""
14638{
14639 if (flag_pic)
14640 operands[2] = pic_offset_table_rtx;
14641 else
14642 {
14643 operands[2] = gen_reg_rtx (Pmode);
14644 emit_insn (gen_set_got (operands[2]));
14645 }
14646 if (TARGET_GNU2_TLS)
14647 {
14648 emit_insn (gen_tls_dynamic_gnu2_32
14649 (operands[0], operands[1], operands[2]));
14650 DONE;
14651 }
14652 operands[3] = ix86_tls_get_addr ();
14653})
14654
14655(define_insn "*tls_global_dynamic_64"
14656 [(set (match_operand:DI 0 "register_operand" "=a")
14657 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14658 (match_operand:DI 3 "" "")))
14659 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14660 UNSPEC_TLS_GD)]
14661 "TARGET_64BIT"
14662 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14663 [(set_attr "type" "multi")
14664 (set_attr "length" "16")])
14665
14666(define_expand "tls_global_dynamic_64"
14667 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14668 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14669 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14670 UNSPEC_TLS_GD)])]
14671 ""
14672{
14673 if (TARGET_GNU2_TLS)
14674 {
14675 emit_insn (gen_tls_dynamic_gnu2_64
14676 (operands[0], operands[1]));
14677 DONE;
14678 }
14679 operands[2] = ix86_tls_get_addr ();
14680})
14681
14682(define_insn "*tls_local_dynamic_base_32_gnu"
14683 [(set (match_operand:SI 0 "register_operand" "=a")
14684 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14685 (match_operand:SI 2 "call_insn_operand" "")]
14686 UNSPEC_TLS_LD_BASE))
14687 (clobber (match_scratch:SI 3 "=d"))
14688 (clobber (match_scratch:SI 4 "=c"))
14689 (clobber (reg:CC FLAGS_REG))]
14690 "!TARGET_64BIT && TARGET_GNU_TLS"
14691 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14692 [(set_attr "type" "multi")
14693 (set_attr "length" "11")])
14694
14695(define_insn "*tls_local_dynamic_base_32_sun"
14696 [(set (match_operand:SI 0 "register_operand" "=a")
14697 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14698 (match_operand:SI 2 "call_insn_operand" "")]
14699 UNSPEC_TLS_LD_BASE))
14700 (clobber (match_scratch:SI 3 "=d"))
14701 (clobber (match_scratch:SI 4 "=c"))
14702 (clobber (reg:CC FLAGS_REG))]
14703 "!TARGET_64BIT && TARGET_SUN_TLS"
14704 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14705 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14706 [(set_attr "type" "multi")
14707 (set_attr "length" "13")])
14708
14709(define_expand "tls_local_dynamic_base_32"
14710 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14711 (unspec:SI [(match_dup 1) (match_dup 2)]
14712 UNSPEC_TLS_LD_BASE))
14713 (clobber (match_scratch:SI 3 ""))
14714 (clobber (match_scratch:SI 4 ""))
14715 (clobber (reg:CC FLAGS_REG))])]
14716 ""
14717{
14718 if (flag_pic)
14719 operands[1] = pic_offset_table_rtx;
14720 else
14721 {
14722 operands[1] = gen_reg_rtx (Pmode);
14723 emit_insn (gen_set_got (operands[1]));
14724 }
14725 if (TARGET_GNU2_TLS)
14726 {
14727 emit_insn (gen_tls_dynamic_gnu2_32
14728 (operands[0], ix86_tls_module_base (), operands[1]));
14729 DONE;
14730 }
14731 operands[2] = ix86_tls_get_addr ();
14732})
14733
14734(define_insn "*tls_local_dynamic_base_64"
14735 [(set (match_operand:DI 0 "register_operand" "=a")
14736 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14737 (match_operand:DI 2 "" "")))
14738 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14739 "TARGET_64BIT"
14740 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14741 [(set_attr "type" "multi")
14742 (set_attr "length" "12")])
14743
14744(define_expand "tls_local_dynamic_base_64"
14745 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14746 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14747 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14748 ""
14749{
14750 if (TARGET_GNU2_TLS)
14751 {
14752 emit_insn (gen_tls_dynamic_gnu2_64
14753 (operands[0], ix86_tls_module_base ()));
14754 DONE;
14755 }
14756 operands[1] = ix86_tls_get_addr ();
14757})
14758
14759;; Local dynamic of a single variable is a lose. Show combine how
14760;; to convert that back to global dynamic.
14761
14762(define_insn_and_split "*tls_local_dynamic_32_once"
14763 [(set (match_operand:SI 0 "register_operand" "=a")
14764 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765 (match_operand:SI 2 "call_insn_operand" "")]
14766 UNSPEC_TLS_LD_BASE)
14767 (const:SI (unspec:SI
14768 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14769 UNSPEC_DTPOFF))))
14770 (clobber (match_scratch:SI 4 "=d"))
14771 (clobber (match_scratch:SI 5 "=c"))
14772 (clobber (reg:CC FLAGS_REG))]
14773 ""
14774 "#"
14775 ""
14776 [(parallel [(set (match_dup 0)
14777 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14778 UNSPEC_TLS_GD))
14779 (clobber (match_dup 4))
14780 (clobber (match_dup 5))
14781 (clobber (reg:CC FLAGS_REG))])]
14782 "")
14783
14784;; Load and add the thread base pointer from %gs:0.
14785
14786(define_insn "*load_tp_si"
14787 [(set (match_operand:SI 0 "register_operand" "=r")
14788 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14789 "!TARGET_64BIT"
14790 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14791 [(set_attr "type" "imov")
14792 (set_attr "modrm" "0")
14793 (set_attr "length" "7")
14794 (set_attr "memory" "load")
14795 (set_attr "imm_disp" "false")])
14796
14797(define_insn "*add_tp_si"
14798 [(set (match_operand:SI 0 "register_operand" "=r")
14799 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14800 (match_operand:SI 1 "register_operand" "0")))
14801 (clobber (reg:CC FLAGS_REG))]
14802 "!TARGET_64BIT"
14803 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14804 [(set_attr "type" "alu")
14805 (set_attr "modrm" "0")
14806 (set_attr "length" "7")
14807 (set_attr "memory" "load")
14808 (set_attr "imm_disp" "false")])
14809
14810(define_insn "*load_tp_di"
14811 [(set (match_operand:DI 0 "register_operand" "=r")
14812 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14813 "TARGET_64BIT"
14814 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14815 [(set_attr "type" "imov")
14816 (set_attr "modrm" "0")
14817 (set_attr "length" "7")
14818 (set_attr "memory" "load")
14819 (set_attr "imm_disp" "false")])
14820
14821(define_insn "*add_tp_di"
14822 [(set (match_operand:DI 0 "register_operand" "=r")
14823 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14824 (match_operand:DI 1 "register_operand" "0")))
14825 (clobber (reg:CC FLAGS_REG))]
14826 "TARGET_64BIT"
14827 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14828 [(set_attr "type" "alu")
14829 (set_attr "modrm" "0")
14830 (set_attr "length" "7")
14831 (set_attr "memory" "load")
14832 (set_attr "imm_disp" "false")])
14833
14834;; GNU2 TLS patterns can be split.
14835
14836(define_expand "tls_dynamic_gnu2_32"
14837 [(set (match_dup 3)
14838 (plus:SI (match_operand:SI 2 "register_operand" "")
14839 (const:SI
14840 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14841 UNSPEC_TLSDESC))))
14842 (parallel
14843 [(set (match_operand:SI 0 "register_operand" "")
14844 (unspec:SI [(match_dup 1) (match_dup 3)
14845 (match_dup 2) (reg:SI SP_REG)]
14846 UNSPEC_TLSDESC))
14847 (clobber (reg:CC FLAGS_REG))])]
14848 "!TARGET_64BIT && TARGET_GNU2_TLS"
14849{
14850 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14851 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14852})
14853
14854(define_insn "*tls_dynamic_lea_32"
14855 [(set (match_operand:SI 0 "register_operand" "=r")
14856 (plus:SI (match_operand:SI 1 "register_operand" "b")
14857 (const:SI
14858 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14859 UNSPEC_TLSDESC))))]
14860 "!TARGET_64BIT && TARGET_GNU2_TLS"
14861 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14862 [(set_attr "type" "lea")
14863 (set_attr "mode" "SI")
14864 (set_attr "length" "6")
14865 (set_attr "length_address" "4")])
14866
14867(define_insn "*tls_dynamic_call_32"
14868 [(set (match_operand:SI 0 "register_operand" "=a")
14869 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14870 (match_operand:SI 2 "register_operand" "0")
14871 ;; we have to make sure %ebx still points to the GOT
14872 (match_operand:SI 3 "register_operand" "b")
14873 (reg:SI SP_REG)]
14874 UNSPEC_TLSDESC))
14875 (clobber (reg:CC FLAGS_REG))]
14876 "!TARGET_64BIT && TARGET_GNU2_TLS"
14877 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14878 [(set_attr "type" "call")
14879 (set_attr "length" "2")
14880 (set_attr "length_address" "0")])
14881
14882(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14883 [(set (match_operand:SI 0 "register_operand" "=&a")
14884 (plus:SI
14885 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14886 (match_operand:SI 4 "" "")
14887 (match_operand:SI 2 "register_operand" "b")
14888 (reg:SI SP_REG)]
14889 UNSPEC_TLSDESC)
14890 (const:SI (unspec:SI
14891 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14892 UNSPEC_DTPOFF))))
14893 (clobber (reg:CC FLAGS_REG))]
14894 "!TARGET_64BIT && TARGET_GNU2_TLS"
14895 "#"
14896 ""
14897 [(set (match_dup 0) (match_dup 5))]
14898{
14899 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14900 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14901})
14902
14903(define_expand "tls_dynamic_gnu2_64"
14904 [(set (match_dup 2)
14905 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14906 UNSPEC_TLSDESC))
14907 (parallel
14908 [(set (match_operand:DI 0 "register_operand" "")
14909 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14910 UNSPEC_TLSDESC))
14911 (clobber (reg:CC FLAGS_REG))])]
14912 "TARGET_64BIT && TARGET_GNU2_TLS"
14913{
14914 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14915 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14916})
14917
14918(define_insn "*tls_dynamic_lea_64"
14919 [(set (match_operand:DI 0 "register_operand" "=r")
14920 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14921 UNSPEC_TLSDESC))]
14922 "TARGET_64BIT && TARGET_GNU2_TLS"
14923 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14924 [(set_attr "type" "lea")
14925 (set_attr "mode" "DI")
14926 (set_attr "length" "7")
14927 (set_attr "length_address" "4")])
14928
14929(define_insn "*tls_dynamic_call_64"
14930 [(set (match_operand:DI 0 "register_operand" "=a")
14931 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14932 (match_operand:DI 2 "register_operand" "0")
14933 (reg:DI SP_REG)]
14934 UNSPEC_TLSDESC))
14935 (clobber (reg:CC FLAGS_REG))]
14936 "TARGET_64BIT && TARGET_GNU2_TLS"
14937 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14938 [(set_attr "type" "call")
14939 (set_attr "length" "2")
14940 (set_attr "length_address" "0")])
14941
14942(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14943 [(set (match_operand:DI 0 "register_operand" "=&a")
14944 (plus:DI
14945 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14946 (match_operand:DI 3 "" "")
14947 (reg:DI SP_REG)]
14948 UNSPEC_TLSDESC)
14949 (const:DI (unspec:DI
14950 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14951 UNSPEC_DTPOFF))))
14952 (clobber (reg:CC FLAGS_REG))]
14953 "TARGET_64BIT && TARGET_GNU2_TLS"
14954 "#"
14955 ""
14956 [(set (match_dup 0) (match_dup 4))]
14957{
14958 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14959 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14960})
14961
14962;;
14963
14964;; These patterns match the binary 387 instructions for addM3, subM3,
14965;; mulM3 and divM3. There are three patterns for each of DFmode and
14966;; SFmode. The first is the normal insn, the second the same insn but
14967;; with one operand a conversion, and the third the same insn but with
14968;; the other operand a conversion. The conversion may be SFmode or
14969;; SImode if the target mode DFmode, but only SImode if the target mode
14970;; is SFmode.
14971
14972;; Gcc is slightly more smart about handling normal two address instructions
14973;; so use special patterns for add and mull.
14974
14975(define_insn "*fop_sf_comm_mixed"
14976 [(set (match_operand:SF 0 "register_operand" "=f,x")
14977 (match_operator:SF 3 "binary_fp_operator"
14978 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14979 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14980 "TARGET_MIX_SSE_I387
14981 && COMMUTATIVE_ARITH_P (operands[3])
14982 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14983 "* return output_387_binary_op (insn, operands);"
14984 [(set (attr "type")
14985 (if_then_else (eq_attr "alternative" "1")
14986 (if_then_else (match_operand:SF 3 "mult_operator" "")
14987 (const_string "ssemul")
14988 (const_string "sseadd"))
14989 (if_then_else (match_operand:SF 3 "mult_operator" "")
14990 (const_string "fmul")
14991 (const_string "fop"))))
14992 (set_attr "mode" "SF")])
14993
14994(define_insn "*fop_sf_comm_sse"
14995 [(set (match_operand:SF 0 "register_operand" "=x")
14996 (match_operator:SF 3 "binary_fp_operator"
14997 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14998 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14999 "TARGET_SSE_MATH
15000 && COMMUTATIVE_ARITH_P (operands[3])
15001 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15002 "* return output_387_binary_op (insn, operands);"
15003 [(set (attr "type")
15004 (if_then_else (match_operand:SF 3 "mult_operator" "")
15005 (const_string "ssemul")
15006 (const_string "sseadd")))
15007 (set_attr "mode" "SF")])
15008
15009(define_insn "*fop_sf_comm_i387"
15010 [(set (match_operand:SF 0 "register_operand" "=f")
15011 (match_operator:SF 3 "binary_fp_operator"
15012 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15013 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15014 "TARGET_80387
15015 && COMMUTATIVE_ARITH_P (operands[3])
15016 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15017 "* return output_387_binary_op (insn, operands);"
15018 [(set (attr "type")
15019 (if_then_else (match_operand:SF 3 "mult_operator" "")
15020 (const_string "fmul")
15021 (const_string "fop")))
15022 (set_attr "mode" "SF")])
15023
15024(define_insn "*fop_sf_1_mixed"
15025 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15026 (match_operator:SF 3 "binary_fp_operator"
15027 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15028 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15029 "TARGET_MIX_SSE_I387
15030 && !COMMUTATIVE_ARITH_P (operands[3])
15031 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15032 "* return output_387_binary_op (insn, operands);"
15033 [(set (attr "type")
15034 (cond [(and (eq_attr "alternative" "2")
15035 (match_operand:SF 3 "mult_operator" ""))
15036 (const_string "ssemul")
15037 (and (eq_attr "alternative" "2")
15038 (match_operand:SF 3 "div_operator" ""))
15039 (const_string "ssediv")
15040 (eq_attr "alternative" "2")
15041 (const_string "sseadd")
15042 (match_operand:SF 3 "mult_operator" "")
15043 (const_string "fmul")
15044 (match_operand:SF 3 "div_operator" "")
15045 (const_string "fdiv")
15046 ]
15047 (const_string "fop")))
15048 (set_attr "mode" "SF")])
15049
15050(define_insn "*fop_sf_1_sse"
15051 [(set (match_operand:SF 0 "register_operand" "=x")
15052 (match_operator:SF 3 "binary_fp_operator"
15053 [(match_operand:SF 1 "register_operand" "0")
15054 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15055 "TARGET_SSE_MATH
15056 && !COMMUTATIVE_ARITH_P (operands[3])"
15057 "* return output_387_binary_op (insn, operands);"
15058 [(set (attr "type")
15059 (cond [(match_operand:SF 3 "mult_operator" "")
15060 (const_string "ssemul")
15061 (match_operand:SF 3 "div_operator" "")
15062 (const_string "ssediv")
15063 ]
15064 (const_string "sseadd")))
15065 (set_attr "mode" "SF")])
15066
15067;; This pattern is not fully shadowed by the pattern above.
15068(define_insn "*fop_sf_1_i387"
15069 [(set (match_operand:SF 0 "register_operand" "=f,f")
15070 (match_operator:SF 3 "binary_fp_operator"
15071 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15072 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15073 "TARGET_80387 && !TARGET_SSE_MATH
15074 && !COMMUTATIVE_ARITH_P (operands[3])
15075 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15076 "* return output_387_binary_op (insn, operands);"
15077 [(set (attr "type")
15078 (cond [(match_operand:SF 3 "mult_operator" "")
15079 (const_string "fmul")
15080 (match_operand:SF 3 "div_operator" "")
15081 (const_string "fdiv")
15082 ]
15083 (const_string "fop")))
15084 (set_attr "mode" "SF")])
15085
15086;; ??? Add SSE splitters for these!
15087(define_insn "*fop_sf_2<mode>_i387"
15088 [(set (match_operand:SF 0 "register_operand" "=f,f")
15089 (match_operator:SF 3 "binary_fp_operator"
15090 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15091 (match_operand:SF 2 "register_operand" "0,0")]))]
15092 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15093 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15094 [(set (attr "type")
15095 (cond [(match_operand:SF 3 "mult_operator" "")
15096 (const_string "fmul")
15097 (match_operand:SF 3 "div_operator" "")
15098 (const_string "fdiv")
15099 ]
15100 (const_string "fop")))
15101 (set_attr "fp_int_src" "true")
15102 (set_attr "mode" "<MODE>")])
15103
15104(define_insn "*fop_sf_3<mode>_i387"
15105 [(set (match_operand:SF 0 "register_operand" "=f,f")
15106 (match_operator:SF 3 "binary_fp_operator"
15107 [(match_operand:SF 1 "register_operand" "0,0")
15108 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15109 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15110 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15111 [(set (attr "type")
15112 (cond [(match_operand:SF 3 "mult_operator" "")
15113 (const_string "fmul")
15114 (match_operand:SF 3 "div_operator" "")
15115 (const_string "fdiv")
15116 ]
15117 (const_string "fop")))
15118 (set_attr "fp_int_src" "true")
15119 (set_attr "mode" "<MODE>")])
15120
15121(define_insn "*fop_df_comm_mixed"
15122 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15123 (match_operator:DF 3 "binary_fp_operator"
15124 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15125 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15126 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15127 && COMMUTATIVE_ARITH_P (operands[3])
15128 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15129 "* return output_387_binary_op (insn, operands);"
15130 [(set (attr "type")
15131 (if_then_else (eq_attr "alternative" "1")
15132 (if_then_else (match_operand:DF 3 "mult_operator" "")
15133 (const_string "ssemul")
15134 (const_string "sseadd"))
15135 (if_then_else (match_operand:DF 3 "mult_operator" "")
15136 (const_string "fmul")
15137 (const_string "fop"))))
15138 (set_attr "mode" "DF")])
15139
15140(define_insn "*fop_df_comm_sse"
15141 [(set (match_operand:DF 0 "register_operand" "=Y")
15142 (match_operator:DF 3 "binary_fp_operator"
15143 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15144 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15145 "TARGET_SSE2 && TARGET_SSE_MATH
15146 && COMMUTATIVE_ARITH_P (operands[3])
15147 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15148 "* return output_387_binary_op (insn, operands);"
15149 [(set (attr "type")
15150 (if_then_else (match_operand:DF 3 "mult_operator" "")
15151 (const_string "ssemul")
15152 (const_string "sseadd")))
15153 (set_attr "mode" "DF")])
15154
15155(define_insn "*fop_df_comm_i387"
15156 [(set (match_operand:DF 0 "register_operand" "=f")
15157 (match_operator:DF 3 "binary_fp_operator"
15158 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15159 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15160 "TARGET_80387
15161 && COMMUTATIVE_ARITH_P (operands[3])
15162 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15163 "* return output_387_binary_op (insn, operands);"
15164 [(set (attr "type")
15165 (if_then_else (match_operand:DF 3 "mult_operator" "")
15166 (const_string "fmul")
15167 (const_string "fop")))
15168 (set_attr "mode" "DF")])
15169
15170(define_insn "*fop_df_1_mixed"
15171 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15172 (match_operator:DF 3 "binary_fp_operator"
15173 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15174 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15175 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15176 && !COMMUTATIVE_ARITH_P (operands[3])
15177 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15178 "* return output_387_binary_op (insn, operands);"
15179 [(set (attr "type")
15180 (cond [(and (eq_attr "alternative" "2")
15181 (match_operand:DF 3 "mult_operator" ""))
15182 (const_string "ssemul")
15183 (and (eq_attr "alternative" "2")
15184 (match_operand:DF 3 "div_operator" ""))
15185 (const_string "ssediv")
15186 (eq_attr "alternative" "2")
15187 (const_string "sseadd")
15188 (match_operand:DF 3 "mult_operator" "")
15189 (const_string "fmul")
15190 (match_operand:DF 3 "div_operator" "")
15191 (const_string "fdiv")
15192 ]
15193 (const_string "fop")))
15194 (set_attr "mode" "DF")])
15195
15196(define_insn "*fop_df_1_sse"
15197 [(set (match_operand:DF 0 "register_operand" "=Y")
15198 (match_operator:DF 3 "binary_fp_operator"
15199 [(match_operand:DF 1 "register_operand" "0")
15200 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15201 "TARGET_SSE2 && TARGET_SSE_MATH
15202 && !COMMUTATIVE_ARITH_P (operands[3])"
15203 "* return output_387_binary_op (insn, operands);"
15204 [(set_attr "mode" "DF")
15205 (set (attr "type")
15206 (cond [(match_operand:DF 3 "mult_operator" "")
15207 (const_string "ssemul")
15208 (match_operand:DF 3 "div_operator" "")
15209 (const_string "ssediv")
15210 ]
15211 (const_string "sseadd")))])
15212
15213;; This pattern is not fully shadowed by the pattern above.
15214(define_insn "*fop_df_1_i387"
15215 [(set (match_operand:DF 0 "register_operand" "=f,f")
15216 (match_operator:DF 3 "binary_fp_operator"
15217 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15218 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15219 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15220 && !COMMUTATIVE_ARITH_P (operands[3])
15221 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15222 "* return output_387_binary_op (insn, operands);"
15223 [(set (attr "type")
15224 (cond [(match_operand:DF 3 "mult_operator" "")
15225 (const_string "fmul")
15226 (match_operand:DF 3 "div_operator" "")
15227 (const_string "fdiv")
15228 ]
15229 (const_string "fop")))
15230 (set_attr "mode" "DF")])
15231
15232;; ??? Add SSE splitters for these!
15233(define_insn "*fop_df_2<mode>_i387"
15234 [(set (match_operand:DF 0 "register_operand" "=f,f")
15235 (match_operator:DF 3 "binary_fp_operator"
15236 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15237 (match_operand:DF 2 "register_operand" "0,0")]))]
15238 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15239 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15240 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15241 [(set (attr "type")
15242 (cond [(match_operand:DF 3 "mult_operator" "")
15243 (const_string "fmul")
15244 (match_operand:DF 3 "div_operator" "")
15245 (const_string "fdiv")
15246 ]
15247 (const_string "fop")))
15248 (set_attr "fp_int_src" "true")
15249 (set_attr "mode" "<MODE>")])
15250
15251(define_insn "*fop_df_3<mode>_i387"
15252 [(set (match_operand:DF 0 "register_operand" "=f,f")
15253 (match_operator:DF 3 "binary_fp_operator"
15254 [(match_operand:DF 1 "register_operand" "0,0")
15255 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15256 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15257 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15258 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15259 [(set (attr "type")
15260 (cond [(match_operand:DF 3 "mult_operator" "")
15261 (const_string "fmul")
15262 (match_operand:DF 3 "div_operator" "")
15263 (const_string "fdiv")
15264 ]
15265 (const_string "fop")))
15266 (set_attr "fp_int_src" "true")
15267 (set_attr "mode" "<MODE>")])
15268
15269(define_insn "*fop_df_4_i387"
15270 [(set (match_operand:DF 0 "register_operand" "=f,f")
15271 (match_operator:DF 3 "binary_fp_operator"
15272 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15273 (match_operand:DF 2 "register_operand" "0,f")]))]
15274 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15275 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15276 "* return output_387_binary_op (insn, operands);"
15277 [(set (attr "type")
15278 (cond [(match_operand:DF 3 "mult_operator" "")
15279 (const_string "fmul")
15280 (match_operand:DF 3 "div_operator" "")
15281 (const_string "fdiv")
15282 ]
15283 (const_string "fop")))
15284 (set_attr "mode" "SF")])
15285
15286(define_insn "*fop_df_5_i387"
15287 [(set (match_operand:DF 0 "register_operand" "=f,f")
15288 (match_operator:DF 3 "binary_fp_operator"
15289 [(match_operand:DF 1 "register_operand" "0,f")
15290 (float_extend:DF
15291 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15292 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15293 "* return output_387_binary_op (insn, operands);"
15294 [(set (attr "type")
15295 (cond [(match_operand:DF 3 "mult_operator" "")
15296 (const_string "fmul")
15297 (match_operand:DF 3 "div_operator" "")
15298 (const_string "fdiv")
15299 ]
15300 (const_string "fop")))
15301 (set_attr "mode" "SF")])
15302
15303(define_insn "*fop_df_6_i387"
15304 [(set (match_operand:DF 0 "register_operand" "=f,f")
15305 (match_operator:DF 3 "binary_fp_operator"
15306 [(float_extend:DF
15307 (match_operand:SF 1 "register_operand" "0,f"))
15308 (float_extend:DF
15309 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15310 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15311 "* return output_387_binary_op (insn, operands);"
15312 [(set (attr "type")
15313 (cond [(match_operand:DF 3 "mult_operator" "")
15314 (const_string "fmul")
15315 (match_operand:DF 3 "div_operator" "")
15316 (const_string "fdiv")
15317 ]
15318 (const_string "fop")))
15319 (set_attr "mode" "SF")])
15320
15321(define_insn "*fop_xf_comm_i387"
15322 [(set (match_operand:XF 0 "register_operand" "=f")
15323 (match_operator:XF 3 "binary_fp_operator"
15324 [(match_operand:XF 1 "register_operand" "%0")
15325 (match_operand:XF 2 "register_operand" "f")]))]
15326 "TARGET_80387
15327 && COMMUTATIVE_ARITH_P (operands[3])"
15328 "* return output_387_binary_op (insn, operands);"
15329 [(set (attr "type")
15330 (if_then_else (match_operand:XF 3 "mult_operator" "")
15331 (const_string "fmul")
15332 (const_string "fop")))
15333 (set_attr "mode" "XF")])
15334
15335(define_insn "*fop_xf_1_i387"
15336 [(set (match_operand:XF 0 "register_operand" "=f,f")
15337 (match_operator:XF 3 "binary_fp_operator"
15338 [(match_operand:XF 1 "register_operand" "0,f")
15339 (match_operand:XF 2 "register_operand" "f,0")]))]
15340 "TARGET_80387
15341 && !COMMUTATIVE_ARITH_P (operands[3])"
15342 "* return output_387_binary_op (insn, operands);"
15343 [(set (attr "type")
15344 (cond [(match_operand:XF 3 "mult_operator" "")
15345 (const_string "fmul")
15346 (match_operand:XF 3 "div_operator" "")
15347 (const_string "fdiv")
15348 ]
15349 (const_string "fop")))
15350 (set_attr "mode" "XF")])
15351
15352(define_insn "*fop_xf_2<mode>_i387"
15353 [(set (match_operand:XF 0 "register_operand" "=f,f")
15354 (match_operator:XF 3 "binary_fp_operator"
15355 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15356 (match_operand:XF 2 "register_operand" "0,0")]))]
15357 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15358 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15359 [(set (attr "type")
15360 (cond [(match_operand:XF 3 "mult_operator" "")
15361 (const_string "fmul")
15362 (match_operand:XF 3 "div_operator" "")
15363 (const_string "fdiv")
15364 ]
15365 (const_string "fop")))
15366 (set_attr "fp_int_src" "true")
15367 (set_attr "mode" "<MODE>")])
15368
15369(define_insn "*fop_xf_3<mode>_i387"
15370 [(set (match_operand:XF 0 "register_operand" "=f,f")
15371 (match_operator:XF 3 "binary_fp_operator"
15372 [(match_operand:XF 1 "register_operand" "0,0")
15373 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15374 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15375 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15376 [(set (attr "type")
15377 (cond [(match_operand:XF 3 "mult_operator" "")
15378 (const_string "fmul")
15379 (match_operand:XF 3 "div_operator" "")
15380 (const_string "fdiv")
15381 ]
15382 (const_string "fop")))
15383 (set_attr "fp_int_src" "true")
15384 (set_attr "mode" "<MODE>")])
15385
15386(define_insn "*fop_xf_4_i387"
15387 [(set (match_operand:XF 0 "register_operand" "=f,f")
15388 (match_operator:XF 3 "binary_fp_operator"
15389 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15390 (match_operand:XF 2 "register_operand" "0,f")]))]
15391 "TARGET_80387"
15392 "* return output_387_binary_op (insn, operands);"
15393 [(set (attr "type")
15394 (cond [(match_operand:XF 3 "mult_operator" "")
15395 (const_string "fmul")
15396 (match_operand:XF 3 "div_operator" "")
15397 (const_string "fdiv")
15398 ]
15399 (const_string "fop")))
15400 (set_attr "mode" "SF")])
15401
15402(define_insn "*fop_xf_5_i387"
15403 [(set (match_operand:XF 0 "register_operand" "=f,f")
15404 (match_operator:XF 3 "binary_fp_operator"
15405 [(match_operand:XF 1 "register_operand" "0,f")
15406 (float_extend:XF
15407 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15408 "TARGET_80387"
15409 "* return output_387_binary_op (insn, operands);"
15410 [(set (attr "type")
15411 (cond [(match_operand:XF 3 "mult_operator" "")
15412 (const_string "fmul")
15413 (match_operand:XF 3 "div_operator" "")
15414 (const_string "fdiv")
15415 ]
15416 (const_string "fop")))
15417 (set_attr "mode" "SF")])
15418
15419(define_insn "*fop_xf_6_i387"
15420 [(set (match_operand:XF 0 "register_operand" "=f,f")
15421 (match_operator:XF 3 "binary_fp_operator"
15422 [(float_extend:XF
15423 (match_operand 1 "register_operand" "0,f"))
15424 (float_extend:XF
15425 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15426 "TARGET_80387"
15427 "* return output_387_binary_op (insn, operands);"
15428 [(set (attr "type")
15429 (cond [(match_operand:XF 3 "mult_operator" "")
15430 (const_string "fmul")
15431 (match_operand:XF 3 "div_operator" "")
15432 (const_string "fdiv")
15433 ]
15434 (const_string "fop")))
15435 (set_attr "mode" "SF")])
15436
15437(define_split
15438 [(set (match_operand 0 "register_operand" "")
15439 (match_operator 3 "binary_fp_operator"
15440 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15441 (match_operand 2 "register_operand" "")]))]
15442 "TARGET_80387 && reload_completed
15443 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15444 [(const_int 0)]
15445{
15446 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15447 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15448 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15449 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15450 GET_MODE (operands[3]),
15451 operands[4],
15452 operands[2])));
15453 ix86_free_from_memory (GET_MODE (operands[1]));
15454 DONE;
15455})
15456
15457(define_split
15458 [(set (match_operand 0 "register_operand" "")
15459 (match_operator 3 "binary_fp_operator"
15460 [(match_operand 1 "register_operand" "")
15461 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15462 "TARGET_80387 && reload_completed
15463 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15464 [(const_int 0)]
15465{
15466 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15467 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15468 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15469 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15470 GET_MODE (operands[3]),
15471 operands[1],
15472 operands[4])));
15473 ix86_free_from_memory (GET_MODE (operands[2]));
15474 DONE;
15475})
15476
15477;; FPU special functions.
15478
15479(define_expand "sqrtsf2"
15480 [(set (match_operand:SF 0 "register_operand" "")
15481 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15482 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15483{
15484 if (!TARGET_SSE_MATH)
15485 operands[1] = force_reg (SFmode, operands[1]);
15486})
15487
15488(define_insn "*sqrtsf2_mixed"
15489 [(set (match_operand:SF 0 "register_operand" "=f,x")
15490 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15491 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15492 "@
15493 fsqrt
15494 sqrtss\t{%1, %0|%0, %1}"
15495 [(set_attr "type" "fpspc,sse")
15496 (set_attr "mode" "SF,SF")
14842
14843;; Thread-local storage patterns for ELF.
14844;;
14845;; Note that these code sequences must appear exactly as shown
14846;; in order to allow linker relaxation.
14847
14848(define_insn "*tls_global_dynamic_32_gnu"
14849 [(set (match_operand:SI 0 "register_operand" "=a")
14850 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14851 (match_operand:SI 2 "tls_symbolic_operand" "")
14852 (match_operand:SI 3 "call_insn_operand" "")]
14853 UNSPEC_TLS_GD))
14854 (clobber (match_scratch:SI 4 "=d"))
14855 (clobber (match_scratch:SI 5 "=c"))
14856 (clobber (reg:CC FLAGS_REG))]
14857 "!TARGET_64BIT && TARGET_GNU_TLS"
14858 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14859 [(set_attr "type" "multi")
14860 (set_attr "length" "12")])
14861
14862(define_insn "*tls_global_dynamic_32_sun"
14863 [(set (match_operand:SI 0 "register_operand" "=a")
14864 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14865 (match_operand:SI 2 "tls_symbolic_operand" "")
14866 (match_operand:SI 3 "call_insn_operand" "")]
14867 UNSPEC_TLS_GD))
14868 (clobber (match_scratch:SI 4 "=d"))
14869 (clobber (match_scratch:SI 5 "=c"))
14870 (clobber (reg:CC FLAGS_REG))]
14871 "!TARGET_64BIT && TARGET_SUN_TLS"
14872 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14873 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14874 [(set_attr "type" "multi")
14875 (set_attr "length" "14")])
14876
14877(define_expand "tls_global_dynamic_32"
14878 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14879 (unspec:SI
14880 [(match_dup 2)
14881 (match_operand:SI 1 "tls_symbolic_operand" "")
14882 (match_dup 3)]
14883 UNSPEC_TLS_GD))
14884 (clobber (match_scratch:SI 4 ""))
14885 (clobber (match_scratch:SI 5 ""))
14886 (clobber (reg:CC FLAGS_REG))])]
14887 ""
14888{
14889 if (flag_pic)
14890 operands[2] = pic_offset_table_rtx;
14891 else
14892 {
14893 operands[2] = gen_reg_rtx (Pmode);
14894 emit_insn (gen_set_got (operands[2]));
14895 }
14896 if (TARGET_GNU2_TLS)
14897 {
14898 emit_insn (gen_tls_dynamic_gnu2_32
14899 (operands[0], operands[1], operands[2]));
14900 DONE;
14901 }
14902 operands[3] = ix86_tls_get_addr ();
14903})
14904
14905(define_insn "*tls_global_dynamic_64"
14906 [(set (match_operand:DI 0 "register_operand" "=a")
14907 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14908 (match_operand:DI 3 "" "")))
14909 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14910 UNSPEC_TLS_GD)]
14911 "TARGET_64BIT"
14912 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14913 [(set_attr "type" "multi")
14914 (set_attr "length" "16")])
14915
14916(define_expand "tls_global_dynamic_64"
14917 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14918 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14919 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14920 UNSPEC_TLS_GD)])]
14921 ""
14922{
14923 if (TARGET_GNU2_TLS)
14924 {
14925 emit_insn (gen_tls_dynamic_gnu2_64
14926 (operands[0], operands[1]));
14927 DONE;
14928 }
14929 operands[2] = ix86_tls_get_addr ();
14930})
14931
14932(define_insn "*tls_local_dynamic_base_32_gnu"
14933 [(set (match_operand:SI 0 "register_operand" "=a")
14934 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14935 (match_operand:SI 2 "call_insn_operand" "")]
14936 UNSPEC_TLS_LD_BASE))
14937 (clobber (match_scratch:SI 3 "=d"))
14938 (clobber (match_scratch:SI 4 "=c"))
14939 (clobber (reg:CC FLAGS_REG))]
14940 "!TARGET_64BIT && TARGET_GNU_TLS"
14941 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14942 [(set_attr "type" "multi")
14943 (set_attr "length" "11")])
14944
14945(define_insn "*tls_local_dynamic_base_32_sun"
14946 [(set (match_operand:SI 0 "register_operand" "=a")
14947 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14948 (match_operand:SI 2 "call_insn_operand" "")]
14949 UNSPEC_TLS_LD_BASE))
14950 (clobber (match_scratch:SI 3 "=d"))
14951 (clobber (match_scratch:SI 4 "=c"))
14952 (clobber (reg:CC FLAGS_REG))]
14953 "!TARGET_64BIT && TARGET_SUN_TLS"
14954 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14955 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14956 [(set_attr "type" "multi")
14957 (set_attr "length" "13")])
14958
14959(define_expand "tls_local_dynamic_base_32"
14960 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14961 (unspec:SI [(match_dup 1) (match_dup 2)]
14962 UNSPEC_TLS_LD_BASE))
14963 (clobber (match_scratch:SI 3 ""))
14964 (clobber (match_scratch:SI 4 ""))
14965 (clobber (reg:CC FLAGS_REG))])]
14966 ""
14967{
14968 if (flag_pic)
14969 operands[1] = pic_offset_table_rtx;
14970 else
14971 {
14972 operands[1] = gen_reg_rtx (Pmode);
14973 emit_insn (gen_set_got (operands[1]));
14974 }
14975 if (TARGET_GNU2_TLS)
14976 {
14977 emit_insn (gen_tls_dynamic_gnu2_32
14978 (operands[0], ix86_tls_module_base (), operands[1]));
14979 DONE;
14980 }
14981 operands[2] = ix86_tls_get_addr ();
14982})
14983
14984(define_insn "*tls_local_dynamic_base_64"
14985 [(set (match_operand:DI 0 "register_operand" "=a")
14986 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14987 (match_operand:DI 2 "" "")))
14988 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14989 "TARGET_64BIT"
14990 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14991 [(set_attr "type" "multi")
14992 (set_attr "length" "12")])
14993
14994(define_expand "tls_local_dynamic_base_64"
14995 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14996 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14997 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14998 ""
14999{
15000 if (TARGET_GNU2_TLS)
15001 {
15002 emit_insn (gen_tls_dynamic_gnu2_64
15003 (operands[0], ix86_tls_module_base ()));
15004 DONE;
15005 }
15006 operands[1] = ix86_tls_get_addr ();
15007})
15008
15009;; Local dynamic of a single variable is a lose. Show combine how
15010;; to convert that back to global dynamic.
15011
15012(define_insn_and_split "*tls_local_dynamic_32_once"
15013 [(set (match_operand:SI 0 "register_operand" "=a")
15014 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15015 (match_operand:SI 2 "call_insn_operand" "")]
15016 UNSPEC_TLS_LD_BASE)
15017 (const:SI (unspec:SI
15018 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15019 UNSPEC_DTPOFF))))
15020 (clobber (match_scratch:SI 4 "=d"))
15021 (clobber (match_scratch:SI 5 "=c"))
15022 (clobber (reg:CC FLAGS_REG))]
15023 ""
15024 "#"
15025 ""
15026 [(parallel [(set (match_dup 0)
15027 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15028 UNSPEC_TLS_GD))
15029 (clobber (match_dup 4))
15030 (clobber (match_dup 5))
15031 (clobber (reg:CC FLAGS_REG))])]
15032 "")
15033
15034;; Load and add the thread base pointer from %gs:0.
15035
15036(define_insn "*load_tp_si"
15037 [(set (match_operand:SI 0 "register_operand" "=r")
15038 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15039 "!TARGET_64BIT"
15040 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15041 [(set_attr "type" "imov")
15042 (set_attr "modrm" "0")
15043 (set_attr "length" "7")
15044 (set_attr "memory" "load")
15045 (set_attr "imm_disp" "false")])
15046
15047(define_insn "*add_tp_si"
15048 [(set (match_operand:SI 0 "register_operand" "=r")
15049 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15050 (match_operand:SI 1 "register_operand" "0")))
15051 (clobber (reg:CC FLAGS_REG))]
15052 "!TARGET_64BIT"
15053 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15054 [(set_attr "type" "alu")
15055 (set_attr "modrm" "0")
15056 (set_attr "length" "7")
15057 (set_attr "memory" "load")
15058 (set_attr "imm_disp" "false")])
15059
15060(define_insn "*load_tp_di"
15061 [(set (match_operand:DI 0 "register_operand" "=r")
15062 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15063 "TARGET_64BIT"
15064 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15065 [(set_attr "type" "imov")
15066 (set_attr "modrm" "0")
15067 (set_attr "length" "7")
15068 (set_attr "memory" "load")
15069 (set_attr "imm_disp" "false")])
15070
15071(define_insn "*add_tp_di"
15072 [(set (match_operand:DI 0 "register_operand" "=r")
15073 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15074 (match_operand:DI 1 "register_operand" "0")))
15075 (clobber (reg:CC FLAGS_REG))]
15076 "TARGET_64BIT"
15077 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15078 [(set_attr "type" "alu")
15079 (set_attr "modrm" "0")
15080 (set_attr "length" "7")
15081 (set_attr "memory" "load")
15082 (set_attr "imm_disp" "false")])
15083
15084;; GNU2 TLS patterns can be split.
15085
15086(define_expand "tls_dynamic_gnu2_32"
15087 [(set (match_dup 3)
15088 (plus:SI (match_operand:SI 2 "register_operand" "")
15089 (const:SI
15090 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15091 UNSPEC_TLSDESC))))
15092 (parallel
15093 [(set (match_operand:SI 0 "register_operand" "")
15094 (unspec:SI [(match_dup 1) (match_dup 3)
15095 (match_dup 2) (reg:SI SP_REG)]
15096 UNSPEC_TLSDESC))
15097 (clobber (reg:CC FLAGS_REG))])]
15098 "!TARGET_64BIT && TARGET_GNU2_TLS"
15099{
15100 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15101 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15102})
15103
15104(define_insn "*tls_dynamic_lea_32"
15105 [(set (match_operand:SI 0 "register_operand" "=r")
15106 (plus:SI (match_operand:SI 1 "register_operand" "b")
15107 (const:SI
15108 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15109 UNSPEC_TLSDESC))))]
15110 "!TARGET_64BIT && TARGET_GNU2_TLS"
15111 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15112 [(set_attr "type" "lea")
15113 (set_attr "mode" "SI")
15114 (set_attr "length" "6")
15115 (set_attr "length_address" "4")])
15116
15117(define_insn "*tls_dynamic_call_32"
15118 [(set (match_operand:SI 0 "register_operand" "=a")
15119 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15120 (match_operand:SI 2 "register_operand" "0")
15121 ;; we have to make sure %ebx still points to the GOT
15122 (match_operand:SI 3 "register_operand" "b")
15123 (reg:SI SP_REG)]
15124 UNSPEC_TLSDESC))
15125 (clobber (reg:CC FLAGS_REG))]
15126 "!TARGET_64BIT && TARGET_GNU2_TLS"
15127 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15128 [(set_attr "type" "call")
15129 (set_attr "length" "2")
15130 (set_attr "length_address" "0")])
15131
15132(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15133 [(set (match_operand:SI 0 "register_operand" "=&a")
15134 (plus:SI
15135 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15136 (match_operand:SI 4 "" "")
15137 (match_operand:SI 2 "register_operand" "b")
15138 (reg:SI SP_REG)]
15139 UNSPEC_TLSDESC)
15140 (const:SI (unspec:SI
15141 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15142 UNSPEC_DTPOFF))))
15143 (clobber (reg:CC FLAGS_REG))]
15144 "!TARGET_64BIT && TARGET_GNU2_TLS"
15145 "#"
15146 ""
15147 [(set (match_dup 0) (match_dup 5))]
15148{
15149 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15150 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15151})
15152
15153(define_expand "tls_dynamic_gnu2_64"
15154 [(set (match_dup 2)
15155 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15156 UNSPEC_TLSDESC))
15157 (parallel
15158 [(set (match_operand:DI 0 "register_operand" "")
15159 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15160 UNSPEC_TLSDESC))
15161 (clobber (reg:CC FLAGS_REG))])]
15162 "TARGET_64BIT && TARGET_GNU2_TLS"
15163{
15164 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15165 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15166})
15167
15168(define_insn "*tls_dynamic_lea_64"
15169 [(set (match_operand:DI 0 "register_operand" "=r")
15170 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15171 UNSPEC_TLSDESC))]
15172 "TARGET_64BIT && TARGET_GNU2_TLS"
15173 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15174 [(set_attr "type" "lea")
15175 (set_attr "mode" "DI")
15176 (set_attr "length" "7")
15177 (set_attr "length_address" "4")])
15178
15179(define_insn "*tls_dynamic_call_64"
15180 [(set (match_operand:DI 0 "register_operand" "=a")
15181 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15182 (match_operand:DI 2 "register_operand" "0")
15183 (reg:DI SP_REG)]
15184 UNSPEC_TLSDESC))
15185 (clobber (reg:CC FLAGS_REG))]
15186 "TARGET_64BIT && TARGET_GNU2_TLS"
15187 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15188 [(set_attr "type" "call")
15189 (set_attr "length" "2")
15190 (set_attr "length_address" "0")])
15191
15192(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15193 [(set (match_operand:DI 0 "register_operand" "=&a")
15194 (plus:DI
15195 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15196 (match_operand:DI 3 "" "")
15197 (reg:DI SP_REG)]
15198 UNSPEC_TLSDESC)
15199 (const:DI (unspec:DI
15200 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15201 UNSPEC_DTPOFF))))
15202 (clobber (reg:CC FLAGS_REG))]
15203 "TARGET_64BIT && TARGET_GNU2_TLS"
15204 "#"
15205 ""
15206 [(set (match_dup 0) (match_dup 4))]
15207{
15208 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15209 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15210})
15211
15212;;
15213
15214;; These patterns match the binary 387 instructions for addM3, subM3,
15215;; mulM3 and divM3. There are three patterns for each of DFmode and
15216;; SFmode. The first is the normal insn, the second the same insn but
15217;; with one operand a conversion, and the third the same insn but with
15218;; the other operand a conversion. The conversion may be SFmode or
15219;; SImode if the target mode DFmode, but only SImode if the target mode
15220;; is SFmode.
15221
15222;; Gcc is slightly more smart about handling normal two address instructions
15223;; so use special patterns for add and mull.
15224
15225(define_insn "*fop_sf_comm_mixed"
15226 [(set (match_operand:SF 0 "register_operand" "=f,x")
15227 (match_operator:SF 3 "binary_fp_operator"
15228 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15229 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15230 "TARGET_MIX_SSE_I387
15231 && COMMUTATIVE_ARITH_P (operands[3])
15232 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15233 "* return output_387_binary_op (insn, operands);"
15234 [(set (attr "type")
15235 (if_then_else (eq_attr "alternative" "1")
15236 (if_then_else (match_operand:SF 3 "mult_operator" "")
15237 (const_string "ssemul")
15238 (const_string "sseadd"))
15239 (if_then_else (match_operand:SF 3 "mult_operator" "")
15240 (const_string "fmul")
15241 (const_string "fop"))))
15242 (set_attr "mode" "SF")])
15243
15244(define_insn "*fop_sf_comm_sse"
15245 [(set (match_operand:SF 0 "register_operand" "=x")
15246 (match_operator:SF 3 "binary_fp_operator"
15247 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15248 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15249 "TARGET_SSE_MATH
15250 && COMMUTATIVE_ARITH_P (operands[3])
15251 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15252 "* return output_387_binary_op (insn, operands);"
15253 [(set (attr "type")
15254 (if_then_else (match_operand:SF 3 "mult_operator" "")
15255 (const_string "ssemul")
15256 (const_string "sseadd")))
15257 (set_attr "mode" "SF")])
15258
15259(define_insn "*fop_sf_comm_i387"
15260 [(set (match_operand:SF 0 "register_operand" "=f")
15261 (match_operator:SF 3 "binary_fp_operator"
15262 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15263 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15264 "TARGET_80387
15265 && COMMUTATIVE_ARITH_P (operands[3])
15266 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15267 "* return output_387_binary_op (insn, operands);"
15268 [(set (attr "type")
15269 (if_then_else (match_operand:SF 3 "mult_operator" "")
15270 (const_string "fmul")
15271 (const_string "fop")))
15272 (set_attr "mode" "SF")])
15273
15274(define_insn "*fop_sf_1_mixed"
15275 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15276 (match_operator:SF 3 "binary_fp_operator"
15277 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15278 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15279 "TARGET_MIX_SSE_I387
15280 && !COMMUTATIVE_ARITH_P (operands[3])
15281 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15282 "* return output_387_binary_op (insn, operands);"
15283 [(set (attr "type")
15284 (cond [(and (eq_attr "alternative" "2")
15285 (match_operand:SF 3 "mult_operator" ""))
15286 (const_string "ssemul")
15287 (and (eq_attr "alternative" "2")
15288 (match_operand:SF 3 "div_operator" ""))
15289 (const_string "ssediv")
15290 (eq_attr "alternative" "2")
15291 (const_string "sseadd")
15292 (match_operand:SF 3 "mult_operator" "")
15293 (const_string "fmul")
15294 (match_operand:SF 3 "div_operator" "")
15295 (const_string "fdiv")
15296 ]
15297 (const_string "fop")))
15298 (set_attr "mode" "SF")])
15299
15300(define_insn "*fop_sf_1_sse"
15301 [(set (match_operand:SF 0 "register_operand" "=x")
15302 (match_operator:SF 3 "binary_fp_operator"
15303 [(match_operand:SF 1 "register_operand" "0")
15304 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15305 "TARGET_SSE_MATH
15306 && !COMMUTATIVE_ARITH_P (operands[3])"
15307 "* return output_387_binary_op (insn, operands);"
15308 [(set (attr "type")
15309 (cond [(match_operand:SF 3 "mult_operator" "")
15310 (const_string "ssemul")
15311 (match_operand:SF 3 "div_operator" "")
15312 (const_string "ssediv")
15313 ]
15314 (const_string "sseadd")))
15315 (set_attr "mode" "SF")])
15316
15317;; This pattern is not fully shadowed by the pattern above.
15318(define_insn "*fop_sf_1_i387"
15319 [(set (match_operand:SF 0 "register_operand" "=f,f")
15320 (match_operator:SF 3 "binary_fp_operator"
15321 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15322 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15323 "TARGET_80387 && !TARGET_SSE_MATH
15324 && !COMMUTATIVE_ARITH_P (operands[3])
15325 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15326 "* return output_387_binary_op (insn, operands);"
15327 [(set (attr "type")
15328 (cond [(match_operand:SF 3 "mult_operator" "")
15329 (const_string "fmul")
15330 (match_operand:SF 3 "div_operator" "")
15331 (const_string "fdiv")
15332 ]
15333 (const_string "fop")))
15334 (set_attr "mode" "SF")])
15335
15336;; ??? Add SSE splitters for these!
15337(define_insn "*fop_sf_2<mode>_i387"
15338 [(set (match_operand:SF 0 "register_operand" "=f,f")
15339 (match_operator:SF 3 "binary_fp_operator"
15340 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15341 (match_operand:SF 2 "register_operand" "0,0")]))]
15342 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15343 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15344 [(set (attr "type")
15345 (cond [(match_operand:SF 3 "mult_operator" "")
15346 (const_string "fmul")
15347 (match_operand:SF 3 "div_operator" "")
15348 (const_string "fdiv")
15349 ]
15350 (const_string "fop")))
15351 (set_attr "fp_int_src" "true")
15352 (set_attr "mode" "<MODE>")])
15353
15354(define_insn "*fop_sf_3<mode>_i387"
15355 [(set (match_operand:SF 0 "register_operand" "=f,f")
15356 (match_operator:SF 3 "binary_fp_operator"
15357 [(match_operand:SF 1 "register_operand" "0,0")
15358 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15359 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15360 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15361 [(set (attr "type")
15362 (cond [(match_operand:SF 3 "mult_operator" "")
15363 (const_string "fmul")
15364 (match_operand:SF 3 "div_operator" "")
15365 (const_string "fdiv")
15366 ]
15367 (const_string "fop")))
15368 (set_attr "fp_int_src" "true")
15369 (set_attr "mode" "<MODE>")])
15370
15371(define_insn "*fop_df_comm_mixed"
15372 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15373 (match_operator:DF 3 "binary_fp_operator"
15374 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15375 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15376 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15377 && COMMUTATIVE_ARITH_P (operands[3])
15378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15379 "* return output_387_binary_op (insn, operands);"
15380 [(set (attr "type")
15381 (if_then_else (eq_attr "alternative" "1")
15382 (if_then_else (match_operand:DF 3 "mult_operator" "")
15383 (const_string "ssemul")
15384 (const_string "sseadd"))
15385 (if_then_else (match_operand:DF 3 "mult_operator" "")
15386 (const_string "fmul")
15387 (const_string "fop"))))
15388 (set_attr "mode" "DF")])
15389
15390(define_insn "*fop_df_comm_sse"
15391 [(set (match_operand:DF 0 "register_operand" "=Y")
15392 (match_operator:DF 3 "binary_fp_operator"
15393 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15394 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15395 "TARGET_SSE2 && TARGET_SSE_MATH
15396 && COMMUTATIVE_ARITH_P (operands[3])
15397 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15398 "* return output_387_binary_op (insn, operands);"
15399 [(set (attr "type")
15400 (if_then_else (match_operand:DF 3 "mult_operator" "")
15401 (const_string "ssemul")
15402 (const_string "sseadd")))
15403 (set_attr "mode" "DF")])
15404
15405(define_insn "*fop_df_comm_i387"
15406 [(set (match_operand:DF 0 "register_operand" "=f")
15407 (match_operator:DF 3 "binary_fp_operator"
15408 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15409 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15410 "TARGET_80387
15411 && COMMUTATIVE_ARITH_P (operands[3])
15412 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15413 "* return output_387_binary_op (insn, operands);"
15414 [(set (attr "type")
15415 (if_then_else (match_operand:DF 3 "mult_operator" "")
15416 (const_string "fmul")
15417 (const_string "fop")))
15418 (set_attr "mode" "DF")])
15419
15420(define_insn "*fop_df_1_mixed"
15421 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15422 (match_operator:DF 3 "binary_fp_operator"
15423 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15424 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15425 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15426 && !COMMUTATIVE_ARITH_P (operands[3])
15427 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15428 "* return output_387_binary_op (insn, operands);"
15429 [(set (attr "type")
15430 (cond [(and (eq_attr "alternative" "2")
15431 (match_operand:DF 3 "mult_operator" ""))
15432 (const_string "ssemul")
15433 (and (eq_attr "alternative" "2")
15434 (match_operand:DF 3 "div_operator" ""))
15435 (const_string "ssediv")
15436 (eq_attr "alternative" "2")
15437 (const_string "sseadd")
15438 (match_operand:DF 3 "mult_operator" "")
15439 (const_string "fmul")
15440 (match_operand:DF 3 "div_operator" "")
15441 (const_string "fdiv")
15442 ]
15443 (const_string "fop")))
15444 (set_attr "mode" "DF")])
15445
15446(define_insn "*fop_df_1_sse"
15447 [(set (match_operand:DF 0 "register_operand" "=Y")
15448 (match_operator:DF 3 "binary_fp_operator"
15449 [(match_operand:DF 1 "register_operand" "0")
15450 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15451 "TARGET_SSE2 && TARGET_SSE_MATH
15452 && !COMMUTATIVE_ARITH_P (operands[3])"
15453 "* return output_387_binary_op (insn, operands);"
15454 [(set_attr "mode" "DF")
15455 (set (attr "type")
15456 (cond [(match_operand:DF 3 "mult_operator" "")
15457 (const_string "ssemul")
15458 (match_operand:DF 3 "div_operator" "")
15459 (const_string "ssediv")
15460 ]
15461 (const_string "sseadd")))])
15462
15463;; This pattern is not fully shadowed by the pattern above.
15464(define_insn "*fop_df_1_i387"
15465 [(set (match_operand:DF 0 "register_operand" "=f,f")
15466 (match_operator:DF 3 "binary_fp_operator"
15467 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15468 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15469 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15470 && !COMMUTATIVE_ARITH_P (operands[3])
15471 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15472 "* return output_387_binary_op (insn, operands);"
15473 [(set (attr "type")
15474 (cond [(match_operand:DF 3 "mult_operator" "")
15475 (const_string "fmul")
15476 (match_operand:DF 3 "div_operator" "")
15477 (const_string "fdiv")
15478 ]
15479 (const_string "fop")))
15480 (set_attr "mode" "DF")])
15481
15482;; ??? Add SSE splitters for these!
15483(define_insn "*fop_df_2<mode>_i387"
15484 [(set (match_operand:DF 0 "register_operand" "=f,f")
15485 (match_operator:DF 3 "binary_fp_operator"
15486 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15487 (match_operand:DF 2 "register_operand" "0,0")]))]
15488 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15489 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15490 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15491 [(set (attr "type")
15492 (cond [(match_operand:DF 3 "mult_operator" "")
15493 (const_string "fmul")
15494 (match_operand:DF 3 "div_operator" "")
15495 (const_string "fdiv")
15496 ]
15497 (const_string "fop")))
15498 (set_attr "fp_int_src" "true")
15499 (set_attr "mode" "<MODE>")])
15500
15501(define_insn "*fop_df_3<mode>_i387"
15502 [(set (match_operand:DF 0 "register_operand" "=f,f")
15503 (match_operator:DF 3 "binary_fp_operator"
15504 [(match_operand:DF 1 "register_operand" "0,0")
15505 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15506 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15507 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15508 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15509 [(set (attr "type")
15510 (cond [(match_operand:DF 3 "mult_operator" "")
15511 (const_string "fmul")
15512 (match_operand:DF 3 "div_operator" "")
15513 (const_string "fdiv")
15514 ]
15515 (const_string "fop")))
15516 (set_attr "fp_int_src" "true")
15517 (set_attr "mode" "<MODE>")])
15518
15519(define_insn "*fop_df_4_i387"
15520 [(set (match_operand:DF 0 "register_operand" "=f,f")
15521 (match_operator:DF 3 "binary_fp_operator"
15522 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15523 (match_operand:DF 2 "register_operand" "0,f")]))]
15524 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15525 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15526 "* return output_387_binary_op (insn, operands);"
15527 [(set (attr "type")
15528 (cond [(match_operand:DF 3 "mult_operator" "")
15529 (const_string "fmul")
15530 (match_operand:DF 3 "div_operator" "")
15531 (const_string "fdiv")
15532 ]
15533 (const_string "fop")))
15534 (set_attr "mode" "SF")])
15535
15536(define_insn "*fop_df_5_i387"
15537 [(set (match_operand:DF 0 "register_operand" "=f,f")
15538 (match_operator:DF 3 "binary_fp_operator"
15539 [(match_operand:DF 1 "register_operand" "0,f")
15540 (float_extend:DF
15541 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15542 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15543 "* return output_387_binary_op (insn, operands);"
15544 [(set (attr "type")
15545 (cond [(match_operand:DF 3 "mult_operator" "")
15546 (const_string "fmul")
15547 (match_operand:DF 3 "div_operator" "")
15548 (const_string "fdiv")
15549 ]
15550 (const_string "fop")))
15551 (set_attr "mode" "SF")])
15552
15553(define_insn "*fop_df_6_i387"
15554 [(set (match_operand:DF 0 "register_operand" "=f,f")
15555 (match_operator:DF 3 "binary_fp_operator"
15556 [(float_extend:DF
15557 (match_operand:SF 1 "register_operand" "0,f"))
15558 (float_extend:DF
15559 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15560 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15561 "* return output_387_binary_op (insn, operands);"
15562 [(set (attr "type")
15563 (cond [(match_operand:DF 3 "mult_operator" "")
15564 (const_string "fmul")
15565 (match_operand:DF 3 "div_operator" "")
15566 (const_string "fdiv")
15567 ]
15568 (const_string "fop")))
15569 (set_attr "mode" "SF")])
15570
15571(define_insn "*fop_xf_comm_i387"
15572 [(set (match_operand:XF 0 "register_operand" "=f")
15573 (match_operator:XF 3 "binary_fp_operator"
15574 [(match_operand:XF 1 "register_operand" "%0")
15575 (match_operand:XF 2 "register_operand" "f")]))]
15576 "TARGET_80387
15577 && COMMUTATIVE_ARITH_P (operands[3])"
15578 "* return output_387_binary_op (insn, operands);"
15579 [(set (attr "type")
15580 (if_then_else (match_operand:XF 3 "mult_operator" "")
15581 (const_string "fmul")
15582 (const_string "fop")))
15583 (set_attr "mode" "XF")])
15584
15585(define_insn "*fop_xf_1_i387"
15586 [(set (match_operand:XF 0 "register_operand" "=f,f")
15587 (match_operator:XF 3 "binary_fp_operator"
15588 [(match_operand:XF 1 "register_operand" "0,f")
15589 (match_operand:XF 2 "register_operand" "f,0")]))]
15590 "TARGET_80387
15591 && !COMMUTATIVE_ARITH_P (operands[3])"
15592 "* return output_387_binary_op (insn, operands);"
15593 [(set (attr "type")
15594 (cond [(match_operand:XF 3 "mult_operator" "")
15595 (const_string "fmul")
15596 (match_operand:XF 3 "div_operator" "")
15597 (const_string "fdiv")
15598 ]
15599 (const_string "fop")))
15600 (set_attr "mode" "XF")])
15601
15602(define_insn "*fop_xf_2<mode>_i387"
15603 [(set (match_operand:XF 0 "register_operand" "=f,f")
15604 (match_operator:XF 3 "binary_fp_operator"
15605 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15606 (match_operand:XF 2 "register_operand" "0,0")]))]
15607 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15608 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15609 [(set (attr "type")
15610 (cond [(match_operand:XF 3 "mult_operator" "")
15611 (const_string "fmul")
15612 (match_operand:XF 3 "div_operator" "")
15613 (const_string "fdiv")
15614 ]
15615 (const_string "fop")))
15616 (set_attr "fp_int_src" "true")
15617 (set_attr "mode" "<MODE>")])
15618
15619(define_insn "*fop_xf_3<mode>_i387"
15620 [(set (match_operand:XF 0 "register_operand" "=f,f")
15621 (match_operator:XF 3 "binary_fp_operator"
15622 [(match_operand:XF 1 "register_operand" "0,0")
15623 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15624 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15625 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15626 [(set (attr "type")
15627 (cond [(match_operand:XF 3 "mult_operator" "")
15628 (const_string "fmul")
15629 (match_operand:XF 3 "div_operator" "")
15630 (const_string "fdiv")
15631 ]
15632 (const_string "fop")))
15633 (set_attr "fp_int_src" "true")
15634 (set_attr "mode" "<MODE>")])
15635
15636(define_insn "*fop_xf_4_i387"
15637 [(set (match_operand:XF 0 "register_operand" "=f,f")
15638 (match_operator:XF 3 "binary_fp_operator"
15639 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15640 (match_operand:XF 2 "register_operand" "0,f")]))]
15641 "TARGET_80387"
15642 "* return output_387_binary_op (insn, operands);"
15643 [(set (attr "type")
15644 (cond [(match_operand:XF 3 "mult_operator" "")
15645 (const_string "fmul")
15646 (match_operand:XF 3 "div_operator" "")
15647 (const_string "fdiv")
15648 ]
15649 (const_string "fop")))
15650 (set_attr "mode" "SF")])
15651
15652(define_insn "*fop_xf_5_i387"
15653 [(set (match_operand:XF 0 "register_operand" "=f,f")
15654 (match_operator:XF 3 "binary_fp_operator"
15655 [(match_operand:XF 1 "register_operand" "0,f")
15656 (float_extend:XF
15657 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15658 "TARGET_80387"
15659 "* return output_387_binary_op (insn, operands);"
15660 [(set (attr "type")
15661 (cond [(match_operand:XF 3 "mult_operator" "")
15662 (const_string "fmul")
15663 (match_operand:XF 3 "div_operator" "")
15664 (const_string "fdiv")
15665 ]
15666 (const_string "fop")))
15667 (set_attr "mode" "SF")])
15668
15669(define_insn "*fop_xf_6_i387"
15670 [(set (match_operand:XF 0 "register_operand" "=f,f")
15671 (match_operator:XF 3 "binary_fp_operator"
15672 [(float_extend:XF
15673 (match_operand 1 "register_operand" "0,f"))
15674 (float_extend:XF
15675 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15676 "TARGET_80387"
15677 "* return output_387_binary_op (insn, operands);"
15678 [(set (attr "type")
15679 (cond [(match_operand:XF 3 "mult_operator" "")
15680 (const_string "fmul")
15681 (match_operand:XF 3 "div_operator" "")
15682 (const_string "fdiv")
15683 ]
15684 (const_string "fop")))
15685 (set_attr "mode" "SF")])
15686
15687(define_split
15688 [(set (match_operand 0 "register_operand" "")
15689 (match_operator 3 "binary_fp_operator"
15690 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15691 (match_operand 2 "register_operand" "")]))]
15692 "TARGET_80387 && reload_completed
15693 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15694 [(const_int 0)]
15695{
15696 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15697 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15698 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15699 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15700 GET_MODE (operands[3]),
15701 operands[4],
15702 operands[2])));
15703 ix86_free_from_memory (GET_MODE (operands[1]));
15704 DONE;
15705})
15706
15707(define_split
15708 [(set (match_operand 0 "register_operand" "")
15709 (match_operator 3 "binary_fp_operator"
15710 [(match_operand 1 "register_operand" "")
15711 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15712 "TARGET_80387 && reload_completed
15713 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15714 [(const_int 0)]
15715{
15716 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15717 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15718 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15719 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15720 GET_MODE (operands[3]),
15721 operands[1],
15722 operands[4])));
15723 ix86_free_from_memory (GET_MODE (operands[2]));
15724 DONE;
15725})
15726
15727;; FPU special functions.
15728
15729(define_expand "sqrtsf2"
15730 [(set (match_operand:SF 0 "register_operand" "")
15731 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15732 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15733{
15734 if (!TARGET_SSE_MATH)
15735 operands[1] = force_reg (SFmode, operands[1]);
15736})
15737
15738(define_insn "*sqrtsf2_mixed"
15739 [(set (match_operand:SF 0 "register_operand" "=f,x")
15740 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15741 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15742 "@
15743 fsqrt
15744 sqrtss\t{%1, %0|%0, %1}"
15745 [(set_attr "type" "fpspc,sse")
15746 (set_attr "mode" "SF,SF")
15497 (set_attr "athlon_decode" "direct,*")])
15747 (set_attr "athlon_decode" "direct,*")
15748 (set_attr "amdfam10_decode" "direct,*")])
15498
15499(define_insn "*sqrtsf2_sse"
15500 [(set (match_operand:SF 0 "register_operand" "=x")
15501 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15502 "TARGET_SSE_MATH"
15503 "sqrtss\t{%1, %0|%0, %1}"
15504 [(set_attr "type" "sse")
15505 (set_attr "mode" "SF")
15749
15750(define_insn "*sqrtsf2_sse"
15751 [(set (match_operand:SF 0 "register_operand" "=x")
15752 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15753 "TARGET_SSE_MATH"
15754 "sqrtss\t{%1, %0|%0, %1}"
15755 [(set_attr "type" "sse")
15756 (set_attr "mode" "SF")
15506 (set_attr "athlon_decode" "*")])
15757 (set_attr "athlon_decode" "*")
15758 (set_attr "amdfam10_decode" "*")])
15507
15508(define_insn "*sqrtsf2_i387"
15509 [(set (match_operand:SF 0 "register_operand" "=f")
15510 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15511 "TARGET_USE_FANCY_MATH_387"
15512 "fsqrt"
15513 [(set_attr "type" "fpspc")
15514 (set_attr "mode" "SF")
15759
15760(define_insn "*sqrtsf2_i387"
15761 [(set (match_operand:SF 0 "register_operand" "=f")
15762 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15763 "TARGET_USE_FANCY_MATH_387"
15764 "fsqrt"
15765 [(set_attr "type" "fpspc")
15766 (set_attr "mode" "SF")
15515 (set_attr "athlon_decode" "direct")])
15767 (set_attr "athlon_decode" "direct")
15768 (set_attr "amdfam10_decode" "direct")])
15516
15517(define_expand "sqrtdf2"
15518 [(set (match_operand:DF 0 "register_operand" "")
15519 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15520 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15521{
15522 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15523 operands[1] = force_reg (DFmode, operands[1]);
15524})
15525
15526(define_insn "*sqrtdf2_mixed"
15527 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15528 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15529 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15530 "@
15531 fsqrt
15532 sqrtsd\t{%1, %0|%0, %1}"
15533 [(set_attr "type" "fpspc,sse")
15534 (set_attr "mode" "DF,DF")
15769
15770(define_expand "sqrtdf2"
15771 [(set (match_operand:DF 0 "register_operand" "")
15772 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15773 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15774{
15775 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15776 operands[1] = force_reg (DFmode, operands[1]);
15777})
15778
15779(define_insn "*sqrtdf2_mixed"
15780 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15781 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15782 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15783 "@
15784 fsqrt
15785 sqrtsd\t{%1, %0|%0, %1}"
15786 [(set_attr "type" "fpspc,sse")
15787 (set_attr "mode" "DF,DF")
15535 (set_attr "athlon_decode" "direct,*")])
15788 (set_attr "athlon_decode" "direct,*")
15789 (set_attr "amdfam10_decode" "direct,*")])
15536
15537(define_insn "*sqrtdf2_sse"
15538 [(set (match_operand:DF 0 "register_operand" "=Y")
15539 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15540 "TARGET_SSE2 && TARGET_SSE_MATH"
15541 "sqrtsd\t{%1, %0|%0, %1}"
15542 [(set_attr "type" "sse")
15543 (set_attr "mode" "DF")
15790
15791(define_insn "*sqrtdf2_sse"
15792 [(set (match_operand:DF 0 "register_operand" "=Y")
15793 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15794 "TARGET_SSE2 && TARGET_SSE_MATH"
15795 "sqrtsd\t{%1, %0|%0, %1}"
15796 [(set_attr "type" "sse")
15797 (set_attr "mode" "DF")
15544 (set_attr "athlon_decode" "*")])
15798 (set_attr "athlon_decode" "*")
15799 (set_attr "amdfam10_decode" "*")])
15545
15546(define_insn "*sqrtdf2_i387"
15547 [(set (match_operand:DF 0 "register_operand" "=f")
15548 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15549 "TARGET_USE_FANCY_MATH_387"
15550 "fsqrt"
15551 [(set_attr "type" "fpspc")
15552 (set_attr "mode" "DF")
15800
15801(define_insn "*sqrtdf2_i387"
15802 [(set (match_operand:DF 0 "register_operand" "=f")
15803 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15804 "TARGET_USE_FANCY_MATH_387"
15805 "fsqrt"
15806 [(set_attr "type" "fpspc")
15807 (set_attr "mode" "DF")
15553 (set_attr "athlon_decode" "direct")])
15808 (set_attr "athlon_decode" "direct")
15809 (set_attr "amdfam10_decode" "direct")])
15554
15555(define_insn "*sqrtextendsfdf2_i387"
15556 [(set (match_operand:DF 0 "register_operand" "=f")
15557 (sqrt:DF (float_extend:DF
15558 (match_operand:SF 1 "register_operand" "0"))))]
15559 "TARGET_USE_FANCY_MATH_387
15560 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15561 "fsqrt"
15562 [(set_attr "type" "fpspc")
15563 (set_attr "mode" "DF")
15810
15811(define_insn "*sqrtextendsfdf2_i387"
15812 [(set (match_operand:DF 0 "register_operand" "=f")
15813 (sqrt:DF (float_extend:DF
15814 (match_operand:SF 1 "register_operand" "0"))))]
15815 "TARGET_USE_FANCY_MATH_387
15816 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15817 "fsqrt"
15818 [(set_attr "type" "fpspc")
15819 (set_attr "mode" "DF")
15564 (set_attr "athlon_decode" "direct")])
15820 (set_attr "athlon_decode" "direct")
15821 (set_attr "amdfam10_decode" "direct")])
15565
15566(define_insn "sqrtxf2"
15567 [(set (match_operand:XF 0 "register_operand" "=f")
15568 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15569 "TARGET_USE_FANCY_MATH_387"
15570 "fsqrt"
15571 [(set_attr "type" "fpspc")
15572 (set_attr "mode" "XF")
15822
15823(define_insn "sqrtxf2"
15824 [(set (match_operand:XF 0 "register_operand" "=f")
15825 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15826 "TARGET_USE_FANCY_MATH_387"
15827 "fsqrt"
15828 [(set_attr "type" "fpspc")
15829 (set_attr "mode" "XF")
15573 (set_attr "athlon_decode" "direct")])
15830 (set_attr "athlon_decode" "direct")
15831 (set_attr "amdfam10_decode" "direct")])
15574
15575(define_insn "*sqrtextendsfxf2_i387"
15576 [(set (match_operand:XF 0 "register_operand" "=f")
15577 (sqrt:XF (float_extend:XF
15578 (match_operand:SF 1 "register_operand" "0"))))]
15579 "TARGET_USE_FANCY_MATH_387"
15580 "fsqrt"
15581 [(set_attr "type" "fpspc")
15582 (set_attr "mode" "XF")
15832
15833(define_insn "*sqrtextendsfxf2_i387"
15834 [(set (match_operand:XF 0 "register_operand" "=f")
15835 (sqrt:XF (float_extend:XF
15836 (match_operand:SF 1 "register_operand" "0"))))]
15837 "TARGET_USE_FANCY_MATH_387"
15838 "fsqrt"
15839 [(set_attr "type" "fpspc")
15840 (set_attr "mode" "XF")
15583 (set_attr "athlon_decode" "direct")])
15841 (set_attr "athlon_decode" "direct")
15842 (set_attr "amdfam10_decode" "direct")])
15584
15585(define_insn "*sqrtextenddfxf2_i387"
15586 [(set (match_operand:XF 0 "register_operand" "=f")
15587 (sqrt:XF (float_extend:XF
15588 (match_operand:DF 1 "register_operand" "0"))))]
15589 "TARGET_USE_FANCY_MATH_387"
15590 "fsqrt"
15591 [(set_attr "type" "fpspc")
15592 (set_attr "mode" "XF")
15843
15844(define_insn "*sqrtextenddfxf2_i387"
15845 [(set (match_operand:XF 0 "register_operand" "=f")
15846 (sqrt:XF (float_extend:XF
15847 (match_operand:DF 1 "register_operand" "0"))))]
15848 "TARGET_USE_FANCY_MATH_387"
15849 "fsqrt"
15850 [(set_attr "type" "fpspc")
15851 (set_attr "mode" "XF")
15593 (set_attr "athlon_decode" "direct")])
15852 (set_attr "athlon_decode" "direct")
15853 (set_attr "amdfam10_decode" "direct")])
15594
15595(define_insn "fpremxf4"
15596 [(set (match_operand:XF 0 "register_operand" "=f")
15597 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15598 (match_operand:XF 3 "register_operand" "1")]
15599 UNSPEC_FPREM_F))
15600 (set (match_operand:XF 1 "register_operand" "=u")
15601 (unspec:XF [(match_dup 2) (match_dup 3)]
15602 UNSPEC_FPREM_U))
15603 (set (reg:CCFP FPSR_REG)
15604 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15605 "TARGET_USE_FANCY_MATH_387
15606 && flag_unsafe_math_optimizations"
15607 "fprem"
15608 [(set_attr "type" "fpspc")
15609 (set_attr "mode" "XF")])
15610
15611(define_expand "fmodsf3"
15612 [(use (match_operand:SF 0 "register_operand" ""))
15613 (use (match_operand:SF 1 "register_operand" ""))
15614 (use (match_operand:SF 2 "register_operand" ""))]
15615 "TARGET_USE_FANCY_MATH_387
15616 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15617 && flag_unsafe_math_optimizations"
15618{
15619 rtx label = gen_label_rtx ();
15620
15621 rtx op1 = gen_reg_rtx (XFmode);
15622 rtx op2 = gen_reg_rtx (XFmode);
15623
15624 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15625 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15626
15627 emit_label (label);
15628
15629 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15630 ix86_emit_fp_unordered_jump (label);
15631
15632 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15633 DONE;
15634})
15635
15636(define_expand "fmoddf3"
15637 [(use (match_operand:DF 0 "register_operand" ""))
15638 (use (match_operand:DF 1 "register_operand" ""))
15639 (use (match_operand:DF 2 "register_operand" ""))]
15640 "TARGET_USE_FANCY_MATH_387
15641 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15642 && flag_unsafe_math_optimizations"
15643{
15644 rtx label = gen_label_rtx ();
15645
15646 rtx op1 = gen_reg_rtx (XFmode);
15647 rtx op2 = gen_reg_rtx (XFmode);
15648
15649 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15650 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15651
15652 emit_label (label);
15653
15654 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15655 ix86_emit_fp_unordered_jump (label);
15656
15657 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15658 DONE;
15659})
15660
15661(define_expand "fmodxf3"
15662 [(use (match_operand:XF 0 "register_operand" ""))
15663 (use (match_operand:XF 1 "register_operand" ""))
15664 (use (match_operand:XF 2 "register_operand" ""))]
15665 "TARGET_USE_FANCY_MATH_387
15666 && flag_unsafe_math_optimizations"
15667{
15668 rtx label = gen_label_rtx ();
15669
15670 emit_label (label);
15671
15672 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15673 operands[1], operands[2]));
15674 ix86_emit_fp_unordered_jump (label);
15675
15676 emit_move_insn (operands[0], operands[1]);
15677 DONE;
15678})
15679
15680(define_insn "fprem1xf4"
15681 [(set (match_operand:XF 0 "register_operand" "=f")
15682 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15683 (match_operand:XF 3 "register_operand" "1")]
15684 UNSPEC_FPREM1_F))
15685 (set (match_operand:XF 1 "register_operand" "=u")
15686 (unspec:XF [(match_dup 2) (match_dup 3)]
15687 UNSPEC_FPREM1_U))
15688 (set (reg:CCFP FPSR_REG)
15689 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15690 "TARGET_USE_FANCY_MATH_387
15691 && flag_unsafe_math_optimizations"
15692 "fprem1"
15693 [(set_attr "type" "fpspc")
15694 (set_attr "mode" "XF")])
15695
15696(define_expand "dremsf3"
15697 [(use (match_operand:SF 0 "register_operand" ""))
15698 (use (match_operand:SF 1 "register_operand" ""))
15699 (use (match_operand:SF 2 "register_operand" ""))]
15700 "TARGET_USE_FANCY_MATH_387
15701 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15702 && flag_unsafe_math_optimizations"
15703{
15704 rtx label = gen_label_rtx ();
15705
15706 rtx op1 = gen_reg_rtx (XFmode);
15707 rtx op2 = gen_reg_rtx (XFmode);
15708
15709 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15710 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15711
15712 emit_label (label);
15713
15714 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15715 ix86_emit_fp_unordered_jump (label);
15716
15717 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15718 DONE;
15719})
15720
15721(define_expand "dremdf3"
15722 [(use (match_operand:DF 0 "register_operand" ""))
15723 (use (match_operand:DF 1 "register_operand" ""))
15724 (use (match_operand:DF 2 "register_operand" ""))]
15725 "TARGET_USE_FANCY_MATH_387
15726 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15727 && flag_unsafe_math_optimizations"
15728{
15729 rtx label = gen_label_rtx ();
15730
15731 rtx op1 = gen_reg_rtx (XFmode);
15732 rtx op2 = gen_reg_rtx (XFmode);
15733
15734 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15735 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15736
15737 emit_label (label);
15738
15739 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15740 ix86_emit_fp_unordered_jump (label);
15741
15742 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15743 DONE;
15744})
15745
15746(define_expand "dremxf3"
15747 [(use (match_operand:XF 0 "register_operand" ""))
15748 (use (match_operand:XF 1 "register_operand" ""))
15749 (use (match_operand:XF 2 "register_operand" ""))]
15750 "TARGET_USE_FANCY_MATH_387
15751 && flag_unsafe_math_optimizations"
15752{
15753 rtx label = gen_label_rtx ();
15754
15755 emit_label (label);
15756
15757 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15758 operands[1], operands[2]));
15759 ix86_emit_fp_unordered_jump (label);
15760
15761 emit_move_insn (operands[0], operands[1]);
15762 DONE;
15763})
15764
15765(define_insn "*sindf2"
15766 [(set (match_operand:DF 0 "register_operand" "=f")
15767 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15768 "TARGET_USE_FANCY_MATH_387
15769 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15770 && flag_unsafe_math_optimizations"
15771 "fsin"
15772 [(set_attr "type" "fpspc")
15773 (set_attr "mode" "DF")])
15774
15775(define_insn "*sinsf2"
15776 [(set (match_operand:SF 0 "register_operand" "=f")
15777 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15778 "TARGET_USE_FANCY_MATH_387
15779 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15780 && flag_unsafe_math_optimizations"
15781 "fsin"
15782 [(set_attr "type" "fpspc")
15783 (set_attr "mode" "SF")])
15784
15785(define_insn "*sinextendsfdf2"
15786 [(set (match_operand:DF 0 "register_operand" "=f")
15787 (unspec:DF [(float_extend:DF
15788 (match_operand:SF 1 "register_operand" "0"))]
15789 UNSPEC_SIN))]
15790 "TARGET_USE_FANCY_MATH_387
15791 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15792 && flag_unsafe_math_optimizations"
15793 "fsin"
15794 [(set_attr "type" "fpspc")
15795 (set_attr "mode" "DF")])
15796
15797(define_insn "*sinxf2"
15798 [(set (match_operand:XF 0 "register_operand" "=f")
15799 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15800 "TARGET_USE_FANCY_MATH_387
15801 && flag_unsafe_math_optimizations"
15802 "fsin"
15803 [(set_attr "type" "fpspc")
15804 (set_attr "mode" "XF")])
15805
15806(define_insn "*cosdf2"
15807 [(set (match_operand:DF 0 "register_operand" "=f")
15808 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15809 "TARGET_USE_FANCY_MATH_387
15810 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15811 && flag_unsafe_math_optimizations"
15812 "fcos"
15813 [(set_attr "type" "fpspc")
15814 (set_attr "mode" "DF")])
15815
15816(define_insn "*cossf2"
15817 [(set (match_operand:SF 0 "register_operand" "=f")
15818 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15819 "TARGET_USE_FANCY_MATH_387
15820 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15821 && flag_unsafe_math_optimizations"
15822 "fcos"
15823 [(set_attr "type" "fpspc")
15824 (set_attr "mode" "SF")])
15825
15826(define_insn "*cosextendsfdf2"
15827 [(set (match_operand:DF 0 "register_operand" "=f")
15828 (unspec:DF [(float_extend:DF
15829 (match_operand:SF 1 "register_operand" "0"))]
15830 UNSPEC_COS))]
15831 "TARGET_USE_FANCY_MATH_387
15832 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15833 && flag_unsafe_math_optimizations"
15834 "fcos"
15835 [(set_attr "type" "fpspc")
15836 (set_attr "mode" "DF")])
15837
15838(define_insn "*cosxf2"
15839 [(set (match_operand:XF 0 "register_operand" "=f")
15840 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15841 "TARGET_USE_FANCY_MATH_387
15842 && flag_unsafe_math_optimizations"
15843 "fcos"
15844 [(set_attr "type" "fpspc")
15845 (set_attr "mode" "XF")])
15846
15847;; With sincos pattern defined, sin and cos builtin function will be
15848;; expanded to sincos pattern with one of its outputs left unused.
15849;; Cse pass will detected, if two sincos patterns can be combined,
15850;; otherwise sincos pattern will be split back to sin or cos pattern,
15851;; depending on the unused output.
15852
15853(define_insn "sincosdf3"
15854 [(set (match_operand:DF 0 "register_operand" "=f")
15855 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15856 UNSPEC_SINCOS_COS))
15857 (set (match_operand:DF 1 "register_operand" "=u")
15858 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15859 "TARGET_USE_FANCY_MATH_387
15860 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15861 && flag_unsafe_math_optimizations"
15862 "fsincos"
15863 [(set_attr "type" "fpspc")
15864 (set_attr "mode" "DF")])
15865
15866(define_split
15867 [(set (match_operand:DF 0 "register_operand" "")
15868 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15869 UNSPEC_SINCOS_COS))
15870 (set (match_operand:DF 1 "register_operand" "")
15871 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15872 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15873 && !reload_completed && !reload_in_progress"
15874 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15875 "")
15876
15877(define_split
15878 [(set (match_operand:DF 0 "register_operand" "")
15879 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15880 UNSPEC_SINCOS_COS))
15881 (set (match_operand:DF 1 "register_operand" "")
15882 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15883 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15884 && !reload_completed && !reload_in_progress"
15885 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15886 "")
15887
15888(define_insn "sincossf3"
15889 [(set (match_operand:SF 0 "register_operand" "=f")
15890 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15891 UNSPEC_SINCOS_COS))
15892 (set (match_operand:SF 1 "register_operand" "=u")
15893 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15894 "TARGET_USE_FANCY_MATH_387
15895 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15896 && flag_unsafe_math_optimizations"
15897 "fsincos"
15898 [(set_attr "type" "fpspc")
15899 (set_attr "mode" "SF")])
15900
15901(define_split
15902 [(set (match_operand:SF 0 "register_operand" "")
15903 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15904 UNSPEC_SINCOS_COS))
15905 (set (match_operand:SF 1 "register_operand" "")
15906 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15907 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15908 && !reload_completed && !reload_in_progress"
15909 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15910 "")
15911
15912(define_split
15913 [(set (match_operand:SF 0 "register_operand" "")
15914 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15915 UNSPEC_SINCOS_COS))
15916 (set (match_operand:SF 1 "register_operand" "")
15917 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15918 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15919 && !reload_completed && !reload_in_progress"
15920 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15921 "")
15922
15923(define_insn "*sincosextendsfdf3"
15924 [(set (match_operand:DF 0 "register_operand" "=f")
15925 (unspec:DF [(float_extend:DF
15926 (match_operand:SF 2 "register_operand" "0"))]
15927 UNSPEC_SINCOS_COS))
15928 (set (match_operand:DF 1 "register_operand" "=u")
15929 (unspec:DF [(float_extend:DF
15930 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15931 "TARGET_USE_FANCY_MATH_387
15932 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15933 && flag_unsafe_math_optimizations"
15934 "fsincos"
15935 [(set_attr "type" "fpspc")
15936 (set_attr "mode" "DF")])
15937
15938(define_split
15939 [(set (match_operand:DF 0 "register_operand" "")
15940 (unspec:DF [(float_extend:DF
15941 (match_operand:SF 2 "register_operand" ""))]
15942 UNSPEC_SINCOS_COS))
15943 (set (match_operand:DF 1 "register_operand" "")
15944 (unspec:DF [(float_extend:DF
15945 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15946 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15947 && !reload_completed && !reload_in_progress"
15948 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15949 (match_dup 2))] UNSPEC_SIN))]
15950 "")
15951
15952(define_split
15953 [(set (match_operand:DF 0 "register_operand" "")
15954 (unspec:DF [(float_extend:DF
15955 (match_operand:SF 2 "register_operand" ""))]
15956 UNSPEC_SINCOS_COS))
15957 (set (match_operand:DF 1 "register_operand" "")
15958 (unspec:DF [(float_extend:DF
15959 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15960 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15961 && !reload_completed && !reload_in_progress"
15962 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15963 (match_dup 2))] UNSPEC_COS))]
15964 "")
15965
15966(define_insn "sincosxf3"
15967 [(set (match_operand:XF 0 "register_operand" "=f")
15968 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15969 UNSPEC_SINCOS_COS))
15970 (set (match_operand:XF 1 "register_operand" "=u")
15971 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15972 "TARGET_USE_FANCY_MATH_387
15973 && flag_unsafe_math_optimizations"
15974 "fsincos"
15975 [(set_attr "type" "fpspc")
15976 (set_attr "mode" "XF")])
15977
15978(define_split
15979 [(set (match_operand:XF 0 "register_operand" "")
15980 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15981 UNSPEC_SINCOS_COS))
15982 (set (match_operand:XF 1 "register_operand" "")
15983 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15984 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15985 && !reload_completed && !reload_in_progress"
15986 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15987 "")
15988
15989(define_split
15990 [(set (match_operand:XF 0 "register_operand" "")
15991 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15992 UNSPEC_SINCOS_COS))
15993 (set (match_operand:XF 1 "register_operand" "")
15994 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15995 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15996 && !reload_completed && !reload_in_progress"
15997 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15998 "")
15999
16000(define_insn "*tandf3_1"
16001 [(set (match_operand:DF 0 "register_operand" "=f")
16002 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16003 UNSPEC_TAN_ONE))
16004 (set (match_operand:DF 1 "register_operand" "=u")
16005 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16006 "TARGET_USE_FANCY_MATH_387
16007 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16008 && flag_unsafe_math_optimizations"
16009 "fptan"
16010 [(set_attr "type" "fpspc")
16011 (set_attr "mode" "DF")])
16012
16013;; optimize sequence: fptan
16014;; fstp %st(0)
16015;; fld1
16016;; into fptan insn.
16017
16018(define_peephole2
16019 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16020 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16021 UNSPEC_TAN_ONE))
16022 (set (match_operand:DF 1 "register_operand" "")
16023 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16024 (set (match_dup 0)
16025 (match_operand:DF 3 "immediate_operand" ""))]
16026 "standard_80387_constant_p (operands[3]) == 2"
16027 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16028 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16029 "")
16030
16031(define_expand "tandf2"
16032 [(parallel [(set (match_dup 2)
16033 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16034 UNSPEC_TAN_ONE))
16035 (set (match_operand:DF 0 "register_operand" "")
16036 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16037 "TARGET_USE_FANCY_MATH_387
16038 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16039 && flag_unsafe_math_optimizations"
16040{
16041 operands[2] = gen_reg_rtx (DFmode);
16042})
16043
16044(define_insn "*tansf3_1"
16045 [(set (match_operand:SF 0 "register_operand" "=f")
16046 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16047 UNSPEC_TAN_ONE))
16048 (set (match_operand:SF 1 "register_operand" "=u")
16049 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16050 "TARGET_USE_FANCY_MATH_387
16051 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16052 && flag_unsafe_math_optimizations"
16053 "fptan"
16054 [(set_attr "type" "fpspc")
16055 (set_attr "mode" "SF")])
16056
16057;; optimize sequence: fptan
16058;; fstp %st(0)
16059;; fld1
16060;; into fptan insn.
16061
16062(define_peephole2
16063 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16064 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16065 UNSPEC_TAN_ONE))
16066 (set (match_operand:SF 1 "register_operand" "")
16067 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16068 (set (match_dup 0)
16069 (match_operand:SF 3 "immediate_operand" ""))]
16070 "standard_80387_constant_p (operands[3]) == 2"
16071 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16072 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16073 "")
16074
16075(define_expand "tansf2"
16076 [(parallel [(set (match_dup 2)
16077 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16078 UNSPEC_TAN_ONE))
16079 (set (match_operand:SF 0 "register_operand" "")
16080 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16081 "TARGET_USE_FANCY_MATH_387
16082 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16083 && flag_unsafe_math_optimizations"
16084{
16085 operands[2] = gen_reg_rtx (SFmode);
16086})
16087
16088(define_insn "*tanxf3_1"
16089 [(set (match_operand:XF 0 "register_operand" "=f")
16090 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16091 UNSPEC_TAN_ONE))
16092 (set (match_operand:XF 1 "register_operand" "=u")
16093 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16094 "TARGET_USE_FANCY_MATH_387
16095 && flag_unsafe_math_optimizations"
16096 "fptan"
16097 [(set_attr "type" "fpspc")
16098 (set_attr "mode" "XF")])
16099
16100;; optimize sequence: fptan
16101;; fstp %st(0)
16102;; fld1
16103;; into fptan insn.
16104
16105(define_peephole2
16106 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16107 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16108 UNSPEC_TAN_ONE))
16109 (set (match_operand:XF 1 "register_operand" "")
16110 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16111 (set (match_dup 0)
16112 (match_operand:XF 3 "immediate_operand" ""))]
16113 "standard_80387_constant_p (operands[3]) == 2"
16114 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16115 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16116 "")
16117
16118(define_expand "tanxf2"
16119 [(parallel [(set (match_dup 2)
16120 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16121 UNSPEC_TAN_ONE))
16122 (set (match_operand:XF 0 "register_operand" "")
16123 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16124 "TARGET_USE_FANCY_MATH_387
16125 && flag_unsafe_math_optimizations"
16126{
16127 operands[2] = gen_reg_rtx (XFmode);
16128})
16129
16130(define_insn "atan2df3_1"
16131 [(set (match_operand:DF 0 "register_operand" "=f")
16132 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16133 (match_operand:DF 1 "register_operand" "u")]
16134 UNSPEC_FPATAN))
16135 (clobber (match_scratch:DF 3 "=1"))]
16136 "TARGET_USE_FANCY_MATH_387
16137 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16138 && flag_unsafe_math_optimizations"
16139 "fpatan"
16140 [(set_attr "type" "fpspc")
16141 (set_attr "mode" "DF")])
16142
16143(define_expand "atan2df3"
16144 [(use (match_operand:DF 0 "register_operand" ""))
16145 (use (match_operand:DF 2 "register_operand" ""))
16146 (use (match_operand:DF 1 "register_operand" ""))]
16147 "TARGET_USE_FANCY_MATH_387
16148 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16149 && flag_unsafe_math_optimizations"
16150{
16151 rtx copy = gen_reg_rtx (DFmode);
16152 emit_move_insn (copy, operands[1]);
16153 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16154 DONE;
16155})
16156
16157(define_expand "atandf2"
16158 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16159 (unspec:DF [(match_dup 2)
16160 (match_operand:DF 1 "register_operand" "")]
16161 UNSPEC_FPATAN))
16162 (clobber (match_scratch:DF 3 ""))])]
16163 "TARGET_USE_FANCY_MATH_387
16164 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16165 && flag_unsafe_math_optimizations"
16166{
16167 operands[2] = gen_reg_rtx (DFmode);
16168 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16169})
16170
16171(define_insn "atan2sf3_1"
16172 [(set (match_operand:SF 0 "register_operand" "=f")
16173 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16174 (match_operand:SF 1 "register_operand" "u")]
16175 UNSPEC_FPATAN))
16176 (clobber (match_scratch:SF 3 "=1"))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16179 && flag_unsafe_math_optimizations"
16180 "fpatan"
16181 [(set_attr "type" "fpspc")
16182 (set_attr "mode" "SF")])
16183
16184(define_expand "atan2sf3"
16185 [(use (match_operand:SF 0 "register_operand" ""))
16186 (use (match_operand:SF 2 "register_operand" ""))
16187 (use (match_operand:SF 1 "register_operand" ""))]
16188 "TARGET_USE_FANCY_MATH_387
16189 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16190 && flag_unsafe_math_optimizations"
16191{
16192 rtx copy = gen_reg_rtx (SFmode);
16193 emit_move_insn (copy, operands[1]);
16194 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16195 DONE;
16196})
16197
16198(define_expand "atansf2"
16199 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16200 (unspec:SF [(match_dup 2)
16201 (match_operand:SF 1 "register_operand" "")]
16202 UNSPEC_FPATAN))
16203 (clobber (match_scratch:SF 3 ""))])]
16204 "TARGET_USE_FANCY_MATH_387
16205 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16206 && flag_unsafe_math_optimizations"
16207{
16208 operands[2] = gen_reg_rtx (SFmode);
16209 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16210})
16211
16212(define_insn "atan2xf3_1"
16213 [(set (match_operand:XF 0 "register_operand" "=f")
16214 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16215 (match_operand:XF 1 "register_operand" "u")]
16216 UNSPEC_FPATAN))
16217 (clobber (match_scratch:XF 3 "=1"))]
16218 "TARGET_USE_FANCY_MATH_387
16219 && flag_unsafe_math_optimizations"
16220 "fpatan"
16221 [(set_attr "type" "fpspc")
16222 (set_attr "mode" "XF")])
16223
16224(define_expand "atan2xf3"
16225 [(use (match_operand:XF 0 "register_operand" ""))
16226 (use (match_operand:XF 2 "register_operand" ""))
16227 (use (match_operand:XF 1 "register_operand" ""))]
16228 "TARGET_USE_FANCY_MATH_387
16229 && flag_unsafe_math_optimizations"
16230{
16231 rtx copy = gen_reg_rtx (XFmode);
16232 emit_move_insn (copy, operands[1]);
16233 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16234 DONE;
16235})
16236
16237(define_expand "atanxf2"
16238 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16239 (unspec:XF [(match_dup 2)
16240 (match_operand:XF 1 "register_operand" "")]
16241 UNSPEC_FPATAN))
16242 (clobber (match_scratch:XF 3 ""))])]
16243 "TARGET_USE_FANCY_MATH_387
16244 && flag_unsafe_math_optimizations"
16245{
16246 operands[2] = gen_reg_rtx (XFmode);
16247 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16248})
16249
16250(define_expand "asindf2"
16251 [(set (match_dup 2)
16252 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16253 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16254 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16255 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16256 (parallel [(set (match_dup 7)
16257 (unspec:XF [(match_dup 6) (match_dup 2)]
16258 UNSPEC_FPATAN))
16259 (clobber (match_scratch:XF 8 ""))])
16260 (set (match_operand:DF 0 "register_operand" "")
16261 (float_truncate:DF (match_dup 7)))]
16262 "TARGET_USE_FANCY_MATH_387
16263 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16264 && flag_unsafe_math_optimizations"
16265{
16266 int i;
16267
16268 for (i=2; i<8; i++)
16269 operands[i] = gen_reg_rtx (XFmode);
16270
16271 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16272})
16273
16274(define_expand "asinsf2"
16275 [(set (match_dup 2)
16276 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16277 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16278 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16279 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16280 (parallel [(set (match_dup 7)
16281 (unspec:XF [(match_dup 6) (match_dup 2)]
16282 UNSPEC_FPATAN))
16283 (clobber (match_scratch:XF 8 ""))])
16284 (set (match_operand:SF 0 "register_operand" "")
16285 (float_truncate:SF (match_dup 7)))]
16286 "TARGET_USE_FANCY_MATH_387
16287 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16288 && flag_unsafe_math_optimizations"
16289{
16290 int i;
16291
16292 for (i=2; i<8; i++)
16293 operands[i] = gen_reg_rtx (XFmode);
16294
16295 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16296})
16297
16298(define_expand "asinxf2"
16299 [(set (match_dup 2)
16300 (mult:XF (match_operand:XF 1 "register_operand" "")
16301 (match_dup 1)))
16302 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16303 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16304 (parallel [(set (match_operand:XF 0 "register_operand" "")
16305 (unspec:XF [(match_dup 5) (match_dup 1)]
16306 UNSPEC_FPATAN))
16307 (clobber (match_scratch:XF 6 ""))])]
16308 "TARGET_USE_FANCY_MATH_387
16309 && flag_unsafe_math_optimizations"
16310{
16311 int i;
16312
16313 for (i=2; i<6; i++)
16314 operands[i] = gen_reg_rtx (XFmode);
16315
16316 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16317})
16318
16319(define_expand "acosdf2"
16320 [(set (match_dup 2)
16321 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16322 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16323 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16324 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16325 (parallel [(set (match_dup 7)
16326 (unspec:XF [(match_dup 2) (match_dup 6)]
16327 UNSPEC_FPATAN))
16328 (clobber (match_scratch:XF 8 ""))])
16329 (set (match_operand:DF 0 "register_operand" "")
16330 (float_truncate:DF (match_dup 7)))]
16331 "TARGET_USE_FANCY_MATH_387
16332 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16333 && flag_unsafe_math_optimizations"
16334{
16335 int i;
16336
16337 for (i=2; i<8; i++)
16338 operands[i] = gen_reg_rtx (XFmode);
16339
16340 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16341})
16342
16343(define_expand "acossf2"
16344 [(set (match_dup 2)
16345 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16346 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16347 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16348 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16349 (parallel [(set (match_dup 7)
16350 (unspec:XF [(match_dup 2) (match_dup 6)]
16351 UNSPEC_FPATAN))
16352 (clobber (match_scratch:XF 8 ""))])
16353 (set (match_operand:SF 0 "register_operand" "")
16354 (float_truncate:SF (match_dup 7)))]
16355 "TARGET_USE_FANCY_MATH_387
16356 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16357 && flag_unsafe_math_optimizations"
16358{
16359 int i;
16360
16361 for (i=2; i<8; i++)
16362 operands[i] = gen_reg_rtx (XFmode);
16363
16364 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16365})
16366
16367(define_expand "acosxf2"
16368 [(set (match_dup 2)
16369 (mult:XF (match_operand:XF 1 "register_operand" "")
16370 (match_dup 1)))
16371 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16372 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16373 (parallel [(set (match_operand:XF 0 "register_operand" "")
16374 (unspec:XF [(match_dup 1) (match_dup 5)]
16375 UNSPEC_FPATAN))
16376 (clobber (match_scratch:XF 6 ""))])]
16377 "TARGET_USE_FANCY_MATH_387
16378 && flag_unsafe_math_optimizations"
16379{
16380 int i;
16381
16382 for (i=2; i<6; i++)
16383 operands[i] = gen_reg_rtx (XFmode);
16384
16385 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16386})
16387
16388(define_insn "fyl2x_xf3"
16389 [(set (match_operand:XF 0 "register_operand" "=f")
16390 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16391 (match_operand:XF 1 "register_operand" "u")]
16392 UNSPEC_FYL2X))
16393 (clobber (match_scratch:XF 3 "=1"))]
16394 "TARGET_USE_FANCY_MATH_387
16395 && flag_unsafe_math_optimizations"
16396 "fyl2x"
16397 [(set_attr "type" "fpspc")
16398 (set_attr "mode" "XF")])
16399
16400(define_expand "logsf2"
16401 [(set (match_dup 2)
16402 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16403 (parallel [(set (match_dup 4)
16404 (unspec:XF [(match_dup 2)
16405 (match_dup 3)] UNSPEC_FYL2X))
16406 (clobber (match_scratch:XF 5 ""))])
16407 (set (match_operand:SF 0 "register_operand" "")
16408 (float_truncate:SF (match_dup 4)))]
16409 "TARGET_USE_FANCY_MATH_387
16410 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16411 && flag_unsafe_math_optimizations"
16412{
16413 rtx temp;
16414
16415 operands[2] = gen_reg_rtx (XFmode);
16416 operands[3] = gen_reg_rtx (XFmode);
16417 operands[4] = gen_reg_rtx (XFmode);
16418
16419 temp = standard_80387_constant_rtx (4); /* fldln2 */
16420 emit_move_insn (operands[3], temp);
16421})
16422
16423(define_expand "logdf2"
16424 [(set (match_dup 2)
16425 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16426 (parallel [(set (match_dup 4)
16427 (unspec:XF [(match_dup 2)
16428 (match_dup 3)] UNSPEC_FYL2X))
16429 (clobber (match_scratch:XF 5 ""))])
16430 (set (match_operand:DF 0 "register_operand" "")
16431 (float_truncate:DF (match_dup 4)))]
16432 "TARGET_USE_FANCY_MATH_387
16433 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16434 && flag_unsafe_math_optimizations"
16435{
16436 rtx temp;
16437
16438 operands[2] = gen_reg_rtx (XFmode);
16439 operands[3] = gen_reg_rtx (XFmode);
16440 operands[4] = gen_reg_rtx (XFmode);
16441
16442 temp = standard_80387_constant_rtx (4); /* fldln2 */
16443 emit_move_insn (operands[3], temp);
16444})
16445
16446(define_expand "logxf2"
16447 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16448 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16449 (match_dup 2)] UNSPEC_FYL2X))
16450 (clobber (match_scratch:XF 3 ""))])]
16451 "TARGET_USE_FANCY_MATH_387
16452 && flag_unsafe_math_optimizations"
16453{
16454 rtx temp;
16455
16456 operands[2] = gen_reg_rtx (XFmode);
16457 temp = standard_80387_constant_rtx (4); /* fldln2 */
16458 emit_move_insn (operands[2], temp);
16459})
16460
16461(define_expand "log10sf2"
16462 [(set (match_dup 2)
16463 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16464 (parallel [(set (match_dup 4)
16465 (unspec:XF [(match_dup 2)
16466 (match_dup 3)] UNSPEC_FYL2X))
16467 (clobber (match_scratch:XF 5 ""))])
16468 (set (match_operand:SF 0 "register_operand" "")
16469 (float_truncate:SF (match_dup 4)))]
16470 "TARGET_USE_FANCY_MATH_387
16471 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16472 && flag_unsafe_math_optimizations"
16473{
16474 rtx temp;
16475
16476 operands[2] = gen_reg_rtx (XFmode);
16477 operands[3] = gen_reg_rtx (XFmode);
16478 operands[4] = gen_reg_rtx (XFmode);
16479
16480 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16481 emit_move_insn (operands[3], temp);
16482})
16483
16484(define_expand "log10df2"
16485 [(set (match_dup 2)
16486 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16487 (parallel [(set (match_dup 4)
16488 (unspec:XF [(match_dup 2)
16489 (match_dup 3)] UNSPEC_FYL2X))
16490 (clobber (match_scratch:XF 5 ""))])
16491 (set (match_operand:DF 0 "register_operand" "")
16492 (float_truncate:DF (match_dup 4)))]
16493 "TARGET_USE_FANCY_MATH_387
16494 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16495 && flag_unsafe_math_optimizations"
16496{
16497 rtx temp;
16498
16499 operands[2] = gen_reg_rtx (XFmode);
16500 operands[3] = gen_reg_rtx (XFmode);
16501 operands[4] = gen_reg_rtx (XFmode);
16502
16503 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16504 emit_move_insn (operands[3], temp);
16505})
16506
16507(define_expand "log10xf2"
16508 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16509 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16510 (match_dup 2)] UNSPEC_FYL2X))
16511 (clobber (match_scratch:XF 3 ""))])]
16512 "TARGET_USE_FANCY_MATH_387
16513 && flag_unsafe_math_optimizations"
16514{
16515 rtx temp;
16516
16517 operands[2] = gen_reg_rtx (XFmode);
16518 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16519 emit_move_insn (operands[2], temp);
16520})
16521
16522(define_expand "log2sf2"
16523 [(set (match_dup 2)
16524 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16525 (parallel [(set (match_dup 4)
16526 (unspec:XF [(match_dup 2)
16527 (match_dup 3)] UNSPEC_FYL2X))
16528 (clobber (match_scratch:XF 5 ""))])
16529 (set (match_operand:SF 0 "register_operand" "")
16530 (float_truncate:SF (match_dup 4)))]
16531 "TARGET_USE_FANCY_MATH_387
16532 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16533 && flag_unsafe_math_optimizations"
16534{
16535 operands[2] = gen_reg_rtx (XFmode);
16536 operands[3] = gen_reg_rtx (XFmode);
16537 operands[4] = gen_reg_rtx (XFmode);
16538
16539 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16540})
16541
16542(define_expand "log2df2"
16543 [(set (match_dup 2)
16544 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16545 (parallel [(set (match_dup 4)
16546 (unspec:XF [(match_dup 2)
16547 (match_dup 3)] UNSPEC_FYL2X))
16548 (clobber (match_scratch:XF 5 ""))])
16549 (set (match_operand:DF 0 "register_operand" "")
16550 (float_truncate:DF (match_dup 4)))]
16551 "TARGET_USE_FANCY_MATH_387
16552 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16553 && flag_unsafe_math_optimizations"
16554{
16555 operands[2] = gen_reg_rtx (XFmode);
16556 operands[3] = gen_reg_rtx (XFmode);
16557 operands[4] = gen_reg_rtx (XFmode);
16558
16559 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16560})
16561
16562(define_expand "log2xf2"
16563 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16564 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16565 (match_dup 2)] UNSPEC_FYL2X))
16566 (clobber (match_scratch:XF 3 ""))])]
16567 "TARGET_USE_FANCY_MATH_387
16568 && flag_unsafe_math_optimizations"
16569{
16570 operands[2] = gen_reg_rtx (XFmode);
16571 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16572})
16573
16574(define_insn "fyl2xp1_xf3"
16575 [(set (match_operand:XF 0 "register_operand" "=f")
16576 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16577 (match_operand:XF 1 "register_operand" "u")]
16578 UNSPEC_FYL2XP1))
16579 (clobber (match_scratch:XF 3 "=1"))]
16580 "TARGET_USE_FANCY_MATH_387
16581 && flag_unsafe_math_optimizations"
16582 "fyl2xp1"
16583 [(set_attr "type" "fpspc")
16584 (set_attr "mode" "XF")])
16585
16586(define_expand "log1psf2"
16587 [(use (match_operand:SF 0 "register_operand" ""))
16588 (use (match_operand:SF 1 "register_operand" ""))]
16589 "TARGET_USE_FANCY_MATH_387
16590 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16591 && flag_unsafe_math_optimizations"
16592{
16593 rtx op0 = gen_reg_rtx (XFmode);
16594 rtx op1 = gen_reg_rtx (XFmode);
16595
16596 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16597 ix86_emit_i387_log1p (op0, op1);
16598 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16599 DONE;
16600})
16601
16602(define_expand "log1pdf2"
16603 [(use (match_operand:DF 0 "register_operand" ""))
16604 (use (match_operand:DF 1 "register_operand" ""))]
16605 "TARGET_USE_FANCY_MATH_387
16606 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16607 && flag_unsafe_math_optimizations"
16608{
16609 rtx op0 = gen_reg_rtx (XFmode);
16610 rtx op1 = gen_reg_rtx (XFmode);
16611
16612 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16613 ix86_emit_i387_log1p (op0, op1);
16614 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16615 DONE;
16616})
16617
16618(define_expand "log1pxf2"
16619 [(use (match_operand:XF 0 "register_operand" ""))
16620 (use (match_operand:XF 1 "register_operand" ""))]
16621 "TARGET_USE_FANCY_MATH_387
16622 && flag_unsafe_math_optimizations"
16623{
16624 ix86_emit_i387_log1p (operands[0], operands[1]);
16625 DONE;
16626})
16627
16628(define_insn "*fxtractxf3"
16629 [(set (match_operand:XF 0 "register_operand" "=f")
16630 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16631 UNSPEC_XTRACT_FRACT))
16632 (set (match_operand:XF 1 "register_operand" "=u")
16633 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16634 "TARGET_USE_FANCY_MATH_387
16635 && flag_unsafe_math_optimizations"
16636 "fxtract"
16637 [(set_attr "type" "fpspc")
16638 (set_attr "mode" "XF")])
16639
16640(define_expand "logbsf2"
16641 [(set (match_dup 2)
16642 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16643 (parallel [(set (match_dup 3)
16644 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16645 (set (match_dup 4)
16646 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16647 (set (match_operand:SF 0 "register_operand" "")
16648 (float_truncate:SF (match_dup 4)))]
16649 "TARGET_USE_FANCY_MATH_387
16650 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16651 && flag_unsafe_math_optimizations"
16652{
16653 operands[2] = gen_reg_rtx (XFmode);
16654 operands[3] = gen_reg_rtx (XFmode);
16655 operands[4] = gen_reg_rtx (XFmode);
16656})
16657
16658(define_expand "logbdf2"
16659 [(set (match_dup 2)
16660 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16661 (parallel [(set (match_dup 3)
16662 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16663 (set (match_dup 4)
16664 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16665 (set (match_operand:DF 0 "register_operand" "")
16666 (float_truncate:DF (match_dup 4)))]
16667 "TARGET_USE_FANCY_MATH_387
16668 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16669 && flag_unsafe_math_optimizations"
16670{
16671 operands[2] = gen_reg_rtx (XFmode);
16672 operands[3] = gen_reg_rtx (XFmode);
16673 operands[4] = gen_reg_rtx (XFmode);
16674})
16675
16676(define_expand "logbxf2"
16677 [(parallel [(set (match_dup 2)
16678 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16679 UNSPEC_XTRACT_FRACT))
16680 (set (match_operand:XF 0 "register_operand" "")
16681 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16682 "TARGET_USE_FANCY_MATH_387
16683 && flag_unsafe_math_optimizations"
16684{
16685 operands[2] = gen_reg_rtx (XFmode);
16686})
16687
16688(define_expand "ilogbsi2"
16689 [(parallel [(set (match_dup 2)
16690 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16691 UNSPEC_XTRACT_FRACT))
16692 (set (match_operand:XF 3 "register_operand" "")
16693 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16694 (parallel [(set (match_operand:SI 0 "register_operand" "")
16695 (fix:SI (match_dup 3)))
16696 (clobber (reg:CC FLAGS_REG))])]
16697 "TARGET_USE_FANCY_MATH_387
16698 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16699 && flag_unsafe_math_optimizations"
16700{
16701 operands[2] = gen_reg_rtx (XFmode);
16702 operands[3] = gen_reg_rtx (XFmode);
16703})
16704
16705(define_insn "*f2xm1xf2"
16706 [(set (match_operand:XF 0 "register_operand" "=f")
16707 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16708 UNSPEC_F2XM1))]
16709 "TARGET_USE_FANCY_MATH_387
16710 && flag_unsafe_math_optimizations"
16711 "f2xm1"
16712 [(set_attr "type" "fpspc")
16713 (set_attr "mode" "XF")])
16714
16715(define_insn "*fscalexf4"
16716 [(set (match_operand:XF 0 "register_operand" "=f")
16717 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16718 (match_operand:XF 3 "register_operand" "1")]
16719 UNSPEC_FSCALE_FRACT))
16720 (set (match_operand:XF 1 "register_operand" "=u")
16721 (unspec:XF [(match_dup 2) (match_dup 3)]
16722 UNSPEC_FSCALE_EXP))]
16723 "TARGET_USE_FANCY_MATH_387
16724 && flag_unsafe_math_optimizations"
16725 "fscale"
16726 [(set_attr "type" "fpspc")
16727 (set_attr "mode" "XF")])
16728
16729(define_expand "expsf2"
16730 [(set (match_dup 2)
16731 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16732 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16733 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16734 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16735 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16736 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16737 (parallel [(set (match_dup 10)
16738 (unspec:XF [(match_dup 9) (match_dup 5)]
16739 UNSPEC_FSCALE_FRACT))
16740 (set (match_dup 11)
16741 (unspec:XF [(match_dup 9) (match_dup 5)]
16742 UNSPEC_FSCALE_EXP))])
16743 (set (match_operand:SF 0 "register_operand" "")
16744 (float_truncate:SF (match_dup 10)))]
16745 "TARGET_USE_FANCY_MATH_387
16746 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16747 && flag_unsafe_math_optimizations"
16748{
16749 rtx temp;
16750 int i;
16751
16752 for (i=2; i<12; i++)
16753 operands[i] = gen_reg_rtx (XFmode);
16754 temp = standard_80387_constant_rtx (5); /* fldl2e */
16755 emit_move_insn (operands[3], temp);
16756 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16757})
16758
16759(define_expand "expdf2"
16760 [(set (match_dup 2)
16761 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16762 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16763 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16764 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16765 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16766 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16767 (parallel [(set (match_dup 10)
16768 (unspec:XF [(match_dup 9) (match_dup 5)]
16769 UNSPEC_FSCALE_FRACT))
16770 (set (match_dup 11)
16771 (unspec:XF [(match_dup 9) (match_dup 5)]
16772 UNSPEC_FSCALE_EXP))])
16773 (set (match_operand:DF 0 "register_operand" "")
16774 (float_truncate:DF (match_dup 10)))]
16775 "TARGET_USE_FANCY_MATH_387
16776 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16777 && flag_unsafe_math_optimizations"
16778{
16779 rtx temp;
16780 int i;
16781
16782 for (i=2; i<12; i++)
16783 operands[i] = gen_reg_rtx (XFmode);
16784 temp = standard_80387_constant_rtx (5); /* fldl2e */
16785 emit_move_insn (operands[3], temp);
16786 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16787})
16788
16789(define_expand "expxf2"
16790 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16791 (match_dup 2)))
16792 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16793 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16794 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16795 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16796 (parallel [(set (match_operand:XF 0 "register_operand" "")
16797 (unspec:XF [(match_dup 8) (match_dup 4)]
16798 UNSPEC_FSCALE_FRACT))
16799 (set (match_dup 9)
16800 (unspec:XF [(match_dup 8) (match_dup 4)]
16801 UNSPEC_FSCALE_EXP))])]
16802 "TARGET_USE_FANCY_MATH_387
16803 && flag_unsafe_math_optimizations"
16804{
16805 rtx temp;
16806 int i;
16807
16808 for (i=2; i<10; i++)
16809 operands[i] = gen_reg_rtx (XFmode);
16810 temp = standard_80387_constant_rtx (5); /* fldl2e */
16811 emit_move_insn (operands[2], temp);
16812 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16813})
16814
16815(define_expand "exp10sf2"
16816 [(set (match_dup 2)
16817 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16818 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16819 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16820 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16821 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16822 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16823 (parallel [(set (match_dup 10)
16824 (unspec:XF [(match_dup 9) (match_dup 5)]
16825 UNSPEC_FSCALE_FRACT))
16826 (set (match_dup 11)
16827 (unspec:XF [(match_dup 9) (match_dup 5)]
16828 UNSPEC_FSCALE_EXP))])
16829 (set (match_operand:SF 0 "register_operand" "")
16830 (float_truncate:SF (match_dup 10)))]
16831 "TARGET_USE_FANCY_MATH_387
16832 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16833 && flag_unsafe_math_optimizations"
16834{
16835 rtx temp;
16836 int i;
16837
16838 for (i=2; i<12; i++)
16839 operands[i] = gen_reg_rtx (XFmode);
16840 temp = standard_80387_constant_rtx (6); /* fldl2t */
16841 emit_move_insn (operands[3], temp);
16842 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16843})
16844
16845(define_expand "exp10df2"
16846 [(set (match_dup 2)
16847 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16848 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16849 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16850 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16851 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16852 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16853 (parallel [(set (match_dup 10)
16854 (unspec:XF [(match_dup 9) (match_dup 5)]
16855 UNSPEC_FSCALE_FRACT))
16856 (set (match_dup 11)
16857 (unspec:XF [(match_dup 9) (match_dup 5)]
16858 UNSPEC_FSCALE_EXP))])
16859 (set (match_operand:DF 0 "register_operand" "")
16860 (float_truncate:DF (match_dup 10)))]
16861 "TARGET_USE_FANCY_MATH_387
16862 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16863 && flag_unsafe_math_optimizations"
16864{
16865 rtx temp;
16866 int i;
16867
16868 for (i=2; i<12; i++)
16869 operands[i] = gen_reg_rtx (XFmode);
16870 temp = standard_80387_constant_rtx (6); /* fldl2t */
16871 emit_move_insn (operands[3], temp);
16872 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16873})
16874
16875(define_expand "exp10xf2"
16876 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16877 (match_dup 2)))
16878 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16879 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16880 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16881 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16882 (parallel [(set (match_operand:XF 0 "register_operand" "")
16883 (unspec:XF [(match_dup 8) (match_dup 4)]
16884 UNSPEC_FSCALE_FRACT))
16885 (set (match_dup 9)
16886 (unspec:XF [(match_dup 8) (match_dup 4)]
16887 UNSPEC_FSCALE_EXP))])]
16888 "TARGET_USE_FANCY_MATH_387
16889 && flag_unsafe_math_optimizations"
16890{
16891 rtx temp;
16892 int i;
16893
16894 for (i=2; i<10; i++)
16895 operands[i] = gen_reg_rtx (XFmode);
16896 temp = standard_80387_constant_rtx (6); /* fldl2t */
16897 emit_move_insn (operands[2], temp);
16898 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16899})
16900
16901(define_expand "exp2sf2"
16902 [(set (match_dup 2)
16903 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16904 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16905 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16906 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16907 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16908 (parallel [(set (match_dup 8)
16909 (unspec:XF [(match_dup 7) (match_dup 3)]
16910 UNSPEC_FSCALE_FRACT))
16911 (set (match_dup 9)
16912 (unspec:XF [(match_dup 7) (match_dup 3)]
16913 UNSPEC_FSCALE_EXP))])
16914 (set (match_operand:SF 0 "register_operand" "")
16915 (float_truncate:SF (match_dup 8)))]
16916 "TARGET_USE_FANCY_MATH_387
16917 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16918 && flag_unsafe_math_optimizations"
16919{
16920 int i;
16921
16922 for (i=2; i<10; i++)
16923 operands[i] = gen_reg_rtx (XFmode);
16924 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16925})
16926
16927(define_expand "exp2df2"
16928 [(set (match_dup 2)
16929 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16930 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16931 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16932 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16933 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16934 (parallel [(set (match_dup 8)
16935 (unspec:XF [(match_dup 7) (match_dup 3)]
16936 UNSPEC_FSCALE_FRACT))
16937 (set (match_dup 9)
16938 (unspec:XF [(match_dup 7) (match_dup 3)]
16939 UNSPEC_FSCALE_EXP))])
16940 (set (match_operand:DF 0 "register_operand" "")
16941 (float_truncate:DF (match_dup 8)))]
16942 "TARGET_USE_FANCY_MATH_387
16943 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16944 && flag_unsafe_math_optimizations"
16945{
16946 int i;
16947
16948 for (i=2; i<10; i++)
16949 operands[i] = gen_reg_rtx (XFmode);
16950 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16951})
16952
16953(define_expand "exp2xf2"
16954 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16955 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16956 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16957 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16958 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16959 (parallel [(set (match_operand:XF 0 "register_operand" "")
16960 (unspec:XF [(match_dup 7) (match_dup 3)]
16961 UNSPEC_FSCALE_FRACT))
16962 (set (match_dup 8)
16963 (unspec:XF [(match_dup 7) (match_dup 3)]
16964 UNSPEC_FSCALE_EXP))])]
16965 "TARGET_USE_FANCY_MATH_387
16966 && flag_unsafe_math_optimizations"
16967{
16968 int i;
16969
16970 for (i=2; i<9; i++)
16971 operands[i] = gen_reg_rtx (XFmode);
16972 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16973})
16974
16975(define_expand "expm1df2"
16976 [(set (match_dup 2)
16977 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16978 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16979 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16980 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16981 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16982 (parallel [(set (match_dup 8)
16983 (unspec:XF [(match_dup 7) (match_dup 5)]
16984 UNSPEC_FSCALE_FRACT))
16985 (set (match_dup 9)
16986 (unspec:XF [(match_dup 7) (match_dup 5)]
16987 UNSPEC_FSCALE_EXP))])
16988 (parallel [(set (match_dup 11)
16989 (unspec:XF [(match_dup 10) (match_dup 9)]
16990 UNSPEC_FSCALE_FRACT))
16991 (set (match_dup 12)
16992 (unspec:XF [(match_dup 10) (match_dup 9)]
16993 UNSPEC_FSCALE_EXP))])
16994 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16995 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16996 (set (match_operand:DF 0 "register_operand" "")
16997 (float_truncate:DF (match_dup 14)))]
16998 "TARGET_USE_FANCY_MATH_387
16999 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17000 && flag_unsafe_math_optimizations"
17001{
17002 rtx temp;
17003 int i;
17004
17005 for (i=2; i<15; i++)
17006 operands[i] = gen_reg_rtx (XFmode);
17007 temp = standard_80387_constant_rtx (5); /* fldl2e */
17008 emit_move_insn (operands[3], temp);
17009 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17010})
17011
17012(define_expand "expm1sf2"
17013 [(set (match_dup 2)
17014 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17015 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17016 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17017 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17018 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17019 (parallel [(set (match_dup 8)
17020 (unspec:XF [(match_dup 7) (match_dup 5)]
17021 UNSPEC_FSCALE_FRACT))
17022 (set (match_dup 9)
17023 (unspec:XF [(match_dup 7) (match_dup 5)]
17024 UNSPEC_FSCALE_EXP))])
17025 (parallel [(set (match_dup 11)
17026 (unspec:XF [(match_dup 10) (match_dup 9)]
17027 UNSPEC_FSCALE_FRACT))
17028 (set (match_dup 12)
17029 (unspec:XF [(match_dup 10) (match_dup 9)]
17030 UNSPEC_FSCALE_EXP))])
17031 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17032 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17033 (set (match_operand:SF 0 "register_operand" "")
17034 (float_truncate:SF (match_dup 14)))]
17035 "TARGET_USE_FANCY_MATH_387
17036 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17037 && flag_unsafe_math_optimizations"
17038{
17039 rtx temp;
17040 int i;
17041
17042 for (i=2; i<15; i++)
17043 operands[i] = gen_reg_rtx (XFmode);
17044 temp = standard_80387_constant_rtx (5); /* fldl2e */
17045 emit_move_insn (operands[3], temp);
17046 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17047})
17048
17049(define_expand "expm1xf2"
17050 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17051 (match_dup 2)))
17052 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17053 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17054 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17055 (parallel [(set (match_dup 7)
17056 (unspec:XF [(match_dup 6) (match_dup 4)]
17057 UNSPEC_FSCALE_FRACT))
17058 (set (match_dup 8)
17059 (unspec:XF [(match_dup 6) (match_dup 4)]
17060 UNSPEC_FSCALE_EXP))])
17061 (parallel [(set (match_dup 10)
17062 (unspec:XF [(match_dup 9) (match_dup 8)]
17063 UNSPEC_FSCALE_FRACT))
17064 (set (match_dup 11)
17065 (unspec:XF [(match_dup 9) (match_dup 8)]
17066 UNSPEC_FSCALE_EXP))])
17067 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17068 (set (match_operand:XF 0 "register_operand" "")
17069 (plus:XF (match_dup 12) (match_dup 7)))]
17070 "TARGET_USE_FANCY_MATH_387
17071 && flag_unsafe_math_optimizations"
17072{
17073 rtx temp;
17074 int i;
17075
17076 for (i=2; i<13; i++)
17077 operands[i] = gen_reg_rtx (XFmode);
17078 temp = standard_80387_constant_rtx (5); /* fldl2e */
17079 emit_move_insn (operands[2], temp);
17080 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17081})
17082
17083(define_expand "ldexpdf3"
17084 [(set (match_dup 3)
17085 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17086 (set (match_dup 4)
17087 (float:XF (match_operand:SI 2 "register_operand" "")))
17088 (parallel [(set (match_dup 5)
17089 (unspec:XF [(match_dup 3) (match_dup 4)]
17090 UNSPEC_FSCALE_FRACT))
17091 (set (match_dup 6)
17092 (unspec:XF [(match_dup 3) (match_dup 4)]
17093 UNSPEC_FSCALE_EXP))])
17094 (set (match_operand:DF 0 "register_operand" "")
17095 (float_truncate:DF (match_dup 5)))]
17096 "TARGET_USE_FANCY_MATH_387
17097 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17098 && flag_unsafe_math_optimizations"
17099{
17100 int i;
17101
17102 for (i=3; i<7; i++)
17103 operands[i] = gen_reg_rtx (XFmode);
17104})
17105
17106(define_expand "ldexpsf3"
17107 [(set (match_dup 3)
17108 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17109 (set (match_dup 4)
17110 (float:XF (match_operand:SI 2 "register_operand" "")))
17111 (parallel [(set (match_dup 5)
17112 (unspec:XF [(match_dup 3) (match_dup 4)]
17113 UNSPEC_FSCALE_FRACT))
17114 (set (match_dup 6)
17115 (unspec:XF [(match_dup 3) (match_dup 4)]
17116 UNSPEC_FSCALE_EXP))])
17117 (set (match_operand:SF 0 "register_operand" "")
17118 (float_truncate:SF (match_dup 5)))]
17119 "TARGET_USE_FANCY_MATH_387
17120 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17121 && flag_unsafe_math_optimizations"
17122{
17123 int i;
17124
17125 for (i=3; i<7; i++)
17126 operands[i] = gen_reg_rtx (XFmode);
17127})
17128
17129(define_expand "ldexpxf3"
17130 [(set (match_dup 3)
17131 (float:XF (match_operand:SI 2 "register_operand" "")))
17132 (parallel [(set (match_operand:XF 0 " register_operand" "")
17133 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17134 (match_dup 3)]
17135 UNSPEC_FSCALE_FRACT))
17136 (set (match_dup 4)
17137 (unspec:XF [(match_dup 1) (match_dup 3)]
17138 UNSPEC_FSCALE_EXP))])]
17139 "TARGET_USE_FANCY_MATH_387
17140 && flag_unsafe_math_optimizations"
17141{
17142 int i;
17143
17144 for (i=3; i<5; i++)
17145 operands[i] = gen_reg_rtx (XFmode);
17146})
17147
17148
17149(define_insn "frndintxf2"
17150 [(set (match_operand:XF 0 "register_operand" "=f")
17151 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17152 UNSPEC_FRNDINT))]
17153 "TARGET_USE_FANCY_MATH_387
17154 && flag_unsafe_math_optimizations"
17155 "frndint"
17156 [(set_attr "type" "fpspc")
17157 (set_attr "mode" "XF")])
17158
17159(define_expand "rintdf2"
17160 [(use (match_operand:DF 0 "register_operand" ""))
17161 (use (match_operand:DF 1 "register_operand" ""))]
17162 "TARGET_USE_FANCY_MATH_387
17163 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17164 && flag_unsafe_math_optimizations"
17165{
17166 rtx op0 = gen_reg_rtx (XFmode);
17167 rtx op1 = gen_reg_rtx (XFmode);
17168
17169 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17170 emit_insn (gen_frndintxf2 (op0, op1));
17171
17172 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17173 DONE;
17174})
17175
17176(define_expand "rintsf2"
17177 [(use (match_operand:SF 0 "register_operand" ""))
17178 (use (match_operand:SF 1 "register_operand" ""))]
17179 "TARGET_USE_FANCY_MATH_387
17180 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17181 && flag_unsafe_math_optimizations"
17182{
17183 rtx op0 = gen_reg_rtx (XFmode);
17184 rtx op1 = gen_reg_rtx (XFmode);
17185
17186 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17187 emit_insn (gen_frndintxf2 (op0, op1));
17188
17189 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17190 DONE;
17191})
17192
17193(define_expand "rintxf2"
17194 [(use (match_operand:XF 0 "register_operand" ""))
17195 (use (match_operand:XF 1 "register_operand" ""))]
17196 "TARGET_USE_FANCY_MATH_387
17197 && flag_unsafe_math_optimizations"
17198{
17199 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17200 DONE;
17201})
17202
17203(define_insn_and_split "*fistdi2_1"
17204 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17205 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17206 UNSPEC_FIST))]
17207 "TARGET_USE_FANCY_MATH_387
17208 && flag_unsafe_math_optimizations
17209 && !(reload_completed || reload_in_progress)"
17210 "#"
17211 "&& 1"
17212 [(const_int 0)]
17213{
17214 if (memory_operand (operands[0], VOIDmode))
17215 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17216 else
17217 {
17218 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17219 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17220 operands[2]));
17221 }
17222 DONE;
17223}
17224 [(set_attr "type" "fpspc")
17225 (set_attr "mode" "DI")])
17226
17227(define_insn "fistdi2"
17228 [(set (match_operand:DI 0 "memory_operand" "=m")
17229 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17230 UNSPEC_FIST))
17231 (clobber (match_scratch:XF 2 "=&1f"))]
17232 "TARGET_USE_FANCY_MATH_387
17233 && flag_unsafe_math_optimizations"
17234 "* return output_fix_trunc (insn, operands, 0);"
17235 [(set_attr "type" "fpspc")
17236 (set_attr "mode" "DI")])
17237
17238(define_insn "fistdi2_with_temp"
17239 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17240 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17241 UNSPEC_FIST))
17242 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17243 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17244 "TARGET_USE_FANCY_MATH_387
17245 && flag_unsafe_math_optimizations"
17246 "#"
17247 [(set_attr "type" "fpspc")
17248 (set_attr "mode" "DI")])
17249
17250(define_split
17251 [(set (match_operand:DI 0 "register_operand" "")
17252 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17253 UNSPEC_FIST))
17254 (clobber (match_operand:DI 2 "memory_operand" ""))
17255 (clobber (match_scratch 3 ""))]
17256 "reload_completed"
17257 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17258 (clobber (match_dup 3))])
17259 (set (match_dup 0) (match_dup 2))]
17260 "")
17261
17262(define_split
17263 [(set (match_operand:DI 0 "memory_operand" "")
17264 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17265 UNSPEC_FIST))
17266 (clobber (match_operand:DI 2 "memory_operand" ""))
17267 (clobber (match_scratch 3 ""))]
17268 "reload_completed"
17269 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17270 (clobber (match_dup 3))])]
17271 "")
17272
17273(define_insn_and_split "*fist<mode>2_1"
17274 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17275 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17276 UNSPEC_FIST))]
17277 "TARGET_USE_FANCY_MATH_387
17278 && flag_unsafe_math_optimizations
17279 && !(reload_completed || reload_in_progress)"
17280 "#"
17281 "&& 1"
17282 [(const_int 0)]
17283{
17284 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17285 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17286 operands[2]));
17287 DONE;
17288}
17289 [(set_attr "type" "fpspc")
17290 (set_attr "mode" "<MODE>")])
17291
17292(define_insn "fist<mode>2"
17293 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17294 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17295 UNSPEC_FIST))]
17296 "TARGET_USE_FANCY_MATH_387
17297 && flag_unsafe_math_optimizations"
17298 "* return output_fix_trunc (insn, operands, 0);"
17299 [(set_attr "type" "fpspc")
17300 (set_attr "mode" "<MODE>")])
17301
17302(define_insn "fist<mode>2_with_temp"
17303 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17304 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17305 UNSPEC_FIST))
17306 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17307 "TARGET_USE_FANCY_MATH_387
17308 && flag_unsafe_math_optimizations"
17309 "#"
17310 [(set_attr "type" "fpspc")
17311 (set_attr "mode" "<MODE>")])
17312
17313(define_split
17314 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17315 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17316 UNSPEC_FIST))
17317 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17318 "reload_completed"
17319 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17320 UNSPEC_FIST))
17321 (set (match_dup 0) (match_dup 2))]
17322 "")
17323
17324(define_split
17325 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17326 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17327 UNSPEC_FIST))
17328 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17329 "reload_completed"
17330 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17331 UNSPEC_FIST))]
17332 "")
17333
17334(define_expand "lrint<mode>2"
17335 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17336 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17337 UNSPEC_FIST))]
17338 "TARGET_USE_FANCY_MATH_387
17339 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17340 && flag_unsafe_math_optimizations"
17341 "")
17342
17343;; Rounding mode control word calculation could clobber FLAGS_REG.
17344(define_insn_and_split "frndintxf2_floor"
17345 [(set (match_operand:XF 0 "register_operand" "=f")
17346 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17347 UNSPEC_FRNDINT_FLOOR))
17348 (clobber (reg:CC FLAGS_REG))]
17349 "TARGET_USE_FANCY_MATH_387
17350 && flag_unsafe_math_optimizations
17351 && !(reload_completed || reload_in_progress)"
17352 "#"
17353 "&& 1"
17354 [(const_int 0)]
17355{
17356 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17357
17358 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17359 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17360
17361 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17362 operands[2], operands[3]));
17363 DONE;
17364}
17365 [(set_attr "type" "frndint")
17366 (set_attr "i387_cw" "floor")
17367 (set_attr "mode" "XF")])
17368
17369(define_insn "frndintxf2_floor_i387"
17370 [(set (match_operand:XF 0 "register_operand" "=f")
17371 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17372 UNSPEC_FRNDINT_FLOOR))
17373 (use (match_operand:HI 2 "memory_operand" "m"))
17374 (use (match_operand:HI 3 "memory_operand" "m"))]
17375 "TARGET_USE_FANCY_MATH_387
17376 && flag_unsafe_math_optimizations"
17377 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17378 [(set_attr "type" "frndint")
17379 (set_attr "i387_cw" "floor")
17380 (set_attr "mode" "XF")])
17381
17382(define_expand "floorxf2"
17383 [(use (match_operand:XF 0 "register_operand" ""))
17384 (use (match_operand:XF 1 "register_operand" ""))]
17385 "TARGET_USE_FANCY_MATH_387
17386 && flag_unsafe_math_optimizations"
17387{
17388 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17389 DONE;
17390})
17391
17392(define_expand "floordf2"
17393 [(use (match_operand:DF 0 "register_operand" ""))
17394 (use (match_operand:DF 1 "register_operand" ""))]
17395 "TARGET_USE_FANCY_MATH_387
17396 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17397 && flag_unsafe_math_optimizations"
17398{
17399 rtx op0 = gen_reg_rtx (XFmode);
17400 rtx op1 = gen_reg_rtx (XFmode);
17401
17402 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17403 emit_insn (gen_frndintxf2_floor (op0, op1));
17404
17405 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17406 DONE;
17407})
17408
17409(define_expand "floorsf2"
17410 [(use (match_operand:SF 0 "register_operand" ""))
17411 (use (match_operand:SF 1 "register_operand" ""))]
17412 "TARGET_USE_FANCY_MATH_387
17413 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17414 && flag_unsafe_math_optimizations"
17415{
17416 rtx op0 = gen_reg_rtx (XFmode);
17417 rtx op1 = gen_reg_rtx (XFmode);
17418
17419 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17420 emit_insn (gen_frndintxf2_floor (op0, op1));
17421
17422 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17423 DONE;
17424})
17425
17426(define_insn_and_split "*fist<mode>2_floor_1"
17427 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17428 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17429 UNSPEC_FIST_FLOOR))
17430 (clobber (reg:CC FLAGS_REG))]
17431 "TARGET_USE_FANCY_MATH_387
17432 && flag_unsafe_math_optimizations
17433 && !(reload_completed || reload_in_progress)"
17434 "#"
17435 "&& 1"
17436 [(const_int 0)]
17437{
17438 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17439
17440 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17441 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17442 if (memory_operand (operands[0], VOIDmode))
17443 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17444 operands[2], operands[3]));
17445 else
17446 {
17447 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17448 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17449 operands[2], operands[3],
17450 operands[4]));
17451 }
17452 DONE;
17453}
17454 [(set_attr "type" "fistp")
17455 (set_attr "i387_cw" "floor")
17456 (set_attr "mode" "<MODE>")])
17457
17458(define_insn "fistdi2_floor"
17459 [(set (match_operand:DI 0 "memory_operand" "=m")
17460 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17461 UNSPEC_FIST_FLOOR))
17462 (use (match_operand:HI 2 "memory_operand" "m"))
17463 (use (match_operand:HI 3 "memory_operand" "m"))
17464 (clobber (match_scratch:XF 4 "=&1f"))]
17465 "TARGET_USE_FANCY_MATH_387
17466 && flag_unsafe_math_optimizations"
17467 "* return output_fix_trunc (insn, operands, 0);"
17468 [(set_attr "type" "fistp")
17469 (set_attr "i387_cw" "floor")
17470 (set_attr "mode" "DI")])
17471
17472(define_insn "fistdi2_floor_with_temp"
17473 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17474 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17475 UNSPEC_FIST_FLOOR))
17476 (use (match_operand:HI 2 "memory_operand" "m,m"))
17477 (use (match_operand:HI 3 "memory_operand" "m,m"))
17478 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17479 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17480 "TARGET_USE_FANCY_MATH_387
17481 && flag_unsafe_math_optimizations"
17482 "#"
17483 [(set_attr "type" "fistp")
17484 (set_attr "i387_cw" "floor")
17485 (set_attr "mode" "DI")])
17486
17487(define_split
17488 [(set (match_operand:DI 0 "register_operand" "")
17489 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17490 UNSPEC_FIST_FLOOR))
17491 (use (match_operand:HI 2 "memory_operand" ""))
17492 (use (match_operand:HI 3 "memory_operand" ""))
17493 (clobber (match_operand:DI 4 "memory_operand" ""))
17494 (clobber (match_scratch 5 ""))]
17495 "reload_completed"
17496 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17497 (use (match_dup 2))
17498 (use (match_dup 3))
17499 (clobber (match_dup 5))])
17500 (set (match_dup 0) (match_dup 4))]
17501 "")
17502
17503(define_split
17504 [(set (match_operand:DI 0 "memory_operand" "")
17505 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17506 UNSPEC_FIST_FLOOR))
17507 (use (match_operand:HI 2 "memory_operand" ""))
17508 (use (match_operand:HI 3 "memory_operand" ""))
17509 (clobber (match_operand:DI 4 "memory_operand" ""))
17510 (clobber (match_scratch 5 ""))]
17511 "reload_completed"
17512 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17513 (use (match_dup 2))
17514 (use (match_dup 3))
17515 (clobber (match_dup 5))])]
17516 "")
17517
17518(define_insn "fist<mode>2_floor"
17519 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17520 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17521 UNSPEC_FIST_FLOOR))
17522 (use (match_operand:HI 2 "memory_operand" "m"))
17523 (use (match_operand:HI 3 "memory_operand" "m"))]
17524 "TARGET_USE_FANCY_MATH_387
17525 && flag_unsafe_math_optimizations"
17526 "* return output_fix_trunc (insn, operands, 0);"
17527 [(set_attr "type" "fistp")
17528 (set_attr "i387_cw" "floor")
17529 (set_attr "mode" "<MODE>")])
17530
17531(define_insn "fist<mode>2_floor_with_temp"
17532 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17533 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17534 UNSPEC_FIST_FLOOR))
17535 (use (match_operand:HI 2 "memory_operand" "m,m"))
17536 (use (match_operand:HI 3 "memory_operand" "m,m"))
17537 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17538 "TARGET_USE_FANCY_MATH_387
17539 && flag_unsafe_math_optimizations"
17540 "#"
17541 [(set_attr "type" "fistp")
17542 (set_attr "i387_cw" "floor")
17543 (set_attr "mode" "<MODE>")])
17544
17545(define_split
17546 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17547 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17548 UNSPEC_FIST_FLOOR))
17549 (use (match_operand:HI 2 "memory_operand" ""))
17550 (use (match_operand:HI 3 "memory_operand" ""))
17551 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17552 "reload_completed"
17553 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17554 UNSPEC_FIST_FLOOR))
17555 (use (match_dup 2))
17556 (use (match_dup 3))])
17557 (set (match_dup 0) (match_dup 4))]
17558 "")
17559
17560(define_split
17561 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17562 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17563 UNSPEC_FIST_FLOOR))
17564 (use (match_operand:HI 2 "memory_operand" ""))
17565 (use (match_operand:HI 3 "memory_operand" ""))
17566 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17567 "reload_completed"
17568 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17569 UNSPEC_FIST_FLOOR))
17570 (use (match_dup 2))
17571 (use (match_dup 3))])]
17572 "")
17573
17574(define_expand "lfloor<mode>2"
17575 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17576 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17577 UNSPEC_FIST_FLOOR))
17578 (clobber (reg:CC FLAGS_REG))])]
17579 "TARGET_USE_FANCY_MATH_387
17580 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17581 && flag_unsafe_math_optimizations"
17582 "")
17583
17584;; Rounding mode control word calculation could clobber FLAGS_REG.
17585(define_insn_and_split "frndintxf2_ceil"
17586 [(set (match_operand:XF 0 "register_operand" "=f")
17587 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17588 UNSPEC_FRNDINT_CEIL))
17589 (clobber (reg:CC FLAGS_REG))]
17590 "TARGET_USE_FANCY_MATH_387
17591 && flag_unsafe_math_optimizations
17592 && !(reload_completed || reload_in_progress)"
17593 "#"
17594 "&& 1"
17595 [(const_int 0)]
17596{
17597 ix86_optimize_mode_switching[I387_CEIL] = 1;
17598
17599 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17600 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17601
17602 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17603 operands[2], operands[3]));
17604 DONE;
17605}
17606 [(set_attr "type" "frndint")
17607 (set_attr "i387_cw" "ceil")
17608 (set_attr "mode" "XF")])
17609
17610(define_insn "frndintxf2_ceil_i387"
17611 [(set (match_operand:XF 0 "register_operand" "=f")
17612 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17613 UNSPEC_FRNDINT_CEIL))
17614 (use (match_operand:HI 2 "memory_operand" "m"))
17615 (use (match_operand:HI 3 "memory_operand" "m"))]
17616 "TARGET_USE_FANCY_MATH_387
17617 && flag_unsafe_math_optimizations"
17618 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17619 [(set_attr "type" "frndint")
17620 (set_attr "i387_cw" "ceil")
17621 (set_attr "mode" "XF")])
17622
17623(define_expand "ceilxf2"
17624 [(use (match_operand:XF 0 "register_operand" ""))
17625 (use (match_operand:XF 1 "register_operand" ""))]
17626 "TARGET_USE_FANCY_MATH_387
17627 && flag_unsafe_math_optimizations"
17628{
17629 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17630 DONE;
17631})
17632
17633(define_expand "ceildf2"
17634 [(use (match_operand:DF 0 "register_operand" ""))
17635 (use (match_operand:DF 1 "register_operand" ""))]
17636 "TARGET_USE_FANCY_MATH_387
17637 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17638 && flag_unsafe_math_optimizations"
17639{
17640 rtx op0 = gen_reg_rtx (XFmode);
17641 rtx op1 = gen_reg_rtx (XFmode);
17642
17643 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17644 emit_insn (gen_frndintxf2_ceil (op0, op1));
17645
17646 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17647 DONE;
17648})
17649
17650(define_expand "ceilsf2"
17651 [(use (match_operand:SF 0 "register_operand" ""))
17652 (use (match_operand:SF 1 "register_operand" ""))]
17653 "TARGET_USE_FANCY_MATH_387
17654 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17655 && flag_unsafe_math_optimizations"
17656{
17657 rtx op0 = gen_reg_rtx (XFmode);
17658 rtx op1 = gen_reg_rtx (XFmode);
17659
17660 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17661 emit_insn (gen_frndintxf2_ceil (op0, op1));
17662
17663 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17664 DONE;
17665})
17666
17667(define_insn_and_split "*fist<mode>2_ceil_1"
17668 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17669 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17670 UNSPEC_FIST_CEIL))
17671 (clobber (reg:CC FLAGS_REG))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && flag_unsafe_math_optimizations
17674 && !(reload_completed || reload_in_progress)"
17675 "#"
17676 "&& 1"
17677 [(const_int 0)]
17678{
17679 ix86_optimize_mode_switching[I387_CEIL] = 1;
17680
17681 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17682 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17683 if (memory_operand (operands[0], VOIDmode))
17684 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17685 operands[2], operands[3]));
17686 else
17687 {
17688 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17689 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17690 operands[2], operands[3],
17691 operands[4]));
17692 }
17693 DONE;
17694}
17695 [(set_attr "type" "fistp")
17696 (set_attr "i387_cw" "ceil")
17697 (set_attr "mode" "<MODE>")])
17698
17699(define_insn "fistdi2_ceil"
17700 [(set (match_operand:DI 0 "memory_operand" "=m")
17701 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17702 UNSPEC_FIST_CEIL))
17703 (use (match_operand:HI 2 "memory_operand" "m"))
17704 (use (match_operand:HI 3 "memory_operand" "m"))
17705 (clobber (match_scratch:XF 4 "=&1f"))]
17706 "TARGET_USE_FANCY_MATH_387
17707 && flag_unsafe_math_optimizations"
17708 "* return output_fix_trunc (insn, operands, 0);"
17709 [(set_attr "type" "fistp")
17710 (set_attr "i387_cw" "ceil")
17711 (set_attr "mode" "DI")])
17712
17713(define_insn "fistdi2_ceil_with_temp"
17714 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17715 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17716 UNSPEC_FIST_CEIL))
17717 (use (match_operand:HI 2 "memory_operand" "m,m"))
17718 (use (match_operand:HI 3 "memory_operand" "m,m"))
17719 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17720 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17721 "TARGET_USE_FANCY_MATH_387
17722 && flag_unsafe_math_optimizations"
17723 "#"
17724 [(set_attr "type" "fistp")
17725 (set_attr "i387_cw" "ceil")
17726 (set_attr "mode" "DI")])
17727
17728(define_split
17729 [(set (match_operand:DI 0 "register_operand" "")
17730 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17731 UNSPEC_FIST_CEIL))
17732 (use (match_operand:HI 2 "memory_operand" ""))
17733 (use (match_operand:HI 3 "memory_operand" ""))
17734 (clobber (match_operand:DI 4 "memory_operand" ""))
17735 (clobber (match_scratch 5 ""))]
17736 "reload_completed"
17737 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17738 (use (match_dup 2))
17739 (use (match_dup 3))
17740 (clobber (match_dup 5))])
17741 (set (match_dup 0) (match_dup 4))]
17742 "")
17743
17744(define_split
17745 [(set (match_operand:DI 0 "memory_operand" "")
17746 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17747 UNSPEC_FIST_CEIL))
17748 (use (match_operand:HI 2 "memory_operand" ""))
17749 (use (match_operand:HI 3 "memory_operand" ""))
17750 (clobber (match_operand:DI 4 "memory_operand" ""))
17751 (clobber (match_scratch 5 ""))]
17752 "reload_completed"
17753 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17754 (use (match_dup 2))
17755 (use (match_dup 3))
17756 (clobber (match_dup 5))])]
17757 "")
17758
17759(define_insn "fist<mode>2_ceil"
17760 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17761 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17762 UNSPEC_FIST_CEIL))
17763 (use (match_operand:HI 2 "memory_operand" "m"))
17764 (use (match_operand:HI 3 "memory_operand" "m"))]
17765 "TARGET_USE_FANCY_MATH_387
17766 && flag_unsafe_math_optimizations"
17767 "* return output_fix_trunc (insn, operands, 0);"
17768 [(set_attr "type" "fistp")
17769 (set_attr "i387_cw" "ceil")
17770 (set_attr "mode" "<MODE>")])
17771
17772(define_insn "fist<mode>2_ceil_with_temp"
17773 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17774 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17775 UNSPEC_FIST_CEIL))
17776 (use (match_operand:HI 2 "memory_operand" "m,m"))
17777 (use (match_operand:HI 3 "memory_operand" "m,m"))
17778 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17779 "TARGET_USE_FANCY_MATH_387
17780 && flag_unsafe_math_optimizations"
17781 "#"
17782 [(set_attr "type" "fistp")
17783 (set_attr "i387_cw" "ceil")
17784 (set_attr "mode" "<MODE>")])
17785
17786(define_split
17787 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17788 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17789 UNSPEC_FIST_CEIL))
17790 (use (match_operand:HI 2 "memory_operand" ""))
17791 (use (match_operand:HI 3 "memory_operand" ""))
17792 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17793 "reload_completed"
17794 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17795 UNSPEC_FIST_CEIL))
17796 (use (match_dup 2))
17797 (use (match_dup 3))])
17798 (set (match_dup 0) (match_dup 4))]
17799 "")
17800
17801(define_split
17802 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17803 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17804 UNSPEC_FIST_CEIL))
17805 (use (match_operand:HI 2 "memory_operand" ""))
17806 (use (match_operand:HI 3 "memory_operand" ""))
17807 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17808 "reload_completed"
17809 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17810 UNSPEC_FIST_CEIL))
17811 (use (match_dup 2))
17812 (use (match_dup 3))])]
17813 "")
17814
17815(define_expand "lceil<mode>2"
17816 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17817 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17818 UNSPEC_FIST_CEIL))
17819 (clobber (reg:CC FLAGS_REG))])]
17820 "TARGET_USE_FANCY_MATH_387
17821 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17822 && flag_unsafe_math_optimizations"
17823 "")
17824
17825;; Rounding mode control word calculation could clobber FLAGS_REG.
17826(define_insn_and_split "frndintxf2_trunc"
17827 [(set (match_operand:XF 0 "register_operand" "=f")
17828 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17829 UNSPEC_FRNDINT_TRUNC))
17830 (clobber (reg:CC FLAGS_REG))]
17831 "TARGET_USE_FANCY_MATH_387
17832 && flag_unsafe_math_optimizations
17833 && !(reload_completed || reload_in_progress)"
17834 "#"
17835 "&& 1"
17836 [(const_int 0)]
17837{
17838 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17839
17840 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17841 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17842
17843 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17844 operands[2], operands[3]));
17845 DONE;
17846}
17847 [(set_attr "type" "frndint")
17848 (set_attr "i387_cw" "trunc")
17849 (set_attr "mode" "XF")])
17850
17851(define_insn "frndintxf2_trunc_i387"
17852 [(set (match_operand:XF 0 "register_operand" "=f")
17853 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17854 UNSPEC_FRNDINT_TRUNC))
17855 (use (match_operand:HI 2 "memory_operand" "m"))
17856 (use (match_operand:HI 3 "memory_operand" "m"))]
17857 "TARGET_USE_FANCY_MATH_387
17858 && flag_unsafe_math_optimizations"
17859 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17860 [(set_attr "type" "frndint")
17861 (set_attr "i387_cw" "trunc")
17862 (set_attr "mode" "XF")])
17863
17864(define_expand "btruncxf2"
17865 [(use (match_operand:XF 0 "register_operand" ""))
17866 (use (match_operand:XF 1 "register_operand" ""))]
17867 "TARGET_USE_FANCY_MATH_387
17868 && flag_unsafe_math_optimizations"
17869{
17870 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17871 DONE;
17872})
17873
17874(define_expand "btruncdf2"
17875 [(use (match_operand:DF 0 "register_operand" ""))
17876 (use (match_operand:DF 1 "register_operand" ""))]
17877 "TARGET_USE_FANCY_MATH_387
17878 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17879 && flag_unsafe_math_optimizations"
17880{
17881 rtx op0 = gen_reg_rtx (XFmode);
17882 rtx op1 = gen_reg_rtx (XFmode);
17883
17884 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17885 emit_insn (gen_frndintxf2_trunc (op0, op1));
17886
17887 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17888 DONE;
17889})
17890
17891(define_expand "btruncsf2"
17892 [(use (match_operand:SF 0 "register_operand" ""))
17893 (use (match_operand:SF 1 "register_operand" ""))]
17894 "TARGET_USE_FANCY_MATH_387
17895 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17896 && flag_unsafe_math_optimizations"
17897{
17898 rtx op0 = gen_reg_rtx (XFmode);
17899 rtx op1 = gen_reg_rtx (XFmode);
17900
17901 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17902 emit_insn (gen_frndintxf2_trunc (op0, op1));
17903
17904 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17905 DONE;
17906})
17907
17908;; Rounding mode control word calculation could clobber FLAGS_REG.
17909(define_insn_and_split "frndintxf2_mask_pm"
17910 [(set (match_operand:XF 0 "register_operand" "=f")
17911 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17912 UNSPEC_FRNDINT_MASK_PM))
17913 (clobber (reg:CC FLAGS_REG))]
17914 "TARGET_USE_FANCY_MATH_387
17915 && flag_unsafe_math_optimizations
17916 && !(reload_completed || reload_in_progress)"
17917 "#"
17918 "&& 1"
17919 [(const_int 0)]
17920{
17921 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17922
17923 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17924 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17925
17926 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17927 operands[2], operands[3]));
17928 DONE;
17929}
17930 [(set_attr "type" "frndint")
17931 (set_attr "i387_cw" "mask_pm")
17932 (set_attr "mode" "XF")])
17933
17934(define_insn "frndintxf2_mask_pm_i387"
17935 [(set (match_operand:XF 0 "register_operand" "=f")
17936 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17937 UNSPEC_FRNDINT_MASK_PM))
17938 (use (match_operand:HI 2 "memory_operand" "m"))
17939 (use (match_operand:HI 3 "memory_operand" "m"))]
17940 "TARGET_USE_FANCY_MATH_387
17941 && flag_unsafe_math_optimizations"
17942 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17943 [(set_attr "type" "frndint")
17944 (set_attr "i387_cw" "mask_pm")
17945 (set_attr "mode" "XF")])
17946
17947(define_expand "nearbyintxf2"
17948 [(use (match_operand:XF 0 "register_operand" ""))
17949 (use (match_operand:XF 1 "register_operand" ""))]
17950 "TARGET_USE_FANCY_MATH_387
17951 && flag_unsafe_math_optimizations"
17952{
17953 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17954
17955 DONE;
17956})
17957
17958(define_expand "nearbyintdf2"
17959 [(use (match_operand:DF 0 "register_operand" ""))
17960 (use (match_operand:DF 1 "register_operand" ""))]
17961 "TARGET_USE_FANCY_MATH_387
17962 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17963 && flag_unsafe_math_optimizations"
17964{
17965 rtx op0 = gen_reg_rtx (XFmode);
17966 rtx op1 = gen_reg_rtx (XFmode);
17967
17968 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17969 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17970
17971 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17972 DONE;
17973})
17974
17975(define_expand "nearbyintsf2"
17976 [(use (match_operand:SF 0 "register_operand" ""))
17977 (use (match_operand:SF 1 "register_operand" ""))]
17978 "TARGET_USE_FANCY_MATH_387
17979 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17980 && flag_unsafe_math_optimizations"
17981{
17982 rtx op0 = gen_reg_rtx (XFmode);
17983 rtx op1 = gen_reg_rtx (XFmode);
17984
17985 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17986 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17987
17988 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17989 DONE;
17990})
17991
17992
17993;; Block operation instructions
17994
17995(define_insn "cld"
17996 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17997 ""
17998 "cld"
17999 [(set_attr "type" "cld")])
18000
18001(define_expand "movmemsi"
18002 [(use (match_operand:BLK 0 "memory_operand" ""))
18003 (use (match_operand:BLK 1 "memory_operand" ""))
18004 (use (match_operand:SI 2 "nonmemory_operand" ""))
18005 (use (match_operand:SI 3 "const_int_operand" ""))]
18006 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18007{
18008 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18009 DONE;
18010 else
18011 FAIL;
18012})
18013
18014(define_expand "movmemdi"
18015 [(use (match_operand:BLK 0 "memory_operand" ""))
18016 (use (match_operand:BLK 1 "memory_operand" ""))
18017 (use (match_operand:DI 2 "nonmemory_operand" ""))
18018 (use (match_operand:DI 3 "const_int_operand" ""))]
18019 "TARGET_64BIT"
18020{
18021 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18022 DONE;
18023 else
18024 FAIL;
18025})
18026
18027;; Most CPUs don't like single string operations
18028;; Handle this case here to simplify previous expander.
18029
18030(define_expand "strmov"
18031 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18032 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18033 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18034 (clobber (reg:CC FLAGS_REG))])
18035 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18036 (clobber (reg:CC FLAGS_REG))])]
18037 ""
18038{
18039 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18040
18041 /* If .md ever supports :P for Pmode, these can be directly
18042 in the pattern above. */
18043 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18044 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18045
18046 if (TARGET_SINGLE_STRINGOP || optimize_size)
18047 {
18048 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18049 operands[2], operands[3],
18050 operands[5], operands[6]));
18051 DONE;
18052 }
18053
18054 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18055})
18056
18057(define_expand "strmov_singleop"
18058 [(parallel [(set (match_operand 1 "memory_operand" "")
18059 (match_operand 3 "memory_operand" ""))
18060 (set (match_operand 0 "register_operand" "")
18061 (match_operand 4 "" ""))
18062 (set (match_operand 2 "register_operand" "")
18063 (match_operand 5 "" ""))
18064 (use (reg:SI DIRFLAG_REG))])]
18065 "TARGET_SINGLE_STRINGOP || optimize_size"
18066 "")
18067
18068(define_insn "*strmovdi_rex_1"
18069 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18070 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18071 (set (match_operand:DI 0 "register_operand" "=D")
18072 (plus:DI (match_dup 2)
18073 (const_int 8)))
18074 (set (match_operand:DI 1 "register_operand" "=S")
18075 (plus:DI (match_dup 3)
18076 (const_int 8)))
18077 (use (reg:SI DIRFLAG_REG))]
18078 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18079 "movsq"
18080 [(set_attr "type" "str")
18081 (set_attr "mode" "DI")
18082 (set_attr "memory" "both")])
18083
18084(define_insn "*strmovsi_1"
18085 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18086 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18087 (set (match_operand:SI 0 "register_operand" "=D")
18088 (plus:SI (match_dup 2)
18089 (const_int 4)))
18090 (set (match_operand:SI 1 "register_operand" "=S")
18091 (plus:SI (match_dup 3)
18092 (const_int 4)))
18093 (use (reg:SI DIRFLAG_REG))]
18094 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18095 "{movsl|movsd}"
18096 [(set_attr "type" "str")
18097 (set_attr "mode" "SI")
18098 (set_attr "memory" "both")])
18099
18100(define_insn "*strmovsi_rex_1"
18101 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18102 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18103 (set (match_operand:DI 0 "register_operand" "=D")
18104 (plus:DI (match_dup 2)
18105 (const_int 4)))
18106 (set (match_operand:DI 1 "register_operand" "=S")
18107 (plus:DI (match_dup 3)
18108 (const_int 4)))
18109 (use (reg:SI DIRFLAG_REG))]
18110 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18111 "{movsl|movsd}"
18112 [(set_attr "type" "str")
18113 (set_attr "mode" "SI")
18114 (set_attr "memory" "both")])
18115
18116(define_insn "*strmovhi_1"
18117 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18118 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18119 (set (match_operand:SI 0 "register_operand" "=D")
18120 (plus:SI (match_dup 2)
18121 (const_int 2)))
18122 (set (match_operand:SI 1 "register_operand" "=S")
18123 (plus:SI (match_dup 3)
18124 (const_int 2)))
18125 (use (reg:SI DIRFLAG_REG))]
18126 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18127 "movsw"
18128 [(set_attr "type" "str")
18129 (set_attr "memory" "both")
18130 (set_attr "mode" "HI")])
18131
18132(define_insn "*strmovhi_rex_1"
18133 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18134 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18135 (set (match_operand:DI 0 "register_operand" "=D")
18136 (plus:DI (match_dup 2)
18137 (const_int 2)))
18138 (set (match_operand:DI 1 "register_operand" "=S")
18139 (plus:DI (match_dup 3)
18140 (const_int 2)))
18141 (use (reg:SI DIRFLAG_REG))]
18142 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18143 "movsw"
18144 [(set_attr "type" "str")
18145 (set_attr "memory" "both")
18146 (set_attr "mode" "HI")])
18147
18148(define_insn "*strmovqi_1"
18149 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18150 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18151 (set (match_operand:SI 0 "register_operand" "=D")
18152 (plus:SI (match_dup 2)
18153 (const_int 1)))
18154 (set (match_operand:SI 1 "register_operand" "=S")
18155 (plus:SI (match_dup 3)
18156 (const_int 1)))
18157 (use (reg:SI DIRFLAG_REG))]
18158 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18159 "movsb"
18160 [(set_attr "type" "str")
18161 (set_attr "memory" "both")
18162 (set_attr "mode" "QI")])
18163
18164(define_insn "*strmovqi_rex_1"
18165 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18166 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18167 (set (match_operand:DI 0 "register_operand" "=D")
18168 (plus:DI (match_dup 2)
18169 (const_int 1)))
18170 (set (match_operand:DI 1 "register_operand" "=S")
18171 (plus:DI (match_dup 3)
18172 (const_int 1)))
18173 (use (reg:SI DIRFLAG_REG))]
18174 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18175 "movsb"
18176 [(set_attr "type" "str")
18177 (set_attr "memory" "both")
18178 (set_attr "mode" "QI")])
18179
18180(define_expand "rep_mov"
18181 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18182 (set (match_operand 0 "register_operand" "")
18183 (match_operand 5 "" ""))
18184 (set (match_operand 2 "register_operand" "")
18185 (match_operand 6 "" ""))
18186 (set (match_operand 1 "memory_operand" "")
18187 (match_operand 3 "memory_operand" ""))
18188 (use (match_dup 4))
18189 (use (reg:SI DIRFLAG_REG))])]
18190 ""
18191 "")
18192
18193(define_insn "*rep_movdi_rex64"
18194 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18195 (set (match_operand:DI 0 "register_operand" "=D")
18196 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18197 (const_int 3))
18198 (match_operand:DI 3 "register_operand" "0")))
18199 (set (match_operand:DI 1 "register_operand" "=S")
18200 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18201 (match_operand:DI 4 "register_operand" "1")))
18202 (set (mem:BLK (match_dup 3))
18203 (mem:BLK (match_dup 4)))
18204 (use (match_dup 5))
18205 (use (reg:SI DIRFLAG_REG))]
18206 "TARGET_64BIT"
18207 "{rep\;movsq|rep movsq}"
18208 [(set_attr "type" "str")
18209 (set_attr "prefix_rep" "1")
18210 (set_attr "memory" "both")
18211 (set_attr "mode" "DI")])
18212
18213(define_insn "*rep_movsi"
18214 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18215 (set (match_operand:SI 0 "register_operand" "=D")
18216 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18217 (const_int 2))
18218 (match_operand:SI 3 "register_operand" "0")))
18219 (set (match_operand:SI 1 "register_operand" "=S")
18220 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18221 (match_operand:SI 4 "register_operand" "1")))
18222 (set (mem:BLK (match_dup 3))
18223 (mem:BLK (match_dup 4)))
18224 (use (match_dup 5))
18225 (use (reg:SI DIRFLAG_REG))]
18226 "!TARGET_64BIT"
18227 "{rep\;movsl|rep movsd}"
18228 [(set_attr "type" "str")
18229 (set_attr "prefix_rep" "1")
18230 (set_attr "memory" "both")
18231 (set_attr "mode" "SI")])
18232
18233(define_insn "*rep_movsi_rex64"
18234 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18235 (set (match_operand:DI 0 "register_operand" "=D")
18236 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18237 (const_int 2))
18238 (match_operand:DI 3 "register_operand" "0")))
18239 (set (match_operand:DI 1 "register_operand" "=S")
18240 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18241 (match_operand:DI 4 "register_operand" "1")))
18242 (set (mem:BLK (match_dup 3))
18243 (mem:BLK (match_dup 4)))
18244 (use (match_dup 5))
18245 (use (reg:SI DIRFLAG_REG))]
18246 "TARGET_64BIT"
18247 "{rep\;movsl|rep movsd}"
18248 [(set_attr "type" "str")
18249 (set_attr "prefix_rep" "1")
18250 (set_attr "memory" "both")
18251 (set_attr "mode" "SI")])
18252
18253(define_insn "*rep_movqi"
18254 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18255 (set (match_operand:SI 0 "register_operand" "=D")
18256 (plus:SI (match_operand:SI 3 "register_operand" "0")
18257 (match_operand:SI 5 "register_operand" "2")))
18258 (set (match_operand:SI 1 "register_operand" "=S")
18259 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18260 (set (mem:BLK (match_dup 3))
18261 (mem:BLK (match_dup 4)))
18262 (use (match_dup 5))
18263 (use (reg:SI DIRFLAG_REG))]
18264 "!TARGET_64BIT"
18265 "{rep\;movsb|rep movsb}"
18266 [(set_attr "type" "str")
18267 (set_attr "prefix_rep" "1")
18268 (set_attr "memory" "both")
18269 (set_attr "mode" "SI")])
18270
18271(define_insn "*rep_movqi_rex64"
18272 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18273 (set (match_operand:DI 0 "register_operand" "=D")
18274 (plus:DI (match_operand:DI 3 "register_operand" "0")
18275 (match_operand:DI 5 "register_operand" "2")))
18276 (set (match_operand:DI 1 "register_operand" "=S")
18277 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18278 (set (mem:BLK (match_dup 3))
18279 (mem:BLK (match_dup 4)))
18280 (use (match_dup 5))
18281 (use (reg:SI DIRFLAG_REG))]
18282 "TARGET_64BIT"
18283 "{rep\;movsb|rep movsb}"
18284 [(set_attr "type" "str")
18285 (set_attr "prefix_rep" "1")
18286 (set_attr "memory" "both")
18287 (set_attr "mode" "SI")])
18288
18289(define_expand "setmemsi"
18290 [(use (match_operand:BLK 0 "memory_operand" ""))
18291 (use (match_operand:SI 1 "nonmemory_operand" ""))
18292 (use (match_operand 2 "const_int_operand" ""))
18293 (use (match_operand 3 "const_int_operand" ""))]
18294 ""
18295{
18296 /* If value to set is not zero, use the library routine. */
18297 if (operands[2] != const0_rtx)
18298 FAIL;
18299
18300 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18301 DONE;
18302 else
18303 FAIL;
18304})
18305
18306(define_expand "setmemdi"
18307 [(use (match_operand:BLK 0 "memory_operand" ""))
18308 (use (match_operand:DI 1 "nonmemory_operand" ""))
18309 (use (match_operand 2 "const_int_operand" ""))
18310 (use (match_operand 3 "const_int_operand" ""))]
18311 "TARGET_64BIT"
18312{
18313 /* If value to set is not zero, use the library routine. */
18314 if (operands[2] != const0_rtx)
18315 FAIL;
18316
18317 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18318 DONE;
18319 else
18320 FAIL;
18321})
18322
18323;; Most CPUs don't like single string operations
18324;; Handle this case here to simplify previous expander.
18325
18326(define_expand "strset"
18327 [(set (match_operand 1 "memory_operand" "")
18328 (match_operand 2 "register_operand" ""))
18329 (parallel [(set (match_operand 0 "register_operand" "")
18330 (match_dup 3))
18331 (clobber (reg:CC FLAGS_REG))])]
18332 ""
18333{
18334 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18335 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18336
18337 /* If .md ever supports :P for Pmode, this can be directly
18338 in the pattern above. */
18339 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18340 GEN_INT (GET_MODE_SIZE (GET_MODE
18341 (operands[2]))));
18342 if (TARGET_SINGLE_STRINGOP || optimize_size)
18343 {
18344 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18345 operands[3]));
18346 DONE;
18347 }
18348})
18349
18350(define_expand "strset_singleop"
18351 [(parallel [(set (match_operand 1 "memory_operand" "")
18352 (match_operand 2 "register_operand" ""))
18353 (set (match_operand 0 "register_operand" "")
18354 (match_operand 3 "" ""))
18355 (use (reg:SI DIRFLAG_REG))])]
18356 "TARGET_SINGLE_STRINGOP || optimize_size"
18357 "")
18358
18359(define_insn "*strsetdi_rex_1"
18360 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18361 (match_operand:DI 2 "register_operand" "a"))
18362 (set (match_operand:DI 0 "register_operand" "=D")
18363 (plus:DI (match_dup 1)
18364 (const_int 8)))
18365 (use (reg:SI DIRFLAG_REG))]
18366 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18367 "stosq"
18368 [(set_attr "type" "str")
18369 (set_attr "memory" "store")
18370 (set_attr "mode" "DI")])
18371
18372(define_insn "*strsetsi_1"
18373 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18374 (match_operand:SI 2 "register_operand" "a"))
18375 (set (match_operand:SI 0 "register_operand" "=D")
18376 (plus:SI (match_dup 1)
18377 (const_int 4)))
18378 (use (reg:SI DIRFLAG_REG))]
18379 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18380 "{stosl|stosd}"
18381 [(set_attr "type" "str")
18382 (set_attr "memory" "store")
18383 (set_attr "mode" "SI")])
18384
18385(define_insn "*strsetsi_rex_1"
18386 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18387 (match_operand:SI 2 "register_operand" "a"))
18388 (set (match_operand:DI 0 "register_operand" "=D")
18389 (plus:DI (match_dup 1)
18390 (const_int 4)))
18391 (use (reg:SI DIRFLAG_REG))]
18392 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18393 "{stosl|stosd}"
18394 [(set_attr "type" "str")
18395 (set_attr "memory" "store")
18396 (set_attr "mode" "SI")])
18397
18398(define_insn "*strsethi_1"
18399 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18400 (match_operand:HI 2 "register_operand" "a"))
18401 (set (match_operand:SI 0 "register_operand" "=D")
18402 (plus:SI (match_dup 1)
18403 (const_int 2)))
18404 (use (reg:SI DIRFLAG_REG))]
18405 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18406 "stosw"
18407 [(set_attr "type" "str")
18408 (set_attr "memory" "store")
18409 (set_attr "mode" "HI")])
18410
18411(define_insn "*strsethi_rex_1"
18412 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18413 (match_operand:HI 2 "register_operand" "a"))
18414 (set (match_operand:DI 0 "register_operand" "=D")
18415 (plus:DI (match_dup 1)
18416 (const_int 2)))
18417 (use (reg:SI DIRFLAG_REG))]
18418 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18419 "stosw"
18420 [(set_attr "type" "str")
18421 (set_attr "memory" "store")
18422 (set_attr "mode" "HI")])
18423
18424(define_insn "*strsetqi_1"
18425 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18426 (match_operand:QI 2 "register_operand" "a"))
18427 (set (match_operand:SI 0 "register_operand" "=D")
18428 (plus:SI (match_dup 1)
18429 (const_int 1)))
18430 (use (reg:SI DIRFLAG_REG))]
18431 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18432 "stosb"
18433 [(set_attr "type" "str")
18434 (set_attr "memory" "store")
18435 (set_attr "mode" "QI")])
18436
18437(define_insn "*strsetqi_rex_1"
18438 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18439 (match_operand:QI 2 "register_operand" "a"))
18440 (set (match_operand:DI 0 "register_operand" "=D")
18441 (plus:DI (match_dup 1)
18442 (const_int 1)))
18443 (use (reg:SI DIRFLAG_REG))]
18444 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18445 "stosb"
18446 [(set_attr "type" "str")
18447 (set_attr "memory" "store")
18448 (set_attr "mode" "QI")])
18449
18450(define_expand "rep_stos"
18451 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18452 (set (match_operand 0 "register_operand" "")
18453 (match_operand 4 "" ""))
18454 (set (match_operand 2 "memory_operand" "") (const_int 0))
18455 (use (match_operand 3 "register_operand" ""))
18456 (use (match_dup 1))
18457 (use (reg:SI DIRFLAG_REG))])]
18458 ""
18459 "")
18460
18461(define_insn "*rep_stosdi_rex64"
18462 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18463 (set (match_operand:DI 0 "register_operand" "=D")
18464 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18465 (const_int 3))
18466 (match_operand:DI 3 "register_operand" "0")))
18467 (set (mem:BLK (match_dup 3))
18468 (const_int 0))
18469 (use (match_operand:DI 2 "register_operand" "a"))
18470 (use (match_dup 4))
18471 (use (reg:SI DIRFLAG_REG))]
18472 "TARGET_64BIT"
18473 "{rep\;stosq|rep stosq}"
18474 [(set_attr "type" "str")
18475 (set_attr "prefix_rep" "1")
18476 (set_attr "memory" "store")
18477 (set_attr "mode" "DI")])
18478
18479(define_insn "*rep_stossi"
18480 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18481 (set (match_operand:SI 0 "register_operand" "=D")
18482 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18483 (const_int 2))
18484 (match_operand:SI 3 "register_operand" "0")))
18485 (set (mem:BLK (match_dup 3))
18486 (const_int 0))
18487 (use (match_operand:SI 2 "register_operand" "a"))
18488 (use (match_dup 4))
18489 (use (reg:SI DIRFLAG_REG))]
18490 "!TARGET_64BIT"
18491 "{rep\;stosl|rep stosd}"
18492 [(set_attr "type" "str")
18493 (set_attr "prefix_rep" "1")
18494 (set_attr "memory" "store")
18495 (set_attr "mode" "SI")])
18496
18497(define_insn "*rep_stossi_rex64"
18498 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18499 (set (match_operand:DI 0 "register_operand" "=D")
18500 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18501 (const_int 2))
18502 (match_operand:DI 3 "register_operand" "0")))
18503 (set (mem:BLK (match_dup 3))
18504 (const_int 0))
18505 (use (match_operand:SI 2 "register_operand" "a"))
18506 (use (match_dup 4))
18507 (use (reg:SI DIRFLAG_REG))]
18508 "TARGET_64BIT"
18509 "{rep\;stosl|rep stosd}"
18510 [(set_attr "type" "str")
18511 (set_attr "prefix_rep" "1")
18512 (set_attr "memory" "store")
18513 (set_attr "mode" "SI")])
18514
18515(define_insn "*rep_stosqi"
18516 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18517 (set (match_operand:SI 0 "register_operand" "=D")
18518 (plus:SI (match_operand:SI 3 "register_operand" "0")
18519 (match_operand:SI 4 "register_operand" "1")))
18520 (set (mem:BLK (match_dup 3))
18521 (const_int 0))
18522 (use (match_operand:QI 2 "register_operand" "a"))
18523 (use (match_dup 4))
18524 (use (reg:SI DIRFLAG_REG))]
18525 "!TARGET_64BIT"
18526 "{rep\;stosb|rep stosb}"
18527 [(set_attr "type" "str")
18528 (set_attr "prefix_rep" "1")
18529 (set_attr "memory" "store")
18530 (set_attr "mode" "QI")])
18531
18532(define_insn "*rep_stosqi_rex64"
18533 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18534 (set (match_operand:DI 0 "register_operand" "=D")
18535 (plus:DI (match_operand:DI 3 "register_operand" "0")
18536 (match_operand:DI 4 "register_operand" "1")))
18537 (set (mem:BLK (match_dup 3))
18538 (const_int 0))
18539 (use (match_operand:QI 2 "register_operand" "a"))
18540 (use (match_dup 4))
18541 (use (reg:SI DIRFLAG_REG))]
18542 "TARGET_64BIT"
18543 "{rep\;stosb|rep stosb}"
18544 [(set_attr "type" "str")
18545 (set_attr "prefix_rep" "1")
18546 (set_attr "memory" "store")
18547 (set_attr "mode" "QI")])
18548
18549(define_expand "cmpstrnsi"
18550 [(set (match_operand:SI 0 "register_operand" "")
18551 (compare:SI (match_operand:BLK 1 "general_operand" "")
18552 (match_operand:BLK 2 "general_operand" "")))
18553 (use (match_operand 3 "general_operand" ""))
18554 (use (match_operand 4 "immediate_operand" ""))]
18555 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18556{
18557 rtx addr1, addr2, out, outlow, count, countreg, align;
18558
18559 /* Can't use this if the user has appropriated esi or edi. */
18560 if (global_regs[4] || global_regs[5])
18561 FAIL;
18562
18563 out = operands[0];
18564 if (GET_CODE (out) != REG)
18565 out = gen_reg_rtx (SImode);
18566
18567 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18568 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18569 if (addr1 != XEXP (operands[1], 0))
18570 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18571 if (addr2 != XEXP (operands[2], 0))
18572 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18573
18574 count = operands[3];
18575 countreg = ix86_zero_extend_to_Pmode (count);
18576
18577 /* %%% Iff we are testing strict equality, we can use known alignment
18578 to good advantage. This may be possible with combine, particularly
18579 once cc0 is dead. */
18580 align = operands[4];
18581
18582 emit_insn (gen_cld ());
18583 if (GET_CODE (count) == CONST_INT)
18584 {
18585 if (INTVAL (count) == 0)
18586 {
18587 emit_move_insn (operands[0], const0_rtx);
18588 DONE;
18589 }
18590 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18591 operands[1], operands[2]));
18592 }
18593 else
18594 {
18595 if (TARGET_64BIT)
18596 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18597 else
18598 emit_insn (gen_cmpsi_1 (countreg, countreg));
18599 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18600 operands[1], operands[2]));
18601 }
18602
18603 outlow = gen_lowpart (QImode, out);
18604 emit_insn (gen_cmpintqi (outlow));
18605 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18606
18607 if (operands[0] != out)
18608 emit_move_insn (operands[0], out);
18609
18610 DONE;
18611})
18612
18613;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18614
18615(define_expand "cmpintqi"
18616 [(set (match_dup 1)
18617 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18618 (set (match_dup 2)
18619 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18620 (parallel [(set (match_operand:QI 0 "register_operand" "")
18621 (minus:QI (match_dup 1)
18622 (match_dup 2)))
18623 (clobber (reg:CC FLAGS_REG))])]
18624 ""
18625 "operands[1] = gen_reg_rtx (QImode);
18626 operands[2] = gen_reg_rtx (QImode);")
18627
18628;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18629;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18630
18631(define_expand "cmpstrnqi_nz_1"
18632 [(parallel [(set (reg:CC FLAGS_REG)
18633 (compare:CC (match_operand 4 "memory_operand" "")
18634 (match_operand 5 "memory_operand" "")))
18635 (use (match_operand 2 "register_operand" ""))
18636 (use (match_operand:SI 3 "immediate_operand" ""))
18637 (use (reg:SI DIRFLAG_REG))
18638 (clobber (match_operand 0 "register_operand" ""))
18639 (clobber (match_operand 1 "register_operand" ""))
18640 (clobber (match_dup 2))])]
18641 ""
18642 "")
18643
18644(define_insn "*cmpstrnqi_nz_1"
18645 [(set (reg:CC FLAGS_REG)
18646 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18647 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18648 (use (match_operand:SI 6 "register_operand" "2"))
18649 (use (match_operand:SI 3 "immediate_operand" "i"))
18650 (use (reg:SI DIRFLAG_REG))
18651 (clobber (match_operand:SI 0 "register_operand" "=S"))
18652 (clobber (match_operand:SI 1 "register_operand" "=D"))
18653 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18654 "!TARGET_64BIT"
18655 "repz{\;| }cmpsb"
18656 [(set_attr "type" "str")
18657 (set_attr "mode" "QI")
18658 (set_attr "prefix_rep" "1")])
18659
18660(define_insn "*cmpstrnqi_nz_rex_1"
18661 [(set (reg:CC FLAGS_REG)
18662 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18663 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18664 (use (match_operand:DI 6 "register_operand" "2"))
18665 (use (match_operand:SI 3 "immediate_operand" "i"))
18666 (use (reg:SI DIRFLAG_REG))
18667 (clobber (match_operand:DI 0 "register_operand" "=S"))
18668 (clobber (match_operand:DI 1 "register_operand" "=D"))
18669 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18670 "TARGET_64BIT"
18671 "repz{\;| }cmpsb"
18672 [(set_attr "type" "str")
18673 (set_attr "mode" "QI")
18674 (set_attr "prefix_rep" "1")])
18675
18676;; The same, but the count is not known to not be zero.
18677
18678(define_expand "cmpstrnqi_1"
18679 [(parallel [(set (reg:CC FLAGS_REG)
18680 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18681 (const_int 0))
18682 (compare:CC (match_operand 4 "memory_operand" "")
18683 (match_operand 5 "memory_operand" ""))
18684 (const_int 0)))
18685 (use (match_operand:SI 3 "immediate_operand" ""))
18686 (use (reg:CC FLAGS_REG))
18687 (use (reg:SI DIRFLAG_REG))
18688 (clobber (match_operand 0 "register_operand" ""))
18689 (clobber (match_operand 1 "register_operand" ""))
18690 (clobber (match_dup 2))])]
18691 ""
18692 "")
18693
18694(define_insn "*cmpstrnqi_1"
18695 [(set (reg:CC FLAGS_REG)
18696 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18697 (const_int 0))
18698 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18699 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18700 (const_int 0)))
18701 (use (match_operand:SI 3 "immediate_operand" "i"))
18702 (use (reg:CC FLAGS_REG))
18703 (use (reg:SI DIRFLAG_REG))
18704 (clobber (match_operand:SI 0 "register_operand" "=S"))
18705 (clobber (match_operand:SI 1 "register_operand" "=D"))
18706 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18707 "!TARGET_64BIT"
18708 "repz{\;| }cmpsb"
18709 [(set_attr "type" "str")
18710 (set_attr "mode" "QI")
18711 (set_attr "prefix_rep" "1")])
18712
18713(define_insn "*cmpstrnqi_rex_1"
18714 [(set (reg:CC FLAGS_REG)
18715 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18716 (const_int 0))
18717 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18718 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18719 (const_int 0)))
18720 (use (match_operand:SI 3 "immediate_operand" "i"))
18721 (use (reg:CC FLAGS_REG))
18722 (use (reg:SI DIRFLAG_REG))
18723 (clobber (match_operand:DI 0 "register_operand" "=S"))
18724 (clobber (match_operand:DI 1 "register_operand" "=D"))
18725 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18726 "TARGET_64BIT"
18727 "repz{\;| }cmpsb"
18728 [(set_attr "type" "str")
18729 (set_attr "mode" "QI")
18730 (set_attr "prefix_rep" "1")])
18731
18732(define_expand "strlensi"
18733 [(set (match_operand:SI 0 "register_operand" "")
18734 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18735 (match_operand:QI 2 "immediate_operand" "")
18736 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18737 ""
18738{
18739 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18740 DONE;
18741 else
18742 FAIL;
18743})
18744
18745(define_expand "strlendi"
18746 [(set (match_operand:DI 0 "register_operand" "")
18747 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18748 (match_operand:QI 2 "immediate_operand" "")
18749 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18750 ""
18751{
18752 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18753 DONE;
18754 else
18755 FAIL;
18756})
18757
18758(define_expand "strlenqi_1"
18759 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18760 (use (reg:SI DIRFLAG_REG))
18761 (clobber (match_operand 1 "register_operand" ""))
18762 (clobber (reg:CC FLAGS_REG))])]
18763 ""
18764 "")
18765
18766(define_insn "*strlenqi_1"
18767 [(set (match_operand:SI 0 "register_operand" "=&c")
18768 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18769 (match_operand:QI 2 "register_operand" "a")
18770 (match_operand:SI 3 "immediate_operand" "i")
18771 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18772 (use (reg:SI DIRFLAG_REG))
18773 (clobber (match_operand:SI 1 "register_operand" "=D"))
18774 (clobber (reg:CC FLAGS_REG))]
18775 "!TARGET_64BIT"
18776 "repnz{\;| }scasb"
18777 [(set_attr "type" "str")
18778 (set_attr "mode" "QI")
18779 (set_attr "prefix_rep" "1")])
18780
18781(define_insn "*strlenqi_rex_1"
18782 [(set (match_operand:DI 0 "register_operand" "=&c")
18783 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18784 (match_operand:QI 2 "register_operand" "a")
18785 (match_operand:DI 3 "immediate_operand" "i")
18786 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18787 (use (reg:SI DIRFLAG_REG))
18788 (clobber (match_operand:DI 1 "register_operand" "=D"))
18789 (clobber (reg:CC FLAGS_REG))]
18790 "TARGET_64BIT"
18791 "repnz{\;| }scasb"
18792 [(set_attr "type" "str")
18793 (set_attr "mode" "QI")
18794 (set_attr "prefix_rep" "1")])
18795
18796;; Peephole optimizations to clean up after cmpstrn*. This should be
18797;; handled in combine, but it is not currently up to the task.
18798;; When used for their truth value, the cmpstrn* expanders generate
18799;; code like this:
18800;;
18801;; repz cmpsb
18802;; seta %al
18803;; setb %dl
18804;; cmpb %al, %dl
18805;; jcc label
18806;;
18807;; The intermediate three instructions are unnecessary.
18808
18809;; This one handles cmpstrn*_nz_1...
18810(define_peephole2
18811 [(parallel[
18812 (set (reg:CC FLAGS_REG)
18813 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18814 (mem:BLK (match_operand 5 "register_operand" ""))))
18815 (use (match_operand 6 "register_operand" ""))
18816 (use (match_operand:SI 3 "immediate_operand" ""))
18817 (use (reg:SI DIRFLAG_REG))
18818 (clobber (match_operand 0 "register_operand" ""))
18819 (clobber (match_operand 1 "register_operand" ""))
18820 (clobber (match_operand 2 "register_operand" ""))])
18821 (set (match_operand:QI 7 "register_operand" "")
18822 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18823 (set (match_operand:QI 8 "register_operand" "")
18824 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18825 (set (reg FLAGS_REG)
18826 (compare (match_dup 7) (match_dup 8)))
18827 ]
18828 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18829 [(parallel[
18830 (set (reg:CC FLAGS_REG)
18831 (compare:CC (mem:BLK (match_dup 4))
18832 (mem:BLK (match_dup 5))))
18833 (use (match_dup 6))
18834 (use (match_dup 3))
18835 (use (reg:SI DIRFLAG_REG))
18836 (clobber (match_dup 0))
18837 (clobber (match_dup 1))
18838 (clobber (match_dup 2))])]
18839 "")
18840
18841;; ...and this one handles cmpstrn*_1.
18842(define_peephole2
18843 [(parallel[
18844 (set (reg:CC FLAGS_REG)
18845 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18846 (const_int 0))
18847 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18848 (mem:BLK (match_operand 5 "register_operand" "")))
18849 (const_int 0)))
18850 (use (match_operand:SI 3 "immediate_operand" ""))
18851 (use (reg:CC FLAGS_REG))
18852 (use (reg:SI DIRFLAG_REG))
18853 (clobber (match_operand 0 "register_operand" ""))
18854 (clobber (match_operand 1 "register_operand" ""))
18855 (clobber (match_operand 2 "register_operand" ""))])
18856 (set (match_operand:QI 7 "register_operand" "")
18857 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18858 (set (match_operand:QI 8 "register_operand" "")
18859 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18860 (set (reg FLAGS_REG)
18861 (compare (match_dup 7) (match_dup 8)))
18862 ]
18863 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18864 [(parallel[
18865 (set (reg:CC FLAGS_REG)
18866 (if_then_else:CC (ne (match_dup 6)
18867 (const_int 0))
18868 (compare:CC (mem:BLK (match_dup 4))
18869 (mem:BLK (match_dup 5)))
18870 (const_int 0)))
18871 (use (match_dup 3))
18872 (use (reg:CC FLAGS_REG))
18873 (use (reg:SI DIRFLAG_REG))
18874 (clobber (match_dup 0))
18875 (clobber (match_dup 1))
18876 (clobber (match_dup 2))])]
18877 "")
18878
18879
18880
18881;; Conditional move instructions.
18882
18883(define_expand "movdicc"
18884 [(set (match_operand:DI 0 "register_operand" "")
18885 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18886 (match_operand:DI 2 "general_operand" "")
18887 (match_operand:DI 3 "general_operand" "")))]
18888 "TARGET_64BIT"
18889 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18890
18891(define_insn "x86_movdicc_0_m1_rex64"
18892 [(set (match_operand:DI 0 "register_operand" "=r")
18893 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18894 (const_int -1)
18895 (const_int 0)))
18896 (clobber (reg:CC FLAGS_REG))]
18897 "TARGET_64BIT"
18898 "sbb{q}\t%0, %0"
18899 ; Since we don't have the proper number of operands for an alu insn,
18900 ; fill in all the blanks.
18901 [(set_attr "type" "alu")
18902 (set_attr "pent_pair" "pu")
18903 (set_attr "memory" "none")
18904 (set_attr "imm_disp" "false")
18905 (set_attr "mode" "DI")
18906 (set_attr "length_immediate" "0")])
18907
18908(define_insn "*movdicc_c_rex64"
18909 [(set (match_operand:DI 0 "register_operand" "=r,r")
18910 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18911 [(reg FLAGS_REG) (const_int 0)])
18912 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18913 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18914 "TARGET_64BIT && TARGET_CMOVE
18915 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18916 "@
18917 cmov%O2%C1\t{%2, %0|%0, %2}
18918 cmov%O2%c1\t{%3, %0|%0, %3}"
18919 [(set_attr "type" "icmov")
18920 (set_attr "mode" "DI")])
18921
18922(define_expand "movsicc"
18923 [(set (match_operand:SI 0 "register_operand" "")
18924 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18925 (match_operand:SI 2 "general_operand" "")
18926 (match_operand:SI 3 "general_operand" "")))]
18927 ""
18928 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18929
18930;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18931;; the register first winds up with `sbbl $0,reg', which is also weird.
18932;; So just document what we're doing explicitly.
18933
18934(define_insn "x86_movsicc_0_m1"
18935 [(set (match_operand:SI 0 "register_operand" "=r")
18936 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18937 (const_int -1)
18938 (const_int 0)))
18939 (clobber (reg:CC FLAGS_REG))]
18940 ""
18941 "sbb{l}\t%0, %0"
18942 ; Since we don't have the proper number of operands for an alu insn,
18943 ; fill in all the blanks.
18944 [(set_attr "type" "alu")
18945 (set_attr "pent_pair" "pu")
18946 (set_attr "memory" "none")
18947 (set_attr "imm_disp" "false")
18948 (set_attr "mode" "SI")
18949 (set_attr "length_immediate" "0")])
18950
18951(define_insn "*movsicc_noc"
18952 [(set (match_operand:SI 0 "register_operand" "=r,r")
18953 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18954 [(reg FLAGS_REG) (const_int 0)])
18955 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18956 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18957 "TARGET_CMOVE
18958 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18959 "@
18960 cmov%O2%C1\t{%2, %0|%0, %2}
18961 cmov%O2%c1\t{%3, %0|%0, %3}"
18962 [(set_attr "type" "icmov")
18963 (set_attr "mode" "SI")])
18964
18965(define_expand "movhicc"
18966 [(set (match_operand:HI 0 "register_operand" "")
18967 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18968 (match_operand:HI 2 "general_operand" "")
18969 (match_operand:HI 3 "general_operand" "")))]
18970 "TARGET_HIMODE_MATH"
18971 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18972
18973(define_insn "*movhicc_noc"
18974 [(set (match_operand:HI 0 "register_operand" "=r,r")
18975 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18976 [(reg FLAGS_REG) (const_int 0)])
18977 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18978 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18979 "TARGET_CMOVE
18980 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18981 "@
18982 cmov%O2%C1\t{%2, %0|%0, %2}
18983 cmov%O2%c1\t{%3, %0|%0, %3}"
18984 [(set_attr "type" "icmov")
18985 (set_attr "mode" "HI")])
18986
18987(define_expand "movqicc"
18988 [(set (match_operand:QI 0 "register_operand" "")
18989 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18990 (match_operand:QI 2 "general_operand" "")
18991 (match_operand:QI 3 "general_operand" "")))]
18992 "TARGET_QIMODE_MATH"
18993 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18994
18995(define_insn_and_split "*movqicc_noc"
18996 [(set (match_operand:QI 0 "register_operand" "=r,r")
18997 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18998 [(match_operand 4 "flags_reg_operand" "")
18999 (const_int 0)])
19000 (match_operand:QI 2 "register_operand" "r,0")
19001 (match_operand:QI 3 "register_operand" "0,r")))]
19002 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19003 "#"
19004 "&& reload_completed"
19005 [(set (match_dup 0)
19006 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19007 (match_dup 2)
19008 (match_dup 3)))]
19009 "operands[0] = gen_lowpart (SImode, operands[0]);
19010 operands[2] = gen_lowpart (SImode, operands[2]);
19011 operands[3] = gen_lowpart (SImode, operands[3]);"
19012 [(set_attr "type" "icmov")
19013 (set_attr "mode" "SI")])
19014
19015(define_expand "movsfcc"
19016 [(set (match_operand:SF 0 "register_operand" "")
19017 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19018 (match_operand:SF 2 "register_operand" "")
19019 (match_operand:SF 3 "register_operand" "")))]
19020 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19021 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19022
19023(define_insn "*movsfcc_1_387"
19024 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19025 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19026 [(reg FLAGS_REG) (const_int 0)])
19027 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19028 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19029 "TARGET_80387 && TARGET_CMOVE
19030 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19031 "@
19032 fcmov%F1\t{%2, %0|%0, %2}
19033 fcmov%f1\t{%3, %0|%0, %3}
19034 cmov%O2%C1\t{%2, %0|%0, %2}
19035 cmov%O2%c1\t{%3, %0|%0, %3}"
19036 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19037 (set_attr "mode" "SF,SF,SI,SI")])
19038
19039(define_expand "movdfcc"
19040 [(set (match_operand:DF 0 "register_operand" "")
19041 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19042 (match_operand:DF 2 "register_operand" "")
19043 (match_operand:DF 3 "register_operand" "")))]
19044 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19045 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19046
19047(define_insn "*movdfcc_1"
19048 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19049 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19050 [(reg FLAGS_REG) (const_int 0)])
19051 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19052 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19053 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19054 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19055 "@
19056 fcmov%F1\t{%2, %0|%0, %2}
19057 fcmov%f1\t{%3, %0|%0, %3}
19058 #
19059 #"
19060 [(set_attr "type" "fcmov,fcmov,multi,multi")
19061 (set_attr "mode" "DF")])
19062
19063(define_insn "*movdfcc_1_rex64"
19064 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19065 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19066 [(reg FLAGS_REG) (const_int 0)])
19067 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19068 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19069 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19070 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19071 "@
19072 fcmov%F1\t{%2, %0|%0, %2}
19073 fcmov%f1\t{%3, %0|%0, %3}
19074 cmov%O2%C1\t{%2, %0|%0, %2}
19075 cmov%O2%c1\t{%3, %0|%0, %3}"
19076 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19077 (set_attr "mode" "DF")])
19078
19079(define_split
19080 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19081 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19082 [(match_operand 4 "flags_reg_operand" "")
19083 (const_int 0)])
19084 (match_operand:DF 2 "nonimmediate_operand" "")
19085 (match_operand:DF 3 "nonimmediate_operand" "")))]
19086 "!TARGET_64BIT && reload_completed"
19087 [(set (match_dup 2)
19088 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19089 (match_dup 5)
19090 (match_dup 7)))
19091 (set (match_dup 3)
19092 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19093 (match_dup 6)
19094 (match_dup 8)))]
19095 "split_di (operands+2, 1, operands+5, operands+6);
19096 split_di (operands+3, 1, operands+7, operands+8);
19097 split_di (operands, 1, operands+2, operands+3);")
19098
19099(define_expand "movxfcc"
19100 [(set (match_operand:XF 0 "register_operand" "")
19101 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19102 (match_operand:XF 2 "register_operand" "")
19103 (match_operand:XF 3 "register_operand" "")))]
19104 "TARGET_80387 && TARGET_CMOVE"
19105 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19106
19107(define_insn "*movxfcc_1"
19108 [(set (match_operand:XF 0 "register_operand" "=f,f")
19109 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19110 [(reg FLAGS_REG) (const_int 0)])
19111 (match_operand:XF 2 "register_operand" "f,0")
19112 (match_operand:XF 3 "register_operand" "0,f")))]
19113 "TARGET_80387 && TARGET_CMOVE"
19114 "@
19115 fcmov%F1\t{%2, %0|%0, %2}
19116 fcmov%f1\t{%3, %0|%0, %3}"
19117 [(set_attr "type" "fcmov")
19118 (set_attr "mode" "XF")])
19119
19120;; These versions of the min/max patterns are intentionally ignorant of
19121;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19122;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19123;; are undefined in this condition, we're certain this is correct.
19124
19125(define_insn "sminsf3"
19126 [(set (match_operand:SF 0 "register_operand" "=x")
19127 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19128 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19129 "TARGET_SSE_MATH"
19130 "minss\t{%2, %0|%0, %2}"
19131 [(set_attr "type" "sseadd")
19132 (set_attr "mode" "SF")])
19133
19134(define_insn "smaxsf3"
19135 [(set (match_operand:SF 0 "register_operand" "=x")
19136 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19137 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19138 "TARGET_SSE_MATH"
19139 "maxss\t{%2, %0|%0, %2}"
19140 [(set_attr "type" "sseadd")
19141 (set_attr "mode" "SF")])
19142
19143(define_insn "smindf3"
19144 [(set (match_operand:DF 0 "register_operand" "=x")
19145 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19146 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19147 "TARGET_SSE2 && TARGET_SSE_MATH"
19148 "minsd\t{%2, %0|%0, %2}"
19149 [(set_attr "type" "sseadd")
19150 (set_attr "mode" "DF")])
19151
19152(define_insn "smaxdf3"
19153 [(set (match_operand:DF 0 "register_operand" "=x")
19154 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19155 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19156 "TARGET_SSE2 && TARGET_SSE_MATH"
19157 "maxsd\t{%2, %0|%0, %2}"
19158 [(set_attr "type" "sseadd")
19159 (set_attr "mode" "DF")])
19160
19161;; These versions of the min/max patterns implement exactly the operations
19162;; min = (op1 < op2 ? op1 : op2)
19163;; max = (!(op1 < op2) ? op1 : op2)
19164;; Their operands are not commutative, and thus they may be used in the
19165;; presence of -0.0 and NaN.
19166
19167(define_insn "*ieee_sminsf3"
19168 [(set (match_operand:SF 0 "register_operand" "=x")
19169 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19170 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19171 UNSPEC_IEEE_MIN))]
19172 "TARGET_SSE_MATH"
19173 "minss\t{%2, %0|%0, %2}"
19174 [(set_attr "type" "sseadd")
19175 (set_attr "mode" "SF")])
19176
19177(define_insn "*ieee_smaxsf3"
19178 [(set (match_operand:SF 0 "register_operand" "=x")
19179 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19180 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19181 UNSPEC_IEEE_MAX))]
19182 "TARGET_SSE_MATH"
19183 "maxss\t{%2, %0|%0, %2}"
19184 [(set_attr "type" "sseadd")
19185 (set_attr "mode" "SF")])
19186
19187(define_insn "*ieee_smindf3"
19188 [(set (match_operand:DF 0 "register_operand" "=x")
19189 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19190 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19191 UNSPEC_IEEE_MIN))]
19192 "TARGET_SSE2 && TARGET_SSE_MATH"
19193 "minsd\t{%2, %0|%0, %2}"
19194 [(set_attr "type" "sseadd")
19195 (set_attr "mode" "DF")])
19196
19197(define_insn "*ieee_smaxdf3"
19198 [(set (match_operand:DF 0 "register_operand" "=x")
19199 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19200 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19201 UNSPEC_IEEE_MAX))]
19202 "TARGET_SSE2 && TARGET_SSE_MATH"
19203 "maxsd\t{%2, %0|%0, %2}"
19204 [(set_attr "type" "sseadd")
19205 (set_attr "mode" "DF")])
19206
19207;; Make two stack loads independent:
19208;; fld aa fld aa
19209;; fld %st(0) -> fld bb
19210;; fmul bb fmul %st(1), %st
19211;;
19212;; Actually we only match the last two instructions for simplicity.
19213(define_peephole2
19214 [(set (match_operand 0 "fp_register_operand" "")
19215 (match_operand 1 "fp_register_operand" ""))
19216 (set (match_dup 0)
19217 (match_operator 2 "binary_fp_operator"
19218 [(match_dup 0)
19219 (match_operand 3 "memory_operand" "")]))]
19220 "REGNO (operands[0]) != REGNO (operands[1])"
19221 [(set (match_dup 0) (match_dup 3))
19222 (set (match_dup 0) (match_dup 4))]
19223
19224 ;; The % modifier is not operational anymore in peephole2's, so we have to
19225 ;; swap the operands manually in the case of addition and multiplication.
19226 "if (COMMUTATIVE_ARITH_P (operands[2]))
19227 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19228 operands[0], operands[1]);
19229 else
19230 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19231 operands[1], operands[0]);")
19232
19233;; Conditional addition patterns
19234(define_expand "addqicc"
19235 [(match_operand:QI 0 "register_operand" "")
19236 (match_operand 1 "comparison_operator" "")
19237 (match_operand:QI 2 "register_operand" "")
19238 (match_operand:QI 3 "const_int_operand" "")]
19239 ""
19240 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19241
19242(define_expand "addhicc"
19243 [(match_operand:HI 0 "register_operand" "")
19244 (match_operand 1 "comparison_operator" "")
19245 (match_operand:HI 2 "register_operand" "")
19246 (match_operand:HI 3 "const_int_operand" "")]
19247 ""
19248 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19249
19250(define_expand "addsicc"
19251 [(match_operand:SI 0 "register_operand" "")
19252 (match_operand 1 "comparison_operator" "")
19253 (match_operand:SI 2 "register_operand" "")
19254 (match_operand:SI 3 "const_int_operand" "")]
19255 ""
19256 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19257
19258(define_expand "adddicc"
19259 [(match_operand:DI 0 "register_operand" "")
19260 (match_operand 1 "comparison_operator" "")
19261 (match_operand:DI 2 "register_operand" "")
19262 (match_operand:DI 3 "const_int_operand" "")]
19263 "TARGET_64BIT"
19264 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19265
19266
19267;; Misc patterns (?)
19268
19269;; This pattern exists to put a dependency on all ebp-based memory accesses.
19270;; Otherwise there will be nothing to keep
19271;;
19272;; [(set (reg ebp) (reg esp))]
19273;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19274;; (clobber (eflags)]
19275;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19276;;
19277;; in proper program order.
19278(define_insn "pro_epilogue_adjust_stack_1"
19279 [(set (match_operand:SI 0 "register_operand" "=r,r")
19280 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19281 (match_operand:SI 2 "immediate_operand" "i,i")))
19282 (clobber (reg:CC FLAGS_REG))
19283 (clobber (mem:BLK (scratch)))]
19284 "!TARGET_64BIT"
19285{
19286 switch (get_attr_type (insn))
19287 {
19288 case TYPE_IMOV:
19289 return "mov{l}\t{%1, %0|%0, %1}";
19290
19291 case TYPE_ALU:
19292 if (GET_CODE (operands[2]) == CONST_INT
19293 && (INTVAL (operands[2]) == 128
19294 || (INTVAL (operands[2]) < 0
19295 && INTVAL (operands[2]) != -128)))
19296 {
19297 operands[2] = GEN_INT (-INTVAL (operands[2]));
19298 return "sub{l}\t{%2, %0|%0, %2}";
19299 }
19300 return "add{l}\t{%2, %0|%0, %2}";
19301
19302 case TYPE_LEA:
19303 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19304 return "lea{l}\t{%a2, %0|%0, %a2}";
19305
19306 default:
19307 gcc_unreachable ();
19308 }
19309}
19310 [(set (attr "type")
19311 (cond [(eq_attr "alternative" "0")
19312 (const_string "alu")
19313 (match_operand:SI 2 "const0_operand" "")
19314 (const_string "imov")
19315 ]
19316 (const_string "lea")))
19317 (set_attr "mode" "SI")])
19318
19319(define_insn "pro_epilogue_adjust_stack_rex64"
19320 [(set (match_operand:DI 0 "register_operand" "=r,r")
19321 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19322 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19323 (clobber (reg:CC FLAGS_REG))
19324 (clobber (mem:BLK (scratch)))]
19325 "TARGET_64BIT"
19326{
19327 switch (get_attr_type (insn))
19328 {
19329 case TYPE_IMOV:
19330 return "mov{q}\t{%1, %0|%0, %1}";
19331
19332 case TYPE_ALU:
19333 if (GET_CODE (operands[2]) == CONST_INT
19334 /* Avoid overflows. */
19335 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19336 && (INTVAL (operands[2]) == 128
19337 || (INTVAL (operands[2]) < 0
19338 && INTVAL (operands[2]) != -128)))
19339 {
19340 operands[2] = GEN_INT (-INTVAL (operands[2]));
19341 return "sub{q}\t{%2, %0|%0, %2}";
19342 }
19343 return "add{q}\t{%2, %0|%0, %2}";
19344
19345 case TYPE_LEA:
19346 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19347 return "lea{q}\t{%a2, %0|%0, %a2}";
19348
19349 default:
19350 gcc_unreachable ();
19351 }
19352}
19353 [(set (attr "type")
19354 (cond [(eq_attr "alternative" "0")
19355 (const_string "alu")
19356 (match_operand:DI 2 "const0_operand" "")
19357 (const_string "imov")
19358 ]
19359 (const_string "lea")))
19360 (set_attr "mode" "DI")])
19361
19362(define_insn "pro_epilogue_adjust_stack_rex64_2"
19363 [(set (match_operand:DI 0 "register_operand" "=r,r")
19364 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19365 (match_operand:DI 3 "immediate_operand" "i,i")))
19366 (use (match_operand:DI 2 "register_operand" "r,r"))
19367 (clobber (reg:CC FLAGS_REG))
19368 (clobber (mem:BLK (scratch)))]
19369 "TARGET_64BIT"
19370{
19371 switch (get_attr_type (insn))
19372 {
19373 case TYPE_ALU:
19374 return "add{q}\t{%2, %0|%0, %2}";
19375
19376 case TYPE_LEA:
19377 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19378 return "lea{q}\t{%a2, %0|%0, %a2}";
19379
19380 default:
19381 gcc_unreachable ();
19382 }
19383}
19384 [(set_attr "type" "alu,lea")
19385 (set_attr "mode" "DI")])
19386
19387(define_expand "allocate_stack_worker"
19388 [(match_operand:SI 0 "register_operand" "")]
19389 "TARGET_STACK_PROBE"
19390{
19391 if (reload_completed)
19392 {
19393 if (TARGET_64BIT)
19394 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19395 else
19396 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19397 }
19398 else
19399 {
19400 if (TARGET_64BIT)
19401 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19402 else
19403 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19404 }
19405 DONE;
19406})
19407
19408(define_insn "allocate_stack_worker_1"
19409 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19410 UNSPECV_STACK_PROBE)
19411 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19412 (clobber (match_scratch:SI 1 "=0"))
19413 (clobber (reg:CC FLAGS_REG))]
19414 "!TARGET_64BIT && TARGET_STACK_PROBE"
19415 "call\t__alloca"
19416 [(set_attr "type" "multi")
19417 (set_attr "length" "5")])
19418
19419(define_expand "allocate_stack_worker_postreload"
19420 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19421 UNSPECV_STACK_PROBE)
19422 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19423 (clobber (match_dup 0))
19424 (clobber (reg:CC FLAGS_REG))])]
19425 ""
19426 "")
19427
19428(define_insn "allocate_stack_worker_rex64"
19429 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19430 UNSPECV_STACK_PROBE)
19431 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19432 (clobber (match_scratch:DI 1 "=0"))
19433 (clobber (reg:CC FLAGS_REG))]
19434 "TARGET_64BIT && TARGET_STACK_PROBE"
19435 "call\t__alloca"
19436 [(set_attr "type" "multi")
19437 (set_attr "length" "5")])
19438
19439(define_expand "allocate_stack_worker_rex64_postreload"
19440 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19441 UNSPECV_STACK_PROBE)
19442 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19443 (clobber (match_dup 0))
19444 (clobber (reg:CC FLAGS_REG))])]
19445 ""
19446 "")
19447
19448(define_expand "allocate_stack"
19449 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19450 (minus:SI (reg:SI SP_REG)
19451 (match_operand:SI 1 "general_operand" "")))
19452 (clobber (reg:CC FLAGS_REG))])
19453 (parallel [(set (reg:SI SP_REG)
19454 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19455 (clobber (reg:CC FLAGS_REG))])]
19456 "TARGET_STACK_PROBE"
19457{
19458#ifdef CHECK_STACK_LIMIT
19459 if (GET_CODE (operands[1]) == CONST_INT
19460 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19461 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19462 operands[1]));
19463 else
19464#endif
19465 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19466 operands[1])));
19467
19468 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19469 DONE;
19470})
19471
19472(define_expand "builtin_setjmp_receiver"
19473 [(label_ref (match_operand 0 "" ""))]
19474 "!TARGET_64BIT && flag_pic"
19475{
19476 if (TARGET_MACHO)
19477 {
19478 rtx xops[3];
19479 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19480 rtx label_rtx = gen_label_rtx ();
19481 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19482 xops[0] = xops[1] = picreg;
19483 xops[2] = gen_rtx_CONST (SImode,
19484 gen_rtx_MINUS (SImode,
19485 gen_rtx_LABEL_REF (SImode, label_rtx),
19486 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19487 ix86_expand_binary_operator (MINUS, SImode, xops);
19488 }
19489 else
19490 emit_insn (gen_set_got (pic_offset_table_rtx));
19491 DONE;
19492})
19493
19494;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19495
19496(define_split
19497 [(set (match_operand 0 "register_operand" "")
19498 (match_operator 3 "promotable_binary_operator"
19499 [(match_operand 1 "register_operand" "")
19500 (match_operand 2 "aligned_operand" "")]))
19501 (clobber (reg:CC FLAGS_REG))]
19502 "! TARGET_PARTIAL_REG_STALL && reload_completed
19503 && ((GET_MODE (operands[0]) == HImode
19504 && ((!optimize_size && !TARGET_FAST_PREFIX)
19505 /* ??? next two lines just !satisfies_constraint_K (...) */
19506 || GET_CODE (operands[2]) != CONST_INT
19507 || satisfies_constraint_K (operands[2])))
19508 || (GET_MODE (operands[0]) == QImode
19509 && (TARGET_PROMOTE_QImode || optimize_size)))"
19510 [(parallel [(set (match_dup 0)
19511 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19512 (clobber (reg:CC FLAGS_REG))])]
19513 "operands[0] = gen_lowpart (SImode, operands[0]);
19514 operands[1] = gen_lowpart (SImode, operands[1]);
19515 if (GET_CODE (operands[3]) != ASHIFT)
19516 operands[2] = gen_lowpart (SImode, operands[2]);
19517 PUT_MODE (operands[3], SImode);")
19518
19519; Promote the QImode tests, as i386 has encoding of the AND
19520; instruction with 32-bit sign-extended immediate and thus the
19521; instruction size is unchanged, except in the %eax case for
19522; which it is increased by one byte, hence the ! optimize_size.
19523(define_split
19524 [(set (match_operand 0 "flags_reg_operand" "")
19525 (match_operator 2 "compare_operator"
19526 [(and (match_operand 3 "aligned_operand" "")
19527 (match_operand 4 "const_int_operand" ""))
19528 (const_int 0)]))
19529 (set (match_operand 1 "register_operand" "")
19530 (and (match_dup 3) (match_dup 4)))]
19531 "! TARGET_PARTIAL_REG_STALL && reload_completed
19532 /* Ensure that the operand will remain sign-extended immediate. */
19533 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19534 && ! optimize_size
19535 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19536 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19537 [(parallel [(set (match_dup 0)
19538 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19539 (const_int 0)]))
19540 (set (match_dup 1)
19541 (and:SI (match_dup 3) (match_dup 4)))])]
19542{
19543 operands[4]
19544 = gen_int_mode (INTVAL (operands[4])
19545 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19546 operands[1] = gen_lowpart (SImode, operands[1]);
19547 operands[3] = gen_lowpart (SImode, operands[3]);
19548})
19549
19550; Don't promote the QImode tests, as i386 doesn't have encoding of
19551; the TEST instruction with 32-bit sign-extended immediate and thus
19552; the instruction size would at least double, which is not what we
19553; want even with ! optimize_size.
19554(define_split
19555 [(set (match_operand 0 "flags_reg_operand" "")
19556 (match_operator 1 "compare_operator"
19557 [(and (match_operand:HI 2 "aligned_operand" "")
19558 (match_operand:HI 3 "const_int_operand" ""))
19559 (const_int 0)]))]
19560 "! TARGET_PARTIAL_REG_STALL && reload_completed
19561 /* Ensure that the operand will remain sign-extended immediate. */
19562 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19563 && ! TARGET_FAST_PREFIX
19564 && ! optimize_size"
19565 [(set (match_dup 0)
19566 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19567 (const_int 0)]))]
19568{
19569 operands[3]
19570 = gen_int_mode (INTVAL (operands[3])
19571 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19572 operands[2] = gen_lowpart (SImode, operands[2]);
19573})
19574
19575(define_split
19576 [(set (match_operand 0 "register_operand" "")
19577 (neg (match_operand 1 "register_operand" "")))
19578 (clobber (reg:CC FLAGS_REG))]
19579 "! TARGET_PARTIAL_REG_STALL && reload_completed
19580 && (GET_MODE (operands[0]) == HImode
19581 || (GET_MODE (operands[0]) == QImode
19582 && (TARGET_PROMOTE_QImode || optimize_size)))"
19583 [(parallel [(set (match_dup 0)
19584 (neg:SI (match_dup 1)))
19585 (clobber (reg:CC FLAGS_REG))])]
19586 "operands[0] = gen_lowpart (SImode, operands[0]);
19587 operands[1] = gen_lowpart (SImode, operands[1]);")
19588
19589(define_split
19590 [(set (match_operand 0 "register_operand" "")
19591 (not (match_operand 1 "register_operand" "")))]
19592 "! TARGET_PARTIAL_REG_STALL && reload_completed
19593 && (GET_MODE (operands[0]) == HImode
19594 || (GET_MODE (operands[0]) == QImode
19595 && (TARGET_PROMOTE_QImode || optimize_size)))"
19596 [(set (match_dup 0)
19597 (not:SI (match_dup 1)))]
19598 "operands[0] = gen_lowpart (SImode, operands[0]);
19599 operands[1] = gen_lowpart (SImode, operands[1]);")
19600
19601(define_split
19602 [(set (match_operand 0 "register_operand" "")
19603 (if_then_else (match_operator 1 "comparison_operator"
19604 [(reg FLAGS_REG) (const_int 0)])
19605 (match_operand 2 "register_operand" "")
19606 (match_operand 3 "register_operand" "")))]
19607 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19608 && (GET_MODE (operands[0]) == HImode
19609 || (GET_MODE (operands[0]) == QImode
19610 && (TARGET_PROMOTE_QImode || optimize_size)))"
19611 [(set (match_dup 0)
19612 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19613 "operands[0] = gen_lowpart (SImode, operands[0]);
19614 operands[2] = gen_lowpart (SImode, operands[2]);
19615 operands[3] = gen_lowpart (SImode, operands[3]);")
19616
19617
19618;; RTL Peephole optimizations, run before sched2. These primarily look to
19619;; transform a complex memory operation into two memory to register operations.
19620
19621;; Don't push memory operands
19622(define_peephole2
19623 [(set (match_operand:SI 0 "push_operand" "")
19624 (match_operand:SI 1 "memory_operand" ""))
19625 (match_scratch:SI 2 "r")]
19626 "!optimize_size && !TARGET_PUSH_MEMORY
19627 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19628 [(set (match_dup 2) (match_dup 1))
19629 (set (match_dup 0) (match_dup 2))]
19630 "")
19631
19632(define_peephole2
19633 [(set (match_operand:DI 0 "push_operand" "")
19634 (match_operand:DI 1 "memory_operand" ""))
19635 (match_scratch:DI 2 "r")]
19636 "!optimize_size && !TARGET_PUSH_MEMORY
19637 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19638 [(set (match_dup 2) (match_dup 1))
19639 (set (match_dup 0) (match_dup 2))]
19640 "")
19641
19642;; We need to handle SFmode only, because DFmode and XFmode is split to
19643;; SImode pushes.
19644(define_peephole2
19645 [(set (match_operand:SF 0 "push_operand" "")
19646 (match_operand:SF 1 "memory_operand" ""))
19647 (match_scratch:SF 2 "r")]
19648 "!optimize_size && !TARGET_PUSH_MEMORY
19649 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19650 [(set (match_dup 2) (match_dup 1))
19651 (set (match_dup 0) (match_dup 2))]
19652 "")
19653
19654(define_peephole2
19655 [(set (match_operand:HI 0 "push_operand" "")
19656 (match_operand:HI 1 "memory_operand" ""))
19657 (match_scratch:HI 2 "r")]
19658 "!optimize_size && !TARGET_PUSH_MEMORY
19659 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19660 [(set (match_dup 2) (match_dup 1))
19661 (set (match_dup 0) (match_dup 2))]
19662 "")
19663
19664(define_peephole2
19665 [(set (match_operand:QI 0 "push_operand" "")
19666 (match_operand:QI 1 "memory_operand" ""))
19667 (match_scratch:QI 2 "q")]
19668 "!optimize_size && !TARGET_PUSH_MEMORY
19669 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19670 [(set (match_dup 2) (match_dup 1))
19671 (set (match_dup 0) (match_dup 2))]
19672 "")
19673
19674;; Don't move an immediate directly to memory when the instruction
19675;; gets too big.
19676(define_peephole2
19677 [(match_scratch:SI 1 "r")
19678 (set (match_operand:SI 0 "memory_operand" "")
19679 (const_int 0))]
19680 "! optimize_size
19681 && ! TARGET_USE_MOV0
19682 && TARGET_SPLIT_LONG_MOVES
19683 && get_attr_length (insn) >= ix86_cost->large_insn
19684 && peep2_regno_dead_p (0, FLAGS_REG)"
19685 [(parallel [(set (match_dup 1) (const_int 0))
19686 (clobber (reg:CC FLAGS_REG))])
19687 (set (match_dup 0) (match_dup 1))]
19688 "")
19689
19690(define_peephole2
19691 [(match_scratch:HI 1 "r")
19692 (set (match_operand:HI 0 "memory_operand" "")
19693 (const_int 0))]
19694 "! optimize_size
19695 && ! TARGET_USE_MOV0
19696 && TARGET_SPLIT_LONG_MOVES
19697 && get_attr_length (insn) >= ix86_cost->large_insn
19698 && peep2_regno_dead_p (0, FLAGS_REG)"
19699 [(parallel [(set (match_dup 2) (const_int 0))
19700 (clobber (reg:CC FLAGS_REG))])
19701 (set (match_dup 0) (match_dup 1))]
19702 "operands[2] = gen_lowpart (SImode, operands[1]);")
19703
19704(define_peephole2
19705 [(match_scratch:QI 1 "q")
19706 (set (match_operand:QI 0 "memory_operand" "")
19707 (const_int 0))]
19708 "! optimize_size
19709 && ! TARGET_USE_MOV0
19710 && TARGET_SPLIT_LONG_MOVES
19711 && get_attr_length (insn) >= ix86_cost->large_insn
19712 && peep2_regno_dead_p (0, FLAGS_REG)"
19713 [(parallel [(set (match_dup 2) (const_int 0))
19714 (clobber (reg:CC FLAGS_REG))])
19715 (set (match_dup 0) (match_dup 1))]
19716 "operands[2] = gen_lowpart (SImode, operands[1]);")
19717
19718(define_peephole2
19719 [(match_scratch:SI 2 "r")
19720 (set (match_operand:SI 0 "memory_operand" "")
19721 (match_operand:SI 1 "immediate_operand" ""))]
19722 "! optimize_size
19723 && get_attr_length (insn) >= ix86_cost->large_insn
19724 && TARGET_SPLIT_LONG_MOVES"
19725 [(set (match_dup 2) (match_dup 1))
19726 (set (match_dup 0) (match_dup 2))]
19727 "")
19728
19729(define_peephole2
19730 [(match_scratch:HI 2 "r")
19731 (set (match_operand:HI 0 "memory_operand" "")
19732 (match_operand:HI 1 "immediate_operand" ""))]
19733 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19734 && TARGET_SPLIT_LONG_MOVES"
19735 [(set (match_dup 2) (match_dup 1))
19736 (set (match_dup 0) (match_dup 2))]
19737 "")
19738
19739(define_peephole2
19740 [(match_scratch:QI 2 "q")
19741 (set (match_operand:QI 0 "memory_operand" "")
19742 (match_operand:QI 1 "immediate_operand" ""))]
19743 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19744 && TARGET_SPLIT_LONG_MOVES"
19745 [(set (match_dup 2) (match_dup 1))
19746 (set (match_dup 0) (match_dup 2))]
19747 "")
19748
19749;; Don't compare memory with zero, load and use a test instead.
19750(define_peephole2
19751 [(set (match_operand 0 "flags_reg_operand" "")
19752 (match_operator 1 "compare_operator"
19753 [(match_operand:SI 2 "memory_operand" "")
19754 (const_int 0)]))
19755 (match_scratch:SI 3 "r")]
19756 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19757 [(set (match_dup 3) (match_dup 2))
19758 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19759 "")
19760
19761;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19762;; Don't split NOTs with a displacement operand, because resulting XOR
19763;; will not be pairable anyway.
19764;;
19765;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19766;; represented using a modRM byte. The XOR replacement is long decoded,
19767;; so this split helps here as well.
19768;;
19769;; Note: Can't do this as a regular split because we can't get proper
19770;; lifetime information then.
19771
19772(define_peephole2
19773 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19774 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19775 "!optimize_size
19776 && peep2_regno_dead_p (0, FLAGS_REG)
19777 && ((TARGET_PENTIUM
19778 && (GET_CODE (operands[0]) != MEM
19779 || !memory_displacement_operand (operands[0], SImode)))
19780 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19781 [(parallel [(set (match_dup 0)
19782 (xor:SI (match_dup 1) (const_int -1)))
19783 (clobber (reg:CC FLAGS_REG))])]
19784 "")
19785
19786(define_peephole2
19787 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19788 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19789 "!optimize_size
19790 && peep2_regno_dead_p (0, FLAGS_REG)
19791 && ((TARGET_PENTIUM
19792 && (GET_CODE (operands[0]) != MEM
19793 || !memory_displacement_operand (operands[0], HImode)))
19794 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19795 [(parallel [(set (match_dup 0)
19796 (xor:HI (match_dup 1) (const_int -1)))
19797 (clobber (reg:CC FLAGS_REG))])]
19798 "")
19799
19800(define_peephole2
19801 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19802 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19803 "!optimize_size
19804 && peep2_regno_dead_p (0, FLAGS_REG)
19805 && ((TARGET_PENTIUM
19806 && (GET_CODE (operands[0]) != MEM
19807 || !memory_displacement_operand (operands[0], QImode)))
19808 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19809 [(parallel [(set (match_dup 0)
19810 (xor:QI (match_dup 1) (const_int -1)))
19811 (clobber (reg:CC FLAGS_REG))])]
19812 "")
19813
19814;; Non pairable "test imm, reg" instructions can be translated to
19815;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19816;; byte opcode instead of two, have a short form for byte operands),
19817;; so do it for other CPUs as well. Given that the value was dead,
19818;; this should not create any new dependencies. Pass on the sub-word
19819;; versions if we're concerned about partial register stalls.
19820
19821(define_peephole2
19822 [(set (match_operand 0 "flags_reg_operand" "")
19823 (match_operator 1 "compare_operator"
19824 [(and:SI (match_operand:SI 2 "register_operand" "")
19825 (match_operand:SI 3 "immediate_operand" ""))
19826 (const_int 0)]))]
19827 "ix86_match_ccmode (insn, CCNOmode)
19828 && (true_regnum (operands[2]) != 0
19829 || satisfies_constraint_K (operands[3]))
19830 && peep2_reg_dead_p (1, operands[2])"
19831 [(parallel
19832 [(set (match_dup 0)
19833 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19834 (const_int 0)]))
19835 (set (match_dup 2)
19836 (and:SI (match_dup 2) (match_dup 3)))])]
19837 "")
19838
19839;; We don't need to handle HImode case, because it will be promoted to SImode
19840;; on ! TARGET_PARTIAL_REG_STALL
19841
19842(define_peephole2
19843 [(set (match_operand 0 "flags_reg_operand" "")
19844 (match_operator 1 "compare_operator"
19845 [(and:QI (match_operand:QI 2 "register_operand" "")
19846 (match_operand:QI 3 "immediate_operand" ""))
19847 (const_int 0)]))]
19848 "! TARGET_PARTIAL_REG_STALL
19849 && ix86_match_ccmode (insn, CCNOmode)
19850 && true_regnum (operands[2]) != 0
19851 && peep2_reg_dead_p (1, operands[2])"
19852 [(parallel
19853 [(set (match_dup 0)
19854 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19855 (const_int 0)]))
19856 (set (match_dup 2)
19857 (and:QI (match_dup 2) (match_dup 3)))])]
19858 "")
19859
19860(define_peephole2
19861 [(set (match_operand 0 "flags_reg_operand" "")
19862 (match_operator 1 "compare_operator"
19863 [(and:SI
19864 (zero_extract:SI
19865 (match_operand 2 "ext_register_operand" "")
19866 (const_int 8)
19867 (const_int 8))
19868 (match_operand 3 "const_int_operand" ""))
19869 (const_int 0)]))]
19870 "! TARGET_PARTIAL_REG_STALL
19871 && ix86_match_ccmode (insn, CCNOmode)
19872 && true_regnum (operands[2]) != 0
19873 && peep2_reg_dead_p (1, operands[2])"
19874 [(parallel [(set (match_dup 0)
19875 (match_op_dup 1
19876 [(and:SI
19877 (zero_extract:SI
19878 (match_dup 2)
19879 (const_int 8)
19880 (const_int 8))
19881 (match_dup 3))
19882 (const_int 0)]))
19883 (set (zero_extract:SI (match_dup 2)
19884 (const_int 8)
19885 (const_int 8))
19886 (and:SI
19887 (zero_extract:SI
19888 (match_dup 2)
19889 (const_int 8)
19890 (const_int 8))
19891 (match_dup 3)))])]
19892 "")
19893
19894;; Don't do logical operations with memory inputs.
19895(define_peephole2
19896 [(match_scratch:SI 2 "r")
19897 (parallel [(set (match_operand:SI 0 "register_operand" "")
19898 (match_operator:SI 3 "arith_or_logical_operator"
19899 [(match_dup 0)
19900 (match_operand:SI 1 "memory_operand" "")]))
19901 (clobber (reg:CC FLAGS_REG))])]
19902 "! optimize_size && ! TARGET_READ_MODIFY"
19903 [(set (match_dup 2) (match_dup 1))
19904 (parallel [(set (match_dup 0)
19905 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19906 (clobber (reg:CC FLAGS_REG))])]
19907 "")
19908
19909(define_peephole2
19910 [(match_scratch:SI 2 "r")
19911 (parallel [(set (match_operand:SI 0 "register_operand" "")
19912 (match_operator:SI 3 "arith_or_logical_operator"
19913 [(match_operand:SI 1 "memory_operand" "")
19914 (match_dup 0)]))
19915 (clobber (reg:CC FLAGS_REG))])]
19916 "! optimize_size && ! TARGET_READ_MODIFY"
19917 [(set (match_dup 2) (match_dup 1))
19918 (parallel [(set (match_dup 0)
19919 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19920 (clobber (reg:CC FLAGS_REG))])]
19921 "")
19922
19923; Don't do logical operations with memory outputs
19924;
19925; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19926; instruction into two 1-uop insns plus a 2-uop insn. That last has
19927; the same decoder scheduling characteristics as the original.
19928
19929(define_peephole2
19930 [(match_scratch:SI 2 "r")
19931 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19932 (match_operator:SI 3 "arith_or_logical_operator"
19933 [(match_dup 0)
19934 (match_operand:SI 1 "nonmemory_operand" "")]))
19935 (clobber (reg:CC FLAGS_REG))])]
19936 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19937 [(set (match_dup 2) (match_dup 0))
19938 (parallel [(set (match_dup 2)
19939 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19940 (clobber (reg:CC FLAGS_REG))])
19941 (set (match_dup 0) (match_dup 2))]
19942 "")
19943
19944(define_peephole2
19945 [(match_scratch:SI 2 "r")
19946 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19947 (match_operator:SI 3 "arith_or_logical_operator"
19948 [(match_operand:SI 1 "nonmemory_operand" "")
19949 (match_dup 0)]))
19950 (clobber (reg:CC FLAGS_REG))])]
19951 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19952 [(set (match_dup 2) (match_dup 0))
19953 (parallel [(set (match_dup 2)
19954 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19955 (clobber (reg:CC FLAGS_REG))])
19956 (set (match_dup 0) (match_dup 2))]
19957 "")
19958
19959;; Attempt to always use XOR for zeroing registers.
19960(define_peephole2
19961 [(set (match_operand 0 "register_operand" "")
19962 (match_operand 1 "const0_operand" ""))]
19963 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19964 && (! TARGET_USE_MOV0 || optimize_size)
19965 && GENERAL_REG_P (operands[0])
19966 && peep2_regno_dead_p (0, FLAGS_REG)"
19967 [(parallel [(set (match_dup 0) (const_int 0))
19968 (clobber (reg:CC FLAGS_REG))])]
19969{
19970 operands[0] = gen_lowpart (word_mode, operands[0]);
19971})
19972
19973(define_peephole2
19974 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19975 (const_int 0))]
19976 "(GET_MODE (operands[0]) == QImode
19977 || GET_MODE (operands[0]) == HImode)
19978 && (! TARGET_USE_MOV0 || optimize_size)
19979 && peep2_regno_dead_p (0, FLAGS_REG)"
19980 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19981 (clobber (reg:CC FLAGS_REG))])])
19982
19983;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19984(define_peephole2
19985 [(set (match_operand 0 "register_operand" "")
19986 (const_int -1))]
19987 "(GET_MODE (operands[0]) == HImode
19988 || GET_MODE (operands[0]) == SImode
19989 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19990 && (optimize_size || TARGET_PENTIUM)
19991 && peep2_regno_dead_p (0, FLAGS_REG)"
19992 [(parallel [(set (match_dup 0) (const_int -1))
19993 (clobber (reg:CC FLAGS_REG))])]
19994 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19995 operands[0]);")
19996
19997;; Attempt to convert simple leas to adds. These can be created by
19998;; move expanders.
19999(define_peephole2
20000 [(set (match_operand:SI 0 "register_operand" "")
20001 (plus:SI (match_dup 0)
20002 (match_operand:SI 1 "nonmemory_operand" "")))]
20003 "peep2_regno_dead_p (0, FLAGS_REG)"
20004 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20005 (clobber (reg:CC FLAGS_REG))])]
20006 "")
20007
20008(define_peephole2
20009 [(set (match_operand:SI 0 "register_operand" "")
20010 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20011 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20012 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20013 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20014 (clobber (reg:CC FLAGS_REG))])]
20015 "operands[2] = gen_lowpart (SImode, operands[2]);")
20016
20017(define_peephole2
20018 [(set (match_operand:DI 0 "register_operand" "")
20019 (plus:DI (match_dup 0)
20020 (match_operand:DI 1 "x86_64_general_operand" "")))]
20021 "peep2_regno_dead_p (0, FLAGS_REG)"
20022 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20023 (clobber (reg:CC FLAGS_REG))])]
20024 "")
20025
20026(define_peephole2
20027 [(set (match_operand:SI 0 "register_operand" "")
20028 (mult:SI (match_dup 0)
20029 (match_operand:SI 1 "const_int_operand" "")))]
20030 "exact_log2 (INTVAL (operands[1])) >= 0
20031 && peep2_regno_dead_p (0, FLAGS_REG)"
20032 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20033 (clobber (reg:CC FLAGS_REG))])]
20034 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20035
20036(define_peephole2
20037 [(set (match_operand:DI 0 "register_operand" "")
20038 (mult:DI (match_dup 0)
20039 (match_operand:DI 1 "const_int_operand" "")))]
20040 "exact_log2 (INTVAL (operands[1])) >= 0
20041 && peep2_regno_dead_p (0, FLAGS_REG)"
20042 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20043 (clobber (reg:CC FLAGS_REG))])]
20044 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20045
20046(define_peephole2
20047 [(set (match_operand:SI 0 "register_operand" "")
20048 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20049 (match_operand:DI 2 "const_int_operand" "")) 0))]
20050 "exact_log2 (INTVAL (operands[2])) >= 0
20051 && REGNO (operands[0]) == REGNO (operands[1])
20052 && peep2_regno_dead_p (0, FLAGS_REG)"
20053 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20054 (clobber (reg:CC FLAGS_REG))])]
20055 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20056
20057;; The ESP adjustments can be done by the push and pop instructions. Resulting
20058;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20059;; many CPUs it is also faster, since special hardware to avoid esp
20060;; dependencies is present.
20061
20062;; While some of these conversions may be done using splitters, we use peepholes
20063;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20064
20065;; Convert prologue esp subtractions to push.
20066;; We need register to push. In order to keep verify_flow_info happy we have
20067;; two choices
20068;; - use scratch and clobber it in order to avoid dependencies
20069;; - use already live register
20070;; We can't use the second way right now, since there is no reliable way how to
20071;; verify that given register is live. First choice will also most likely in
20072;; fewer dependencies. On the place of esp adjustments it is very likely that
20073;; call clobbered registers are dead. We may want to use base pointer as an
20074;; alternative when no register is available later.
20075
20076(define_peephole2
20077 [(match_scratch:SI 0 "r")
20078 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20079 (clobber (reg:CC FLAGS_REG))
20080 (clobber (mem:BLK (scratch)))])]
20081 "optimize_size || !TARGET_SUB_ESP_4"
20082 [(clobber (match_dup 0))
20083 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20084 (clobber (mem:BLK (scratch)))])])
20085
20086(define_peephole2
20087 [(match_scratch:SI 0 "r")
20088 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20089 (clobber (reg:CC FLAGS_REG))
20090 (clobber (mem:BLK (scratch)))])]
20091 "optimize_size || !TARGET_SUB_ESP_8"
20092 [(clobber (match_dup 0))
20093 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20094 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20095 (clobber (mem:BLK (scratch)))])])
20096
20097;; Convert esp subtractions to push.
20098(define_peephole2
20099 [(match_scratch:SI 0 "r")
20100 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20101 (clobber (reg:CC FLAGS_REG))])]
20102 "optimize_size || !TARGET_SUB_ESP_4"
20103 [(clobber (match_dup 0))
20104 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20105
20106(define_peephole2
20107 [(match_scratch:SI 0 "r")
20108 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20109 (clobber (reg:CC FLAGS_REG))])]
20110 "optimize_size || !TARGET_SUB_ESP_8"
20111 [(clobber (match_dup 0))
20112 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20113 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20114
20115;; Convert epilogue deallocator to pop.
20116(define_peephole2
20117 [(match_scratch:SI 0 "r")
20118 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20119 (clobber (reg:CC FLAGS_REG))
20120 (clobber (mem:BLK (scratch)))])]
20121 "optimize_size || !TARGET_ADD_ESP_4"
20122 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20123 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20124 (clobber (mem:BLK (scratch)))])]
20125 "")
20126
20127;; Two pops case is tricky, since pop causes dependency on destination register.
20128;; We use two registers if available.
20129(define_peephole2
20130 [(match_scratch:SI 0 "r")
20131 (match_scratch:SI 1 "r")
20132 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20133 (clobber (reg:CC FLAGS_REG))
20134 (clobber (mem:BLK (scratch)))])]
20135 "optimize_size || !TARGET_ADD_ESP_8"
20136 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20137 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20138 (clobber (mem:BLK (scratch)))])
20139 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20140 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20141 "")
20142
20143(define_peephole2
20144 [(match_scratch:SI 0 "r")
20145 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20146 (clobber (reg:CC FLAGS_REG))
20147 (clobber (mem:BLK (scratch)))])]
20148 "optimize_size"
20149 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20150 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20151 (clobber (mem:BLK (scratch)))])
20152 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20153 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20154 "")
20155
20156;; Convert esp additions to pop.
20157(define_peephole2
20158 [(match_scratch:SI 0 "r")
20159 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20160 (clobber (reg:CC FLAGS_REG))])]
20161 ""
20162 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20163 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20164 "")
20165
20166;; Two pops case is tricky, since pop causes dependency on destination register.
20167;; We use two registers if available.
20168(define_peephole2
20169 [(match_scratch:SI 0 "r")
20170 (match_scratch:SI 1 "r")
20171 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20172 (clobber (reg:CC FLAGS_REG))])]
20173 ""
20174 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20175 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20176 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20177 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20178 "")
20179
20180(define_peephole2
20181 [(match_scratch:SI 0 "r")
20182 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20183 (clobber (reg:CC FLAGS_REG))])]
20184 "optimize_size"
20185 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20186 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20187 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20188 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20189 "")
20190
20191;; Convert compares with 1 to shorter inc/dec operations when CF is not
20192;; required and register dies. Similarly for 128 to plus -128.
20193(define_peephole2
20194 [(set (match_operand 0 "flags_reg_operand" "")
20195 (match_operator 1 "compare_operator"
20196 [(match_operand 2 "register_operand" "")
20197 (match_operand 3 "const_int_operand" "")]))]
20198 "(INTVAL (operands[3]) == -1
20199 || INTVAL (operands[3]) == 1
20200 || INTVAL (operands[3]) == 128)
20201 && ix86_match_ccmode (insn, CCGCmode)
20202 && peep2_reg_dead_p (1, operands[2])"
20203 [(parallel [(set (match_dup 0)
20204 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20205 (clobber (match_dup 2))])]
20206 "")
20207
20208(define_peephole2
20209 [(match_scratch:DI 0 "r")
20210 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20211 (clobber (reg:CC FLAGS_REG))
20212 (clobber (mem:BLK (scratch)))])]
20213 "optimize_size || !TARGET_SUB_ESP_4"
20214 [(clobber (match_dup 0))
20215 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20216 (clobber (mem:BLK (scratch)))])])
20217
20218(define_peephole2
20219 [(match_scratch:DI 0 "r")
20220 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20221 (clobber (reg:CC FLAGS_REG))
20222 (clobber (mem:BLK (scratch)))])]
20223 "optimize_size || !TARGET_SUB_ESP_8"
20224 [(clobber (match_dup 0))
20225 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20226 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20227 (clobber (mem:BLK (scratch)))])])
20228
20229;; Convert esp subtractions to push.
20230(define_peephole2
20231 [(match_scratch:DI 0 "r")
20232 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20233 (clobber (reg:CC FLAGS_REG))])]
20234 "optimize_size || !TARGET_SUB_ESP_4"
20235 [(clobber (match_dup 0))
20236 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20237
20238(define_peephole2
20239 [(match_scratch:DI 0 "r")
20240 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20241 (clobber (reg:CC FLAGS_REG))])]
20242 "optimize_size || !TARGET_SUB_ESP_8"
20243 [(clobber (match_dup 0))
20244 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20245 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20246
20247;; Convert epilogue deallocator to pop.
20248(define_peephole2
20249 [(match_scratch:DI 0 "r")
20250 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20251 (clobber (reg:CC FLAGS_REG))
20252 (clobber (mem:BLK (scratch)))])]
20253 "optimize_size || !TARGET_ADD_ESP_4"
20254 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20255 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20256 (clobber (mem:BLK (scratch)))])]
20257 "")
20258
20259;; Two pops case is tricky, since pop causes dependency on destination register.
20260;; We use two registers if available.
20261(define_peephole2
20262 [(match_scratch:DI 0 "r")
20263 (match_scratch:DI 1 "r")
20264 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20265 (clobber (reg:CC FLAGS_REG))
20266 (clobber (mem:BLK (scratch)))])]
20267 "optimize_size || !TARGET_ADD_ESP_8"
20268 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20269 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20270 (clobber (mem:BLK (scratch)))])
20271 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20272 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20273 "")
20274
20275(define_peephole2
20276 [(match_scratch:DI 0 "r")
20277 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20278 (clobber (reg:CC FLAGS_REG))
20279 (clobber (mem:BLK (scratch)))])]
20280 "optimize_size"
20281 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20282 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20283 (clobber (mem:BLK (scratch)))])
20284 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20285 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20286 "")
20287
20288;; Convert esp additions to pop.
20289(define_peephole2
20290 [(match_scratch:DI 0 "r")
20291 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20292 (clobber (reg:CC FLAGS_REG))])]
20293 ""
20294 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20295 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20296 "")
20297
20298;; Two pops case is tricky, since pop causes dependency on destination register.
20299;; We use two registers if available.
20300(define_peephole2
20301 [(match_scratch:DI 0 "r")
20302 (match_scratch:DI 1 "r")
20303 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20304 (clobber (reg:CC FLAGS_REG))])]
20305 ""
20306 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20307 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20308 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20309 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20310 "")
20311
20312(define_peephole2
20313 [(match_scratch:DI 0 "r")
20314 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20315 (clobber (reg:CC FLAGS_REG))])]
20316 "optimize_size"
20317 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20318 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20319 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20320 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20321 "")
20322
20323;; Convert imul by three, five and nine into lea
20324(define_peephole2
20325 [(parallel
20326 [(set (match_operand:SI 0 "register_operand" "")
20327 (mult:SI (match_operand:SI 1 "register_operand" "")
20328 (match_operand:SI 2 "const_int_operand" "")))
20329 (clobber (reg:CC FLAGS_REG))])]
20330 "INTVAL (operands[2]) == 3
20331 || INTVAL (operands[2]) == 5
20332 || INTVAL (operands[2]) == 9"
20333 [(set (match_dup 0)
20334 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20335 (match_dup 1)))]
20336 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20337
20338(define_peephole2
20339 [(parallel
20340 [(set (match_operand:SI 0 "register_operand" "")
20341 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20342 (match_operand:SI 2 "const_int_operand" "")))
20343 (clobber (reg:CC FLAGS_REG))])]
20344 "!optimize_size
20345 && (INTVAL (operands[2]) == 3
20346 || INTVAL (operands[2]) == 5
20347 || INTVAL (operands[2]) == 9)"
20348 [(set (match_dup 0) (match_dup 1))
20349 (set (match_dup 0)
20350 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20351 (match_dup 0)))]
20352 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20353
20354(define_peephole2
20355 [(parallel
20356 [(set (match_operand:DI 0 "register_operand" "")
20357 (mult:DI (match_operand:DI 1 "register_operand" "")
20358 (match_operand:DI 2 "const_int_operand" "")))
20359 (clobber (reg:CC FLAGS_REG))])]
20360 "TARGET_64BIT
20361 && (INTVAL (operands[2]) == 3
20362 || INTVAL (operands[2]) == 5
20363 || INTVAL (operands[2]) == 9)"
20364 [(set (match_dup 0)
20365 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20366 (match_dup 1)))]
20367 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20368
20369(define_peephole2
20370 [(parallel
20371 [(set (match_operand:DI 0 "register_operand" "")
20372 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20373 (match_operand:DI 2 "const_int_operand" "")))
20374 (clobber (reg:CC FLAGS_REG))])]
20375 "TARGET_64BIT
20376 && !optimize_size
20377 && (INTVAL (operands[2]) == 3
20378 || INTVAL (operands[2]) == 5
20379 || INTVAL (operands[2]) == 9)"
20380 [(set (match_dup 0) (match_dup 1))
20381 (set (match_dup 0)
20382 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20383 (match_dup 0)))]
20384 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20385
20386;; Imul $32bit_imm, mem, reg is vector decoded, while
20387;; imul $32bit_imm, reg, reg is direct decoded.
20388(define_peephole2
20389 [(match_scratch:DI 3 "r")
20390 (parallel [(set (match_operand:DI 0 "register_operand" "")
20391 (mult:DI (match_operand:DI 1 "memory_operand" "")
20392 (match_operand:DI 2 "immediate_operand" "")))
20393 (clobber (reg:CC FLAGS_REG))])]
15854
15855(define_insn "fpremxf4"
15856 [(set (match_operand:XF 0 "register_operand" "=f")
15857 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15858 (match_operand:XF 3 "register_operand" "1")]
15859 UNSPEC_FPREM_F))
15860 (set (match_operand:XF 1 "register_operand" "=u")
15861 (unspec:XF [(match_dup 2) (match_dup 3)]
15862 UNSPEC_FPREM_U))
15863 (set (reg:CCFP FPSR_REG)
15864 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15865 "TARGET_USE_FANCY_MATH_387
15866 && flag_unsafe_math_optimizations"
15867 "fprem"
15868 [(set_attr "type" "fpspc")
15869 (set_attr "mode" "XF")])
15870
15871(define_expand "fmodsf3"
15872 [(use (match_operand:SF 0 "register_operand" ""))
15873 (use (match_operand:SF 1 "register_operand" ""))
15874 (use (match_operand:SF 2 "register_operand" ""))]
15875 "TARGET_USE_FANCY_MATH_387
15876 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15877 && flag_unsafe_math_optimizations"
15878{
15879 rtx label = gen_label_rtx ();
15880
15881 rtx op1 = gen_reg_rtx (XFmode);
15882 rtx op2 = gen_reg_rtx (XFmode);
15883
15884 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15885 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15886
15887 emit_label (label);
15888
15889 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15890 ix86_emit_fp_unordered_jump (label);
15891
15892 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15893 DONE;
15894})
15895
15896(define_expand "fmoddf3"
15897 [(use (match_operand:DF 0 "register_operand" ""))
15898 (use (match_operand:DF 1 "register_operand" ""))
15899 (use (match_operand:DF 2 "register_operand" ""))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15902 && flag_unsafe_math_optimizations"
15903{
15904 rtx label = gen_label_rtx ();
15905
15906 rtx op1 = gen_reg_rtx (XFmode);
15907 rtx op2 = gen_reg_rtx (XFmode);
15908
15909 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15910 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15911
15912 emit_label (label);
15913
15914 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15915 ix86_emit_fp_unordered_jump (label);
15916
15917 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15918 DONE;
15919})
15920
15921(define_expand "fmodxf3"
15922 [(use (match_operand:XF 0 "register_operand" ""))
15923 (use (match_operand:XF 1 "register_operand" ""))
15924 (use (match_operand:XF 2 "register_operand" ""))]
15925 "TARGET_USE_FANCY_MATH_387
15926 && flag_unsafe_math_optimizations"
15927{
15928 rtx label = gen_label_rtx ();
15929
15930 emit_label (label);
15931
15932 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15933 operands[1], operands[2]));
15934 ix86_emit_fp_unordered_jump (label);
15935
15936 emit_move_insn (operands[0], operands[1]);
15937 DONE;
15938})
15939
15940(define_insn "fprem1xf4"
15941 [(set (match_operand:XF 0 "register_operand" "=f")
15942 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15943 (match_operand:XF 3 "register_operand" "1")]
15944 UNSPEC_FPREM1_F))
15945 (set (match_operand:XF 1 "register_operand" "=u")
15946 (unspec:XF [(match_dup 2) (match_dup 3)]
15947 UNSPEC_FPREM1_U))
15948 (set (reg:CCFP FPSR_REG)
15949 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15950 "TARGET_USE_FANCY_MATH_387
15951 && flag_unsafe_math_optimizations"
15952 "fprem1"
15953 [(set_attr "type" "fpspc")
15954 (set_attr "mode" "XF")])
15955
15956(define_expand "dremsf3"
15957 [(use (match_operand:SF 0 "register_operand" ""))
15958 (use (match_operand:SF 1 "register_operand" ""))
15959 (use (match_operand:SF 2 "register_operand" ""))]
15960 "TARGET_USE_FANCY_MATH_387
15961 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15962 && flag_unsafe_math_optimizations"
15963{
15964 rtx label = gen_label_rtx ();
15965
15966 rtx op1 = gen_reg_rtx (XFmode);
15967 rtx op2 = gen_reg_rtx (XFmode);
15968
15969 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15970 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15971
15972 emit_label (label);
15973
15974 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15975 ix86_emit_fp_unordered_jump (label);
15976
15977 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15978 DONE;
15979})
15980
15981(define_expand "dremdf3"
15982 [(use (match_operand:DF 0 "register_operand" ""))
15983 (use (match_operand:DF 1 "register_operand" ""))
15984 (use (match_operand:DF 2 "register_operand" ""))]
15985 "TARGET_USE_FANCY_MATH_387
15986 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15987 && flag_unsafe_math_optimizations"
15988{
15989 rtx label = gen_label_rtx ();
15990
15991 rtx op1 = gen_reg_rtx (XFmode);
15992 rtx op2 = gen_reg_rtx (XFmode);
15993
15994 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15995 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15996
15997 emit_label (label);
15998
15999 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
16000 ix86_emit_fp_unordered_jump (label);
16001
16002 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
16003 DONE;
16004})
16005
16006(define_expand "dremxf3"
16007 [(use (match_operand:XF 0 "register_operand" ""))
16008 (use (match_operand:XF 1 "register_operand" ""))
16009 (use (match_operand:XF 2 "register_operand" ""))]
16010 "TARGET_USE_FANCY_MATH_387
16011 && flag_unsafe_math_optimizations"
16012{
16013 rtx label = gen_label_rtx ();
16014
16015 emit_label (label);
16016
16017 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
16018 operands[1], operands[2]));
16019 ix86_emit_fp_unordered_jump (label);
16020
16021 emit_move_insn (operands[0], operands[1]);
16022 DONE;
16023})
16024
16025(define_insn "*sindf2"
16026 [(set (match_operand:DF 0 "register_operand" "=f")
16027 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
16028 "TARGET_USE_FANCY_MATH_387
16029 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16030 && flag_unsafe_math_optimizations"
16031 "fsin"
16032 [(set_attr "type" "fpspc")
16033 (set_attr "mode" "DF")])
16034
16035(define_insn "*sinsf2"
16036 [(set (match_operand:SF 0 "register_operand" "=f")
16037 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
16038 "TARGET_USE_FANCY_MATH_387
16039 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16040 && flag_unsafe_math_optimizations"
16041 "fsin"
16042 [(set_attr "type" "fpspc")
16043 (set_attr "mode" "SF")])
16044
16045(define_insn "*sinextendsfdf2"
16046 [(set (match_operand:DF 0 "register_operand" "=f")
16047 (unspec:DF [(float_extend:DF
16048 (match_operand:SF 1 "register_operand" "0"))]
16049 UNSPEC_SIN))]
16050 "TARGET_USE_FANCY_MATH_387
16051 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16052 && flag_unsafe_math_optimizations"
16053 "fsin"
16054 [(set_attr "type" "fpspc")
16055 (set_attr "mode" "DF")])
16056
16057(define_insn "*sinxf2"
16058 [(set (match_operand:XF 0 "register_operand" "=f")
16059 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16060 "TARGET_USE_FANCY_MATH_387
16061 && flag_unsafe_math_optimizations"
16062 "fsin"
16063 [(set_attr "type" "fpspc")
16064 (set_attr "mode" "XF")])
16065
16066(define_insn "*cosdf2"
16067 [(set (match_operand:DF 0 "register_operand" "=f")
16068 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
16069 "TARGET_USE_FANCY_MATH_387
16070 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16071 && flag_unsafe_math_optimizations"
16072 "fcos"
16073 [(set_attr "type" "fpspc")
16074 (set_attr "mode" "DF")])
16075
16076(define_insn "*cossf2"
16077 [(set (match_operand:SF 0 "register_operand" "=f")
16078 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
16079 "TARGET_USE_FANCY_MATH_387
16080 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16081 && flag_unsafe_math_optimizations"
16082 "fcos"
16083 [(set_attr "type" "fpspc")
16084 (set_attr "mode" "SF")])
16085
16086(define_insn "*cosextendsfdf2"
16087 [(set (match_operand:DF 0 "register_operand" "=f")
16088 (unspec:DF [(float_extend:DF
16089 (match_operand:SF 1 "register_operand" "0"))]
16090 UNSPEC_COS))]
16091 "TARGET_USE_FANCY_MATH_387
16092 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16093 && flag_unsafe_math_optimizations"
16094 "fcos"
16095 [(set_attr "type" "fpspc")
16096 (set_attr "mode" "DF")])
16097
16098(define_insn "*cosxf2"
16099 [(set (match_operand:XF 0 "register_operand" "=f")
16100 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16101 "TARGET_USE_FANCY_MATH_387
16102 && flag_unsafe_math_optimizations"
16103 "fcos"
16104 [(set_attr "type" "fpspc")
16105 (set_attr "mode" "XF")])
16106
16107;; With sincos pattern defined, sin and cos builtin function will be
16108;; expanded to sincos pattern with one of its outputs left unused.
16109;; Cse pass will detected, if two sincos patterns can be combined,
16110;; otherwise sincos pattern will be split back to sin or cos pattern,
16111;; depending on the unused output.
16112
16113(define_insn "sincosdf3"
16114 [(set (match_operand:DF 0 "register_operand" "=f")
16115 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16116 UNSPEC_SINCOS_COS))
16117 (set (match_operand:DF 1 "register_operand" "=u")
16118 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16121 && flag_unsafe_math_optimizations"
16122 "fsincos"
16123 [(set_attr "type" "fpspc")
16124 (set_attr "mode" "DF")])
16125
16126(define_split
16127 [(set (match_operand:DF 0 "register_operand" "")
16128 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16129 UNSPEC_SINCOS_COS))
16130 (set (match_operand:DF 1 "register_operand" "")
16131 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16132 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16133 && !reload_completed && !reload_in_progress"
16134 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
16135 "")
16136
16137(define_split
16138 [(set (match_operand:DF 0 "register_operand" "")
16139 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16140 UNSPEC_SINCOS_COS))
16141 (set (match_operand:DF 1 "register_operand" "")
16142 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16143 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16144 && !reload_completed && !reload_in_progress"
16145 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
16146 "")
16147
16148(define_insn "sincossf3"
16149 [(set (match_operand:SF 0 "register_operand" "=f")
16150 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16151 UNSPEC_SINCOS_COS))
16152 (set (match_operand:SF 1 "register_operand" "=u")
16153 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16154 "TARGET_USE_FANCY_MATH_387
16155 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16156 && flag_unsafe_math_optimizations"
16157 "fsincos"
16158 [(set_attr "type" "fpspc")
16159 (set_attr "mode" "SF")])
16160
16161(define_split
16162 [(set (match_operand:SF 0 "register_operand" "")
16163 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16164 UNSPEC_SINCOS_COS))
16165 (set (match_operand:SF 1 "register_operand" "")
16166 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16167 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16168 && !reload_completed && !reload_in_progress"
16169 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
16170 "")
16171
16172(define_split
16173 [(set (match_operand:SF 0 "register_operand" "")
16174 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16175 UNSPEC_SINCOS_COS))
16176 (set (match_operand:SF 1 "register_operand" "")
16177 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16178 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16179 && !reload_completed && !reload_in_progress"
16180 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
16181 "")
16182
16183(define_insn "*sincosextendsfdf3"
16184 [(set (match_operand:DF 0 "register_operand" "=f")
16185 (unspec:DF [(float_extend:DF
16186 (match_operand:SF 2 "register_operand" "0"))]
16187 UNSPEC_SINCOS_COS))
16188 (set (match_operand:DF 1 "register_operand" "=u")
16189 (unspec:DF [(float_extend:DF
16190 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16191 "TARGET_USE_FANCY_MATH_387
16192 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16193 && flag_unsafe_math_optimizations"
16194 "fsincos"
16195 [(set_attr "type" "fpspc")
16196 (set_attr "mode" "DF")])
16197
16198(define_split
16199 [(set (match_operand:DF 0 "register_operand" "")
16200 (unspec:DF [(float_extend:DF
16201 (match_operand:SF 2 "register_operand" ""))]
16202 UNSPEC_SINCOS_COS))
16203 (set (match_operand:DF 1 "register_operand" "")
16204 (unspec:DF [(float_extend:DF
16205 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16206 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16207 && !reload_completed && !reload_in_progress"
16208 [(set (match_dup 1) (unspec:DF [(float_extend:DF
16209 (match_dup 2))] UNSPEC_SIN))]
16210 "")
16211
16212(define_split
16213 [(set (match_operand:DF 0 "register_operand" "")
16214 (unspec:DF [(float_extend:DF
16215 (match_operand:SF 2 "register_operand" ""))]
16216 UNSPEC_SINCOS_COS))
16217 (set (match_operand:DF 1 "register_operand" "")
16218 (unspec:DF [(float_extend:DF
16219 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16220 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16221 && !reload_completed && !reload_in_progress"
16222 [(set (match_dup 0) (unspec:DF [(float_extend:DF
16223 (match_dup 2))] UNSPEC_COS))]
16224 "")
16225
16226(define_insn "sincosxf3"
16227 [(set (match_operand:XF 0 "register_operand" "=f")
16228 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16229 UNSPEC_SINCOS_COS))
16230 (set (match_operand:XF 1 "register_operand" "=u")
16231 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16232 "TARGET_USE_FANCY_MATH_387
16233 && flag_unsafe_math_optimizations"
16234 "fsincos"
16235 [(set_attr "type" "fpspc")
16236 (set_attr "mode" "XF")])
16237
16238(define_split
16239 [(set (match_operand:XF 0 "register_operand" "")
16240 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16241 UNSPEC_SINCOS_COS))
16242 (set (match_operand:XF 1 "register_operand" "")
16243 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16244 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16245 && !reload_completed && !reload_in_progress"
16246 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16247 "")
16248
16249(define_split
16250 [(set (match_operand:XF 0 "register_operand" "")
16251 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16252 UNSPEC_SINCOS_COS))
16253 (set (match_operand:XF 1 "register_operand" "")
16254 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16255 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16256 && !reload_completed && !reload_in_progress"
16257 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16258 "")
16259
16260(define_insn "*tandf3_1"
16261 [(set (match_operand:DF 0 "register_operand" "=f")
16262 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16263 UNSPEC_TAN_ONE))
16264 (set (match_operand:DF 1 "register_operand" "=u")
16265 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16266 "TARGET_USE_FANCY_MATH_387
16267 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16268 && flag_unsafe_math_optimizations"
16269 "fptan"
16270 [(set_attr "type" "fpspc")
16271 (set_attr "mode" "DF")])
16272
16273;; optimize sequence: fptan
16274;; fstp %st(0)
16275;; fld1
16276;; into fptan insn.
16277
16278(define_peephole2
16279 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16280 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16281 UNSPEC_TAN_ONE))
16282 (set (match_operand:DF 1 "register_operand" "")
16283 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16284 (set (match_dup 0)
16285 (match_operand:DF 3 "immediate_operand" ""))]
16286 "standard_80387_constant_p (operands[3]) == 2"
16287 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16288 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16289 "")
16290
16291(define_expand "tandf2"
16292 [(parallel [(set (match_dup 2)
16293 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16294 UNSPEC_TAN_ONE))
16295 (set (match_operand:DF 0 "register_operand" "")
16296 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16297 "TARGET_USE_FANCY_MATH_387
16298 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16299 && flag_unsafe_math_optimizations"
16300{
16301 operands[2] = gen_reg_rtx (DFmode);
16302})
16303
16304(define_insn "*tansf3_1"
16305 [(set (match_operand:SF 0 "register_operand" "=f")
16306 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16307 UNSPEC_TAN_ONE))
16308 (set (match_operand:SF 1 "register_operand" "=u")
16309 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16310 "TARGET_USE_FANCY_MATH_387
16311 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16312 && flag_unsafe_math_optimizations"
16313 "fptan"
16314 [(set_attr "type" "fpspc")
16315 (set_attr "mode" "SF")])
16316
16317;; optimize sequence: fptan
16318;; fstp %st(0)
16319;; fld1
16320;; into fptan insn.
16321
16322(define_peephole2
16323 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16324 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16325 UNSPEC_TAN_ONE))
16326 (set (match_operand:SF 1 "register_operand" "")
16327 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16328 (set (match_dup 0)
16329 (match_operand:SF 3 "immediate_operand" ""))]
16330 "standard_80387_constant_p (operands[3]) == 2"
16331 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16332 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16333 "")
16334
16335(define_expand "tansf2"
16336 [(parallel [(set (match_dup 2)
16337 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16338 UNSPEC_TAN_ONE))
16339 (set (match_operand:SF 0 "register_operand" "")
16340 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16341 "TARGET_USE_FANCY_MATH_387
16342 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16343 && flag_unsafe_math_optimizations"
16344{
16345 operands[2] = gen_reg_rtx (SFmode);
16346})
16347
16348(define_insn "*tanxf3_1"
16349 [(set (match_operand:XF 0 "register_operand" "=f")
16350 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16351 UNSPEC_TAN_ONE))
16352 (set (match_operand:XF 1 "register_operand" "=u")
16353 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16354 "TARGET_USE_FANCY_MATH_387
16355 && flag_unsafe_math_optimizations"
16356 "fptan"
16357 [(set_attr "type" "fpspc")
16358 (set_attr "mode" "XF")])
16359
16360;; optimize sequence: fptan
16361;; fstp %st(0)
16362;; fld1
16363;; into fptan insn.
16364
16365(define_peephole2
16366 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16367 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16368 UNSPEC_TAN_ONE))
16369 (set (match_operand:XF 1 "register_operand" "")
16370 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16371 (set (match_dup 0)
16372 (match_operand:XF 3 "immediate_operand" ""))]
16373 "standard_80387_constant_p (operands[3]) == 2"
16374 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16375 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16376 "")
16377
16378(define_expand "tanxf2"
16379 [(parallel [(set (match_dup 2)
16380 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16381 UNSPEC_TAN_ONE))
16382 (set (match_operand:XF 0 "register_operand" "")
16383 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16384 "TARGET_USE_FANCY_MATH_387
16385 && flag_unsafe_math_optimizations"
16386{
16387 operands[2] = gen_reg_rtx (XFmode);
16388})
16389
16390(define_insn "atan2df3_1"
16391 [(set (match_operand:DF 0 "register_operand" "=f")
16392 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16393 (match_operand:DF 1 "register_operand" "u")]
16394 UNSPEC_FPATAN))
16395 (clobber (match_scratch:DF 3 "=1"))]
16396 "TARGET_USE_FANCY_MATH_387
16397 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16398 && flag_unsafe_math_optimizations"
16399 "fpatan"
16400 [(set_attr "type" "fpspc")
16401 (set_attr "mode" "DF")])
16402
16403(define_expand "atan2df3"
16404 [(use (match_operand:DF 0 "register_operand" ""))
16405 (use (match_operand:DF 2 "register_operand" ""))
16406 (use (match_operand:DF 1 "register_operand" ""))]
16407 "TARGET_USE_FANCY_MATH_387
16408 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16409 && flag_unsafe_math_optimizations"
16410{
16411 rtx copy = gen_reg_rtx (DFmode);
16412 emit_move_insn (copy, operands[1]);
16413 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16414 DONE;
16415})
16416
16417(define_expand "atandf2"
16418 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16419 (unspec:DF [(match_dup 2)
16420 (match_operand:DF 1 "register_operand" "")]
16421 UNSPEC_FPATAN))
16422 (clobber (match_scratch:DF 3 ""))])]
16423 "TARGET_USE_FANCY_MATH_387
16424 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16425 && flag_unsafe_math_optimizations"
16426{
16427 operands[2] = gen_reg_rtx (DFmode);
16428 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16429})
16430
16431(define_insn "atan2sf3_1"
16432 [(set (match_operand:SF 0 "register_operand" "=f")
16433 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16434 (match_operand:SF 1 "register_operand" "u")]
16435 UNSPEC_FPATAN))
16436 (clobber (match_scratch:SF 3 "=1"))]
16437 "TARGET_USE_FANCY_MATH_387
16438 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16439 && flag_unsafe_math_optimizations"
16440 "fpatan"
16441 [(set_attr "type" "fpspc")
16442 (set_attr "mode" "SF")])
16443
16444(define_expand "atan2sf3"
16445 [(use (match_operand:SF 0 "register_operand" ""))
16446 (use (match_operand:SF 2 "register_operand" ""))
16447 (use (match_operand:SF 1 "register_operand" ""))]
16448 "TARGET_USE_FANCY_MATH_387
16449 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16450 && flag_unsafe_math_optimizations"
16451{
16452 rtx copy = gen_reg_rtx (SFmode);
16453 emit_move_insn (copy, operands[1]);
16454 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16455 DONE;
16456})
16457
16458(define_expand "atansf2"
16459 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16460 (unspec:SF [(match_dup 2)
16461 (match_operand:SF 1 "register_operand" "")]
16462 UNSPEC_FPATAN))
16463 (clobber (match_scratch:SF 3 ""))])]
16464 "TARGET_USE_FANCY_MATH_387
16465 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16466 && flag_unsafe_math_optimizations"
16467{
16468 operands[2] = gen_reg_rtx (SFmode);
16469 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16470})
16471
16472(define_insn "atan2xf3_1"
16473 [(set (match_operand:XF 0 "register_operand" "=f")
16474 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16475 (match_operand:XF 1 "register_operand" "u")]
16476 UNSPEC_FPATAN))
16477 (clobber (match_scratch:XF 3 "=1"))]
16478 "TARGET_USE_FANCY_MATH_387
16479 && flag_unsafe_math_optimizations"
16480 "fpatan"
16481 [(set_attr "type" "fpspc")
16482 (set_attr "mode" "XF")])
16483
16484(define_expand "atan2xf3"
16485 [(use (match_operand:XF 0 "register_operand" ""))
16486 (use (match_operand:XF 2 "register_operand" ""))
16487 (use (match_operand:XF 1 "register_operand" ""))]
16488 "TARGET_USE_FANCY_MATH_387
16489 && flag_unsafe_math_optimizations"
16490{
16491 rtx copy = gen_reg_rtx (XFmode);
16492 emit_move_insn (copy, operands[1]);
16493 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16494 DONE;
16495})
16496
16497(define_expand "atanxf2"
16498 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16499 (unspec:XF [(match_dup 2)
16500 (match_operand:XF 1 "register_operand" "")]
16501 UNSPEC_FPATAN))
16502 (clobber (match_scratch:XF 3 ""))])]
16503 "TARGET_USE_FANCY_MATH_387
16504 && flag_unsafe_math_optimizations"
16505{
16506 operands[2] = gen_reg_rtx (XFmode);
16507 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16508})
16509
16510(define_expand "asindf2"
16511 [(set (match_dup 2)
16512 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16513 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16514 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16515 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16516 (parallel [(set (match_dup 7)
16517 (unspec:XF [(match_dup 6) (match_dup 2)]
16518 UNSPEC_FPATAN))
16519 (clobber (match_scratch:XF 8 ""))])
16520 (set (match_operand:DF 0 "register_operand" "")
16521 (float_truncate:DF (match_dup 7)))]
16522 "TARGET_USE_FANCY_MATH_387
16523 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16524 && flag_unsafe_math_optimizations"
16525{
16526 int i;
16527
16528 for (i=2; i<8; i++)
16529 operands[i] = gen_reg_rtx (XFmode);
16530
16531 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16532})
16533
16534(define_expand "asinsf2"
16535 [(set (match_dup 2)
16536 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16537 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16538 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16539 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16540 (parallel [(set (match_dup 7)
16541 (unspec:XF [(match_dup 6) (match_dup 2)]
16542 UNSPEC_FPATAN))
16543 (clobber (match_scratch:XF 8 ""))])
16544 (set (match_operand:SF 0 "register_operand" "")
16545 (float_truncate:SF (match_dup 7)))]
16546 "TARGET_USE_FANCY_MATH_387
16547 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16548 && flag_unsafe_math_optimizations"
16549{
16550 int i;
16551
16552 for (i=2; i<8; i++)
16553 operands[i] = gen_reg_rtx (XFmode);
16554
16555 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16556})
16557
16558(define_expand "asinxf2"
16559 [(set (match_dup 2)
16560 (mult:XF (match_operand:XF 1 "register_operand" "")
16561 (match_dup 1)))
16562 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16563 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16564 (parallel [(set (match_operand:XF 0 "register_operand" "")
16565 (unspec:XF [(match_dup 5) (match_dup 1)]
16566 UNSPEC_FPATAN))
16567 (clobber (match_scratch:XF 6 ""))])]
16568 "TARGET_USE_FANCY_MATH_387
16569 && flag_unsafe_math_optimizations"
16570{
16571 int i;
16572
16573 for (i=2; i<6; i++)
16574 operands[i] = gen_reg_rtx (XFmode);
16575
16576 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16577})
16578
16579(define_expand "acosdf2"
16580 [(set (match_dup 2)
16581 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16582 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16583 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16584 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16585 (parallel [(set (match_dup 7)
16586 (unspec:XF [(match_dup 2) (match_dup 6)]
16587 UNSPEC_FPATAN))
16588 (clobber (match_scratch:XF 8 ""))])
16589 (set (match_operand:DF 0 "register_operand" "")
16590 (float_truncate:DF (match_dup 7)))]
16591 "TARGET_USE_FANCY_MATH_387
16592 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16593 && flag_unsafe_math_optimizations"
16594{
16595 int i;
16596
16597 for (i=2; i<8; i++)
16598 operands[i] = gen_reg_rtx (XFmode);
16599
16600 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16601})
16602
16603(define_expand "acossf2"
16604 [(set (match_dup 2)
16605 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16606 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16607 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16608 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16609 (parallel [(set (match_dup 7)
16610 (unspec:XF [(match_dup 2) (match_dup 6)]
16611 UNSPEC_FPATAN))
16612 (clobber (match_scratch:XF 8 ""))])
16613 (set (match_operand:SF 0 "register_operand" "")
16614 (float_truncate:SF (match_dup 7)))]
16615 "TARGET_USE_FANCY_MATH_387
16616 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16617 && flag_unsafe_math_optimizations"
16618{
16619 int i;
16620
16621 for (i=2; i<8; i++)
16622 operands[i] = gen_reg_rtx (XFmode);
16623
16624 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16625})
16626
16627(define_expand "acosxf2"
16628 [(set (match_dup 2)
16629 (mult:XF (match_operand:XF 1 "register_operand" "")
16630 (match_dup 1)))
16631 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16632 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16633 (parallel [(set (match_operand:XF 0 "register_operand" "")
16634 (unspec:XF [(match_dup 1) (match_dup 5)]
16635 UNSPEC_FPATAN))
16636 (clobber (match_scratch:XF 6 ""))])]
16637 "TARGET_USE_FANCY_MATH_387
16638 && flag_unsafe_math_optimizations"
16639{
16640 int i;
16641
16642 for (i=2; i<6; i++)
16643 operands[i] = gen_reg_rtx (XFmode);
16644
16645 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16646})
16647
16648(define_insn "fyl2x_xf3"
16649 [(set (match_operand:XF 0 "register_operand" "=f")
16650 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16651 (match_operand:XF 1 "register_operand" "u")]
16652 UNSPEC_FYL2X))
16653 (clobber (match_scratch:XF 3 "=1"))]
16654 "TARGET_USE_FANCY_MATH_387
16655 && flag_unsafe_math_optimizations"
16656 "fyl2x"
16657 [(set_attr "type" "fpspc")
16658 (set_attr "mode" "XF")])
16659
16660(define_expand "logsf2"
16661 [(set (match_dup 2)
16662 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16663 (parallel [(set (match_dup 4)
16664 (unspec:XF [(match_dup 2)
16665 (match_dup 3)] UNSPEC_FYL2X))
16666 (clobber (match_scratch:XF 5 ""))])
16667 (set (match_operand:SF 0 "register_operand" "")
16668 (float_truncate:SF (match_dup 4)))]
16669 "TARGET_USE_FANCY_MATH_387
16670 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16671 && flag_unsafe_math_optimizations"
16672{
16673 rtx temp;
16674
16675 operands[2] = gen_reg_rtx (XFmode);
16676 operands[3] = gen_reg_rtx (XFmode);
16677 operands[4] = gen_reg_rtx (XFmode);
16678
16679 temp = standard_80387_constant_rtx (4); /* fldln2 */
16680 emit_move_insn (operands[3], temp);
16681})
16682
16683(define_expand "logdf2"
16684 [(set (match_dup 2)
16685 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16686 (parallel [(set (match_dup 4)
16687 (unspec:XF [(match_dup 2)
16688 (match_dup 3)] UNSPEC_FYL2X))
16689 (clobber (match_scratch:XF 5 ""))])
16690 (set (match_operand:DF 0 "register_operand" "")
16691 (float_truncate:DF (match_dup 4)))]
16692 "TARGET_USE_FANCY_MATH_387
16693 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16694 && flag_unsafe_math_optimizations"
16695{
16696 rtx temp;
16697
16698 operands[2] = gen_reg_rtx (XFmode);
16699 operands[3] = gen_reg_rtx (XFmode);
16700 operands[4] = gen_reg_rtx (XFmode);
16701
16702 temp = standard_80387_constant_rtx (4); /* fldln2 */
16703 emit_move_insn (operands[3], temp);
16704})
16705
16706(define_expand "logxf2"
16707 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16708 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16709 (match_dup 2)] UNSPEC_FYL2X))
16710 (clobber (match_scratch:XF 3 ""))])]
16711 "TARGET_USE_FANCY_MATH_387
16712 && flag_unsafe_math_optimizations"
16713{
16714 rtx temp;
16715
16716 operands[2] = gen_reg_rtx (XFmode);
16717 temp = standard_80387_constant_rtx (4); /* fldln2 */
16718 emit_move_insn (operands[2], temp);
16719})
16720
16721(define_expand "log10sf2"
16722 [(set (match_dup 2)
16723 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16724 (parallel [(set (match_dup 4)
16725 (unspec:XF [(match_dup 2)
16726 (match_dup 3)] UNSPEC_FYL2X))
16727 (clobber (match_scratch:XF 5 ""))])
16728 (set (match_operand:SF 0 "register_operand" "")
16729 (float_truncate:SF (match_dup 4)))]
16730 "TARGET_USE_FANCY_MATH_387
16731 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16732 && flag_unsafe_math_optimizations"
16733{
16734 rtx temp;
16735
16736 operands[2] = gen_reg_rtx (XFmode);
16737 operands[3] = gen_reg_rtx (XFmode);
16738 operands[4] = gen_reg_rtx (XFmode);
16739
16740 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16741 emit_move_insn (operands[3], temp);
16742})
16743
16744(define_expand "log10df2"
16745 [(set (match_dup 2)
16746 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16747 (parallel [(set (match_dup 4)
16748 (unspec:XF [(match_dup 2)
16749 (match_dup 3)] UNSPEC_FYL2X))
16750 (clobber (match_scratch:XF 5 ""))])
16751 (set (match_operand:DF 0 "register_operand" "")
16752 (float_truncate:DF (match_dup 4)))]
16753 "TARGET_USE_FANCY_MATH_387
16754 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16755 && flag_unsafe_math_optimizations"
16756{
16757 rtx temp;
16758
16759 operands[2] = gen_reg_rtx (XFmode);
16760 operands[3] = gen_reg_rtx (XFmode);
16761 operands[4] = gen_reg_rtx (XFmode);
16762
16763 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16764 emit_move_insn (operands[3], temp);
16765})
16766
16767(define_expand "log10xf2"
16768 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16769 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16770 (match_dup 2)] UNSPEC_FYL2X))
16771 (clobber (match_scratch:XF 3 ""))])]
16772 "TARGET_USE_FANCY_MATH_387
16773 && flag_unsafe_math_optimizations"
16774{
16775 rtx temp;
16776
16777 operands[2] = gen_reg_rtx (XFmode);
16778 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16779 emit_move_insn (operands[2], temp);
16780})
16781
16782(define_expand "log2sf2"
16783 [(set (match_dup 2)
16784 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16785 (parallel [(set (match_dup 4)
16786 (unspec:XF [(match_dup 2)
16787 (match_dup 3)] UNSPEC_FYL2X))
16788 (clobber (match_scratch:XF 5 ""))])
16789 (set (match_operand:SF 0 "register_operand" "")
16790 (float_truncate:SF (match_dup 4)))]
16791 "TARGET_USE_FANCY_MATH_387
16792 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16793 && flag_unsafe_math_optimizations"
16794{
16795 operands[2] = gen_reg_rtx (XFmode);
16796 operands[3] = gen_reg_rtx (XFmode);
16797 operands[4] = gen_reg_rtx (XFmode);
16798
16799 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16800})
16801
16802(define_expand "log2df2"
16803 [(set (match_dup 2)
16804 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16805 (parallel [(set (match_dup 4)
16806 (unspec:XF [(match_dup 2)
16807 (match_dup 3)] UNSPEC_FYL2X))
16808 (clobber (match_scratch:XF 5 ""))])
16809 (set (match_operand:DF 0 "register_operand" "")
16810 (float_truncate:DF (match_dup 4)))]
16811 "TARGET_USE_FANCY_MATH_387
16812 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16813 && flag_unsafe_math_optimizations"
16814{
16815 operands[2] = gen_reg_rtx (XFmode);
16816 operands[3] = gen_reg_rtx (XFmode);
16817 operands[4] = gen_reg_rtx (XFmode);
16818
16819 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16820})
16821
16822(define_expand "log2xf2"
16823 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16824 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16825 (match_dup 2)] UNSPEC_FYL2X))
16826 (clobber (match_scratch:XF 3 ""))])]
16827 "TARGET_USE_FANCY_MATH_387
16828 && flag_unsafe_math_optimizations"
16829{
16830 operands[2] = gen_reg_rtx (XFmode);
16831 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16832})
16833
16834(define_insn "fyl2xp1_xf3"
16835 [(set (match_operand:XF 0 "register_operand" "=f")
16836 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16837 (match_operand:XF 1 "register_operand" "u")]
16838 UNSPEC_FYL2XP1))
16839 (clobber (match_scratch:XF 3 "=1"))]
16840 "TARGET_USE_FANCY_MATH_387
16841 && flag_unsafe_math_optimizations"
16842 "fyl2xp1"
16843 [(set_attr "type" "fpspc")
16844 (set_attr "mode" "XF")])
16845
16846(define_expand "log1psf2"
16847 [(use (match_operand:SF 0 "register_operand" ""))
16848 (use (match_operand:SF 1 "register_operand" ""))]
16849 "TARGET_USE_FANCY_MATH_387
16850 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16851 && flag_unsafe_math_optimizations"
16852{
16853 rtx op0 = gen_reg_rtx (XFmode);
16854 rtx op1 = gen_reg_rtx (XFmode);
16855
16856 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16857 ix86_emit_i387_log1p (op0, op1);
16858 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16859 DONE;
16860})
16861
16862(define_expand "log1pdf2"
16863 [(use (match_operand:DF 0 "register_operand" ""))
16864 (use (match_operand:DF 1 "register_operand" ""))]
16865 "TARGET_USE_FANCY_MATH_387
16866 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16867 && flag_unsafe_math_optimizations"
16868{
16869 rtx op0 = gen_reg_rtx (XFmode);
16870 rtx op1 = gen_reg_rtx (XFmode);
16871
16872 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16873 ix86_emit_i387_log1p (op0, op1);
16874 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16875 DONE;
16876})
16877
16878(define_expand "log1pxf2"
16879 [(use (match_operand:XF 0 "register_operand" ""))
16880 (use (match_operand:XF 1 "register_operand" ""))]
16881 "TARGET_USE_FANCY_MATH_387
16882 && flag_unsafe_math_optimizations"
16883{
16884 ix86_emit_i387_log1p (operands[0], operands[1]);
16885 DONE;
16886})
16887
16888(define_insn "*fxtractxf3"
16889 [(set (match_operand:XF 0 "register_operand" "=f")
16890 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16891 UNSPEC_XTRACT_FRACT))
16892 (set (match_operand:XF 1 "register_operand" "=u")
16893 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16894 "TARGET_USE_FANCY_MATH_387
16895 && flag_unsafe_math_optimizations"
16896 "fxtract"
16897 [(set_attr "type" "fpspc")
16898 (set_attr "mode" "XF")])
16899
16900(define_expand "logbsf2"
16901 [(set (match_dup 2)
16902 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16903 (parallel [(set (match_dup 3)
16904 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16905 (set (match_dup 4)
16906 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16907 (set (match_operand:SF 0 "register_operand" "")
16908 (float_truncate:SF (match_dup 4)))]
16909 "TARGET_USE_FANCY_MATH_387
16910 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16911 && flag_unsafe_math_optimizations"
16912{
16913 operands[2] = gen_reg_rtx (XFmode);
16914 operands[3] = gen_reg_rtx (XFmode);
16915 operands[4] = gen_reg_rtx (XFmode);
16916})
16917
16918(define_expand "logbdf2"
16919 [(set (match_dup 2)
16920 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16921 (parallel [(set (match_dup 3)
16922 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16923 (set (match_dup 4)
16924 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16925 (set (match_operand:DF 0 "register_operand" "")
16926 (float_truncate:DF (match_dup 4)))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16929 && flag_unsafe_math_optimizations"
16930{
16931 operands[2] = gen_reg_rtx (XFmode);
16932 operands[3] = gen_reg_rtx (XFmode);
16933 operands[4] = gen_reg_rtx (XFmode);
16934})
16935
16936(define_expand "logbxf2"
16937 [(parallel [(set (match_dup 2)
16938 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16939 UNSPEC_XTRACT_FRACT))
16940 (set (match_operand:XF 0 "register_operand" "")
16941 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16942 "TARGET_USE_FANCY_MATH_387
16943 && flag_unsafe_math_optimizations"
16944{
16945 operands[2] = gen_reg_rtx (XFmode);
16946})
16947
16948(define_expand "ilogbsi2"
16949 [(parallel [(set (match_dup 2)
16950 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16951 UNSPEC_XTRACT_FRACT))
16952 (set (match_operand:XF 3 "register_operand" "")
16953 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16954 (parallel [(set (match_operand:SI 0 "register_operand" "")
16955 (fix:SI (match_dup 3)))
16956 (clobber (reg:CC FLAGS_REG))])]
16957 "TARGET_USE_FANCY_MATH_387
16958 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16959 && flag_unsafe_math_optimizations"
16960{
16961 operands[2] = gen_reg_rtx (XFmode);
16962 operands[3] = gen_reg_rtx (XFmode);
16963})
16964
16965(define_insn "*f2xm1xf2"
16966 [(set (match_operand:XF 0 "register_operand" "=f")
16967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16968 UNSPEC_F2XM1))]
16969 "TARGET_USE_FANCY_MATH_387
16970 && flag_unsafe_math_optimizations"
16971 "f2xm1"
16972 [(set_attr "type" "fpspc")
16973 (set_attr "mode" "XF")])
16974
16975(define_insn "*fscalexf4"
16976 [(set (match_operand:XF 0 "register_operand" "=f")
16977 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16978 (match_operand:XF 3 "register_operand" "1")]
16979 UNSPEC_FSCALE_FRACT))
16980 (set (match_operand:XF 1 "register_operand" "=u")
16981 (unspec:XF [(match_dup 2) (match_dup 3)]
16982 UNSPEC_FSCALE_EXP))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && flag_unsafe_math_optimizations"
16985 "fscale"
16986 [(set_attr "type" "fpspc")
16987 (set_attr "mode" "XF")])
16988
16989(define_expand "expsf2"
16990 [(set (match_dup 2)
16991 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16992 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16993 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16994 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16995 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16996 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16997 (parallel [(set (match_dup 10)
16998 (unspec:XF [(match_dup 9) (match_dup 5)]
16999 UNSPEC_FSCALE_FRACT))
17000 (set (match_dup 11)
17001 (unspec:XF [(match_dup 9) (match_dup 5)]
17002 UNSPEC_FSCALE_EXP))])
17003 (set (match_operand:SF 0 "register_operand" "")
17004 (float_truncate:SF (match_dup 10)))]
17005 "TARGET_USE_FANCY_MATH_387
17006 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17007 && flag_unsafe_math_optimizations"
17008{
17009 rtx temp;
17010 int i;
17011
17012 for (i=2; i<12; i++)
17013 operands[i] = gen_reg_rtx (XFmode);
17014 temp = standard_80387_constant_rtx (5); /* fldl2e */
17015 emit_move_insn (operands[3], temp);
17016 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17017})
17018
17019(define_expand "expdf2"
17020 [(set (match_dup 2)
17021 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17022 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17023 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17024 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17025 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17026 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17027 (parallel [(set (match_dup 10)
17028 (unspec:XF [(match_dup 9) (match_dup 5)]
17029 UNSPEC_FSCALE_FRACT))
17030 (set (match_dup 11)
17031 (unspec:XF [(match_dup 9) (match_dup 5)]
17032 UNSPEC_FSCALE_EXP))])
17033 (set (match_operand:DF 0 "register_operand" "")
17034 (float_truncate:DF (match_dup 10)))]
17035 "TARGET_USE_FANCY_MATH_387
17036 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17037 && flag_unsafe_math_optimizations"
17038{
17039 rtx temp;
17040 int i;
17041
17042 for (i=2; i<12; i++)
17043 operands[i] = gen_reg_rtx (XFmode);
17044 temp = standard_80387_constant_rtx (5); /* fldl2e */
17045 emit_move_insn (operands[3], temp);
17046 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17047})
17048
17049(define_expand "expxf2"
17050 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17051 (match_dup 2)))
17052 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17053 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17054 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17055 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17056 (parallel [(set (match_operand:XF 0 "register_operand" "")
17057 (unspec:XF [(match_dup 8) (match_dup 4)]
17058 UNSPEC_FSCALE_FRACT))
17059 (set (match_dup 9)
17060 (unspec:XF [(match_dup 8) (match_dup 4)]
17061 UNSPEC_FSCALE_EXP))])]
17062 "TARGET_USE_FANCY_MATH_387
17063 && flag_unsafe_math_optimizations"
17064{
17065 rtx temp;
17066 int i;
17067
17068 for (i=2; i<10; i++)
17069 operands[i] = gen_reg_rtx (XFmode);
17070 temp = standard_80387_constant_rtx (5); /* fldl2e */
17071 emit_move_insn (operands[2], temp);
17072 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17073})
17074
17075(define_expand "exp10sf2"
17076 [(set (match_dup 2)
17077 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17078 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17079 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17080 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17081 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17082 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17083 (parallel [(set (match_dup 10)
17084 (unspec:XF [(match_dup 9) (match_dup 5)]
17085 UNSPEC_FSCALE_FRACT))
17086 (set (match_dup 11)
17087 (unspec:XF [(match_dup 9) (match_dup 5)]
17088 UNSPEC_FSCALE_EXP))])
17089 (set (match_operand:SF 0 "register_operand" "")
17090 (float_truncate:SF (match_dup 10)))]
17091 "TARGET_USE_FANCY_MATH_387
17092 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17093 && flag_unsafe_math_optimizations"
17094{
17095 rtx temp;
17096 int i;
17097
17098 for (i=2; i<12; i++)
17099 operands[i] = gen_reg_rtx (XFmode);
17100 temp = standard_80387_constant_rtx (6); /* fldl2t */
17101 emit_move_insn (operands[3], temp);
17102 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17103})
17104
17105(define_expand "exp10df2"
17106 [(set (match_dup 2)
17107 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17108 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17109 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17110 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17111 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17112 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17113 (parallel [(set (match_dup 10)
17114 (unspec:XF [(match_dup 9) (match_dup 5)]
17115 UNSPEC_FSCALE_FRACT))
17116 (set (match_dup 11)
17117 (unspec:XF [(match_dup 9) (match_dup 5)]
17118 UNSPEC_FSCALE_EXP))])
17119 (set (match_operand:DF 0 "register_operand" "")
17120 (float_truncate:DF (match_dup 10)))]
17121 "TARGET_USE_FANCY_MATH_387
17122 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17123 && flag_unsafe_math_optimizations"
17124{
17125 rtx temp;
17126 int i;
17127
17128 for (i=2; i<12; i++)
17129 operands[i] = gen_reg_rtx (XFmode);
17130 temp = standard_80387_constant_rtx (6); /* fldl2t */
17131 emit_move_insn (operands[3], temp);
17132 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17133})
17134
17135(define_expand "exp10xf2"
17136 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17137 (match_dup 2)))
17138 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17139 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17140 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17141 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17142 (parallel [(set (match_operand:XF 0 "register_operand" "")
17143 (unspec:XF [(match_dup 8) (match_dup 4)]
17144 UNSPEC_FSCALE_FRACT))
17145 (set (match_dup 9)
17146 (unspec:XF [(match_dup 8) (match_dup 4)]
17147 UNSPEC_FSCALE_EXP))])]
17148 "TARGET_USE_FANCY_MATH_387
17149 && flag_unsafe_math_optimizations"
17150{
17151 rtx temp;
17152 int i;
17153
17154 for (i=2; i<10; i++)
17155 operands[i] = gen_reg_rtx (XFmode);
17156 temp = standard_80387_constant_rtx (6); /* fldl2t */
17157 emit_move_insn (operands[2], temp);
17158 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17159})
17160
17161(define_expand "exp2sf2"
17162 [(set (match_dup 2)
17163 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17164 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17165 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17166 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17167 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17168 (parallel [(set (match_dup 8)
17169 (unspec:XF [(match_dup 7) (match_dup 3)]
17170 UNSPEC_FSCALE_FRACT))
17171 (set (match_dup 9)
17172 (unspec:XF [(match_dup 7) (match_dup 3)]
17173 UNSPEC_FSCALE_EXP))])
17174 (set (match_operand:SF 0 "register_operand" "")
17175 (float_truncate:SF (match_dup 8)))]
17176 "TARGET_USE_FANCY_MATH_387
17177 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17178 && flag_unsafe_math_optimizations"
17179{
17180 int i;
17181
17182 for (i=2; i<10; i++)
17183 operands[i] = gen_reg_rtx (XFmode);
17184 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17185})
17186
17187(define_expand "exp2df2"
17188 [(set (match_dup 2)
17189 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17190 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17191 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17192 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17193 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17194 (parallel [(set (match_dup 8)
17195 (unspec:XF [(match_dup 7) (match_dup 3)]
17196 UNSPEC_FSCALE_FRACT))
17197 (set (match_dup 9)
17198 (unspec:XF [(match_dup 7) (match_dup 3)]
17199 UNSPEC_FSCALE_EXP))])
17200 (set (match_operand:DF 0 "register_operand" "")
17201 (float_truncate:DF (match_dup 8)))]
17202 "TARGET_USE_FANCY_MATH_387
17203 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17204 && flag_unsafe_math_optimizations"
17205{
17206 int i;
17207
17208 for (i=2; i<10; i++)
17209 operands[i] = gen_reg_rtx (XFmode);
17210 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17211})
17212
17213(define_expand "exp2xf2"
17214 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
17215 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17216 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17217 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17218 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17219 (parallel [(set (match_operand:XF 0 "register_operand" "")
17220 (unspec:XF [(match_dup 7) (match_dup 3)]
17221 UNSPEC_FSCALE_FRACT))
17222 (set (match_dup 8)
17223 (unspec:XF [(match_dup 7) (match_dup 3)]
17224 UNSPEC_FSCALE_EXP))])]
17225 "TARGET_USE_FANCY_MATH_387
17226 && flag_unsafe_math_optimizations"
17227{
17228 int i;
17229
17230 for (i=2; i<9; i++)
17231 operands[i] = gen_reg_rtx (XFmode);
17232 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17233})
17234
17235(define_expand "expm1df2"
17236 [(set (match_dup 2)
17237 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17238 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17239 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17240 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17241 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17242 (parallel [(set (match_dup 8)
17243 (unspec:XF [(match_dup 7) (match_dup 5)]
17244 UNSPEC_FSCALE_FRACT))
17245 (set (match_dup 9)
17246 (unspec:XF [(match_dup 7) (match_dup 5)]
17247 UNSPEC_FSCALE_EXP))])
17248 (parallel [(set (match_dup 11)
17249 (unspec:XF [(match_dup 10) (match_dup 9)]
17250 UNSPEC_FSCALE_FRACT))
17251 (set (match_dup 12)
17252 (unspec:XF [(match_dup 10) (match_dup 9)]
17253 UNSPEC_FSCALE_EXP))])
17254 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17255 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17256 (set (match_operand:DF 0 "register_operand" "")
17257 (float_truncate:DF (match_dup 14)))]
17258 "TARGET_USE_FANCY_MATH_387
17259 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17260 && flag_unsafe_math_optimizations"
17261{
17262 rtx temp;
17263 int i;
17264
17265 for (i=2; i<15; i++)
17266 operands[i] = gen_reg_rtx (XFmode);
17267 temp = standard_80387_constant_rtx (5); /* fldl2e */
17268 emit_move_insn (operands[3], temp);
17269 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17270})
17271
17272(define_expand "expm1sf2"
17273 [(set (match_dup 2)
17274 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17275 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17276 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17277 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17278 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17279 (parallel [(set (match_dup 8)
17280 (unspec:XF [(match_dup 7) (match_dup 5)]
17281 UNSPEC_FSCALE_FRACT))
17282 (set (match_dup 9)
17283 (unspec:XF [(match_dup 7) (match_dup 5)]
17284 UNSPEC_FSCALE_EXP))])
17285 (parallel [(set (match_dup 11)
17286 (unspec:XF [(match_dup 10) (match_dup 9)]
17287 UNSPEC_FSCALE_FRACT))
17288 (set (match_dup 12)
17289 (unspec:XF [(match_dup 10) (match_dup 9)]
17290 UNSPEC_FSCALE_EXP))])
17291 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17292 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17293 (set (match_operand:SF 0 "register_operand" "")
17294 (float_truncate:SF (match_dup 14)))]
17295 "TARGET_USE_FANCY_MATH_387
17296 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17297 && flag_unsafe_math_optimizations"
17298{
17299 rtx temp;
17300 int i;
17301
17302 for (i=2; i<15; i++)
17303 operands[i] = gen_reg_rtx (XFmode);
17304 temp = standard_80387_constant_rtx (5); /* fldl2e */
17305 emit_move_insn (operands[3], temp);
17306 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17307})
17308
17309(define_expand "expm1xf2"
17310 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17311 (match_dup 2)))
17312 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17313 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17314 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17315 (parallel [(set (match_dup 7)
17316 (unspec:XF [(match_dup 6) (match_dup 4)]
17317 UNSPEC_FSCALE_FRACT))
17318 (set (match_dup 8)
17319 (unspec:XF [(match_dup 6) (match_dup 4)]
17320 UNSPEC_FSCALE_EXP))])
17321 (parallel [(set (match_dup 10)
17322 (unspec:XF [(match_dup 9) (match_dup 8)]
17323 UNSPEC_FSCALE_FRACT))
17324 (set (match_dup 11)
17325 (unspec:XF [(match_dup 9) (match_dup 8)]
17326 UNSPEC_FSCALE_EXP))])
17327 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17328 (set (match_operand:XF 0 "register_operand" "")
17329 (plus:XF (match_dup 12) (match_dup 7)))]
17330 "TARGET_USE_FANCY_MATH_387
17331 && flag_unsafe_math_optimizations"
17332{
17333 rtx temp;
17334 int i;
17335
17336 for (i=2; i<13; i++)
17337 operands[i] = gen_reg_rtx (XFmode);
17338 temp = standard_80387_constant_rtx (5); /* fldl2e */
17339 emit_move_insn (operands[2], temp);
17340 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17341})
17342
17343(define_expand "ldexpdf3"
17344 [(set (match_dup 3)
17345 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17346 (set (match_dup 4)
17347 (float:XF (match_operand:SI 2 "register_operand" "")))
17348 (parallel [(set (match_dup 5)
17349 (unspec:XF [(match_dup 3) (match_dup 4)]
17350 UNSPEC_FSCALE_FRACT))
17351 (set (match_dup 6)
17352 (unspec:XF [(match_dup 3) (match_dup 4)]
17353 UNSPEC_FSCALE_EXP))])
17354 (set (match_operand:DF 0 "register_operand" "")
17355 (float_truncate:DF (match_dup 5)))]
17356 "TARGET_USE_FANCY_MATH_387
17357 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17358 && flag_unsafe_math_optimizations"
17359{
17360 int i;
17361
17362 for (i=3; i<7; i++)
17363 operands[i] = gen_reg_rtx (XFmode);
17364})
17365
17366(define_expand "ldexpsf3"
17367 [(set (match_dup 3)
17368 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17369 (set (match_dup 4)
17370 (float:XF (match_operand:SI 2 "register_operand" "")))
17371 (parallel [(set (match_dup 5)
17372 (unspec:XF [(match_dup 3) (match_dup 4)]
17373 UNSPEC_FSCALE_FRACT))
17374 (set (match_dup 6)
17375 (unspec:XF [(match_dup 3) (match_dup 4)]
17376 UNSPEC_FSCALE_EXP))])
17377 (set (match_operand:SF 0 "register_operand" "")
17378 (float_truncate:SF (match_dup 5)))]
17379 "TARGET_USE_FANCY_MATH_387
17380 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17381 && flag_unsafe_math_optimizations"
17382{
17383 int i;
17384
17385 for (i=3; i<7; i++)
17386 operands[i] = gen_reg_rtx (XFmode);
17387})
17388
17389(define_expand "ldexpxf3"
17390 [(set (match_dup 3)
17391 (float:XF (match_operand:SI 2 "register_operand" "")))
17392 (parallel [(set (match_operand:XF 0 " register_operand" "")
17393 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17394 (match_dup 3)]
17395 UNSPEC_FSCALE_FRACT))
17396 (set (match_dup 4)
17397 (unspec:XF [(match_dup 1) (match_dup 3)]
17398 UNSPEC_FSCALE_EXP))])]
17399 "TARGET_USE_FANCY_MATH_387
17400 && flag_unsafe_math_optimizations"
17401{
17402 int i;
17403
17404 for (i=3; i<5; i++)
17405 operands[i] = gen_reg_rtx (XFmode);
17406})
17407
17408
17409(define_insn "frndintxf2"
17410 [(set (match_operand:XF 0 "register_operand" "=f")
17411 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17412 UNSPEC_FRNDINT))]
17413 "TARGET_USE_FANCY_MATH_387
17414 && flag_unsafe_math_optimizations"
17415 "frndint"
17416 [(set_attr "type" "fpspc")
17417 (set_attr "mode" "XF")])
17418
17419(define_expand "rintdf2"
17420 [(use (match_operand:DF 0 "register_operand" ""))
17421 (use (match_operand:DF 1 "register_operand" ""))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17424 && flag_unsafe_math_optimizations"
17425{
17426 rtx op0 = gen_reg_rtx (XFmode);
17427 rtx op1 = gen_reg_rtx (XFmode);
17428
17429 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17430 emit_insn (gen_frndintxf2 (op0, op1));
17431
17432 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17433 DONE;
17434})
17435
17436(define_expand "rintsf2"
17437 [(use (match_operand:SF 0 "register_operand" ""))
17438 (use (match_operand:SF 1 "register_operand" ""))]
17439 "TARGET_USE_FANCY_MATH_387
17440 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17441 && flag_unsafe_math_optimizations"
17442{
17443 rtx op0 = gen_reg_rtx (XFmode);
17444 rtx op1 = gen_reg_rtx (XFmode);
17445
17446 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17447 emit_insn (gen_frndintxf2 (op0, op1));
17448
17449 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17450 DONE;
17451})
17452
17453(define_expand "rintxf2"
17454 [(use (match_operand:XF 0 "register_operand" ""))
17455 (use (match_operand:XF 1 "register_operand" ""))]
17456 "TARGET_USE_FANCY_MATH_387
17457 && flag_unsafe_math_optimizations"
17458{
17459 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17460 DONE;
17461})
17462
17463(define_insn_and_split "*fistdi2_1"
17464 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17465 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17466 UNSPEC_FIST))]
17467 "TARGET_USE_FANCY_MATH_387
17468 && flag_unsafe_math_optimizations
17469 && !(reload_completed || reload_in_progress)"
17470 "#"
17471 "&& 1"
17472 [(const_int 0)]
17473{
17474 if (memory_operand (operands[0], VOIDmode))
17475 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17476 else
17477 {
17478 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17479 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17480 operands[2]));
17481 }
17482 DONE;
17483}
17484 [(set_attr "type" "fpspc")
17485 (set_attr "mode" "DI")])
17486
17487(define_insn "fistdi2"
17488 [(set (match_operand:DI 0 "memory_operand" "=m")
17489 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17490 UNSPEC_FIST))
17491 (clobber (match_scratch:XF 2 "=&1f"))]
17492 "TARGET_USE_FANCY_MATH_387
17493 && flag_unsafe_math_optimizations"
17494 "* return output_fix_trunc (insn, operands, 0);"
17495 [(set_attr "type" "fpspc")
17496 (set_attr "mode" "DI")])
17497
17498(define_insn "fistdi2_with_temp"
17499 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17500 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17501 UNSPEC_FIST))
17502 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17503 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17504 "TARGET_USE_FANCY_MATH_387
17505 && flag_unsafe_math_optimizations"
17506 "#"
17507 [(set_attr "type" "fpspc")
17508 (set_attr "mode" "DI")])
17509
17510(define_split
17511 [(set (match_operand:DI 0 "register_operand" "")
17512 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17513 UNSPEC_FIST))
17514 (clobber (match_operand:DI 2 "memory_operand" ""))
17515 (clobber (match_scratch 3 ""))]
17516 "reload_completed"
17517 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17518 (clobber (match_dup 3))])
17519 (set (match_dup 0) (match_dup 2))]
17520 "")
17521
17522(define_split
17523 [(set (match_operand:DI 0 "memory_operand" "")
17524 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17525 UNSPEC_FIST))
17526 (clobber (match_operand:DI 2 "memory_operand" ""))
17527 (clobber (match_scratch 3 ""))]
17528 "reload_completed"
17529 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17530 (clobber (match_dup 3))])]
17531 "")
17532
17533(define_insn_and_split "*fist<mode>2_1"
17534 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17535 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17536 UNSPEC_FIST))]
17537 "TARGET_USE_FANCY_MATH_387
17538 && flag_unsafe_math_optimizations
17539 && !(reload_completed || reload_in_progress)"
17540 "#"
17541 "&& 1"
17542 [(const_int 0)]
17543{
17544 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17545 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17546 operands[2]));
17547 DONE;
17548}
17549 [(set_attr "type" "fpspc")
17550 (set_attr "mode" "<MODE>")])
17551
17552(define_insn "fist<mode>2"
17553 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17554 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17555 UNSPEC_FIST))]
17556 "TARGET_USE_FANCY_MATH_387
17557 && flag_unsafe_math_optimizations"
17558 "* return output_fix_trunc (insn, operands, 0);"
17559 [(set_attr "type" "fpspc")
17560 (set_attr "mode" "<MODE>")])
17561
17562(define_insn "fist<mode>2_with_temp"
17563 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17564 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17565 UNSPEC_FIST))
17566 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17567 "TARGET_USE_FANCY_MATH_387
17568 && flag_unsafe_math_optimizations"
17569 "#"
17570 [(set_attr "type" "fpspc")
17571 (set_attr "mode" "<MODE>")])
17572
17573(define_split
17574 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17575 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17576 UNSPEC_FIST))
17577 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17578 "reload_completed"
17579 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17580 UNSPEC_FIST))
17581 (set (match_dup 0) (match_dup 2))]
17582 "")
17583
17584(define_split
17585 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17586 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17587 UNSPEC_FIST))
17588 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17589 "reload_completed"
17590 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17591 UNSPEC_FIST))]
17592 "")
17593
17594(define_expand "lrint<mode>2"
17595 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17596 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17597 UNSPEC_FIST))]
17598 "TARGET_USE_FANCY_MATH_387
17599 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17600 && flag_unsafe_math_optimizations"
17601 "")
17602
17603;; Rounding mode control word calculation could clobber FLAGS_REG.
17604(define_insn_and_split "frndintxf2_floor"
17605 [(set (match_operand:XF 0 "register_operand" "=f")
17606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17607 UNSPEC_FRNDINT_FLOOR))
17608 (clobber (reg:CC FLAGS_REG))]
17609 "TARGET_USE_FANCY_MATH_387
17610 && flag_unsafe_math_optimizations
17611 && !(reload_completed || reload_in_progress)"
17612 "#"
17613 "&& 1"
17614 [(const_int 0)]
17615{
17616 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17617
17618 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17619 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17620
17621 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17622 operands[2], operands[3]));
17623 DONE;
17624}
17625 [(set_attr "type" "frndint")
17626 (set_attr "i387_cw" "floor")
17627 (set_attr "mode" "XF")])
17628
17629(define_insn "frndintxf2_floor_i387"
17630 [(set (match_operand:XF 0 "register_operand" "=f")
17631 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17632 UNSPEC_FRNDINT_FLOOR))
17633 (use (match_operand:HI 2 "memory_operand" "m"))
17634 (use (match_operand:HI 3 "memory_operand" "m"))]
17635 "TARGET_USE_FANCY_MATH_387
17636 && flag_unsafe_math_optimizations"
17637 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17638 [(set_attr "type" "frndint")
17639 (set_attr "i387_cw" "floor")
17640 (set_attr "mode" "XF")])
17641
17642(define_expand "floorxf2"
17643 [(use (match_operand:XF 0 "register_operand" ""))
17644 (use (match_operand:XF 1 "register_operand" ""))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && flag_unsafe_math_optimizations"
17647{
17648 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17649 DONE;
17650})
17651
17652(define_expand "floordf2"
17653 [(use (match_operand:DF 0 "register_operand" ""))
17654 (use (match_operand:DF 1 "register_operand" ""))]
17655 "TARGET_USE_FANCY_MATH_387
17656 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17657 && flag_unsafe_math_optimizations"
17658{
17659 rtx op0 = gen_reg_rtx (XFmode);
17660 rtx op1 = gen_reg_rtx (XFmode);
17661
17662 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17663 emit_insn (gen_frndintxf2_floor (op0, op1));
17664
17665 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17666 DONE;
17667})
17668
17669(define_expand "floorsf2"
17670 [(use (match_operand:SF 0 "register_operand" ""))
17671 (use (match_operand:SF 1 "register_operand" ""))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17674 && flag_unsafe_math_optimizations"
17675{
17676 rtx op0 = gen_reg_rtx (XFmode);
17677 rtx op1 = gen_reg_rtx (XFmode);
17678
17679 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17680 emit_insn (gen_frndintxf2_floor (op0, op1));
17681
17682 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17683 DONE;
17684})
17685
17686(define_insn_and_split "*fist<mode>2_floor_1"
17687 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17688 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17689 UNSPEC_FIST_FLOOR))
17690 (clobber (reg:CC FLAGS_REG))]
17691 "TARGET_USE_FANCY_MATH_387
17692 && flag_unsafe_math_optimizations
17693 && !(reload_completed || reload_in_progress)"
17694 "#"
17695 "&& 1"
17696 [(const_int 0)]
17697{
17698 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17699
17700 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17701 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17702 if (memory_operand (operands[0], VOIDmode))
17703 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17704 operands[2], operands[3]));
17705 else
17706 {
17707 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17708 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17709 operands[2], operands[3],
17710 operands[4]));
17711 }
17712 DONE;
17713}
17714 [(set_attr "type" "fistp")
17715 (set_attr "i387_cw" "floor")
17716 (set_attr "mode" "<MODE>")])
17717
17718(define_insn "fistdi2_floor"
17719 [(set (match_operand:DI 0 "memory_operand" "=m")
17720 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17721 UNSPEC_FIST_FLOOR))
17722 (use (match_operand:HI 2 "memory_operand" "m"))
17723 (use (match_operand:HI 3 "memory_operand" "m"))
17724 (clobber (match_scratch:XF 4 "=&1f"))]
17725 "TARGET_USE_FANCY_MATH_387
17726 && flag_unsafe_math_optimizations"
17727 "* return output_fix_trunc (insn, operands, 0);"
17728 [(set_attr "type" "fistp")
17729 (set_attr "i387_cw" "floor")
17730 (set_attr "mode" "DI")])
17731
17732(define_insn "fistdi2_floor_with_temp"
17733 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17734 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17735 UNSPEC_FIST_FLOOR))
17736 (use (match_operand:HI 2 "memory_operand" "m,m"))
17737 (use (match_operand:HI 3 "memory_operand" "m,m"))
17738 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17739 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17740 "TARGET_USE_FANCY_MATH_387
17741 && flag_unsafe_math_optimizations"
17742 "#"
17743 [(set_attr "type" "fistp")
17744 (set_attr "i387_cw" "floor")
17745 (set_attr "mode" "DI")])
17746
17747(define_split
17748 [(set (match_operand:DI 0 "register_operand" "")
17749 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17750 UNSPEC_FIST_FLOOR))
17751 (use (match_operand:HI 2 "memory_operand" ""))
17752 (use (match_operand:HI 3 "memory_operand" ""))
17753 (clobber (match_operand:DI 4 "memory_operand" ""))
17754 (clobber (match_scratch 5 ""))]
17755 "reload_completed"
17756 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17757 (use (match_dup 2))
17758 (use (match_dup 3))
17759 (clobber (match_dup 5))])
17760 (set (match_dup 0) (match_dup 4))]
17761 "")
17762
17763(define_split
17764 [(set (match_operand:DI 0 "memory_operand" "")
17765 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17766 UNSPEC_FIST_FLOOR))
17767 (use (match_operand:HI 2 "memory_operand" ""))
17768 (use (match_operand:HI 3 "memory_operand" ""))
17769 (clobber (match_operand:DI 4 "memory_operand" ""))
17770 (clobber (match_scratch 5 ""))]
17771 "reload_completed"
17772 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17773 (use (match_dup 2))
17774 (use (match_dup 3))
17775 (clobber (match_dup 5))])]
17776 "")
17777
17778(define_insn "fist<mode>2_floor"
17779 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17780 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17781 UNSPEC_FIST_FLOOR))
17782 (use (match_operand:HI 2 "memory_operand" "m"))
17783 (use (match_operand:HI 3 "memory_operand" "m"))]
17784 "TARGET_USE_FANCY_MATH_387
17785 && flag_unsafe_math_optimizations"
17786 "* return output_fix_trunc (insn, operands, 0);"
17787 [(set_attr "type" "fistp")
17788 (set_attr "i387_cw" "floor")
17789 (set_attr "mode" "<MODE>")])
17790
17791(define_insn "fist<mode>2_floor_with_temp"
17792 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17793 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17794 UNSPEC_FIST_FLOOR))
17795 (use (match_operand:HI 2 "memory_operand" "m,m"))
17796 (use (match_operand:HI 3 "memory_operand" "m,m"))
17797 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17798 "TARGET_USE_FANCY_MATH_387
17799 && flag_unsafe_math_optimizations"
17800 "#"
17801 [(set_attr "type" "fistp")
17802 (set_attr "i387_cw" "floor")
17803 (set_attr "mode" "<MODE>")])
17804
17805(define_split
17806 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17807 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17808 UNSPEC_FIST_FLOOR))
17809 (use (match_operand:HI 2 "memory_operand" ""))
17810 (use (match_operand:HI 3 "memory_operand" ""))
17811 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17812 "reload_completed"
17813 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17814 UNSPEC_FIST_FLOOR))
17815 (use (match_dup 2))
17816 (use (match_dup 3))])
17817 (set (match_dup 0) (match_dup 4))]
17818 "")
17819
17820(define_split
17821 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17822 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17823 UNSPEC_FIST_FLOOR))
17824 (use (match_operand:HI 2 "memory_operand" ""))
17825 (use (match_operand:HI 3 "memory_operand" ""))
17826 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17827 "reload_completed"
17828 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17829 UNSPEC_FIST_FLOOR))
17830 (use (match_dup 2))
17831 (use (match_dup 3))])]
17832 "")
17833
17834(define_expand "lfloor<mode>2"
17835 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17836 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17837 UNSPEC_FIST_FLOOR))
17838 (clobber (reg:CC FLAGS_REG))])]
17839 "TARGET_USE_FANCY_MATH_387
17840 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17841 && flag_unsafe_math_optimizations"
17842 "")
17843
17844;; Rounding mode control word calculation could clobber FLAGS_REG.
17845(define_insn_and_split "frndintxf2_ceil"
17846 [(set (match_operand:XF 0 "register_operand" "=f")
17847 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17848 UNSPEC_FRNDINT_CEIL))
17849 (clobber (reg:CC FLAGS_REG))]
17850 "TARGET_USE_FANCY_MATH_387
17851 && flag_unsafe_math_optimizations
17852 && !(reload_completed || reload_in_progress)"
17853 "#"
17854 "&& 1"
17855 [(const_int 0)]
17856{
17857 ix86_optimize_mode_switching[I387_CEIL] = 1;
17858
17859 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17860 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17861
17862 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17863 operands[2], operands[3]));
17864 DONE;
17865}
17866 [(set_attr "type" "frndint")
17867 (set_attr "i387_cw" "ceil")
17868 (set_attr "mode" "XF")])
17869
17870(define_insn "frndintxf2_ceil_i387"
17871 [(set (match_operand:XF 0 "register_operand" "=f")
17872 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17873 UNSPEC_FRNDINT_CEIL))
17874 (use (match_operand:HI 2 "memory_operand" "m"))
17875 (use (match_operand:HI 3 "memory_operand" "m"))]
17876 "TARGET_USE_FANCY_MATH_387
17877 && flag_unsafe_math_optimizations"
17878 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17879 [(set_attr "type" "frndint")
17880 (set_attr "i387_cw" "ceil")
17881 (set_attr "mode" "XF")])
17882
17883(define_expand "ceilxf2"
17884 [(use (match_operand:XF 0 "register_operand" ""))
17885 (use (match_operand:XF 1 "register_operand" ""))]
17886 "TARGET_USE_FANCY_MATH_387
17887 && flag_unsafe_math_optimizations"
17888{
17889 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17890 DONE;
17891})
17892
17893(define_expand "ceildf2"
17894 [(use (match_operand:DF 0 "register_operand" ""))
17895 (use (match_operand:DF 1 "register_operand" ""))]
17896 "TARGET_USE_FANCY_MATH_387
17897 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17898 && flag_unsafe_math_optimizations"
17899{
17900 rtx op0 = gen_reg_rtx (XFmode);
17901 rtx op1 = gen_reg_rtx (XFmode);
17902
17903 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17904 emit_insn (gen_frndintxf2_ceil (op0, op1));
17905
17906 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17907 DONE;
17908})
17909
17910(define_expand "ceilsf2"
17911 [(use (match_operand:SF 0 "register_operand" ""))
17912 (use (match_operand:SF 1 "register_operand" ""))]
17913 "TARGET_USE_FANCY_MATH_387
17914 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17915 && flag_unsafe_math_optimizations"
17916{
17917 rtx op0 = gen_reg_rtx (XFmode);
17918 rtx op1 = gen_reg_rtx (XFmode);
17919
17920 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17921 emit_insn (gen_frndintxf2_ceil (op0, op1));
17922
17923 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17924 DONE;
17925})
17926
17927(define_insn_and_split "*fist<mode>2_ceil_1"
17928 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17929 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17930 UNSPEC_FIST_CEIL))
17931 (clobber (reg:CC FLAGS_REG))]
17932 "TARGET_USE_FANCY_MATH_387
17933 && flag_unsafe_math_optimizations
17934 && !(reload_completed || reload_in_progress)"
17935 "#"
17936 "&& 1"
17937 [(const_int 0)]
17938{
17939 ix86_optimize_mode_switching[I387_CEIL] = 1;
17940
17941 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17942 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17943 if (memory_operand (operands[0], VOIDmode))
17944 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17945 operands[2], operands[3]));
17946 else
17947 {
17948 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17949 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17950 operands[2], operands[3],
17951 operands[4]));
17952 }
17953 DONE;
17954}
17955 [(set_attr "type" "fistp")
17956 (set_attr "i387_cw" "ceil")
17957 (set_attr "mode" "<MODE>")])
17958
17959(define_insn "fistdi2_ceil"
17960 [(set (match_operand:DI 0 "memory_operand" "=m")
17961 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17962 UNSPEC_FIST_CEIL))
17963 (use (match_operand:HI 2 "memory_operand" "m"))
17964 (use (match_operand:HI 3 "memory_operand" "m"))
17965 (clobber (match_scratch:XF 4 "=&1f"))]
17966 "TARGET_USE_FANCY_MATH_387
17967 && flag_unsafe_math_optimizations"
17968 "* return output_fix_trunc (insn, operands, 0);"
17969 [(set_attr "type" "fistp")
17970 (set_attr "i387_cw" "ceil")
17971 (set_attr "mode" "DI")])
17972
17973(define_insn "fistdi2_ceil_with_temp"
17974 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17975 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17976 UNSPEC_FIST_CEIL))
17977 (use (match_operand:HI 2 "memory_operand" "m,m"))
17978 (use (match_operand:HI 3 "memory_operand" "m,m"))
17979 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17980 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17981 "TARGET_USE_FANCY_MATH_387
17982 && flag_unsafe_math_optimizations"
17983 "#"
17984 [(set_attr "type" "fistp")
17985 (set_attr "i387_cw" "ceil")
17986 (set_attr "mode" "DI")])
17987
17988(define_split
17989 [(set (match_operand:DI 0 "register_operand" "")
17990 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17991 UNSPEC_FIST_CEIL))
17992 (use (match_operand:HI 2 "memory_operand" ""))
17993 (use (match_operand:HI 3 "memory_operand" ""))
17994 (clobber (match_operand:DI 4 "memory_operand" ""))
17995 (clobber (match_scratch 5 ""))]
17996 "reload_completed"
17997 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17998 (use (match_dup 2))
17999 (use (match_dup 3))
18000 (clobber (match_dup 5))])
18001 (set (match_dup 0) (match_dup 4))]
18002 "")
18003
18004(define_split
18005 [(set (match_operand:DI 0 "memory_operand" "")
18006 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18007 UNSPEC_FIST_CEIL))
18008 (use (match_operand:HI 2 "memory_operand" ""))
18009 (use (match_operand:HI 3 "memory_operand" ""))
18010 (clobber (match_operand:DI 4 "memory_operand" ""))
18011 (clobber (match_scratch 5 ""))]
18012 "reload_completed"
18013 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18014 (use (match_dup 2))
18015 (use (match_dup 3))
18016 (clobber (match_dup 5))])]
18017 "")
18018
18019(define_insn "fist<mode>2_ceil"
18020 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18021 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18022 UNSPEC_FIST_CEIL))
18023 (use (match_operand:HI 2 "memory_operand" "m"))
18024 (use (match_operand:HI 3 "memory_operand" "m"))]
18025 "TARGET_USE_FANCY_MATH_387
18026 && flag_unsafe_math_optimizations"
18027 "* return output_fix_trunc (insn, operands, 0);"
18028 [(set_attr "type" "fistp")
18029 (set_attr "i387_cw" "ceil")
18030 (set_attr "mode" "<MODE>")])
18031
18032(define_insn "fist<mode>2_ceil_with_temp"
18033 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18034 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18035 UNSPEC_FIST_CEIL))
18036 (use (match_operand:HI 2 "memory_operand" "m,m"))
18037 (use (match_operand:HI 3 "memory_operand" "m,m"))
18038 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18039 "TARGET_USE_FANCY_MATH_387
18040 && flag_unsafe_math_optimizations"
18041 "#"
18042 [(set_attr "type" "fistp")
18043 (set_attr "i387_cw" "ceil")
18044 (set_attr "mode" "<MODE>")])
18045
18046(define_split
18047 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18048 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18049 UNSPEC_FIST_CEIL))
18050 (use (match_operand:HI 2 "memory_operand" ""))
18051 (use (match_operand:HI 3 "memory_operand" ""))
18052 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18053 "reload_completed"
18054 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18055 UNSPEC_FIST_CEIL))
18056 (use (match_dup 2))
18057 (use (match_dup 3))])
18058 (set (match_dup 0) (match_dup 4))]
18059 "")
18060
18061(define_split
18062 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18063 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18064 UNSPEC_FIST_CEIL))
18065 (use (match_operand:HI 2 "memory_operand" ""))
18066 (use (match_operand:HI 3 "memory_operand" ""))
18067 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18068 "reload_completed"
18069 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18070 UNSPEC_FIST_CEIL))
18071 (use (match_dup 2))
18072 (use (match_dup 3))])]
18073 "")
18074
18075(define_expand "lceil<mode>2"
18076 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18077 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18078 UNSPEC_FIST_CEIL))
18079 (clobber (reg:CC FLAGS_REG))])]
18080 "TARGET_USE_FANCY_MATH_387
18081 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18082 && flag_unsafe_math_optimizations"
18083 "")
18084
18085;; Rounding mode control word calculation could clobber FLAGS_REG.
18086(define_insn_and_split "frndintxf2_trunc"
18087 [(set (match_operand:XF 0 "register_operand" "=f")
18088 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18089 UNSPEC_FRNDINT_TRUNC))
18090 (clobber (reg:CC FLAGS_REG))]
18091 "TARGET_USE_FANCY_MATH_387
18092 && flag_unsafe_math_optimizations
18093 && !(reload_completed || reload_in_progress)"
18094 "#"
18095 "&& 1"
18096 [(const_int 0)]
18097{
18098 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18099
18100 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18101 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18102
18103 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18104 operands[2], operands[3]));
18105 DONE;
18106}
18107 [(set_attr "type" "frndint")
18108 (set_attr "i387_cw" "trunc")
18109 (set_attr "mode" "XF")])
18110
18111(define_insn "frndintxf2_trunc_i387"
18112 [(set (match_operand:XF 0 "register_operand" "=f")
18113 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18114 UNSPEC_FRNDINT_TRUNC))
18115 (use (match_operand:HI 2 "memory_operand" "m"))
18116 (use (match_operand:HI 3 "memory_operand" "m"))]
18117 "TARGET_USE_FANCY_MATH_387
18118 && flag_unsafe_math_optimizations"
18119 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18120 [(set_attr "type" "frndint")
18121 (set_attr "i387_cw" "trunc")
18122 (set_attr "mode" "XF")])
18123
18124(define_expand "btruncxf2"
18125 [(use (match_operand:XF 0 "register_operand" ""))
18126 (use (match_operand:XF 1 "register_operand" ""))]
18127 "TARGET_USE_FANCY_MATH_387
18128 && flag_unsafe_math_optimizations"
18129{
18130 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18131 DONE;
18132})
18133
18134(define_expand "btruncdf2"
18135 [(use (match_operand:DF 0 "register_operand" ""))
18136 (use (match_operand:DF 1 "register_operand" ""))]
18137 "TARGET_USE_FANCY_MATH_387
18138 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18139 && flag_unsafe_math_optimizations"
18140{
18141 rtx op0 = gen_reg_rtx (XFmode);
18142 rtx op1 = gen_reg_rtx (XFmode);
18143
18144 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18145 emit_insn (gen_frndintxf2_trunc (op0, op1));
18146
18147 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18148 DONE;
18149})
18150
18151(define_expand "btruncsf2"
18152 [(use (match_operand:SF 0 "register_operand" ""))
18153 (use (match_operand:SF 1 "register_operand" ""))]
18154 "TARGET_USE_FANCY_MATH_387
18155 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18156 && flag_unsafe_math_optimizations"
18157{
18158 rtx op0 = gen_reg_rtx (XFmode);
18159 rtx op1 = gen_reg_rtx (XFmode);
18160
18161 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18162 emit_insn (gen_frndintxf2_trunc (op0, op1));
18163
18164 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18165 DONE;
18166})
18167
18168;; Rounding mode control word calculation could clobber FLAGS_REG.
18169(define_insn_and_split "frndintxf2_mask_pm"
18170 [(set (match_operand:XF 0 "register_operand" "=f")
18171 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18172 UNSPEC_FRNDINT_MASK_PM))
18173 (clobber (reg:CC FLAGS_REG))]
18174 "TARGET_USE_FANCY_MATH_387
18175 && flag_unsafe_math_optimizations
18176 && !(reload_completed || reload_in_progress)"
18177 "#"
18178 "&& 1"
18179 [(const_int 0)]
18180{
18181 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18182
18183 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18184 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18185
18186 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18187 operands[2], operands[3]));
18188 DONE;
18189}
18190 [(set_attr "type" "frndint")
18191 (set_attr "i387_cw" "mask_pm")
18192 (set_attr "mode" "XF")])
18193
18194(define_insn "frndintxf2_mask_pm_i387"
18195 [(set (match_operand:XF 0 "register_operand" "=f")
18196 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18197 UNSPEC_FRNDINT_MASK_PM))
18198 (use (match_operand:HI 2 "memory_operand" "m"))
18199 (use (match_operand:HI 3 "memory_operand" "m"))]
18200 "TARGET_USE_FANCY_MATH_387
18201 && flag_unsafe_math_optimizations"
18202 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18203 [(set_attr "type" "frndint")
18204 (set_attr "i387_cw" "mask_pm")
18205 (set_attr "mode" "XF")])
18206
18207(define_expand "nearbyintxf2"
18208 [(use (match_operand:XF 0 "register_operand" ""))
18209 (use (match_operand:XF 1 "register_operand" ""))]
18210 "TARGET_USE_FANCY_MATH_387
18211 && flag_unsafe_math_optimizations"
18212{
18213 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18214
18215 DONE;
18216})
18217
18218(define_expand "nearbyintdf2"
18219 [(use (match_operand:DF 0 "register_operand" ""))
18220 (use (match_operand:DF 1 "register_operand" ""))]
18221 "TARGET_USE_FANCY_MATH_387
18222 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18223 && flag_unsafe_math_optimizations"
18224{
18225 rtx op0 = gen_reg_rtx (XFmode);
18226 rtx op1 = gen_reg_rtx (XFmode);
18227
18228 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18229 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18230
18231 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18232 DONE;
18233})
18234
18235(define_expand "nearbyintsf2"
18236 [(use (match_operand:SF 0 "register_operand" ""))
18237 (use (match_operand:SF 1 "register_operand" ""))]
18238 "TARGET_USE_FANCY_MATH_387
18239 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18240 && flag_unsafe_math_optimizations"
18241{
18242 rtx op0 = gen_reg_rtx (XFmode);
18243 rtx op1 = gen_reg_rtx (XFmode);
18244
18245 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18246 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18247
18248 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18249 DONE;
18250})
18251
18252
18253;; Block operation instructions
18254
18255(define_insn "cld"
18256 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18257 ""
18258 "cld"
18259 [(set_attr "type" "cld")])
18260
18261(define_expand "movmemsi"
18262 [(use (match_operand:BLK 0 "memory_operand" ""))
18263 (use (match_operand:BLK 1 "memory_operand" ""))
18264 (use (match_operand:SI 2 "nonmemory_operand" ""))
18265 (use (match_operand:SI 3 "const_int_operand" ""))]
18266 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18267{
18268 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18269 DONE;
18270 else
18271 FAIL;
18272})
18273
18274(define_expand "movmemdi"
18275 [(use (match_operand:BLK 0 "memory_operand" ""))
18276 (use (match_operand:BLK 1 "memory_operand" ""))
18277 (use (match_operand:DI 2 "nonmemory_operand" ""))
18278 (use (match_operand:DI 3 "const_int_operand" ""))]
18279 "TARGET_64BIT"
18280{
18281 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18282 DONE;
18283 else
18284 FAIL;
18285})
18286
18287;; Most CPUs don't like single string operations
18288;; Handle this case here to simplify previous expander.
18289
18290(define_expand "strmov"
18291 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18292 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18293 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18294 (clobber (reg:CC FLAGS_REG))])
18295 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18296 (clobber (reg:CC FLAGS_REG))])]
18297 ""
18298{
18299 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18300
18301 /* If .md ever supports :P for Pmode, these can be directly
18302 in the pattern above. */
18303 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18304 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18305
18306 if (TARGET_SINGLE_STRINGOP || optimize_size)
18307 {
18308 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18309 operands[2], operands[3],
18310 operands[5], operands[6]));
18311 DONE;
18312 }
18313
18314 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18315})
18316
18317(define_expand "strmov_singleop"
18318 [(parallel [(set (match_operand 1 "memory_operand" "")
18319 (match_operand 3 "memory_operand" ""))
18320 (set (match_operand 0 "register_operand" "")
18321 (match_operand 4 "" ""))
18322 (set (match_operand 2 "register_operand" "")
18323 (match_operand 5 "" ""))
18324 (use (reg:SI DIRFLAG_REG))])]
18325 "TARGET_SINGLE_STRINGOP || optimize_size"
18326 "")
18327
18328(define_insn "*strmovdi_rex_1"
18329 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18330 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18331 (set (match_operand:DI 0 "register_operand" "=D")
18332 (plus:DI (match_dup 2)
18333 (const_int 8)))
18334 (set (match_operand:DI 1 "register_operand" "=S")
18335 (plus:DI (match_dup 3)
18336 (const_int 8)))
18337 (use (reg:SI DIRFLAG_REG))]
18338 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18339 "movsq"
18340 [(set_attr "type" "str")
18341 (set_attr "mode" "DI")
18342 (set_attr "memory" "both")])
18343
18344(define_insn "*strmovsi_1"
18345 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18346 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18347 (set (match_operand:SI 0 "register_operand" "=D")
18348 (plus:SI (match_dup 2)
18349 (const_int 4)))
18350 (set (match_operand:SI 1 "register_operand" "=S")
18351 (plus:SI (match_dup 3)
18352 (const_int 4)))
18353 (use (reg:SI DIRFLAG_REG))]
18354 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18355 "{movsl|movsd}"
18356 [(set_attr "type" "str")
18357 (set_attr "mode" "SI")
18358 (set_attr "memory" "both")])
18359
18360(define_insn "*strmovsi_rex_1"
18361 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18362 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18363 (set (match_operand:DI 0 "register_operand" "=D")
18364 (plus:DI (match_dup 2)
18365 (const_int 4)))
18366 (set (match_operand:DI 1 "register_operand" "=S")
18367 (plus:DI (match_dup 3)
18368 (const_int 4)))
18369 (use (reg:SI DIRFLAG_REG))]
18370 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18371 "{movsl|movsd}"
18372 [(set_attr "type" "str")
18373 (set_attr "mode" "SI")
18374 (set_attr "memory" "both")])
18375
18376(define_insn "*strmovhi_1"
18377 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18378 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18379 (set (match_operand:SI 0 "register_operand" "=D")
18380 (plus:SI (match_dup 2)
18381 (const_int 2)))
18382 (set (match_operand:SI 1 "register_operand" "=S")
18383 (plus:SI (match_dup 3)
18384 (const_int 2)))
18385 (use (reg:SI DIRFLAG_REG))]
18386 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18387 "movsw"
18388 [(set_attr "type" "str")
18389 (set_attr "memory" "both")
18390 (set_attr "mode" "HI")])
18391
18392(define_insn "*strmovhi_rex_1"
18393 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18394 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18395 (set (match_operand:DI 0 "register_operand" "=D")
18396 (plus:DI (match_dup 2)
18397 (const_int 2)))
18398 (set (match_operand:DI 1 "register_operand" "=S")
18399 (plus:DI (match_dup 3)
18400 (const_int 2)))
18401 (use (reg:SI DIRFLAG_REG))]
18402 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18403 "movsw"
18404 [(set_attr "type" "str")
18405 (set_attr "memory" "both")
18406 (set_attr "mode" "HI")])
18407
18408(define_insn "*strmovqi_1"
18409 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18410 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18411 (set (match_operand:SI 0 "register_operand" "=D")
18412 (plus:SI (match_dup 2)
18413 (const_int 1)))
18414 (set (match_operand:SI 1 "register_operand" "=S")
18415 (plus:SI (match_dup 3)
18416 (const_int 1)))
18417 (use (reg:SI DIRFLAG_REG))]
18418 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18419 "movsb"
18420 [(set_attr "type" "str")
18421 (set_attr "memory" "both")
18422 (set_attr "mode" "QI")])
18423
18424(define_insn "*strmovqi_rex_1"
18425 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18426 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18427 (set (match_operand:DI 0 "register_operand" "=D")
18428 (plus:DI (match_dup 2)
18429 (const_int 1)))
18430 (set (match_operand:DI 1 "register_operand" "=S")
18431 (plus:DI (match_dup 3)
18432 (const_int 1)))
18433 (use (reg:SI DIRFLAG_REG))]
18434 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18435 "movsb"
18436 [(set_attr "type" "str")
18437 (set_attr "memory" "both")
18438 (set_attr "mode" "QI")])
18439
18440(define_expand "rep_mov"
18441 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18442 (set (match_operand 0 "register_operand" "")
18443 (match_operand 5 "" ""))
18444 (set (match_operand 2 "register_operand" "")
18445 (match_operand 6 "" ""))
18446 (set (match_operand 1 "memory_operand" "")
18447 (match_operand 3 "memory_operand" ""))
18448 (use (match_dup 4))
18449 (use (reg:SI DIRFLAG_REG))])]
18450 ""
18451 "")
18452
18453(define_insn "*rep_movdi_rex64"
18454 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18455 (set (match_operand:DI 0 "register_operand" "=D")
18456 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18457 (const_int 3))
18458 (match_operand:DI 3 "register_operand" "0")))
18459 (set (match_operand:DI 1 "register_operand" "=S")
18460 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18461 (match_operand:DI 4 "register_operand" "1")))
18462 (set (mem:BLK (match_dup 3))
18463 (mem:BLK (match_dup 4)))
18464 (use (match_dup 5))
18465 (use (reg:SI DIRFLAG_REG))]
18466 "TARGET_64BIT"
18467 "{rep\;movsq|rep movsq}"
18468 [(set_attr "type" "str")
18469 (set_attr "prefix_rep" "1")
18470 (set_attr "memory" "both")
18471 (set_attr "mode" "DI")])
18472
18473(define_insn "*rep_movsi"
18474 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18475 (set (match_operand:SI 0 "register_operand" "=D")
18476 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18477 (const_int 2))
18478 (match_operand:SI 3 "register_operand" "0")))
18479 (set (match_operand:SI 1 "register_operand" "=S")
18480 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18481 (match_operand:SI 4 "register_operand" "1")))
18482 (set (mem:BLK (match_dup 3))
18483 (mem:BLK (match_dup 4)))
18484 (use (match_dup 5))
18485 (use (reg:SI DIRFLAG_REG))]
18486 "!TARGET_64BIT"
18487 "{rep\;movsl|rep movsd}"
18488 [(set_attr "type" "str")
18489 (set_attr "prefix_rep" "1")
18490 (set_attr "memory" "both")
18491 (set_attr "mode" "SI")])
18492
18493(define_insn "*rep_movsi_rex64"
18494 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18495 (set (match_operand:DI 0 "register_operand" "=D")
18496 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18497 (const_int 2))
18498 (match_operand:DI 3 "register_operand" "0")))
18499 (set (match_operand:DI 1 "register_operand" "=S")
18500 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18501 (match_operand:DI 4 "register_operand" "1")))
18502 (set (mem:BLK (match_dup 3))
18503 (mem:BLK (match_dup 4)))
18504 (use (match_dup 5))
18505 (use (reg:SI DIRFLAG_REG))]
18506 "TARGET_64BIT"
18507 "{rep\;movsl|rep movsd}"
18508 [(set_attr "type" "str")
18509 (set_attr "prefix_rep" "1")
18510 (set_attr "memory" "both")
18511 (set_attr "mode" "SI")])
18512
18513(define_insn "*rep_movqi"
18514 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18515 (set (match_operand:SI 0 "register_operand" "=D")
18516 (plus:SI (match_operand:SI 3 "register_operand" "0")
18517 (match_operand:SI 5 "register_operand" "2")))
18518 (set (match_operand:SI 1 "register_operand" "=S")
18519 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18520 (set (mem:BLK (match_dup 3))
18521 (mem:BLK (match_dup 4)))
18522 (use (match_dup 5))
18523 (use (reg:SI DIRFLAG_REG))]
18524 "!TARGET_64BIT"
18525 "{rep\;movsb|rep movsb}"
18526 [(set_attr "type" "str")
18527 (set_attr "prefix_rep" "1")
18528 (set_attr "memory" "both")
18529 (set_attr "mode" "SI")])
18530
18531(define_insn "*rep_movqi_rex64"
18532 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18533 (set (match_operand:DI 0 "register_operand" "=D")
18534 (plus:DI (match_operand:DI 3 "register_operand" "0")
18535 (match_operand:DI 5 "register_operand" "2")))
18536 (set (match_operand:DI 1 "register_operand" "=S")
18537 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18538 (set (mem:BLK (match_dup 3))
18539 (mem:BLK (match_dup 4)))
18540 (use (match_dup 5))
18541 (use (reg:SI DIRFLAG_REG))]
18542 "TARGET_64BIT"
18543 "{rep\;movsb|rep movsb}"
18544 [(set_attr "type" "str")
18545 (set_attr "prefix_rep" "1")
18546 (set_attr "memory" "both")
18547 (set_attr "mode" "SI")])
18548
18549(define_expand "setmemsi"
18550 [(use (match_operand:BLK 0 "memory_operand" ""))
18551 (use (match_operand:SI 1 "nonmemory_operand" ""))
18552 (use (match_operand 2 "const_int_operand" ""))
18553 (use (match_operand 3 "const_int_operand" ""))]
18554 ""
18555{
18556 /* If value to set is not zero, use the library routine. */
18557 if (operands[2] != const0_rtx)
18558 FAIL;
18559
18560 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18561 DONE;
18562 else
18563 FAIL;
18564})
18565
18566(define_expand "setmemdi"
18567 [(use (match_operand:BLK 0 "memory_operand" ""))
18568 (use (match_operand:DI 1 "nonmemory_operand" ""))
18569 (use (match_operand 2 "const_int_operand" ""))
18570 (use (match_operand 3 "const_int_operand" ""))]
18571 "TARGET_64BIT"
18572{
18573 /* If value to set is not zero, use the library routine. */
18574 if (operands[2] != const0_rtx)
18575 FAIL;
18576
18577 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18578 DONE;
18579 else
18580 FAIL;
18581})
18582
18583;; Most CPUs don't like single string operations
18584;; Handle this case here to simplify previous expander.
18585
18586(define_expand "strset"
18587 [(set (match_operand 1 "memory_operand" "")
18588 (match_operand 2 "register_operand" ""))
18589 (parallel [(set (match_operand 0 "register_operand" "")
18590 (match_dup 3))
18591 (clobber (reg:CC FLAGS_REG))])]
18592 ""
18593{
18594 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18595 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18596
18597 /* If .md ever supports :P for Pmode, this can be directly
18598 in the pattern above. */
18599 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18600 GEN_INT (GET_MODE_SIZE (GET_MODE
18601 (operands[2]))));
18602 if (TARGET_SINGLE_STRINGOP || optimize_size)
18603 {
18604 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18605 operands[3]));
18606 DONE;
18607 }
18608})
18609
18610(define_expand "strset_singleop"
18611 [(parallel [(set (match_operand 1 "memory_operand" "")
18612 (match_operand 2 "register_operand" ""))
18613 (set (match_operand 0 "register_operand" "")
18614 (match_operand 3 "" ""))
18615 (use (reg:SI DIRFLAG_REG))])]
18616 "TARGET_SINGLE_STRINGOP || optimize_size"
18617 "")
18618
18619(define_insn "*strsetdi_rex_1"
18620 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18621 (match_operand:DI 2 "register_operand" "a"))
18622 (set (match_operand:DI 0 "register_operand" "=D")
18623 (plus:DI (match_dup 1)
18624 (const_int 8)))
18625 (use (reg:SI DIRFLAG_REG))]
18626 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18627 "stosq"
18628 [(set_attr "type" "str")
18629 (set_attr "memory" "store")
18630 (set_attr "mode" "DI")])
18631
18632(define_insn "*strsetsi_1"
18633 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18634 (match_operand:SI 2 "register_operand" "a"))
18635 (set (match_operand:SI 0 "register_operand" "=D")
18636 (plus:SI (match_dup 1)
18637 (const_int 4)))
18638 (use (reg:SI DIRFLAG_REG))]
18639 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18640 "{stosl|stosd}"
18641 [(set_attr "type" "str")
18642 (set_attr "memory" "store")
18643 (set_attr "mode" "SI")])
18644
18645(define_insn "*strsetsi_rex_1"
18646 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18647 (match_operand:SI 2 "register_operand" "a"))
18648 (set (match_operand:DI 0 "register_operand" "=D")
18649 (plus:DI (match_dup 1)
18650 (const_int 4)))
18651 (use (reg:SI DIRFLAG_REG))]
18652 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18653 "{stosl|stosd}"
18654 [(set_attr "type" "str")
18655 (set_attr "memory" "store")
18656 (set_attr "mode" "SI")])
18657
18658(define_insn "*strsethi_1"
18659 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18660 (match_operand:HI 2 "register_operand" "a"))
18661 (set (match_operand:SI 0 "register_operand" "=D")
18662 (plus:SI (match_dup 1)
18663 (const_int 2)))
18664 (use (reg:SI DIRFLAG_REG))]
18665 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18666 "stosw"
18667 [(set_attr "type" "str")
18668 (set_attr "memory" "store")
18669 (set_attr "mode" "HI")])
18670
18671(define_insn "*strsethi_rex_1"
18672 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18673 (match_operand:HI 2 "register_operand" "a"))
18674 (set (match_operand:DI 0 "register_operand" "=D")
18675 (plus:DI (match_dup 1)
18676 (const_int 2)))
18677 (use (reg:SI DIRFLAG_REG))]
18678 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18679 "stosw"
18680 [(set_attr "type" "str")
18681 (set_attr "memory" "store")
18682 (set_attr "mode" "HI")])
18683
18684(define_insn "*strsetqi_1"
18685 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18686 (match_operand:QI 2 "register_operand" "a"))
18687 (set (match_operand:SI 0 "register_operand" "=D")
18688 (plus:SI (match_dup 1)
18689 (const_int 1)))
18690 (use (reg:SI DIRFLAG_REG))]
18691 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18692 "stosb"
18693 [(set_attr "type" "str")
18694 (set_attr "memory" "store")
18695 (set_attr "mode" "QI")])
18696
18697(define_insn "*strsetqi_rex_1"
18698 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18699 (match_operand:QI 2 "register_operand" "a"))
18700 (set (match_operand:DI 0 "register_operand" "=D")
18701 (plus:DI (match_dup 1)
18702 (const_int 1)))
18703 (use (reg:SI DIRFLAG_REG))]
18704 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18705 "stosb"
18706 [(set_attr "type" "str")
18707 (set_attr "memory" "store")
18708 (set_attr "mode" "QI")])
18709
18710(define_expand "rep_stos"
18711 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18712 (set (match_operand 0 "register_operand" "")
18713 (match_operand 4 "" ""))
18714 (set (match_operand 2 "memory_operand" "") (const_int 0))
18715 (use (match_operand 3 "register_operand" ""))
18716 (use (match_dup 1))
18717 (use (reg:SI DIRFLAG_REG))])]
18718 ""
18719 "")
18720
18721(define_insn "*rep_stosdi_rex64"
18722 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18723 (set (match_operand:DI 0 "register_operand" "=D")
18724 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18725 (const_int 3))
18726 (match_operand:DI 3 "register_operand" "0")))
18727 (set (mem:BLK (match_dup 3))
18728 (const_int 0))
18729 (use (match_operand:DI 2 "register_operand" "a"))
18730 (use (match_dup 4))
18731 (use (reg:SI DIRFLAG_REG))]
18732 "TARGET_64BIT"
18733 "{rep\;stosq|rep stosq}"
18734 [(set_attr "type" "str")
18735 (set_attr "prefix_rep" "1")
18736 (set_attr "memory" "store")
18737 (set_attr "mode" "DI")])
18738
18739(define_insn "*rep_stossi"
18740 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18741 (set (match_operand:SI 0 "register_operand" "=D")
18742 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18743 (const_int 2))
18744 (match_operand:SI 3 "register_operand" "0")))
18745 (set (mem:BLK (match_dup 3))
18746 (const_int 0))
18747 (use (match_operand:SI 2 "register_operand" "a"))
18748 (use (match_dup 4))
18749 (use (reg:SI DIRFLAG_REG))]
18750 "!TARGET_64BIT"
18751 "{rep\;stosl|rep stosd}"
18752 [(set_attr "type" "str")
18753 (set_attr "prefix_rep" "1")
18754 (set_attr "memory" "store")
18755 (set_attr "mode" "SI")])
18756
18757(define_insn "*rep_stossi_rex64"
18758 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18759 (set (match_operand:DI 0 "register_operand" "=D")
18760 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18761 (const_int 2))
18762 (match_operand:DI 3 "register_operand" "0")))
18763 (set (mem:BLK (match_dup 3))
18764 (const_int 0))
18765 (use (match_operand:SI 2 "register_operand" "a"))
18766 (use (match_dup 4))
18767 (use (reg:SI DIRFLAG_REG))]
18768 "TARGET_64BIT"
18769 "{rep\;stosl|rep stosd}"
18770 [(set_attr "type" "str")
18771 (set_attr "prefix_rep" "1")
18772 (set_attr "memory" "store")
18773 (set_attr "mode" "SI")])
18774
18775(define_insn "*rep_stosqi"
18776 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18777 (set (match_operand:SI 0 "register_operand" "=D")
18778 (plus:SI (match_operand:SI 3 "register_operand" "0")
18779 (match_operand:SI 4 "register_operand" "1")))
18780 (set (mem:BLK (match_dup 3))
18781 (const_int 0))
18782 (use (match_operand:QI 2 "register_operand" "a"))
18783 (use (match_dup 4))
18784 (use (reg:SI DIRFLAG_REG))]
18785 "!TARGET_64BIT"
18786 "{rep\;stosb|rep stosb}"
18787 [(set_attr "type" "str")
18788 (set_attr "prefix_rep" "1")
18789 (set_attr "memory" "store")
18790 (set_attr "mode" "QI")])
18791
18792(define_insn "*rep_stosqi_rex64"
18793 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18794 (set (match_operand:DI 0 "register_operand" "=D")
18795 (plus:DI (match_operand:DI 3 "register_operand" "0")
18796 (match_operand:DI 4 "register_operand" "1")))
18797 (set (mem:BLK (match_dup 3))
18798 (const_int 0))
18799 (use (match_operand:QI 2 "register_operand" "a"))
18800 (use (match_dup 4))
18801 (use (reg:SI DIRFLAG_REG))]
18802 "TARGET_64BIT"
18803 "{rep\;stosb|rep stosb}"
18804 [(set_attr "type" "str")
18805 (set_attr "prefix_rep" "1")
18806 (set_attr "memory" "store")
18807 (set_attr "mode" "QI")])
18808
18809(define_expand "cmpstrnsi"
18810 [(set (match_operand:SI 0 "register_operand" "")
18811 (compare:SI (match_operand:BLK 1 "general_operand" "")
18812 (match_operand:BLK 2 "general_operand" "")))
18813 (use (match_operand 3 "general_operand" ""))
18814 (use (match_operand 4 "immediate_operand" ""))]
18815 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18816{
18817 rtx addr1, addr2, out, outlow, count, countreg, align;
18818
18819 /* Can't use this if the user has appropriated esi or edi. */
18820 if (global_regs[4] || global_regs[5])
18821 FAIL;
18822
18823 out = operands[0];
18824 if (GET_CODE (out) != REG)
18825 out = gen_reg_rtx (SImode);
18826
18827 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18828 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18829 if (addr1 != XEXP (operands[1], 0))
18830 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18831 if (addr2 != XEXP (operands[2], 0))
18832 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18833
18834 count = operands[3];
18835 countreg = ix86_zero_extend_to_Pmode (count);
18836
18837 /* %%% Iff we are testing strict equality, we can use known alignment
18838 to good advantage. This may be possible with combine, particularly
18839 once cc0 is dead. */
18840 align = operands[4];
18841
18842 emit_insn (gen_cld ());
18843 if (GET_CODE (count) == CONST_INT)
18844 {
18845 if (INTVAL (count) == 0)
18846 {
18847 emit_move_insn (operands[0], const0_rtx);
18848 DONE;
18849 }
18850 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18851 operands[1], operands[2]));
18852 }
18853 else
18854 {
18855 if (TARGET_64BIT)
18856 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18857 else
18858 emit_insn (gen_cmpsi_1 (countreg, countreg));
18859 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18860 operands[1], operands[2]));
18861 }
18862
18863 outlow = gen_lowpart (QImode, out);
18864 emit_insn (gen_cmpintqi (outlow));
18865 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18866
18867 if (operands[0] != out)
18868 emit_move_insn (operands[0], out);
18869
18870 DONE;
18871})
18872
18873;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18874
18875(define_expand "cmpintqi"
18876 [(set (match_dup 1)
18877 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18878 (set (match_dup 2)
18879 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18880 (parallel [(set (match_operand:QI 0 "register_operand" "")
18881 (minus:QI (match_dup 1)
18882 (match_dup 2)))
18883 (clobber (reg:CC FLAGS_REG))])]
18884 ""
18885 "operands[1] = gen_reg_rtx (QImode);
18886 operands[2] = gen_reg_rtx (QImode);")
18887
18888;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18889;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18890
18891(define_expand "cmpstrnqi_nz_1"
18892 [(parallel [(set (reg:CC FLAGS_REG)
18893 (compare:CC (match_operand 4 "memory_operand" "")
18894 (match_operand 5 "memory_operand" "")))
18895 (use (match_operand 2 "register_operand" ""))
18896 (use (match_operand:SI 3 "immediate_operand" ""))
18897 (use (reg:SI DIRFLAG_REG))
18898 (clobber (match_operand 0 "register_operand" ""))
18899 (clobber (match_operand 1 "register_operand" ""))
18900 (clobber (match_dup 2))])]
18901 ""
18902 "")
18903
18904(define_insn "*cmpstrnqi_nz_1"
18905 [(set (reg:CC FLAGS_REG)
18906 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18907 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18908 (use (match_operand:SI 6 "register_operand" "2"))
18909 (use (match_operand:SI 3 "immediate_operand" "i"))
18910 (use (reg:SI DIRFLAG_REG))
18911 (clobber (match_operand:SI 0 "register_operand" "=S"))
18912 (clobber (match_operand:SI 1 "register_operand" "=D"))
18913 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18914 "!TARGET_64BIT"
18915 "repz{\;| }cmpsb"
18916 [(set_attr "type" "str")
18917 (set_attr "mode" "QI")
18918 (set_attr "prefix_rep" "1")])
18919
18920(define_insn "*cmpstrnqi_nz_rex_1"
18921 [(set (reg:CC FLAGS_REG)
18922 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18923 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18924 (use (match_operand:DI 6 "register_operand" "2"))
18925 (use (match_operand:SI 3 "immediate_operand" "i"))
18926 (use (reg:SI DIRFLAG_REG))
18927 (clobber (match_operand:DI 0 "register_operand" "=S"))
18928 (clobber (match_operand:DI 1 "register_operand" "=D"))
18929 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18930 "TARGET_64BIT"
18931 "repz{\;| }cmpsb"
18932 [(set_attr "type" "str")
18933 (set_attr "mode" "QI")
18934 (set_attr "prefix_rep" "1")])
18935
18936;; The same, but the count is not known to not be zero.
18937
18938(define_expand "cmpstrnqi_1"
18939 [(parallel [(set (reg:CC FLAGS_REG)
18940 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18941 (const_int 0))
18942 (compare:CC (match_operand 4 "memory_operand" "")
18943 (match_operand 5 "memory_operand" ""))
18944 (const_int 0)))
18945 (use (match_operand:SI 3 "immediate_operand" ""))
18946 (use (reg:CC FLAGS_REG))
18947 (use (reg:SI DIRFLAG_REG))
18948 (clobber (match_operand 0 "register_operand" ""))
18949 (clobber (match_operand 1 "register_operand" ""))
18950 (clobber (match_dup 2))])]
18951 ""
18952 "")
18953
18954(define_insn "*cmpstrnqi_1"
18955 [(set (reg:CC FLAGS_REG)
18956 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18957 (const_int 0))
18958 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18959 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18960 (const_int 0)))
18961 (use (match_operand:SI 3 "immediate_operand" "i"))
18962 (use (reg:CC FLAGS_REG))
18963 (use (reg:SI DIRFLAG_REG))
18964 (clobber (match_operand:SI 0 "register_operand" "=S"))
18965 (clobber (match_operand:SI 1 "register_operand" "=D"))
18966 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18967 "!TARGET_64BIT"
18968 "repz{\;| }cmpsb"
18969 [(set_attr "type" "str")
18970 (set_attr "mode" "QI")
18971 (set_attr "prefix_rep" "1")])
18972
18973(define_insn "*cmpstrnqi_rex_1"
18974 [(set (reg:CC FLAGS_REG)
18975 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18976 (const_int 0))
18977 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18978 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18979 (const_int 0)))
18980 (use (match_operand:SI 3 "immediate_operand" "i"))
18981 (use (reg:CC FLAGS_REG))
18982 (use (reg:SI DIRFLAG_REG))
18983 (clobber (match_operand:DI 0 "register_operand" "=S"))
18984 (clobber (match_operand:DI 1 "register_operand" "=D"))
18985 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18986 "TARGET_64BIT"
18987 "repz{\;| }cmpsb"
18988 [(set_attr "type" "str")
18989 (set_attr "mode" "QI")
18990 (set_attr "prefix_rep" "1")])
18991
18992(define_expand "strlensi"
18993 [(set (match_operand:SI 0 "register_operand" "")
18994 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18995 (match_operand:QI 2 "immediate_operand" "")
18996 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18997 ""
18998{
18999 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19000 DONE;
19001 else
19002 FAIL;
19003})
19004
19005(define_expand "strlendi"
19006 [(set (match_operand:DI 0 "register_operand" "")
19007 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19008 (match_operand:QI 2 "immediate_operand" "")
19009 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19010 ""
19011{
19012 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19013 DONE;
19014 else
19015 FAIL;
19016})
19017
19018(define_expand "strlenqi_1"
19019 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19020 (use (reg:SI DIRFLAG_REG))
19021 (clobber (match_operand 1 "register_operand" ""))
19022 (clobber (reg:CC FLAGS_REG))])]
19023 ""
19024 "")
19025
19026(define_insn "*strlenqi_1"
19027 [(set (match_operand:SI 0 "register_operand" "=&c")
19028 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19029 (match_operand:QI 2 "register_operand" "a")
19030 (match_operand:SI 3 "immediate_operand" "i")
19031 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19032 (use (reg:SI DIRFLAG_REG))
19033 (clobber (match_operand:SI 1 "register_operand" "=D"))
19034 (clobber (reg:CC FLAGS_REG))]
19035 "!TARGET_64BIT"
19036 "repnz{\;| }scasb"
19037 [(set_attr "type" "str")
19038 (set_attr "mode" "QI")
19039 (set_attr "prefix_rep" "1")])
19040
19041(define_insn "*strlenqi_rex_1"
19042 [(set (match_operand:DI 0 "register_operand" "=&c")
19043 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19044 (match_operand:QI 2 "register_operand" "a")
19045 (match_operand:DI 3 "immediate_operand" "i")
19046 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19047 (use (reg:SI DIRFLAG_REG))
19048 (clobber (match_operand:DI 1 "register_operand" "=D"))
19049 (clobber (reg:CC FLAGS_REG))]
19050 "TARGET_64BIT"
19051 "repnz{\;| }scasb"
19052 [(set_attr "type" "str")
19053 (set_attr "mode" "QI")
19054 (set_attr "prefix_rep" "1")])
19055
19056;; Peephole optimizations to clean up after cmpstrn*. This should be
19057;; handled in combine, but it is not currently up to the task.
19058;; When used for their truth value, the cmpstrn* expanders generate
19059;; code like this:
19060;;
19061;; repz cmpsb
19062;; seta %al
19063;; setb %dl
19064;; cmpb %al, %dl
19065;; jcc label
19066;;
19067;; The intermediate three instructions are unnecessary.
19068
19069;; This one handles cmpstrn*_nz_1...
19070(define_peephole2
19071 [(parallel[
19072 (set (reg:CC FLAGS_REG)
19073 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19074 (mem:BLK (match_operand 5 "register_operand" ""))))
19075 (use (match_operand 6 "register_operand" ""))
19076 (use (match_operand:SI 3 "immediate_operand" ""))
19077 (use (reg:SI DIRFLAG_REG))
19078 (clobber (match_operand 0 "register_operand" ""))
19079 (clobber (match_operand 1 "register_operand" ""))
19080 (clobber (match_operand 2 "register_operand" ""))])
19081 (set (match_operand:QI 7 "register_operand" "")
19082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19083 (set (match_operand:QI 8 "register_operand" "")
19084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085 (set (reg FLAGS_REG)
19086 (compare (match_dup 7) (match_dup 8)))
19087 ]
19088 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19089 [(parallel[
19090 (set (reg:CC FLAGS_REG)
19091 (compare:CC (mem:BLK (match_dup 4))
19092 (mem:BLK (match_dup 5))))
19093 (use (match_dup 6))
19094 (use (match_dup 3))
19095 (use (reg:SI DIRFLAG_REG))
19096 (clobber (match_dup 0))
19097 (clobber (match_dup 1))
19098 (clobber (match_dup 2))])]
19099 "")
19100
19101;; ...and this one handles cmpstrn*_1.
19102(define_peephole2
19103 [(parallel[
19104 (set (reg:CC FLAGS_REG)
19105 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19106 (const_int 0))
19107 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19108 (mem:BLK (match_operand 5 "register_operand" "")))
19109 (const_int 0)))
19110 (use (match_operand:SI 3 "immediate_operand" ""))
19111 (use (reg:CC FLAGS_REG))
19112 (use (reg:SI DIRFLAG_REG))
19113 (clobber (match_operand 0 "register_operand" ""))
19114 (clobber (match_operand 1 "register_operand" ""))
19115 (clobber (match_operand 2 "register_operand" ""))])
19116 (set (match_operand:QI 7 "register_operand" "")
19117 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19118 (set (match_operand:QI 8 "register_operand" "")
19119 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19120 (set (reg FLAGS_REG)
19121 (compare (match_dup 7) (match_dup 8)))
19122 ]
19123 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19124 [(parallel[
19125 (set (reg:CC FLAGS_REG)
19126 (if_then_else:CC (ne (match_dup 6)
19127 (const_int 0))
19128 (compare:CC (mem:BLK (match_dup 4))
19129 (mem:BLK (match_dup 5)))
19130 (const_int 0)))
19131 (use (match_dup 3))
19132 (use (reg:CC FLAGS_REG))
19133 (use (reg:SI DIRFLAG_REG))
19134 (clobber (match_dup 0))
19135 (clobber (match_dup 1))
19136 (clobber (match_dup 2))])]
19137 "")
19138
19139
19140
19141;; Conditional move instructions.
19142
19143(define_expand "movdicc"
19144 [(set (match_operand:DI 0 "register_operand" "")
19145 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19146 (match_operand:DI 2 "general_operand" "")
19147 (match_operand:DI 3 "general_operand" "")))]
19148 "TARGET_64BIT"
19149 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19150
19151(define_insn "x86_movdicc_0_m1_rex64"
19152 [(set (match_operand:DI 0 "register_operand" "=r")
19153 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19154 (const_int -1)
19155 (const_int 0)))
19156 (clobber (reg:CC FLAGS_REG))]
19157 "TARGET_64BIT"
19158 "sbb{q}\t%0, %0"
19159 ; Since we don't have the proper number of operands for an alu insn,
19160 ; fill in all the blanks.
19161 [(set_attr "type" "alu")
19162 (set_attr "pent_pair" "pu")
19163 (set_attr "memory" "none")
19164 (set_attr "imm_disp" "false")
19165 (set_attr "mode" "DI")
19166 (set_attr "length_immediate" "0")])
19167
19168(define_insn "*movdicc_c_rex64"
19169 [(set (match_operand:DI 0 "register_operand" "=r,r")
19170 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19171 [(reg FLAGS_REG) (const_int 0)])
19172 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19173 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19174 "TARGET_64BIT && TARGET_CMOVE
19175 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19176 "@
19177 cmov%O2%C1\t{%2, %0|%0, %2}
19178 cmov%O2%c1\t{%3, %0|%0, %3}"
19179 [(set_attr "type" "icmov")
19180 (set_attr "mode" "DI")])
19181
19182(define_expand "movsicc"
19183 [(set (match_operand:SI 0 "register_operand" "")
19184 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19185 (match_operand:SI 2 "general_operand" "")
19186 (match_operand:SI 3 "general_operand" "")))]
19187 ""
19188 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19189
19190;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19191;; the register first winds up with `sbbl $0,reg', which is also weird.
19192;; So just document what we're doing explicitly.
19193
19194(define_insn "x86_movsicc_0_m1"
19195 [(set (match_operand:SI 0 "register_operand" "=r")
19196 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19197 (const_int -1)
19198 (const_int 0)))
19199 (clobber (reg:CC FLAGS_REG))]
19200 ""
19201 "sbb{l}\t%0, %0"
19202 ; Since we don't have the proper number of operands for an alu insn,
19203 ; fill in all the blanks.
19204 [(set_attr "type" "alu")
19205 (set_attr "pent_pair" "pu")
19206 (set_attr "memory" "none")
19207 (set_attr "imm_disp" "false")
19208 (set_attr "mode" "SI")
19209 (set_attr "length_immediate" "0")])
19210
19211(define_insn "*movsicc_noc"
19212 [(set (match_operand:SI 0 "register_operand" "=r,r")
19213 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19214 [(reg FLAGS_REG) (const_int 0)])
19215 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19216 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19217 "TARGET_CMOVE
19218 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19219 "@
19220 cmov%O2%C1\t{%2, %0|%0, %2}
19221 cmov%O2%c1\t{%3, %0|%0, %3}"
19222 [(set_attr "type" "icmov")
19223 (set_attr "mode" "SI")])
19224
19225(define_expand "movhicc"
19226 [(set (match_operand:HI 0 "register_operand" "")
19227 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19228 (match_operand:HI 2 "general_operand" "")
19229 (match_operand:HI 3 "general_operand" "")))]
19230 "TARGET_HIMODE_MATH"
19231 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19232
19233(define_insn "*movhicc_noc"
19234 [(set (match_operand:HI 0 "register_operand" "=r,r")
19235 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19236 [(reg FLAGS_REG) (const_int 0)])
19237 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19238 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19239 "TARGET_CMOVE
19240 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19241 "@
19242 cmov%O2%C1\t{%2, %0|%0, %2}
19243 cmov%O2%c1\t{%3, %0|%0, %3}"
19244 [(set_attr "type" "icmov")
19245 (set_attr "mode" "HI")])
19246
19247(define_expand "movqicc"
19248 [(set (match_operand:QI 0 "register_operand" "")
19249 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19250 (match_operand:QI 2 "general_operand" "")
19251 (match_operand:QI 3 "general_operand" "")))]
19252 "TARGET_QIMODE_MATH"
19253 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19254
19255(define_insn_and_split "*movqicc_noc"
19256 [(set (match_operand:QI 0 "register_operand" "=r,r")
19257 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19258 [(match_operand 4 "flags_reg_operand" "")
19259 (const_int 0)])
19260 (match_operand:QI 2 "register_operand" "r,0")
19261 (match_operand:QI 3 "register_operand" "0,r")))]
19262 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19263 "#"
19264 "&& reload_completed"
19265 [(set (match_dup 0)
19266 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19267 (match_dup 2)
19268 (match_dup 3)))]
19269 "operands[0] = gen_lowpart (SImode, operands[0]);
19270 operands[2] = gen_lowpart (SImode, operands[2]);
19271 operands[3] = gen_lowpart (SImode, operands[3]);"
19272 [(set_attr "type" "icmov")
19273 (set_attr "mode" "SI")])
19274
19275(define_expand "movsfcc"
19276 [(set (match_operand:SF 0 "register_operand" "")
19277 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19278 (match_operand:SF 2 "register_operand" "")
19279 (match_operand:SF 3 "register_operand" "")))]
19280 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19281 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19282
19283(define_insn "*movsfcc_1_387"
19284 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19285 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19286 [(reg FLAGS_REG) (const_int 0)])
19287 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19288 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19289 "TARGET_80387 && TARGET_CMOVE
19290 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19291 "@
19292 fcmov%F1\t{%2, %0|%0, %2}
19293 fcmov%f1\t{%3, %0|%0, %3}
19294 cmov%O2%C1\t{%2, %0|%0, %2}
19295 cmov%O2%c1\t{%3, %0|%0, %3}"
19296 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19297 (set_attr "mode" "SF,SF,SI,SI")])
19298
19299(define_expand "movdfcc"
19300 [(set (match_operand:DF 0 "register_operand" "")
19301 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19302 (match_operand:DF 2 "register_operand" "")
19303 (match_operand:DF 3 "register_operand" "")))]
19304 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19305 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19306
19307(define_insn "*movdfcc_1"
19308 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19309 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19310 [(reg FLAGS_REG) (const_int 0)])
19311 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19312 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19313 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19314 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19315 "@
19316 fcmov%F1\t{%2, %0|%0, %2}
19317 fcmov%f1\t{%3, %0|%0, %3}
19318 #
19319 #"
19320 [(set_attr "type" "fcmov,fcmov,multi,multi")
19321 (set_attr "mode" "DF")])
19322
19323(define_insn "*movdfcc_1_rex64"
19324 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19325 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19326 [(reg FLAGS_REG) (const_int 0)])
19327 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19328 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19329 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19330 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19331 "@
19332 fcmov%F1\t{%2, %0|%0, %2}
19333 fcmov%f1\t{%3, %0|%0, %3}
19334 cmov%O2%C1\t{%2, %0|%0, %2}
19335 cmov%O2%c1\t{%3, %0|%0, %3}"
19336 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19337 (set_attr "mode" "DF")])
19338
19339(define_split
19340 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19341 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19342 [(match_operand 4 "flags_reg_operand" "")
19343 (const_int 0)])
19344 (match_operand:DF 2 "nonimmediate_operand" "")
19345 (match_operand:DF 3 "nonimmediate_operand" "")))]
19346 "!TARGET_64BIT && reload_completed"
19347 [(set (match_dup 2)
19348 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19349 (match_dup 5)
19350 (match_dup 7)))
19351 (set (match_dup 3)
19352 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19353 (match_dup 6)
19354 (match_dup 8)))]
19355 "split_di (operands+2, 1, operands+5, operands+6);
19356 split_di (operands+3, 1, operands+7, operands+8);
19357 split_di (operands, 1, operands+2, operands+3);")
19358
19359(define_expand "movxfcc"
19360 [(set (match_operand:XF 0 "register_operand" "")
19361 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19362 (match_operand:XF 2 "register_operand" "")
19363 (match_operand:XF 3 "register_operand" "")))]
19364 "TARGET_80387 && TARGET_CMOVE"
19365 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19366
19367(define_insn "*movxfcc_1"
19368 [(set (match_operand:XF 0 "register_operand" "=f,f")
19369 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19370 [(reg FLAGS_REG) (const_int 0)])
19371 (match_operand:XF 2 "register_operand" "f,0")
19372 (match_operand:XF 3 "register_operand" "0,f")))]
19373 "TARGET_80387 && TARGET_CMOVE"
19374 "@
19375 fcmov%F1\t{%2, %0|%0, %2}
19376 fcmov%f1\t{%3, %0|%0, %3}"
19377 [(set_attr "type" "fcmov")
19378 (set_attr "mode" "XF")])
19379
19380;; These versions of the min/max patterns are intentionally ignorant of
19381;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19382;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19383;; are undefined in this condition, we're certain this is correct.
19384
19385(define_insn "sminsf3"
19386 [(set (match_operand:SF 0 "register_operand" "=x")
19387 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19388 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19389 "TARGET_SSE_MATH"
19390 "minss\t{%2, %0|%0, %2}"
19391 [(set_attr "type" "sseadd")
19392 (set_attr "mode" "SF")])
19393
19394(define_insn "smaxsf3"
19395 [(set (match_operand:SF 0 "register_operand" "=x")
19396 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19397 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19398 "TARGET_SSE_MATH"
19399 "maxss\t{%2, %0|%0, %2}"
19400 [(set_attr "type" "sseadd")
19401 (set_attr "mode" "SF")])
19402
19403(define_insn "smindf3"
19404 [(set (match_operand:DF 0 "register_operand" "=x")
19405 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19406 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19407 "TARGET_SSE2 && TARGET_SSE_MATH"
19408 "minsd\t{%2, %0|%0, %2}"
19409 [(set_attr "type" "sseadd")
19410 (set_attr "mode" "DF")])
19411
19412(define_insn "smaxdf3"
19413 [(set (match_operand:DF 0 "register_operand" "=x")
19414 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19415 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19416 "TARGET_SSE2 && TARGET_SSE_MATH"
19417 "maxsd\t{%2, %0|%0, %2}"
19418 [(set_attr "type" "sseadd")
19419 (set_attr "mode" "DF")])
19420
19421;; These versions of the min/max patterns implement exactly the operations
19422;; min = (op1 < op2 ? op1 : op2)
19423;; max = (!(op1 < op2) ? op1 : op2)
19424;; Their operands are not commutative, and thus they may be used in the
19425;; presence of -0.0 and NaN.
19426
19427(define_insn "*ieee_sminsf3"
19428 [(set (match_operand:SF 0 "register_operand" "=x")
19429 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19430 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19431 UNSPEC_IEEE_MIN))]
19432 "TARGET_SSE_MATH"
19433 "minss\t{%2, %0|%0, %2}"
19434 [(set_attr "type" "sseadd")
19435 (set_attr "mode" "SF")])
19436
19437(define_insn "*ieee_smaxsf3"
19438 [(set (match_operand:SF 0 "register_operand" "=x")
19439 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19440 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19441 UNSPEC_IEEE_MAX))]
19442 "TARGET_SSE_MATH"
19443 "maxss\t{%2, %0|%0, %2}"
19444 [(set_attr "type" "sseadd")
19445 (set_attr "mode" "SF")])
19446
19447(define_insn "*ieee_smindf3"
19448 [(set (match_operand:DF 0 "register_operand" "=x")
19449 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19450 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19451 UNSPEC_IEEE_MIN))]
19452 "TARGET_SSE2 && TARGET_SSE_MATH"
19453 "minsd\t{%2, %0|%0, %2}"
19454 [(set_attr "type" "sseadd")
19455 (set_attr "mode" "DF")])
19456
19457(define_insn "*ieee_smaxdf3"
19458 [(set (match_operand:DF 0 "register_operand" "=x")
19459 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19460 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19461 UNSPEC_IEEE_MAX))]
19462 "TARGET_SSE2 && TARGET_SSE_MATH"
19463 "maxsd\t{%2, %0|%0, %2}"
19464 [(set_attr "type" "sseadd")
19465 (set_attr "mode" "DF")])
19466
19467;; Make two stack loads independent:
19468;; fld aa fld aa
19469;; fld %st(0) -> fld bb
19470;; fmul bb fmul %st(1), %st
19471;;
19472;; Actually we only match the last two instructions for simplicity.
19473(define_peephole2
19474 [(set (match_operand 0 "fp_register_operand" "")
19475 (match_operand 1 "fp_register_operand" ""))
19476 (set (match_dup 0)
19477 (match_operator 2 "binary_fp_operator"
19478 [(match_dup 0)
19479 (match_operand 3 "memory_operand" "")]))]
19480 "REGNO (operands[0]) != REGNO (operands[1])"
19481 [(set (match_dup 0) (match_dup 3))
19482 (set (match_dup 0) (match_dup 4))]
19483
19484 ;; The % modifier is not operational anymore in peephole2's, so we have to
19485 ;; swap the operands manually in the case of addition and multiplication.
19486 "if (COMMUTATIVE_ARITH_P (operands[2]))
19487 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19488 operands[0], operands[1]);
19489 else
19490 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19491 operands[1], operands[0]);")
19492
19493;; Conditional addition patterns
19494(define_expand "addqicc"
19495 [(match_operand:QI 0 "register_operand" "")
19496 (match_operand 1 "comparison_operator" "")
19497 (match_operand:QI 2 "register_operand" "")
19498 (match_operand:QI 3 "const_int_operand" "")]
19499 ""
19500 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19501
19502(define_expand "addhicc"
19503 [(match_operand:HI 0 "register_operand" "")
19504 (match_operand 1 "comparison_operator" "")
19505 (match_operand:HI 2 "register_operand" "")
19506 (match_operand:HI 3 "const_int_operand" "")]
19507 ""
19508 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19509
19510(define_expand "addsicc"
19511 [(match_operand:SI 0 "register_operand" "")
19512 (match_operand 1 "comparison_operator" "")
19513 (match_operand:SI 2 "register_operand" "")
19514 (match_operand:SI 3 "const_int_operand" "")]
19515 ""
19516 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19517
19518(define_expand "adddicc"
19519 [(match_operand:DI 0 "register_operand" "")
19520 (match_operand 1 "comparison_operator" "")
19521 (match_operand:DI 2 "register_operand" "")
19522 (match_operand:DI 3 "const_int_operand" "")]
19523 "TARGET_64BIT"
19524 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19525
19526
19527;; Misc patterns (?)
19528
19529;; This pattern exists to put a dependency on all ebp-based memory accesses.
19530;; Otherwise there will be nothing to keep
19531;;
19532;; [(set (reg ebp) (reg esp))]
19533;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19534;; (clobber (eflags)]
19535;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19536;;
19537;; in proper program order.
19538(define_insn "pro_epilogue_adjust_stack_1"
19539 [(set (match_operand:SI 0 "register_operand" "=r,r")
19540 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19541 (match_operand:SI 2 "immediate_operand" "i,i")))
19542 (clobber (reg:CC FLAGS_REG))
19543 (clobber (mem:BLK (scratch)))]
19544 "!TARGET_64BIT"
19545{
19546 switch (get_attr_type (insn))
19547 {
19548 case TYPE_IMOV:
19549 return "mov{l}\t{%1, %0|%0, %1}";
19550
19551 case TYPE_ALU:
19552 if (GET_CODE (operands[2]) == CONST_INT
19553 && (INTVAL (operands[2]) == 128
19554 || (INTVAL (operands[2]) < 0
19555 && INTVAL (operands[2]) != -128)))
19556 {
19557 operands[2] = GEN_INT (-INTVAL (operands[2]));
19558 return "sub{l}\t{%2, %0|%0, %2}";
19559 }
19560 return "add{l}\t{%2, %0|%0, %2}";
19561
19562 case TYPE_LEA:
19563 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19564 return "lea{l}\t{%a2, %0|%0, %a2}";
19565
19566 default:
19567 gcc_unreachable ();
19568 }
19569}
19570 [(set (attr "type")
19571 (cond [(eq_attr "alternative" "0")
19572 (const_string "alu")
19573 (match_operand:SI 2 "const0_operand" "")
19574 (const_string "imov")
19575 ]
19576 (const_string "lea")))
19577 (set_attr "mode" "SI")])
19578
19579(define_insn "pro_epilogue_adjust_stack_rex64"
19580 [(set (match_operand:DI 0 "register_operand" "=r,r")
19581 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19582 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19583 (clobber (reg:CC FLAGS_REG))
19584 (clobber (mem:BLK (scratch)))]
19585 "TARGET_64BIT"
19586{
19587 switch (get_attr_type (insn))
19588 {
19589 case TYPE_IMOV:
19590 return "mov{q}\t{%1, %0|%0, %1}";
19591
19592 case TYPE_ALU:
19593 if (GET_CODE (operands[2]) == CONST_INT
19594 /* Avoid overflows. */
19595 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19596 && (INTVAL (operands[2]) == 128
19597 || (INTVAL (operands[2]) < 0
19598 && INTVAL (operands[2]) != -128)))
19599 {
19600 operands[2] = GEN_INT (-INTVAL (operands[2]));
19601 return "sub{q}\t{%2, %0|%0, %2}";
19602 }
19603 return "add{q}\t{%2, %0|%0, %2}";
19604
19605 case TYPE_LEA:
19606 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19607 return "lea{q}\t{%a2, %0|%0, %a2}";
19608
19609 default:
19610 gcc_unreachable ();
19611 }
19612}
19613 [(set (attr "type")
19614 (cond [(eq_attr "alternative" "0")
19615 (const_string "alu")
19616 (match_operand:DI 2 "const0_operand" "")
19617 (const_string "imov")
19618 ]
19619 (const_string "lea")))
19620 (set_attr "mode" "DI")])
19621
19622(define_insn "pro_epilogue_adjust_stack_rex64_2"
19623 [(set (match_operand:DI 0 "register_operand" "=r,r")
19624 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19625 (match_operand:DI 3 "immediate_operand" "i,i")))
19626 (use (match_operand:DI 2 "register_operand" "r,r"))
19627 (clobber (reg:CC FLAGS_REG))
19628 (clobber (mem:BLK (scratch)))]
19629 "TARGET_64BIT"
19630{
19631 switch (get_attr_type (insn))
19632 {
19633 case TYPE_ALU:
19634 return "add{q}\t{%2, %0|%0, %2}";
19635
19636 case TYPE_LEA:
19637 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19638 return "lea{q}\t{%a2, %0|%0, %a2}";
19639
19640 default:
19641 gcc_unreachable ();
19642 }
19643}
19644 [(set_attr "type" "alu,lea")
19645 (set_attr "mode" "DI")])
19646
19647(define_expand "allocate_stack_worker"
19648 [(match_operand:SI 0 "register_operand" "")]
19649 "TARGET_STACK_PROBE"
19650{
19651 if (reload_completed)
19652 {
19653 if (TARGET_64BIT)
19654 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19655 else
19656 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19657 }
19658 else
19659 {
19660 if (TARGET_64BIT)
19661 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19662 else
19663 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19664 }
19665 DONE;
19666})
19667
19668(define_insn "allocate_stack_worker_1"
19669 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19670 UNSPECV_STACK_PROBE)
19671 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19672 (clobber (match_scratch:SI 1 "=0"))
19673 (clobber (reg:CC FLAGS_REG))]
19674 "!TARGET_64BIT && TARGET_STACK_PROBE"
19675 "call\t__alloca"
19676 [(set_attr "type" "multi")
19677 (set_attr "length" "5")])
19678
19679(define_expand "allocate_stack_worker_postreload"
19680 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19681 UNSPECV_STACK_PROBE)
19682 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19683 (clobber (match_dup 0))
19684 (clobber (reg:CC FLAGS_REG))])]
19685 ""
19686 "")
19687
19688(define_insn "allocate_stack_worker_rex64"
19689 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19690 UNSPECV_STACK_PROBE)
19691 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19692 (clobber (match_scratch:DI 1 "=0"))
19693 (clobber (reg:CC FLAGS_REG))]
19694 "TARGET_64BIT && TARGET_STACK_PROBE"
19695 "call\t__alloca"
19696 [(set_attr "type" "multi")
19697 (set_attr "length" "5")])
19698
19699(define_expand "allocate_stack_worker_rex64_postreload"
19700 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19701 UNSPECV_STACK_PROBE)
19702 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19703 (clobber (match_dup 0))
19704 (clobber (reg:CC FLAGS_REG))])]
19705 ""
19706 "")
19707
19708(define_expand "allocate_stack"
19709 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19710 (minus:SI (reg:SI SP_REG)
19711 (match_operand:SI 1 "general_operand" "")))
19712 (clobber (reg:CC FLAGS_REG))])
19713 (parallel [(set (reg:SI SP_REG)
19714 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19715 (clobber (reg:CC FLAGS_REG))])]
19716 "TARGET_STACK_PROBE"
19717{
19718#ifdef CHECK_STACK_LIMIT
19719 if (GET_CODE (operands[1]) == CONST_INT
19720 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19721 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19722 operands[1]));
19723 else
19724#endif
19725 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19726 operands[1])));
19727
19728 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19729 DONE;
19730})
19731
19732(define_expand "builtin_setjmp_receiver"
19733 [(label_ref (match_operand 0 "" ""))]
19734 "!TARGET_64BIT && flag_pic"
19735{
19736 if (TARGET_MACHO)
19737 {
19738 rtx xops[3];
19739 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19740 rtx label_rtx = gen_label_rtx ();
19741 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19742 xops[0] = xops[1] = picreg;
19743 xops[2] = gen_rtx_CONST (SImode,
19744 gen_rtx_MINUS (SImode,
19745 gen_rtx_LABEL_REF (SImode, label_rtx),
19746 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19747 ix86_expand_binary_operator (MINUS, SImode, xops);
19748 }
19749 else
19750 emit_insn (gen_set_got (pic_offset_table_rtx));
19751 DONE;
19752})
19753
19754;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19755
19756(define_split
19757 [(set (match_operand 0 "register_operand" "")
19758 (match_operator 3 "promotable_binary_operator"
19759 [(match_operand 1 "register_operand" "")
19760 (match_operand 2 "aligned_operand" "")]))
19761 (clobber (reg:CC FLAGS_REG))]
19762 "! TARGET_PARTIAL_REG_STALL && reload_completed
19763 && ((GET_MODE (operands[0]) == HImode
19764 && ((!optimize_size && !TARGET_FAST_PREFIX)
19765 /* ??? next two lines just !satisfies_constraint_K (...) */
19766 || GET_CODE (operands[2]) != CONST_INT
19767 || satisfies_constraint_K (operands[2])))
19768 || (GET_MODE (operands[0]) == QImode
19769 && (TARGET_PROMOTE_QImode || optimize_size)))"
19770 [(parallel [(set (match_dup 0)
19771 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19772 (clobber (reg:CC FLAGS_REG))])]
19773 "operands[0] = gen_lowpart (SImode, operands[0]);
19774 operands[1] = gen_lowpart (SImode, operands[1]);
19775 if (GET_CODE (operands[3]) != ASHIFT)
19776 operands[2] = gen_lowpart (SImode, operands[2]);
19777 PUT_MODE (operands[3], SImode);")
19778
19779; Promote the QImode tests, as i386 has encoding of the AND
19780; instruction with 32-bit sign-extended immediate and thus the
19781; instruction size is unchanged, except in the %eax case for
19782; which it is increased by one byte, hence the ! optimize_size.
19783(define_split
19784 [(set (match_operand 0 "flags_reg_operand" "")
19785 (match_operator 2 "compare_operator"
19786 [(and (match_operand 3 "aligned_operand" "")
19787 (match_operand 4 "const_int_operand" ""))
19788 (const_int 0)]))
19789 (set (match_operand 1 "register_operand" "")
19790 (and (match_dup 3) (match_dup 4)))]
19791 "! TARGET_PARTIAL_REG_STALL && reload_completed
19792 /* Ensure that the operand will remain sign-extended immediate. */
19793 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19794 && ! optimize_size
19795 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19796 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19797 [(parallel [(set (match_dup 0)
19798 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19799 (const_int 0)]))
19800 (set (match_dup 1)
19801 (and:SI (match_dup 3) (match_dup 4)))])]
19802{
19803 operands[4]
19804 = gen_int_mode (INTVAL (operands[4])
19805 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19806 operands[1] = gen_lowpart (SImode, operands[1]);
19807 operands[3] = gen_lowpart (SImode, operands[3]);
19808})
19809
19810; Don't promote the QImode tests, as i386 doesn't have encoding of
19811; the TEST instruction with 32-bit sign-extended immediate and thus
19812; the instruction size would at least double, which is not what we
19813; want even with ! optimize_size.
19814(define_split
19815 [(set (match_operand 0 "flags_reg_operand" "")
19816 (match_operator 1 "compare_operator"
19817 [(and (match_operand:HI 2 "aligned_operand" "")
19818 (match_operand:HI 3 "const_int_operand" ""))
19819 (const_int 0)]))]
19820 "! TARGET_PARTIAL_REG_STALL && reload_completed
19821 /* Ensure that the operand will remain sign-extended immediate. */
19822 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19823 && ! TARGET_FAST_PREFIX
19824 && ! optimize_size"
19825 [(set (match_dup 0)
19826 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19827 (const_int 0)]))]
19828{
19829 operands[3]
19830 = gen_int_mode (INTVAL (operands[3])
19831 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19832 operands[2] = gen_lowpart (SImode, operands[2]);
19833})
19834
19835(define_split
19836 [(set (match_operand 0 "register_operand" "")
19837 (neg (match_operand 1 "register_operand" "")))
19838 (clobber (reg:CC FLAGS_REG))]
19839 "! TARGET_PARTIAL_REG_STALL && reload_completed
19840 && (GET_MODE (operands[0]) == HImode
19841 || (GET_MODE (operands[0]) == QImode
19842 && (TARGET_PROMOTE_QImode || optimize_size)))"
19843 [(parallel [(set (match_dup 0)
19844 (neg:SI (match_dup 1)))
19845 (clobber (reg:CC FLAGS_REG))])]
19846 "operands[0] = gen_lowpart (SImode, operands[0]);
19847 operands[1] = gen_lowpart (SImode, operands[1]);")
19848
19849(define_split
19850 [(set (match_operand 0 "register_operand" "")
19851 (not (match_operand 1 "register_operand" "")))]
19852 "! TARGET_PARTIAL_REG_STALL && reload_completed
19853 && (GET_MODE (operands[0]) == HImode
19854 || (GET_MODE (operands[0]) == QImode
19855 && (TARGET_PROMOTE_QImode || optimize_size)))"
19856 [(set (match_dup 0)
19857 (not:SI (match_dup 1)))]
19858 "operands[0] = gen_lowpart (SImode, operands[0]);
19859 operands[1] = gen_lowpart (SImode, operands[1]);")
19860
19861(define_split
19862 [(set (match_operand 0 "register_operand" "")
19863 (if_then_else (match_operator 1 "comparison_operator"
19864 [(reg FLAGS_REG) (const_int 0)])
19865 (match_operand 2 "register_operand" "")
19866 (match_operand 3 "register_operand" "")))]
19867 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19868 && (GET_MODE (operands[0]) == HImode
19869 || (GET_MODE (operands[0]) == QImode
19870 && (TARGET_PROMOTE_QImode || optimize_size)))"
19871 [(set (match_dup 0)
19872 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19873 "operands[0] = gen_lowpart (SImode, operands[0]);
19874 operands[2] = gen_lowpart (SImode, operands[2]);
19875 operands[3] = gen_lowpart (SImode, operands[3]);")
19876
19877
19878;; RTL Peephole optimizations, run before sched2. These primarily look to
19879;; transform a complex memory operation into two memory to register operations.
19880
19881;; Don't push memory operands
19882(define_peephole2
19883 [(set (match_operand:SI 0 "push_operand" "")
19884 (match_operand:SI 1 "memory_operand" ""))
19885 (match_scratch:SI 2 "r")]
19886 "!optimize_size && !TARGET_PUSH_MEMORY
19887 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19888 [(set (match_dup 2) (match_dup 1))
19889 (set (match_dup 0) (match_dup 2))]
19890 "")
19891
19892(define_peephole2
19893 [(set (match_operand:DI 0 "push_operand" "")
19894 (match_operand:DI 1 "memory_operand" ""))
19895 (match_scratch:DI 2 "r")]
19896 "!optimize_size && !TARGET_PUSH_MEMORY
19897 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19898 [(set (match_dup 2) (match_dup 1))
19899 (set (match_dup 0) (match_dup 2))]
19900 "")
19901
19902;; We need to handle SFmode only, because DFmode and XFmode is split to
19903;; SImode pushes.
19904(define_peephole2
19905 [(set (match_operand:SF 0 "push_operand" "")
19906 (match_operand:SF 1 "memory_operand" ""))
19907 (match_scratch:SF 2 "r")]
19908 "!optimize_size && !TARGET_PUSH_MEMORY
19909 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19910 [(set (match_dup 2) (match_dup 1))
19911 (set (match_dup 0) (match_dup 2))]
19912 "")
19913
19914(define_peephole2
19915 [(set (match_operand:HI 0 "push_operand" "")
19916 (match_operand:HI 1 "memory_operand" ""))
19917 (match_scratch:HI 2 "r")]
19918 "!optimize_size && !TARGET_PUSH_MEMORY
19919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920 [(set (match_dup 2) (match_dup 1))
19921 (set (match_dup 0) (match_dup 2))]
19922 "")
19923
19924(define_peephole2
19925 [(set (match_operand:QI 0 "push_operand" "")
19926 (match_operand:QI 1 "memory_operand" ""))
19927 (match_scratch:QI 2 "q")]
19928 "!optimize_size && !TARGET_PUSH_MEMORY
19929 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930 [(set (match_dup 2) (match_dup 1))
19931 (set (match_dup 0) (match_dup 2))]
19932 "")
19933
19934;; Don't move an immediate directly to memory when the instruction
19935;; gets too big.
19936(define_peephole2
19937 [(match_scratch:SI 1 "r")
19938 (set (match_operand:SI 0 "memory_operand" "")
19939 (const_int 0))]
19940 "! optimize_size
19941 && ! TARGET_USE_MOV0
19942 && TARGET_SPLIT_LONG_MOVES
19943 && get_attr_length (insn) >= ix86_cost->large_insn
19944 && peep2_regno_dead_p (0, FLAGS_REG)"
19945 [(parallel [(set (match_dup 1) (const_int 0))
19946 (clobber (reg:CC FLAGS_REG))])
19947 (set (match_dup 0) (match_dup 1))]
19948 "")
19949
19950(define_peephole2
19951 [(match_scratch:HI 1 "r")
19952 (set (match_operand:HI 0 "memory_operand" "")
19953 (const_int 0))]
19954 "! optimize_size
19955 && ! TARGET_USE_MOV0
19956 && TARGET_SPLIT_LONG_MOVES
19957 && get_attr_length (insn) >= ix86_cost->large_insn
19958 && peep2_regno_dead_p (0, FLAGS_REG)"
19959 [(parallel [(set (match_dup 2) (const_int 0))
19960 (clobber (reg:CC FLAGS_REG))])
19961 (set (match_dup 0) (match_dup 1))]
19962 "operands[2] = gen_lowpart (SImode, operands[1]);")
19963
19964(define_peephole2
19965 [(match_scratch:QI 1 "q")
19966 (set (match_operand:QI 0 "memory_operand" "")
19967 (const_int 0))]
19968 "! optimize_size
19969 && ! TARGET_USE_MOV0
19970 && TARGET_SPLIT_LONG_MOVES
19971 && get_attr_length (insn) >= ix86_cost->large_insn
19972 && peep2_regno_dead_p (0, FLAGS_REG)"
19973 [(parallel [(set (match_dup 2) (const_int 0))
19974 (clobber (reg:CC FLAGS_REG))])
19975 (set (match_dup 0) (match_dup 1))]
19976 "operands[2] = gen_lowpart (SImode, operands[1]);")
19977
19978(define_peephole2
19979 [(match_scratch:SI 2 "r")
19980 (set (match_operand:SI 0 "memory_operand" "")
19981 (match_operand:SI 1 "immediate_operand" ""))]
19982 "! optimize_size
19983 && get_attr_length (insn) >= ix86_cost->large_insn
19984 && TARGET_SPLIT_LONG_MOVES"
19985 [(set (match_dup 2) (match_dup 1))
19986 (set (match_dup 0) (match_dup 2))]
19987 "")
19988
19989(define_peephole2
19990 [(match_scratch:HI 2 "r")
19991 (set (match_operand:HI 0 "memory_operand" "")
19992 (match_operand:HI 1 "immediate_operand" ""))]
19993 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19994 && TARGET_SPLIT_LONG_MOVES"
19995 [(set (match_dup 2) (match_dup 1))
19996 (set (match_dup 0) (match_dup 2))]
19997 "")
19998
19999(define_peephole2
20000 [(match_scratch:QI 2 "q")
20001 (set (match_operand:QI 0 "memory_operand" "")
20002 (match_operand:QI 1 "immediate_operand" ""))]
20003 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20004 && TARGET_SPLIT_LONG_MOVES"
20005 [(set (match_dup 2) (match_dup 1))
20006 (set (match_dup 0) (match_dup 2))]
20007 "")
20008
20009;; Don't compare memory with zero, load and use a test instead.
20010(define_peephole2
20011 [(set (match_operand 0 "flags_reg_operand" "")
20012 (match_operator 1 "compare_operator"
20013 [(match_operand:SI 2 "memory_operand" "")
20014 (const_int 0)]))
20015 (match_scratch:SI 3 "r")]
20016 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20017 [(set (match_dup 3) (match_dup 2))
20018 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20019 "")
20020
20021;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20022;; Don't split NOTs with a displacement operand, because resulting XOR
20023;; will not be pairable anyway.
20024;;
20025;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20026;; represented using a modRM byte. The XOR replacement is long decoded,
20027;; so this split helps here as well.
20028;;
20029;; Note: Can't do this as a regular split because we can't get proper
20030;; lifetime information then.
20031
20032(define_peephole2
20033 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20034 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20035 "!optimize_size
20036 && peep2_regno_dead_p (0, FLAGS_REG)
20037 && ((TARGET_PENTIUM
20038 && (GET_CODE (operands[0]) != MEM
20039 || !memory_displacement_operand (operands[0], SImode)))
20040 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20041 [(parallel [(set (match_dup 0)
20042 (xor:SI (match_dup 1) (const_int -1)))
20043 (clobber (reg:CC FLAGS_REG))])]
20044 "")
20045
20046(define_peephole2
20047 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20048 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20049 "!optimize_size
20050 && peep2_regno_dead_p (0, FLAGS_REG)
20051 && ((TARGET_PENTIUM
20052 && (GET_CODE (operands[0]) != MEM
20053 || !memory_displacement_operand (operands[0], HImode)))
20054 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20055 [(parallel [(set (match_dup 0)
20056 (xor:HI (match_dup 1) (const_int -1)))
20057 (clobber (reg:CC FLAGS_REG))])]
20058 "")
20059
20060(define_peephole2
20061 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20062 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20063 "!optimize_size
20064 && peep2_regno_dead_p (0, FLAGS_REG)
20065 && ((TARGET_PENTIUM
20066 && (GET_CODE (operands[0]) != MEM
20067 || !memory_displacement_operand (operands[0], QImode)))
20068 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20069 [(parallel [(set (match_dup 0)
20070 (xor:QI (match_dup 1) (const_int -1)))
20071 (clobber (reg:CC FLAGS_REG))])]
20072 "")
20073
20074;; Non pairable "test imm, reg" instructions can be translated to
20075;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20076;; byte opcode instead of two, have a short form for byte operands),
20077;; so do it for other CPUs as well. Given that the value was dead,
20078;; this should not create any new dependencies. Pass on the sub-word
20079;; versions if we're concerned about partial register stalls.
20080
20081(define_peephole2
20082 [(set (match_operand 0 "flags_reg_operand" "")
20083 (match_operator 1 "compare_operator"
20084 [(and:SI (match_operand:SI 2 "register_operand" "")
20085 (match_operand:SI 3 "immediate_operand" ""))
20086 (const_int 0)]))]
20087 "ix86_match_ccmode (insn, CCNOmode)
20088 && (true_regnum (operands[2]) != 0
20089 || satisfies_constraint_K (operands[3]))
20090 && peep2_reg_dead_p (1, operands[2])"
20091 [(parallel
20092 [(set (match_dup 0)
20093 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20094 (const_int 0)]))
20095 (set (match_dup 2)
20096 (and:SI (match_dup 2) (match_dup 3)))])]
20097 "")
20098
20099;; We don't need to handle HImode case, because it will be promoted to SImode
20100;; on ! TARGET_PARTIAL_REG_STALL
20101
20102(define_peephole2
20103 [(set (match_operand 0 "flags_reg_operand" "")
20104 (match_operator 1 "compare_operator"
20105 [(and:QI (match_operand:QI 2 "register_operand" "")
20106 (match_operand:QI 3 "immediate_operand" ""))
20107 (const_int 0)]))]
20108 "! TARGET_PARTIAL_REG_STALL
20109 && ix86_match_ccmode (insn, CCNOmode)
20110 && true_regnum (operands[2]) != 0
20111 && peep2_reg_dead_p (1, operands[2])"
20112 [(parallel
20113 [(set (match_dup 0)
20114 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20115 (const_int 0)]))
20116 (set (match_dup 2)
20117 (and:QI (match_dup 2) (match_dup 3)))])]
20118 "")
20119
20120(define_peephole2
20121 [(set (match_operand 0 "flags_reg_operand" "")
20122 (match_operator 1 "compare_operator"
20123 [(and:SI
20124 (zero_extract:SI
20125 (match_operand 2 "ext_register_operand" "")
20126 (const_int 8)
20127 (const_int 8))
20128 (match_operand 3 "const_int_operand" ""))
20129 (const_int 0)]))]
20130 "! TARGET_PARTIAL_REG_STALL
20131 && ix86_match_ccmode (insn, CCNOmode)
20132 && true_regnum (operands[2]) != 0
20133 && peep2_reg_dead_p (1, operands[2])"
20134 [(parallel [(set (match_dup 0)
20135 (match_op_dup 1
20136 [(and:SI
20137 (zero_extract:SI
20138 (match_dup 2)
20139 (const_int 8)
20140 (const_int 8))
20141 (match_dup 3))
20142 (const_int 0)]))
20143 (set (zero_extract:SI (match_dup 2)
20144 (const_int 8)
20145 (const_int 8))
20146 (and:SI
20147 (zero_extract:SI
20148 (match_dup 2)
20149 (const_int 8)
20150 (const_int 8))
20151 (match_dup 3)))])]
20152 "")
20153
20154;; Don't do logical operations with memory inputs.
20155(define_peephole2
20156 [(match_scratch:SI 2 "r")
20157 (parallel [(set (match_operand:SI 0 "register_operand" "")
20158 (match_operator:SI 3 "arith_or_logical_operator"
20159 [(match_dup 0)
20160 (match_operand:SI 1 "memory_operand" "")]))
20161 (clobber (reg:CC FLAGS_REG))])]
20162 "! optimize_size && ! TARGET_READ_MODIFY"
20163 [(set (match_dup 2) (match_dup 1))
20164 (parallel [(set (match_dup 0)
20165 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20166 (clobber (reg:CC FLAGS_REG))])]
20167 "")
20168
20169(define_peephole2
20170 [(match_scratch:SI 2 "r")
20171 (parallel [(set (match_operand:SI 0 "register_operand" "")
20172 (match_operator:SI 3 "arith_or_logical_operator"
20173 [(match_operand:SI 1 "memory_operand" "")
20174 (match_dup 0)]))
20175 (clobber (reg:CC FLAGS_REG))])]
20176 "! optimize_size && ! TARGET_READ_MODIFY"
20177 [(set (match_dup 2) (match_dup 1))
20178 (parallel [(set (match_dup 0)
20179 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20180 (clobber (reg:CC FLAGS_REG))])]
20181 "")
20182
20183; Don't do logical operations with memory outputs
20184;
20185; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20186; instruction into two 1-uop insns plus a 2-uop insn. That last has
20187; the same decoder scheduling characteristics as the original.
20188
20189(define_peephole2
20190 [(match_scratch:SI 2 "r")
20191 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20192 (match_operator:SI 3 "arith_or_logical_operator"
20193 [(match_dup 0)
20194 (match_operand:SI 1 "nonmemory_operand" "")]))
20195 (clobber (reg:CC FLAGS_REG))])]
20196 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20197 [(set (match_dup 2) (match_dup 0))
20198 (parallel [(set (match_dup 2)
20199 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20200 (clobber (reg:CC FLAGS_REG))])
20201 (set (match_dup 0) (match_dup 2))]
20202 "")
20203
20204(define_peephole2
20205 [(match_scratch:SI 2 "r")
20206 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20207 (match_operator:SI 3 "arith_or_logical_operator"
20208 [(match_operand:SI 1 "nonmemory_operand" "")
20209 (match_dup 0)]))
20210 (clobber (reg:CC FLAGS_REG))])]
20211 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20212 [(set (match_dup 2) (match_dup 0))
20213 (parallel [(set (match_dup 2)
20214 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20215 (clobber (reg:CC FLAGS_REG))])
20216 (set (match_dup 0) (match_dup 2))]
20217 "")
20218
20219;; Attempt to always use XOR for zeroing registers.
20220(define_peephole2
20221 [(set (match_operand 0 "register_operand" "")
20222 (match_operand 1 "const0_operand" ""))]
20223 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20224 && (! TARGET_USE_MOV0 || optimize_size)
20225 && GENERAL_REG_P (operands[0])
20226 && peep2_regno_dead_p (0, FLAGS_REG)"
20227 [(parallel [(set (match_dup 0) (const_int 0))
20228 (clobber (reg:CC FLAGS_REG))])]
20229{
20230 operands[0] = gen_lowpart (word_mode, operands[0]);
20231})
20232
20233(define_peephole2
20234 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20235 (const_int 0))]
20236 "(GET_MODE (operands[0]) == QImode
20237 || GET_MODE (operands[0]) == HImode)
20238 && (! TARGET_USE_MOV0 || optimize_size)
20239 && peep2_regno_dead_p (0, FLAGS_REG)"
20240 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20241 (clobber (reg:CC FLAGS_REG))])])
20242
20243;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20244(define_peephole2
20245 [(set (match_operand 0 "register_operand" "")
20246 (const_int -1))]
20247 "(GET_MODE (operands[0]) == HImode
20248 || GET_MODE (operands[0]) == SImode
20249 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20250 && (optimize_size || TARGET_PENTIUM)
20251 && peep2_regno_dead_p (0, FLAGS_REG)"
20252 [(parallel [(set (match_dup 0) (const_int -1))
20253 (clobber (reg:CC FLAGS_REG))])]
20254 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20255 operands[0]);")
20256
20257;; Attempt to convert simple leas to adds. These can be created by
20258;; move expanders.
20259(define_peephole2
20260 [(set (match_operand:SI 0 "register_operand" "")
20261 (plus:SI (match_dup 0)
20262 (match_operand:SI 1 "nonmemory_operand" "")))]
20263 "peep2_regno_dead_p (0, FLAGS_REG)"
20264 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20265 (clobber (reg:CC FLAGS_REG))])]
20266 "")
20267
20268(define_peephole2
20269 [(set (match_operand:SI 0 "register_operand" "")
20270 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20271 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20272 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20273 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20274 (clobber (reg:CC FLAGS_REG))])]
20275 "operands[2] = gen_lowpart (SImode, operands[2]);")
20276
20277(define_peephole2
20278 [(set (match_operand:DI 0 "register_operand" "")
20279 (plus:DI (match_dup 0)
20280 (match_operand:DI 1 "x86_64_general_operand" "")))]
20281 "peep2_regno_dead_p (0, FLAGS_REG)"
20282 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20283 (clobber (reg:CC FLAGS_REG))])]
20284 "")
20285
20286(define_peephole2
20287 [(set (match_operand:SI 0 "register_operand" "")
20288 (mult:SI (match_dup 0)
20289 (match_operand:SI 1 "const_int_operand" "")))]
20290 "exact_log2 (INTVAL (operands[1])) >= 0
20291 && peep2_regno_dead_p (0, FLAGS_REG)"
20292 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20293 (clobber (reg:CC FLAGS_REG))])]
20294 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20295
20296(define_peephole2
20297 [(set (match_operand:DI 0 "register_operand" "")
20298 (mult:DI (match_dup 0)
20299 (match_operand:DI 1 "const_int_operand" "")))]
20300 "exact_log2 (INTVAL (operands[1])) >= 0
20301 && peep2_regno_dead_p (0, FLAGS_REG)"
20302 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20303 (clobber (reg:CC FLAGS_REG))])]
20304 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20305
20306(define_peephole2
20307 [(set (match_operand:SI 0 "register_operand" "")
20308 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20309 (match_operand:DI 2 "const_int_operand" "")) 0))]
20310 "exact_log2 (INTVAL (operands[2])) >= 0
20311 && REGNO (operands[0]) == REGNO (operands[1])
20312 && peep2_regno_dead_p (0, FLAGS_REG)"
20313 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20314 (clobber (reg:CC FLAGS_REG))])]
20315 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20316
20317;; The ESP adjustments can be done by the push and pop instructions. Resulting
20318;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20319;; many CPUs it is also faster, since special hardware to avoid esp
20320;; dependencies is present.
20321
20322;; While some of these conversions may be done using splitters, we use peepholes
20323;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20324
20325;; Convert prologue esp subtractions to push.
20326;; We need register to push. In order to keep verify_flow_info happy we have
20327;; two choices
20328;; - use scratch and clobber it in order to avoid dependencies
20329;; - use already live register
20330;; We can't use the second way right now, since there is no reliable way how to
20331;; verify that given register is live. First choice will also most likely in
20332;; fewer dependencies. On the place of esp adjustments it is very likely that
20333;; call clobbered registers are dead. We may want to use base pointer as an
20334;; alternative when no register is available later.
20335
20336(define_peephole2
20337 [(match_scratch:SI 0 "r")
20338 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20339 (clobber (reg:CC FLAGS_REG))
20340 (clobber (mem:BLK (scratch)))])]
20341 "optimize_size || !TARGET_SUB_ESP_4"
20342 [(clobber (match_dup 0))
20343 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20344 (clobber (mem:BLK (scratch)))])])
20345
20346(define_peephole2
20347 [(match_scratch:SI 0 "r")
20348 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20349 (clobber (reg:CC FLAGS_REG))
20350 (clobber (mem:BLK (scratch)))])]
20351 "optimize_size || !TARGET_SUB_ESP_8"
20352 [(clobber (match_dup 0))
20353 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20354 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20355 (clobber (mem:BLK (scratch)))])])
20356
20357;; Convert esp subtractions to push.
20358(define_peephole2
20359 [(match_scratch:SI 0 "r")
20360 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20361 (clobber (reg:CC FLAGS_REG))])]
20362 "optimize_size || !TARGET_SUB_ESP_4"
20363 [(clobber (match_dup 0))
20364 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20365
20366(define_peephole2
20367 [(match_scratch:SI 0 "r")
20368 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20369 (clobber (reg:CC FLAGS_REG))])]
20370 "optimize_size || !TARGET_SUB_ESP_8"
20371 [(clobber (match_dup 0))
20372 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20373 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20374
20375;; Convert epilogue deallocator to pop.
20376(define_peephole2
20377 [(match_scratch:SI 0 "r")
20378 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20379 (clobber (reg:CC FLAGS_REG))
20380 (clobber (mem:BLK (scratch)))])]
20381 "optimize_size || !TARGET_ADD_ESP_4"
20382 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20383 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20384 (clobber (mem:BLK (scratch)))])]
20385 "")
20386
20387;; Two pops case is tricky, since pop causes dependency on destination register.
20388;; We use two registers if available.
20389(define_peephole2
20390 [(match_scratch:SI 0 "r")
20391 (match_scratch:SI 1 "r")
20392 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20393 (clobber (reg:CC FLAGS_REG))
20394 (clobber (mem:BLK (scratch)))])]
20395 "optimize_size || !TARGET_ADD_ESP_8"
20396 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20397 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20398 (clobber (mem:BLK (scratch)))])
20399 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20400 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20401 "")
20402
20403(define_peephole2
20404 [(match_scratch:SI 0 "r")
20405 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20406 (clobber (reg:CC FLAGS_REG))
20407 (clobber (mem:BLK (scratch)))])]
20408 "optimize_size"
20409 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20411 (clobber (mem:BLK (scratch)))])
20412 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20414 "")
20415
20416;; Convert esp additions to pop.
20417(define_peephole2
20418 [(match_scratch:SI 0 "r")
20419 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20420 (clobber (reg:CC FLAGS_REG))])]
20421 ""
20422 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20423 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20424 "")
20425
20426;; Two pops case is tricky, since pop causes dependency on destination register.
20427;; We use two registers if available.
20428(define_peephole2
20429 [(match_scratch:SI 0 "r")
20430 (match_scratch:SI 1 "r")
20431 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20432 (clobber (reg:CC FLAGS_REG))])]
20433 ""
20434 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20435 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20436 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20437 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20438 "")
20439
20440(define_peephole2
20441 [(match_scratch:SI 0 "r")
20442 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20443 (clobber (reg:CC FLAGS_REG))])]
20444 "optimize_size"
20445 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20446 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20447 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20448 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20449 "")
20450
20451;; Convert compares with 1 to shorter inc/dec operations when CF is not
20452;; required and register dies. Similarly for 128 to plus -128.
20453(define_peephole2
20454 [(set (match_operand 0 "flags_reg_operand" "")
20455 (match_operator 1 "compare_operator"
20456 [(match_operand 2 "register_operand" "")
20457 (match_operand 3 "const_int_operand" "")]))]
20458 "(INTVAL (operands[3]) == -1
20459 || INTVAL (operands[3]) == 1
20460 || INTVAL (operands[3]) == 128)
20461 && ix86_match_ccmode (insn, CCGCmode)
20462 && peep2_reg_dead_p (1, operands[2])"
20463 [(parallel [(set (match_dup 0)
20464 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20465 (clobber (match_dup 2))])]
20466 "")
20467
20468(define_peephole2
20469 [(match_scratch:DI 0 "r")
20470 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20471 (clobber (reg:CC FLAGS_REG))
20472 (clobber (mem:BLK (scratch)))])]
20473 "optimize_size || !TARGET_SUB_ESP_4"
20474 [(clobber (match_dup 0))
20475 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20476 (clobber (mem:BLK (scratch)))])])
20477
20478(define_peephole2
20479 [(match_scratch:DI 0 "r")
20480 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20481 (clobber (reg:CC FLAGS_REG))
20482 (clobber (mem:BLK (scratch)))])]
20483 "optimize_size || !TARGET_SUB_ESP_8"
20484 [(clobber (match_dup 0))
20485 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20486 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20487 (clobber (mem:BLK (scratch)))])])
20488
20489;; Convert esp subtractions to push.
20490(define_peephole2
20491 [(match_scratch:DI 0 "r")
20492 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20493 (clobber (reg:CC FLAGS_REG))])]
20494 "optimize_size || !TARGET_SUB_ESP_4"
20495 [(clobber (match_dup 0))
20496 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20497
20498(define_peephole2
20499 [(match_scratch:DI 0 "r")
20500 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20501 (clobber (reg:CC FLAGS_REG))])]
20502 "optimize_size || !TARGET_SUB_ESP_8"
20503 [(clobber (match_dup 0))
20504 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20505 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20506
20507;; Convert epilogue deallocator to pop.
20508(define_peephole2
20509 [(match_scratch:DI 0 "r")
20510 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20511 (clobber (reg:CC FLAGS_REG))
20512 (clobber (mem:BLK (scratch)))])]
20513 "optimize_size || !TARGET_ADD_ESP_4"
20514 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20515 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20516 (clobber (mem:BLK (scratch)))])]
20517 "")
20518
20519;; Two pops case is tricky, since pop causes dependency on destination register.
20520;; We use two registers if available.
20521(define_peephole2
20522 [(match_scratch:DI 0 "r")
20523 (match_scratch:DI 1 "r")
20524 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20525 (clobber (reg:CC FLAGS_REG))
20526 (clobber (mem:BLK (scratch)))])]
20527 "optimize_size || !TARGET_ADD_ESP_8"
20528 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20529 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20530 (clobber (mem:BLK (scratch)))])
20531 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20532 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20533 "")
20534
20535(define_peephole2
20536 [(match_scratch:DI 0 "r")
20537 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20538 (clobber (reg:CC FLAGS_REG))
20539 (clobber (mem:BLK (scratch)))])]
20540 "optimize_size"
20541 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20542 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20543 (clobber (mem:BLK (scratch)))])
20544 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20546 "")
20547
20548;; Convert esp additions to pop.
20549(define_peephole2
20550 [(match_scratch:DI 0 "r")
20551 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20552 (clobber (reg:CC FLAGS_REG))])]
20553 ""
20554 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20555 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20556 "")
20557
20558;; Two pops case is tricky, since pop causes dependency on destination register.
20559;; We use two registers if available.
20560(define_peephole2
20561 [(match_scratch:DI 0 "r")
20562 (match_scratch:DI 1 "r")
20563 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20564 (clobber (reg:CC FLAGS_REG))])]
20565 ""
20566 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20567 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20568 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20569 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20570 "")
20571
20572(define_peephole2
20573 [(match_scratch:DI 0 "r")
20574 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20575 (clobber (reg:CC FLAGS_REG))])]
20576 "optimize_size"
20577 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20578 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20579 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20580 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20581 "")
20582
20583;; Convert imul by three, five and nine into lea
20584(define_peephole2
20585 [(parallel
20586 [(set (match_operand:SI 0 "register_operand" "")
20587 (mult:SI (match_operand:SI 1 "register_operand" "")
20588 (match_operand:SI 2 "const_int_operand" "")))
20589 (clobber (reg:CC FLAGS_REG))])]
20590 "INTVAL (operands[2]) == 3
20591 || INTVAL (operands[2]) == 5
20592 || INTVAL (operands[2]) == 9"
20593 [(set (match_dup 0)
20594 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20595 (match_dup 1)))]
20596 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20597
20598(define_peephole2
20599 [(parallel
20600 [(set (match_operand:SI 0 "register_operand" "")
20601 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20602 (match_operand:SI 2 "const_int_operand" "")))
20603 (clobber (reg:CC FLAGS_REG))])]
20604 "!optimize_size
20605 && (INTVAL (operands[2]) == 3
20606 || INTVAL (operands[2]) == 5
20607 || INTVAL (operands[2]) == 9)"
20608 [(set (match_dup 0) (match_dup 1))
20609 (set (match_dup 0)
20610 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20611 (match_dup 0)))]
20612 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20613
20614(define_peephole2
20615 [(parallel
20616 [(set (match_operand:DI 0 "register_operand" "")
20617 (mult:DI (match_operand:DI 1 "register_operand" "")
20618 (match_operand:DI 2 "const_int_operand" "")))
20619 (clobber (reg:CC FLAGS_REG))])]
20620 "TARGET_64BIT
20621 && (INTVAL (operands[2]) == 3
20622 || INTVAL (operands[2]) == 5
20623 || INTVAL (operands[2]) == 9)"
20624 [(set (match_dup 0)
20625 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20626 (match_dup 1)))]
20627 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20628
20629(define_peephole2
20630 [(parallel
20631 [(set (match_operand:DI 0 "register_operand" "")
20632 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20633 (match_operand:DI 2 "const_int_operand" "")))
20634 (clobber (reg:CC FLAGS_REG))])]
20635 "TARGET_64BIT
20636 && !optimize_size
20637 && (INTVAL (operands[2]) == 3
20638 || INTVAL (operands[2]) == 5
20639 || INTVAL (operands[2]) == 9)"
20640 [(set (match_dup 0) (match_dup 1))
20641 (set (match_dup 0)
20642 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20643 (match_dup 0)))]
20644 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20645
20646;; Imul $32bit_imm, mem, reg is vector decoded, while
20647;; imul $32bit_imm, reg, reg is direct decoded.
20648(define_peephole2
20649 [(match_scratch:DI 3 "r")
20650 (parallel [(set (match_operand:DI 0 "register_operand" "")
20651 (mult:DI (match_operand:DI 1 "memory_operand" "")
20652 (match_operand:DI 2 "immediate_operand" "")))
20653 (clobber (reg:CC FLAGS_REG))])]
20394 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20654 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20395 && !satisfies_constraint_K (operands[2])"
20396 [(set (match_dup 3) (match_dup 1))
20397 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20398 (clobber (reg:CC FLAGS_REG))])]
20399"")
20400
20401(define_peephole2
20402 [(match_scratch:SI 3 "r")
20403 (parallel [(set (match_operand:SI 0 "register_operand" "")
20404 (mult:SI (match_operand:SI 1 "memory_operand" "")
20405 (match_operand:SI 2 "immediate_operand" "")))
20406 (clobber (reg:CC FLAGS_REG))])]
20655 && !satisfies_constraint_K (operands[2])"
20656 [(set (match_dup 3) (match_dup 1))
20657 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20658 (clobber (reg:CC FLAGS_REG))])]
20659"")
20660
20661(define_peephole2
20662 [(match_scratch:SI 3 "r")
20663 (parallel [(set (match_operand:SI 0 "register_operand" "")
20664 (mult:SI (match_operand:SI 1 "memory_operand" "")
20665 (match_operand:SI 2 "immediate_operand" "")))
20666 (clobber (reg:CC FLAGS_REG))])]
20407 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20667 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20408 && !satisfies_constraint_K (operands[2])"
20409 [(set (match_dup 3) (match_dup 1))
20410 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20411 (clobber (reg:CC FLAGS_REG))])]
20412"")
20413
20414(define_peephole2
20415 [(match_scratch:SI 3 "r")
20416 (parallel [(set (match_operand:DI 0 "register_operand" "")
20417 (zero_extend:DI
20418 (mult:SI (match_operand:SI 1 "memory_operand" "")
20419 (match_operand:SI 2 "immediate_operand" ""))))
20420 (clobber (reg:CC FLAGS_REG))])]
20668 && !satisfies_constraint_K (operands[2])"
20669 [(set (match_dup 3) (match_dup 1))
20670 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20671 (clobber (reg:CC FLAGS_REG))])]
20672"")
20673
20674(define_peephole2
20675 [(match_scratch:SI 3 "r")
20676 (parallel [(set (match_operand:DI 0 "register_operand" "")
20677 (zero_extend:DI
20678 (mult:SI (match_operand:SI 1 "memory_operand" "")
20679 (match_operand:SI 2 "immediate_operand" ""))))
20680 (clobber (reg:CC FLAGS_REG))])]
20421 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20681 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20422 && !satisfies_constraint_K (operands[2])"
20423 [(set (match_dup 3) (match_dup 1))
20424 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20425 (clobber (reg:CC FLAGS_REG))])]
20426"")
20427
20428;; imul $8/16bit_imm, regmem, reg is vector decoded.
20429;; Convert it into imul reg, reg
20430;; It would be better to force assembler to encode instruction using long
20431;; immediate, but there is apparently no way to do so.
20432(define_peephole2
20433 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20434 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20435 (match_operand:DI 2 "const_int_operand" "")))
20436 (clobber (reg:CC FLAGS_REG))])
20437 (match_scratch:DI 3 "r")]
20682 && !satisfies_constraint_K (operands[2])"
20683 [(set (match_dup 3) (match_dup 1))
20684 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20685 (clobber (reg:CC FLAGS_REG))])]
20686"")
20687
20688;; imul $8/16bit_imm, regmem, reg is vector decoded.
20689;; Convert it into imul reg, reg
20690;; It would be better to force assembler to encode instruction using long
20691;; immediate, but there is apparently no way to do so.
20692(define_peephole2
20693 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20694 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20695 (match_operand:DI 2 "const_int_operand" "")))
20696 (clobber (reg:CC FLAGS_REG))])
20697 (match_scratch:DI 3 "r")]
20438 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20698 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20439 && satisfies_constraint_K (operands[2])"
20440 [(set (match_dup 3) (match_dup 2))
20441 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20442 (clobber (reg:CC FLAGS_REG))])]
20443{
20444 if (!rtx_equal_p (operands[0], operands[1]))
20445 emit_move_insn (operands[0], operands[1]);
20446})
20447
20448(define_peephole2
20449 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20450 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20451 (match_operand:SI 2 "const_int_operand" "")))
20452 (clobber (reg:CC FLAGS_REG))])
20453 (match_scratch:SI 3 "r")]
20699 && satisfies_constraint_K (operands[2])"
20700 [(set (match_dup 3) (match_dup 2))
20701 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20702 (clobber (reg:CC FLAGS_REG))])]
20703{
20704 if (!rtx_equal_p (operands[0], operands[1]))
20705 emit_move_insn (operands[0], operands[1]);
20706})
20707
20708(define_peephole2
20709 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20710 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20711 (match_operand:SI 2 "const_int_operand" "")))
20712 (clobber (reg:CC FLAGS_REG))])
20713 (match_scratch:SI 3 "r")]
20454 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20714 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20455 && satisfies_constraint_K (operands[2])"
20456 [(set (match_dup 3) (match_dup 2))
20457 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20458 (clobber (reg:CC FLAGS_REG))])]
20459{
20460 if (!rtx_equal_p (operands[0], operands[1]))
20461 emit_move_insn (operands[0], operands[1]);
20462})
20463
20464(define_peephole2
20465 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20466 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20467 (match_operand:HI 2 "immediate_operand" "")))
20468 (clobber (reg:CC FLAGS_REG))])
20469 (match_scratch:HI 3 "r")]
20715 && satisfies_constraint_K (operands[2])"
20716 [(set (match_dup 3) (match_dup 2))
20717 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20718 (clobber (reg:CC FLAGS_REG))])]
20719{
20720 if (!rtx_equal_p (operands[0], operands[1]))
20721 emit_move_insn (operands[0], operands[1]);
20722})
20723
20724(define_peephole2
20725 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20726 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20727 (match_operand:HI 2 "immediate_operand" "")))
20728 (clobber (reg:CC FLAGS_REG))])
20729 (match_scratch:HI 3 "r")]
20470 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20730 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20471 [(set (match_dup 3) (match_dup 2))
20472 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20473 (clobber (reg:CC FLAGS_REG))])]
20474{
20475 if (!rtx_equal_p (operands[0], operands[1]))
20476 emit_move_insn (operands[0], operands[1]);
20477})
20478
20479;; After splitting up read-modify operations, array accesses with memory
20480;; operands might end up in form:
20481;; sall $2, %eax
20482;; movl 4(%esp), %edx
20483;; addl %edx, %eax
20484;; instead of pre-splitting:
20485;; sall $2, %eax
20486;; addl 4(%esp), %eax
20487;; Turn it into:
20488;; movl 4(%esp), %edx
20489;; leal (%edx,%eax,4), %eax
20490
20491(define_peephole2
20492 [(parallel [(set (match_operand 0 "register_operand" "")
20493 (ashift (match_operand 1 "register_operand" "")
20494 (match_operand 2 "const_int_operand" "")))
20495 (clobber (reg:CC FLAGS_REG))])
20496 (set (match_operand 3 "register_operand")
20497 (match_operand 4 "x86_64_general_operand" ""))
20498 (parallel [(set (match_operand 5 "register_operand" "")
20499 (plus (match_operand 6 "register_operand" "")
20500 (match_operand 7 "register_operand" "")))
20501 (clobber (reg:CC FLAGS_REG))])]
20502 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20503 /* Validate MODE for lea. */
20504 && ((!TARGET_PARTIAL_REG_STALL
20505 && (GET_MODE (operands[0]) == QImode
20506 || GET_MODE (operands[0]) == HImode))
20507 || GET_MODE (operands[0]) == SImode
20508 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20509 /* We reorder load and the shift. */
20510 && !rtx_equal_p (operands[1], operands[3])
20511 && !reg_overlap_mentioned_p (operands[0], operands[4])
20512 /* Last PLUS must consist of operand 0 and 3. */
20513 && !rtx_equal_p (operands[0], operands[3])
20514 && (rtx_equal_p (operands[3], operands[6])
20515 || rtx_equal_p (operands[3], operands[7]))
20516 && (rtx_equal_p (operands[0], operands[6])
20517 || rtx_equal_p (operands[0], operands[7]))
20518 /* The intermediate operand 0 must die or be same as output. */
20519 && (rtx_equal_p (operands[0], operands[5])
20520 || peep2_reg_dead_p (3, operands[0]))"
20521 [(set (match_dup 3) (match_dup 4))
20522 (set (match_dup 0) (match_dup 1))]
20523{
20524 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20525 int scale = 1 << INTVAL (operands[2]);
20526 rtx index = gen_lowpart (Pmode, operands[1]);
20527 rtx base = gen_lowpart (Pmode, operands[3]);
20528 rtx dest = gen_lowpart (mode, operands[5]);
20529
20530 operands[1] = gen_rtx_PLUS (Pmode, base,
20531 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20532 if (mode != Pmode)
20533 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20534 operands[0] = dest;
20535})
20536
20537;; Call-value patterns last so that the wildcard operand does not
20538;; disrupt insn-recog's switch tables.
20539
20540(define_insn "*call_value_pop_0"
20541 [(set (match_operand 0 "" "")
20542 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20543 (match_operand:SI 2 "" "")))
20544 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20545 (match_operand:SI 3 "immediate_operand" "")))]
20546 "!TARGET_64BIT"
20547{
20548 if (SIBLING_CALL_P (insn))
20549 return "jmp\t%P1";
20550 else
20551 return "call\t%P1";
20552}
20553 [(set_attr "type" "callv")])
20554
20555(define_insn "*call_value_pop_1"
20556 [(set (match_operand 0 "" "")
20557 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20558 (match_operand:SI 2 "" "")))
20559 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20560 (match_operand:SI 3 "immediate_operand" "i")))]
20561 "!TARGET_64BIT"
20562{
20563 if (constant_call_address_operand (operands[1], Pmode))
20564 {
20565 if (SIBLING_CALL_P (insn))
20566 return "jmp\t%P1";
20567 else
20568 return "call\t%P1";
20569 }
20570 if (SIBLING_CALL_P (insn))
20571 return "jmp\t%A1";
20572 else
20573 return "call\t%A1";
20574}
20575 [(set_attr "type" "callv")])
20576
20577(define_insn "*call_value_0"
20578 [(set (match_operand 0 "" "")
20579 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20580 (match_operand:SI 2 "" "")))]
20581 "!TARGET_64BIT"
20582{
20583 if (SIBLING_CALL_P (insn))
20584 return "jmp\t%P1";
20585 else
20586 return "call\t%P1";
20587}
20588 [(set_attr "type" "callv")])
20589
20590(define_insn "*call_value_0_rex64"
20591 [(set (match_operand 0 "" "")
20592 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20593 (match_operand:DI 2 "const_int_operand" "")))]
20594 "TARGET_64BIT"
20595{
20596 if (SIBLING_CALL_P (insn))
20597 return "jmp\t%P1";
20598 else
20599 return "call\t%P1";
20600}
20601 [(set_attr "type" "callv")])
20602
20603(define_insn "*call_value_1"
20604 [(set (match_operand 0 "" "")
20605 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20606 (match_operand:SI 2 "" "")))]
20607 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20608{
20609 if (constant_call_address_operand (operands[1], Pmode))
20610 return "call\t%P1";
20611 return "call\t%A1";
20612}
20613 [(set_attr "type" "callv")])
20614
20615(define_insn "*sibcall_value_1"
20616 [(set (match_operand 0 "" "")
20617 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20618 (match_operand:SI 2 "" "")))]
20619 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20620{
20621 if (constant_call_address_operand (operands[1], Pmode))
20622 return "jmp\t%P1";
20623 return "jmp\t%A1";
20624}
20625 [(set_attr "type" "callv")])
20626
20627(define_insn "*call_value_1_rex64"
20628 [(set (match_operand 0 "" "")
20629 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20630 (match_operand:DI 2 "" "")))]
20631 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20632{
20633 if (constant_call_address_operand (operands[1], Pmode))
20634 return "call\t%P1";
20635 return "call\t%A1";
20636}
20637 [(set_attr "type" "callv")])
20638
20639(define_insn "*sibcall_value_1_rex64"
20640 [(set (match_operand 0 "" "")
20641 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20642 (match_operand:DI 2 "" "")))]
20643 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20644 "jmp\t%P1"
20645 [(set_attr "type" "callv")])
20646
20647(define_insn "*sibcall_value_1_rex64_v"
20648 [(set (match_operand 0 "" "")
20649 (call (mem:QI (reg:DI 40))
20650 (match_operand:DI 1 "" "")))]
20651 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20652 "jmp\t*%%r11"
20653 [(set_attr "type" "callv")])
20654
20655;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20656;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20657;; caught for use by garbage collectors and the like. Using an insn that
20658;; maps to SIGILL makes it more likely the program will rightfully die.
20659;; Keeping with tradition, "6" is in honor of #UD.
20660(define_insn "trap"
20661 [(trap_if (const_int 1) (const_int 6))]
20662 ""
20663 { return ASM_SHORT "0x0b0f"; }
20664 [(set_attr "length" "2")])
20665
20666(define_expand "sse_prologue_save"
20667 [(parallel [(set (match_operand:BLK 0 "" "")
20668 (unspec:BLK [(reg:DI 21)
20669 (reg:DI 22)
20670 (reg:DI 23)
20671 (reg:DI 24)
20672 (reg:DI 25)
20673 (reg:DI 26)
20674 (reg:DI 27)
20675 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20676 (use (match_operand:DI 1 "register_operand" ""))
20677 (use (match_operand:DI 2 "immediate_operand" ""))
20678 (use (label_ref:DI (match_operand 3 "" "")))])]
20679 "TARGET_64BIT"
20680 "")
20681
20682(define_insn "*sse_prologue_save_insn"
20683 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20684 (match_operand:DI 4 "const_int_operand" "n")))
20685 (unspec:BLK [(reg:DI 21)
20686 (reg:DI 22)
20687 (reg:DI 23)
20688 (reg:DI 24)
20689 (reg:DI 25)
20690 (reg:DI 26)
20691 (reg:DI 27)
20692 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20693 (use (match_operand:DI 1 "register_operand" "r"))
20694 (use (match_operand:DI 2 "const_int_operand" "i"))
20695 (use (label_ref:DI (match_operand 3 "" "X")))]
20696 "TARGET_64BIT
20697 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20698 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20699 "*
20700{
20701 int i;
20702 operands[0] = gen_rtx_MEM (Pmode,
20703 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20704 output_asm_insn (\"jmp\\t%A1\", operands);
20705 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20706 {
20707 operands[4] = adjust_address (operands[0], DImode, i*16);
20708 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20709 PUT_MODE (operands[4], TImode);
20710 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20711 output_asm_insn (\"rex\", operands);
20712 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20713 }
20714 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20715 CODE_LABEL_NUMBER (operands[3]));
20716 RET;
20717}
20718 "
20719 [(set_attr "type" "other")
20720 (set_attr "length_immediate" "0")
20721 (set_attr "length_address" "0")
20722 (set_attr "length" "135")
20723 (set_attr "memory" "store")
20724 (set_attr "modrm" "0")
20725 (set_attr "mode" "DI")])
20726
20727(define_expand "prefetch"
20728 [(prefetch (match_operand 0 "address_operand" "")
20729 (match_operand:SI 1 "const_int_operand" "")
20730 (match_operand:SI 2 "const_int_operand" ""))]
20731 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20732{
20733 int rw = INTVAL (operands[1]);
20734 int locality = INTVAL (operands[2]);
20735
20736 gcc_assert (rw == 0 || rw == 1);
20737 gcc_assert (locality >= 0 && locality <= 3);
20738 gcc_assert (GET_MODE (operands[0]) == Pmode
20739 || GET_MODE (operands[0]) == VOIDmode);
20740
20741 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20742 supported by SSE counterpart or the SSE prefetch is not available
20743 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20744 of locality. */
20745 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20746 operands[2] = GEN_INT (3);
20747 else
20748 operands[1] = const0_rtx;
20749})
20750
20751(define_insn "*prefetch_sse"
20752 [(prefetch (match_operand:SI 0 "address_operand" "p")
20753 (const_int 0)
20754 (match_operand:SI 1 "const_int_operand" ""))]
20755 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20756{
20757 static const char * const patterns[4] = {
20758 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20759 };
20760
20761 int locality = INTVAL (operands[1]);
20762 gcc_assert (locality >= 0 && locality <= 3);
20763
20764 return patterns[locality];
20765}
20766 [(set_attr "type" "sse")
20767 (set_attr "memory" "none")])
20768
20769(define_insn "*prefetch_sse_rex"
20770 [(prefetch (match_operand:DI 0 "address_operand" "p")
20771 (const_int 0)
20772 (match_operand:SI 1 "const_int_operand" ""))]
20773 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20774{
20775 static const char * const patterns[4] = {
20776 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20777 };
20778
20779 int locality = INTVAL (operands[1]);
20780 gcc_assert (locality >= 0 && locality <= 3);
20781
20782 return patterns[locality];
20783}
20784 [(set_attr "type" "sse")
20785 (set_attr "memory" "none")])
20786
20787(define_insn "*prefetch_3dnow"
20788 [(prefetch (match_operand:SI 0 "address_operand" "p")
20789 (match_operand:SI 1 "const_int_operand" "n")
20790 (const_int 3))]
20791 "TARGET_3DNOW && !TARGET_64BIT"
20792{
20793 if (INTVAL (operands[1]) == 0)
20794 return "prefetch\t%a0";
20795 else
20796 return "prefetchw\t%a0";
20797}
20798 [(set_attr "type" "mmx")
20799 (set_attr "memory" "none")])
20800
20801(define_insn "*prefetch_3dnow_rex"
20802 [(prefetch (match_operand:DI 0 "address_operand" "p")
20803 (match_operand:SI 1 "const_int_operand" "n")
20804 (const_int 3))]
20805 "TARGET_3DNOW && TARGET_64BIT"
20806{
20807 if (INTVAL (operands[1]) == 0)
20808 return "prefetch\t%a0";
20809 else
20810 return "prefetchw\t%a0";
20811}
20812 [(set_attr "type" "mmx")
20813 (set_attr "memory" "none")])
20814
20815(define_expand "stack_protect_set"
20816 [(match_operand 0 "memory_operand" "")
20817 (match_operand 1 "memory_operand" "")]
20818 ""
20819{
20820#ifdef TARGET_THREAD_SSP_OFFSET
20821 if (TARGET_64BIT)
20822 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20823 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20824 else
20825 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20826 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20827#else
20828 if (TARGET_64BIT)
20829 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20830 else
20831 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20832#endif
20833 DONE;
20834})
20835
20836(define_insn "stack_protect_set_si"
20837 [(set (match_operand:SI 0 "memory_operand" "=m")
20838 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20839 (set (match_scratch:SI 2 "=&r") (const_int 0))
20840 (clobber (reg:CC FLAGS_REG))]
20841 ""
20842 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20843 [(set_attr "type" "multi")])
20844
20845(define_insn "stack_protect_set_di"
20846 [(set (match_operand:DI 0 "memory_operand" "=m")
20847 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20848 (set (match_scratch:DI 2 "=&r") (const_int 0))
20849 (clobber (reg:CC FLAGS_REG))]
20850 "TARGET_64BIT"
20851 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20852 [(set_attr "type" "multi")])
20853
20854(define_insn "stack_tls_protect_set_si"
20855 [(set (match_operand:SI 0 "memory_operand" "=m")
20856 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20857 (set (match_scratch:SI 2 "=&r") (const_int 0))
20858 (clobber (reg:CC FLAGS_REG))]
20859 ""
20860 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20861 [(set_attr "type" "multi")])
20862
20863(define_insn "stack_tls_protect_set_di"
20864 [(set (match_operand:DI 0 "memory_operand" "=m")
20865 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20866 (set (match_scratch:DI 2 "=&r") (const_int 0))
20867 (clobber (reg:CC FLAGS_REG))]
20868 "TARGET_64BIT"
20869 {
20870 /* The kernel uses a different segment register for performance reasons; a
20871 system call would not have to trash the userspace segment register,
20872 which would be expensive */
20873 if (ix86_cmodel != CM_KERNEL)
20874 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20875 else
20876 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20877 }
20878 [(set_attr "type" "multi")])
20879
20880(define_expand "stack_protect_test"
20881 [(match_operand 0 "memory_operand" "")
20882 (match_operand 1 "memory_operand" "")
20883 (match_operand 2 "" "")]
20884 ""
20885{
20886 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20887 ix86_compare_op0 = operands[0];
20888 ix86_compare_op1 = operands[1];
20889 ix86_compare_emitted = flags;
20890
20891#ifdef TARGET_THREAD_SSP_OFFSET
20892 if (TARGET_64BIT)
20893 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20894 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20895 else
20896 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20897 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20898#else
20899 if (TARGET_64BIT)
20900 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20901 else
20902 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20903#endif
20904 emit_jump_insn (gen_beq (operands[2]));
20905 DONE;
20906})
20907
20908(define_insn "stack_protect_test_si"
20909 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20910 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20911 (match_operand:SI 2 "memory_operand" "m")]
20912 UNSPEC_SP_TEST))
20913 (clobber (match_scratch:SI 3 "=&r"))]
20914 ""
20915 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20916 [(set_attr "type" "multi")])
20917
20918(define_insn "stack_protect_test_di"
20919 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20920 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20921 (match_operand:DI 2 "memory_operand" "m")]
20922 UNSPEC_SP_TEST))
20923 (clobber (match_scratch:DI 3 "=&r"))]
20924 "TARGET_64BIT"
20925 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20926 [(set_attr "type" "multi")])
20927
20928(define_insn "stack_tls_protect_test_si"
20929 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20930 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20931 (match_operand:SI 2 "const_int_operand" "i")]
20932 UNSPEC_SP_TLS_TEST))
20933 (clobber (match_scratch:SI 3 "=r"))]
20934 ""
20935 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20936 [(set_attr "type" "multi")])
20937
20938(define_insn "stack_tls_protect_test_di"
20939 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20940 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20941 (match_operand:DI 2 "const_int_operand" "i")]
20942 UNSPEC_SP_TLS_TEST))
20943 (clobber (match_scratch:DI 3 "=r"))]
20944 "TARGET_64BIT"
20945 {
20946 /* The kernel uses a different segment register for performance reasons; a
20947 system call would not have to trash the userspace segment register,
20948 which would be expensive */
20949 if (ix86_cmodel != CM_KERNEL)
20950 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20951 else
20952 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20953 }
20954 [(set_attr "type" "multi")])
20955
20956(include "mmx.md")
20957(include "sse.md")
20958(include "sync.md")
20731 [(set (match_dup 3) (match_dup 2))
20732 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20733 (clobber (reg:CC FLAGS_REG))])]
20734{
20735 if (!rtx_equal_p (operands[0], operands[1]))
20736 emit_move_insn (operands[0], operands[1]);
20737})
20738
20739;; After splitting up read-modify operations, array accesses with memory
20740;; operands might end up in form:
20741;; sall $2, %eax
20742;; movl 4(%esp), %edx
20743;; addl %edx, %eax
20744;; instead of pre-splitting:
20745;; sall $2, %eax
20746;; addl 4(%esp), %eax
20747;; Turn it into:
20748;; movl 4(%esp), %edx
20749;; leal (%edx,%eax,4), %eax
20750
20751(define_peephole2
20752 [(parallel [(set (match_operand 0 "register_operand" "")
20753 (ashift (match_operand 1 "register_operand" "")
20754 (match_operand 2 "const_int_operand" "")))
20755 (clobber (reg:CC FLAGS_REG))])
20756 (set (match_operand 3 "register_operand")
20757 (match_operand 4 "x86_64_general_operand" ""))
20758 (parallel [(set (match_operand 5 "register_operand" "")
20759 (plus (match_operand 6 "register_operand" "")
20760 (match_operand 7 "register_operand" "")))
20761 (clobber (reg:CC FLAGS_REG))])]
20762 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20763 /* Validate MODE for lea. */
20764 && ((!TARGET_PARTIAL_REG_STALL
20765 && (GET_MODE (operands[0]) == QImode
20766 || GET_MODE (operands[0]) == HImode))
20767 || GET_MODE (operands[0]) == SImode
20768 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20769 /* We reorder load and the shift. */
20770 && !rtx_equal_p (operands[1], operands[3])
20771 && !reg_overlap_mentioned_p (operands[0], operands[4])
20772 /* Last PLUS must consist of operand 0 and 3. */
20773 && !rtx_equal_p (operands[0], operands[3])
20774 && (rtx_equal_p (operands[3], operands[6])
20775 || rtx_equal_p (operands[3], operands[7]))
20776 && (rtx_equal_p (operands[0], operands[6])
20777 || rtx_equal_p (operands[0], operands[7]))
20778 /* The intermediate operand 0 must die or be same as output. */
20779 && (rtx_equal_p (operands[0], operands[5])
20780 || peep2_reg_dead_p (3, operands[0]))"
20781 [(set (match_dup 3) (match_dup 4))
20782 (set (match_dup 0) (match_dup 1))]
20783{
20784 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20785 int scale = 1 << INTVAL (operands[2]);
20786 rtx index = gen_lowpart (Pmode, operands[1]);
20787 rtx base = gen_lowpart (Pmode, operands[3]);
20788 rtx dest = gen_lowpart (mode, operands[5]);
20789
20790 operands[1] = gen_rtx_PLUS (Pmode, base,
20791 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20792 if (mode != Pmode)
20793 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20794 operands[0] = dest;
20795})
20796
20797;; Call-value patterns last so that the wildcard operand does not
20798;; disrupt insn-recog's switch tables.
20799
20800(define_insn "*call_value_pop_0"
20801 [(set (match_operand 0 "" "")
20802 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20803 (match_operand:SI 2 "" "")))
20804 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20805 (match_operand:SI 3 "immediate_operand" "")))]
20806 "!TARGET_64BIT"
20807{
20808 if (SIBLING_CALL_P (insn))
20809 return "jmp\t%P1";
20810 else
20811 return "call\t%P1";
20812}
20813 [(set_attr "type" "callv")])
20814
20815(define_insn "*call_value_pop_1"
20816 [(set (match_operand 0 "" "")
20817 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20818 (match_operand:SI 2 "" "")))
20819 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20820 (match_operand:SI 3 "immediate_operand" "i")))]
20821 "!TARGET_64BIT"
20822{
20823 if (constant_call_address_operand (operands[1], Pmode))
20824 {
20825 if (SIBLING_CALL_P (insn))
20826 return "jmp\t%P1";
20827 else
20828 return "call\t%P1";
20829 }
20830 if (SIBLING_CALL_P (insn))
20831 return "jmp\t%A1";
20832 else
20833 return "call\t%A1";
20834}
20835 [(set_attr "type" "callv")])
20836
20837(define_insn "*call_value_0"
20838 [(set (match_operand 0 "" "")
20839 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20840 (match_operand:SI 2 "" "")))]
20841 "!TARGET_64BIT"
20842{
20843 if (SIBLING_CALL_P (insn))
20844 return "jmp\t%P1";
20845 else
20846 return "call\t%P1";
20847}
20848 [(set_attr "type" "callv")])
20849
20850(define_insn "*call_value_0_rex64"
20851 [(set (match_operand 0 "" "")
20852 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20853 (match_operand:DI 2 "const_int_operand" "")))]
20854 "TARGET_64BIT"
20855{
20856 if (SIBLING_CALL_P (insn))
20857 return "jmp\t%P1";
20858 else
20859 return "call\t%P1";
20860}
20861 [(set_attr "type" "callv")])
20862
20863(define_insn "*call_value_1"
20864 [(set (match_operand 0 "" "")
20865 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20866 (match_operand:SI 2 "" "")))]
20867 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20868{
20869 if (constant_call_address_operand (operands[1], Pmode))
20870 return "call\t%P1";
20871 return "call\t%A1";
20872}
20873 [(set_attr "type" "callv")])
20874
20875(define_insn "*sibcall_value_1"
20876 [(set (match_operand 0 "" "")
20877 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20878 (match_operand:SI 2 "" "")))]
20879 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20880{
20881 if (constant_call_address_operand (operands[1], Pmode))
20882 return "jmp\t%P1";
20883 return "jmp\t%A1";
20884}
20885 [(set_attr "type" "callv")])
20886
20887(define_insn "*call_value_1_rex64"
20888 [(set (match_operand 0 "" "")
20889 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20890 (match_operand:DI 2 "" "")))]
20891 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20892{
20893 if (constant_call_address_operand (operands[1], Pmode))
20894 return "call\t%P1";
20895 return "call\t%A1";
20896}
20897 [(set_attr "type" "callv")])
20898
20899(define_insn "*sibcall_value_1_rex64"
20900 [(set (match_operand 0 "" "")
20901 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20902 (match_operand:DI 2 "" "")))]
20903 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20904 "jmp\t%P1"
20905 [(set_attr "type" "callv")])
20906
20907(define_insn "*sibcall_value_1_rex64_v"
20908 [(set (match_operand 0 "" "")
20909 (call (mem:QI (reg:DI 40))
20910 (match_operand:DI 1 "" "")))]
20911 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20912 "jmp\t*%%r11"
20913 [(set_attr "type" "callv")])
20914
20915;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20916;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20917;; caught for use by garbage collectors and the like. Using an insn that
20918;; maps to SIGILL makes it more likely the program will rightfully die.
20919;; Keeping with tradition, "6" is in honor of #UD.
20920(define_insn "trap"
20921 [(trap_if (const_int 1) (const_int 6))]
20922 ""
20923 { return ASM_SHORT "0x0b0f"; }
20924 [(set_attr "length" "2")])
20925
20926(define_expand "sse_prologue_save"
20927 [(parallel [(set (match_operand:BLK 0 "" "")
20928 (unspec:BLK [(reg:DI 21)
20929 (reg:DI 22)
20930 (reg:DI 23)
20931 (reg:DI 24)
20932 (reg:DI 25)
20933 (reg:DI 26)
20934 (reg:DI 27)
20935 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20936 (use (match_operand:DI 1 "register_operand" ""))
20937 (use (match_operand:DI 2 "immediate_operand" ""))
20938 (use (label_ref:DI (match_operand 3 "" "")))])]
20939 "TARGET_64BIT"
20940 "")
20941
20942(define_insn "*sse_prologue_save_insn"
20943 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20944 (match_operand:DI 4 "const_int_operand" "n")))
20945 (unspec:BLK [(reg:DI 21)
20946 (reg:DI 22)
20947 (reg:DI 23)
20948 (reg:DI 24)
20949 (reg:DI 25)
20950 (reg:DI 26)
20951 (reg:DI 27)
20952 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20953 (use (match_operand:DI 1 "register_operand" "r"))
20954 (use (match_operand:DI 2 "const_int_operand" "i"))
20955 (use (label_ref:DI (match_operand 3 "" "X")))]
20956 "TARGET_64BIT
20957 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20958 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20959 "*
20960{
20961 int i;
20962 operands[0] = gen_rtx_MEM (Pmode,
20963 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20964 output_asm_insn (\"jmp\\t%A1\", operands);
20965 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20966 {
20967 operands[4] = adjust_address (operands[0], DImode, i*16);
20968 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20969 PUT_MODE (operands[4], TImode);
20970 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20971 output_asm_insn (\"rex\", operands);
20972 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20973 }
20974 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20975 CODE_LABEL_NUMBER (operands[3]));
20976 RET;
20977}
20978 "
20979 [(set_attr "type" "other")
20980 (set_attr "length_immediate" "0")
20981 (set_attr "length_address" "0")
20982 (set_attr "length" "135")
20983 (set_attr "memory" "store")
20984 (set_attr "modrm" "0")
20985 (set_attr "mode" "DI")])
20986
20987(define_expand "prefetch"
20988 [(prefetch (match_operand 0 "address_operand" "")
20989 (match_operand:SI 1 "const_int_operand" "")
20990 (match_operand:SI 2 "const_int_operand" ""))]
20991 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20992{
20993 int rw = INTVAL (operands[1]);
20994 int locality = INTVAL (operands[2]);
20995
20996 gcc_assert (rw == 0 || rw == 1);
20997 gcc_assert (locality >= 0 && locality <= 3);
20998 gcc_assert (GET_MODE (operands[0]) == Pmode
20999 || GET_MODE (operands[0]) == VOIDmode);
21000
21001 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21002 supported by SSE counterpart or the SSE prefetch is not available
21003 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21004 of locality. */
21005 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21006 operands[2] = GEN_INT (3);
21007 else
21008 operands[1] = const0_rtx;
21009})
21010
21011(define_insn "*prefetch_sse"
21012 [(prefetch (match_operand:SI 0 "address_operand" "p")
21013 (const_int 0)
21014 (match_operand:SI 1 "const_int_operand" ""))]
21015 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21016{
21017 static const char * const patterns[4] = {
21018 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21019 };
21020
21021 int locality = INTVAL (operands[1]);
21022 gcc_assert (locality >= 0 && locality <= 3);
21023
21024 return patterns[locality];
21025}
21026 [(set_attr "type" "sse")
21027 (set_attr "memory" "none")])
21028
21029(define_insn "*prefetch_sse_rex"
21030 [(prefetch (match_operand:DI 0 "address_operand" "p")
21031 (const_int 0)
21032 (match_operand:SI 1 "const_int_operand" ""))]
21033 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21034{
21035 static const char * const patterns[4] = {
21036 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21037 };
21038
21039 int locality = INTVAL (operands[1]);
21040 gcc_assert (locality >= 0 && locality <= 3);
21041
21042 return patterns[locality];
21043}
21044 [(set_attr "type" "sse")
21045 (set_attr "memory" "none")])
21046
21047(define_insn "*prefetch_3dnow"
21048 [(prefetch (match_operand:SI 0 "address_operand" "p")
21049 (match_operand:SI 1 "const_int_operand" "n")
21050 (const_int 3))]
21051 "TARGET_3DNOW && !TARGET_64BIT"
21052{
21053 if (INTVAL (operands[1]) == 0)
21054 return "prefetch\t%a0";
21055 else
21056 return "prefetchw\t%a0";
21057}
21058 [(set_attr "type" "mmx")
21059 (set_attr "memory" "none")])
21060
21061(define_insn "*prefetch_3dnow_rex"
21062 [(prefetch (match_operand:DI 0 "address_operand" "p")
21063 (match_operand:SI 1 "const_int_operand" "n")
21064 (const_int 3))]
21065 "TARGET_3DNOW && TARGET_64BIT"
21066{
21067 if (INTVAL (operands[1]) == 0)
21068 return "prefetch\t%a0";
21069 else
21070 return "prefetchw\t%a0";
21071}
21072 [(set_attr "type" "mmx")
21073 (set_attr "memory" "none")])
21074
21075(define_expand "stack_protect_set"
21076 [(match_operand 0 "memory_operand" "")
21077 (match_operand 1 "memory_operand" "")]
21078 ""
21079{
21080#ifdef TARGET_THREAD_SSP_OFFSET
21081 if (TARGET_64BIT)
21082 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21083 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21084 else
21085 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21086 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21087#else
21088 if (TARGET_64BIT)
21089 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21090 else
21091 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21092#endif
21093 DONE;
21094})
21095
21096(define_insn "stack_protect_set_si"
21097 [(set (match_operand:SI 0 "memory_operand" "=m")
21098 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21099 (set (match_scratch:SI 2 "=&r") (const_int 0))
21100 (clobber (reg:CC FLAGS_REG))]
21101 ""
21102 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21103 [(set_attr "type" "multi")])
21104
21105(define_insn "stack_protect_set_di"
21106 [(set (match_operand:DI 0 "memory_operand" "=m")
21107 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21108 (set (match_scratch:DI 2 "=&r") (const_int 0))
21109 (clobber (reg:CC FLAGS_REG))]
21110 "TARGET_64BIT"
21111 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21112 [(set_attr "type" "multi")])
21113
21114(define_insn "stack_tls_protect_set_si"
21115 [(set (match_operand:SI 0 "memory_operand" "=m")
21116 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21117 (set (match_scratch:SI 2 "=&r") (const_int 0))
21118 (clobber (reg:CC FLAGS_REG))]
21119 ""
21120 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121 [(set_attr "type" "multi")])
21122
21123(define_insn "stack_tls_protect_set_di"
21124 [(set (match_operand:DI 0 "memory_operand" "=m")
21125 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21126 (set (match_scratch:DI 2 "=&r") (const_int 0))
21127 (clobber (reg:CC FLAGS_REG))]
21128 "TARGET_64BIT"
21129 {
21130 /* The kernel uses a different segment register for performance reasons; a
21131 system call would not have to trash the userspace segment register,
21132 which would be expensive */
21133 if (ix86_cmodel != CM_KERNEL)
21134 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21135 else
21136 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21137 }
21138 [(set_attr "type" "multi")])
21139
21140(define_expand "stack_protect_test"
21141 [(match_operand 0 "memory_operand" "")
21142 (match_operand 1 "memory_operand" "")
21143 (match_operand 2 "" "")]
21144 ""
21145{
21146 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21147 ix86_compare_op0 = operands[0];
21148 ix86_compare_op1 = operands[1];
21149 ix86_compare_emitted = flags;
21150
21151#ifdef TARGET_THREAD_SSP_OFFSET
21152 if (TARGET_64BIT)
21153 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21154 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21155 else
21156 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21157 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21158#else
21159 if (TARGET_64BIT)
21160 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21161 else
21162 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21163#endif
21164 emit_jump_insn (gen_beq (operands[2]));
21165 DONE;
21166})
21167
21168(define_insn "stack_protect_test_si"
21169 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21170 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21171 (match_operand:SI 2 "memory_operand" "m")]
21172 UNSPEC_SP_TEST))
21173 (clobber (match_scratch:SI 3 "=&r"))]
21174 ""
21175 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21176 [(set_attr "type" "multi")])
21177
21178(define_insn "stack_protect_test_di"
21179 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21180 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21181 (match_operand:DI 2 "memory_operand" "m")]
21182 UNSPEC_SP_TEST))
21183 (clobber (match_scratch:DI 3 "=&r"))]
21184 "TARGET_64BIT"
21185 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21186 [(set_attr "type" "multi")])
21187
21188(define_insn "stack_tls_protect_test_si"
21189 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21190 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21191 (match_operand:SI 2 "const_int_operand" "i")]
21192 UNSPEC_SP_TLS_TEST))
21193 (clobber (match_scratch:SI 3 "=r"))]
21194 ""
21195 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21196 [(set_attr "type" "multi")])
21197
21198(define_insn "stack_tls_protect_test_di"
21199 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21200 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21201 (match_operand:DI 2 "const_int_operand" "i")]
21202 UNSPEC_SP_TLS_TEST))
21203 (clobber (match_scratch:DI 3 "=r"))]
21204 "TARGET_64BIT"
21205 {
21206 /* The kernel uses a different segment register for performance reasons; a
21207 system call would not have to trash the userspace segment register,
21208 which would be expensive */
21209 if (ix86_cmodel != CM_KERNEL)
21210 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21211 else
21212 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21213 }
21214 [(set_attr "type" "multi")])
21215
21216(include "mmx.md")
21217(include "sse.md")
21218(include "sync.md")