]>
Commit | Line | Data |
---|---|---|
d2836273 | 1 | ;; GCC machine description for IA-32 and x86-64. |
0e4970d7 | 2 | ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 |
4592bdcb | 3 | ;; Free Software Foundation, Inc. |
886c62d1 | 4 | ;; Mostly by William Schelter. |
d2836273 | 5 | ;; x86_64 support added by Jan Hubicka |
e075ae69 | 6 | ;; |
886c62d1 | 7 | ;; This file is part of GNU CC. |
e075ae69 | 8 | ;; |
886c62d1 JVA |
9 | ;; GNU CC is free software; you can redistribute it and/or modify |
10 | ;; it under the terms of the GNU General Public License as published by | |
11 | ;; the Free Software Foundation; either version 2, or (at your option) | |
12 | ;; any later version. | |
e075ae69 | 13 | ;; |
886c62d1 JVA |
14 | ;; GNU CC is distributed in the hope that it will be useful, |
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
e075ae69 | 18 | ;; |
886c62d1 JVA |
19 | ;; You should have received a copy of the GNU General Public License |
20 | ;; along with GNU CC; see the file COPYING. If not, write to | |
3f63df56 | 21 | ;; the Free Software Foundation, 59 Temple Place - Suite 330, |
2ae0f82c | 22 | ;; Boston, MA 02111-1307, USA. */ |
e075ae69 | 23 | ;; |
4af3895e JVA |
24 | ;; The original PO technology requires these to be ordered by speed, |
25 | ;; so that assigner will pick the fastest. | |
e075ae69 | 26 | ;; |
4af3895e | 27 | ;; See file "rtl.def" for documentation on define_insn, match_*, et. al. |
e075ae69 | 28 | ;; |
4af3895e JVA |
29 | ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code |
30 | ;; updates for most instructions. | |
e075ae69 | 31 | ;; |
4af3895e JVA |
32 | ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register |
33 | ;; constraint letters. | |
e075ae69 RH |
34 | ;; |
35 | ;; The special asm out single letter directives following a '%' are: | |
4af3895e JVA |
36 | ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of |
37 | ;; operands[1]. | |
38 | ;; 'L' Print the opcode suffix for a 32-bit integer opcode. | |
39 | ;; 'W' Print the opcode suffix for a 16-bit integer opcode. | |
40 | ;; 'B' Print the opcode suffix for an 8-bit integer opcode. | |
4af3895e | 41 | ;; 'Q' Print the opcode suffix for a 64-bit float opcode. |
56710e42 | 42 | ;; 'S' Print the opcode suffix for a 32-bit float opcode. |
b08de47e MM |
43 | ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. |
44 | ;; 'J' Print the appropriate jump operand. | |
e075ae69 | 45 | ;; |
4af3895e JVA |
46 | ;; 'b' Print the QImode name of the register for the indicated operand. |
47 | ;; %b0 would print %al if operands[0] is reg 0. | |
48 | ;; 'w' Likewise, print the HImode name of the register. | |
49 | ;; 'k' Likewise, print the SImode name of the register. | |
50 | ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh. | |
51 | ;; 'y' Print "st(0)" instead of "st" as a register. | |
e075ae69 | 52 | ;; |
4af3895e JVA |
53 | ;; UNSPEC usage: |
54 | ;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode. | |
55 | ;; operand 0 is the memory address to scan. | |
56 | ;; operand 1 is a register containing the value to scan for. The mode | |
57 | ;; of the scas opcode will be the same as the mode of this operand. | |
58 | ;; operand 2 is the known alignment of operand 0. | |
a199fdd6 JVA |
59 | ;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT. |
60 | ;; operand 0 is the argument for `sin'. | |
61 | ;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT. | |
62 | ;; operand 0 is the argument for `cos'. | |
578b58f5 RK |
63 | ;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is |
64 | ;; always SImode. operand 0 is the size of the stack allocation. | |
47d36400 BS |
65 | ;; 4 This is the source of a fake SET of the frame pointer which is used to |
66 | ;; prevent insns referencing it being scheduled across the initial | |
67 | ;; decrement of the stack pointer. | |
ce193852 | 68 | ;; 5 This is a `bsf' operation. |
91bb873f RH |
69 | ;; 6 This is the @GOT offset of a PIC address. |
70 | ;; 7 This is the @GOTOFF offset of a PIC address. | |
71 | ;; 8 This is a reference to a symbol's @PLT address. | |
e075ae69 RH |
72 | ;; 9 This is an `fnstsw' operation. |
73 | ;; 10 This is a `sahf' operation. | |
74 | ;; 11 This is a `fstcw' operation | |
7e08e190 | 75 | ;; 12 This is behaviour of add when setting carry flag. |
915119a5 BS |
76 | |
77 | ;; For SSE/MMX support: | |
78 | ;; 30 This is `fix', guaranteed to be truncating. | |
79 | ;; 31 This is a `emms' operation. | |
80 | ;; 32 This is a `maskmov' operation. | |
81 | ;; 33 This is a `movmsk' operation. | |
82 | ;; 34 This is a `non-temporal' move. | |
83 | ;; 35 This is a `prefetch' operation. | |
84 | ;; 36 This is used to distinguish COMISS from UCOMISS. | |
85 | ;; 37 This is a `ldmxcsr' operation. | |
86 | ;; 38 This is a forced `movaps' instruction (rather than whatever movti does) | |
87 | ;; 39 This is a forced `movups' instruction (rather than whatever movti does) | |
88 | ;; 40 This is a `stmxcsr' operation. | |
89 | ;; 41 This is a `shuffle' operation. | |
90 | ;; 42 This is a `rcp' operation. | |
91 | ;; 43 This is a `rsqsrt' operation. | |
92 | ;; 44 This is a `sfence' operation. | |
93 | ;; 45 This is a noop to prevent excessive combiner cleverness. | |
94 | ||
6343a50e ZW |
95 | ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls |
96 | ;; from i386.c. | |
97 | ||
2ae0f82c | 98 | \f |
e075ae69 RH |
99 | ;; Processor type. This attribute must exactly match the processor_type |
100 | ;; enumeration in i386.h. | |
b4e89e2d | 101 | (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4" |
e075ae69 | 102 | (const (symbol_ref "ix86_cpu"))) |
2ae0f82c | 103 | |
e075ae69 RH |
104 | ;; A basic instruction type. Refinements due to arguments to be |
105 | ;; provided in other attributes. | |
a269a03c | 106 | (define_attr "type" |
915119a5 | 107 | "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx" |
e075ae69 RH |
108 | (const_string "other")) |
109 | ||
6ef67412 | 110 | ;; Main data type used by the insn |
2b04e52b | 111 | (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI" |
6ef67412 JH |
112 | (const_string "unknown")) |
113 | ||
114 | ;; Set for i387 operations. | |
115 | (define_attr "i387" "" | |
116 | (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch") | |
117 | (const_int 1) | |
118 | (const_int 0))) | |
119 | ||
120 | ;; The (bounding maximum) length of an instruction immediate. | |
121 | (define_attr "length_immediate" "" | |
bd793c65 | 122 | (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx") |
6ef67412 JH |
123 | (const_int 0) |
124 | (eq_attr "i387" "1") | |
125 | (const_int 0) | |
126 | (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop") | |
127 | (symbol_ref "ix86_attr_length_immediate_default(insn,1)") | |
128 | (eq_attr "type" "imov,test") | |
129 | (symbol_ref "ix86_attr_length_immediate_default(insn,0)") | |
130 | (eq_attr "type" "call") | |
131 | (if_then_else (match_operand 0 "constant_call_address_operand" "") | |
132 | (const_int 4) | |
133 | (const_int 0)) | |
134 | (eq_attr "type" "callv") | |
135 | (if_then_else (match_operand 1 "constant_call_address_operand" "") | |
136 | (const_int 4) | |
137 | (const_int 0)) | |
138 | (eq_attr "type" "ibr") | |
139 | (if_then_else (and (ge (minus (match_dup 0) (pc)) | |
140 | (const_int -128)) | |
141 | (lt (minus (match_dup 0) (pc)) | |
142 | (const_int 124))) | |
143 | (const_int 1) | |
144 | (const_int 4)) | |
145 | ] | |
146 | (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1"))) | |
e075ae69 | 147 | |
6ef67412 JH |
148 | ;; The (bounding maximum) length of an instruction address. |
149 | (define_attr "length_address" "" | |
150 | (cond [(eq_attr "type" "str,cld,other,multi,fxch") | |
151 | (const_int 0) | |
152 | (and (eq_attr "type" "call") | |
153 | (match_operand 1 "constant_call_address_operand" "")) | |
154 | (const_int 0) | |
155 | (and (eq_attr "type" "callv") | |
156 | (match_operand 1 "constant_call_address_operand" "")) | |
157 | (const_int 0) | |
158 | ] | |
159 | (symbol_ref "ix86_attr_length_address_default (insn)"))) | |
160 | ||
161 | ;; Set when length prefix is used. | |
162 | (define_attr "prefix_data16" "" | |
163 | (if_then_else (eq_attr "mode" "HI") | |
164 | (const_int 1) | |
165 | (const_int 0))) | |
166 | ||
167 | ;; Set when string REP prefix is used. | |
168 | (define_attr "prefix_rep" "" (const_int 0)) | |
169 | ||
170 | ;; Set when 0f opcode prefix is used. | |
171 | (define_attr "prefix_0f" "" | |
bd793c65 | 172 | (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx") |
6ef67412 JH |
173 | (const_int 1) |
174 | (const_int 0))) | |
175 | ||
176 | ;; Set when modrm byte is used. | |
177 | (define_attr "modrm" "" | |
178 | (cond [(eq_attr "type" "str,cld") | |
179 | (const_int 0) | |
180 | (eq_attr "i387" "1") | |
181 | (const_int 0) | |
e075ae69 RH |
182 | (and (eq_attr "type" "incdec") |
183 | (ior (match_operand:SI 1 "register_operand" "") | |
184 | (match_operand:HI 1 "register_operand" ""))) | |
6ef67412 | 185 | (const_int 0) |
e075ae69 RH |
186 | (and (eq_attr "type" "push") |
187 | (not (match_operand 1 "memory_operand" ""))) | |
6ef67412 | 188 | (const_int 0) |
e075ae69 RH |
189 | (and (eq_attr "type" "pop") |
190 | (not (match_operand 0 "memory_operand" ""))) | |
6ef67412 | 191 | (const_int 0) |
e075ae69 RH |
192 | (and (eq_attr "type" "imov") |
193 | (and (match_operand 0 "register_operand" "") | |
194 | (match_operand 1 "immediate_operand" ""))) | |
6ef67412 | 195 | (const_int 0) |
e075ae69 | 196 | ] |
6ef67412 JH |
197 | (const_int 1))) |
198 | ||
199 | ;; The (bounding maximum) length of an instruction in bytes. | |
200 | (define_attr "length" "" | |
201 | (cond [(eq_attr "type" "other,multi") | |
202 | (const_int 16) | |
203 | ] | |
204 | (plus (plus (attr "modrm") | |
205 | (plus (attr "prefix_0f") | |
206 | (plus (attr "i387") | |
207 | (const_int 1)))) | |
208 | (plus (attr "prefix_rep") | |
209 | (plus (attr "prefix_data16") | |
210 | (plus (attr "length_immediate") | |
211 | (attr "length_address"))))))) | |
e075ae69 RH |
212 | |
213 | ;; The `memory' attribute is `none' if no memory is referenced, `load' or | |
214 | ;; `store' if there is a simple memory reference therein, or `unknown' | |
215 | ;; if the instruction is complex. | |
216 | ||
217 | (define_attr "memory" "none,load,store,both,unknown" | |
7c7ef435 | 218 | (cond [(eq_attr "type" "other,multi,str") |
e075ae69 | 219 | (const_string "unknown") |
7c7ef435 | 220 | (eq_attr "type" "lea,fcmov,fpspc,cld") |
e075ae69 RH |
221 | (const_string "none") |
222 | (eq_attr "type" "push") | |
223 | (if_then_else (match_operand 1 "memory_operand" "") | |
224 | (const_string "both") | |
225 | (const_string "store")) | |
226 | (eq_attr "type" "pop,setcc") | |
227 | (if_then_else (match_operand 0 "memory_operand" "") | |
228 | (const_string "both") | |
229 | (const_string "load")) | |
6ef67412 | 230 | (eq_attr "type" "icmp,test") |
e075ae69 RH |
231 | (if_then_else (ior (match_operand 0 "memory_operand" "") |
232 | (match_operand 1 "memory_operand" "")) | |
233 | (const_string "load") | |
234 | (const_string "none")) | |
235 | (eq_attr "type" "ibr") | |
236 | (if_then_else (match_operand 0 "memory_operand" "") | |
237 | (const_string "load") | |
238 | (const_string "none")) | |
239 | (eq_attr "type" "call") | |
240 | (if_then_else (match_operand 0 "constant_call_address_operand" "") | |
241 | (const_string "none") | |
242 | (const_string "load")) | |
243 | (eq_attr "type" "callv") | |
244 | (if_then_else (match_operand 1 "constant_call_address_operand" "") | |
245 | (const_string "none") | |
246 | (const_string "load")) | |
247 | (and (eq_attr "type" "alu1,negnot") | |
a269a03c | 248 | (match_operand 1 "memory_operand" "")) |
e075ae69 RH |
249 | (const_string "both") |
250 | (and (match_operand 0 "memory_operand" "") | |
251 | (match_operand 1 "memory_operand" "")) | |
252 | (const_string "both") | |
253 | (match_operand 0 "memory_operand" "") | |
254 | (const_string "store") | |
255 | (match_operand 1 "memory_operand" "") | |
256 | (const_string "load") | |
915119a5 | 257 | (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx") |
e075ae69 RH |
258 | (match_operand 2 "memory_operand" "")) |
259 | (const_string "load") | |
260 | (and (eq_attr "type" "icmov") | |
261 | (match_operand 3 "memory_operand" "")) | |
262 | (const_string "load") | |
263 | ] | |
a269a03c JC |
264 | (const_string "none"))) |
265 | ||
e075ae69 RH |
266 | ;; Indicates if an instruction has both an immediate and a displacement. |
267 | ||
268 | (define_attr "imm_disp" "false,true,unknown" | |
269 | (cond [(eq_attr "type" "other,multi") | |
270 | (const_string "unknown") | |
6ef67412 | 271 | (and (eq_attr "type" "icmp,test,imov") |
e075ae69 RH |
272 | (and (match_operand 0 "memory_displacement_operand" "") |
273 | (match_operand 1 "immediate_operand" ""))) | |
274 | (const_string "true") | |
275 | (and (eq_attr "type" "alu,ishift,imul,idiv") | |
276 | (and (match_operand 0 "memory_displacement_operand" "") | |
277 | (match_operand 2 "immediate_operand" ""))) | |
278 | (const_string "true") | |
279 | ] | |
280 | (const_string "false"))) | |
281 | ||
282 | ;; Indicates if an FP operation has an integer source. | |
283 | ||
284 | (define_attr "fp_int_src" "false,true" | |
285 | (const_string "false")) | |
286 | ||
287 | ;; Describe a user's asm statement. | |
288 | (define_asm_attributes | |
289 | [(set_attr "length" "128") | |
290 | (set_attr "type" "multi")]) | |
291 | \f | |
292 | ;; Pentium Scheduling | |
293 | ;; | |
294 | ;; The Pentium is an in-order core with two integer pipelines. | |
295 | ||
6ef67412 JH |
296 | ;; True for insns that behave like prefixed insns on the Pentium. |
297 | (define_attr "pent_prefix" "false,true" | |
298 | (if_then_else (ior (eq_attr "prefix_0f" "1") | |
299 | (ior (eq_attr "prefix_data16" "1") | |
300 | (eq_attr "prefix_rep" "1"))) | |
301 | (const_string "true") | |
302 | (const_string "false"))) | |
303 | ||
e075ae69 RH |
304 | ;; Categorize how an instruction slots. |
305 | ||
306 | ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only, | |
307 | ;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium | |
308 | ;; rules, because it results in noticeably better code on non-MMX Pentium | |
309 | ;; and doesn't hurt much on MMX. (Prefixed instructions are not very | |
310 | ;; common, so the scheduler usualy has a non-prefixed insn to pair). | |
311 | ||
312 | (define_attr "pent_pair" "uv,pu,pv,np" | |
313 | (cond [(eq_attr "imm_disp" "true") | |
314 | (const_string "np") | |
6ef67412 JH |
315 | (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec") |
316 | (and (eq_attr "type" "pop,push") | |
317 | (eq_attr "memory" "!both"))) | |
318 | (if_then_else (eq_attr "pent_prefix" "true") | |
e075ae69 RH |
319 | (const_string "pu") |
320 | (const_string "uv")) | |
321 | (eq_attr "type" "ibr") | |
322 | (const_string "pv") | |
323 | (and (eq_attr "type" "ishift") | |
324 | (match_operand 2 "const_int_operand" "")) | |
325 | (const_string "pu") | |
e075ae69 RH |
326 | (and (eq_attr "type" "call") |
327 | (match_operand 0 "constant_call_address_operand" "")) | |
328 | (const_string "pv") | |
329 | (and (eq_attr "type" "callv") | |
330 | (match_operand 1 "constant_call_address_operand" "")) | |
331 | (const_string "pv") | |
332 | ] | |
333 | (const_string "np"))) | |
334 | ||
335 | ;; Rough readiness numbers. Fine tuning happens in i386.c. | |
336 | ;; | |
337 | ;; u describes pipe U | |
338 | ;; v describes pipe V | |
339 | ;; uv describes either pipe U or V for those that can issue to either | |
340 | ;; np describes not paring | |
341 | ;; fpu describes fpu | |
342 | ;; fpm describes fp insns of different types are not pipelined. | |
343 | ;; | |
344 | ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real. | |
2ae0f82c | 345 | |
e075ae69 RH |
346 | (define_function_unit "pent_np" 1 0 |
347 | (and (eq_attr "cpu" "pentium") | |
348 | (eq_attr "type" "imul")) | |
349 | 11 11) | |
36cf4bcf | 350 | |
e075ae69 RH |
351 | (define_function_unit "pent_mul" 1 1 |
352 | (and (eq_attr "cpu" "pentium") | |
353 | (eq_attr "type" "imul")) | |
354 | 11 11) | |
36cf4bcf | 355 | |
7c7ef435 JH |
356 | ;; Rep movs takes minimally 12 cycles. |
357 | (define_function_unit "pent_np" 1 0 | |
358 | (and (eq_attr "cpu" "pentium") | |
359 | (eq_attr "type" "str")) | |
360 | 12 12) | |
361 | ||
e075ae69 RH |
362 | ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22 |
363 | (define_function_unit "pent_np" 1 0 | |
364 | (and (eq_attr "cpu" "pentium") | |
365 | (eq_attr "type" "idiv")) | |
366 | 46 46) | |
367 | ||
368 | ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode, | |
369 | ; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF. | |
370 | ; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable. | |
371 | ; The integer <-> fp conversion is not modeled correctly. Fild behaves | |
372 | ; like normal fp operation and fist takes 6 cycles. | |
373 | ||
374 | (define_function_unit "fpu" 1 0 | |
375 | (and (eq_attr "cpu" "pentium") | |
376 | (and (eq_attr "type" "fmov") | |
2b589241 JH |
377 | (and (eq_attr "memory" "load,store") |
378 | (eq_attr "mode" "XF")))) | |
e075ae69 RH |
379 | 3 3) |
380 | ||
381 | (define_function_unit "pent_np" 1 0 | |
382 | (and (eq_attr "cpu" "pentium") | |
383 | (and (eq_attr "type" "fmov") | |
2b589241 JH |
384 | (and (eq_attr "memory" "load,store") |
385 | (eq_attr "mode" "XF")))) | |
e075ae69 RH |
386 | 3 3) |
387 | ||
388 | (define_function_unit "fpu" 1 0 | |
389 | (and (eq_attr "cpu" "pentium") | |
390 | (and (eq_attr "type" "fmov") | |
391 | (ior (match_operand 1 "immediate_operand" "") | |
392 | (eq_attr "memory" "store")))) | |
393 | 2 2) | |
36cf4bcf | 394 | |
e075ae69 RH |
395 | (define_function_unit "pent_np" 1 0 |
396 | (and (eq_attr "cpu" "pentium") | |
397 | (and (eq_attr "type" "fmov") | |
398 | (ior (match_operand 1 "immediate_operand" "") | |
399 | (eq_attr "memory" "store")))) | |
400 | 2 2) | |
2ae0f82c | 401 | |
7c7ef435 JH |
402 | (define_function_unit "pent_np" 1 0 |
403 | (and (eq_attr "cpu" "pentium") | |
404 | (eq_attr "type" "cld")) | |
405 | 2 2) | |
406 | ||
e075ae69 RH |
407 | (define_function_unit "fpu" 1 0 |
408 | (and (eq_attr "cpu" "pentium") | |
409 | (and (eq_attr "type" "fmov") | |
410 | (eq_attr "memory" "none,load"))) | |
411 | 1 1) | |
412 | ||
413 | ; Read/Modify/Write instructions usually take 3 cycles. | |
414 | (define_function_unit "pent_u" 1 0 | |
415 | (and (eq_attr "cpu" "pentium") | |
416 | (and (eq_attr "type" "alu,alu1,ishift") | |
417 | (and (eq_attr "pent_pair" "pu") | |
418 | (eq_attr "memory" "both")))) | |
419 | 3 3) | |
420 | ||
421 | (define_function_unit "pent_uv" 2 0 | |
422 | (and (eq_attr "cpu" "pentium") | |
423 | (and (eq_attr "type" "alu,alu1,ishift") | |
424 | (and (eq_attr "pent_pair" "!np") | |
425 | (eq_attr "memory" "both")))) | |
426 | 3 3) | |
427 | ||
428 | (define_function_unit "pent_np" 1 0 | |
429 | (and (eq_attr "cpu" "pentium") | |
430 | (and (eq_attr "type" "alu,alu1,negnot,ishift") | |
431 | (and (eq_attr "pent_pair" "np") | |
432 | (eq_attr "memory" "both")))) | |
433 | 3 3) | |
434 | ||
435 | ; Read/Modify or Modify/Write instructions usually take 2 cycles. | |
436 | (define_function_unit "pent_u" 1 0 | |
437 | (and (eq_attr "cpu" "pentium") | |
438 | (and (eq_attr "type" "alu,ishift") | |
439 | (and (eq_attr "pent_pair" "pu") | |
440 | (eq_attr "memory" "load,store")))) | |
441 | 2 2) | |
2ae0f82c | 442 | |
e075ae69 RH |
443 | (define_function_unit "pent_uv" 2 0 |
444 | (and (eq_attr "cpu" "pentium") | |
445 | (and (eq_attr "type" "alu,ishift") | |
446 | (and (eq_attr "pent_pair" "!np") | |
447 | (eq_attr "memory" "load,store")))) | |
448 | 2 2) | |
2ae0f82c | 449 | |
e075ae69 RH |
450 | (define_function_unit "pent_np" 1 0 |
451 | (and (eq_attr "cpu" "pentium") | |
452 | (and (eq_attr "type" "alu,ishift") | |
453 | (and (eq_attr "pent_pair" "np") | |
454 | (eq_attr "memory" "load,store")))) | |
455 | 2 2) | |
36cf4bcf | 456 | |
e075ae69 RH |
457 | ; Insns w/o memory operands and move instructions usually take one cycle. |
458 | (define_function_unit "pent_u" 1 0 | |
459 | (and (eq_attr "cpu" "pentium") | |
460 | (eq_attr "pent_pair" "pu")) | |
461 | 1 1) | |
462 | ||
463 | (define_function_unit "pent_v" 1 0 | |
464 | (and (eq_attr "cpu" "pentium") | |
465 | (eq_attr "pent_pair" "pv")) | |
466 | 1 1) | |
467 | ||
468 | (define_function_unit "pent_uv" 2 0 | |
469 | (and (eq_attr "cpu" "pentium") | |
470 | (eq_attr "pent_pair" "!np")) | |
471 | 1 1) | |
472 | ||
473 | (define_function_unit "pent_np" 1 0 | |
474 | (and (eq_attr "cpu" "pentium") | |
475 | (eq_attr "pent_pair" "np")) | |
476 | 1 1) | |
477 | ||
478 | ; Pairable insns only conflict with other non-pairable insns. | |
479 | (define_function_unit "pent_np" 1 0 | |
480 | (and (eq_attr "cpu" "pentium") | |
481 | (and (eq_attr "type" "alu,alu1,ishift") | |
482 | (and (eq_attr "pent_pair" "!np") | |
483 | (eq_attr "memory" "both")))) | |
484 | 3 3 | |
485 | [(eq_attr "pent_pair" "np")]) | |
486 | ||
487 | (define_function_unit "pent_np" 1 0 | |
488 | (and (eq_attr "cpu" "pentium") | |
489 | (and (eq_attr "type" "alu,alu1,ishift") | |
490 | (and (eq_attr "pent_pair" "!np") | |
491 | (eq_attr "memory" "load,store")))) | |
492 | 2 2 | |
493 | [(eq_attr "pent_pair" "np")]) | |
494 | ||
495 | (define_function_unit "pent_np" 1 0 | |
496 | (and (eq_attr "cpu" "pentium") | |
497 | (eq_attr "pent_pair" "!np")) | |
498 | 1 1 | |
499 | [(eq_attr "pent_pair" "np")]) | |
500 | ||
501 | ; Floating point instructions usually blocks cycle longer when combined with | |
502 | ; integer instructions, because of the inpaired fxch instruction. | |
503 | (define_function_unit "pent_np" 1 0 | |
504 | (and (eq_attr "cpu" "pentium") | |
505 | (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")) | |
506 | 2 2 | |
507 | [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")]) | |
508 | ||
509 | (define_function_unit "fpu" 1 0 | |
510 | (and (eq_attr "cpu" "pentium") | |
511 | (eq_attr "type" "fcmp,fxch,fsgn")) | |
512 | 1 1) | |
513 | ||
514 | ; Addition takes 3 cycles; assume other random cruft does as well. | |
515 | ; ??? Trivial fp operations such as fabs or fchs takes only one cycle. | |
516 | (define_function_unit "fpu" 1 0 | |
517 | (and (eq_attr "cpu" "pentium") | |
518 | (eq_attr "type" "fop,fop1")) | |
519 | 3 1) | |
520 | ||
521 | ; Multiplication takes 3 cycles and is only half pipelined. | |
522 | (define_function_unit "fpu" 1 0 | |
523 | (and (eq_attr "cpu" "pentium") | |
524 | (eq_attr "type" "fmul")) | |
525 | 3 1) | |
526 | ||
527 | (define_function_unit "pent_mul" 1 1 | |
528 | (and (eq_attr "cpu" "pentium") | |
529 | (eq_attr "type" "fmul")) | |
530 | 2 2) | |
36cf4bcf | 531 | |
e075ae69 RH |
532 | ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles. |
533 | ; They can overlap with integer insns. Only the last two cycles can overlap | |
534 | ; with other fp insns. Only fsin/fcos can overlap with multiplies. | |
535 | ; Only last two cycles of fsin/fcos can overlap with other instructions. | |
536 | (define_function_unit "fpu" 1 0 | |
537 | (and (eq_attr "cpu" "pentium") | |
538 | (eq_attr "type" "fdiv")) | |
539 | 39 37) | |
540 | ||
541 | (define_function_unit "pent_mul" 1 1 | |
542 | (and (eq_attr "cpu" "pentium") | |
543 | (eq_attr "type" "fdiv")) | |
544 | 39 39) | |
545 | ||
546 | (define_function_unit "fpu" 1 0 | |
547 | (and (eq_attr "cpu" "pentium") | |
548 | (eq_attr "type" "fpspc")) | |
549 | 70 68) | |
550 | ||
551 | (define_function_unit "pent_mul" 1 1 | |
552 | (and (eq_attr "cpu" "pentium") | |
553 | (eq_attr "type" "fpspc")) | |
554 | 70 70) | |
555 | \f | |
556 | ;; Pentium Pro/PII Scheduling | |
557 | ;; | |
558 | ;; The PPro has an out-of-order core, but the instruction decoders are | |
559 | ;; naturally in-order and asymmetric. We get best performance by scheduling | |
560 | ;; for the decoders, for in doing so we give the oo execution unit the | |
561 | ;; most choices. | |
562 | ||
563 | ;; Categorize how many uops an ia32 instruction evaluates to: | |
564 | ;; one -- an instruction with 1 uop can be decoded by any of the | |
565 | ;; three decoders. | |
566 | ;; few -- an instruction with 1 to 4 uops can be decoded only by | |
567 | ;; decoder 0. | |
568 | ;; many -- a complex instruction may take an unspecified number of | |
569 | ;; cycles to decode in decoder 0. | |
570 | ||
571 | (define_attr "ppro_uops" "one,few,many" | |
7c7ef435 | 572 | (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str") |
e075ae69 | 573 | (const_string "many") |
7c7ef435 | 574 | (eq_attr "type" "icmov,fcmov,str,cld") |
e075ae69 RH |
575 | (const_string "few") |
576 | (eq_attr "type" "imov") | |
577 | (if_then_else (eq_attr "memory" "store,both") | |
578 | (const_string "few") | |
579 | (const_string "one")) | |
580 | (eq_attr "memory" "!none") | |
581 | (const_string "few") | |
582 | ] | |
583 | (const_string "one"))) | |
584 | ||
585 | ;; Rough readiness numbers. Fine tuning happens in i386.c. | |
586 | ;; | |
587 | ;; p0 describes port 0. | |
588 | ;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either. | |
589 | ;; p2 describes port 2 for loads. | |
590 | ;; p34 describes ports 3 and 4 for stores. | |
591 | ;; fpu describes the fpu accessed via port 0. | |
592 | ;; ??? It is less than clear if there are separate fadd and fmul units | |
593 | ;; that could operate in parallel. | |
594 | ;; | |
595 | ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real. | |
596 | ||
597 | (define_function_unit "ppro_p0" 1 0 | |
598 | (and (eq_attr "cpu" "pentiumpro") | |
7c7ef435 | 599 | (eq_attr "type" "ishift,lea,ibr,cld")) |
e075ae69 RH |
600 | 1 1) |
601 | ||
602 | (define_function_unit "ppro_p0" 1 0 | |
603 | (and (eq_attr "cpu" "pentiumpro") | |
604 | (eq_attr "type" "imul")) | |
605 | 4 1) | |
606 | ||
607 | ;; ??? Does the divider lock out the pipe while it works, | |
608 | ;; or is there a disconnected unit? | |
609 | (define_function_unit "ppro_p0" 1 0 | |
610 | (and (eq_attr "cpu" "pentiumpro") | |
611 | (eq_attr "type" "idiv")) | |
612 | 17 17) | |
36cf4bcf | 613 | |
e075ae69 RH |
614 | (define_function_unit "ppro_p0" 1 0 |
615 | (and (eq_attr "cpu" "pentiumpro") | |
616 | (eq_attr "type" "fop,fop1,fsgn")) | |
617 | 3 1) | |
618 | ||
619 | (define_function_unit "ppro_p0" 1 0 | |
620 | (and (eq_attr "cpu" "pentiumpro") | |
621 | (eq_attr "type" "fcmov")) | |
622 | 2 1) | |
623 | ||
624 | (define_function_unit "ppro_p0" 1 0 | |
625 | (and (eq_attr "cpu" "pentiumpro") | |
626 | (eq_attr "type" "fcmp")) | |
627 | 1 1) | |
628 | ||
629 | (define_function_unit "ppro_p0" 1 0 | |
630 | (and (eq_attr "cpu" "pentiumpro") | |
631 | (eq_attr "type" "fmov")) | |
632 | 1 1) | |
633 | ||
634 | (define_function_unit "ppro_p0" 1 0 | |
635 | (and (eq_attr "cpu" "pentiumpro") | |
636 | (eq_attr "type" "fmul")) | |
637 | 5 1) | |
638 | ||
639 | (define_function_unit "ppro_p0" 1 0 | |
640 | (and (eq_attr "cpu" "pentiumpro") | |
641 | (eq_attr "type" "fdiv,fpspc")) | |
642 | 56 1) | |
643 | ||
644 | (define_function_unit "ppro_p01" 2 0 | |
645 | (and (eq_attr "cpu" "pentiumpro") | |
646 | (eq_attr "type" "!imov,fmov")) | |
647 | 1 1) | |
648 | ||
649 | (define_function_unit "ppro_p01" 2 0 | |
650 | (and (and (eq_attr "cpu" "pentiumpro") | |
651 | (eq_attr "type" "imov,fmov")) | |
652 | (eq_attr "memory" "none")) | |
653 | 1 1) | |
654 | ||
655 | (define_function_unit "ppro_p2" 1 0 | |
656 | (and (eq_attr "cpu" "pentiumpro") | |
657 | (ior (eq_attr "type" "pop") | |
658 | (eq_attr "memory" "load,both"))) | |
659 | 3 1) | |
660 | ||
661 | (define_function_unit "ppro_p34" 1 0 | |
662 | (and (eq_attr "cpu" "pentiumpro") | |
663 | (ior (eq_attr "type" "push") | |
664 | (eq_attr "memory" "store,both"))) | |
665 | 1 1) | |
666 | ||
667 | (define_function_unit "fpu" 1 0 | |
668 | (and (eq_attr "cpu" "pentiumpro") | |
669 | (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov")) | |
670 | 1 1) | |
671 | ||
672 | (define_function_unit "fpu" 1 0 | |
673 | (and (eq_attr "cpu" "pentiumpro") | |
674 | (eq_attr "type" "fmul")) | |
675 | 5 2) | |
676 | ||
677 | (define_function_unit "fpu" 1 0 | |
678 | (and (eq_attr "cpu" "pentiumpro") | |
679 | (eq_attr "type" "fdiv,fpspc")) | |
680 | 56 56) | |
681 | ||
682 | ;; imul uses the fpu. ??? does it have the same throughput as fmul? | |
683 | (define_function_unit "fpu" 1 0 | |
684 | (and (eq_attr "cpu" "pentiumpro") | |
685 | (eq_attr "type" "imul")) | |
686 | 4 1) | |
687 | \f | |
688 | ;; AMD K6/K6-2 Scheduling | |
689 | ;; | |
690 | ;; The K6 has similar architecture to PPro. Important difference is, that | |
691 | ;; there are only two decoders and they seems to be much slower than execution | |
692 | ;; units. So we have to pay much more attention to proper decoding for | |
693 | ;; schedulers. We share most of scheduler code for PPro in i386.c | |
694 | ;; | |
695 | ;; The fp unit is not pipelined and do one operation per two cycles including | |
696 | ;; the FXCH. | |
697 | ;; | |
698 | ;; alu describes both ALU units (ALU-X and ALU-Y). | |
699 | ;; alux describes X alu unit | |
700 | ;; fpu describes FPU unit | |
701 | ;; load describes load unit. | |
702 | ;; branch describes branch unit. | |
703 | ;; store decsribes store unit. This unit is not modelled completely and only | |
704 | ;; used to model lea operation. Otherwise it lie outside of the critical | |
705 | ;; path. | |
706 | ;; | |
707 | ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real. | |
36cf4bcf | 708 | |
e075ae69 | 709 | ;; The decoder specification is in the PPro section above! |
2ae0f82c | 710 | |
e075ae69 RH |
711 | ;; Shift instructions and certain arithmetic are issued only to X pipe. |
712 | (define_function_unit "k6_alux" 1 0 | |
713 | (and (eq_attr "cpu" "k6") | |
7c7ef435 | 714 | (eq_attr "type" "ishift,alu1,negnot,cld")) |
e075ae69 | 715 | 1 1) |
2ae0f82c | 716 | |
e075ae69 RH |
717 | ;; The QI mode arithmetic is issued to X pipe only. |
718 | (define_function_unit "k6_alux" 1 0 | |
719 | (and (eq_attr "cpu" "k6") | |
6ef67412 | 720 | (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec") |
e075ae69 RH |
721 | (match_operand:QI 0 "general_operand" ""))) |
722 | 1 1) | |
a269a03c | 723 | |
e075ae69 RH |
724 | (define_function_unit "k6_alu" 2 0 |
725 | (and (eq_attr "cpu" "k6") | |
6ef67412 | 726 | (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea")) |
e075ae69 | 727 | 1 1) |
a269a03c | 728 | |
e075ae69 RH |
729 | (define_function_unit "k6_alu" 2 0 |
730 | (and (eq_attr "cpu" "k6") | |
731 | (and (eq_attr "type" "imov") | |
732 | (eq_attr "memory" "none"))) | |
733 | 1 1) | |
a269a03c | 734 | |
e075ae69 | 735 | (define_function_unit "k6_branch" 1 0 |
a269a03c | 736 | (and (eq_attr "cpu" "k6") |
e075ae69 RH |
737 | (eq_attr "type" "call,callv,ibr")) |
738 | 1 1) | |
a269a03c | 739 | |
e075ae69 RH |
740 | ;; Load unit have two cycle latency, but we take care for it in adjust_cost |
741 | (define_function_unit "k6_load" 1 0 | |
a269a03c | 742 | (and (eq_attr "cpu" "k6") |
e075ae69 RH |
743 | (ior (eq_attr "type" "pop") |
744 | (eq_attr "memory" "load,both"))) | |
745 | 1 1) | |
a269a03c | 746 | |
7c7ef435 JH |
747 | (define_function_unit "k6_load" 1 0 |
748 | (and (eq_attr "cpu" "k6") | |
749 | (and (eq_attr "type" "str") | |
750 | (eq_attr "memory" "load,both"))) | |
751 | 10 10) | |
752 | ||
e075ae69 RH |
753 | ;; Lea have two instructions, so latency is probably 2 |
754 | (define_function_unit "k6_store" 1 0 | |
755 | (and (eq_attr "cpu" "k6") | |
756 | (eq_attr "type" "lea")) | |
757 | 2 1) | |
a269a03c | 758 | |
7c7ef435 JH |
759 | (define_function_unit "k6_store" 1 0 |
760 | (and (eq_attr "cpu" "k6") | |
761 | (eq_attr "type" "str")) | |
762 | 10 10) | |
763 | ||
e075ae69 RH |
764 | (define_function_unit "k6_store" 1 0 |
765 | (and (eq_attr "cpu" "k6") | |
766 | (ior (eq_attr "type" "push") | |
767 | (eq_attr "memory" "store,both"))) | |
768 | 1 1) | |
a269a03c | 769 | |
e075ae69 RH |
770 | (define_function_unit "k6_fpu" 1 1 |
771 | (and (eq_attr "cpu" "k6") | |
772 | (eq_attr "type" "fop,fop1,fmov,fcmp")) | |
773 | 2 2) | |
a269a03c | 774 | |
e075ae69 RH |
775 | (define_function_unit "k6_fpu" 1 1 |
776 | (and (eq_attr "cpu" "k6") | |
777 | (eq_attr "type" "fmul")) | |
778 | 2 2) | |
a269a03c | 779 | |
e075ae69 RH |
780 | ;; ??? Guess |
781 | (define_function_unit "k6_fpu" 1 1 | |
782 | (and (eq_attr "cpu" "k6") | |
783 | (eq_attr "type" "fdiv,fpspc")) | |
784 | 56 56) | |
a269a03c | 785 | |
e075ae69 RH |
786 | (define_function_unit "k6_alu" 2 0 |
787 | (and (eq_attr "cpu" "k6") | |
788 | (eq_attr "type" "imul")) | |
789 | 2 2) | |
a269a03c | 790 | |
e075ae69 RH |
791 | (define_function_unit "k6_alux" 1 0 |
792 | (and (eq_attr "cpu" "k6") | |
793 | (eq_attr "type" "imul")) | |
794 | 2 2) | |
a269a03c | 795 | |
e075ae69 RH |
796 | ;; ??? Guess |
797 | (define_function_unit "k6_alu" 2 0 | |
798 | (and (eq_attr "cpu" "k6") | |
799 | (eq_attr "type" "idiv")) | |
800 | 17 17) | |
2ae0f82c | 801 | |
e075ae69 RH |
802 | (define_function_unit "k6_alux" 1 0 |
803 | (and (eq_attr "cpu" "k6") | |
804 | (eq_attr "type" "idiv")) | |
805 | 17 17) | |
886c62d1 | 806 | \f |
309ada50 JH |
807 | ;; AMD Athlon Scheduling |
808 | ;; | |
809 | ;; The Athlon does contain three pipelined FP units, three integer units and | |
810 | ;; three address generation units. | |
811 | ;; | |
812 | ;; The predecode logic is determining boundaries of instructions in the 64 | |
813 | ;; byte cache line. So the cache line straddling problem of K6 might be issue | |
814 | ;; here as well, but it is not noted in the documentation. | |
815 | ;; | |
816 | ;; Three DirectPath instructions decoders and only one VectorPath decoder | |
817 | ;; is available. They can decode three DirectPath instructions or one VectorPath | |
818 | ;; instruction per cycle. | |
819 | ;; Decoded macro instructions are then passed to 72 entry instruction control | |
820 | ;; unit, that passes | |
821 | ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers. | |
822 | ;; | |
823 | ;; The load/store queue unit is not attached to the schedulers but | |
824 | ;; communicates with all the execution units seperately instead. | |
825 | ||
826 | (define_attr "athlon_decode" "direct,vector" | |
0b5107cf | 827 | (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov") |
309ada50 JH |
828 | (const_string "vector") |
829 | (and (eq_attr "type" "push") | |
830 | (match_operand 1 "memory_operand" "")) | |
831 | (const_string "vector") | |
832 | (and (eq_attr "type" "fmov") | |
2b589241 JH |
833 | (and (eq_attr "memory" "load,store") |
834 | (eq_attr "mode" "XF"))) | |
309ada50 JH |
835 | (const_string "vector")] |
836 | (const_string "direct"))) | |
837 | ||
838 | (define_function_unit "athlon_vectordec" 1 0 | |
839 | (and (eq_attr "cpu" "athlon") | |
840 | (eq_attr "athlon_decode" "vector")) | |
841 | 1 1) | |
842 | ||
843 | (define_function_unit "athlon_directdec" 3 0 | |
844 | (and (eq_attr "cpu" "athlon") | |
845 | (eq_attr "athlon_decode" "direct")) | |
846 | 1 1) | |
847 | ||
848 | (define_function_unit "athlon_vectordec" 1 0 | |
849 | (and (eq_attr "cpu" "athlon") | |
850 | (eq_attr "athlon_decode" "direct")) | |
851 | 1 1 [(eq_attr "athlon_decode" "vector")]) | |
852 | ||
853 | (define_function_unit "athlon_ieu" 3 0 | |
854 | (and (eq_attr "cpu" "athlon") | |
6ef67412 | 855 | (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop")) |
309ada50 JH |
856 | 1 1) |
857 | ||
7c7ef435 JH |
858 | (define_function_unit "athlon_ieu" 3 0 |
859 | (and (eq_attr "cpu" "athlon") | |
860 | (eq_attr "type" "str")) | |
861 | 15 15) | |
862 | ||
309ada50 JH |
863 | (define_function_unit "athlon_ieu" 3 0 |
864 | (and (eq_attr "cpu" "athlon") | |
865 | (eq_attr "type" "imul")) | |
0b5107cf | 866 | 5 0) |
309ada50 JH |
867 | |
868 | (define_function_unit "athlon_ieu" 3 0 | |
869 | (and (eq_attr "cpu" "athlon") | |
870 | (eq_attr "type" "idiv")) | |
0b5107cf | 871 | 42 0) |
309ada50 JH |
872 | |
873 | (define_function_unit "athlon_muldiv" 1 0 | |
874 | (and (eq_attr "cpu" "athlon") | |
875 | (eq_attr "type" "imul")) | |
876 | 5 0) | |
877 | ||
878 | (define_function_unit "athlon_muldiv" 1 0 | |
879 | (and (eq_attr "cpu" "athlon") | |
880 | (eq_attr "type" "idiv")) | |
0b5107cf | 881 | 42 42) |
309ada50 | 882 | |
0b5107cf | 883 | (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any" |
309ada50 JH |
884 | (cond [(eq_attr "type" "fop,fop1,fcmp") |
885 | (const_string "add") | |
0b5107cf | 886 | (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov") |
309ada50 | 887 | (const_string "mul") |
0b5107cf | 888 | (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both")) |
309ada50 | 889 | (const_string "store") |
0b5107cf JH |
890 | (and (eq_attr "type" "fmov") (eq_attr "memory" "load")) |
891 | (const_string "any") | |
309ada50 JH |
892 | (and (eq_attr "type" "fmov") |
893 | (ior (match_operand:SI 1 "register_operand" "") | |
894 | (match_operand 1 "immediate_operand" ""))) | |
895 | (const_string "store") | |
896 | (eq_attr "type" "fmov") | |
0b5107cf | 897 | (const_string "muladd")] |
309ada50 JH |
898 | (const_string "none"))) |
899 | ||
0b5107cf JH |
900 | ;; We use latencies 1 for definitions. This is OK to model colisions |
901 | ;; in execution units. The real latencies are modeled in the "fp" pipeline. | |
902 | ||
903 | ;; fsin, fcos: 96-192 | |
904 | ;; fsincos: 107-211 | |
905 | ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode. | |
906 | (define_function_unit "athlon_fp" 3 0 | |
309ada50 | 907 | (and (eq_attr "cpu" "athlon") |
0b5107cf JH |
908 | (eq_attr "type" "fpspc")) |
909 | 100 1) | |
309ada50 | 910 | |
0b5107cf JH |
911 | ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode. |
912 | (define_function_unit "athlon_fp" 3 0 | |
309ada50 | 913 | (and (eq_attr "cpu" "athlon") |
0b5107cf JH |
914 | (eq_attr "type" "fdiv")) |
915 | 24 1) | |
916 | ||
917 | (define_function_unit "athlon_fp" 3 0 | |
918 | (and (eq_attr "cpu" "athlon") | |
919 | (eq_attr "type" "fop,fop1,fmul")) | |
309ada50 JH |
920 | 4 1) |
921 | ||
0b5107cf JH |
922 | ;; XFmode loads are slow. |
923 | ;; XFmode store is slow too (8 cycles), but we don't need to model it, because | |
924 | ;; there are no dependent instructions. | |
925 | ||
926 | (define_function_unit "athlon_fp" 3 0 | |
309ada50 JH |
927 | (and (eq_attr "cpu" "athlon") |
928 | (and (eq_attr "type" "fmov") | |
2b589241 JH |
929 | (and (eq_attr "memory" "load") |
930 | (eq_attr "mode" "XF")))) | |
0b5107cf JH |
931 | 10 1) |
932 | ||
933 | (define_function_unit "athlon_fp" 3 0 | |
934 | (and (eq_attr "cpu" "athlon") | |
935 | (eq_attr "type" "fmov,fsgn")) | |
309ada50 JH |
936 | 2 1) |
937 | ||
0b5107cf JH |
938 | ;; fcmp and ftst instructions |
939 | (define_function_unit "athlon_fp" 3 0 | |
940 | (and (eq_attr "cpu" "athlon") | |
941 | (and (eq_attr "type" "fcmp") | |
942 | (eq_attr "athlon_decode" "direct"))) | |
943 | 3 1) | |
944 | ||
945 | ;; fcmpi instructions. | |
946 | (define_function_unit "athlon_fp" 3 0 | |
947 | (and (eq_attr "cpu" "athlon") | |
948 | (and (eq_attr "type" "fcmp") | |
949 | (eq_attr "athlon_decode" "vector"))) | |
950 | 3 1) | |
951 | ||
952 | (define_function_unit "athlon_fp" 3 0 | |
953 | (and (eq_attr "cpu" "athlon") | |
954 | (eq_attr "type" "fcmov")) | |
955 | 7 1) | |
956 | ||
957 | (define_function_unit "athlon_fp_mul" 1 0 | |
958 | (and (eq_attr "cpu" "athlon") | |
959 | (eq_attr "athlon_fpunits" "mul")) | |
960 | 1 1) | |
961 | ||
962 | (define_function_unit "athlon_fp_add" 1 0 | |
963 | (and (eq_attr "cpu" "athlon") | |
964 | (eq_attr "athlon_fpunits" "add")) | |
965 | 1 1) | |
966 | ||
309ada50 JH |
967 | (define_function_unit "athlon_fp_muladd" 2 0 |
968 | (and (eq_attr "cpu" "athlon") | |
0b5107cf JH |
969 | (eq_attr "athlon_fpunits" "muladd,mul,add")) |
970 | 1 1) | |
309ada50 JH |
971 | |
972 | (define_function_unit "athlon_fp_store" 1 0 | |
973 | (and (eq_attr "cpu" "athlon") | |
0b5107cf | 974 | (eq_attr "athlon_fpunits" "store")) |
309ada50 JH |
975 | 1 1) |
976 | ||
0b5107cf JH |
977 | ;; We don't need to model the Adress Generation Unit, since we don't model |
978 | ;; the re-order buffer yet and thus we never schedule more than three operations | |
979 | ;; at time. Later we may want to experiment with MD_SCHED macros modeling the | |
980 | ;; decoders independently on the functional units. | |
981 | ||
982 | ;(define_function_unit "athlon_agu" 3 0 | |
983 | ; (and (eq_attr "cpu" "athlon") | |
984 | ; (and (eq_attr "memory" "!none") | |
985 | ; (eq_attr "athlon_fpunits" "none"))) | |
986 | ; 1 1) | |
987 | ||
988 | ;; Model load unit to avoid too long sequences of loads. We don't need to | |
989 | ;; model store queue, since it is hardly going to be bottleneck. | |
990 | ||
991 | (define_function_unit "athlon_load" 2 0 | |
309ada50 | 992 | (and (eq_attr "cpu" "athlon") |
0b5107cf | 993 | (eq_attr "memory" "load,both")) |
309ada50 JH |
994 | 1 1) |
995 | ||
996 | \f | |
e075ae69 | 997 | ;; Compare instructions. |
886c62d1 | 998 | |
e075ae69 | 999 | ;; All compare insns have expanders that save the operands away without |
c572e5ba | 1000 | ;; actually generating RTL. The bCOND or sCOND (emitted immediately |
e075ae69 | 1001 | ;; after the cmp) will actually emit the cmpM. |
886c62d1 | 1002 | |
e075ae69 RH |
1003 | (define_expand "cmpdi" |
1004 | [(set (reg:CC 17) | |
1005 | (compare:CC (match_operand:DI 0 "general_operand" "") | |
1006 | (match_operand:DI 1 "general_operand" "")))] | |
c572e5ba JVA |
1007 | "" |
1008 | " | |
1009 | { | |
e075ae69 RH |
1010 | if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) |
1011 | || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1]))) | |
1012 | operands[0] = force_reg (DImode, operands[0]); | |
1013 | ix86_compare_op0 = operands[0]; | |
1014 | ix86_compare_op1 = operands[1]; | |
c572e5ba JVA |
1015 | DONE; |
1016 | }") | |
1017 | ||
e075ae69 RH |
1018 | (define_expand "cmpsi" |
1019 | [(set (reg:CC 17) | |
1020 | (compare:CC (match_operand:SI 0 "cmpsi_operand" "") | |
1021 | (match_operand:SI 1 "general_operand" "")))] | |
c572e5ba JVA |
1022 | "" |
1023 | " | |
1024 | { | |
e075ae69 RH |
1025 | if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) |
1026 | || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1]))) | |
1027 | operands[0] = force_reg (SImode, operands[0]); | |
1028 | ix86_compare_op0 = operands[0]; | |
1029 | ix86_compare_op1 = operands[1]; | |
c572e5ba JVA |
1030 | DONE; |
1031 | }") | |
1032 | ||
e075ae69 RH |
1033 | (define_expand "cmphi" |
1034 | [(set (reg:CC 17) | |
1035 | (compare:CC (match_operand:HI 0 "general_operand" "") | |
1036 | (match_operand:HI 1 "general_operand" "")))] | |
c572e5ba JVA |
1037 | "" |
1038 | " | |
1039 | { | |
e075ae69 RH |
1040 | if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) |
1041 | || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1]))) | |
1042 | operands[0] = force_reg (HImode, operands[0]); | |
1043 | ix86_compare_op0 = operands[0]; | |
1044 | ix86_compare_op1 = operands[1]; | |
c572e5ba JVA |
1045 | DONE; |
1046 | }") | |
1047 | ||
e075ae69 RH |
1048 | (define_expand "cmpqi" |
1049 | [(set (reg:CC 17) | |
1050 | (compare:CC (match_operand:QI 0 "general_operand" "") | |
1051 | (match_operand:QI 1 "general_operand" "")))] | |
d9f32422 | 1052 | "TARGET_QIMODE_MATH" |
c572e5ba JVA |
1053 | " |
1054 | { | |
e075ae69 RH |
1055 | if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) |
1056 | || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1]))) | |
1057 | operands[0] = force_reg (QImode, operands[0]); | |
1058 | ix86_compare_op0 = operands[0]; | |
1059 | ix86_compare_op1 = operands[1]; | |
c572e5ba | 1060 | DONE; |
886c62d1 JVA |
1061 | }") |
1062 | ||
9076b9c1 JH |
1063 | (define_insn "*cmpsi_ccno_1" |
1064 | [(set (reg 17) | |
1065 | (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") | |
1066 | (match_operand:SI 1 "const0_operand" "n,n")))] | |
1067 | "ix86_match_ccmode (insn, CCNOmode)" | |
16189740 RH |
1068 | "@ |
1069 | test{l}\\t{%0, %0|%0, %0} | |
1070 | cmp{l}\\t{%1, %0|%0, %1}" | |
6ef67412 JH |
1071 | [(set_attr "type" "test,icmp") |
1072 | (set_attr "length_immediate" "0,1") | |
1073 | (set_attr "mode" "SI")]) | |
16189740 | 1074 | |
9076b9c1 JH |
1075 | (define_insn "*cmpsi_minus_1" |
1076 | [(set (reg 17) | |
1077 | (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r") | |
1078 | (match_operand:SI 1 "general_operand" "ri,mr")) | |
1079 | (const_int 0)))] | |
1080 | "ix86_match_ccmode (insn, CCGOCmode)" | |
1081 | "cmp{l}\\t{%1, %0|%0, %1}" | |
1082 | [(set_attr "type" "icmp") | |
6ef67412 | 1083 | (set_attr "mode" "SI")]) |
886c62d1 | 1084 | |
9076b9c1 | 1085 | (define_expand "cmpsi_1" |
e075ae69 RH |
1086 | [(set (reg:CC 17) |
1087 | (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r") | |
1088 | (match_operand:SI 1 "general_operand" "ri,mr")))] | |
9076b9c1 JH |
1089 | "" |
1090 | "") | |
1091 | ||
1092 | (define_insn "*cmpsi_1_insn" | |
1093 | [(set (reg 17) | |
1094 | (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r") | |
1095 | (match_operand:SI 1 "general_operand" "ri,mr")))] | |
1096 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) | |
1097 | && ix86_match_ccmode (insn, CCmode)" | |
e075ae69 | 1098 | "cmp{l}\\t{%1, %0|%0, %1}" |
6ef67412 JH |
1099 | [(set_attr "type" "icmp") |
1100 | (set_attr "mode" "SI")]) | |
886c62d1 | 1101 | |
9076b9c1 | 1102 | (define_insn "*cmphi_ccno_1" |
16189740 RH |
1103 | [(set (reg 17) |
1104 | (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") | |
1105 | (match_operand:HI 1 "const0_operand" "n,n")))] | |
1106 | "ix86_match_ccmode (insn, CCNOmode)" | |
e075ae69 RH |
1107 | "@ |
1108 | test{w}\\t{%0, %0|%0, %0} | |
1109 | cmp{w}\\t{%1, %0|%0, %1}" | |
6ef67412 JH |
1110 | [(set_attr "type" "test,icmp") |
1111 | (set_attr "length_immediate" "0,1") | |
1112 | (set_attr "mode" "HI")]) | |
886c62d1 | 1113 | |
9076b9c1 JH |
1114 | (define_insn "*cmphi_minus_1" |
1115 | [(set (reg 17) | |
1116 | (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") | |
1117 | (match_operand:HI 1 "general_operand" "ri,mr")) | |
1118 | (const_int 0)))] | |
1119 | "ix86_match_ccmode (insn, CCGOCmode)" | |
e075ae69 | 1120 | "cmp{w}\\t{%1, %0|%0, %1}" |
6ef67412 JH |
1121 | [(set_attr "type" "icmp") |
1122 | (set_attr "mode" "HI")]) | |
e075ae69 | 1123 | |
9076b9c1 JH |
1124 | (define_insn "*cmphi_1" |
1125 | [(set (reg 17) | |
1126 | (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") | |
1127 | (match_operand:HI 1 "general_operand" "ri,mr")))] | |
1128 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) | |
1129 | && ix86_match_ccmode (insn, CCmode)" | |
1130 | "cmp{w}\\t{%1, %0|%0, %1}" | |
1131 | [(set_attr "type" "icmp") | |
1132 | (set_attr "mode" "HI")]) | |
16189740 RH |
1133 | |
1134 | (define_insn "*cmpqi_ccno_1" | |
9076b9c1 JH |
1135 | [(set (reg 17) |
1136 | (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") | |
1137 | (match_operand:QI 1 "const0_operand" "n,n")))] | |
1138 | "ix86_match_ccmode (insn, CCNOmode)" | |
e075ae69 RH |
1139 | "@ |
1140 | test{b}\\t{%0, %0|%0, %0} | |
1141 | cmp{b}\\t{$0, %0|%0, 0}" | |
6ef67412 JH |
1142 | [(set_attr "type" "test,icmp") |
1143 | (set_attr "length_immediate" "0,1") | |
1144 | (set_attr "mode" "QI")]) | |
886c62d1 | 1145 | |
16189740 | 1146 | (define_insn "*cmpqi_1" |
9076b9c1 JH |
1147 | [(set (reg 17) |
1148 | (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") | |
1149 | (match_operand:QI 1 "general_operand" "qi,mq")))] | |
1150 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) | |
1151 | && ix86_match_ccmode (insn, CCmode)" | |
e075ae69 | 1152 | "cmp{b}\\t{%1, %0|%0, %1}" |
6ef67412 JH |
1153 | [(set_attr "type" "icmp") |
1154 | (set_attr "mode" "QI")]) | |
e075ae69 | 1155 | |
9076b9c1 JH |
1156 | (define_insn "*cmpqi_minus_1" |
1157 | [(set (reg 17) | |
d70401eb JJ |
1158 | (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q") |
1159 | (match_operand:QI 1 "general_operand" "qi,mq")) | |
9076b9c1 JH |
1160 | (const_int 0)))] |
1161 | "ix86_match_ccmode (insn, CCGOCmode)" | |
5efdd890 | 1162 | "cmp{b}\\t{%1, %0|%0, %1}" |
9076b9c1 JH |
1163 | [(set_attr "type" "icmp") |
1164 | (set_attr "mode" "QI")]) | |
1165 | ||
e075ae69 | 1166 | (define_insn "*cmpqi_ext_1" |
9076b9c1 JH |
1167 | [(set (reg 17) |
1168 | (compare | |
d2836273 | 1169 | (match_operand:QI 0 "general_operand" "Qm") |
e075ae69 RH |
1170 | (subreg:QI |
1171 | (zero_extract:SI | |
d2836273 | 1172 | (match_operand 1 "ext_register_operand" "Q") |
e075ae69 RH |
1173 | (const_int 8) |
1174 | (const_int 8)) 0)))] | |
d2836273 JH |
1175 | "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" |
1176 | "cmp{b}\\t{%h1, %0|%0, %h1}" | |
1177 | [(set_attr "type" "icmp") | |
1178 | (set_attr "mode" "QI")]) | |
1179 | ||
1180 | (define_insn "*cmpqi_ext_1_rex64" | |
1181 | [(set (reg 17) | |
1182 | (compare | |
1183 | (match_operand:QI 0 "ext_register_operand" "Q") | |
1184 | (subreg:QI | |
1185 | (zero_extract:SI | |
1186 | (match_operand 1 "ext_register_operand" "Q") | |
1187 | (const_int 8) | |
1188 | (const_int 8)) 0)))] | |
1189 | "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" | |
e075ae69 | 1190 | "cmp{b}\\t{%h1, %0|%0, %h1}" |
6ef67412 JH |
1191 | [(set_attr "type" "icmp") |
1192 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
1193 | |
1194 | (define_insn "*cmpqi_ext_2" | |
16189740 RH |
1195 | [(set (reg 17) |
1196 | (compare | |
e075ae69 RH |
1197 | (subreg:QI |
1198 | (zero_extract:SI | |
d2836273 | 1199 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
1200 | (const_int 8) |
1201 | (const_int 8)) 0) | |
1202 | (match_operand:QI 1 "const0_operand" "n")))] | |
16189740 | 1203 | "ix86_match_ccmode (insn, CCNOmode)" |
e075ae69 | 1204 | "test{b}\\t%h0, %h0" |
6ef67412 JH |
1205 | [(set_attr "type" "test") |
1206 | (set_attr "length_immediate" "0") | |
1207 | (set_attr "mode" "QI")]) | |
e075ae69 | 1208 | |
9076b9c1 | 1209 | (define_expand "cmpqi_ext_3" |
e075ae69 RH |
1210 | [(set (reg:CC 17) |
1211 | (compare:CC | |
1212 | (subreg:QI | |
1213 | (zero_extract:SI | |
d2836273 | 1214 | (match_operand 0 "ext_register_operand" "") |
e075ae69 RH |
1215 | (const_int 8) |
1216 | (const_int 8)) 0) | |
d2836273 | 1217 | (match_operand:QI 1 "general_operand" "")))] |
e075ae69 | 1218 | "" |
9076b9c1 JH |
1219 | "") |
1220 | ||
1221 | (define_insn "cmpqi_ext_3_insn" | |
1222 | [(set (reg 17) | |
1223 | (compare | |
1224 | (subreg:QI | |
1225 | (zero_extract:SI | |
d2836273 | 1226 | (match_operand 0 "ext_register_operand" "Q") |
9076b9c1 JH |
1227 | (const_int 8) |
1228 | (const_int 8)) 0) | |
d2836273 JH |
1229 | (match_operand:QI 1 "general_operand" "Qmn")))] |
1230 | "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" | |
1231 | "cmp{b}\\t{%1, %h0|%h0, %1}" | |
1232 | [(set_attr "type" "icmp") | |
1233 | (set_attr "mode" "QI")]) | |
1234 | ||
1235 | (define_insn "cmpqi_ext_3_insn_rex64" | |
1236 | [(set (reg 17) | |
1237 | (compare | |
1238 | (subreg:QI | |
1239 | (zero_extract:SI | |
1240 | (match_operand 0 "ext_register_operand" "Q") | |
1241 | (const_int 8) | |
1242 | (const_int 8)) 0) | |
1243 | (match_operand:QI 1 "nonmemory_operand" "Qn")))] | |
1244 | "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" | |
e075ae69 | 1245 | "cmp{b}\\t{%1, %h0|%h0, %1}" |
6ef67412 JH |
1246 | [(set_attr "type" "icmp") |
1247 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
1248 | |
1249 | (define_insn "*cmpqi_ext_4" | |
9076b9c1 JH |
1250 | [(set (reg 17) |
1251 | (compare | |
e075ae69 RH |
1252 | (subreg:QI |
1253 | (zero_extract:SI | |
d2836273 | 1254 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
1255 | (const_int 8) |
1256 | (const_int 8)) 0) | |
1257 | (subreg:QI | |
1258 | (zero_extract:SI | |
d2836273 | 1259 | (match_operand 1 "ext_register_operand" "Q") |
e075ae69 RH |
1260 | (const_int 8) |
1261 | (const_int 8)) 0)))] | |
9076b9c1 | 1262 | "ix86_match_ccmode (insn, CCmode)" |
e075ae69 | 1263 | "cmp{b}\\t{%h1, %h0|%h0, %h1}" |
6ef67412 JH |
1264 | [(set_attr "type" "icmp") |
1265 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
1266 | |
1267 | ;; These implement float point compares. | |
1268 | ;; %%% See if we can get away with VOIDmode operands on the actual insns, | |
1269 | ;; which would allow mix and match FP modes on the compares. Which is what | |
1270 | ;; the old patterns did, but with many more of them. | |
c572e5ba | 1271 | |
e075ae69 RH |
1272 | (define_expand "cmpxf" |
1273 | [(set (reg:CC 17) | |
1274 | (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "") | |
1275 | (match_operand:XF 1 "cmp_fp_expander_operand" "")))] | |
1e07edd3 | 1276 | "TARGET_80387 && !TARGET_64BIT" |
c572e5ba JVA |
1277 | " |
1278 | { | |
e075ae69 RH |
1279 | ix86_compare_op0 = operands[0]; |
1280 | ix86_compare_op1 = operands[1]; | |
c572e5ba | 1281 | DONE; |
886c62d1 | 1282 | }") |
4fb21e90 | 1283 | |
2b589241 JH |
1284 | (define_expand "cmptf" |
1285 | [(set (reg:CC 17) | |
1286 | (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "") | |
1287 | (match_operand:TF 1 "cmp_fp_expander_operand" "")))] | |
1288 | "TARGET_80387" | |
1289 | " | |
1290 | { | |
1291 | ix86_compare_op0 = operands[0]; | |
1292 | ix86_compare_op1 = operands[1]; | |
1293 | DONE; | |
1294 | }") | |
1295 | ||
e075ae69 RH |
1296 | (define_expand "cmpdf" |
1297 | [(set (reg:CC 17) | |
1298 | (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "") | |
1299 | (match_operand:DF 1 "cmp_fp_expander_operand" "")))] | |
0644b628 | 1300 | "TARGET_80387 || TARGET_SSE2" |
4fb21e90 JVA |
1301 | " |
1302 | { | |
e075ae69 RH |
1303 | ix86_compare_op0 = operands[0]; |
1304 | ix86_compare_op1 = operands[1]; | |
4fb21e90 JVA |
1305 | DONE; |
1306 | }") | |
886c62d1 | 1307 | |
e075ae69 RH |
1308 | (define_expand "cmpsf" |
1309 | [(set (reg:CC 17) | |
1310 | (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "") | |
1311 | (match_operand:SF 1 "cmp_fp_expander_operand" "")))] | |
0644b628 | 1312 | "TARGET_80387 || TARGET_SSE" |
c572e5ba JVA |
1313 | " |
1314 | { | |
e075ae69 RH |
1315 | ix86_compare_op0 = operands[0]; |
1316 | ix86_compare_op1 = operands[1]; | |
c572e5ba JVA |
1317 | DONE; |
1318 | }") | |
1319 | ||
e075ae69 RH |
1320 | ;; FP compares, step 1: |
1321 | ;; Set the FP condition codes. | |
1322 | ;; | |
1323 | ;; CCFPmode compare with exceptions | |
1324 | ;; CCFPUmode compare with no exceptions | |
fe4435d9 | 1325 | |
e075ae69 RH |
1326 | ;; %%% It is an unfortunate fact that ftst has no non-popping variant, |
1327 | ;; and that fp moves clobber the condition codes, and that there is | |
1328 | ;; currently no way to describe this fact to reg-stack. So there are | |
1329 | ;; no splitters yet for this. | |
c572e5ba | 1330 | |
e075ae69 RH |
1331 | ;; %%% YIKES! This scheme does not retain a strong connection between |
1332 | ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not | |
1333 | ;; work! Only allow tos/mem with tos in op 0. | |
1334 | ;; | |
1335 | ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps | |
1336 | ;; things aren't as bad as they sound... | |
886c62d1 | 1337 | |
e075ae69 RH |
1338 | (define_insn "*cmpfp_0" |
1339 | [(set (match_operand:HI 0 "register_operand" "=a") | |
1340 | (unspec:HI | |
1341 | [(compare:CCFP (match_operand 1 "register_operand" "f") | |
1342 | (match_operand 2 "const0_operand" "X"))] 9))] | |
1343 | "TARGET_80387 | |
1344 | && FLOAT_MODE_P (GET_MODE (operands[1])) | |
1345 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
1346 | "* | |
c572e5ba | 1347 | { |
e075ae69 RH |
1348 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) |
1349 | return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\"; | |
1350 | else | |
1351 | return \"ftst\;fnstsw\\t%0\"; | |
1352 | }" | |
6ef67412 JH |
1353 | [(set_attr "type" "multi") |
1354 | (set_attr "mode" "unknownfp")]) | |
c572e5ba | 1355 | |
e075ae69 RH |
1356 | ;; We may not use "#" to split and emit these, since the REG_DEAD notes |
1357 | ;; used to manage the reg stack popping would not be preserved. | |
886c62d1 | 1358 | |
e075ae69 RH |
1359 | (define_insn "*cmpfp_2_sf" |
1360 | [(set (reg:CCFP 18) | |
1361 | (compare:CCFP | |
1362 | (match_operand:SF 0 "register_operand" "f") | |
1363 | (match_operand:SF 1 "nonimmediate_operand" "fm")))] | |
cac58785 | 1364 | "TARGET_80387" |
e075ae69 | 1365 | "* return output_fp_compare (insn, operands, 0, 0);" |
6ef67412 JH |
1366 | [(set_attr "type" "fcmp") |
1367 | (set_attr "mode" "SF")]) | |
4fb21e90 | 1368 | |
6343a50e | 1369 | (define_insn "*cmpfp_2_sf_1" |
e075ae69 RH |
1370 | [(set (match_operand:HI 0 "register_operand" "=a") |
1371 | (unspec:HI | |
1372 | [(compare:CCFP | |
1373 | (match_operand:SF 1 "register_operand" "f") | |
1374 | (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))] | |
4fb21e90 | 1375 | "TARGET_80387" |
e075ae69 | 1376 | "* return output_fp_compare (insn, operands, 2, 0);" |
6ef67412 JH |
1377 | [(set_attr "type" "fcmp") |
1378 | (set_attr "mode" "SF")]) | |
e075ae69 RH |
1379 | |
1380 | (define_insn "*cmpfp_2_df" | |
1381 | [(set (reg:CCFP 18) | |
1382 | (compare:CCFP | |
1383 | (match_operand:DF 0 "register_operand" "f") | |
1384 | (match_operand:DF 1 "nonimmediate_operand" "fm")))] | |
926b3fae | 1385 | "TARGET_80387" |
e075ae69 | 1386 | "* return output_fp_compare (insn, operands, 0, 0);" |
6ef67412 JH |
1387 | [(set_attr "type" "fcmp") |
1388 | (set_attr "mode" "DF")]) | |
926b3fae | 1389 | |
6343a50e | 1390 | (define_insn "*cmpfp_2_df_1" |
e075ae69 RH |
1391 | [(set (match_operand:HI 0 "register_operand" "=a") |
1392 | (unspec:HI | |
1393 | [(compare:CCFP | |
1394 | (match_operand:DF 1 "register_operand" "f") | |
1395 | (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))] | |
4fb21e90 | 1396 | "TARGET_80387" |
e075ae69 | 1397 | "* return output_fp_compare (insn, operands, 2, 0);" |
6ef67412 JH |
1398 | [(set_attr "type" "multi") |
1399 | (set_attr "mode" "DF")]) | |
e075ae69 RH |
1400 | |
1401 | (define_insn "*cmpfp_2_xf" | |
1402 | [(set (reg:CCFP 18) | |
1403 | (compare:CCFP | |
1404 | (match_operand:XF 0 "register_operand" "f") | |
1405 | (match_operand:XF 1 "register_operand" "f")))] | |
1e07edd3 | 1406 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 | 1407 | "* return output_fp_compare (insn, operands, 0, 0);" |
6ef67412 JH |
1408 | [(set_attr "type" "fcmp") |
1409 | (set_attr "mode" "XF")]) | |
9ec36da5 | 1410 | |
2b589241 JH |
1411 | (define_insn "*cmpfp_2_tf" |
1412 | [(set (reg:CCFP 18) | |
1413 | (compare:CCFP | |
1414 | (match_operand:TF 0 "register_operand" "f") | |
1415 | (match_operand:TF 1 "register_operand" "f")))] | |
1416 | "TARGET_80387" | |
1417 | "* return output_fp_compare (insn, operands, 0, 0);" | |
1418 | [(set_attr "type" "fcmp") | |
1419 | (set_attr "mode" "XF")]) | |
1420 | ||
6343a50e | 1421 | (define_insn "*cmpfp_2_xf_1" |
e075ae69 RH |
1422 | [(set (match_operand:HI 0 "register_operand" "=a") |
1423 | (unspec:HI | |
1424 | [(compare:CCFP | |
1425 | (match_operand:XF 1 "register_operand" "f") | |
1426 | (match_operand:XF 2 "register_operand" "f"))] 9))] | |
1e07edd3 | 1427 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 | 1428 | "* return output_fp_compare (insn, operands, 2, 0);" |
6ef67412 JH |
1429 | [(set_attr "type" "multi") |
1430 | (set_attr "mode" "XF")]) | |
e075ae69 | 1431 | |
2b589241 JH |
1432 | (define_insn "*cmpfp_2_tf_1" |
1433 | [(set (match_operand:HI 0 "register_operand" "=a") | |
1434 | (unspec:HI | |
1435 | [(compare:CCFP | |
1436 | (match_operand:TF 1 "register_operand" "f") | |
1437 | (match_operand:TF 2 "register_operand" "f"))] 9))] | |
1438 | "TARGET_80387" | |
1439 | "* return output_fp_compare (insn, operands, 2, 0);" | |
1440 | [(set_attr "type" "multi") | |
1441 | (set_attr "mode" "XF")]) | |
1442 | ||
e075ae69 RH |
1443 | (define_insn "*cmpfp_2u" |
1444 | [(set (reg:CCFPU 18) | |
1445 | (compare:CCFPU | |
1446 | (match_operand 0 "register_operand" "f") | |
1447 | (match_operand 1 "register_operand" "f")))] | |
1448 | "TARGET_80387 | |
1449 | && FLOAT_MODE_P (GET_MODE (operands[0])) | |
1450 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" | |
1451 | "* return output_fp_compare (insn, operands, 0, 1);" | |
6ef67412 JH |
1452 | [(set_attr "type" "fcmp") |
1453 | (set_attr "mode" "unknownfp")]) | |
4fb21e90 | 1454 | |
6343a50e | 1455 | (define_insn "*cmpfp_2u_1" |
e075ae69 RH |
1456 | [(set (match_operand:HI 0 "register_operand" "=a") |
1457 | (unspec:HI | |
1458 | [(compare:CCFPU | |
1459 | (match_operand 1 "register_operand" "f") | |
1460 | (match_operand 2 "register_operand" "f"))] 9))] | |
08a7baac | 1461 | "TARGET_80387 |
e075ae69 RH |
1462 | && FLOAT_MODE_P (GET_MODE (operands[1])) |
1463 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
1464 | "* return output_fp_compare (insn, operands, 2, 1);" | |
6ef67412 JH |
1465 | [(set_attr "type" "multi") |
1466 | (set_attr "mode" "unknownfp")]) | |
08a7baac | 1467 | |
e075ae69 RH |
1468 | ;; Patterns to match the SImode-in-memory ficom instructions. |
1469 | ;; | |
1470 | ;; %%% Play games with accepting gp registers, as otherwise we have to | |
1471 | ;; force them to memory during rtl generation, which is no good. We | |
1472 | ;; can get rid of this once we teach reload to do memory input reloads | |
1473 | ;; via pushes. | |
1474 | ||
6343a50e | 1475 | (define_insn "*ficom_1" |
e075ae69 RH |
1476 | [(set (reg:CCFP 18) |
1477 | (compare:CCFP | |
1478 | (match_operand 0 "register_operand" "f,f") | |
1479 | (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))] | |
1480 | "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0])) | |
1481 | && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])" | |
1482 | "#") | |
08a7baac | 1483 | |
e075ae69 RH |
1484 | ;; Split the not-really-implemented gp register case into a |
1485 | ;; push-op-pop sequence. | |
1486 | ;; | |
1487 | ;; %%% This is most efficient, but am I gonna get in trouble | |
1488 | ;; for separating cc0_setter and cc0_user? | |
2bb7a0f5 | 1489 | |
e075ae69 RH |
1490 | (define_split |
1491 | [(set (reg:CCFP 18) | |
1492 | (compare:CCFP | |
1493 | (match_operand:SF 0 "register_operand" "") | |
1494 | (float (match_operand:SI 1 "register_operand" ""))))] | |
1495 | "0 && TARGET_80387 && reload_completed" | |
1496 | [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1)) | |
1497 | (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2))) | |
1498 | (parallel [(set (match_dup 1) (mem:SI (reg:SI 7))) | |
1499 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])] | |
1500 | "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx); | |
1501 | operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);") | |
1502 | ||
1503 | ;; FP compares, step 2 | |
1504 | ;; Move the fpsw to ax. | |
1505 | ||
1506 | (define_insn "x86_fnstsw_1" | |
1507 | [(set (match_operand:HI 0 "register_operand" "=a") | |
1508 | (unspec:HI [(reg 18)] 9))] | |
2ae0f82c | 1509 | "TARGET_80387" |
e075ae69 RH |
1510 | "fnstsw\\t%0" |
1511 | [(set_attr "length" "2") | |
6ef67412 JH |
1512 | (set_attr "mode" "SI") |
1513 | (set_attr "i387" "1") | |
e075ae69 RH |
1514 | (set_attr "ppro_uops" "few")]) |
1515 | ||
1516 | ;; FP compares, step 3 | |
1517 | ;; Get ax into flags, general case. | |
1518 | ||
1519 | (define_insn "x86_sahf_1" | |
1520 | [(set (reg:CC 17) | |
1521 | (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))] | |
1e07edd3 | 1522 | "!TARGET_64BIT" |
e075ae69 RH |
1523 | "sahf" |
1524 | [(set_attr "length" "1") | |
0b5107cf | 1525 | (set_attr "athlon_decode" "vector") |
6ef67412 | 1526 | (set_attr "mode" "SI") |
e075ae69 RH |
1527 | (set_attr "ppro_uops" "one")]) |
1528 | ||
1529 | ;; Pentium Pro can do steps 1 through 3 in one go. | |
1530 | ||
1531 | (define_insn "*cmpfp_i" | |
1532 | [(set (reg:CCFP 17) | |
1533 | (compare:CCFP (match_operand 0 "register_operand" "f") | |
1534 | (match_operand 1 "register_operand" "f")))] | |
1535 | "TARGET_80387 && TARGET_CMOVE | |
0644b628 | 1536 | && !SSE_FLOAT_MODE_P (GET_MODE (operands[0])) |
e075ae69 RH |
1537 | && FLOAT_MODE_P (GET_MODE (operands[0])) |
1538 | && GET_MODE (operands[0]) == GET_MODE (operands[0])" | |
1539 | "* return output_fp_compare (insn, operands, 1, 0);" | |
309ada50 | 1540 | [(set_attr "type" "fcmp") |
6ef67412 | 1541 | (set_attr "mode" "unknownfp") |
309ada50 | 1542 | (set_attr "athlon_decode" "vector")]) |
e075ae69 | 1543 | |
0644b628 JH |
1544 | (define_insn "*cmpfp_i_sse" |
1545 | [(set (reg:CCFP 17) | |
1546 | (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f") | |
1547 | (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))] | |
1548 | "TARGET_80387 | |
1549 | && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) | |
1550 | && GET_MODE (operands[0]) == GET_MODE (operands[0])" | |
1551 | "* return output_fp_compare (insn, operands, 1, 0);" | |
1552 | [(set_attr "type" "fcmp,sse") | |
1553 | (set_attr "mode" "unknownfp") | |
1554 | (set_attr "athlon_decode" "vector")]) | |
1555 | ||
1556 | (define_insn "*cmpfp_i_sse_only" | |
1557 | [(set (reg:CCFP 17) | |
1558 | (compare:CCFP (match_operand 0 "register_operand" "x") | |
1559 | (match_operand 1 "nonimmediate_operand" "xm")))] | |
1560 | "SSE_FLOAT_MODE_P (GET_MODE (operands[0])) | |
1561 | && GET_MODE (operands[0]) == GET_MODE (operands[0])" | |
1562 | "* return output_fp_compare (insn, operands, 1, 0);" | |
1563 | [(set_attr "type" "sse") | |
1564 | (set_attr "mode" "unknownfp") | |
1565 | (set_attr "athlon_decode" "vector")]) | |
1566 | ||
e075ae69 RH |
1567 | (define_insn "*cmpfp_iu" |
1568 | [(set (reg:CCFPU 17) | |
1569 | (compare:CCFPU (match_operand 0 "register_operand" "f") | |
1570 | (match_operand 1 "register_operand" "f")))] | |
1571 | "TARGET_80387 && TARGET_CMOVE | |
0644b628 | 1572 | && !SSE_FLOAT_MODE_P (GET_MODE (operands[0])) |
e075ae69 RH |
1573 | && FLOAT_MODE_P (GET_MODE (operands[0])) |
1574 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" | |
1575 | "* return output_fp_compare (insn, operands, 1, 1);" | |
309ada50 | 1576 | [(set_attr "type" "fcmp") |
6ef67412 | 1577 | (set_attr "mode" "unknownfp") |
309ada50 | 1578 | (set_attr "athlon_decode" "vector")]) |
0644b628 JH |
1579 | |
1580 | (define_insn "*cmpfp_iu_sse" | |
1581 | [(set (reg:CCFPU 17) | |
1582 | (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f") | |
1583 | (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))] | |
1584 | "TARGET_80387 | |
1585 | && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) | |
1586 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" | |
1587 | "* return output_fp_compare (insn, operands, 1, 1);" | |
1588 | [(set_attr "type" "fcmp,sse") | |
1589 | (set_attr "mode" "unknownfp") | |
1590 | (set_attr "athlon_decode" "vector")]) | |
1591 | ||
1592 | (define_insn "*cmpfp_iu_sse_only" | |
1593 | [(set (reg:CCFPU 17) | |
1594 | (compare:CCFPU (match_operand 0 "register_operand" "x") | |
1595 | (match_operand 1 "nonimmediate_operand" "xm")))] | |
1596 | "SSE_FLOAT_MODE_P (GET_MODE (operands[0])) | |
1597 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" | |
1598 | "* return output_fp_compare (insn, operands, 1, 1);" | |
1599 | [(set_attr "type" "sse") | |
1600 | (set_attr "mode" "unknownfp") | |
1601 | (set_attr "athlon_decode" "vector")]) | |
e075ae69 RH |
1602 | \f |
1603 | ;; Move instructions. | |
2ae0f82c | 1604 | |
e075ae69 | 1605 | ;; General case of fullword move. |
886c62d1 | 1606 | |
e075ae69 RH |
1607 | (define_expand "movsi" |
1608 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
1609 | (match_operand:SI 1 "general_operand" ""))] | |
1610 | "" | |
1611 | "ix86_expand_move (SImode, operands); DONE;") | |
08a7baac | 1612 | |
e075ae69 RH |
1613 | ;; Push/pop instructions. They are separate since autoinc/dec is not a |
1614 | ;; general_operand. | |
1615 | ;; | |
1616 | ;; %%% We don't use a post-inc memory reference because x86 is not a | |
1617 | ;; general AUTO_INC_DEC host, which impacts how it is treated in flow. | |
1618 | ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC | |
1619 | ;; targets without our curiosities, and it is just as easy to represent | |
1620 | ;; this differently. | |
886c62d1 | 1621 | |
a4414093 | 1622 | (define_insn "*pushsi2" |
e075ae69 | 1623 | [(set (match_operand:SI 0 "push_operand" "=<") |
2c5a510c | 1624 | (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] |
e075ae69 RH |
1625 | "" |
1626 | "push{l}\\t%1" | |
6ef67412 JH |
1627 | [(set_attr "type" "push") |
1628 | (set_attr "mode" "SI")]) | |
4fb21e90 | 1629 | |
bdeb029c JH |
1630 | (define_insn "*pushsi2_prologue" |
1631 | [(set (match_operand:SI 0 "push_operand" "=<") | |
1632 | (match_operand:SI 1 "general_no_elim_operand" "ri*m")) | |
1633 | (set (reg:SI 6) (reg:SI 6))] | |
1634 | "" | |
1635 | "push{l}\\t%1" | |
6ef67412 JH |
1636 | [(set_attr "type" "push") |
1637 | (set_attr "mode" "SI")]) | |
bdeb029c JH |
1638 | |
1639 | (define_insn "*popsi1_epilogue" | |
1640 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") | |
1641 | (mem:SI (reg:SI 7))) | |
1642 | (set (reg:SI 7) | |
1643 | (plus:SI (reg:SI 7) (const_int 4))) | |
1644 | (set (reg:SI 6) (reg:SI 6))] | |
1e07edd3 | 1645 | "!TARGET_64BIT" |
bdeb029c | 1646 | "pop{l}\\t%0" |
6ef67412 JH |
1647 | [(set_attr "type" "pop") |
1648 | (set_attr "mode" "SI")]) | |
bdeb029c | 1649 | |
e075ae69 RH |
1650 | (define_insn "popsi1" |
1651 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") | |
1652 | (mem:SI (reg:SI 7))) | |
1653 | (set (reg:SI 7) | |
1654 | (plus:SI (reg:SI 7) (const_int 4)))] | |
1e07edd3 | 1655 | "!TARGET_64BIT" |
e075ae69 | 1656 | "pop{l}\\t%0" |
6ef67412 JH |
1657 | [(set_attr "type" "pop") |
1658 | (set_attr "mode" "SI")]) | |
c572e5ba | 1659 | |
591702de JH |
1660 | (define_insn "*movsi_xor" |
1661 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1662 | (match_operand:SI 1 "const0_operand" "i")) | |
e075ae69 | 1663 | (clobber (reg:CC 17))] |
591702de JH |
1664 | "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" |
1665 | "xor{l}\\t{%0, %0|%0, %0}" | |
1666 | [(set_attr "type" "alu1") | |
6ef67412 JH |
1667 | (set_attr "mode" "SI") |
1668 | (set_attr "length_immediate" "0")]) | |
591702de JH |
1669 | |
1670 | (define_insn "*movsi_or" | |
1671 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1672 | (match_operand:SI 1 "immediate_operand" "i")) | |
1673 | (clobber (reg:CC 17))] | |
1674 | "reload_completed && GET_CODE (operands[1]) == CONST_INT | |
1675 | && INTVAL (operands[1]) == -1 | |
1676 | && (TARGET_PENTIUM || optimize_size)" | |
e075ae69 | 1677 | "* |
c572e5ba | 1678 | { |
591702de | 1679 | operands[1] = constm1_rtx; |
406df25c | 1680 | return \"or{l}\\t{%1, %0|%0, %1}\"; |
a269a03c | 1681 | }" |
591702de | 1682 | [(set_attr "type" "alu1") |
6ef67412 JH |
1683 | (set_attr "mode" "SI") |
1684 | (set_attr "length_immediate" "1")]) | |
e075ae69 | 1685 | |
591702de | 1686 | (define_insn "*movsi_1" |
915119a5 BS |
1687 | [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!r") |
1688 | (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,r,*y"))] | |
e075ae69 | 1689 | "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" |
886c62d1 JVA |
1690 | "* |
1691 | { | |
e075ae69 | 1692 | switch (get_attr_type (insn)) |
886c62d1 | 1693 | { |
915119a5 BS |
1694 | case TYPE_MMX: |
1695 | return \"movd\\t{%1, %0|%0, %1}\"; | |
1696 | ||
e075ae69 RH |
1697 | case TYPE_LEA: |
1698 | return \"lea{l}\\t{%1, %0|%0, %1}\"; | |
915119a5 | 1699 | |
e075ae69 RH |
1700 | default: |
1701 | if (flag_pic && SYMBOLIC_CONST (operands[1])) | |
1702 | abort(); | |
1703 | return \"mov{l}\\t{%1, %0|%0, %1}\"; | |
886c62d1 | 1704 | } |
a269a03c | 1705 | }" |
e075ae69 | 1706 | [(set (attr "type") |
915119a5 BS |
1707 | (cond [(ior (match_operand:SI 0 "mmx_reg_operand" "") |
1708 | (match_operand:SI 1 "mmx_reg_operand" "")) | |
1709 | (const_string "mmx") | |
1710 | (and (ne (symbol_ref "flag_pic") (const_int 0)) | |
e075ae69 RH |
1711 | (match_operand:SI 1 "symbolic_operand" "")) |
1712 | (const_string "lea") | |
1713 | ] | |
6ef67412 | 1714 | (const_string "imov"))) |
915119a5 | 1715 | (set_attr "modrm" "0,*,0,*,*,*") |
6ef67412 | 1716 | (set_attr "mode" "SI")]) |
e075ae69 RH |
1717 | |
1718 | (define_insn "*swapsi" | |
1719 | [(set (match_operand:SI 0 "register_operand" "+r") | |
1720 | (match_operand:SI 1 "register_operand" "+r")) | |
1721 | (set (match_dup 1) | |
1722 | (match_dup 0))] | |
2bb7a0f5 | 1723 | "" |
e075ae69 RH |
1724 | "xchg{l}\\t%1, %0" |
1725 | [(set_attr "type" "imov") | |
1726 | (set_attr "pent_pair" "np") | |
0b5107cf | 1727 | (set_attr "athlon_decode" "vector") |
6ef67412 JH |
1728 | (set_attr "mode" "SI") |
1729 | (set_attr "modrm" "0") | |
e075ae69 | 1730 | (set_attr "ppro_uops" "few")]) |
886c62d1 | 1731 | |
e075ae69 RH |
1732 | (define_expand "movhi" |
1733 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
1734 | (match_operand:HI 1 "general_operand" ""))] | |
ca097615 | 1735 | "" |
e075ae69 | 1736 | "ix86_expand_move (HImode, operands); DONE;") |
2f2a49e8 | 1737 | |
a4414093 | 1738 | (define_insn "*pushhi2" |
e075ae69 | 1739 | [(set (match_operand:HI 0 "push_operand" "=<,<") |
2c5a510c | 1740 | (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))] |
1e07edd3 | 1741 | "!TARGET_64BIT" |
e075ae69 RH |
1742 | "@ |
1743 | push{w}\\t{|WORD PTR }%1 | |
1744 | push{w}\\t%1" | |
6ef67412 JH |
1745 | [(set_attr "type" "push") |
1746 | (set_attr "mode" "HI")]) | |
e075ae69 | 1747 | |
a4414093 | 1748 | (define_insn "*pophi1" |
e075ae69 RH |
1749 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m") |
1750 | (mem:HI (reg:SI 7))) | |
1751 | (set (reg:SI 7) | |
1752 | (plus:SI (reg:SI 7) (const_int 2)))] | |
1e07edd3 | 1753 | "!TARGET_64BIT" |
e075ae69 | 1754 | "pop{w}\\t%0" |
6ef67412 JH |
1755 | [(set_attr "type" "pop") |
1756 | (set_attr "mode" "HI")]) | |
e075ae69 RH |
1757 | |
1758 | (define_insn "*movhi_1" | |
6ef67412 JH |
1759 | [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m") |
1760 | (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))] | |
e075ae69 | 1761 | "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" |
886c62d1 JVA |
1762 | "* |
1763 | { | |
e075ae69 | 1764 | switch (get_attr_type (insn)) |
886c62d1 | 1765 | { |
e075ae69 RH |
1766 | case TYPE_IMOVX: |
1767 | /* movzwl is faster than movw on p2 due to partial word stalls, | |
1768 | though not as fast as an aligned movl. */ | |
1769 | return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\"; | |
1770 | default: | |
6ef67412 | 1771 | if (get_attr_mode (insn) == MODE_SI) |
e075ae69 RH |
1772 | return \"mov{l}\\t{%k1, %k0|%k0, %k1}\"; |
1773 | else | |
1774 | return \"mov{w}\\t{%1, %0|%0, %1}\"; | |
886c62d1 | 1775 | } |
a269a03c | 1776 | }" |
e075ae69 | 1777 | [(set (attr "type") |
6ef67412 | 1778 | (cond [(and (eq_attr "alternative" "0,1") |
0b5107cf JH |
1779 | (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") |
1780 | (const_int 0)) | |
1781 | (eq (symbol_ref "TARGET_HIMODE_MATH") | |
1782 | (const_int 0)))) | |
369e59b1 | 1783 | (const_string "imov") |
6ef67412 | 1784 | (and (eq_attr "alternative" "2,3,4") |
2247f6ed | 1785 | (match_operand:HI 1 "aligned_operand" "")) |
e075ae69 RH |
1786 | (const_string "imov") |
1787 | (and (ne (symbol_ref "TARGET_MOVX") | |
1788 | (const_int 0)) | |
6ef67412 | 1789 | (eq_attr "alternative" "0,1,3,4")) |
e075ae69 RH |
1790 | (const_string "imovx") |
1791 | ] | |
1792 | (const_string "imov"))) | |
6ef67412 | 1793 | (set (attr "mode") |
e075ae69 | 1794 | (cond [(eq_attr "type" "imovx") |
6ef67412 JH |
1795 | (const_string "SI") |
1796 | (and (eq_attr "alternative" "2,3,4") | |
369e59b1 | 1797 | (match_operand:HI 1 "aligned_operand" "")) |
6ef67412 JH |
1798 | (const_string "SI") |
1799 | (and (eq_attr "alternative" "0,1") | |
0b5107cf JH |
1800 | (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") |
1801 | (const_int 0)) | |
1802 | (eq (symbol_ref "TARGET_HIMODE_MATH") | |
1803 | (const_int 0)))) | |
6ef67412 | 1804 | (const_string "SI") |
e075ae69 | 1805 | ] |
6ef67412 JH |
1806 | (const_string "HI"))) |
1807 | (set_attr "modrm" "0,*,*,0,*,*")]) | |
e075ae69 RH |
1808 | |
1809 | (define_insn "*swaphi_1" | |
1810 | [(set (match_operand:HI 0 "register_operand" "+r") | |
1811 | (match_operand:HI 1 "register_operand" "+r")) | |
1812 | (set (match_dup 1) | |
1813 | (match_dup 0))] | |
1814 | "TARGET_PARTIAL_REG_STALL" | |
1815 | "xchg{w}\\t%1, %0" | |
1816 | [(set_attr "type" "imov") | |
1817 | (set_attr "pent_pair" "np") | |
6ef67412 JH |
1818 | (set_attr "mode" "HI") |
1819 | (set_attr "modrm" "0") | |
e075ae69 RH |
1820 | (set_attr "ppro_uops" "few")]) |
1821 | ||
1822 | (define_insn "*swaphi_2" | |
1823 | [(set (match_operand:HI 0 "register_operand" "+r") | |
1824 | (match_operand:HI 1 "register_operand" "+r")) | |
1825 | (set (match_dup 1) | |
1826 | (match_dup 0))] | |
1827 | "! TARGET_PARTIAL_REG_STALL" | |
1828 | "xchg{l}\\t%k1, %k0" | |
1829 | [(set_attr "type" "imov") | |
e075ae69 | 1830 | (set_attr "pent_pair" "np") |
6ef67412 JH |
1831 | (set_attr "mode" "SI") |
1832 | (set_attr "modrm" "0") | |
e075ae69 | 1833 | (set_attr "ppro_uops" "few")]) |
886c62d1 | 1834 | |
2f2a49e8 | 1835 | (define_expand "movstricthi" |
e075ae69 | 1836 | [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) |
2f2a49e8 | 1837 | (match_operand:HI 1 "general_operand" ""))] |
e075ae69 | 1838 | "! TARGET_PARTIAL_REG_STALL" |
2f2a49e8 MM |
1839 | " |
1840 | { | |
1841 | /* Don't generate memory->memory moves, go through a register */ | |
e075ae69 RH |
1842 | if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) |
1843 | operands[1] = force_reg (HImode, operands[1]); | |
2f2a49e8 MM |
1844 | }") |
1845 | ||
e075ae69 | 1846 | (define_insn "*movstricthi_1" |
fc524c1c | 1847 | [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r")) |
e075ae69 RH |
1848 | (match_operand:HI 1 "general_operand" "rn,m"))] |
1849 | "! TARGET_PARTIAL_REG_STALL | |
1850 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" | |
1851 | "mov{w}\\t{%1, %0|%0, %1}" | |
6ef67412 JH |
1852 | [(set_attr "type" "imov") |
1853 | (set_attr "mode" "HI")]) | |
1854 | ||
1855 | (define_insn "*movstricthi_xor" | |
208b0ab1 | 1856 | [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) |
6ef67412 JH |
1857 | (match_operand:HI 1 "const0_operand" "i")) |
1858 | (clobber (reg:CC 17))] | |
1859 | "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" | |
1860 | "xor{w}\\t{%0, %0|%0, %0}" | |
1861 | [(set_attr "type" "alu1") | |
1862 | (set_attr "mode" "HI") | |
1863 | (set_attr "length_immediate" "0")]) | |
886c62d1 | 1864 | |
2f2a49e8 | 1865 | (define_expand "movqi" |
4cbfbb1b | 1866 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
2f2a49e8 MM |
1867 | (match_operand:QI 1 "general_operand" ""))] |
1868 | "" | |
e075ae69 RH |
1869 | "ix86_expand_move (QImode, operands); DONE;") |
1870 | ||
1871 | ;; emit_push_insn when it calls move_by_pieces requires an insn to | |
1872 | ;; "push a byte". But actually we use pushw, which has the effect | |
1873 | ;; of rounding the amount pushed up to a halfword. | |
1874 | ||
a4414093 | 1875 | (define_insn "*pushqi2" |
e075ae69 | 1876 | [(set (match_operand:QI 0 "push_operand" "=<,<") |
2c5a510c | 1877 | (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))] |
1e07edd3 | 1878 | "!TARGET_64BIT" |
e075ae69 RH |
1879 | "@ |
1880 | push{w}\\t{|word ptr }%1 | |
1881 | push{w}\\t%w1" | |
1882 | [(set_attr "type" "push") | |
6ef67412 | 1883 | (set_attr "mode" "HI")]) |
e075ae69 | 1884 | |
a4414093 | 1885 | (define_insn "*popqi1" |
e075ae69 RH |
1886 | [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m") |
1887 | (mem:QI (reg:SI 7))) | |
1888 | (set (reg:SI 7) | |
1889 | (plus:SI (reg:SI 7) (const_int 2)))] | |
1e07edd3 | 1890 | "!TARGET_64BIT" |
e075ae69 RH |
1891 | "pop{w}\\t%0" |
1892 | [(set_attr "type" "pop") | |
6ef67412 | 1893 | (set_attr "mode" "HI")]) |
e075ae69 | 1894 | |
0b5107cf JH |
1895 | ;; Situation is quite tricky about when to choose full sized (SImode) move |
1896 | ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for | |
1897 | ;; partial register dependency machines (such as AMD Athlon), where QImode | |
1898 | ;; moves issue extra dependency and for partial register stalls machines | |
1899 | ;; that don't use QImode patterns (and QImode move cause stall on the next | |
1900 | ;; instruction). | |
1901 | ;; | |
1902 | ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial | |
1903 | ;; register stall machines with, where we use QImode instructions, since | |
1904 | ;; partial register stall can be caused there. Then we use movzx. | |
e075ae69 | 1905 | (define_insn "*movqi_1" |
0b5107cf JH |
1906 | [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") |
1907 | (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] | |
e075ae69 | 1908 | "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" |
886c62d1 JVA |
1909 | "* |
1910 | { | |
e075ae69 | 1911 | switch (get_attr_type (insn)) |
b76c90cf | 1912 | { |
e075ae69 | 1913 | case TYPE_IMOVX: |
1a06f5fe | 1914 | if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM) |
e075ae69 RH |
1915 | abort (); |
1916 | return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\"; | |
1917 | default: | |
6ef67412 | 1918 | if (get_attr_mode (insn) == MODE_SI) |
e075ae69 | 1919 | return \"mov{l}\\t{%k1, %k0|%k0, %k1}\"; |
b76c90cf | 1920 | else |
e075ae69 | 1921 | return \"mov{b}\\t{%1, %0|%0, %1}\"; |
b76c90cf | 1922 | } |
e075ae69 RH |
1923 | }" |
1924 | [(set (attr "type") | |
0b5107cf JH |
1925 | (cond [(and (eq_attr "alternative" "3") |
1926 | (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") | |
1927 | (const_int 0)) | |
1928 | (eq (symbol_ref "TARGET_QIMODE_MATH") | |
1929 | (const_int 0)))) | |
1930 | (const_string "imov") | |
1931 | (eq_attr "alternative" "3,5") | |
e075ae69 RH |
1932 | (const_string "imovx") |
1933 | (and (ne (symbol_ref "TARGET_MOVX") | |
1934 | (const_int 0)) | |
0b5107cf | 1935 | (eq_attr "alternative" "2")) |
e075ae69 RH |
1936 | (const_string "imovx") |
1937 | ] | |
1938 | (const_string "imov"))) | |
6ef67412 JH |
1939 | (set (attr "mode") |
1940 | (cond [(eq_attr "alternative" "3,4,5") | |
1941 | (const_string "SI") | |
1942 | (eq_attr "alternative" "6") | |
1943 | (const_string "QI") | |
1944 | (eq_attr "type" "imovx") | |
1945 | (const_string "SI") | |
0b5107cf | 1946 | (and (eq_attr "type" "imov") |
6ef67412 | 1947 | (and (eq_attr "alternative" "0,1,2") |
0b5107cf JH |
1948 | (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY") |
1949 | (const_int 0)))) | |
6ef67412 | 1950 | (const_string "SI") |
0b5107cf JH |
1951 | ;; Avoid partial register stalls when not using QImode arithmetic |
1952 | (and (eq_attr "type" "imov") | |
6ef67412 | 1953 | (and (eq_attr "alternative" "0,1,2") |
0b5107cf JH |
1954 | (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL") |
1955 | (const_int 0)) | |
1956 | (eq (symbol_ref "TARGET_QIMODE_MATH") | |
1957 | (const_int 0))))) | |
6ef67412 JH |
1958 | (const_string "SI") |
1959 | ] | |
1960 | (const_string "QI")))]) | |
e075ae69 RH |
1961 | |
1962 | (define_expand "reload_outqi" | |
1963 | [(parallel [(match_operand:QI 0 "" "=m") | |
1964 | (match_operand:QI 1 "register_operand" "r") | |
1965 | (match_operand:QI 2 "register_operand" "=&q")])] | |
1966 | "" | |
1967 | " | |
1968 | { | |
1969 | rtx op0, op1, op2; | |
1970 | op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; | |
886c62d1 | 1971 | |
e075ae69 RH |
1972 | if (reg_overlap_mentioned_p (op2, op0)) |
1973 | abort (); | |
1974 | if (! q_regs_operand (op1, QImode)) | |
1975 | { | |
1976 | emit_insn (gen_movqi (op2, op1)); | |
1977 | op1 = op2; | |
1978 | } | |
1979 | emit_insn (gen_movqi (op0, op1)); | |
1980 | DONE; | |
886c62d1 JVA |
1981 | }") |
1982 | ||
e075ae69 RH |
1983 | (define_insn "*swapqi" |
1984 | [(set (match_operand:QI 0 "register_operand" "+r") | |
1985 | (match_operand:QI 1 "register_operand" "+r")) | |
1986 | (set (match_dup 1) | |
1987 | (match_dup 0))] | |
1988 | "" | |
1989 | "xchg{b}\\t%1, %0" | |
1990 | [(set_attr "type" "imov") | |
1991 | (set_attr "pent_pair" "np") | |
6ef67412 JH |
1992 | (set_attr "mode" "QI") |
1993 | (set_attr "modrm" "0") | |
e075ae69 | 1994 | (set_attr "ppro_uops" "few")]) |
886c62d1 | 1995 | |
2f2a49e8 | 1996 | (define_expand "movstrictqi" |
4cbfbb1b | 1997 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) |
2f2a49e8 | 1998 | (match_operand:QI 1 "general_operand" ""))] |
e075ae69 | 1999 | "! TARGET_PARTIAL_REG_STALL" |
2f2a49e8 MM |
2000 | " |
2001 | { | |
2002 | /* Don't generate memory->memory moves, go through a register */ | |
e075ae69 RH |
2003 | if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) |
2004 | operands[1] = force_reg (QImode, operands[1]); | |
2f2a49e8 MM |
2005 | }") |
2006 | ||
e075ae69 | 2007 | (define_insn "*movstrictqi_1" |
2ae0f82c | 2008 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) |
c0f06344 | 2009 | (match_operand:QI 1 "general_operand" "*qn,m"))] |
e075ae69 RH |
2010 | "! TARGET_PARTIAL_REG_STALL |
2011 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" | |
2012 | "mov{b}\\t{%1, %0|%0, %1}" | |
6ef67412 JH |
2013 | [(set_attr "type" "imov") |
2014 | (set_attr "mode" "QI")]) | |
2015 | ||
2016 | (define_insn "*movstrictqi_xor" | |
5e6d6bf0 | 2017 | [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) |
6ef67412 JH |
2018 | (match_operand:QI 1 "const0_operand" "i")) |
2019 | (clobber (reg:CC 17))] | |
2020 | "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" | |
2021 | "xor{b}\\t{%0, %0|%0, %0}" | |
2022 | [(set_attr "type" "alu1") | |
2023 | (set_attr "mode" "QI") | |
2024 | (set_attr "length_immediate" "0")]) | |
e075ae69 RH |
2025 | |
2026 | (define_insn "*movsi_extv_1" | |
d2836273 JH |
2027 | [(set (match_operand:SI 0 "register_operand" "=R") |
2028 | (sign_extract:SI (match_operand:SI 1 "ext_register_operand" "Q") | |
e075ae69 RH |
2029 | (const_int 8) |
2030 | (const_int 8)))] | |
2031 | "" | |
2032 | "movs{bl|x}\\t{%h1, %0|%0, %h1}" | |
6ef67412 JH |
2033 | [(set_attr "type" "imovx") |
2034 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
2035 | |
2036 | (define_insn "*movhi_extv_1" | |
d2836273 JH |
2037 | [(set (match_operand:HI 0 "register_operand" "=R") |
2038 | (sign_extract:HI (match_operand:SI 1 "ext_register_operand" "Q") | |
e075ae69 RH |
2039 | (const_int 8) |
2040 | (const_int 8)))] | |
2041 | "" | |
2042 | "movs{bl|x}\\t{%h1, %k0|%k0, %h1}" | |
6ef67412 JH |
2043 | [(set_attr "type" "imovx") |
2044 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
2045 | |
2046 | (define_insn "*movqi_extv_1" | |
7c6b971d JH |
2047 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r") |
2048 | (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q") | |
e075ae69 RH |
2049 | (const_int 8) |
2050 | (const_int 8)))] | |
2051 | "" | |
886c62d1 JVA |
2052 | "* |
2053 | { | |
e075ae69 | 2054 | switch (get_attr_type (insn)) |
886c62d1 | 2055 | { |
e075ae69 RH |
2056 | case TYPE_IMOVX: |
2057 | return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\"; | |
2058 | default: | |
2059 | return \"mov{b}\\t{%h1, %0|%0, %h1}\"; | |
886c62d1 | 2060 | } |
e075ae69 RH |
2061 | }" |
2062 | [(set (attr "type") | |
2063 | (if_then_else (and (match_operand:QI 0 "register_operand" "") | |
2064 | (ior (not (match_operand:QI 0 "q_regs_operand" "")) | |
2065 | (ne (symbol_ref "TARGET_MOVX") | |
2066 | (const_int 0)))) | |
2067 | (const_string "imovx") | |
6ef67412 JH |
2068 | (const_string "imov"))) |
2069 | (set (attr "mode") | |
2070 | (if_then_else (eq_attr "type" "imovx") | |
2071 | (const_string "SI") | |
2072 | (const_string "QI")))]) | |
e075ae69 RH |
2073 | |
2074 | (define_insn "*movsi_extzv_1" | |
d2836273 JH |
2075 | [(set (match_operand:SI 0 "register_operand" "=R") |
2076 | (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") | |
e075ae69 RH |
2077 | (const_int 8) |
2078 | (const_int 8)))] | |
2079 | "" | |
2080 | "movz{bl|x}\\t{%h1, %0|%0, %h1}" | |
6ef67412 JH |
2081 | [(set_attr "type" "imovx") |
2082 | (set_attr "mode" "SI")]) | |
886c62d1 | 2083 | |
d2836273 JH |
2084 | (define_insn "*movqi_extzv_2" |
2085 | [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") | |
2086 | (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") | |
e075ae69 RH |
2087 | (const_int 8) |
2088 | (const_int 8)) 0))] | |
d2836273 | 2089 | "!TARGET_64BIT" |
f31fce3f JW |
2090 | "* |
2091 | { | |
e075ae69 | 2092 | switch (get_attr_type (insn)) |
f31fce3f | 2093 | { |
e075ae69 RH |
2094 | case TYPE_IMOVX: |
2095 | return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\"; | |
2096 | default: | |
2097 | return \"mov{b}\\t{%h1, %0|%0, %h1}\"; | |
2098 | } | |
2099 | }" | |
2100 | [(set (attr "type") | |
2101 | (if_then_else (and (match_operand:QI 0 "register_operand" "") | |
2102 | (ior (not (match_operand:QI 0 "q_regs_operand" "")) | |
2103 | (ne (symbol_ref "TARGET_MOVX") | |
2104 | (const_int 0)))) | |
2105 | (const_string "imovx") | |
6ef67412 JH |
2106 | (const_string "imov"))) |
2107 | (set (attr "mode") | |
2108 | (if_then_else (eq_attr "type" "imovx") | |
2109 | (const_string "SI") | |
2110 | (const_string "QI")))]) | |
e075ae69 | 2111 | |
d2836273 JH |
2112 | (define_insn "*movqi_extzv_2_rex64" |
2113 | [(set (match_operand:QI 0 "register_operand" "=Q,?R") | |
2114 | (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") | |
2115 | (const_int 8) | |
2116 | (const_int 8)) 0))] | |
2117 | "TARGET_64BIT" | |
2118 | "* | |
2119 | { | |
2120 | switch (get_attr_type (insn)) | |
2121 | { | |
2122 | case TYPE_IMOVX: | |
2123 | return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\"; | |
2124 | default: | |
2125 | return \"mov{b}\\t{%h1, %0|%0, %h1}\"; | |
2126 | } | |
2127 | }" | |
2128 | [(set (attr "type") | |
2129 | (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" "")) | |
2130 | (ne (symbol_ref "TARGET_MOVX") | |
2131 | (const_int 0))) | |
2132 | (const_string "imovx") | |
2133 | (const_string "imov"))) | |
2134 | (set (attr "mode") | |
2135 | (if_then_else (eq_attr "type" "imovx") | |
2136 | (const_string "SI") | |
2137 | (const_string "QI")))]) | |
2138 | ||
e075ae69 | 2139 | (define_insn "*movsi_insv_1" |
d2836273 | 2140 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") |
e075ae69 RH |
2141 | (const_int 8) |
2142 | (const_int 8)) | |
d2836273 JH |
2143 | (match_operand:SI 1 "nonimmediate_operand" "Qm"))] |
2144 | "!TARGET_64BIT" | |
2145 | "mov{b}\\t{%b1, %h0|%h0, %b1}" | |
2146 | [(set_attr "type" "imov") | |
2147 | (set_attr "mode" "QI")]) | |
2148 | ||
2149 | (define_insn "*movsi_insv_1_rex64" | |
2150 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") | |
2151 | (const_int 8) | |
2152 | (const_int 8)) | |
2153 | (match_operand:SI 1 "ext_register_operand" "Q"))] | |
2154 | "TARGET_64BIT" | |
e075ae69 | 2155 | "mov{b}\\t{%b1, %h0|%h0, %b1}" |
6ef67412 JH |
2156 | [(set_attr "type" "imov") |
2157 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
2158 | |
2159 | (define_insn "*movqi_insv_2" | |
d2836273 | 2160 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") |
e075ae69 RH |
2161 | (const_int 8) |
2162 | (const_int 8)) | |
d2836273 | 2163 | (and:SI (lshiftrt:SI (match_operand:SI 1 "ext_register_operand" "Q") |
e075ae69 RH |
2164 | (const_int 8)) |
2165 | (const_int 255)))] | |
2166 | "" | |
2167 | "mov{b}\\t{%h1, %h0|%h0, %h1}" | |
6ef67412 JH |
2168 | [(set_attr "type" "imov") |
2169 | (set_attr "mode" "QI")]) | |
f31fce3f | 2170 | |
e075ae69 | 2171 | (define_expand "movdi" |
4cbfbb1b | 2172 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
e075ae69 RH |
2173 | (match_operand:DI 1 "general_operand" ""))] |
2174 | "" | |
2175 | "ix86_expand_move (DImode, operands); DONE;") | |
f31fce3f | 2176 | |
e075ae69 RH |
2177 | (define_insn "*pushdi" |
2178 | [(set (match_operand:DI 0 "push_operand" "=<") | |
2c5a510c | 2179 | (match_operand:DI 1 "general_no_elim_operand" "riF*m"))] |
1e07edd3 | 2180 | "!TARGET_64BIT" |
e075ae69 | 2181 | "#") |
f31fce3f | 2182 | |
e075ae69 | 2183 | (define_insn "*movdi_2" |
915119a5 BS |
2184 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y") |
2185 | (match_operand:DI 1 "general_operand" "riFo,riF,*y,m"))] | |
1e07edd3 JH |
2186 | "!TARGET_64BIT |
2187 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" | |
915119a5 BS |
2188 | "@ |
2189 | # | |
2190 | # | |
2191 | movq\\t{%1, %0|%0, %1} | |
2192 | movq\\t{%1, %0|%0, %1}" | |
2193 | [(set_attr "type" "*,*,mmx,mmx")]) | |
dc0f0eb8 | 2194 | |
e075ae69 RH |
2195 | (define_split |
2196 | [(set (match_operand:DI 0 "push_operand" "") | |
2197 | (match_operand:DI 1 "general_operand" ""))] | |
1e07edd3 | 2198 | "reload_completed && ! MMX_REG_P (operands[1]) && !TARGET_64BIT" |
2450a057 JH |
2199 | [(const_int 0)] |
2200 | "if (!ix86_split_long_move (operands)) abort (); DONE;") | |
f31fce3f | 2201 | |
e075ae69 | 2202 | ;; %%% This multiword shite has got to go. |
e075ae69 | 2203 | (define_split |
c76aab11 | 2204 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
e075ae69 | 2205 | (match_operand:DI 1 "general_operand" ""))] |
915119a5 | 2206 | "reload_completed && ! MMX_REG_P (operands[0]) && ! MMX_REG_P (operands[1])" |
2450a057 JH |
2207 | [(set (match_dup 2) (match_dup 5)) |
2208 | (set (match_dup 3) (match_dup 6))] | |
2209 | "if (ix86_split_long_move (operands)) DONE;") | |
e075ae69 | 2210 | |
0be5d99f | 2211 | (define_expand "movsf" |
4cbfbb1b | 2212 | [(set (match_operand:SF 0 "nonimmediate_operand" "") |
0be5d99f MM |
2213 | (match_operand:SF 1 "general_operand" ""))] |
2214 | "" | |
e075ae69 RH |
2215 | "ix86_expand_move (SFmode, operands); DONE;") |
2216 | ||
2217 | (define_insn "*pushsf" | |
446988df | 2218 | [(set (match_operand:SF 0 "push_operand" "=<,<,<") |
c6e95f34 | 2219 | (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))] |
e075ae69 RH |
2220 | "" |
2221 | "* | |
0be5d99f | 2222 | { |
e075ae69 | 2223 | switch (which_alternative) |
0be5d99f | 2224 | { |
e075ae69 RH |
2225 | case 0: |
2226 | /* %%% We loose REG_DEAD notes for controling pops if we split late. */ | |
2227 | operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx); | |
2228 | operands[2] = stack_pointer_rtx; | |
2229 | operands[3] = GEN_INT (4); | |
2230 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 2231 | return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; |
e075ae69 | 2232 | else |
7ebb782b | 2233 | return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; |
0bb6c81b | 2234 | |
e075ae69 RH |
2235 | case 1: |
2236 | return \"push{l}\\t%1\"; | |
446988df JH |
2237 | case 2: |
2238 | return \"#\"; | |
e075ae69 RH |
2239 | |
2240 | default: | |
2241 | abort (); | |
0bb6c81b | 2242 | } |
e075ae69 | 2243 | }" |
446988df JH |
2244 | [(set_attr "type" "multi,push,multi") |
2245 | (set_attr "mode" "SF,SI,SF")]) | |
0be5d99f | 2246 | |
d7a29404 JH |
2247 | (define_split |
2248 | [(set (match_operand:SF 0 "push_operand" "") | |
2249 | (match_operand:SF 1 "memory_operand" ""))] | |
2250 | "reload_completed | |
2251 | && GET_CODE (operands[1]) == MEM | |
2252 | && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF | |
2253 | && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))" | |
2254 | [(set (match_dup 0) | |
2255 | (match_dup 1))] | |
2256 | "operands[1] = get_pool_constant (XEXP (operands[1], 0));") | |
2257 | ||
2258 | ||
e075ae69 RH |
2259 | ;; %%% Kill this when call knows how to work this out. |
2260 | (define_split | |
2261 | [(set (match_operand:SF 0 "push_operand" "") | |
2262 | (match_operand:SF 1 "register_operand" ""))] | |
446988df | 2263 | "ANY_FP_REGNO_P (REGNO (operands[1]))" |
e075ae69 RH |
2264 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4))) |
2265 | (set (mem:SF (reg:SI 7)) (match_dup 1))]) | |
2266 | ||
2267 | (define_insn "*movsf_1" | |
2b04e52b JH |
2268 | [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m") |
2269 | (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))] | |
d7a29404 JH |
2270 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) |
2271 | && (reload_in_progress || reload_completed | |
2272 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
2273 | || memory_operand (operands[0], SFmode))" | |
886c62d1 JVA |
2274 | "* |
2275 | { | |
e075ae69 | 2276 | switch (which_alternative) |
886c62d1 | 2277 | { |
e075ae69 | 2278 | case 0: |
0c174a68 AB |
2279 | if (REG_P (operands[1]) |
2280 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 2281 | return \"fstp\\t%y0\"; |
e075ae69 | 2282 | else if (STACK_TOP_P (operands[0])) |
7ebb782b | 2283 | return \"fld%z1\\t%y1\"; |
886c62d1 | 2284 | else |
7ebb782b | 2285 | return \"fst\\t%y0\"; |
886c62d1 | 2286 | |
e075ae69 RH |
2287 | case 1: |
2288 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 2289 | return \"fstp%z0\\t%y0\"; |
886c62d1 | 2290 | else |
7ebb782b | 2291 | return \"fst%z0\\t%y0\"; |
886c62d1 | 2292 | |
e075ae69 RH |
2293 | case 2: |
2294 | switch (standard_80387_constant_p (operands[1])) | |
2295 | { | |
2296 | case 1: | |
2297 | return \"fldz\"; | |
2298 | case 2: | |
2299 | return \"fld1\"; | |
2300 | } | |
2301 | abort(); | |
886c62d1 | 2302 | |
e075ae69 RH |
2303 | case 3: |
2304 | case 4: | |
e075ae69 | 2305 | return \"mov{l}\\t{%1, %0|%0, %1}\"; |
446988df | 2306 | case 5: |
2b04e52b | 2307 | return \"pxor\\t%0, %0\"; |
446988df | 2308 | case 6: |
2b04e52b | 2309 | if (TARGET_PARTIAL_REG_DEPENDENCY) |
79005df5 | 2310 | return \"movaps\\t{%1, %0|%0, %1}\"; |
2b04e52b JH |
2311 | else |
2312 | return \"movss\\t{%1, %0|%0, %1}\"; | |
2313 | case 7: | |
2314 | case 8: | |
446988df | 2315 | return \"movss\\t{%1, %0|%0, %1}\"; |
886c62d1 | 2316 | |
e075ae69 RH |
2317 | default: |
2318 | abort(); | |
2319 | } | |
2ae0f82c | 2320 | }" |
2b04e52b JH |
2321 | [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse") |
2322 | (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")]) | |
d7a29404 | 2323 | |
a4414093 | 2324 | (define_insn "*swapsf" |
e075ae69 RH |
2325 | [(set (match_operand:SF 0 "register_operand" "+f") |
2326 | (match_operand:SF 1 "register_operand" "+f")) | |
0be5d99f MM |
2327 | (set (match_dup 1) |
2328 | (match_dup 0))] | |
446988df | 2329 | "reload_completed || !TARGET_SSE2" |
0be5d99f MM |
2330 | "* |
2331 | { | |
2332 | if (STACK_TOP_P (operands[0])) | |
e075ae69 | 2333 | return \"fxch\\t%1\"; |
0be5d99f | 2334 | else |
e075ae69 RH |
2335 | return \"fxch\\t%0\"; |
2336 | }" | |
6ef67412 JH |
2337 | [(set_attr "type" "fxch") |
2338 | (set_attr "mode" "SF")]) | |
0be5d99f | 2339 | |
e075ae69 | 2340 | (define_expand "movdf" |
4cbfbb1b | 2341 | [(set (match_operand:DF 0 "nonimmediate_operand" "") |
e075ae69 RH |
2342 | (match_operand:DF 1 "general_operand" ""))] |
2343 | "" | |
2344 | "ix86_expand_move (DFmode, operands); DONE;") | |
55953cea | 2345 | |
8fcaaa80 JH |
2346 | ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. |
2347 | ;; Size of pushdf using integer insturctions is 2+2*memory operand size | |
2348 | ;; On the average, pushdf using integers can be still shorter. Allow this | |
2349 | ;; pattern for optimize_size too. | |
2350 | ||
0b5107cf | 2351 | (define_insn "*pushdf_nointeger" |
446988df | 2352 | [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") |
c6e95f34 | 2353 | (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))] |
0b5107cf JH |
2354 | "!TARGET_INTEGER_DFMODE_MOVES" |
2355 | "* | |
2356 | { | |
2357 | switch (which_alternative) | |
2358 | { | |
2359 | case 0: | |
2360 | /* %%% We loose REG_DEAD notes for controling pops if we split late. */ | |
2361 | operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx); | |
2362 | operands[2] = stack_pointer_rtx; | |
2363 | operands[3] = GEN_INT (8); | |
2364 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2365 | return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; | |
2366 | else | |
2367 | return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; | |
2368 | ||
2369 | case 1: | |
2370 | case 2: | |
446988df | 2371 | case 3: |
0b5107cf JH |
2372 | return \"#\"; |
2373 | ||
2374 | default: | |
2375 | abort (); | |
2376 | } | |
2377 | }" | |
6ef67412 | 2378 | [(set_attr "type" "multi") |
446988df | 2379 | (set_attr "mode" "DF,SI,SI,DF")]) |
0b5107cf JH |
2380 | |
2381 | (define_insn "*pushdf_integer" | |
446988df JH |
2382 | [(set (match_operand:DF 0 "push_operand" "=<,<,<") |
2383 | (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))] | |
0b5107cf | 2384 | "TARGET_INTEGER_DFMODE_MOVES" |
f31fce3f JW |
2385 | "* |
2386 | { | |
e075ae69 | 2387 | switch (which_alternative) |
f31fce3f | 2388 | { |
e075ae69 RH |
2389 | case 0: |
2390 | /* %%% We loose REG_DEAD notes for controling pops if we split late. */ | |
2391 | operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx); | |
2392 | operands[2] = stack_pointer_rtx; | |
2393 | operands[3] = GEN_INT (8); | |
2394 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 2395 | return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; |
f31fce3f | 2396 | else |
7ebb782b | 2397 | return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; |
dc0f0eb8 | 2398 | |
e075ae69 | 2399 | case 1: |
446988df | 2400 | case 2: |
e075ae69 | 2401 | return \"#\"; |
dc0f0eb8 | 2402 | |
e075ae69 RH |
2403 | default: |
2404 | abort (); | |
2405 | } | |
2406 | }" | |
6ef67412 | 2407 | [(set_attr "type" "multi") |
446988df | 2408 | (set_attr "mode" "DF,SI,DF")]) |
f31fce3f | 2409 | |
e075ae69 | 2410 | ;; %%% Kill this when call knows how to work this out. |
f72b27a5 JH |
2411 | (define_split |
2412 | [(set (match_operand:DF 0 "push_operand" "") | |
e075ae69 | 2413 | (match_operand:DF 1 "register_operand" ""))] |
446988df | 2414 | "reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))" |
e075ae69 RH |
2415 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8))) |
2416 | (set (mem:DF (reg:SI 7)) (match_dup 1))] | |
f72b27a5 | 2417 | "") |
f31fce3f | 2418 | |
e075ae69 RH |
2419 | (define_split |
2420 | [(set (match_operand:DF 0 "push_operand" "") | |
0be5d99f | 2421 | (match_operand:DF 1 "general_operand" ""))] |
e075ae69 | 2422 | "reload_completed" |
2450a057 JH |
2423 | [(const_int 0)] |
2424 | "if (!ix86_split_long_move (operands)) abort (); DONE;") | |
0be5d99f | 2425 | |
8fcaaa80 JH |
2426 | ;; Moving is usually shorter when only FP registers are used. This separate |
2427 | ;; movdf pattern avoids the use of integer registers for FP operations | |
2428 | ;; when optimizing for size. | |
2429 | ||
2430 | (define_insn "*movdf_nointeger" | |
2b04e52b JH |
2431 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m") |
2432 | (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))] | |
8fcaaa80 | 2433 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) |
0b5107cf | 2434 | && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES) |
d7a29404 JH |
2435 | && (reload_in_progress || reload_completed |
2436 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
2437 | || memory_operand (operands[0], DFmode))" | |
8fcaaa80 JH |
2438 | "* |
2439 | { | |
2440 | switch (which_alternative) | |
2441 | { | |
2442 | case 0: | |
2443 | if (REG_P (operands[1]) | |
2444 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2445 | return \"fstp\\t%y0\"; | |
2446 | else if (STACK_TOP_P (operands[0])) | |
2447 | return \"fld%z1\\t%y1\"; | |
2448 | else | |
2449 | return \"fst\\t%y0\"; | |
2450 | ||
2451 | case 1: | |
2452 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2453 | return \"fstp%z0\\t%y0\"; | |
2454 | else | |
2455 | return \"fst%z0\\t%y0\"; | |
2456 | ||
2457 | case 2: | |
2458 | switch (standard_80387_constant_p (operands[1])) | |
2459 | { | |
2460 | case 1: | |
2461 | return \"fldz\"; | |
2462 | case 2: | |
2463 | return \"fld1\"; | |
2464 | } | |
2465 | abort(); | |
2466 | ||
2467 | case 3: | |
2468 | case 4: | |
2469 | return \"#\"; | |
446988df | 2470 | case 5: |
2b04e52b | 2471 | return \"pxor\\t%0, %0\"; |
446988df | 2472 | case 6: |
2b04e52b | 2473 | if (TARGET_PARTIAL_REG_DEPENDENCY) |
79005df5 | 2474 | return \"movapd\\t{%1, %0|%0, %1}\"; |
2b04e52b JH |
2475 | else |
2476 | return \"movsd\\t{%1, %0|%0, %1}\"; | |
2477 | case 7: | |
2478 | case 8: | |
2479 | return \"movsd\\t{%1, %0|%0, %1}\"; | |
8fcaaa80 JH |
2480 | |
2481 | default: | |
2482 | abort(); | |
2483 | } | |
2484 | }" | |
2b04e52b JH |
2485 | [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse") |
2486 | (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")]) | |
8fcaaa80 JH |
2487 | |
2488 | (define_insn "*movdf_integer" | |
2b04e52b JH |
2489 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m") |
2490 | (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))] | |
8fcaaa80 | 2491 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) |
0b5107cf | 2492 | && !optimize_size && TARGET_INTEGER_DFMODE_MOVES |
d7a29404 JH |
2493 | && (reload_in_progress || reload_completed |
2494 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
2495 | || memory_operand (operands[0], DFmode))" | |
886c62d1 JVA |
2496 | "* |
2497 | { | |
e075ae69 | 2498 | switch (which_alternative) |
886c62d1 | 2499 | { |
e075ae69 | 2500 | case 0: |
0c174a68 AB |
2501 | if (REG_P (operands[1]) |
2502 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 2503 | return \"fstp\\t%y0\"; |
e075ae69 | 2504 | else if (STACK_TOP_P (operands[0])) |
7ebb782b | 2505 | return \"fld%z1\\t%y1\"; |
886c62d1 | 2506 | else |
7ebb782b | 2507 | return \"fst\\t%y0\"; |
886c62d1 | 2508 | |
e075ae69 RH |
2509 | case 1: |
2510 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 2511 | return \"fstp%z0\\t%y0\"; |
886c62d1 | 2512 | else |
7ebb782b | 2513 | return \"fst%z0\\t%y0\"; |
886c62d1 | 2514 | |
e075ae69 RH |
2515 | case 2: |
2516 | switch (standard_80387_constant_p (operands[1])) | |
2517 | { | |
2518 | case 1: | |
2519 | return \"fldz\"; | |
2520 | case 2: | |
2521 | return \"fld1\"; | |
2522 | } | |
2523 | abort(); | |
886c62d1 | 2524 | |
e075ae69 RH |
2525 | case 3: |
2526 | case 4: | |
e075ae69 | 2527 | return \"#\"; |
886c62d1 | 2528 | |
446988df | 2529 | case 5: |
2b04e52b | 2530 | return \"pxor\\t%0, %0\"; |
446988df | 2531 | case 6: |
2b04e52b JH |
2532 | if (TARGET_PARTIAL_REG_DEPENDENCY) |
2533 | return \"movapd\\t{%1, %0|%0, %1}\"; | |
2534 | else | |
2535 | return \"movsd\\t{%1, %0|%0, %1}\"; | |
2536 | case 7: | |
2537 | case 8: | |
446988df JH |
2538 | return \"movsd\\t{%1, %0|%0, %1}\"; |
2539 | ||
e075ae69 RH |
2540 | default: |
2541 | abort(); | |
2542 | } | |
2ae0f82c | 2543 | }" |
2b04e52b JH |
2544 | [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse") |
2545 | (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")]) | |
2ae0f82c | 2546 | |
e075ae69 RH |
2547 | (define_split |
2548 | [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
2549 | (match_operand:DF 1 "general_operand" ""))] | |
2550 | "reload_completed | |
2551 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) | |
446988df | 2552 | && ! (ANY_FP_REG_P (operands[0]) || |
e075ae69 | 2553 | (GET_CODE (operands[0]) == SUBREG |
446988df JH |
2554 | && ANY_FP_REG_P (SUBREG_REG (operands[0])))) |
2555 | && ! (ANY_FP_REG_P (operands[1]) || | |
e075ae69 | 2556 | (GET_CODE (operands[1]) == SUBREG |
446988df | 2557 | && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" |
2450a057 JH |
2558 | [(set (match_dup 2) (match_dup 5)) |
2559 | (set (match_dup 3) (match_dup 6))] | |
2560 | "if (ix86_split_long_move (operands)) DONE;") | |
886c62d1 | 2561 | |
a4414093 | 2562 | (define_insn "*swapdf" |
e075ae69 RH |
2563 | [(set (match_operand:DF 0 "register_operand" "+f") |
2564 | (match_operand:DF 1 "register_operand" "+f")) | |
0be5d99f MM |
2565 | (set (match_dup 1) |
2566 | (match_dup 0))] | |
446988df | 2567 | "reload_completed || !TARGET_SSE2" |
0be5d99f MM |
2568 | "* |
2569 | { | |
2570 | if (STACK_TOP_P (operands[0])) | |
e075ae69 | 2571 | return \"fxch\\t%1\"; |
0be5d99f | 2572 | else |
e075ae69 RH |
2573 | return \"fxch\\t%0\"; |
2574 | }" | |
6ef67412 JH |
2575 | [(set_attr "type" "fxch") |
2576 | (set_attr "mode" "DF")]) | |
e075ae69 RH |
2577 | |
2578 | (define_expand "movxf" | |
4cbfbb1b | 2579 | [(set (match_operand:XF 0 "nonimmediate_operand" "") |
e075ae69 | 2580 | (match_operand:XF 1 "general_operand" ""))] |
1e07edd3 | 2581 | "!TARGET_64BIT" |
e075ae69 | 2582 | "ix86_expand_move (XFmode, operands); DONE;") |
0be5d99f | 2583 | |
2b589241 JH |
2584 | (define_expand "movtf" |
2585 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
2586 | (match_operand:TF 1 "general_operand" ""))] | |
2587 | "" | |
2588 | "ix86_expand_move (TFmode, operands); DONE;") | |
2589 | ||
8fcaaa80 JH |
2590 | ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. |
2591 | ;; Size of pushdf using integer insturctions is 3+3*memory operand size | |
2592 | ;; Pushing using integer instructions is longer except for constants | |
2593 | ;; and direct memory references. | |
2594 | ;; (assuming that any given constant is pushed only once, but this ought to be | |
2595 | ;; handled elsewhere). | |
2596 | ||
2597 | (define_insn "*pushxf_nointeger" | |
1e07edd3 | 2598 | [(set (match_operand:XF 0 "push_operand" "=X,X,X") |
2c5a510c | 2599 | (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))] |
1e07edd3 | 2600 | "optimize_size && !TARGET_64BIT" |
8fcaaa80 JH |
2601 | "* |
2602 | { | |
2603 | switch (which_alternative) | |
2604 | { | |
2605 | case 0: | |
2606 | /* %%% We loose REG_DEAD notes for controling pops if we split late. */ | |
2607 | operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx); | |
2608 | operands[2] = stack_pointer_rtx; | |
2609 | operands[3] = GEN_INT (12); | |
2610 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2611 | return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; | |
2612 | else | |
2613 | return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; | |
2614 | ||
2615 | case 1: | |
2616 | case 2: | |
2617 | return \"#\"; | |
2618 | ||
2619 | default: | |
2620 | abort (); | |
2621 | } | |
2622 | }" | |
6ef67412 JH |
2623 | [(set_attr "type" "multi") |
2624 | (set_attr "mode" "XF,SI,SI")]) | |
8fcaaa80 | 2625 | |
2b589241 JH |
2626 | (define_insn "*pushtf_nointeger" |
2627 | [(set (match_operand:TF 0 "push_operand" "=<,<,<") | |
2628 | (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))] | |
2629 | "optimize_size" | |
2630 | "* | |
2631 | { | |
2632 | switch (which_alternative) | |
2633 | { | |
2634 | case 0: | |
2635 | /* %%% We loose REG_DEAD notes for controling pops if we split late. */ | |
2636 | operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx); | |
2637 | operands[2] = stack_pointer_rtx; | |
2638 | operands[3] = GEN_INT (16); | |
2639 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2640 | return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; | |
2641 | else | |
2642 | return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; | |
2643 | ||
2644 | case 1: | |
2645 | case 2: | |
2646 | return \"#\"; | |
2647 | ||
2648 | default: | |
2649 | abort (); | |
2650 | } | |
2651 | }" | |
2652 | [(set_attr "type" "multi") | |
2653 | (set_attr "mode" "XF,SI,SI")]) | |
2654 | ||
8fcaaa80 | 2655 | (define_insn "*pushxf_integer" |
2450a057 | 2656 | [(set (match_operand:XF 0 "push_operand" "=<,<") |
1e07edd3 JH |
2657 | (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))] |
2658 | "!optimize_size && !TARGET_64BIT" | |
f31fce3f JW |
2659 | "* |
2660 | { | |
8fcaaa80 JH |
2661 | switch (which_alternative) |
2662 | { | |
2663 | case 0: | |
2664 | /* %%% We loose REG_DEAD notes for controling pops if we split late. */ | |
2665 | operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx); | |
2666 | operands[2] = stack_pointer_rtx; | |
2667 | operands[3] = GEN_INT (12); | |
2668 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2669 | return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; | |
2670 | else | |
2671 | return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; | |
2672 | ||
2673 | case 1: | |
2674 | return \"#\"; | |
2675 | ||
2676 | default: | |
2677 | abort (); | |
2678 | } | |
e075ae69 | 2679 | }" |
6ef67412 JH |
2680 | [(set_attr "type" "multi") |
2681 | (set_attr "mode" "XF,SI")]) | |
f31fce3f | 2682 | |
2b589241 JH |
2683 | (define_insn "*pushtf_integer" |
2684 | [(set (match_operand:TF 0 "push_operand" "=<,<") | |
2685 | (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))] | |
2686 | "!optimize_size" | |
2687 | "* | |
2688 | { | |
2689 | switch (which_alternative) | |
2690 | { | |
2691 | case 0: | |
2692 | /* %%% We loose REG_DEAD notes for controling pops if we split late. */ | |
2693 | operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx); | |
2694 | operands[2] = stack_pointer_rtx; | |
2695 | operands[3] = GEN_INT (16); | |
2696 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2697 | return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; | |
2698 | else | |
2699 | return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; | |
2700 | ||
2701 | case 1: | |
2702 | return \"#\"; | |
2703 | ||
2704 | default: | |
2705 | abort (); | |
2706 | } | |
2707 | }" | |
2708 | [(set_attr "type" "multi") | |
2709 | (set_attr "mode" "XF,SI")]) | |
2710 | ||
2450a057 | 2711 | (define_split |
2b589241 JH |
2712 | [(set (match_operand 0 "push_operand" "") |
2713 | (match_operand 1 "general_operand" ""))] | |
2450a057 | 2714 | "reload_completed |
2b589241 JH |
2715 | && (GET_MODE (operands[0]) == XFmode |
2716 | || GET_MODE (operands[0]) == TFmode | |
2717 | || GET_MODE (operands[0]) == DFmode) | |
446988df | 2718 | && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))" |
2450a057 JH |
2719 | [(const_int 0)] |
2720 | "if (!ix86_split_long_move (operands)) abort (); DONE;") | |
2721 | ||
f72b27a5 JH |
2722 | (define_split |
2723 | [(set (match_operand:XF 0 "push_operand" "") | |
e075ae69 | 2724 | (match_operand:XF 1 "register_operand" ""))] |
446988df | 2725 | "ANY_FP_REGNO_P (REGNO (operands[1]))" |
e075ae69 RH |
2726 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12))) |
2727 | (set (mem:XF (reg:SI 7)) (match_dup 1))]) | |
f31fce3f | 2728 | |
2b589241 JH |
2729 | (define_split |
2730 | [(set (match_operand:TF 0 "push_operand" "") | |
2731 | (match_operand:TF 1 "register_operand" ""))] | |
446988df | 2732 | "ANY_FP_REGNO_P (REGNO (operands[1]))" |
2b589241 JH |
2733 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16))) |
2734 | (set (mem:TF (reg:SI 7)) (match_dup 1))]) | |
2735 | ||
8fcaaa80 JH |
2736 | ;; Do not use integer registers when optimizing for size |
2737 | (define_insn "*movxf_nointeger" | |
2738 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o") | |
2739 | (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))] | |
2740 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) | |
1e07edd3 | 2741 | && !TARGET_64BIT |
d7a29404 JH |
2742 | && optimize_size |
2743 | && (reload_in_progress || reload_completed | |
2744 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
2745 | || memory_operand (operands[0], XFmode))" | |
8fcaaa80 | 2746 | "* |
0be5d99f | 2747 | { |
8fcaaa80 JH |
2748 | switch (which_alternative) |
2749 | { | |
2750 | case 0: | |
2751 | if (REG_P (operands[1]) | |
2752 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2753 | return \"fstp\\t%y0\"; | |
2754 | else if (STACK_TOP_P (operands[0])) | |
2755 | return \"fld%z1\\t%y1\"; | |
2756 | else | |
2757 | return \"fst\\t%y0\"; | |
0be5d99f | 2758 | |
8fcaaa80 JH |
2759 | case 1: |
2760 | /* There is no non-popping store to memory for XFmode. So if | |
2761 | we need one, follow the store with a load. */ | |
2762 | if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2763 | return \"fstp%z0\\t%y0\;fld%z0\\t%y0\"; | |
2764 | else | |
2765 | return \"fstp%z0\\t%y0\"; | |
2766 | ||
2767 | case 2: | |
2768 | switch (standard_80387_constant_p (operands[1])) | |
2769 | { | |
2770 | case 1: | |
2771 | return \"fldz\"; | |
2772 | case 2: | |
2773 | return \"fld1\"; | |
2774 | } | |
2775 | break; | |
2776 | ||
2777 | case 3: case 4: | |
2778 | return \"#\"; | |
2779 | } | |
2780 | abort(); | |
2781 | }" | |
6ef67412 JH |
2782 | [(set_attr "type" "fmov,fmov,fmov,multi,multi") |
2783 | (set_attr "mode" "XF,XF,XF,SI,SI")]) | |
8fcaaa80 | 2784 | |
2b589241 JH |
2785 | (define_insn "*movtf_nointeger" |
2786 | [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o") | |
2787 | (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))] | |
2788 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) | |
2789 | && optimize_size | |
2790 | && (reload_in_progress || reload_completed | |
2791 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
2792 | || memory_operand (operands[0], TFmode))" | |
2793 | "* | |
2794 | { | |
2795 | switch (which_alternative) | |
2796 | { | |
2797 | case 0: | |
2798 | if (REG_P (operands[1]) | |
2799 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2800 | return \"fstp\\t%y0\"; | |
2801 | else if (STACK_TOP_P (operands[0])) | |
2802 | return \"fld%z1\\t%y1\"; | |
2803 | else | |
2804 | return \"fst\\t%y0\"; | |
2805 | ||
2806 | case 1: | |
2807 | /* There is no non-popping store to memory for XFmode. So if | |
2808 | we need one, follow the store with a load. */ | |
2809 | if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2810 | return \"fstp%z0\\t%y0\;fld%z0\\t%y0\"; | |
2811 | else | |
2812 | return \"fstp%z0\\t%y0\"; | |
2813 | ||
2814 | case 2: | |
2815 | switch (standard_80387_constant_p (operands[1])) | |
2816 | { | |
2817 | case 1: | |
2818 | return \"fldz\"; | |
2819 | case 2: | |
2820 | return \"fld1\"; | |
2821 | } | |
2822 | break; | |
2823 | ||
2824 | case 3: case 4: | |
2825 | return \"#\"; | |
2826 | } | |
2827 | abort(); | |
2828 | }" | |
2829 | [(set_attr "type" "fmov,fmov,fmov,multi,multi") | |
2830 | (set_attr "mode" "XF,XF,XF,SI,SI")]) | |
2831 | ||
8fcaaa80 JH |
2832 | (define_insn "*movxf_integer" |
2833 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o") | |
2834 | (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))] | |
2835 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) | |
1e07edd3 | 2836 | && !TARGET_64BIT |
d7a29404 JH |
2837 | && !optimize_size |
2838 | && (reload_in_progress || reload_completed | |
2839 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
2840 | || memory_operand (operands[0], XFmode))" | |
4fb21e90 JVA |
2841 | "* |
2842 | { | |
e075ae69 | 2843 | switch (which_alternative) |
4fb21e90 | 2844 | { |
e075ae69 | 2845 | case 0: |
0c174a68 AB |
2846 | if (REG_P (operands[1]) |
2847 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 2848 | return \"fstp\\t%y0\"; |
e075ae69 | 2849 | else if (STACK_TOP_P (operands[0])) |
7ebb782b | 2850 | return \"fld%z1\\t%y1\"; |
4fb21e90 | 2851 | else |
7ebb782b | 2852 | return \"fst\\t%y0\"; |
4fb21e90 | 2853 | |
e075ae69 RH |
2854 | case 1: |
2855 | /* There is no non-popping store to memory for XFmode. So if | |
2856 | we need one, follow the store with a load. */ | |
2857 | if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 2858 | return \"fstp%z0\\t%y0\;fld%z0\\t%y0\"; |
e075ae69 | 2859 | else |
7ebb782b | 2860 | return \"fstp%z0\\t%y0\"; |
2f17722a | 2861 | |
e075ae69 RH |
2862 | case 2: |
2863 | switch (standard_80387_constant_p (operands[1])) | |
2864 | { | |
2865 | case 1: | |
2866 | return \"fldz\"; | |
2867 | case 2: | |
2868 | return \"fld1\"; | |
2869 | } | |
2870 | break; | |
467403ca RH |
2871 | |
2872 | case 3: case 4: | |
2873 | return \"#\"; | |
4fb21e90 | 2874 | } |
e075ae69 RH |
2875 | abort(); |
2876 | }" | |
6ef67412 JH |
2877 | [(set_attr "type" "fmov,fmov,fmov,multi,multi") |
2878 | (set_attr "mode" "XF,XF,XF,SI,SI")]) | |
4fb21e90 | 2879 | |
2b589241 JH |
2880 | (define_insn "*movtf_integer" |
2881 | [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o") | |
2882 | (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))] | |
2883 | "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) | |
2884 | && !optimize_size | |
2885 | && (reload_in_progress || reload_completed | |
2886 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
2887 | || memory_operand (operands[0], TFmode))" | |
2888 | "* | |
2889 | { | |
2890 | switch (which_alternative) | |
2891 | { | |
2892 | case 0: | |
2893 | if (REG_P (operands[1]) | |
2894 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2895 | return \"fstp\\t%y0\"; | |
2896 | else if (STACK_TOP_P (operands[0])) | |
2897 | return \"fld%z1\\t%y1\"; | |
2898 | else | |
2899 | return \"fst\\t%y0\"; | |
2900 | ||
2901 | case 1: | |
2902 | /* There is no non-popping store to memory for XFmode. So if | |
2903 | we need one, follow the store with a load. */ | |
2904 | if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
2905 | return \"fstp%z0\\t%y0\;fld%z0\\t%y0\"; | |
2906 | else | |
2907 | return \"fstp%z0\\t%y0\"; | |
2908 | ||
2909 | case 2: | |
2910 | switch (standard_80387_constant_p (operands[1])) | |
2911 | { | |
2912 | case 1: | |
2913 | return \"fldz\"; | |
2914 | case 2: | |
2915 | return \"fld1\"; | |
2916 | } | |
2917 | break; | |
2918 | ||
2919 | case 3: case 4: | |
2920 | return \"#\"; | |
2921 | } | |
2922 | abort(); | |
2923 | }" | |
2924 | [(set_attr "type" "fmov,fmov,fmov,multi,multi") | |
2925 | (set_attr "mode" "XF,XF,XF,SI,SI")]) | |
2926 | ||
467403ca | 2927 | (define_split |
2b589241 JH |
2928 | [(set (match_operand 0 "nonimmediate_operand" "") |
2929 | (match_operand 1 "general_operand" ""))] | |
2450a057 | 2930 | "reload_completed |
8fcaaa80 | 2931 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) |
2b589241 | 2932 | && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode) |
446988df | 2933 | && ! (ANY_FP_REG_P (operands[0]) || |
8fcaaa80 | 2934 | (GET_CODE (operands[0]) == SUBREG |
446988df JH |
2935 | && ANY_FP_REG_P (SUBREG_REG (operands[0])))) |
2936 | && ! (ANY_FP_REG_P (operands[1]) || | |
8fcaaa80 | 2937 | (GET_CODE (operands[1]) == SUBREG |
446988df | 2938 | && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" |
2450a057 JH |
2939 | [(set (match_dup 2) (match_dup 5)) |
2940 | (set (match_dup 3) (match_dup 6)) | |
2941 | (set (match_dup 4) (match_dup 7))] | |
2942 | "if (ix86_split_long_move (operands)) DONE;") | |
467403ca | 2943 | |
d7a29404 | 2944 | (define_split |
2b589241 JH |
2945 | [(set (match_operand 0 "register_operand" "") |
2946 | (match_operand 1 "memory_operand" ""))] | |
d7a29404 JH |
2947 | "reload_completed |
2948 | && GET_CODE (operands[1]) == MEM | |
2b04e52b JH |
2949 | && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode |
2950 | || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode) | |
d7a29404 JH |
2951 | && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF |
2952 | && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)) | |
2b04e52b JH |
2953 | && (!(SSE_REG_P (operands[0]) || |
2954 | (GET_CODE (operands[0]) == SUBREG | |
2955 | && SSE_REG_P (SUBREG_REG (operands[0])))) | |
2956 | || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0)))) | |
2957 | && (!(FP_REG_P (operands[0]) || | |
2958 | (GET_CODE (operands[0]) == SUBREG | |
2959 | && FP_REG_P (SUBREG_REG (operands[0])))) | |
2960 | || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))" | |
d7a29404 JH |
2961 | [(set (match_dup 0) |
2962 | (match_dup 1))] | |
2963 | "operands[1] = get_pool_constant (XEXP (operands[1], 0));") | |
2964 | ||
e075ae69 RH |
2965 | (define_insn "swapxf" |
2966 | [(set (match_operand:XF 0 "register_operand" "+f") | |
2967 | (match_operand:XF 1 "register_operand" "+f")) | |
0be5d99f MM |
2968 | (set (match_dup 1) |
2969 | (match_dup 0))] | |
2970 | "" | |
2971 | "* | |
2972 | { | |
2973 | if (STACK_TOP_P (operands[0])) | |
e075ae69 | 2974 | return \"fxch\\t%1\"; |
0be5d99f | 2975 | else |
e075ae69 RH |
2976 | return \"fxch\\t%0\"; |
2977 | }" | |
0b5107cf | 2978 | [(set_attr "type" "fxch") |
6ef67412 | 2979 | (set_attr "mode" "XF")]) |
2b589241 JH |
2980 | |
2981 | (define_insn "swaptf" | |
2982 | [(set (match_operand:TF 0 "register_operand" "+f") | |
2983 | (match_operand:TF 1 "register_operand" "+f")) | |
2984 | (set (match_dup 1) | |
2985 | (match_dup 0))] | |
2986 | "" | |
2987 | "* | |
2988 | { | |
2989 | if (STACK_TOP_P (operands[0])) | |
2990 | return \"fxch\\t%1\"; | |
2991 | else | |
2992 | return \"fxch\\t%0\"; | |
2993 | }" | |
2994 | [(set_attr "type" "fxch") | |
2995 | (set_attr "mode" "XF")]) | |
886c62d1 | 2996 | \f |
e075ae69 | 2997 | ;; Zero extension instructions |
886c62d1 | 2998 | |
8f7661f2 JH |
2999 | (define_expand "zero_extendhisi2" |
3000 | [(set (match_operand:SI 0 "register_operand" "") | |
3001 | (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] | |
d626200a | 3002 | "" |
8f7661f2 | 3003 | " |
e075ae69 | 3004 | { |
8f7661f2 | 3005 | if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) |
2ae0f82c | 3006 | { |
8f7661f2 JH |
3007 | operands[1] = force_reg (HImode, operands[1]); |
3008 | emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); | |
3009 | DONE; | |
2ae0f82c | 3010 | } |
8f7661f2 | 3011 | }") |
886c62d1 | 3012 | |
8f7661f2 JH |
3013 | (define_insn "zero_extendhisi2_and" |
3014 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3015 | (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) | |
e075ae69 | 3016 | (clobber (reg:CC 17))] |
8f7661f2 JH |
3017 | "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" |
3018 | "#" | |
6ef67412 JH |
3019 | [(set_attr "type" "alu1") |
3020 | (set_attr "mode" "SI")]) | |
2ae0f82c SC |
3021 | |
3022 | (define_split | |
3023 | [(set (match_operand:SI 0 "register_operand" "") | |
8f7661f2 | 3024 | (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) |
e075ae69 | 3025 | (clobber (reg:CC 17))] |
8f7661f2 JH |
3026 | "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" |
3027 | [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) | |
e075ae69 | 3028 | (clobber (reg:CC 17))])] |
d626200a JL |
3029 | "") |
3030 | ||
8f7661f2 JH |
3031 | (define_insn "*zero_extendhisi2_movzwl" |
3032 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3033 | (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] | |
3034 | "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" | |
3035 | "movz{wl|x}\\t{%1, %0|%0, %1}" | |
6ef67412 JH |
3036 | [(set_attr "type" "imovx") |
3037 | (set_attr "mode" "SI")]) | |
8f7661f2 JH |
3038 | |
3039 | (define_expand "zero_extendqihi2" | |
3040 | [(parallel | |
3041 | [(set (match_operand:HI 0 "register_operand" "") | |
3042 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) | |
3043 | (clobber (reg:CC 17))])] | |
e075ae69 | 3044 | "" |
8f7661f2 JH |
3045 | "") |
3046 | ||
3047 | (define_insn "*zero_extendqihi2_and" | |
3048 | [(set (match_operand:HI 0 "register_operand" "=r,?&q") | |
3049 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) | |
3050 | (clobber (reg:CC 17))] | |
3051 | "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" | |
3052 | "#" | |
6ef67412 JH |
3053 | [(set_attr "type" "alu1") |
3054 | (set_attr "mode" "HI")]) | |
8f7661f2 JH |
3055 | |
3056 | (define_insn "*zero_extendqihi2_movzbw_and" | |
3057 | [(set (match_operand:HI 0 "register_operand" "=r,r") | |
3058 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) | |
3059 | (clobber (reg:CC 17))] | |
3060 | "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" | |
3061 | "#" | |
6ef67412 JH |
3062 | [(set_attr "type" "imovx,alu1") |
3063 | (set_attr "mode" "HI")]) | |
886c62d1 | 3064 | |
8f7661f2 JH |
3065 | (define_insn "*zero_extendqihi2_movzbw" |
3066 | [(set (match_operand:HI 0 "register_operand" "=r") | |
3067 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] | |
1c27d4b2 | 3068 | "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" |
8f7661f2 | 3069 | "movz{bw|x}\\t{%1, %0|%0, %1}" |
6ef67412 JH |
3070 | [(set_attr "type" "imovx") |
3071 | (set_attr "mode" "HI")]) | |
8f7661f2 JH |
3072 | |
3073 | ;; For the movzbw case strip only the clobber | |
2ae0f82c SC |
3074 | (define_split |
3075 | [(set (match_operand:HI 0 "register_operand" "") | |
e075ae69 RH |
3076 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) |
3077 | (clobber (reg:CC 17))] | |
8f7661f2 JH |
3078 | "reload_completed |
3079 | && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) | |
1a06f5fe | 3080 | && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" |
8f7661f2 JH |
3081 | [(set (match_operand:HI 0 "register_operand" "") |
3082 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) | |
2ae0f82c | 3083 | |
8f7661f2 JH |
3084 | ;; When source and destination does not overlap, clear destination |
3085 | ;; first and then do the movb | |
2ae0f82c SC |
3086 | (define_split |
3087 | [(set (match_operand:HI 0 "register_operand" "") | |
8f7661f2 | 3088 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) |
e075ae69 RH |
3089 | (clobber (reg:CC 17))] |
3090 | "reload_completed | |
1a06f5fe | 3091 | && ANY_QI_REG_P (operands[0]) |
8f7661f2 JH |
3092 | && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) |
3093 | && !reg_overlap_mentioned_p (operands[0], operands[1])" | |
3094 | [(set (match_dup 0) (const_int 0)) | |
3095 | (set (strict_low_part (match_dup 2)) (match_dup 1))] | |
3096 | "operands[2] = gen_lowpart (QImode, operands[0]);") | |
2ae0f82c | 3097 | |
8f7661f2 | 3098 | ;; Rest is handled by single and. |
2ae0f82c SC |
3099 | (define_split |
3100 | [(set (match_operand:HI 0 "register_operand" "") | |
e075ae69 RH |
3101 | (zero_extend:HI (match_operand:QI 1 "register_operand" ""))) |
3102 | (clobber (reg:CC 17))] | |
3103 | "reload_completed | |
8f7661f2 JH |
3104 | && true_regnum (operands[0]) == true_regnum (operands[1])" |
3105 | [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) | |
e075ae69 | 3106 | (clobber (reg:CC 17))])] |
d626200a JL |
3107 | "") |
3108 | ||
8f7661f2 JH |
3109 | (define_expand "zero_extendqisi2" |
3110 | [(parallel | |
3111 | [(set (match_operand:SI 0 "register_operand" "") | |
3112 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) | |
3113 | (clobber (reg:CC 17))])] | |
e075ae69 | 3114 | "" |
8f7661f2 JH |
3115 | "") |
3116 | ||
3117 | (define_insn "*zero_extendqisi2_and" | |
3118 | [(set (match_operand:SI 0 "register_operand" "=r,?&q") | |
3119 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) | |
3120 | (clobber (reg:CC 17))] | |
3121 | "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" | |
3122 | "#" | |
6ef67412 JH |
3123 | [(set_attr "type" "alu1") |
3124 | (set_attr "mode" "SI")]) | |
8f7661f2 JH |
3125 | |
3126 | (define_insn "*zero_extendqisi2_movzbw_and" | |
3127 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
3128 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) | |
3129 | (clobber (reg:CC 17))] | |
3130 | "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" | |
3131 | "#" | |
6ef67412 JH |
3132 | [(set_attr "type" "imovx,alu1") |
3133 | (set_attr "mode" "SI")]) | |
2ae0f82c | 3134 | |
8f7661f2 JH |
3135 | (define_insn "*zero_extendqisi2_movzbw" |
3136 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3137 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] | |
3138 | "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" | |
3139 | "movz{bl|x}\\t{%1, %0|%0, %1}" | |
6ef67412 JH |
3140 | [(set_attr "type" "imovx") |
3141 | (set_attr "mode" "SI")]) | |
8f7661f2 JH |
3142 | |
3143 | ;; For the movzbl case strip only the clobber | |
3144 | (define_split | |
3145 | [(set (match_operand:SI 0 "register_operand" "") | |
3146 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) | |
3147 | (clobber (reg:CC 17))] | |
3148 | "reload_completed | |
3149 | && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) | |
1a06f5fe | 3150 | && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" |
8f7661f2 JH |
3151 | [(set (match_dup 0) |
3152 | (zero_extend:SI (match_dup 1)))]) | |
3153 | ||
3154 | ;; When source and destination does not overlap, clear destination | |
3155 | ;; first and then do the movb | |
2ae0f82c SC |
3156 | (define_split |
3157 | [(set (match_operand:SI 0 "register_operand" "") | |
e075ae69 RH |
3158 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) |
3159 | (clobber (reg:CC 17))] | |
3160 | "reload_completed | |
1a06f5fe JH |
3161 | && ANY_QI_REG_P (operands[0]) |
3162 | && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) | |
8f7661f2 | 3163 | && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) |
e075ae69 | 3164 | && !reg_overlap_mentioned_p (operands[0], operands[1])" |
8f7661f2 JH |
3165 | [(set (match_dup 0) (const_int 0)) |
3166 | (set (strict_low_part (match_dup 2)) (match_dup 1))] | |
3167 | "operands[2] = gen_lowpart (QImode, operands[0]);") | |
2ae0f82c | 3168 | |
8f7661f2 | 3169 | ;; Rest is handled by single and. |
2ae0f82c SC |
3170 | (define_split |
3171 | [(set (match_operand:SI 0 "register_operand" "") | |
e075ae69 RH |
3172 | (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) |
3173 | (clobber (reg:CC 17))] | |
3174 | "reload_completed | |
8f7661f2 JH |
3175 | && true_regnum (operands[0]) == true_regnum (operands[1])" |
3176 | [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) | |
e075ae69 RH |
3177 | (clobber (reg:CC 17))])] |
3178 | "") | |
2ae0f82c | 3179 | |
e075ae69 | 3180 | ;; %%% Kill me once multi-word ops are sane. |
9c530261 | 3181 | (define_insn "zero_extendsidi2" |
bb62e19a | 3182 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o") |
e075ae69 RH |
3183 | (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r"))) |
3184 | (clobber (reg:CC 17))] | |
9c530261 | 3185 | "" |
6ef67412 JH |
3186 | "#" |
3187 | [(set_attr "mode" "SI")]) | |
2ae0f82c | 3188 | |
bb62e19a JH |
3189 | (define_split |
3190 | [(set (match_operand:DI 0 "register_operand" "") | |
e075ae69 RH |
3191 | (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) |
3192 | (clobber (reg:CC 17))] | |
1e07edd3 JH |
3193 | "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1]) |
3194 | && !TARGET_64BIT" | |
591702de | 3195 | [(set (match_dup 4) (const_int 0))] |
bb62e19a JH |
3196 | "split_di (&operands[0], 1, &operands[3], &operands[4]);") |
3197 | ||
3198 | (define_split | |
3199 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
e075ae69 RH |
3200 | (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) |
3201 | (clobber (reg:CC 17))] | |
bb62e19a JH |
3202 | "reload_completed" |
3203 | [(set (match_dup 3) (match_dup 1)) | |
591702de | 3204 | (set (match_dup 4) (const_int 0))] |
bb62e19a | 3205 | "split_di (&operands[0], 1, &operands[3], &operands[4]);") |
886c62d1 | 3206 | \f |
e075ae69 | 3207 | ;; Sign extension instructions |
886c62d1 | 3208 | |
886c62d1 | 3209 | (define_insn "extendsidi2" |
e075ae69 RH |
3210 | [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") |
3211 | (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) | |
6b29b0e2 JW |
3212 | (clobber (reg:CC 17)) |
3213 | (clobber (match_scratch:SI 2 "=X,X,X,&r"))] | |
886c62d1 | 3214 | "" |
724d568a JH |
3215 | "#") |
3216 | ||
3217 | ;; Extend to memory case when source register does die. | |
3218 | (define_split | |
3219 | [(set (match_operand:DI 0 "memory_operand" "") | |
3220 | (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
6b29b0e2 JW |
3221 | (clobber (reg:CC 17)) |
3222 | (clobber (match_operand:SI 2 "register_operand" ""))] | |
d7a29404 | 3223 | "(reload_completed |
724d568a JH |
3224 | && dead_or_set_p (insn, operands[1]) |
3225 | && !reg_mentioned_p (operands[1], operands[0]))" | |
3226 | [(set (match_dup 3) (match_dup 1)) | |
e075ae69 RH |
3227 | (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) |
3228 | (clobber (reg:CC 17))]) | |
724d568a JH |
3229 | (set (match_dup 4) (match_dup 1))] |
3230 | "split_di (&operands[0], 1, &operands[3], &operands[4]);") | |
3231 | ||
3232 | ;; Extend to memory case when source register does not die. | |
3233 | (define_split | |
3234 | [(set (match_operand:DI 0 "memory_operand" "") | |
3235 | (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
6b29b0e2 JW |
3236 | (clobber (reg:CC 17)) |
3237 | (clobber (match_operand:SI 2 "register_operand" ""))] | |
d7a29404 | 3238 | "reload_completed" |
724d568a JH |
3239 | [(const_int 0)] |
3240 | " | |
9c530261 | 3241 | { |
724d568a JH |
3242 | split_di (&operands[0], 1, &operands[3], &operands[4]); |
3243 | ||
3244 | emit_move_insn (operands[3], operands[1]); | |
3245 | ||
3246 | /* Generate a cltd if possible and doing so it profitable. */ | |
3247 | if (true_regnum (operands[1]) == 0 | |
3248 | && true_regnum (operands[2]) == 1 | |
e075ae69 | 3249 | && (optimize_size || TARGET_USE_CLTD)) |
71a247f0 | 3250 | { |
e075ae69 | 3251 | emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31))); |
724d568a JH |
3252 | } |
3253 | else | |
3254 | { | |
3255 | emit_move_insn (operands[2], operands[1]); | |
e075ae69 | 3256 | emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31))); |
71a247f0 | 3257 | } |
724d568a JH |
3258 | emit_move_insn (operands[4], operands[2]); |
3259 | DONE; | |
3260 | }") | |
9c530261 | 3261 | |
724d568a JH |
3262 | ;; Extend to register case. Optimize case where source and destination |
3263 | ;; registers match and cases where we can use cltd. | |
3264 | (define_split | |
3265 | [(set (match_operand:DI 0 "register_operand" "") | |
3266 | (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
6b29b0e2 JW |
3267 | (clobber (reg:CC 17)) |
3268 | (clobber (match_scratch:SI 2 ""))] | |
724d568a JH |
3269 | "reload_completed" |
3270 | [(const_int 0)] | |
3271 | " | |
3272 | { | |
3273 | split_di (&operands[0], 1, &operands[3], &operands[4]); | |
3274 | ||
3275 | if (true_regnum (operands[3]) != true_regnum (operands[1])) | |
3276 | emit_move_insn (operands[3], operands[1]); | |
9c530261 | 3277 | |
724d568a JH |
3278 | /* Generate a cltd if possible and doing so it profitable. */ |
3279 | if (true_regnum (operands[3]) == 0 | |
e075ae69 | 3280 | && (optimize_size || TARGET_USE_CLTD)) |
724d568a | 3281 | { |
e075ae69 | 3282 | emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31))); |
724d568a JH |
3283 | DONE; |
3284 | } | |
3285 | ||
3286 | if (true_regnum (operands[4]) != true_regnum (operands[1])) | |
3287 | emit_move_insn (operands[4], operands[1]); | |
3288 | ||
e075ae69 | 3289 | emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31))); |
724d568a | 3290 | DONE; |
9c530261 | 3291 | }") |
886c62d1 | 3292 | |
886c62d1 | 3293 | (define_insn "extendhisi2" |
e075ae69 RH |
3294 | [(set (match_operand:SI 0 "register_operand" "=*a,r") |
3295 | (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] | |
886c62d1 JVA |
3296 | "" |
3297 | "* | |
3298 | { | |
6ef67412 | 3299 | switch (get_attr_prefix_0f (insn)) |
e075ae69 | 3300 | { |
6ef67412 | 3301 | case 0: |
e075ae69 RH |
3302 | return \"{cwtl|cwde}\"; |
3303 | default: | |
3304 | return \"movs{wl|x}\\t{%1,%0|%0, %1}\"; | |
3305 | } | |
3306 | }" | |
3307 | [(set_attr "type" "imovx") | |
6ef67412 JH |
3308 | (set_attr "mode" "SI") |
3309 | (set (attr "prefix_0f") | |
3310 | ;; movsx is short decodable while cwtl is vector decoded. | |
3311 | (if_then_else (and (eq_attr "cpu" "!k6") | |
3312 | (eq_attr "alternative" "0")) | |
3313 | (const_string "0") | |
3314 | (const_string "1"))) | |
3315 | (set (attr "modrm") | |
3316 | (if_then_else (eq_attr "prefix_0f" "0") | |
3317 | (const_string "0") | |
3318 | (const_string "1")))]) | |
886c62d1 JVA |
3319 | |
3320 | (define_insn "extendqihi2" | |
e075ae69 RH |
3321 | [(set (match_operand:HI 0 "register_operand" "=*a,r") |
3322 | (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] | |
886c62d1 JVA |
3323 | "" |
3324 | "* | |
3325 | { | |
6ef67412 | 3326 | switch (get_attr_prefix_0f (insn)) |
e075ae69 | 3327 | { |
6ef67412 | 3328 | case 0: |
e075ae69 RH |
3329 | return \"{cbtw|cbw}\"; |
3330 | default: | |
3331 | return \"movs{bw|x}\\t{%1,%0|%0, %1}\"; | |
3332 | } | |
3333 | }" | |
3334 | [(set_attr "type" "imovx") | |
6ef67412 JH |
3335 | (set_attr "mode" "HI") |
3336 | (set (attr "prefix_0f") | |
3337 | ;; movsx is short decodable while cwtl is vector decoded. | |
3338 | (if_then_else (and (eq_attr "cpu" "!k6") | |
3339 | (eq_attr "alternative" "0")) | |
3340 | (const_string "0") | |
3341 | (const_string "1"))) | |
3342 | (set (attr "modrm") | |
3343 | (if_then_else (eq_attr "prefix_0f" "0") | |
3344 | (const_string "0") | |
3345 | (const_string "1")))]) | |
886c62d1 JVA |
3346 | |
3347 | (define_insn "extendqisi2" | |
2ae0f82c SC |
3348 | [(set (match_operand:SI 0 "register_operand" "=r") |
3349 | (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] | |
886c62d1 | 3350 | "" |
e075ae69 | 3351 | "movs{bl|x}\\t{%1,%0|%0, %1}" |
6ef67412 JH |
3352 | [(set_attr "type" "imovx") |
3353 | (set_attr "mode" "SI")]) | |
886c62d1 JVA |
3354 | \f |
3355 | ;; Conversions between float and double. | |
3356 | ||
e075ae69 RH |
3357 | ;; These are all no-ops in the model used for the 80387. So just |
3358 | ;; emit moves. | |
6a4a5d95 | 3359 | |
e075ae69 | 3360 | ;; %%% Kill these when call knows how to work out a DFmode push earlier. |
6343a50e | 3361 | (define_insn "*dummy_extendsfdf2" |
e075ae69 | 3362 | [(set (match_operand:DF 0 "push_operand" "=<") |
42a0aa6f | 3363 | (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))] |
e075ae69 RH |
3364 | "0" |
3365 | "#") | |
6a4a5d95 JW |
3366 | |
3367 | (define_split | |
e075ae69 RH |
3368 | [(set (match_operand:DF 0 "push_operand" "") |
3369 | (float_extend:DF (match_operand:SF 1 "register_operand" "")))] | |
3370 | "FP_REGNO_P (REGNO (operands[1]))" | |
3371 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8))) | |
3372 | (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))]) | |
0fcad513 | 3373 | |
6343a50e | 3374 | (define_insn "*dummy_extendsfxf2" |
e075ae69 RH |
3375 | [(set (match_operand:XF 0 "push_operand" "=<") |
3376 | (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))] | |
3377 | "0" | |
3378 | "#") | |
e4ad1003 JW |
3379 | |
3380 | (define_split | |
e075ae69 RH |
3381 | [(set (match_operand:XF 0 "push_operand" "") |
3382 | (float_extend:XF (match_operand:SF 1 "register_operand" "")))] | |
3383 | "FP_REGNO_P (REGNO (operands[1]))" | |
3384 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12))) | |
2b589241 JH |
3385 | (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]) |
3386 | ||
3387 | (define_insn "*dummy_extendsftf2" | |
3388 | [(set (match_operand:TF 0 "push_operand" "=<") | |
3389 | (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))] | |
3390 | "0" | |
3391 | "#") | |
3392 | ||
3393 | (define_split | |
3394 | [(set (match_operand:TF 0 "push_operand" "") | |
3395 | (float_extend:TF (match_operand:SF 1 "register_operand" "")))] | |
3396 | "FP_REGNO_P (REGNO (operands[1]))" | |
3397 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16))) | |
3398 | (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))]) | |
4fb21e90 | 3399 | |
6343a50e | 3400 | (define_insn "*dummy_extenddfxf2" |
e075ae69 RH |
3401 | [(set (match_operand:XF 0 "push_operand" "=<") |
3402 | (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))] | |
3403 | "0" | |
3404 | "#") | |
e4ad1003 JW |
3405 | |
3406 | (define_split | |
e075ae69 RH |
3407 | [(set (match_operand:XF 0 "push_operand" "") |
3408 | (float_extend:XF (match_operand:DF 1 "register_operand" "")))] | |
3409 | "FP_REGNO_P (REGNO (operands[1]))" | |
3410 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12))) | |
2b589241 JH |
3411 | (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]) |
3412 | ||
3413 | (define_insn "*dummy_extenddftf2" | |
3414 | [(set (match_operand:TF 0 "push_operand" "=<") | |
3415 | (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))] | |
3416 | "0" | |
3417 | "#") | |
3418 | ||
3419 | (define_split | |
3420 | [(set (match_operand:TF 0 "push_operand" "") | |
3421 | (float_extend:TF (match_operand:DF 1 "register_operand" "")))] | |
3422 | "FP_REGNO_P (REGNO (operands[1]))" | |
3423 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16))) | |
3424 | (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))]) | |
4fb21e90 | 3425 | |
f97d9ec3 JH |
3426 | (define_expand "extendsfdf2" |
3427 | [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
3428 | (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))] | |
42a0aa6f | 3429 | "TARGET_80387 || TARGET_SSE2" |
f97d9ec3 JH |
3430 | " |
3431 | { | |
3432 | if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) | |
34289d57 | 3433 | operands[1] = force_reg (SFmode, operands[1]); |
f97d9ec3 JH |
3434 | }") |
3435 | ||
3436 | (define_insn "*extendsfdf2_1" | |
a811cc63 JH |
3437 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f") |
3438 | (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))] | |
42a0aa6f | 3439 | "(TARGET_80387 || TARGET_SSE2) |
f97d9ec3 | 3440 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" |
4fb21e90 JVA |
3441 | "* |
3442 | { | |
e075ae69 | 3443 | switch (which_alternative) |
4fb21e90 | 3444 | { |
e075ae69 | 3445 | case 0: |
0c174a68 AB |
3446 | if (REG_P (operands[1]) |
3447 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3448 | return \"fstp\\t%y0\"; |
e075ae69 | 3449 | else if (STACK_TOP_P (operands[0])) |
7ebb782b | 3450 | return \"fld%z1\\t%y1\"; |
e075ae69 | 3451 | else |
7ebb782b | 3452 | return \"fst\\t%y0\"; |
886c62d1 | 3453 | |
e075ae69 RH |
3454 | case 1: |
3455 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3456 | return \"fstp%z0\\t%y0\"; |
10195bd8 | 3457 | |
e075ae69 | 3458 | else |
7ebb782b | 3459 | return \"fst%z0\\t%y0\"; |
42a0aa6f | 3460 | case 2: |
42a0aa6f | 3461 | return \"cvtss2sd\\t{%1, %0|%0, %1}\"; |
4fb21e90 | 3462 | |
e075ae69 RH |
3463 | default: |
3464 | abort (); | |
3465 | } | |
3466 | }" | |
a811cc63 JH |
3467 | [(set_attr "type" "fmov,fmov,sse") |
3468 | (set_attr "mode" "SF,XF,DF")]) | |
42a0aa6f JH |
3469 | |
3470 | (define_insn "*extendsfdf2_1_sse_only" | |
3471 | [(set (match_operand:DF 0 "register_operand" "=Y") | |
3472 | (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))] | |
3473 | "!TARGET_80387 && TARGET_SSE2 | |
3474 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" | |
3475 | "cvtss2sd\\t{%1, %0|%0, %1}" | |
3476 | [(set_attr "type" "sse") | |
3477 | (set_attr "mode" "DF")]) | |
e075ae69 | 3478 | |
f97d9ec3 JH |
3479 | (define_expand "extendsfxf2" |
3480 | [(set (match_operand:XF 0 "nonimmediate_operand" "") | |
3481 | (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))] | |
1e07edd3 | 3482 | "TARGET_80387 && !TARGET_64BIT" |
f97d9ec3 JH |
3483 | " |
3484 | { | |
3485 | if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) | |
34289d57 | 3486 | operands[1] = force_reg (SFmode, operands[1]); |
f97d9ec3 JH |
3487 | }") |
3488 | ||
3489 | (define_insn "*extendsfxf2_1" | |
e075ae69 RH |
3490 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") |
3491 | (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] | |
1e07edd3 | 3492 | "TARGET_80387 && !TARGET_64BIT |
f97d9ec3 | 3493 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" |
e075ae69 | 3494 | "* |
10195bd8 | 3495 | { |
e075ae69 RH |
3496 | switch (which_alternative) |
3497 | { | |
3498 | case 0: | |
0c174a68 AB |
3499 | if (REG_P (operands[1]) |
3500 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3501 | return \"fstp\\t%y0\"; |
e075ae69 | 3502 | else if (STACK_TOP_P (operands[0])) |
7ebb782b | 3503 | return \"fld%z1\\t%y1\"; |
e075ae69 | 3504 | else |
7ebb782b | 3505 | return \"fst\\t%y0\"; |
886c62d1 | 3506 | |
e075ae69 RH |
3507 | case 1: |
3508 | /* There is no non-popping store to memory for XFmode. So if | |
3509 | we need one, follow the store with a load. */ | |
3510 | if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3511 | return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\"; |
e075ae69 | 3512 | else |
7ebb782b | 3513 | return \"fstp%z0\\t%y0\"; |
886c62d1 | 3514 | |
e075ae69 RH |
3515 | default: |
3516 | abort (); | |
3517 | } | |
3518 | }" | |
6ef67412 JH |
3519 | [(set_attr "type" "fmov") |
3520 | (set_attr "mode" "SF,XF")]) | |
886c62d1 | 3521 | |
2b589241 JH |
3522 | (define_expand "extendsftf2" |
3523 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
3524 | (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))] | |
3525 | "TARGET_80387" | |
3526 | " | |
3527 | { | |
3528 | if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) | |
3529 | operands[1] = force_reg (SFmode, operands[1]); | |
3530 | }") | |
3531 | ||
3532 | (define_insn "*extendsftf2_1" | |
3533 | [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m") | |
3534 | (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] | |
3535 | "TARGET_80387 | |
3536 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" | |
3537 | "* | |
3538 | { | |
3539 | switch (which_alternative) | |
3540 | { | |
3541 | case 0: | |
3542 | if (REG_P (operands[1]) | |
3543 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
3544 | return \"fstp\\t%y0\"; | |
3545 | else if (STACK_TOP_P (operands[0])) | |
3546 | return \"fld%z1\\t%y1\"; | |
3547 | else | |
3548 | return \"fst\\t%y0\"; | |
3549 | ||
3550 | case 1: | |
3551 | /* There is no non-popping store to memory for XFmode. So if | |
3552 | we need one, follow the store with a load. */ | |
3553 | if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
3554 | return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\"; | |
3555 | else | |
3556 | return \"fstp%z0\\t%y0\"; | |
3557 | ||
3558 | default: | |
3559 | abort (); | |
3560 | } | |
3561 | }" | |
3562 | [(set_attr "type" "fmov") | |
3563 | (set_attr "mode" "SF,XF")]) | |
3564 | ||
f97d9ec3 JH |
3565 | (define_expand "extenddfxf2" |
3566 | [(set (match_operand:XF 0 "nonimmediate_operand" "") | |
3567 | (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))] | |
1e07edd3 | 3568 | "TARGET_80387 && !TARGET_64BIT" |
f97d9ec3 JH |
3569 | " |
3570 | { | |
3571 | if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) | |
34289d57 | 3572 | operands[1] = force_reg (DFmode, operands[1]); |
f97d9ec3 JH |
3573 | }") |
3574 | ||
3575 | (define_insn "*extenddfxf2_1" | |
e075ae69 RH |
3576 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") |
3577 | (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] | |
1e07edd3 | 3578 | "TARGET_80387 && !TARGET_64BIT |
f97d9ec3 | 3579 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" |
e075ae69 RH |
3580 | "* |
3581 | { | |
3582 | switch (which_alternative) | |
3583 | { | |
3584 | case 0: | |
0c174a68 AB |
3585 | if (REG_P (operands[1]) |
3586 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3587 | return \"fstp\\t%y0\"; |
e075ae69 | 3588 | else if (STACK_TOP_P (operands[0])) |
7ebb782b | 3589 | return \"fld%z1\\t%y1\"; |
e075ae69 | 3590 | else |
7ebb782b | 3591 | return \"fst\\t%y0\"; |
bc725565 | 3592 | |
e075ae69 RH |
3593 | case 1: |
3594 | /* There is no non-popping store to memory for XFmode. So if | |
3595 | we need one, follow the store with a load. */ | |
3596 | if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3597 | return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\"; |
e075ae69 | 3598 | else |
7ebb782b | 3599 | return \"fstp%z0\\t%y0\"; |
bc725565 | 3600 | |
e075ae69 RH |
3601 | default: |
3602 | abort (); | |
3603 | } | |
3604 | }" | |
6ef67412 JH |
3605 | [(set_attr "type" "fmov") |
3606 | (set_attr "mode" "DF,XF")]) | |
bc725565 | 3607 | |
2b589241 JH |
3608 | (define_expand "extenddftf2" |
3609 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
3610 | (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))] | |
3611 | "TARGET_80387" | |
3612 | " | |
3613 | { | |
3614 | if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) | |
3615 | operands[1] = force_reg (DFmode, operands[1]); | |
3616 | }") | |
3617 | ||
3618 | (define_insn "*extenddftf2_1" | |
3619 | [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m") | |
3620 | (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] | |
3621 | "TARGET_80387 | |
3622 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" | |
3623 | "* | |
3624 | { | |
3625 | switch (which_alternative) | |
3626 | { | |
3627 | case 0: | |
3628 | if (REG_P (operands[1]) | |
3629 | && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
3630 | return \"fstp\\t%y0\"; | |
3631 | else if (STACK_TOP_P (operands[0])) | |
3632 | return \"fld%z1\\t%y1\"; | |
3633 | else | |
3634 | return \"fst\\t%y0\"; | |
3635 | ||
3636 | case 1: | |
3637 | /* There is no non-popping store to memory for XFmode. So if | |
3638 | we need one, follow the store with a load. */ | |
3639 | if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
3640 | return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\"; | |
3641 | else | |
3642 | return \"fstp%z0\\t%y0\"; | |
3643 | ||
3644 | default: | |
3645 | abort (); | |
3646 | } | |
3647 | }" | |
3648 | [(set_attr "type" "fmov") | |
3649 | (set_attr "mode" "DF,XF")]) | |
3650 | ||
e075ae69 RH |
3651 | ;; %%% This seems bad bad news. |
3652 | ;; This cannot output into an f-reg because there is no way to be sure | |
3653 | ;; of truncating in that case. Otherwise this is just like a simple move | |
3654 | ;; insn. So we pretend we can output to a reg in order to get better | |
3655 | ;; register preferencing, but we really use a stack slot. | |
886c62d1 | 3656 | |
e075ae69 RH |
3657 | (define_expand "truncdfsf2" |
3658 | [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
3659 | (float_truncate:SF | |
3660 | (match_operand:DF 1 "register_operand" ""))) | |
3661 | (clobber (match_dup 2))])] | |
42a0aa6f JH |
3662 | "TARGET_80387 || TARGET_SSE2" |
3663 | " | |
3664 | if (TARGET_80387) | |
3665 | operands[2] = assign_386_stack_local (SFmode, 0); | |
3666 | else | |
3667 | { | |
3668 | emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1])); | |
3669 | DONE; | |
3670 | } | |
3671 | ") | |
bc725565 | 3672 | |
e075ae69 | 3673 | (define_insn "*truncdfsf2_1" |
42a0aa6f | 3674 | [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f") |
e075ae69 RH |
3675 | (float_truncate:SF |
3676 | (match_operand:DF 1 "register_operand" "f,0"))) | |
42a0aa6f JH |
3677 | (clobber (match_operand:SF 2 "memory_operand" "=X,m"))] |
3678 | "TARGET_80387 && !TARGET_SSE2" | |
e075ae69 RH |
3679 | "* |
3680 | { | |
3681 | switch (which_alternative) | |
3682 | { | |
3683 | case 0: | |
3684 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3685 | return \"fstp%z0\\t%y0\"; |
e075ae69 | 3686 | else |
7ebb782b | 3687 | return \"fst%z0\\t%y0\"; |
e075ae69 | 3688 | case 1: |
7ebb782b | 3689 | return \"fstp%z2\\t%y2\;fld%z2\\t%y2\"; |
e075ae69 RH |
3690 | } |
3691 | abort (); | |
3692 | }" | |
6ef67412 | 3693 | [(set_attr "type" "fmov,multi") |
42a0aa6f JH |
3694 | (set_attr "mode" "SF,SF")]) |
3695 | ||
3696 | (define_insn "*truncdfsf2_1_sse" | |
79005df5 | 3697 | [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f,Y") |
42a0aa6f JH |
3698 | (float_truncate:SF |
3699 | (match_operand:DF 1 "nonimmediate_operand" "f,0,mY"))) | |
3700 | (clobber (match_operand:SF 2 "memory_operand" "=X,m,X"))] | |
3701 | "TARGET_80387 && TARGET_SSE2" | |
3702 | "* | |
3703 | { | |
3704 | switch (which_alternative) | |
3705 | { | |
3706 | case 0: | |
3707 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
3708 | return \"fstp%z0\\t%y0\"; | |
3709 | else | |
3710 | return \"fst%z0\\t%y0\"; | |
3711 | case 1: | |
3712 | return \"fstp%z2\\t%y2\;fld%z2\\t%y2\"; | |
3713 | case 2: | |
3714 | case 3: | |
3715 | return \"cvtsd2ss\\t{%1, %0|%0, %1}\"; | |
3716 | } | |
3717 | abort (); | |
3718 | }" | |
3719 | [(set_attr "type" "fmov,multi,sse") | |
3720 | (set_attr "mode" "SF,SF,DF")]) | |
53b5ce19 | 3721 | |
e075ae69 | 3722 | (define_insn "*truncdfsf2_2" |
79005df5 | 3723 | [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m") |
42a0aa6f | 3724 | (float_truncate:SF |
79005df5 JH |
3725 | (match_operand:DF 1 "nonimmediate_operand" "mY,f")))] |
3726 | "TARGET_80387 && TARGET_SSE2 | |
3727 | && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" | |
42a0aa6f JH |
3728 | "* |
3729 | { | |
3730 | switch (which_alternative) | |
3731 | { | |
3732 | case 0: | |
79005df5 JH |
3733 | return \"cvtsd2ss\\t{%1, %0|%0, %1}\"; |
3734 | case 1: | |
42a0aa6f JH |
3735 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) |
3736 | return \"fstp%z0\\t%y0\"; | |
3737 | else | |
3738 | return \"fst%z0\\t%y0\"; | |
42a0aa6f JH |
3739 | } |
3740 | }" | |
79005df5 JH |
3741 | [(set_attr "type" "sse,fmov") |
3742 | (set_attr "mode" "DF,SF")]) | |
42a0aa6f JH |
3743 | |
3744 | (define_insn "truncdfsf2_3" | |
3745 | [(set (match_operand:SF 0 "nonimmediate_operand" "=m") | |
e075ae69 RH |
3746 | (float_truncate:SF |
3747 | (match_operand:DF 1 "register_operand" "f")))] | |
53b5ce19 | 3748 | "TARGET_80387" |
e075ae69 RH |
3749 | "* |
3750 | { | |
3751 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3752 | return \"fstp%z0\\t%y0\"; |
e075ae69 | 3753 | else |
7ebb782b | 3754 | return \"fst%z0\\t%y0\"; |
e075ae69 | 3755 | }" |
6ef67412 JH |
3756 | [(set_attr "type" "fmov") |
3757 | (set_attr "mode" "SF")]) | |
53b5ce19 | 3758 | |
42a0aa6f JH |
3759 | (define_insn "truncdfsf2_sse_only" |
3760 | [(set (match_operand:SF 0 "register_operand" "=Y") | |
3761 | (float_truncate:SF | |
3762 | (match_operand:DF 1 "nonimmediate_operand" "mY")))] | |
3763 | "!TARGET_80387 && TARGET_SSE2" | |
3764 | "cvtsd2ss\\t{%1, %0|%0, %1}" | |
3765 | [(set_attr "type" "sse") | |
3766 | (set_attr "mode" "DF")]) | |
3767 | ||
53b5ce19 | 3768 | (define_split |
e075ae69 RH |
3769 | [(set (match_operand:SF 0 "memory_operand" "") |
3770 | (float_truncate:SF | |
3771 | (match_operand:DF 1 "register_operand" ""))) | |
3772 | (clobber (match_operand:SF 2 "memory_operand" ""))] | |
3773 | "TARGET_80387" | |
3774 | [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] | |
53b5ce19 JW |
3775 | "") |
3776 | ||
42a0aa6f JH |
3777 | (define_split |
3778 | [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
3779 | (float_truncate:SF | |
3780 | (match_operand:DF 1 "nonimmediate_operand" ""))) | |
3781 | (clobber (match_operand 2 "" ""))] | |
3782 | "TARGET_80387 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])" | |
3783 | [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] | |
3784 | "") | |
3785 | ||
53b5ce19 JW |
3786 | (define_split |
3787 | [(set (match_operand:SF 0 "register_operand" "") | |
e075ae69 RH |
3788 | (float_truncate:SF |
3789 | (match_operand:DF 1 "register_operand" ""))) | |
3790 | (clobber (match_operand:SF 2 "memory_operand" ""))] | |
42a0aa6f JH |
3791 | "TARGET_80387 && reload_completed |
3792 | && FP_REG_P (operands[0])" | |
e075ae69 RH |
3793 | [(set (match_dup 2) (float_truncate:SF (match_dup 1))) |
3794 | (set (match_dup 0) (match_dup 2))] | |
53b5ce19 JW |
3795 | "") |
3796 | ||
e075ae69 RH |
3797 | (define_expand "truncxfsf2" |
3798 | [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
3799 | (float_truncate:SF | |
3800 | (match_operand:XF 1 "register_operand" ""))) | |
3801 | (clobber (match_dup 2))])] | |
1e07edd3 | 3802 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 | 3803 | "operands[2] = assign_386_stack_local (SFmode, 0);") |
53b5ce19 | 3804 | |
e075ae69 RH |
3805 | (define_insn "*truncxfsf2_1" |
3806 | [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f") | |
3807 | (float_truncate:SF | |
3808 | (match_operand:XF 1 "register_operand" "f,0"))) | |
c76aab11 | 3809 | (clobber (match_operand:SF 2 "memory_operand" "=m,m"))] |
1e07edd3 | 3810 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
3811 | "* |
3812 | { | |
3813 | switch (which_alternative) | |
3814 | { | |
3815 | case 0: | |
3816 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3817 | return \"fstp%z0\\t%y0\"; |
e075ae69 | 3818 | else |
7ebb782b | 3819 | return \"fst%z0\\t%y0\"; |
e075ae69 | 3820 | case 1: |
7ebb782b | 3821 | return \"fstp%z2\\t%y2\;fld%z2\\t%y2\"; |
e075ae69 RH |
3822 | } |
3823 | abort (); | |
3824 | }" | |
6ef67412 JH |
3825 | [(set_attr "type" "fmov,multi") |
3826 | (set_attr "mode" "SF")]) | |
886c62d1 | 3827 | |
e075ae69 | 3828 | (define_insn "*truncxfsf2_2" |
dd80b906 | 3829 | [(set (match_operand:SF 0 "memory_operand" "=m") |
e075ae69 RH |
3830 | (float_truncate:SF |
3831 | (match_operand:XF 1 "register_operand" "f")))] | |
1e07edd3 | 3832 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
3833 | "* |
3834 | { | |
3835 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3836 | return \"fstp%z0\\t%y0\"; |
e075ae69 | 3837 | else |
7ebb782b | 3838 | return \"fst%z0\\t%y0\"; |
e075ae69 | 3839 | }" |
6ef67412 JH |
3840 | [(set_attr "type" "fmov") |
3841 | (set_attr "mode" "SF")]) | |
bc725565 JW |
3842 | |
3843 | (define_split | |
e075ae69 RH |
3844 | [(set (match_operand:SF 0 "memory_operand" "") |
3845 | (float_truncate:SF | |
3846 | (match_operand:XF 1 "register_operand" ""))) | |
3847 | (clobber (match_operand:SF 2 "memory_operand" ""))] | |
3848 | "TARGET_80387" | |
3849 | [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] | |
886c62d1 JVA |
3850 | "") |
3851 | ||
bc725565 | 3852 | (define_split |
6a4a5d95 | 3853 | [(set (match_operand:SF 0 "register_operand" "") |
e075ae69 RH |
3854 | (float_truncate:SF |
3855 | (match_operand:XF 1 "register_operand" ""))) | |
3856 | (clobber (match_operand:SF 2 "memory_operand" ""))] | |
bc725565 | 3857 | "TARGET_80387 && reload_completed" |
e075ae69 RH |
3858 | [(set (match_dup 2) (float_truncate:SF (match_dup 1))) |
3859 | (set (match_dup 0) (match_dup 2))] | |
886c62d1 JVA |
3860 | "") |
3861 | ||
2b589241 JH |
3862 | (define_expand "trunctfsf2" |
3863 | [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
3864 | (float_truncate:SF | |
3865 | (match_operand:TF 1 "register_operand" ""))) | |
3866 | (clobber (match_dup 2))])] | |
3867 | "TARGET_80387" | |
3868 | "operands[2] = assign_386_stack_local (SFmode, 0);") | |
3869 | ||
3870 | (define_insn "*trunctfsf2_1" | |
3871 | [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f") | |
3872 | (float_truncate:SF | |
3873 | (match_operand:TF 1 "register_operand" "f,0"))) | |
3874 | (clobber (match_operand:SF 2 "memory_operand" "=m,m"))] | |
3875 | "TARGET_80387" | |
3876 | "* | |
3877 | { | |
3878 | switch (which_alternative) | |
3879 | { | |
3880 | case 0: | |
3881 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
3882 | return \"fstp%z0\\t%y0\"; | |
3883 | else | |
3884 | return \"fst%z0\\t%y0\"; | |
3885 | case 1: | |
3886 | return \"fstp%z2\\t%y2\;fld%z2\\t%y2\"; | |
3887 | } | |
3888 | abort (); | |
3889 | }" | |
3890 | [(set_attr "type" "fmov,multi") | |
3891 | (set_attr "mode" "SF")]) | |
3892 | ||
1e07edd3 | 3893 | (define_insn "*trunctfsf2_2" |
2b589241 JH |
3894 | [(set (match_operand:SF 0 "nonimmediate_operand" "=m") |
3895 | (float_truncate:SF | |
3896 | (match_operand:TF 1 "register_operand" "f")))] | |
3897 | "TARGET_80387" | |
3898 | "* | |
3899 | { | |
3900 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
3901 | return \"fstp%z0\\t%y0\"; | |
3902 | else | |
3903 | return \"fst%z0\\t%y0\"; | |
3904 | }" | |
3905 | [(set_attr "type" "fmov") | |
3906 | (set_attr "mode" "SF")]) | |
3907 | ||
3908 | (define_split | |
3909 | [(set (match_operand:SF 0 "memory_operand" "") | |
3910 | (float_truncate:SF | |
3911 | (match_operand:TF 1 "register_operand" ""))) | |
3912 | (clobber (match_operand:SF 2 "memory_operand" ""))] | |
3913 | "TARGET_80387" | |
3914 | [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] | |
3915 | "") | |
3916 | ||
3917 | (define_split | |
3918 | [(set (match_operand:SF 0 "register_operand" "") | |
3919 | (float_truncate:SF | |
3920 | (match_operand:TF 1 "register_operand" ""))) | |
3921 | (clobber (match_operand:SF 2 "memory_operand" ""))] | |
3922 | "TARGET_80387 && reload_completed" | |
3923 | [(set (match_dup 2) (float_truncate:SF (match_dup 1))) | |
3924 | (set (match_dup 0) (match_dup 2))] | |
3925 | "") | |
3926 | ||
3927 | ||
e075ae69 RH |
3928 | (define_expand "truncxfdf2" |
3929 | [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
3930 | (float_truncate:DF | |
3931 | (match_operand:XF 1 "register_operand" ""))) | |
3932 | (clobber (match_dup 2))])] | |
1e07edd3 | 3933 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 | 3934 | "operands[2] = assign_386_stack_local (DFmode, 0);") |
bc725565 | 3935 | |
e075ae69 RH |
3936 | (define_insn "*truncxfdf2_1" |
3937 | [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f") | |
3938 | (float_truncate:DF | |
3939 | (match_operand:XF 1 "register_operand" "f,0"))) | |
c76aab11 | 3940 | (clobber (match_operand:DF 2 "memory_operand" "=m,m"))] |
1e07edd3 | 3941 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
3942 | "* |
3943 | { | |
3944 | switch (which_alternative) | |
3945 | { | |
3946 | case 0: | |
3947 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3948 | return \"fstp%z0\\t%y0\"; |
e075ae69 | 3949 | else |
7ebb782b | 3950 | return \"fst%z0\\t%y0\"; |
e075ae69 | 3951 | case 1: |
7ebb782b | 3952 | return \"fstp%z2\\t%y2\;fld%z2\\t%y2\"; |
e075ae69 RH |
3953 | } |
3954 | abort (); | |
3955 | }" | |
6ef67412 JH |
3956 | [(set_attr "type" "fmov,multi") |
3957 | (set_attr "mode" "DF")]) | |
bc725565 | 3958 | |
e075ae69 RH |
3959 | (define_insn "*truncxfdf2_2" |
3960 | [(set (match_operand:DF 0 "memory_operand" "=m") | |
3961 | (float_truncate:DF | |
3962 | (match_operand:XF 1 "register_operand" "f")))] | |
1e07edd3 | 3963 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
3964 | "* |
3965 | { | |
3966 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
7ebb782b | 3967 | return \"fstp%z0\\t%y0\"; |
e075ae69 | 3968 | else |
7ebb782b | 3969 | return \"fst%z0\\t%y0\"; |
e075ae69 | 3970 | }" |
6ef67412 JH |
3971 | [(set_attr "type" "fmov") |
3972 | (set_attr "mode" "DF")]) | |
bc725565 JW |
3973 | |
3974 | (define_split | |
e075ae69 RH |
3975 | [(set (match_operand:DF 0 "memory_operand" "") |
3976 | (float_truncate:DF | |
3977 | (match_operand:XF 1 "register_operand" ""))) | |
3978 | (clobber (match_operand:DF 2 "memory_operand" ""))] | |
ca285e07 JH |
3979 | "TARGET_80387" |
3980 | [(set (match_dup 0) (float_truncate:DF (match_dup 1)))] | |
4fb21e90 JVA |
3981 | "") |
3982 | ||
bc725565 | 3983 | (define_split |
6a4a5d95 | 3984 | [(set (match_operand:DF 0 "register_operand" "") |
e075ae69 RH |
3985 | (float_truncate:DF |
3986 | (match_operand:XF 1 "register_operand" ""))) | |
3987 | (clobber (match_operand:DF 2 "memory_operand" ""))] | |
bc725565 | 3988 | "TARGET_80387 && reload_completed" |
ca285e07 | 3989 | [(set (match_dup 2) (float_truncate:DF (match_dup 1))) |
e075ae69 | 3990 | (set (match_dup 0) (match_dup 2))] |
4fb21e90 | 3991 | "") |
ca285e07 | 3992 | |
2b589241 JH |
3993 | (define_expand "trunctfdf2" |
3994 | [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
3995 | (float_truncate:DF | |
3996 | (match_operand:TF 1 "register_operand" ""))) | |
3997 | (clobber (match_dup 2))])] | |
3998 | "TARGET_80387" | |
3999 | "operands[2] = assign_386_stack_local (DFmode, 0);") | |
4000 | ||
4001 | (define_insn "*trunctfdf2_1" | |
4002 | [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f") | |
4003 | (float_truncate:DF | |
4004 | (match_operand:TF 1 "register_operand" "f,0"))) | |
4005 | (clobber (match_operand:DF 2 "memory_operand" "=m,m"))] | |
4006 | "TARGET_80387" | |
4007 | "* | |
4008 | { | |
4009 | switch (which_alternative) | |
4010 | { | |
4011 | case 0: | |
4012 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
4013 | return \"fstp%z0\\t%y0\"; | |
4014 | else | |
4015 | return \"fst%z0\\t%y0\"; | |
4016 | case 1: | |
4017 | return \"fstp%z2\\t%y2\;fld%z2\\t%y2\"; | |
4018 | } | |
4019 | abort (); | |
4020 | }" | |
4021 | [(set_attr "type" "fmov,multi") | |
4022 | (set_attr "mode" "DF")]) | |
4023 | ||
3d117b30 | 4024 | (define_insn "*trunctfdf2_2" |
2b589241 JH |
4025 | [(set (match_operand:DF 0 "memory_operand" "=m") |
4026 | (float_truncate:DF | |
4027 | (match_operand:TF 1 "register_operand" "f")))] | |
4028 | "TARGET_80387" | |
4029 | "* | |
4030 | { | |
4031 | if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) | |
4032 | return \"fstp%z0\\t%y0\"; | |
4033 | else | |
4034 | return \"fst%z0\\t%y0\"; | |
4035 | }" | |
4036 | [(set_attr "type" "fmov") | |
4037 | (set_attr "mode" "DF")]) | |
4038 | ||
4039 | (define_split | |
4040 | [(set (match_operand:DF 0 "memory_operand" "") | |
4041 | (float_truncate:DF | |
4042 | (match_operand:TF 1 "register_operand" ""))) | |
4043 | (clobber (match_operand:DF 2 "memory_operand" ""))] | |
4044 | "TARGET_80387" | |
4045 | [(set (match_dup 0) (float_truncate:DF (match_dup 1)))] | |
4046 | "") | |
4047 | ||
4048 | (define_split | |
4049 | [(set (match_operand:DF 0 "register_operand" "") | |
4050 | (float_truncate:DF | |
4051 | (match_operand:TF 1 "register_operand" ""))) | |
4052 | (clobber (match_operand:DF 2 "memory_operand" ""))] | |
4053 | "TARGET_80387 && reload_completed" | |
4054 | [(set (match_dup 2) (float_truncate:DF (match_dup 1))) | |
4055 | (set (match_dup 0) (match_dup 2))] | |
4056 | "") | |
4057 | ||
e075ae69 RH |
4058 | \f |
4059 | ;; %%% Break up all these bad boys. | |
4fb21e90 | 4060 | |
e075ae69 RH |
4061 | ;; Signed conversion to DImode. |
4062 | ||
2b589241 JH |
4063 | (define_expand "fix_truncxfdi2" |
4064 | [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
4065 | (fix:DI (match_operand:XF 1 "register_operand" ""))) | |
4066 | (clobber (match_dup 2)) | |
4067 | (clobber (match_dup 3)) | |
4068 | (clobber (match_scratch:SI 4 "")) | |
4069 | (clobber (match_scratch:XF 5 ""))])] | |
1e07edd3 | 4070 | "TARGET_80387 && !TARGET_64BIT" |
2b589241 JH |
4071 | "operands[2] = assign_386_stack_local (SImode, 0); |
4072 | operands[3] = assign_386_stack_local (DImode, 1);") | |
4073 | ||
4074 | (define_expand "fix_trunctfdi2" | |
e075ae69 | 4075 | [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") |
2b589241 | 4076 | (fix:DI (match_operand:TF 1 "register_operand" ""))) |
e075ae69 RH |
4077 | (clobber (match_dup 2)) |
4078 | (clobber (match_dup 3)) | |
4079 | (clobber (match_scratch:SI 4 "")) | |
2b589241 | 4080 | (clobber (match_scratch:TF 5 ""))])] |
bc725565 | 4081 | "TARGET_80387" |
e075ae69 RH |
4082 | "operands[2] = assign_386_stack_local (SImode, 0); |
4083 | operands[3] = assign_386_stack_local (DImode, 1);") | |
bc725565 | 4084 | |
e075ae69 RH |
4085 | (define_expand "fix_truncdfdi2" |
4086 | [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
4087 | (fix:DI (match_operand:DF 1 "register_operand" ""))) | |
4088 | (clobber (match_dup 2)) | |
4089 | (clobber (match_dup 3)) | |
4090 | (clobber (match_scratch:SI 4 "")) | |
a05924f9 | 4091 | (clobber (match_scratch:DF 5 ""))])] |
53b5ce19 | 4092 | "TARGET_80387" |
e075ae69 RH |
4093 | "operands[2] = assign_386_stack_local (SImode, 0); |
4094 | operands[3] = assign_386_stack_local (DImode, 1);") | |
53b5ce19 | 4095 | |
e075ae69 RH |
4096 | (define_expand "fix_truncsfdi2" |
4097 | [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
4098 | (fix:DI (match_operand:SF 1 "register_operand" ""))) | |
4099 | (clobber (match_dup 2)) | |
4100 | (clobber (match_dup 3)) | |
4101 | (clobber (match_scratch:SI 4 "")) | |
a05924f9 | 4102 | (clobber (match_scratch:SF 5 ""))])] |
53b5ce19 | 4103 | "TARGET_80387" |
e075ae69 RH |
4104 | "operands[2] = assign_386_stack_local (SImode, 0); |
4105 | operands[3] = assign_386_stack_local (DImode, 1);") | |
4106 | ||
4107 | (define_insn "*fix_truncdi_1" | |
c76aab11 | 4108 | [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") |
e075ae69 | 4109 | (fix:DI (match_operand 1 "register_operand" "f,f"))) |
c76aab11 RH |
4110 | (clobber (match_operand:SI 2 "memory_operand" "=o,o")) |
4111 | (clobber (match_operand:DI 3 "memory_operand" "=m,m")) | |
a05924f9 JH |
4112 | (clobber (match_scratch:SI 4 "=&r,&r")) |
4113 | (clobber (match_scratch 5 "=&f,&f"))] | |
e075ae69 RH |
4114 | "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))" |
4115 | "* return output_fix_trunc (insn, operands);" | |
4116 | [(set_attr "type" "multi")]) | |
53b5ce19 | 4117 | |
e075ae69 RH |
4118 | (define_split |
4119 | [(set (match_operand:DI 0 "register_operand" "") | |
4120 | (fix:DI (match_operand 1 "register_operand" ""))) | |
4121 | (clobber (match_operand:SI 2 "memory_operand" "")) | |
4122 | (clobber (match_operand:DI 3 "memory_operand" "")) | |
4123 | (clobber (match_scratch:SI 4 "")) | |
a05924f9 | 4124 | (clobber (match_scratch 5 ""))] |
e075ae69 RH |
4125 | "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])" |
4126 | [(parallel [(set (match_dup 3) (fix:DI (match_dup 1))) | |
4127 | (clobber (match_dup 2)) | |
4128 | (clobber (match_dup 3)) | |
4129 | (clobber (match_dup 4)) | |
4130 | (clobber (match_dup 5))]) | |
4131 | (set (match_dup 0) (match_dup 3))] | |
53b5ce19 JW |
4132 | "") |
4133 | ||
e075ae69 | 4134 | ;; Signed conversion to SImode. |
53b5ce19 | 4135 | |
e075ae69 RH |
4136 | (define_expand "fix_truncxfsi2" |
4137 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
4138 | (fix:SI (match_operand:XF 1 "register_operand" ""))) | |
4139 | (clobber (match_dup 2)) | |
4140 | (clobber (match_dup 3)) | |
4141 | (clobber (match_scratch:SI 4 ""))])] | |
1e07edd3 | 4142 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
4143 | "operands[2] = assign_386_stack_local (SImode, 0); |
4144 | operands[3] = assign_386_stack_local (SImode, 1);") | |
53b5ce19 | 4145 | |
2b589241 JH |
4146 | (define_expand "fix_trunctfsi2" |
4147 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
4148 | (fix:SI (match_operand:TF 1 "register_operand" ""))) | |
4149 | (clobber (match_dup 2)) | |
4150 | (clobber (match_dup 3)) | |
4151 | (clobber (match_scratch:SI 4 ""))])] | |
4152 | "TARGET_80387" | |
4153 | "operands[2] = assign_386_stack_local (SImode, 0); | |
4154 | operands[3] = assign_386_stack_local (SImode, 1);") | |
4155 | ||
e075ae69 RH |
4156 | (define_expand "fix_truncdfsi2" |
4157 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
4158 | (fix:SI (match_operand:DF 1 "register_operand" ""))) | |
4159 | (clobber (match_dup 2)) | |
4160 | (clobber (match_dup 3)) | |
4161 | (clobber (match_scratch:SI 4 ""))])] | |
42a0aa6f JH |
4162 | "TARGET_80387 || TARGET_SSE2" |
4163 | " | |
4164 | { | |
4165 | if (TARGET_SSE2) | |
4166 | { | |
ca9a9b12 | 4167 | rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); |
b1675dbd JH |
4168 | emit_insn (gen_fix_truncdfsi_sse (out, operands[1])); |
4169 | if (out != operands[0]) | |
4170 | emit_move_insn (operands[0], out); | |
42a0aa6f JH |
4171 | DONE; |
4172 | } | |
4173 | else | |
4174 | { | |
4175 | operands[2] = assign_386_stack_local (SImode, 0); | |
4176 | operands[3] = assign_386_stack_local (SImode, 1); | |
4177 | } | |
4178 | }") | |
886c62d1 | 4179 | |
e075ae69 RH |
4180 | (define_expand "fix_truncsfsi2" |
4181 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
4182 | (fix:SI (match_operand:SF 1 "register_operand" ""))) | |
4183 | (clobber (match_dup 2)) | |
4184 | (clobber (match_dup 3)) | |
4185 | (clobber (match_scratch:SI 4 ""))])] | |
42a0aa6f JH |
4186 | "TARGET_80387 || TARGET_SSE" |
4187 | " | |
4188 | { | |
4189 | if (TARGET_SSE2) | |
4190 | { | |
ca9a9b12 | 4191 | rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); |
b1675dbd JH |
4192 | emit_insn (gen_fix_truncdfsi_sse (out, operands[1])); |
4193 | if (out != operands[0]) | |
4194 | emit_move_insn (operands[0], out); | |
42a0aa6f JH |
4195 | DONE; |
4196 | } | |
4197 | else | |
4198 | { | |
4199 | operands[2] = assign_386_stack_local (SImode, 0); | |
4200 | operands[3] = assign_386_stack_local (SImode, 1); | |
4201 | } | |
4202 | }") | |
e075ae69 RH |
4203 | |
4204 | (define_insn "*fix_truncsi_1" | |
c76aab11 | 4205 | [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r") |
e075ae69 | 4206 | (fix:SI (match_operand 1 "register_operand" "f,f"))) |
c76aab11 RH |
4207 | (clobber (match_operand:SI 2 "memory_operand" "=o,o")) |
4208 | (clobber (match_operand:SI 3 "memory_operand" "=m,m")) | |
e075ae69 | 4209 | (clobber (match_scratch:SI 4 "=&r,r"))] |
42a0aa6f JH |
4210 | "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1])) |
4211 | && (!TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" | |
e075ae69 RH |
4212 | "* return output_fix_trunc (insn, operands);" |
4213 | [(set_attr "type" "multi")]) | |
bc725565 | 4214 | |
42a0aa6f JH |
4215 | ;; When SSE available, it is always faster to use it! |
4216 | (define_insn "fix_truncsfsi_sse" | |
4217 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4218 | (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))] | |
4219 | "TARGET_SSE" | |
4220 | "cvttss2si\\t{%1, %0|%0, %1}" | |
4221 | [(set_attr "type" "sse")]) | |
4222 | ||
4223 | (define_insn "fix_truncdfsi_sse" | |
4224 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4225 | (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))] | |
4226 | "TARGET_SSE2" | |
4227 | "cvttsd2si\\t{%1, %0|%0, %1}" | |
4228 | [(set_attr "type" "sse")]) | |
4229 | ||
e075ae69 RH |
4230 | (define_split |
4231 | [(set (match_operand:SI 0 "register_operand" "") | |
4232 | (fix:SI (match_operand 1 "register_operand" ""))) | |
4233 | (clobber (match_operand:SI 2 "memory_operand" "")) | |
4234 | (clobber (match_operand:SI 3 "memory_operand" "")) | |
4235 | (clobber (match_scratch:SI 4 ""))] | |
4236 | "reload_completed" | |
4237 | [(parallel [(set (match_dup 3) (fix:SI (match_dup 1))) | |
4238 | (clobber (match_dup 2)) | |
4239 | (clobber (match_dup 3)) | |
4240 | (clobber (match_dup 4))]) | |
4241 | (set (match_dup 0) (match_dup 3))] | |
bc725565 | 4242 | "") |
4fb21e90 | 4243 | |
46d21d2c JW |
4244 | ;; Signed conversion to HImode. |
4245 | ||
4246 | (define_expand "fix_truncxfhi2" | |
4247 | [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
4248 | (fix:HI (match_operand:XF 1 "register_operand" ""))) | |
4249 | (clobber (match_dup 2)) | |
4250 | (clobber (match_dup 3)) | |
4251 | (clobber (match_scratch:SI 4 ""))])] | |
4252 | "TARGET_80387" | |
4253 | "operands[2] = assign_386_stack_local (SImode, 0); | |
4254 | operands[3] = assign_386_stack_local (HImode, 1);") | |
4255 | ||
2b589241 JH |
4256 | (define_expand "fix_trunctfhi2" |
4257 | [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
4258 | (fix:HI (match_operand:TF 1 "register_operand" ""))) | |
4259 | (clobber (match_dup 2)) | |
4260 | (clobber (match_dup 3)) | |
4261 | (clobber (match_scratch:SI 4 ""))])] | |
4262 | "TARGET_80387" | |
4263 | "operands[2] = assign_386_stack_local (SImode, 0); | |
4264 | operands[3] = assign_386_stack_local (HImode, 1);") | |
4265 | ||
46d21d2c JW |
4266 | (define_expand "fix_truncdfhi2" |
4267 | [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
4268 | (fix:HI (match_operand:DF 1 "register_operand" ""))) | |
4269 | (clobber (match_dup 2)) | |
4270 | (clobber (match_dup 3)) | |
4271 | (clobber (match_scratch:SI 4 ""))])] | |
42a0aa6f | 4272 | "TARGET_80387 && !TARGET_SSE2" |
46d21d2c JW |
4273 | "operands[2] = assign_386_stack_local (SImode, 0); |
4274 | operands[3] = assign_386_stack_local (HImode, 1);") | |
4275 | ||
4276 | (define_expand "fix_truncsfhi2" | |
4277 | [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
4278 | (fix:HI (match_operand:SF 1 "register_operand" ""))) | |
4279 | (clobber (match_dup 2)) | |
4280 | (clobber (match_dup 3)) | |
4281 | (clobber (match_scratch:SI 4 ""))])] | |
42a0aa6f | 4282 | "TARGET_80387 && !TARGET_SSE" |
46d21d2c JW |
4283 | "operands[2] = assign_386_stack_local (SImode, 0); |
4284 | operands[3] = assign_386_stack_local (HImode, 1);") | |
4285 | ||
4286 | (define_insn "*fix_trunchi_1" | |
4287 | [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r") | |
4288 | (fix:HI (match_operand 1 "register_operand" "f,f"))) | |
4289 | (clobber (match_operand:SI 2 "memory_operand" "=o,o")) | |
4290 | (clobber (match_operand:HI 3 "memory_operand" "=m,m")) | |
4291 | (clobber (match_scratch:SI 4 "=&r,r"))] | |
42a0aa6f JH |
4292 | "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1])) |
4293 | && (TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" | |
46d21d2c JW |
4294 | "* return output_fix_trunc (insn, operands);" |
4295 | [(set_attr "type" "multi")]) | |
4296 | ||
4297 | (define_split | |
4298 | [(set (match_operand:HI 0 "register_operand" "") | |
4299 | (fix:HI (match_operand 1 "register_operand" ""))) | |
4300 | (clobber (match_operand:SI 2 "memory_operand" "")) | |
4301 | (clobber (match_operand:HI 3 "memory_operand" "")) | |
4302 | (clobber (match_scratch:SI 4 ""))] | |
4303 | "reload_completed" | |
4304 | [(parallel [(set (match_dup 3) (fix:HI (match_dup 1))) | |
4305 | (clobber (match_dup 2)) | |
4306 | (clobber (match_dup 3)) | |
4307 | (clobber (match_dup 4))]) | |
4308 | (set (match_dup 0) (match_dup 3))] | |
4309 | "") | |
4310 | ||
42a0aa6f JH |
4311 | ;; %%% Kill these when reload knows how to do it. |
4312 | (define_split | |
4313 | [(set (match_operand 0 "register_operand" "") | |
4314 | (fix (match_operand 1 "register_operand" "")))] | |
4315 | "reload_completed && FLOAT_MODE_P (GET_MODE (operands[1])) | |
4316 | && FP_REG_P (operands[1])" | |
4317 | [(const_int 0)] | |
4318 | " | |
4319 | { | |
4320 | operands[2] = ix86_force_to_memory (GET_MODE (operands[0]), operands[0]); | |
4321 | operands[2] = gen_rtx_FIX (GET_MODE (operands[2]), operands[1]); | |
4322 | emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1])); | |
4323 | emit_move_insn (operands[0], operands[2]); | |
4324 | ix86_free_from_memory (GET_MODE (operands[0])); | |
4325 | DONE; | |
4326 | }") | |
4327 | ||
e075ae69 RH |
4328 | ;; %% Not used yet. |
4329 | (define_insn "x86_fnstcw_1" | |
c76aab11 RH |
4330 | [(set (match_operand:HI 0 "memory_operand" "=m") |
4331 | (unspec:HI [(reg:HI 18)] 11))] | |
e1f998ad | 4332 | "TARGET_80387" |
e075ae69 | 4333 | "fnstcw\\t%0" |
6ef67412 JH |
4334 | [(set_attr "length" "2") |
4335 | (set_attr "mode" "HI") | |
4336 | (set_attr "i387" "1") | |
e075ae69 | 4337 | (set_attr "ppro_uops" "few")]) |
bc725565 | 4338 | |
e075ae69 RH |
4339 | (define_insn "x86_fldcw_1" |
4340 | [(set (reg:HI 18) | |
c76aab11 | 4341 | (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))] |
bc725565 | 4342 | "TARGET_80387" |
e075ae69 | 4343 | "fldcw\\t%0" |
6ef67412 JH |
4344 | [(set_attr "length" "2") |
4345 | (set_attr "mode" "HI") | |
4346 | (set_attr "i387" "1") | |
0b5107cf | 4347 | (set_attr "athlon_decode" "vector") |
e075ae69 RH |
4348 | (set_attr "ppro_uops" "few")]) |
4349 | \f | |
4350 | ;; Conversion between fixed point and floating point. | |
886c62d1 | 4351 | |
e075ae69 RH |
4352 | ;; Even though we only accept memory inputs, the backend _really_ |
4353 | ;; wants to be able to do this between registers. | |
4354 | ||
155d8a47 JW |
4355 | (define_insn "floathisf2" |
4356 | [(set (match_operand:SF 0 "register_operand" "=f,f") | |
4357 | (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))] | |
42a0aa6f | 4358 | "TARGET_80387 && !TARGET_SSE" |
155d8a47 JW |
4359 | "@ |
4360 | fild%z1\\t%1 | |
4361 | #" | |
4362 | [(set_attr "type" "fmov,multi") | |
6ef67412 | 4363 | (set_attr "mode" "SF") |
155d8a47 JW |
4364 | (set_attr "fp_int_src" "true")]) |
4365 | ||
42a0aa6f JH |
4366 | (define_expand "floatsisf2" |
4367 | [(set (match_operand:SF 0 "register_operand" "") | |
4368 | (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] | |
4369 | "TARGET_SSE || TARGET_80387" | |
4370 | "") | |
4371 | ||
4372 | (define_insn "*floatsisf2_i387" | |
4373 | [(set (match_operand:SF 0 "register_operand" "=f,?f,x") | |
4374 | (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))] | |
4375 | "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)" | |
e075ae69 RH |
4376 | "@ |
4377 | fild%z1\\t%1 | |
42a0aa6f JH |
4378 | # |
4379 | cvtsi2ss\\t{%1, %0|%0, %1}" | |
4380 | [(set_attr "type" "fmov,multi,sse") | |
4381 | (set_attr "mode" "SF") | |
4382 | (set_attr "fp_int_src" "true")]) | |
4383 | ||
4384 | (define_insn "*floatsisf2_sse" | |
4385 | [(set (match_operand:SF 0 "register_operand" "=x") | |
4386 | (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))] | |
4387 | "TARGET_80387 && TARGET_SSE" | |
4388 | "cvtsi2ss\\t{%1, %0|%0, %1}" | |
4389 | [(set_attr "type" "sse") | |
6ef67412 | 4390 | (set_attr "mode" "SF") |
e075ae69 | 4391 | (set_attr "fp_int_src" "true")]) |
bc725565 | 4392 | |
e075ae69 RH |
4393 | (define_insn "floatdisf2" |
4394 | [(set (match_operand:SF 0 "register_operand" "=f,f") | |
4395 | (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))] | |
4396 | "TARGET_80387" | |
4397 | "@ | |
4398 | fild%z1\\t%1 | |
4399 | #" | |
4400 | [(set_attr "type" "fmov,multi") | |
6ef67412 | 4401 | (set_attr "mode" "SF") |
e075ae69 | 4402 | (set_attr "fp_int_src" "true")]) |
bc725565 | 4403 | |
155d8a47 JW |
4404 | (define_insn "floathidf2" |
4405 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
4406 | (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))] | |
42a0aa6f | 4407 | "TARGET_80387 && !TARGET_SSE2" |
155d8a47 JW |
4408 | "@ |
4409 | fild%z1\\t%1 | |
4410 | #" | |
4411 | [(set_attr "type" "fmov,multi") | |
6ef67412 | 4412 | (set_attr "mode" "DF") |
155d8a47 JW |
4413 | (set_attr "fp_int_src" "true")]) |
4414 | ||
42a0aa6f JH |
4415 | (define_expand "floatsidf2" |
4416 | [(set (match_operand:DF 0 "register_operand" "") | |
4417 | (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] | |
4418 | "" | |
4419 | "") | |
4420 | ||
4421 | (define_insn "*floatsidf2_i387" | |
4422 | [(set (match_operand:DF 0 "register_operand" "=f,?f,Y") | |
4423 | (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))] | |
4424 | "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)" | |
e075ae69 RH |
4425 | "@ |
4426 | fild%z1\\t%1 | |
42a0aa6f JH |
4427 | # |
4428 | cvtsi2sd\\t{%1, %0|%0, %1}" | |
4429 | [(set_attr "type" "fmov,multi,sse") | |
4430 | (set_attr "mode" "DF") | |
4431 | (set_attr "fp_int_src" "true")]) | |
4432 | ||
4433 | (define_insn "*floatsidf2_sse" | |
4434 | [(set (match_operand:DF 0 "register_operand" "=Y") | |
4435 | (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))] | |
4436 | "TARGET_SSE2" | |
4437 | "cvtsi2sd\\t{%1, %0|%0, %1}" | |
4438 | [(set_attr "type" "sse") | |
6ef67412 | 4439 | (set_attr "mode" "DF") |
e075ae69 | 4440 | (set_attr "fp_int_src" "true")]) |
e1f998ad | 4441 | |
e075ae69 RH |
4442 | (define_insn "floatdidf2" |
4443 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
4444 | (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))] | |
42a0aa6f | 4445 | "TARGET_80387 && TARGET_SSE2" |
e075ae69 RH |
4446 | "@ |
4447 | fild%z1\\t%1 | |
4448 | #" | |
4449 | [(set_attr "type" "fmov,multi") | |
6ef67412 | 4450 | (set_attr "mode" "DF") |
e075ae69 | 4451 | (set_attr "fp_int_src" "true")]) |
bc725565 | 4452 | |
155d8a47 JW |
4453 | (define_insn "floathixf2" |
4454 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
4455 | (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))] | |
1e07edd3 | 4456 | "TARGET_80387 && !TARGET_64BIT" |
155d8a47 JW |
4457 | "@ |
4458 | fild%z1\\t%1 | |
4459 | #" | |
4460 | [(set_attr "type" "fmov,multi") | |
6ef67412 | 4461 | (set_attr "mode" "XF") |
155d8a47 JW |
4462 | (set_attr "fp_int_src" "true")]) |
4463 | ||
2b589241 JH |
4464 | (define_insn "floathitf2" |
4465 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
4466 | (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))] | |
4467 | "TARGET_80387" | |
4468 | "@ | |
4469 | fild%z1\\t%1 | |
4470 | #" | |
4471 | [(set_attr "type" "fmov,multi") | |
4472 | (set_attr "mode" "XF") | |
4473 | (set_attr "fp_int_src" "true")]) | |
4474 | ||
e075ae69 RH |
4475 | (define_insn "floatsixf2" |
4476 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
4477 | (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))] | |
1e07edd3 | 4478 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
4479 | "@ |
4480 | fild%z1\\t%1 | |
4481 | #" | |
4482 | [(set_attr "type" "fmov,multi") | |
6ef67412 | 4483 | (set_attr "mode" "XF") |
e075ae69 | 4484 | (set_attr "fp_int_src" "true")]) |
53b5ce19 | 4485 | |
2b589241 JH |
4486 | (define_insn "floatsitf2" |
4487 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
4488 | (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))] | |
4489 | "TARGET_80387" | |
4490 | "@ | |
4491 | fild%z1\\t%1 | |
4492 | #" | |
4493 | [(set_attr "type" "fmov,multi") | |
4494 | (set_attr "mode" "XF") | |
4495 | (set_attr "fp_int_src" "true")]) | |
4496 | ||
e075ae69 | 4497 | (define_insn "floatdixf2" |
53b5ce19 | 4498 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
e075ae69 | 4499 | (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))] |
1e07edd3 | 4500 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
4501 | "@ |
4502 | fild%z1\\t%1 | |
4503 | #" | |
4504 | [(set_attr "type" "fmov,multi") | |
6ef67412 | 4505 | (set_attr "mode" "XF") |
e075ae69 | 4506 | (set_attr "fp_int_src" "true")]) |
53b5ce19 | 4507 | |
2b589241 JH |
4508 | (define_insn "floatditf2" |
4509 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
4510 | (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))] | |
4511 | "TARGET_80387" | |
4512 | "@ | |
4513 | fild%z1\\t%1 | |
4514 | #" | |
4515 | [(set_attr "type" "fmov,multi") | |
4516 | (set_attr "mode" "XF") | |
4517 | (set_attr "fp_int_src" "true")]) | |
4518 | ||
e075ae69 | 4519 | ;; %%% Kill these when reload knows how to do it. |
155d8a47 JW |
4520 | (define_split |
4521 | [(set (match_operand 0 "register_operand" "") | |
4211a8fb | 4522 | (float (match_operand 1 "register_operand" "")))] |
bf71a4f8 JH |
4523 | "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0])) |
4524 | && FP_REG_P (operands[0])" | |
4211a8fb JH |
4525 | [(const_int 0)] |
4526 | " | |
4527 | { | |
4528 | operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); | |
4529 | operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]); | |
4530 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2])); | |
4531 | ix86_free_from_memory (GET_MODE (operands[1])); | |
4532 | DONE; | |
4533 | }") | |
e075ae69 RH |
4534 | \f |
4535 | ;; Add instructions | |
53b5ce19 | 4536 | |
e075ae69 RH |
4537 | ;; %%% define_expand from the very first? |
4538 | ;; %%% splits for addsidi3 | |
4539 | ; [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
4540 | ; (plus:DI (match_operand:DI 1 "general_operand" "") | |
4541 | ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))] | |
e1f998ad | 4542 | |
e075ae69 RH |
4543 | (define_insn "adddi3" |
4544 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") | |
4545 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") | |
4546 | (match_operand:DI 2 "general_operand" "roiF,riF"))) | |
4547 | (clobber (reg:CC 17))] | |
4548 | "" | |
bc725565 JW |
4549 | "#") |
4550 | ||
4551 | (define_split | |
e075ae69 | 4552 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
4cbfbb1b | 4553 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") |
e075ae69 RH |
4554 | (match_operand:DI 2 "general_operand" ""))) |
4555 | (clobber (reg:CC 17))] | |
1e07edd3 | 4556 | "reload_completed && !TARGET_64BIT" |
7e08e190 | 4557 | [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12)) |
e075ae69 RH |
4558 | (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) |
4559 | (parallel [(set (match_dup 3) | |
7e08e190 | 4560 | (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0)) |
9dcbdc7e JH |
4561 | (match_dup 4)) |
4562 | (match_dup 5))) | |
e075ae69 RH |
4563 | (clobber (reg:CC 17))])] |
4564 | "split_di (operands+0, 1, operands+0, operands+3); | |
4565 | split_di (operands+1, 1, operands+1, operands+4); | |
4566 | split_di (operands+2, 1, operands+2, operands+5);") | |
4567 | ||
7abd4e00 | 4568 | (define_insn "*addsi3_carry" |
e075ae69 | 4569 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
9dcbdc7e JH |
4570 | (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0)) |
4571 | (match_operand:SI 1 "nonimmediate_operand" "%0,0")) | |
4572 | (match_operand:SI 2 "general_operand" "ri,rm"))) | |
e075ae69 | 4573 | (clobber (reg:CC 17))] |
d525dfdf | 4574 | "ix86_binary_operator_ok (PLUS, SImode, operands)" |
e075ae69 RH |
4575 | "adc{l}\\t{%2, %0|%0, %2}" |
4576 | [(set_attr "type" "alu") | |
4577 | (set_attr "pent_pair" "pu") | |
6ef67412 | 4578 | (set_attr "mode" "SI") |
e075ae69 | 4579 | (set_attr "ppro_uops" "few")]) |
4fb21e90 | 4580 | |
7e08e190 JH |
4581 | (define_insn "*addsi3_cc" |
4582 | [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
4583 | (match_operand:SI 2 "general_operand" "ri,rm")] 12)) | |
4584 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
4585 | (plus:SI (match_dup 1) (match_dup 2)))] | |
265dab10 | 4586 | "ix86_binary_operator_ok (PLUS, SImode, operands)" |
7e08e190 | 4587 | "add{l}\\t{%2, %0|%0, %2}" |
265dab10 | 4588 | [(set_attr "type" "alu") |
7e08e190 JH |
4589 | (set_attr "mode" "SI")]) |
4590 | ||
4591 | (define_insn "addqi3_cc" | |
4592 | [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0") | |
4593 | (match_operand:QI 2 "general_operand" "qi,qm")] 12)) | |
4594 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") | |
4595 | (plus:QI (match_dup 1) (match_dup 2)))] | |
4596 | "ix86_binary_operator_ok (PLUS, QImode, operands)" | |
4597 | "add{b}\\t{%2, %0|%0, %2}" | |
4598 | [(set_attr "type" "alu") | |
4599 | (set_attr "mode" "QI")]) | |
265dab10 | 4600 | |
e075ae69 RH |
4601 | (define_expand "addsi3" |
4602 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
4603 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
4604 | (match_operand:SI 2 "general_operand" ""))) | |
4605 | (clobber (reg:CC 17))])] | |
4606 | "" | |
4607 | "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;") | |
886c62d1 | 4608 | |
ad678cb0 | 4609 | (define_insn "*lea_0" |
e075ae69 | 4610 | [(set (match_operand:SI 0 "register_operand" "=r") |
ad678cb0 | 4611 | (match_operand:SI 1 "address_operand" "p"))] |
f58acb67 | 4612 | "" |
ad678cb0 | 4613 | "lea{l}\\t{%a1, %0|%0, %a1}" |
6ef67412 JH |
4614 | [(set_attr "type" "lea") |
4615 | (set_attr "mode" "SI")]) | |
2ae0f82c | 4616 | |
58787064 JH |
4617 | ;; The lea patterns for non-Pmodes needs to be matched by several |
4618 | ;; insns converted to real lea by splitters. | |
4619 | ||
4620 | (define_insn_and_split "*lea_general_1" | |
4621 | [(set (match_operand 0 "register_operand" "=r") | |
4622 | (plus (plus (match_operand 1 "register_operand" "r") | |
4623 | (match_operand 2 "register_operand" "r")) | |
4624 | (match_operand 3 "immediate_operand" "i")))] | |
4625 | "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) | |
4626 | && (!TARGET_PARTIAL_REG_STALL || optimize_size) | |
4627 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
4628 | && GET_MODE (operands[0]) == GET_MODE (operands[2]) | |
4629 | && (GET_MODE (operands[0]) == GET_MODE (operands[3]) | |
4630 | || GET_MODE (operands[3]) == VOIDmode)" | |
4631 | "#" | |
cb694d2c | 4632 | "&& reload_completed" |
58787064 JH |
4633 | [(const_int 0)] |
4634 | " | |
4635 | { | |
4636 | rtx pat; | |
4637 | operands[0] = gen_lowpart (SImode, operands[0]); | |
4638 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
4639 | operands[2] = gen_lowpart (Pmode, operands[2]); | |
4640 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
4641 | pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]), | |
4642 | operands[3]); | |
4643 | if (Pmode != SImode) | |
4644 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
4645 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
4646 | DONE; | |
4647 | }" | |
4648 | [(set_attr "type" "lea") | |
4649 | (set_attr "mode" "SI")]) | |
4650 | ||
4651 | (define_insn_and_split "*lea_general_2" | |
4652 | [(set (match_operand 0 "register_operand" "=r") | |
4653 | (plus (mult (match_operand 1 "register_operand" "r") | |
4654 | (match_operand 2 "const248_operand" "i")) | |
4655 | (match_operand 3 "nonmemory_operand" "ri")))] | |
4656 | "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) | |
4657 | && (!TARGET_PARTIAL_REG_STALL || optimize_size) | |
4658 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
4659 | && (GET_MODE (operands[0]) == GET_MODE (operands[3]) | |
4660 | || GET_MODE (operands[3]) == VOIDmode)" | |
4661 | "#" | |
cb694d2c | 4662 | "&& reload_completed" |
58787064 JH |
4663 | [(const_int 0)] |
4664 | " | |
4665 | { | |
4666 | rtx pat; | |
4667 | operands[0] = gen_lowpart (SImode, operands[0]); | |
4668 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
4669 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
4670 | pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]), | |
4671 | operands[3]); | |
4672 | if (Pmode != SImode) | |
4673 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
4674 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
4675 | DONE; | |
4676 | }" | |
4677 | [(set_attr "type" "lea") | |
4678 | (set_attr "mode" "SI")]) | |
4679 | ||
4680 | (define_insn_and_split "*lea_general_3" | |
4681 | [(set (match_operand 0 "register_operand" "=r") | |
4682 | (plus (plus (mult (match_operand 1 "register_operand" "r") | |
4683 | (match_operand 2 "const248_operand" "i")) | |
4684 | (match_operand 3 "register_operand" "r")) | |
4685 | (match_operand 4 "immediate_operand" "i")))] | |
4686 | "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) | |
4687 | && (!TARGET_PARTIAL_REG_STALL || optimize_size) | |
4688 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
4689 | && GET_MODE (operands[0]) == GET_MODE (operands[3])" | |
4690 | "#" | |
cb694d2c | 4691 | "&& reload_completed" |
58787064 JH |
4692 | [(const_int 0)] |
4693 | " | |
4694 | { | |
4695 | rtx pat; | |
4696 | operands[0] = gen_lowpart (SImode, operands[0]); | |
4697 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
4698 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
4699 | operands[4] = gen_lowpart (Pmode, operands[4]); | |
4700 | pat = gen_rtx_PLUS (Pmode, | |
4701 | gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], | |
4702 | operands[2]), | |
4703 | operands[3]), | |
4704 | operands[4]); | |
4705 | if (Pmode != SImode) | |
4706 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
4707 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
4708 | DONE; | |
4709 | }" | |
4710 | [(set_attr "type" "lea") | |
4711 | (set_attr "mode" "SI")]) | |
4712 | ||
e075ae69 RH |
4713 | (define_insn "*addsi_1" |
4714 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") | |
4715 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") | |
4716 | (match_operand:SI 2 "general_operand" "rmni,rni,rni"))) | |
4717 | (clobber (reg:CC 17))] | |
4718 | "ix86_binary_operator_ok (PLUS, SImode, operands)" | |
2ae0f82c SC |
4719 | "* |
4720 | { | |
e075ae69 | 4721 | switch (get_attr_type (insn)) |
2ae0f82c | 4722 | { |
e075ae69 RH |
4723 | case TYPE_LEA: |
4724 | operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); | |
4725 | return \"lea{l}\\t{%a2, %0|%0, %a2}\"; | |
2ae0f82c | 4726 | |
e075ae69 RH |
4727 | case TYPE_INCDEC: |
4728 | if (! rtx_equal_p (operands[0], operands[1])) | |
4729 | abort (); | |
4730 | if (operands[2] == const1_rtx) | |
4731 | return \"inc{l}\\t%0\"; | |
4732 | else if (operands[2] == constm1_rtx) | |
4733 | return \"dec{l}\\t%0\"; | |
2ae0f82c | 4734 | else |
e075ae69 | 4735 | abort(); |
2ae0f82c | 4736 | |
e075ae69 RH |
4737 | default: |
4738 | if (! rtx_equal_p (operands[0], operands[1])) | |
4739 | abort (); | |
2ae0f82c | 4740 | |
e075ae69 RH |
4741 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
4742 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
4743 | if (GET_CODE (operands[2]) == CONST_INT | |
4744 | && (INTVAL (operands[2]) == 128 | |
4745 | || (INTVAL (operands[2]) < 0 | |
4746 | && INTVAL (operands[2]) != -128))) | |
4747 | { | |
4748 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
4749 | return \"sub{l}\\t{%2, %0|%0, %2}\"; | |
4750 | } | |
4751 | return \"add{l}\\t{%2, %0|%0, %2}\"; | |
4752 | } | |
4753 | }" | |
4754 | [(set (attr "type") | |
4755 | (cond [(eq_attr "alternative" "2") | |
4756 | (const_string "lea") | |
4757 | ; Current assemblers are broken and do not allow @GOTOFF in | |
4758 | ; ought but a memory context. | |
4759 | (match_operand:SI 2 "pic_symbolic_operand" "") | |
4760 | (const_string "lea") | |
4761 | (match_operand:SI 2 "incdec_operand" "") | |
4762 | (const_string "incdec") | |
4763 | ] | |
6ef67412 JH |
4764 | (const_string "alu"))) |
4765 | (set_attr "mode" "SI")]) | |
e075ae69 | 4766 | |
1c27d4b2 JH |
4767 | ;; Convert lea to the lea pattern to avoid flags dependency. |
4768 | (define_split | |
58787064 JH |
4769 | [(set (match_operand 0 "register_operand" "") |
4770 | (plus (match_operand 1 "register_operand" "") | |
4771 | (match_operand 2 "nonmemory_operand" ""))) | |
1c27d4b2 | 4772 | (clobber (reg:CC 17))] |
abe24fb3 JH |
4773 | "reload_completed |
4774 | && true_regnum (operands[0]) != true_regnum (operands[1])" | |
58787064 JH |
4775 | [(const_int 0)] |
4776 | " | |
4777 | { | |
4778 | rtx pat; | |
58787064 JH |
4779 | /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) |
4780 | may confuse gen_lowpart. */ | |
4781 | if (GET_MODE (operands[0]) != Pmode) | |
4782 | { | |
4783 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
4784 | operands[2] = gen_lowpart (Pmode, operands[2]); | |
4785 | } | |
91f9a498 | 4786 | operands[0] = gen_lowpart (SImode, operands[0]); |
58787064 JH |
4787 | pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); |
4788 | if (Pmode != SImode) | |
4789 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
4790 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
4791 | DONE; | |
4792 | }") | |
1c27d4b2 | 4793 | |
e075ae69 | 4794 | (define_insn "*addsi_2" |
16189740 RH |
4795 | [(set (reg 17) |
4796 | (compare | |
e075ae69 RH |
4797 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") |
4798 | (match_operand:SI 2 "general_operand" "rmni,rni")) | |
4799 | (const_int 0))) | |
4800 | (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") | |
4801 | (plus:SI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 4802 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 4803 | && ix86_binary_operator_ok (PLUS, SImode, operands) |
e075ae69 RH |
4804 | /* Current assemblers are broken and do not allow @GOTOFF in |
4805 | ought but a memory context. */ | |
4806 | && ! pic_symbolic_operand (operands[2], VOIDmode)" | |
886c62d1 JVA |
4807 | "* |
4808 | { | |
e075ae69 | 4809 | switch (get_attr_type (insn)) |
96f218bb | 4810 | { |
e075ae69 RH |
4811 | case TYPE_INCDEC: |
4812 | if (! rtx_equal_p (operands[0], operands[1])) | |
4813 | abort (); | |
4814 | if (operands[2] == const1_rtx) | |
4815 | return \"inc{l}\\t%0\"; | |
4816 | else if (operands[2] == constm1_rtx) | |
4817 | return \"dec{l}\\t%0\"; | |
96f218bb | 4818 | else |
e075ae69 | 4819 | abort(); |
96f218bb | 4820 | |
e075ae69 RH |
4821 | default: |
4822 | if (! rtx_equal_p (operands[0], operands[1])) | |
4823 | abort (); | |
4824 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
4825 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
4826 | if (GET_CODE (operands[2]) == CONST_INT | |
4827 | && (INTVAL (operands[2]) == 128 | |
4828 | || (INTVAL (operands[2]) < 0 | |
4829 | && INTVAL (operands[2]) != -128))) | |
4830 | { | |
4831 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
4832 | return \"sub{l}\\t{%2, %0|%0, %2}\"; | |
4833 | } | |
4834 | return \"add{l}\\t{%2, %0|%0, %2}\"; | |
9c530261 | 4835 | } |
a269a03c | 4836 | }" |
e075ae69 RH |
4837 | [(set (attr "type") |
4838 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
4839 | (const_string "incdec") | |
6ef67412 JH |
4840 | (const_string "alu"))) |
4841 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
4842 | |
4843 | (define_insn "*addsi_3" | |
d90ffc8d | 4844 | [(set (reg 17) |
7e08e190 JH |
4845 | (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) |
4846 | (match_operand:SI 1 "nonimmediate_operand" "%0"))) | |
d90ffc8d | 4847 | (clobber (match_scratch:SI 0 "=r"))] |
7e08e190 | 4848 | "ix86_match_ccmode (insn, CCZmode) |
d90ffc8d JH |
4849 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) |
4850 | /* Current assemblers are broken and do not allow @GOTOFF in | |
4851 | ought but a memory context. */ | |
4852 | && ! pic_symbolic_operand (operands[2], VOIDmode)" | |
4853 | "* | |
4854 | { | |
4855 | switch (get_attr_type (insn)) | |
4856 | { | |
4857 | case TYPE_INCDEC: | |
4858 | if (! rtx_equal_p (operands[0], operands[1])) | |
4859 | abort (); | |
4860 | if (operands[2] == const1_rtx) | |
4861 | return \"inc{l}\\t%0\"; | |
4862 | else if (operands[2] == constm1_rtx) | |
4863 | return \"dec{l}\\t%0\"; | |
4864 | else | |
4865 | abort(); | |
4866 | ||
4867 | default: | |
4868 | if (! rtx_equal_p (operands[0], operands[1])) | |
4869 | abort (); | |
4870 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
4871 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
4872 | if (GET_CODE (operands[2]) == CONST_INT | |
4873 | && (INTVAL (operands[2]) == 128 | |
4874 | || (INTVAL (operands[2]) < 0 | |
4875 | && INTVAL (operands[2]) != -128))) | |
4876 | { | |
4877 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
4878 | return \"sub{l}\\t{%2, %0|%0, %2}\"; | |
4879 | } | |
4880 | return \"add{l}\\t{%2, %0|%0, %2}\"; | |
4881 | } | |
4882 | }" | |
4883 | [(set (attr "type") | |
4884 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
4885 | (const_string "incdec") | |
4886 | (const_string "alu"))) | |
4887 | (set_attr "mode" "SI")]) | |
4888 | ||
7e08e190 JH |
4889 | ; For comparisons agains 1, -1 and 128, we may generate better code |
4890 | ; by converting cmp to add, inc or dec as done by peephole2. This pattern | |
4891 | ; is matched then. We can't accept general immediate, because for | |
4892 | ; case of overflows, the result is messed up. | |
4893 | ; This pattern also don't hold of 0x80000000, since the value overflows | |
4894 | ; when negated. | |
4895 | ; Also carry flag is reversed compared to cmp, so this converison is valid | |
4896 | ; only for comparisons not depending on it. | |
d90ffc8d | 4897 | (define_insn "*addsi_4" |
9076b9c1 | 4898 | [(set (reg 17) |
7e08e190 JH |
4899 | (compare (match_operand:SI 1 "nonimmediate_operand" "0") |
4900 | (match_operand:SI 2 "const_int_operand" "n"))) | |
4901 | (clobber (match_scratch:SI 0 "=rm"))] | |
4902 | "ix86_match_ccmode (insn, CCGCmode) | |
4903 | && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000" | |
4904 | "* | |
4905 | { | |
4906 | switch (get_attr_type (insn)) | |
4907 | { | |
4908 | case TYPE_INCDEC: | |
4909 | if (operands[2] == constm1_rtx) | |
4910 | return \"inc{l}\\t%0\"; | |
4911 | else if (operands[2] == const1_rtx) | |
4912 | return \"dec{l}\\t%0\"; | |
4913 | else | |
4914 | abort(); | |
e075ae69 | 4915 | |
7e08e190 JH |
4916 | default: |
4917 | if (! rtx_equal_p (operands[0], operands[1])) | |
4918 | abort (); | |
4919 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
4920 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
4921 | if ((INTVAL (operands[2]) == -128 | |
4922 | || (INTVAL (operands[2]) > 0 | |
4923 | && INTVAL (operands[2]) != 128))) | |
4924 | return \"sub{l}\\t{%2, %0|%0, %2}\"; | |
4925 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
4926 | return \"add{l}\\t{%2, %0|%0, %2}\"; | |
4927 | } | |
4928 | }" | |
4929 | [(set (attr "type") | |
4930 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
4931 | (const_string "incdec") | |
4932 | (const_string "alu"))) | |
d90ffc8d JH |
4933 | (set_attr "mode" "SI")]) |
4934 | ||
7e08e190 | 4935 | (define_insn "*addsi_5" |
9076b9c1 JH |
4936 | [(set (reg 17) |
4937 | (compare | |
4938 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") | |
4939 | (match_operand:SI 2 "general_operand" "rmni")) | |
4940 | (const_int 0))) | |
4941 | (clobber (match_scratch:SI 0 "=r"))] | |
4942 | "ix86_match_ccmode (insn, CCGOCmode) | |
4943 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) | |
4944 | /* Current assemblers are broken and do not allow @GOTOFF in | |
4945 | ought but a memory context. */ | |
4946 | && ! pic_symbolic_operand (operands[2], VOIDmode)" | |
4947 | "* | |
4948 | { | |
4949 | switch (get_attr_type (insn)) | |
4950 | { | |
4951 | case TYPE_INCDEC: | |
4952 | if (! rtx_equal_p (operands[0], operands[1])) | |
4953 | abort (); | |
4954 | if (operands[2] == const1_rtx) | |
4955 | return \"inc{l}\\t%0\"; | |
4956 | else if (operands[2] == constm1_rtx) | |
4957 | return \"dec{l}\\t%0\"; | |
4958 | else | |
4959 | abort(); | |
4960 | ||
4961 | default: | |
4962 | if (! rtx_equal_p (operands[0], operands[1])) | |
4963 | abort (); | |
4964 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
4965 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
4966 | if (GET_CODE (operands[2]) == CONST_INT | |
4967 | && (INTVAL (operands[2]) == 128 | |
4968 | || (INTVAL (operands[2]) < 0 | |
4969 | && INTVAL (operands[2]) != -128))) | |
4970 | { | |
4971 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
4972 | return \"sub{l}\\t{%2, %0|%0, %2}\"; | |
4973 | } | |
4974 | return \"add{l}\\t{%2, %0|%0, %2}\"; | |
4975 | } | |
4976 | }" | |
4977 | [(set (attr "type") | |
4978 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
4979 | (const_string "incdec") | |
4980 | (const_string "alu"))) | |
4981 | (set_attr "mode" "SI")]) | |
4982 | ||
2ae0f82c | 4983 | (define_expand "addhi3" |
4cbfbb1b | 4984 | [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") |
e075ae69 RH |
4985 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") |
4986 | (match_operand:HI 2 "general_operand" ""))) | |
4987 | (clobber (reg:CC 17))])] | |
d9f32422 | 4988 | "TARGET_HIMODE_MATH" |
e075ae69 | 4989 | "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;") |
2ae0f82c | 4990 | |
e075ae69 RH |
4991 | ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah |
4992 | ;; type optimizations enabled by define-splits. This is not important | |
4993 | ;; for PII, and in fact harmful because of partial register stalls. | |
4994 | ||
58787064 JH |
4995 | (define_insn "*addhi_1_lea" |
4996 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") | |
4997 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") | |
4998 | (match_operand:HI 2 "general_operand" "ri,rm,rni"))) | |
4999 | (clobber (reg:CC 17))] | |
5000 | "!TARGET_PARTIAL_REG_STALL | |
5001 | && ix86_binary_operator_ok (PLUS, HImode, operands)" | |
5002 | "* | |
5003 | { | |
5004 | switch (get_attr_type (insn)) | |
5005 | { | |
5006 | case TYPE_LEA: | |
5007 | return \"#\"; | |
5008 | case TYPE_INCDEC: | |
5009 | if (operands[2] == const1_rtx) | |
5010 | return \"inc{w}\\t%0\"; | |
5011 | else if (operands[2] == constm1_rtx | |
5012 | || (GET_CODE (operands[2]) == CONST_INT | |
5013 | && INTVAL (operands[2]) == 65535)) | |
5014 | return \"dec{w}\\t%0\"; | |
5015 | abort(); | |
5016 | ||
5017 | default: | |
5018 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
5019 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
5020 | if (GET_CODE (operands[2]) == CONST_INT | |
5021 | && (INTVAL (operands[2]) == 128 | |
5022 | || (INTVAL (operands[2]) < 0 | |
5023 | && INTVAL (operands[2]) != -128))) | |
5024 | { | |
5025 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5026 | return \"sub{w}\\t{%2, %0|%0, %2}\"; | |
5027 | } | |
5028 | return \"add{w}\\t{%2, %0|%0, %2}\"; | |
5029 | } | |
5030 | }" | |
5031 | [(set (attr "type") | |
5032 | (if_then_else (eq_attr "alternative" "2") | |
5033 | (const_string "lea") | |
5034 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
5035 | (const_string "incdec") | |
5036 | (const_string "alu")))) | |
5037 | (set_attr "mode" "HI,HI,SI")]) | |
5038 | ||
e075ae69 RH |
5039 | (define_insn "*addhi_1" |
5040 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
5041 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
5042 | (match_operand:HI 2 "general_operand" "ri,rm"))) | |
5043 | (clobber (reg:CC 17))] | |
58787064 JH |
5044 | "TARGET_PARTIAL_REG_STALL |
5045 | && ix86_binary_operator_ok (PLUS, HImode, operands)" | |
886c62d1 JVA |
5046 | "* |
5047 | { | |
e075ae69 | 5048 | switch (get_attr_type (insn)) |
7c802a40 | 5049 | { |
e075ae69 RH |
5050 | case TYPE_INCDEC: |
5051 | if (operands[2] == const1_rtx) | |
5052 | return \"inc{w}\\t%0\"; | |
5053 | else if (operands[2] == constm1_rtx | |
5054 | || (GET_CODE (operands[2]) == CONST_INT | |
5055 | && INTVAL (operands[2]) == 65535)) | |
5056 | return \"dec{w}\\t%0\"; | |
5057 | abort(); | |
7c802a40 | 5058 | |
e075ae69 RH |
5059 | default: |
5060 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
5061 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
5062 | if (GET_CODE (operands[2]) == CONST_INT | |
5063 | && (INTVAL (operands[2]) == 128 | |
5064 | || (INTVAL (operands[2]) < 0 | |
5065 | && INTVAL (operands[2]) != -128))) | |
5066 | { | |
5067 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5068 | return \"sub{w}\\t{%2, %0|%0, %2}\"; | |
5069 | } | |
5070 | return \"add{w}\\t{%2, %0|%0, %2}\"; | |
7c802a40 | 5071 | } |
e075ae69 RH |
5072 | }" |
5073 | [(set (attr "type") | |
5074 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
5075 | (const_string "incdec") | |
6ef67412 JH |
5076 | (const_string "alu"))) |
5077 | (set_attr "mode" "HI")]) | |
7c802a40 | 5078 | |
e075ae69 | 5079 | (define_insn "*addhi_2" |
16189740 RH |
5080 | [(set (reg 17) |
5081 | (compare | |
e075ae69 RH |
5082 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") |
5083 | (match_operand:HI 2 "general_operand" "rmni,rni")) | |
5084 | (const_int 0))) | |
5085 | (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") | |
5086 | (plus:HI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 5087 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 5088 | && ix86_binary_operator_ok (PLUS, HImode, operands)" |
e075ae69 RH |
5089 | "* |
5090 | { | |
5091 | switch (get_attr_type (insn)) | |
b980bec0 | 5092 | { |
e075ae69 RH |
5093 | case TYPE_INCDEC: |
5094 | if (operands[2] == const1_rtx) | |
5095 | return \"inc{w}\\t%0\"; | |
5096 | else if (operands[2] == constm1_rtx | |
5097 | || (GET_CODE (operands[2]) == CONST_INT | |
5098 | && INTVAL (operands[2]) == 65535)) | |
5099 | return \"dec{w}\\t%0\"; | |
5100 | abort(); | |
b980bec0 | 5101 | |
e075ae69 RH |
5102 | default: |
5103 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
5104 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
5105 | if (GET_CODE (operands[2]) == CONST_INT | |
5106 | && (INTVAL (operands[2]) == 128 | |
5107 | || (INTVAL (operands[2]) < 0 | |
5108 | && INTVAL (operands[2]) != -128))) | |
5109 | { | |
5110 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5111 | return \"sub{w}\\t{%2, %0|%0, %2}\"; | |
5112 | } | |
5113 | return \"add{w}\\t{%2, %0|%0, %2}\"; | |
b980bec0 | 5114 | } |
e075ae69 RH |
5115 | }" |
5116 | [(set (attr "type") | |
5117 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
5118 | (const_string "incdec") | |
6ef67412 JH |
5119 | (const_string "alu"))) |
5120 | (set_attr "mode" "HI")]) | |
e075ae69 RH |
5121 | |
5122 | (define_insn "*addhi_3" | |
d90ffc8d | 5123 | [(set (reg 17) |
7e08e190 JH |
5124 | (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) |
5125 | (match_operand:HI 1 "nonimmediate_operand" "%0"))) | |
d90ffc8d | 5126 | (clobber (match_scratch:HI 0 "=r"))] |
7e08e190 | 5127 | "ix86_match_ccmode (insn, CCZmode) |
d90ffc8d JH |
5128 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" |
5129 | "* | |
5130 | { | |
5131 | switch (get_attr_type (insn)) | |
5132 | { | |
5133 | case TYPE_INCDEC: | |
5134 | if (operands[2] == const1_rtx) | |
5135 | return \"inc{w}\\t%0\"; | |
5136 | else if (operands[2] == constm1_rtx | |
5137 | || (GET_CODE (operands[2]) == CONST_INT | |
5138 | && INTVAL (operands[2]) == 65535)) | |
5139 | return \"dec{w}\\t%0\"; | |
5140 | abort(); | |
5141 | ||
5142 | default: | |
5143 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
5144 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
5145 | if (GET_CODE (operands[2]) == CONST_INT | |
5146 | && (INTVAL (operands[2]) == 128 | |
5147 | || (INTVAL (operands[2]) < 0 | |
5148 | && INTVAL (operands[2]) != -128))) | |
5149 | { | |
5150 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5151 | return \"sub{w}\\t{%2, %0|%0, %2}\"; | |
5152 | } | |
5153 | return \"add{w}\\t{%2, %0|%0, %2}\"; | |
5154 | } | |
5155 | }" | |
5156 | [(set (attr "type") | |
5157 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
5158 | (const_string "incdec") | |
5159 | (const_string "alu"))) | |
5160 | (set_attr "mode" "HI")]) | |
5161 | ||
7e08e190 | 5162 | ; See comments above addsi_3_imm for details. |
d90ffc8d | 5163 | (define_insn "*addhi_4" |
9076b9c1 | 5164 | [(set (reg 17) |
7e08e190 JH |
5165 | (compare (match_operand:HI 1 "nonimmediate_operand" "0") |
5166 | (match_operand:HI 2 "const_int_operand" "n"))) | |
5167 | (clobber (match_scratch:HI 0 "=rm"))] | |
5168 | "ix86_match_ccmode (insn, CCGCmode) | |
5169 | && (INTVAL (operands[2]) & 0xffff) != 0x8000" | |
5170 | "* | |
5171 | { | |
5172 | switch (get_attr_type (insn)) | |
5173 | { | |
5174 | case TYPE_INCDEC: | |
5175 | if (operands[2] == constm1_rtx | |
5176 | || (GET_CODE (operands[2]) == CONST_INT | |
5177 | && INTVAL (operands[2]) == 65535)) | |
5178 | return \"inc{w}\\t%0\"; | |
5179 | else if (operands[2] == const1_rtx) | |
5180 | return \"dec{w}\\t%0\"; | |
5181 | else | |
5182 | abort(); | |
5183 | ||
5184 | default: | |
5185 | if (! rtx_equal_p (operands[0], operands[1])) | |
5186 | abort (); | |
5187 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
5188 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
5189 | if ((INTVAL (operands[2]) == -128 | |
5190 | || (INTVAL (operands[2]) > 0 | |
5191 | && INTVAL (operands[2]) != 128))) | |
5192 | return \"sub{w}\\t{%2, %0|%0, %2}\"; | |
5193 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5194 | return \"add{w}\\t{%2, %0|%0, %2}\"; | |
5195 | } | |
5196 | }" | |
5197 | [(set (attr "type") | |
5198 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
5199 | (const_string "incdec") | |
5200 | (const_string "alu"))) | |
5201 | (set_attr "mode" "SI")]) | |
b980bec0 | 5202 | |
d90ffc8d | 5203 | |
7e08e190 | 5204 | (define_insn "*addhi_5" |
9076b9c1 JH |
5205 | [(set (reg 17) |
5206 | (compare | |
5207 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") | |
5208 | (match_operand:HI 2 "general_operand" "rmni")) | |
5209 | (const_int 0))) | |
5210 | (clobber (match_scratch:HI 0 "=r"))] | |
5211 | "ix86_match_ccmode (insn, CCGOCmode) | |
5212 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
5213 | "* | |
5214 | { | |
5215 | switch (get_attr_type (insn)) | |
5216 | { | |
5217 | case TYPE_INCDEC: | |
5218 | if (operands[2] == const1_rtx) | |
5219 | return \"inc{w}\\t%0\"; | |
5220 | else if (operands[2] == constm1_rtx | |
5221 | || (GET_CODE (operands[2]) == CONST_INT | |
5222 | && INTVAL (operands[2]) == 65535)) | |
5223 | return \"dec{w}\\t%0\"; | |
5224 | abort(); | |
5225 | ||
5226 | default: | |
5227 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
5228 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
5229 | if (GET_CODE (operands[2]) == CONST_INT | |
5230 | && (INTVAL (operands[2]) == 128 | |
5231 | || (INTVAL (operands[2]) < 0 | |
5232 | && INTVAL (operands[2]) != -128))) | |
5233 | { | |
5234 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5235 | return \"sub{w}\\t{%2, %0|%0, %2}\"; | |
5236 | } | |
5237 | return \"add{w}\\t{%2, %0|%0, %2}\"; | |
5238 | } | |
5239 | }" | |
5240 | [(set (attr "type") | |
5241 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
5242 | (const_string "incdec") | |
5243 | (const_string "alu"))) | |
5244 | (set_attr "mode" "HI")]) | |
5245 | ||
e075ae69 | 5246 | (define_expand "addqi3" |
4cbfbb1b JH |
5247 | [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") |
5248 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
e075ae69 RH |
5249 | (match_operand:QI 2 "general_operand" ""))) |
5250 | (clobber (reg:CC 17))])] | |
d9f32422 | 5251 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
5252 | "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;") |
5253 | ||
5254 | ;; %%% Potential partial reg stall on alternative 2. What to do? | |
58787064 JH |
5255 | (define_insn "*addqi_1_lea" |
5256 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r") | |
5257 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r") | |
5258 | (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn"))) | |
5259 | (clobber (reg:CC 17))] | |
5260 | "!TARGET_PARTIAL_REG_STALL | |
5261 | && ix86_binary_operator_ok (PLUS, QImode, operands)" | |
5262 | "* | |
5263 | { | |
5264 | int widen = (which_alternative == 2); | |
5265 | switch (get_attr_type (insn)) | |
5266 | { | |
5267 | case TYPE_LEA: | |
5268 | return \"#\"; | |
5269 | case TYPE_INCDEC: | |
5270 | if (operands[2] == const1_rtx) | |
5271 | return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\"; | |
5272 | else if (operands[2] == constm1_rtx | |
5273 | || (GET_CODE (operands[2]) == CONST_INT | |
5274 | && INTVAL (operands[2]) == 255)) | |
5275 | return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\"; | |
5276 | abort(); | |
5277 | ||
5278 | default: | |
5279 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
5280 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
5281 | if (GET_CODE (operands[2]) == CONST_INT | |
5282 | && (INTVAL (operands[2]) == 128 | |
5283 | || (INTVAL (operands[2]) < 0 | |
5284 | && INTVAL (operands[2]) != -128))) | |
5285 | { | |
5286 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5287 | if (widen) | |
5288 | return \"sub{l}\\t{%2, %k0|%k0, %2}\"; | |
5289 | else | |
5290 | return \"sub{b}\\t{%2, %0|%0, %2}\"; | |
5291 | } | |
5292 | if (widen) | |
5293 | return \"add{l}\\t{%k2, %k0|%k0, %k2}\"; | |
5294 | else | |
5295 | return \"add{b}\\t{%2, %0|%0, %2}\"; | |
5296 | } | |
5297 | }" | |
5298 | [(set (attr "type") | |
5299 | (if_then_else (eq_attr "alternative" "3") | |
5300 | (const_string "lea") | |
adc88131 | 5301 | (if_then_else (match_operand:QI 2 "incdec_operand" "") |
58787064 JH |
5302 | (const_string "incdec") |
5303 | (const_string "alu")))) | |
adc88131 | 5304 | (set_attr "mode" "QI,QI,SI,SI")]) |
58787064 | 5305 | |
e075ae69 | 5306 | (define_insn "*addqi_1" |
7c6b971d | 5307 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") |
e075ae69 | 5308 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
7c6b971d | 5309 | (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) |
e075ae69 | 5310 | (clobber (reg:CC 17))] |
58787064 JH |
5311 | "TARGET_PARTIAL_REG_STALL |
5312 | && ix86_binary_operator_ok (PLUS, QImode, operands)" | |
e075ae69 RH |
5313 | "* |
5314 | { | |
5315 | int widen = (which_alternative == 2); | |
5316 | switch (get_attr_type (insn)) | |
5bc7cd8e | 5317 | { |
e075ae69 RH |
5318 | case TYPE_INCDEC: |
5319 | if (operands[2] == const1_rtx) | |
5320 | return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\"; | |
5321 | else if (operands[2] == constm1_rtx | |
5322 | || (GET_CODE (operands[2]) == CONST_INT | |
5323 | && INTVAL (operands[2]) == 255)) | |
5324 | return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\"; | |
5325 | abort(); | |
5bc7cd8e | 5326 | |
e075ae69 RH |
5327 | default: |
5328 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
5329 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
5330 | if (GET_CODE (operands[2]) == CONST_INT | |
5331 | && (INTVAL (operands[2]) == 128 | |
5332 | || (INTVAL (operands[2]) < 0 | |
5333 | && INTVAL (operands[2]) != -128))) | |
5bc7cd8e | 5334 | { |
e075ae69 RH |
5335 | operands[2] = GEN_INT (-INTVAL (operands[2])); |
5336 | if (widen) | |
5337 | return \"sub{l}\\t{%2, %k0|%k0, %2}\"; | |
5338 | else | |
5339 | return \"sub{b}\\t{%2, %0|%0, %2}\"; | |
5bc7cd8e | 5340 | } |
e075ae69 RH |
5341 | if (widen) |
5342 | return \"add{l}\\t{%k2, %k0|%k0, %k2}\"; | |
5343 | else | |
5344 | return \"add{b}\\t{%2, %0|%0, %2}\"; | |
5bc7cd8e | 5345 | } |
e075ae69 RH |
5346 | }" |
5347 | [(set (attr "type") | |
5348 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
5349 | (const_string "incdec") | |
6ef67412 JH |
5350 | (const_string "alu"))) |
5351 | (set_attr "mode" "QI,QI,SI")]) | |
e075ae69 RH |
5352 | |
5353 | (define_insn "*addqi_2" | |
16189740 RH |
5354 | [(set (reg 17) |
5355 | (compare | |
e075ae69 RH |
5356 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") |
5357 | (match_operand:QI 2 "general_operand" "qmni,qni")) | |
5358 | (const_int 0))) | |
5359 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") | |
5360 | (plus:QI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 5361 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 5362 | && ix86_binary_operator_ok (PLUS, QImode, operands)" |
e075ae69 RH |
5363 | "* |
5364 | { | |
5365 | switch (get_attr_type (insn)) | |
5366 | { | |
5367 | case TYPE_INCDEC: | |
5368 | if (operands[2] == const1_rtx) | |
5369 | return \"inc{b}\\t%0\"; | |
5370 | else if (operands[2] == constm1_rtx | |
5371 | || (GET_CODE (operands[2]) == CONST_INT | |
5372 | && INTVAL (operands[2]) == 255)) | |
5373 | return \"dec{b}\\t%0\"; | |
5374 | abort(); | |
5bc7cd8e | 5375 | |
e075ae69 RH |
5376 | default: |
5377 | /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ | |
5378 | if (GET_CODE (operands[2]) == CONST_INT | |
5379 | && INTVAL (operands[2]) < 0) | |
5380 | { | |
5381 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5382 | return \"sub{b}\\t{%2, %0|%0, %2}\"; | |
5383 | } | |
5384 | return \"add{b}\\t{%2, %0|%0, %2}\"; | |
5385 | } | |
a269a03c | 5386 | }" |
e075ae69 RH |
5387 | [(set (attr "type") |
5388 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
5389 | (const_string "incdec") | |
6ef67412 JH |
5390 | (const_string "alu"))) |
5391 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
5392 | |
5393 | (define_insn "*addqi_3" | |
d90ffc8d | 5394 | [(set (reg 17) |
7e08e190 JH |
5395 | (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) |
5396 | (match_operand:QI 1 "nonimmediate_operand" "%0"))) | |
5397 | (clobber (match_scratch:QI 0 "=q"))] | |
5398 | "ix86_match_ccmode (insn, CCZmode) | |
d90ffc8d JH |
5399 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" |
5400 | "* | |
5401 | { | |
5402 | switch (get_attr_type (insn)) | |
5403 | { | |
5404 | case TYPE_INCDEC: | |
5405 | if (operands[2] == const1_rtx) | |
5406 | return \"inc{b}\\t%0\"; | |
5407 | else if (operands[2] == constm1_rtx | |
5408 | || (GET_CODE (operands[2]) == CONST_INT | |
5409 | && INTVAL (operands[2]) == 255)) | |
5410 | return \"dec{b}\\t%0\"; | |
5411 | abort(); | |
5412 | ||
5413 | default: | |
5414 | /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ | |
5415 | if (GET_CODE (operands[2]) == CONST_INT | |
5416 | && INTVAL (operands[2]) < 0) | |
5417 | { | |
5418 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5419 | return \"sub{b}\\t{%2, %0|%0, %2}\"; | |
5420 | } | |
5421 | return \"add{b}\\t{%2, %0|%0, %2}\"; | |
5422 | } | |
5423 | }" | |
5424 | [(set (attr "type") | |
5425 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
5426 | (const_string "incdec") | |
5427 | (const_string "alu"))) | |
5428 | (set_attr "mode" "QI")]) | |
5429 | ||
7e08e190 | 5430 | ; See comments above addsi_3_imm for details. |
d90ffc8d | 5431 | (define_insn "*addqi_4" |
9076b9c1 | 5432 | [(set (reg 17) |
7e08e190 JH |
5433 | (compare (match_operand:QI 1 "nonimmediate_operand" "0") |
5434 | (match_operand:QI 2 "const_int_operand" "n"))) | |
5435 | (clobber (match_scratch:QI 0 "=qm"))] | |
5436 | "ix86_match_ccmode (insn, CCGCmode) | |
5437 | && (INTVAL (operands[2]) & 0xff) != 0x80" | |
5438 | "* | |
5439 | { | |
5440 | switch (get_attr_type (insn)) | |
5441 | { | |
5442 | case TYPE_INCDEC: | |
5443 | if (operands[2] == constm1_rtx | |
5444 | || (GET_CODE (operands[2]) == CONST_INT | |
5445 | && INTVAL (operands[2]) == 255)) | |
5446 | return \"inc{b}\\t%0\"; | |
5447 | else if (operands[2] == const1_rtx) | |
5448 | return \"dec{b}\\t%0\"; | |
5449 | else | |
5450 | abort(); | |
5451 | ||
5452 | default: | |
5453 | if (! rtx_equal_p (operands[0], operands[1])) | |
5454 | abort (); | |
5455 | if (INTVAL (operands[2]) < 0) | |
5456 | { | |
5457 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5458 | return \"add{b}\\t{%2, %0|%0, %2}\"; | |
5459 | } | |
5460 | return \"sub{b}\\t{%2, %0|%0, %2}\"; | |
5461 | } | |
5462 | }" | |
5463 | [(set (attr "type") | |
5464 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
5465 | (const_string "incdec") | |
5466 | (const_string "alu"))) | |
6ef67412 | 5467 | (set_attr "mode" "QI")]) |
886c62d1 | 5468 | |
9dcbdc7e | 5469 | |
d90ffc8d | 5470 | (define_insn "*addqi_5" |
9076b9c1 JH |
5471 | [(set (reg 17) |
5472 | (compare | |
5473 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") | |
5474 | (match_operand:QI 2 "general_operand" "qmni")) | |
5475 | (const_int 0))) | |
7e08e190 | 5476 | (clobber (match_scratch:QI 0 "=q"))] |
9076b9c1 JH |
5477 | "ix86_match_ccmode (insn, CCGOCmode) |
5478 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
5479 | "* | |
5480 | { | |
5481 | switch (get_attr_type (insn)) | |
5482 | { | |
5483 | case TYPE_INCDEC: | |
5484 | if (operands[2] == const1_rtx) | |
5485 | return \"inc{b}\\t%0\"; | |
5486 | else if (operands[2] == constm1_rtx | |
5487 | || (GET_CODE (operands[2]) == CONST_INT | |
5488 | && INTVAL (operands[2]) == 255)) | |
5489 | return \"dec{b}\\t%0\"; | |
5490 | abort(); | |
5491 | ||
5492 | default: | |
5493 | /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ | |
5494 | if (GET_CODE (operands[2]) == CONST_INT | |
5495 | && INTVAL (operands[2]) < 0) | |
5496 | { | |
5497 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
5498 | return \"sub{b}\\t{%2, %0|%0, %2}\"; | |
5499 | } | |
5500 | return \"add{b}\\t{%2, %0|%0, %2}\"; | |
5501 | } | |
5502 | }" | |
5503 | [(set (attr "type") | |
5504 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
5505 | (const_string "incdec") | |
5506 | (const_string "alu"))) | |
5507 | (set_attr "mode" "QI")]) | |
5508 | ||
e075ae69 RH |
5509 | |
5510 | (define_insn "addqi_ext_1" | |
5511 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") | |
5512 | (const_int 8) | |
5513 | (const_int 8)) | |
5514 | (plus:SI | |
5515 | (zero_extract:SI | |
5516 | (match_operand 1 "ext_register_operand" "0") | |
5517 | (const_int 8) | |
5518 | (const_int 8)) | |
5519 | (match_operand:QI 2 "general_operand" "qmn"))) | |
5520 | (clobber (reg:CC 17))] | |
d2836273 JH |
5521 | "!TARGET_64BIT" |
5522 | "* | |
5523 | { | |
5524 | switch (get_attr_type (insn)) | |
5525 | { | |
5526 | case TYPE_INCDEC: | |
5527 | if (operands[2] == const1_rtx) | |
5528 | return \"inc{b}\\t%h0\"; | |
5529 | else if (operands[2] == constm1_rtx | |
5530 | || (GET_CODE (operands[2]) == CONST_INT | |
5531 | && INTVAL (operands[2]) == 255)) | |
5532 | return \"dec{b}\\t%h0\"; | |
5533 | abort(); | |
5534 | ||
5535 | default: | |
5536 | return \"add{b}\\t{%2, %h0|%h0, %2}\"; | |
5537 | } | |
5538 | }" | |
5539 | [(set (attr "type") | |
5540 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
5541 | (const_string "incdec") | |
5542 | (const_string "alu"))) | |
5543 | (set_attr "mode" "QI")]) | |
5544 | ||
5545 | (define_insn "*addqi_ext_1_rex64" | |
5546 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
5547 | (const_int 8) | |
5548 | (const_int 8)) | |
5549 | (plus:SI | |
5550 | (zero_extract:SI | |
5551 | (match_operand 1 "ext_register_operand" "0") | |
5552 | (const_int 8) | |
5553 | (const_int 8)) | |
5554 | (match_operand:QI 2 "nonmemory_operand" "Qn"))) | |
5555 | (clobber (reg:CC 17))] | |
5556 | "TARGET_64BIT" | |
e075ae69 RH |
5557 | "* |
5558 | { | |
5559 | switch (get_attr_type (insn)) | |
5560 | { | |
5561 | case TYPE_INCDEC: | |
5562 | if (operands[2] == const1_rtx) | |
5563 | return \"inc{b}\\t%h0\"; | |
5564 | else if (operands[2] == constm1_rtx | |
5565 | || (GET_CODE (operands[2]) == CONST_INT | |
5566 | && INTVAL (operands[2]) == 255)) | |
5567 | return \"dec{b}\\t%h0\"; | |
5568 | abort(); | |
886c62d1 | 5569 | |
e075ae69 RH |
5570 | default: |
5571 | return \"add{b}\\t{%2, %h0|%h0, %2}\"; | |
5572 | } | |
a269a03c | 5573 | }" |
e075ae69 RH |
5574 | [(set (attr "type") |
5575 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
5576 | (const_string "incdec") | |
6ef67412 JH |
5577 | (const_string "alu"))) |
5578 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
5579 | |
5580 | (define_insn "*addqi_ext_2" | |
d2836273 | 5581 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
5582 | (const_int 8) |
5583 | (const_int 8)) | |
5584 | (plus:SI | |
5585 | (zero_extract:SI | |
5586 | (match_operand 1 "ext_register_operand" "%0") | |
5587 | (const_int 8) | |
5588 | (const_int 8)) | |
5589 | (zero_extract:SI | |
d2836273 | 5590 | (match_operand 2 "ext_register_operand" "Q") |
e075ae69 RH |
5591 | (const_int 8) |
5592 | (const_int 8)))) | |
5593 | (clobber (reg:CC 17))] | |
5594 | "" | |
5595 | "add{b}\\t{%h2, %h0|%h0, %h2}" | |
6ef67412 JH |
5596 | [(set_attr "type" "alu") |
5597 | (set_attr "mode" "QI")]) | |
886c62d1 | 5598 | |
886c62d1 JVA |
5599 | ;; The patterns that match these are at the end of this file. |
5600 | ||
4fb21e90 JVA |
5601 | (define_expand "addxf3" |
5602 | [(set (match_operand:XF 0 "register_operand" "") | |
2ae0f82c SC |
5603 | (plus:XF (match_operand:XF 1 "register_operand" "") |
5604 | (match_operand:XF 2 "register_operand" "")))] | |
1e07edd3 | 5605 | "TARGET_80387 && !TARGET_64BIT" |
4fb21e90 JVA |
5606 | "") |
5607 | ||
2b589241 JH |
5608 | (define_expand "addtf3" |
5609 | [(set (match_operand:TF 0 "register_operand" "") | |
5610 | (plus:TF (match_operand:TF 1 "register_operand" "") | |
5611 | (match_operand:TF 2 "register_operand" "")))] | |
5612 | "TARGET_80387" | |
5613 | "") | |
5614 | ||
886c62d1 JVA |
5615 | (define_expand "adddf3" |
5616 | [(set (match_operand:DF 0 "register_operand" "") | |
06a964de | 5617 | (plus:DF (match_operand:DF 1 "register_operand" "") |
886c62d1 | 5618 | (match_operand:DF 2 "nonimmediate_operand" "")))] |
1deaa899 | 5619 | "TARGET_80387 || TARGET_SSE2" |
886c62d1 JVA |
5620 | "") |
5621 | ||
5622 | (define_expand "addsf3" | |
5623 | [(set (match_operand:SF 0 "register_operand" "") | |
06a964de | 5624 | (plus:SF (match_operand:SF 1 "register_operand" "") |
886c62d1 | 5625 | (match_operand:SF 2 "nonimmediate_operand" "")))] |
1deaa899 | 5626 | "TARGET_80387 || TARGET_SSE" |
886c62d1 JVA |
5627 | "") |
5628 | \f | |
e075ae69 | 5629 | ;; Subtract instructions |
a269a03c | 5630 | |
e075ae69 RH |
5631 | ;; %%% define_expand from the very first? |
5632 | ;; %%% splits for subsidi3 | |
2ae0f82c | 5633 | |
f58acb67 | 5634 | (define_insn "subdi3" |
e075ae69 | 5635 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") |
4cbfbb1b | 5636 | (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") |
e075ae69 RH |
5637 | (match_operand:DI 2 "general_operand" "roiF,riF"))) |
5638 | (clobber (reg:CC 17))] | |
acb94fa1 | 5639 | "" |
e075ae69 | 5640 | "#") |
9c530261 | 5641 | |
e075ae69 RH |
5642 | (define_split |
5643 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
4cbfbb1b | 5644 | (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") |
e075ae69 RH |
5645 | (match_operand:DI 2 "general_operand" ""))) |
5646 | (clobber (reg:CC 17))] | |
1e07edd3 | 5647 | "reload_completed && !TARGET_64BIT" |
9dcbdc7e | 5648 | [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2))) |
e075ae69 RH |
5649 | (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) |
5650 | (parallel [(set (match_dup 3) | |
5651 | (minus:SI (match_dup 4) | |
9dcbdc7e JH |
5652 | (plus:SI (ltu:SI (reg:CC 17) (const_int 0)) |
5653 | (match_dup 5)))) | |
e075ae69 RH |
5654 | (clobber (reg:CC 17))])] |
5655 | "split_di (operands+0, 1, operands+0, operands+3); | |
5656 | split_di (operands+1, 1, operands+1, operands+4); | |
5657 | split_di (operands+2, 1, operands+2, operands+5);") | |
5658 | ||
7e08e190 | 5659 | (define_insn "subsi3_carry" |
e075ae69 RH |
5660 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
5661 | (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
9dcbdc7e JH |
5662 | (plus:SI (ltu:SI (reg:CC 17) (const_int 0)) |
5663 | (match_operand:SI 2 "general_operand" "ri,rm")))) | |
e075ae69 | 5664 | (clobber (reg:CC 17))] |
d525dfdf | 5665 | "ix86_binary_operator_ok (MINUS, SImode, operands)" |
e075ae69 RH |
5666 | "sbb{l}\\t{%2, %0|%0, %2}" |
5667 | [(set_attr "type" "alu") | |
5668 | (set_attr "pent_pair" "pu") | |
6ef67412 JH |
5669 | (set_attr "ppro_uops" "few") |
5670 | (set_attr "mode" "SI")]) | |
886c62d1 | 5671 | |
2ae0f82c | 5672 | (define_expand "subsi3" |
e075ae69 RH |
5673 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") |
5674 | (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
5675 | (match_operand:SI 2 "general_operand" ""))) | |
5676 | (clobber (reg:CC 17))])] | |
886c62d1 | 5677 | "" |
e075ae69 | 5678 | "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;") |
2ae0f82c | 5679 | |
e075ae69 | 5680 | (define_insn "*subsi_1" |
2ae0f82c SC |
5681 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
5682 | (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
e075ae69 RH |
5683 | (match_operand:SI 2 "general_operand" "ri,rm"))) |
5684 | (clobber (reg:CC 17))] | |
5685 | "ix86_binary_operator_ok (MINUS, SImode, operands)" | |
5686 | "sub{l}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
5687 | [(set_attr "type" "alu") |
5688 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
5689 | |
5690 | (define_insn "*subsi_2" | |
16189740 RH |
5691 | [(set (reg 17) |
5692 | (compare | |
e075ae69 RH |
5693 | (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") |
5694 | (match_operand:SI 2 "general_operand" "ri,rm")) | |
5695 | (const_int 0))) | |
5696 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
5697 | (minus:SI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 5698 | "ix86_match_ccmode (insn, CCGOCmode) |
d90ffc8d JH |
5699 | && ix86_binary_operator_ok (MINUS, SImode, operands)" |
5700 | "sub{l}\\t{%2, %0|%0, %2}" | |
5701 | [(set_attr "type" "alu") | |
5702 | (set_attr "mode" "SI")]) | |
5703 | ||
5704 | (define_insn "*subsi_3" | |
5705 | [(set (reg 17) | |
5706 | (compare (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
5707 | (match_operand:SI 2 "general_operand" "ri,rm"))) | |
5708 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
5709 | (minus:SI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
5710 | "ix86_match_ccmode (insn, CCmode) |
5711 | && ix86_binary_operator_ok (MINUS, SImode, operands)" | |
e075ae69 | 5712 | "sub{l}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
5713 | [(set_attr "type" "alu") |
5714 | (set_attr "mode" "SI")]) | |
886c62d1 | 5715 | |
2ae0f82c | 5716 | (define_expand "subhi3" |
4cbfbb1b | 5717 | [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") |
e075ae69 RH |
5718 | (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") |
5719 | (match_operand:HI 2 "general_operand" ""))) | |
5720 | (clobber (reg:CC 17))])] | |
d9f32422 | 5721 | "TARGET_HIMODE_MATH" |
e075ae69 | 5722 | "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;") |
2ae0f82c | 5723 | |
e075ae69 | 5724 | (define_insn "*subhi_1" |
2ae0f82c | 5725 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") |
87fd1847 | 5726 | (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") |
e075ae69 RH |
5727 | (match_operand:HI 2 "general_operand" "ri,rm"))) |
5728 | (clobber (reg:CC 17))] | |
2ae0f82c | 5729 | "ix86_binary_operator_ok (MINUS, HImode, operands)" |
e075ae69 | 5730 | "sub{w}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
5731 | [(set_attr "type" "alu") |
5732 | (set_attr "mode" "HI")]) | |
e075ae69 RH |
5733 | |
5734 | (define_insn "*subhi_2" | |
16189740 RH |
5735 | [(set (reg 17) |
5736 | (compare | |
e075ae69 RH |
5737 | (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") |
5738 | (match_operand:HI 2 "general_operand" "ri,rm")) | |
5739 | (const_int 0))) | |
5740 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
5741 | (minus:HI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 5742 | "ix86_match_ccmode (insn, CCGOCmode) |
d90ffc8d JH |
5743 | && ix86_binary_operator_ok (MINUS, HImode, operands)" |
5744 | "sub{w}\\t{%2, %0|%0, %2}" | |
5745 | [(set_attr "type" "alu") | |
5746 | (set_attr "mode" "HI")]) | |
5747 | ||
5748 | (define_insn "*subhi_3" | |
5749 | [(set (reg 17) | |
5750 | (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
5751 | (match_operand:HI 2 "general_operand" "ri,rm"))) | |
5752 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
5753 | (minus:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
5754 | "ix86_match_ccmode (insn, CCmode) |
5755 | && ix86_binary_operator_ok (MINUS, HImode, operands)" | |
e075ae69 | 5756 | "sub{w}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
5757 | [(set_attr "type" "alu") |
5758 | (set_attr "mode" "HI")]) | |
886c62d1 | 5759 | |
2ae0f82c | 5760 | (define_expand "subqi3" |
4cbfbb1b JH |
5761 | [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") |
5762 | (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
e075ae69 RH |
5763 | (match_operand:QI 2 "general_operand" ""))) |
5764 | (clobber (reg:CC 17))])] | |
d9f32422 | 5765 | "TARGET_QIMODE_MATH" |
e075ae69 | 5766 | "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;") |
2ae0f82c | 5767 | |
e075ae69 | 5768 | (define_insn "*subqi_1" |
2ae0f82c SC |
5769 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") |
5770 | (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
e075ae69 RH |
5771 | (match_operand:QI 2 "general_operand" "qn,qmn"))) |
5772 | (clobber (reg:CC 17))] | |
5773 | "ix86_binary_operator_ok (MINUS, QImode, operands)" | |
5774 | "sub{b}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
5775 | [(set_attr "type" "alu") |
5776 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
5777 | |
5778 | (define_insn "*subqi_2" | |
16189740 RH |
5779 | [(set (reg 17) |
5780 | (compare | |
e075ae69 RH |
5781 | (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") |
5782 | (match_operand:QI 2 "general_operand" "qi,qm")) | |
5783 | (const_int 0))) | |
5784 | (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") | |
5785 | (minus:HI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 5786 | "ix86_match_ccmode (insn, CCGOCmode) |
d90ffc8d JH |
5787 | && ix86_binary_operator_ok (MINUS, QImode, operands)" |
5788 | "sub{b}\\t{%2, %0|%0, %2}" | |
5789 | [(set_attr "type" "alu") | |
5790 | (set_attr "mode" "QI")]) | |
5791 | ||
5792 | (define_insn "*subqi_3" | |
5793 | [(set (reg 17) | |
5794 | (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
5795 | (match_operand:QI 2 "general_operand" "qi,qm"))) | |
5796 | (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") | |
5797 | (minus:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
5798 | "ix86_match_ccmode (insn, CCmode) |
5799 | && ix86_binary_operator_ok (MINUS, QImode, operands)" | |
e075ae69 | 5800 | "sub{b}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
5801 | [(set_attr "type" "alu") |
5802 | (set_attr "mode" "QI")]) | |
2ae0f82c | 5803 | |
886c62d1 JVA |
5804 | ;; The patterns that match these are at the end of this file. |
5805 | ||
4fb21e90 JVA |
5806 | (define_expand "subxf3" |
5807 | [(set (match_operand:XF 0 "register_operand" "") | |
2ae0f82c SC |
5808 | (minus:XF (match_operand:XF 1 "register_operand" "") |
5809 | (match_operand:XF 2 "register_operand" "")))] | |
1e07edd3 | 5810 | "TARGET_80387 && !TARGET_64BIT" |
4fb21e90 JVA |
5811 | "") |
5812 | ||
2b589241 JH |
5813 | (define_expand "subtf3" |
5814 | [(set (match_operand:TF 0 "register_operand" "") | |
5815 | (minus:TF (match_operand:TF 1 "register_operand" "") | |
5816 | (match_operand:TF 2 "register_operand" "")))] | |
5817 | "TARGET_80387" | |
5818 | "") | |
5819 | ||
886c62d1 JVA |
5820 | (define_expand "subdf3" |
5821 | [(set (match_operand:DF 0 "register_operand" "") | |
06a964de | 5822 | (minus:DF (match_operand:DF 1 "register_operand" "") |
886c62d1 | 5823 | (match_operand:DF 2 "nonimmediate_operand" "")))] |
1deaa899 | 5824 | "TARGET_80387 || TARGET_SSE2" |
886c62d1 JVA |
5825 | "") |
5826 | ||
5827 | (define_expand "subsf3" | |
5828 | [(set (match_operand:SF 0 "register_operand" "") | |
06a964de | 5829 | (minus:SF (match_operand:SF 1 "register_operand" "") |
886c62d1 | 5830 | (match_operand:SF 2 "nonimmediate_operand" "")))] |
1deaa899 | 5831 | "TARGET_80387 || TARGET_SSE" |
886c62d1 JVA |
5832 | "") |
5833 | \f | |
e075ae69 | 5834 | ;; Multiply instructions |
886c62d1 | 5835 | |
d525dfdf JH |
5836 | (define_expand "mulsi3" |
5837 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
5838 | (mult:SI (match_operand:SI 1 "register_operand" "") | |
5839 | (match_operand:SI 2 "general_operand" ""))) | |
5840 | (clobber (reg:CC 17))])] | |
5841 | "" | |
5842 | "") | |
5843 | ||
5844 | (define_insn "*mulsi3_1" | |
e075ae69 RH |
5845 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") |
5846 | (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0") | |
5847 | (match_operand:SI 2 "general_operand" "K,i,mr"))) | |
5848 | (clobber (reg:CC 17))] | |
d525dfdf | 5849 | "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" |
20819a09 MM |
5850 | ; For the {r,0,i} alternative (i.e., register <- register * immediate), |
5851 | ; there are two ways of writing the exact same machine instruction | |
5852 | ; in assembly language. One, for example, is: | |
5853 | ; | |
5854 | ; imul $12, %eax | |
5855 | ; | |
5856 | ; while the other is: | |
5857 | ; | |
5858 | ; imul $12, %eax, %eax | |
5859 | ; | |
5860 | ; The first is simply short-hand for the latter. But, some assemblers, | |
5861 | ; like the SCO OSR5 COFF assembler, don't handle the first form. | |
e075ae69 RH |
5862 | "@ |
5863 | imul{l}\\t{%2, %1, %0|%0, %1, %2} | |
20819a09 | 5864 | imul{l}\\t{%2, %1, %0|%0, %1, %2} |
e075ae69 RH |
5865 | imul{l}\\t{%2, %0|%0, %2}" |
5866 | [(set_attr "type" "imul") | |
6ef67412 JH |
5867 | (set_attr "prefix_0f" "0,0,1") |
5868 | (set_attr "mode" "SI")]) | |
886c62d1 | 5869 | |
d525dfdf JH |
5870 | (define_expand "mulhi3" |
5871 | [(parallel [(set (match_operand:HI 0 "register_operand" "") | |
5872 | (mult:HI (match_operand:HI 1 "register_operand" "") | |
5873 | (match_operand:HI 2 "general_operand" ""))) | |
5874 | (clobber (reg:CC 17))])] | |
d9f32422 | 5875 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
5876 | "") |
5877 | ||
5878 | (define_insn "*mulhi3_1" | |
6ef67412 JH |
5879 | [(set (match_operand:HI 0 "register_operand" "=r,r,r") |
5880 | (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0") | |
5881 | (match_operand:HI 2 "general_operand" "K,i,mr"))) | |
e075ae69 | 5882 | (clobber (reg:CC 17))] |
d525dfdf | 5883 | "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" |
e075ae69 RH |
5884 | ; %%% There was a note about "Assembler has weird restrictions", |
5885 | ; concerning alternative 1 when op1 == op0. True? | |
5886 | "@ | |
6ef67412 | 5887 | imul{w}\\t{%2, %1, %0|%0, %1, %2} |
e075ae69 RH |
5888 | imul{w}\\t{%2, %1, %0|%0, %1, %2} |
5889 | imul{w}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
5890 | [(set_attr "type" "imul") |
5891 | (set_attr "prefix_0f" "0,0,1") | |
5892 | (set_attr "mode" "HI")]) | |
886c62d1 | 5893 | |
765a46f9 JH |
5894 | (define_insn "mulqi3" |
5895 | [(set (match_operand:QI 0 "register_operand" "=a") | |
5896 | (mult:QI (match_operand:QI 1 "register_operand" "%0") | |
5897 | (match_operand:QI 2 "nonimmediate_operand" "qm"))) | |
5898 | (clobber (reg:CC 17))] | |
d9f32422 | 5899 | "TARGET_QIMODE_MATH" |
765a46f9 | 5900 | "mul{b}\\t%2" |
6ef67412 JH |
5901 | [(set_attr "type" "imul") |
5902 | (set_attr "length_immediate" "0") | |
5903 | (set_attr "mode" "QI")]) | |
765a46f9 | 5904 | |
4b71cd6e | 5905 | (define_insn "umulqihi3" |
2ae0f82c SC |
5906 | [(set (match_operand:HI 0 "register_operand" "=a") |
5907 | (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) | |
e075ae69 RH |
5908 | (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) |
5909 | (clobber (reg:CC 17))] | |
d9f32422 | 5910 | "TARGET_QIMODE_MATH" |
e075ae69 | 5911 | "mul{b}\\t%2" |
6ef67412 JH |
5912 | [(set_attr "type" "imul") |
5913 | (set_attr "length_immediate" "0") | |
5914 | (set_attr "mode" "QI")]) | |
886c62d1 | 5915 | |
4b71cd6e | 5916 | (define_insn "mulqihi3" |
2ae0f82c SC |
5917 | [(set (match_operand:HI 0 "register_operand" "=a") |
5918 | (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) | |
e075ae69 RH |
5919 | (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) |
5920 | (clobber (reg:CC 17))] | |
d9f32422 | 5921 | "TARGET_QIMODE_MATH" |
e075ae69 | 5922 | "imul{b}\\t%2" |
6ef67412 JH |
5923 | [(set_attr "type" "imul") |
5924 | (set_attr "length_immediate" "0") | |
5925 | (set_attr "mode" "QI")]) | |
4b71cd6e | 5926 | |
1e07edd3 JH |
5927 | (define_insn "umulsi3" |
5928 | [(set (match_operand:SI 0 "register_operand" "=a") | |
5929 | (mult:SI (match_operand:SI 1 "register_operand" "%0") | |
5930 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) | |
5931 | (clobber (match_operand:SI 3 "register_operand" "=d")) | |
5932 | (clobber (reg:CC 17))] | |
5933 | "" | |
5934 | "mul{l}\\t%2" | |
5935 | [(set_attr "type" "imul") | |
5936 | (set_attr "ppro_uops" "few") | |
5937 | (set_attr "length_immediate" "0") | |
5938 | (set_attr "mode" "SI")]) | |
5939 | ||
5940 | ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers | |
4b71cd6e MM |
5941 | (define_insn "umulsidi3" |
5942 | [(set (match_operand:DI 0 "register_operand" "=A") | |
5943 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) | |
e075ae69 RH |
5944 | (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) |
5945 | (clobber (reg:CC 17))] | |
1e07edd3 | 5946 | "!TARGET_64BIT" |
e075ae69 RH |
5947 | "mul{l}\\t%2" |
5948 | [(set_attr "type" "imul") | |
6ef67412 JH |
5949 | (set_attr "ppro_uops" "few") |
5950 | (set_attr "length_immediate" "0") | |
5951 | (set_attr "mode" "SI")]) | |
4b71cd6e MM |
5952 | |
5953 | (define_insn "mulsidi3" | |
5954 | [(set (match_operand:DI 0 "register_operand" "=A") | |
5955 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) | |
e075ae69 RH |
5956 | (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) |
5957 | (clobber (reg:CC 17))] | |
1e07edd3 | 5958 | "!TARGET_64BIT" |
e075ae69 | 5959 | "imul{l}\\t%2" |
6ef67412 JH |
5960 | [(set_attr "type" "imul") |
5961 | (set_attr "length_immediate" "0") | |
5962 | (set_attr "mode" "SI")]) | |
2f2a49e8 | 5963 | |
34c659e2 | 5964 | (define_insn "umulsi3_highpart" |
2f2a49e8 | 5965 | [(set (match_operand:SI 0 "register_operand" "=d") |
e075ae69 RH |
5966 | (truncate:SI |
5967 | (lshiftrt:DI | |
5968 | (mult:DI (zero_extend:DI | |
5969 | (match_operand:SI 1 "register_operand" "%a")) | |
5970 | (zero_extend:DI | |
5971 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) | |
5972 | (const_int 32)))) | |
5973 | (clobber (match_scratch:SI 3 "=a")) | |
5974 | (clobber (reg:CC 17))] | |
1e07edd3 | 5975 | "!TARGET_64BIT" |
e075ae69 RH |
5976 | "mul{l}\\t%2" |
5977 | [(set_attr "type" "imul") | |
6ef67412 JH |
5978 | (set_attr "ppro_uops" "few") |
5979 | (set_attr "length_immediate" "0") | |
5980 | (set_attr "mode" "SI")]) | |
2f2a49e8 | 5981 | |
34c659e2 | 5982 | (define_insn "smulsi3_highpart" |
2f2a49e8 | 5983 | [(set (match_operand:SI 0 "register_operand" "=d") |
e075ae69 RH |
5984 | (truncate:SI |
5985 | (lshiftrt:DI | |
5986 | (mult:DI (sign_extend:DI | |
5987 | (match_operand:SI 1 "register_operand" "%a")) | |
5988 | (sign_extend:DI | |
5989 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) | |
5990 | (const_int 32)))) | |
5991 | (clobber (match_scratch:SI 3 "=a")) | |
5992 | (clobber (reg:CC 17))] | |
5993 | "" | |
5994 | "imul{l}\\t%2" | |
5995 | [(set_attr "type" "imul") | |
6ef67412 JH |
5996 | (set_attr "ppro_uops" "few") |
5997 | (set_attr "mode" "SI")]) | |
4b71cd6e | 5998 | |
886c62d1 JVA |
5999 | ;; The patterns that match these are at the end of this file. |
6000 | ||
4fb21e90 JVA |
6001 | (define_expand "mulxf3" |
6002 | [(set (match_operand:XF 0 "register_operand" "") | |
2ae0f82c SC |
6003 | (mult:XF (match_operand:XF 1 "register_operand" "") |
6004 | (match_operand:XF 2 "register_operand" "")))] | |
1e07edd3 | 6005 | "TARGET_80387 && !TARGET_64BIT" |
4fb21e90 JVA |
6006 | "") |
6007 | ||
2b589241 JH |
6008 | (define_expand "multf3" |
6009 | [(set (match_operand:TF 0 "register_operand" "") | |
6010 | (mult:TF (match_operand:TF 1 "register_operand" "") | |
6011 | (match_operand:TF 2 "register_operand" "")))] | |
6012 | "TARGET_80387" | |
6013 | "") | |
6014 | ||
886c62d1 JVA |
6015 | (define_expand "muldf3" |
6016 | [(set (match_operand:DF 0 "register_operand" "") | |
2ae0f82c | 6017 | (mult:DF (match_operand:DF 1 "register_operand" "") |
886c62d1 | 6018 | (match_operand:DF 2 "nonimmediate_operand" "")))] |
1deaa899 | 6019 | "TARGET_80387 || TARGET_SSE2" |
886c62d1 JVA |
6020 | "") |
6021 | ||
6022 | (define_expand "mulsf3" | |
6023 | [(set (match_operand:SF 0 "register_operand" "") | |
2ae0f82c | 6024 | (mult:SF (match_operand:SF 1 "register_operand" "") |
886c62d1 | 6025 | (match_operand:SF 2 "nonimmediate_operand" "")))] |
1deaa899 | 6026 | "TARGET_80387 || TARGET_SSE" |
886c62d1 JVA |
6027 | "") |
6028 | \f | |
e075ae69 | 6029 | ;; Divide instructions |
886c62d1 JVA |
6030 | |
6031 | (define_insn "divqi3" | |
2ae0f82c SC |
6032 | [(set (match_operand:QI 0 "register_operand" "=a") |
6033 | (div:QI (match_operand:HI 1 "register_operand" "0") | |
e075ae69 RH |
6034 | (match_operand:QI 2 "nonimmediate_operand" "qm"))) |
6035 | (clobber (reg:CC 17))] | |
d9f32422 | 6036 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
6037 | "idiv{b}\\t%2" |
6038 | [(set_attr "type" "idiv") | |
6ef67412 | 6039 | (set_attr "mode" "QI") |
e075ae69 | 6040 | (set_attr "ppro_uops" "few")]) |
886c62d1 JVA |
6041 | |
6042 | (define_insn "udivqi3" | |
2ae0f82c SC |
6043 | [(set (match_operand:QI 0 "register_operand" "=a") |
6044 | (udiv:QI (match_operand:HI 1 "register_operand" "0") | |
e075ae69 RH |
6045 | (match_operand:QI 2 "nonimmediate_operand" "qm"))) |
6046 | (clobber (reg:CC 17))] | |
d9f32422 | 6047 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
6048 | "div{b}\\t%2" |
6049 | [(set_attr "type" "idiv") | |
6ef67412 | 6050 | (set_attr "mode" "QI") |
e075ae69 | 6051 | (set_attr "ppro_uops" "few")]) |
886c62d1 JVA |
6052 | |
6053 | ;; The patterns that match these are at the end of this file. | |
6054 | ||
4fb21e90 JVA |
6055 | (define_expand "divxf3" |
6056 | [(set (match_operand:XF 0 "register_operand" "") | |
2ae0f82c SC |
6057 | (div:XF (match_operand:XF 1 "register_operand" "") |
6058 | (match_operand:XF 2 "register_operand" "")))] | |
1e07edd3 | 6059 | "TARGET_80387 && !TARGET_64BIT" |
886c62d1 JVA |
6060 | "") |
6061 | ||
2b589241 JH |
6062 | (define_expand "divtf3" |
6063 | [(set (match_operand:TF 0 "register_operand" "") | |
6064 | (div:TF (match_operand:TF 1 "register_operand" "") | |
6065 | (match_operand:TF 2 "register_operand" "")))] | |
6066 | "TARGET_80387" | |
6067 | "") | |
6068 | ||
a78cb986 SC |
6069 | (define_expand "divdf3" |
6070 | [(set (match_operand:DF 0 "register_operand" "") | |
6071 | (div:DF (match_operand:DF 1 "register_operand" "") | |
6072 | (match_operand:DF 2 "nonimmediate_operand" "")))] | |
1deaa899 | 6073 | "TARGET_80387 || TARGET_SSE2" |
a78cb986 SC |
6074 | "") |
6075 | ||
886c62d1 JVA |
6076 | (define_expand "divsf3" |
6077 | [(set (match_operand:SF 0 "register_operand" "") | |
2ae0f82c | 6078 | (div:SF (match_operand:SF 1 "register_operand" "") |
886c62d1 | 6079 | (match_operand:SF 2 "nonimmediate_operand" "")))] |
1deaa899 | 6080 | "TARGET_80387 || TARGET_SSE" |
886c62d1 JVA |
6081 | "") |
6082 | \f | |
6083 | ;; Remainder instructions. | |
40745eec JH |
6084 | (define_expand "divmodsi4" |
6085 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
6086 | (div:SI (match_operand:SI 1 "register_operand" "") | |
6087 | (match_operand:SI 2 "nonimmediate_operand" ""))) | |
6088 | (set (match_operand:SI 3 "register_operand" "") | |
6089 | (mod:SI (match_dup 1) (match_dup 2))) | |
6090 | (clobber (reg:CC 17))])] | |
6091 | "" | |
6092 | "") | |
6093 | ||
6094 | ;; Allow to come the parameter in eax or edx to avoid extra moves. | |
6095 | ;; Penalize eax case sligthly because it results in worse scheduling | |
6096 | ;; of code. | |
6097 | (define_insn "*divmodsi4_nocltd" | |
6098 | [(set (match_operand:SI 0 "register_operand" "=&a,?a") | |
6099 | (div:SI (match_operand:SI 2 "register_operand" "1,0") | |
6100 | (match_operand:SI 3 "nonimmediate_operand" "rm,rm"))) | |
6101 | (set (match_operand:SI 1 "register_operand" "=&d,&d") | |
6102 | (mod:SI (match_dup 2) (match_dup 3))) | |
6103 | (clobber (reg:CC 17))] | |
6104 | "!optimize_size && !TARGET_USE_CLTD" | |
6105 | "#" | |
6106 | [(set_attr "type" "multi")]) | |
886c62d1 | 6107 | |
40745eec | 6108 | (define_insn "*divmodsi4_cltd" |
2bb7a0f5 | 6109 | [(set (match_operand:SI 0 "register_operand" "=a") |
40745eec JH |
6110 | (div:SI (match_operand:SI 2 "register_operand" "a") |
6111 | (match_operand:SI 3 "nonimmediate_operand" "rm"))) | |
6112 | (set (match_operand:SI 1 "register_operand" "=&d") | |
6113 | (mod:SI (match_dup 2) (match_dup 3))) | |
e075ae69 | 6114 | (clobber (reg:CC 17))] |
40745eec JH |
6115 | "optimize_size || TARGET_USE_CLTD" |
6116 | "#" | |
e075ae69 RH |
6117 | [(set_attr "type" "multi")]) |
6118 | ||
6343a50e | 6119 | (define_insn "*divmodsi_noext" |
e075ae69 | 6120 | [(set (match_operand:SI 0 "register_operand" "=a") |
40745eec | 6121 | (div:SI (match_operand:SI 1 "register_operand" "0") |
e075ae69 RH |
6122 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) |
6123 | (set (match_operand:SI 3 "register_operand" "=d") | |
6124 | (mod:SI (match_dup 1) (match_dup 2))) | |
40745eec | 6125 | (use (match_operand:SI 4 "register_operand" "3")) |
e075ae69 RH |
6126 | (clobber (reg:CC 17))] |
6127 | "" | |
6128 | "idiv{l}\\t%2" | |
6129 | [(set_attr "type" "idiv") | |
6ef67412 | 6130 | (set_attr "mode" "SI") |
e075ae69 RH |
6131 | (set_attr "ppro_uops" "few")]) |
6132 | ||
6133 | (define_split | |
6134 | [(set (match_operand:SI 0 "register_operand" "") | |
6135 | (div:SI (match_operand:SI 1 "register_operand" "") | |
6136 | (match_operand:SI 2 "nonimmediate_operand" ""))) | |
6137 | (set (match_operand:SI 3 "register_operand" "") | |
6138 | (mod:SI (match_dup 1) (match_dup 2))) | |
6139 | (clobber (reg:CC 17))] | |
6140 | "reload_completed" | |
6141 | [(parallel [(set (match_dup 3) | |
6142 | (ashiftrt:SI (match_dup 4) (const_int 31))) | |
6143 | (clobber (reg:CC 17))]) | |
6144 | (parallel [(set (match_dup 0) | |
40745eec | 6145 | (div:SI (reg:SI 0) (match_dup 2))) |
e075ae69 | 6146 | (set (match_dup 3) |
40745eec | 6147 | (mod:SI (reg:SI 0) (match_dup 2))) |
e075ae69 RH |
6148 | (use (match_dup 3)) |
6149 | (clobber (reg:CC 17))])] | |
6150 | " | |
886c62d1 | 6151 | { |
e075ae69 | 6152 | /* Avoid use of cltd in favour of a mov+shift. */ |
40745eec | 6153 | if (!TARGET_USE_CLTD && !optimize_size) |
e075ae69 | 6154 | { |
40745eec JH |
6155 | if (true_regnum (operands[1])) |
6156 | emit_move_insn (operands[0], operands[1]); | |
6157 | else | |
6158 | emit_move_insn (operands[3], operands[1]); | |
e075ae69 RH |
6159 | operands[4] = operands[3]; |
6160 | } | |
6161 | else | |
40745eec JH |
6162 | { |
6163 | if (true_regnum (operands[1])) | |
6164 | abort(); | |
6165 | operands[4] = operands[1]; | |
6166 | } | |
e075ae69 | 6167 | }") |
e075ae69 | 6168 | ;; %%% Split me. |
886c62d1 | 6169 | (define_insn "divmodhi4" |
2bb7a0f5 RS |
6170 | [(set (match_operand:HI 0 "register_operand" "=a") |
6171 | (div:HI (match_operand:HI 1 "register_operand" "0") | |
2ae0f82c | 6172 | (match_operand:HI 2 "nonimmediate_operand" "rm"))) |
2bb7a0f5 | 6173 | (set (match_operand:HI 3 "register_operand" "=&d") |
e075ae69 RH |
6174 | (mod:HI (match_dup 1) (match_dup 2))) |
6175 | (clobber (reg:CC 17))] | |
d9f32422 | 6176 | "TARGET_HIMODE_MATH" |
e075ae69 | 6177 | "cwtd\;idiv{w}\\t%2" |
6ef67412 JH |
6178 | [(set_attr "type" "multi") |
6179 | (set_attr "length_immediate" "0") | |
6180 | (set_attr "mode" "SI")]) | |
886c62d1 | 6181 | |
886c62d1 | 6182 | (define_insn "udivmodsi4" |
2bb7a0f5 RS |
6183 | [(set (match_operand:SI 0 "register_operand" "=a") |
6184 | (udiv:SI (match_operand:SI 1 "register_operand" "0") | |
2ae0f82c | 6185 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) |
2bb7a0f5 | 6186 | (set (match_operand:SI 3 "register_operand" "=&d") |
e075ae69 RH |
6187 | (umod:SI (match_dup 1) (match_dup 2))) |
6188 | (clobber (reg:CC 17))] | |
886c62d1 | 6189 | "" |
e075ae69 | 6190 | "xor{l}\\t%3, %3\;div{l}\\t%2" |
6ef67412 JH |
6191 | [(set_attr "type" "multi") |
6192 | (set_attr "length_immediate" "0") | |
6193 | (set_attr "mode" "SI")]) | |
886c62d1 | 6194 | |
6343a50e | 6195 | (define_insn "*udivmodsi4_noext" |
2bb7a0f5 | 6196 | [(set (match_operand:SI 0 "register_operand" "=a") |
e075ae69 | 6197 | (udiv:SI (match_operand:SI 1 "register_operand" "0") |
2ae0f82c | 6198 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) |
2bb7a0f5 | 6199 | (set (match_operand:SI 3 "register_operand" "=d") |
e075ae69 RH |
6200 | (umod:SI (match_dup 1) (match_dup 2))) |
6201 | (use (match_dup 3)) | |
6202 | (clobber (reg:CC 17))] | |
886c62d1 | 6203 | "" |
e075ae69 RH |
6204 | "div{l}\\t%2" |
6205 | [(set_attr "type" "idiv") | |
6ef67412 JH |
6206 | (set_attr "ppro_uops" "few") |
6207 | (set_attr "mode" "SI")]) | |
886c62d1 | 6208 | |
e075ae69 RH |
6209 | (define_split |
6210 | [(set (match_operand:SI 0 "register_operand" "") | |
6211 | (udiv:SI (match_operand:SI 1 "register_operand" "") | |
6212 | (match_operand:SI 2 "nonimmediate_operand" ""))) | |
6213 | (set (match_operand:SI 3 "register_operand" "") | |
6214 | (umod:SI (match_dup 1) (match_dup 2))) | |
6215 | (clobber (reg:CC 17))] | |
6216 | "reload_completed" | |
591702de | 6217 | [(set (match_dup 3) (const_int 0)) |
e075ae69 RH |
6218 | (parallel [(set (match_dup 0) |
6219 | (udiv:SI (match_dup 1) (match_dup 2))) | |
6220 | (set (match_dup 3) | |
6221 | (umod:SI (match_dup 1) (match_dup 2))) | |
6222 | (use (match_dup 3)) | |
6223 | (clobber (reg:CC 17))])] | |
6224 | "") | |
886c62d1 | 6225 | |
e075ae69 | 6226 | (define_expand "udivmodhi4" |
591702de | 6227 | [(set (match_dup 4) (const_int 0)) |
40745eec JH |
6228 | (parallel [(set (match_operand:HI 0 "register_operand" "") |
6229 | (udiv:HI (match_operand:HI 1 "register_operand" "") | |
6230 | (match_operand:HI 2 "nonimmediate_operand" ""))) | |
6231 | (set (match_operand:HI 3 "register_operand" "") | |
e075ae69 RH |
6232 | (umod:HI (match_dup 1) (match_dup 2))) |
6233 | (use (match_dup 4)) | |
6234 | (clobber (reg:CC 17))])] | |
d9f32422 | 6235 | "TARGET_HIMODE_MATH" |
e075ae69 | 6236 | "operands[4] = gen_reg_rtx (HImode);") |
886c62d1 | 6237 | |
6343a50e | 6238 | (define_insn "*udivmodhi_noext" |
e075ae69 RH |
6239 | [(set (match_operand:HI 0 "register_operand" "=a") |
6240 | (udiv:HI (match_operand:HI 1 "register_operand" "0") | |
6241 | (match_operand:HI 2 "nonimmediate_operand" "rm"))) | |
6242 | (set (match_operand:HI 3 "register_operand" "=d") | |
6243 | (umod:HI (match_dup 1) (match_dup 2))) | |
6244 | (use (match_operand:HI 4 "register_operand" "3")) | |
6245 | (clobber (reg:CC 17))] | |
6246 | "" | |
6247 | "div{w}\\t%2" | |
6248 | [(set_attr "type" "idiv") | |
6ef67412 | 6249 | (set_attr "mode" "HI") |
e075ae69 RH |
6250 | (set_attr "ppro_uops" "few")]) |
6251 | ||
6252 | ;; We can not use div/idiv for double division, because it causes | |
6253 | ;; "division by zero" on the overflow and that's not what we expect | |
6254 | ;; from truncate. Because true (non truncating) double division is | |
6255 | ;; never generated, we can't create this insn anyway. | |
6256 | ; | |
6257 | ;(define_insn "" | |
6258 | ; [(set (match_operand:SI 0 "register_operand" "=a") | |
6259 | ; (truncate:SI | |
6260 | ; (udiv:DI (match_operand:DI 1 "register_operand" "A") | |
6261 | ; (zero_extend:DI | |
6262 | ; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) | |
6263 | ; (set (match_operand:SI 3 "register_operand" "=d") | |
6264 | ; (truncate:SI | |
6265 | ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) | |
6266 | ; (clobber (reg:CC 17))] | |
6267 | ; "" | |
6268 | ; "div{l}\\t{%2, %0|%0, %2}" | |
6269 | ; [(set_attr "type" "idiv") | |
6270 | ; (set_attr "ppro_uops" "few")]) | |
886c62d1 | 6271 | \f |
e075ae69 RH |
6272 | ;;- Logical AND instructions |
6273 | ||
6274 | ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. | |
6275 | ;; Note that this excludes ah. | |
6276 | ||
9076b9c1 JH |
6277 | |
6278 | (define_insn "testsi_1" | |
6279 | [(set (reg 17) | |
6280 | (compare | |
16189740 RH |
6281 | (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm") |
6282 | (match_operand:SI 1 "nonmemory_operand" "in,in,rin")) | |
6283 | (const_int 0)))] | |
9076b9c1 | 6284 | "ix86_match_ccmode (insn, CCNOmode)" |
e075ae69 | 6285 | "test{l}\\t{%1, %0|%0, %1}" |
6ef67412 JH |
6286 | [(set_attr "type" "test") |
6287 | (set_attr "modrm" "0,1,1") | |
6288 | (set_attr "mode" "SI") | |
e075ae69 RH |
6289 | (set_attr "pent_pair" "uv,np,uv")]) |
6290 | ||
9076b9c1 | 6291 | (define_expand "testsi_ccno_1" |
e075ae69 | 6292 | [(set (reg:CCNO 17) |
16189740 | 6293 | (compare:CCNO |
9076b9c1 JH |
6294 | (and:SI (match_operand:SI 0 "nonimmediate_operand" "") |
6295 | (match_operand:SI 1 "nonmemory_operand" "")) | |
16189740 | 6296 | (const_int 0)))] |
a1cbdd7f | 6297 | "" |
9076b9c1 | 6298 | "") |
16189740 RH |
6299 | |
6300 | (define_insn "*testhi_1" | |
6301 | [(set (reg 17) | |
6302 | (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm") | |
6303 | (match_operand:HI 1 "nonmemory_operand" "n,n,rn")) | |
6304 | (const_int 0)))] | |
6305 | "ix86_match_ccmode (insn, CCNOmode)" | |
e075ae69 | 6306 | "test{w}\\t{%1, %0|%0, %1}" |
6ef67412 JH |
6307 | [(set_attr "type" "test") |
6308 | (set_attr "modrm" "0,1,1") | |
6309 | (set_attr "mode" "HI") | |
e075ae69 RH |
6310 | (set_attr "pent_pair" "uv,np,uv")]) |
6311 | ||
9076b9c1 | 6312 | (define_expand "testqi_ccz_1" |
16189740 | 6313 | [(set (reg:CCZ 17) |
9076b9c1 JH |
6314 | (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") |
6315 | (match_operand:QI 1 "nonmemory_operand" "")) | |
6316 | (const_int 0)))] | |
16189740 | 6317 | "" |
9076b9c1 | 6318 | "") |
16189740 | 6319 | |
9076b9c1 JH |
6320 | (define_insn "*testqi_1" |
6321 | [(set (reg 17) | |
6322 | (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r") | |
6323 | (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n")) | |
6324 | (const_int 0)))] | |
6325 | "ix86_match_ccmode (insn, CCNOmode)" | |
adc88131 JJ |
6326 | "* |
6327 | { | |
6328 | if (which_alternative == 3) | |
6329 | { | |
6330 | if (GET_CODE (operands[1]) == CONST_INT | |
6331 | && (INTVAL (operands[1]) & 0xffffff00)) | |
6332 | operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); | |
6333 | return \"test{l}\\t{%1, %k0|%k0, %1}\"; | |
6334 | } | |
6335 | return \"test{b}\\t{%1, %0|%0, %1}\"; | |
6336 | }" | |
6ef67412 JH |
6337 | [(set_attr "type" "test") |
6338 | (set_attr "modrm" "0,1,1,1") | |
6339 | (set_attr "mode" "QI,QI,QI,SI") | |
6340 | (set_attr "pent_pair" "uv,np,uv,np")]) | |
e075ae69 | 6341 | |
9076b9c1 JH |
6342 | (define_expand "testqi_ext_ccno_0" |
6343 | [(set (reg:CCNO 17) | |
6344 | (compare:CCNO | |
16189740 RH |
6345 | (and:SI |
6346 | (zero_extract:SI | |
9076b9c1 | 6347 | (match_operand 0 "ext_register_operand" "") |
16189740 RH |
6348 | (const_int 8) |
6349 | (const_int 8)) | |
9076b9c1 | 6350 | (match_operand 1 "const_int_operand" "")) |
16189740 | 6351 | (const_int 0)))] |
9076b9c1 JH |
6352 | "" |
6353 | "") | |
e075ae69 | 6354 | |
9076b9c1 JH |
6355 | (define_insn "*testqi_ext_0" |
6356 | [(set (reg 17) | |
6357 | (compare | |
e075ae69 RH |
6358 | (and:SI |
6359 | (zero_extract:SI | |
d2836273 | 6360 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
6361 | (const_int 8) |
6362 | (const_int 8)) | |
6363 | (match_operand 1 "const_int_operand" "n")) | |
6364 | (const_int 0)))] | |
9076b9c1 JH |
6365 | "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff |
6366 | && ix86_match_ccmode (insn, CCNOmode)" | |
e075ae69 | 6367 | "test{b}\\t{%1, %h0|%h0, %1}" |
6ef67412 JH |
6368 | [(set_attr "type" "test") |
6369 | (set_attr "mode" "QI") | |
6370 | (set_attr "length_immediate" "1") | |
e075ae69 RH |
6371 | (set_attr "pent_pair" "np")]) |
6372 | ||
6373 | (define_insn "*testqi_ext_1" | |
16189740 RH |
6374 | [(set (reg 17) |
6375 | (compare | |
e075ae69 RH |
6376 | (and:SI |
6377 | (zero_extract:SI | |
d2836273 | 6378 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
6379 | (const_int 8) |
6380 | (const_int 8)) | |
6381 | (zero_extend:SI | |
d2836273 | 6382 | (match_operand:QI 1 "nonimmediate_operand" "Qm"))) |
e075ae69 | 6383 | (const_int 0)))] |
d2836273 JH |
6384 | "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" |
6385 | "test{b}\\t{%1, %h0|%h0, %1}" | |
6386 | [(set_attr "type" "test") | |
6387 | (set_attr "mode" "QI")]) | |
6388 | ||
6389 | (define_insn "*testqi_ext_1_rex64" | |
6390 | [(set (reg 17) | |
6391 | (compare | |
6392 | (and:SI | |
6393 | (zero_extract:SI | |
6394 | (match_operand 0 "ext_register_operand" "Q") | |
6395 | (const_int 8) | |
6396 | (const_int 8)) | |
6397 | (zero_extend:SI | |
6398 | (match_operand:QI 1 "ext_register_operand" "Q"))) | |
6399 | (const_int 0)))] | |
6400 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" | |
e075ae69 | 6401 | "test{b}\\t{%1, %h0|%h0, %1}" |
6ef67412 JH |
6402 | [(set_attr "type" "test") |
6403 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
6404 | |
6405 | (define_insn "*testqi_ext_2" | |
16189740 RH |
6406 | [(set (reg 17) |
6407 | (compare | |
e075ae69 RH |
6408 | (and:SI |
6409 | (zero_extract:SI | |
d2836273 | 6410 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
6411 | (const_int 8) |
6412 | (const_int 8)) | |
6413 | (zero_extract:SI | |
d2836273 | 6414 | (match_operand 1 "ext_register_operand" "Q") |
e075ae69 RH |
6415 | (const_int 8) |
6416 | (const_int 8))) | |
6417 | (const_int 0)))] | |
16189740 | 6418 | "ix86_match_ccmode (insn, CCNOmode)" |
e075ae69 | 6419 | "test{b}\\t{%h1, %h0|%h0, %h1}" |
6ef67412 JH |
6420 | [(set_attr "type" "test") |
6421 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
6422 | |
6423 | ;; Combine likes to form bit extractions for some tests. Humor it. | |
6343a50e | 6424 | (define_insn "*testqi_ext_3" |
16189740 RH |
6425 | [(set (reg 17) |
6426 | (compare (zero_extract:SI | |
6427 | (match_operand 0 "nonimmediate_operand" "rm") | |
6428 | (match_operand:SI 1 "const_int_operand" "") | |
6429 | (match_operand:SI 2 "const_int_operand" "")) | |
6430 | (const_int 0)))] | |
6431 | "ix86_match_ccmode (insn, CCNOmode) | |
6432 | && (GET_MODE (operands[0]) == SImode | |
6433 | || GET_MODE (operands[0]) == HImode | |
6434 | || GET_MODE (operands[0]) == QImode)" | |
e075ae69 | 6435 | "#") |
4fce8e83 | 6436 | |
e075ae69 | 6437 | (define_split |
16189740 RH |
6438 | [(set (reg 17) |
6439 | (compare (zero_extract:SI | |
6440 | (match_operand 0 "nonimmediate_operand" "rm") | |
6441 | (match_operand:SI 1 "const_int_operand" "") | |
6442 | (match_operand:SI 2 "const_int_operand" "")) | |
6443 | (const_int 0)))] | |
6444 | "ix86_match_ccmode (insn, CCNOmode)" | |
e075ae69 RH |
6445 | [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))] |
6446 | " | |
6447 | { | |
6448 | HOST_WIDE_INT len = INTVAL (operands[1]); | |
6449 | HOST_WIDE_INT pos = INTVAL (operands[2]); | |
6450 | HOST_WIDE_INT mask; | |
6451 | enum machine_mode mode; | |
886c62d1 | 6452 | |
e075ae69 RH |
6453 | mode = GET_MODE (operands[0]); |
6454 | if (GET_CODE (operands[0]) == MEM) | |
5bc7cd8e | 6455 | { |
e075ae69 RH |
6456 | /* ??? Combine likes to put non-volatile mem extractions in QImode |
6457 | no matter the size of the test. So find a mode that works. */ | |
6458 | if (! MEM_VOLATILE_P (operands[0])) | |
6459 | { | |
6460 | mode = smallest_mode_for_size (pos + len, MODE_INT); | |
6461 | operands[0] = change_address (operands[0], mode, NULL_RTX); | |
6462 | } | |
5bc7cd8e | 6463 | } |
e075ae69 | 6464 | else if (mode == HImode && pos + len <= 8) |
5bc7cd8e | 6465 | { |
e075ae69 RH |
6466 | /* Small HImode tests can be converted to QImode. */ |
6467 | mode = QImode; | |
6468 | operands[0] = gen_lowpart (QImode, operands[0]); | |
5bc7cd8e SC |
6469 | } |
6470 | ||
e075ae69 RH |
6471 | mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1; |
6472 | mask &= ~(((HOST_WIDE_INT)1 << pos) - 1); | |
886c62d1 | 6473 | |
e075ae69 RH |
6474 | operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask)); |
6475 | }") | |
886c62d1 | 6476 | |
e075ae69 RH |
6477 | ;; %%% This used to optimize known byte-wide and operations to memory, |
6478 | ;; and sometimes to QImode registers. If this is considered useful, | |
6479 | ;; it should be done with splitters. | |
6480 | ||
6481 | (define_expand "andsi3" | |
6482 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
6483 | (and:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
6484 | (match_operand:SI 2 "general_operand" ""))) | |
6485 | (clobber (reg:CC 17))] | |
6486 | "" | |
6487 | "ix86_expand_binary_operator (AND, SImode, operands); DONE;") | |
6488 | ||
6489 | (define_insn "*andsi_1" | |
6490 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") | |
6491 | (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") | |
6492 | (match_operand:SI 2 "general_operand" "ri,rm,L"))) | |
6493 | (clobber (reg:CC 17))] | |
6494 | "ix86_binary_operator_ok (AND, SImode, operands)" | |
886c62d1 JVA |
6495 | "* |
6496 | { | |
e075ae69 | 6497 | switch (get_attr_type (insn)) |
886c62d1 | 6498 | { |
e075ae69 RH |
6499 | case TYPE_IMOVX: |
6500 | { | |
6501 | enum machine_mode mode; | |
5bc7cd8e | 6502 | |
e075ae69 RH |
6503 | if (GET_CODE (operands[2]) != CONST_INT) |
6504 | abort (); | |
6505 | if (INTVAL (operands[2]) == 0xff) | |
6506 | mode = QImode; | |
6507 | else if (INTVAL (operands[2]) == 0xffff) | |
6508 | mode = HImode; | |
6509 | else | |
6510 | abort (); | |
6511 | ||
6512 | operands[1] = gen_lowpart (mode, operands[1]); | |
6513 | if (mode == QImode) | |
6514 | return \"movz{bl|x}\\t{%1,%0|%0, %1}\"; | |
6515 | else | |
6516 | return \"movz{wl|x}\\t{%1,%0|%0, %1}\"; | |
6517 | } | |
5bc7cd8e | 6518 | |
e075ae69 RH |
6519 | default: |
6520 | if (! rtx_equal_p (operands[0], operands[1])) | |
6521 | abort (); | |
e075ae69 | 6522 | return \"and{l}\\t{%2, %0|%0, %2}\"; |
886c62d1 | 6523 | } |
a269a03c | 6524 | }" |
6ef67412 JH |
6525 | [(set_attr "type" "alu,alu,imovx") |
6526 | (set_attr "length_immediate" "*,*,0") | |
6527 | (set_attr "mode" "SI")]) | |
6528 | ||
6529 | (define_split | |
6530 | [(set (match_operand:SI 0 "register_operand" "") | |
6531 | (and:SI (match_dup 0) | |
6532 | (const_int -65536))) | |
6533 | (clobber (reg:CC 17))] | |
6534 | "optimize_size" | |
6535 | [(set (strict_low_part (match_dup 1)) (const_int 0))] | |
6536 | "operands[1] = gen_lowpart (HImode, operands[0]);") | |
6537 | ||
6538 | (define_split | |
5e1a2fc7 JJ |
6539 | [(set (match_operand 0 "q_regs_operand" "") |
6540 | (and (match_dup 0) | |
6ef67412 JH |
6541 | (const_int -256))) |
6542 | (clobber (reg:CC 17))] | |
6543 | "(optimize_size || !TARGET_PARTIAL_REG_STALL) | |
6544 | && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)" | |
6545 | [(set (strict_low_part (match_dup 1)) (const_int 0))] | |
6546 | "operands[1] = gen_lowpart (QImode, operands[0]);") | |
6547 | ||
6548 | (define_split | |
5e1a2fc7 | 6549 | [(set (match_operand 0 "q_regs_operand" "") |
6ef67412 JH |
6550 | (and (match_dup 0) |
6551 | (const_int -65281))) | |
6552 | (clobber (reg:CC 17))] | |
6553 | "(optimize_size || !TARGET_PARTIAL_REG_STALL) | |
6554 | && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)" | |
6555 | [(parallel [(set (zero_extract:SI (match_dup 0) | |
6556 | (const_int 8) | |
6557 | (const_int 8)) | |
6558 | (xor:SI | |
6559 | (zero_extract:SI (match_dup 0) | |
6560 | (const_int 8) | |
6561 | (const_int 8)) | |
6562 | (zero_extract:SI (match_dup 0) | |
6563 | (const_int 8) | |
6564 | (const_int 8)))) | |
6565 | (clobber (reg:CC 17))])] | |
6566 | "operands[0] = gen_lowpart (SImode, operands[0]);") | |
e075ae69 RH |
6567 | |
6568 | (define_insn "*andsi_2" | |
16189740 RH |
6569 | [(set (reg 17) |
6570 | (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
6571 | (match_operand:SI 2 "general_operand" "rim,ri")) | |
6572 | (const_int 0))) | |
e075ae69 RH |
6573 | (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") |
6574 | (and:SI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
6575 | "ix86_match_ccmode (insn, CCNOmode) |
6576 | && ix86_binary_operator_ok (AND, SImode, operands)" | |
e075ae69 | 6577 | "and{l}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
6578 | [(set_attr "type" "alu") |
6579 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
6580 | |
6581 | (define_expand "andhi3" | |
6582 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
6583 | (and:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
6584 | (match_operand:HI 2 "general_operand" ""))) | |
6585 | (clobber (reg:CC 17))] | |
d9f32422 | 6586 | "TARGET_HIMODE_MATH" |
e075ae69 RH |
6587 | "ix86_expand_binary_operator (AND, HImode, operands); DONE;") |
6588 | ||
6589 | (define_insn "*andhi_1" | |
6590 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") | |
6591 | (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") | |
6592 | (match_operand:HI 2 "general_operand" "ri,rm,L"))) | |
6593 | (clobber (reg:CC 17))] | |
6594 | "ix86_binary_operator_ok (AND, HImode, operands)" | |
886c62d1 JVA |
6595 | "* |
6596 | { | |
e075ae69 | 6597 | switch (get_attr_type (insn)) |
886c62d1 | 6598 | { |
e075ae69 RH |
6599 | case TYPE_IMOVX: |
6600 | if (GET_CODE (operands[2]) != CONST_INT) | |
6601 | abort (); | |
6602 | if (INTVAL (operands[2]) == 0xff) | |
6603 | return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\"; | |
6604 | abort (); | |
886c62d1 | 6605 | |
e075ae69 RH |
6606 | default: |
6607 | if (! rtx_equal_p (operands[0], operands[1])) | |
6608 | abort (); | |
886c62d1 | 6609 | |
e075ae69 | 6610 | return \"and{w}\\t{%2, %0|%0, %2}\"; |
5bc7cd8e | 6611 | } |
e075ae69 | 6612 | }" |
6ef67412 JH |
6613 | [(set_attr "type" "alu,alu,imovx") |
6614 | (set_attr "length_immediate" "*,*,0") | |
6615 | (set_attr "mode" "HI,HI,SI")]) | |
5bc7cd8e | 6616 | |
e075ae69 | 6617 | (define_insn "*andhi_2" |
16189740 RH |
6618 | [(set (reg 17) |
6619 | (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
6620 | (match_operand:HI 2 "general_operand" "rim,ri")) | |
6621 | (const_int 0))) | |
e075ae69 RH |
6622 | (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") |
6623 | (and:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
6624 | "ix86_match_ccmode (insn, CCNOmode) |
6625 | && ix86_binary_operator_ok (AND, HImode, operands)" | |
e075ae69 | 6626 | "and{w}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
6627 | [(set_attr "type" "alu") |
6628 | (set_attr "mode" "HI")]) | |
5bc7cd8e | 6629 | |
e075ae69 RH |
6630 | (define_expand "andqi3" |
6631 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
6632 | (and:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
6633 | (match_operand:QI 2 "general_operand" ""))) | |
6634 | (clobber (reg:CC 17))] | |
d9f32422 | 6635 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
6636 | "ix86_expand_binary_operator (AND, QImode, operands); DONE;") |
6637 | ||
6638 | ;; %%% Potential partial reg stall on alternative 2. What to do? | |
6639 | (define_insn "*andqi_1" | |
7c6b971d | 6640 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") |
e075ae69 | 6641 | (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
7c6b971d | 6642 | (match_operand:QI 2 "general_operand" "qi,qmi,ri"))) |
e075ae69 RH |
6643 | (clobber (reg:CC 17))] |
6644 | "ix86_binary_operator_ok (AND, QImode, operands)" | |
6645 | "@ | |
6646 | and{b}\\t{%2, %0|%0, %2} | |
6647 | and{b}\\t{%2, %0|%0, %2} | |
6648 | and{l}\\t{%k2, %k0|%k0, %k2}" | |
6ef67412 JH |
6649 | [(set_attr "type" "alu") |
6650 | (set_attr "mode" "QI,QI,SI")]) | |
e075ae69 | 6651 | |
a1b8572c JH |
6652 | (define_insn "*andqi_1_slp" |
6653 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) | |
6654 | (and:QI (match_dup 0) | |
6655 | (match_operand:QI 1 "general_operand" "qi,qmi"))) | |
6656 | (clobber (reg:CC 17))] | |
6657 | "" | |
6658 | "and{b}\\t{%1, %0|%0, %1}" | |
6659 | [(set_attr "type" "alu1") | |
6660 | (set_attr "mode" "QI")]) | |
6661 | ||
e075ae69 | 6662 | (define_insn "*andqi_2" |
16189740 RH |
6663 | [(set (reg 17) |
6664 | (compare (and:QI | |
6665 | (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") | |
6666 | (match_operand:QI 2 "general_operand" "qim,qi,i")) | |
6667 | (const_int 0))) | |
e075ae69 RH |
6668 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") |
6669 | (and:QI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
6670 | "ix86_match_ccmode (insn, CCNOmode) |
6671 | && ix86_binary_operator_ok (AND, QImode, operands)" | |
adc88131 JJ |
6672 | "* |
6673 | { | |
6674 | if (which_alternative == 2) | |
6675 | { | |
6676 | if (GET_CODE (operands[2]) == CONST_INT | |
6677 | && (INTVAL (operands[2]) & 0xffffff00)) | |
6678 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); | |
6679 | return \"and{l}\\t{%2, %k0|%k0, %2}\"; | |
6680 | } | |
6681 | return \"and{b}\\t{%2, %0|%0, %2}\"; | |
6682 | }" | |
6ef67412 JH |
6683 | [(set_attr "type" "alu") |
6684 | (set_attr "mode" "QI,QI,SI")]) | |
e075ae69 | 6685 | |
a1b8572c JH |
6686 | (define_insn "*andqi_2_slp" |
6687 | [(set (reg 17) | |
6688 | (compare (and:QI | |
6689 | (match_operand:QI 0 "nonimmediate_operand" "+q,qm") | |
6690 | (match_operand:QI 1 "nonimmediate_operand" "qmi,qi")) | |
6691 | (const_int 0))) | |
6692 | (set (strict_low_part (match_dup 0)) | |
6693 | (and:QI (match_dup 0) (match_dup 1)))] | |
6694 | "ix86_match_ccmode (insn, CCNOmode)" | |
6695 | "and{b}\\t{%1, %0|%0, %1}" | |
6696 | [(set_attr "type" "alu1") | |
6697 | (set_attr "mode" "QI")]) | |
6698 | ||
e075ae69 RH |
6699 | ;; ??? A bug in recog prevents it from recognizing a const_int as an |
6700 | ;; operand to zero_extend in andqi_ext_1. It was checking explicitly | |
6701 | ;; for a QImode operand, which of course failed. | |
6702 | ||
6703 | (define_insn "andqi_ext_0" | |
d2836273 | 6704 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
6705 | (const_int 8) |
6706 | (const_int 8)) | |
6707 | (and:SI | |
6708 | (zero_extract:SI | |
6709 | (match_operand 1 "ext_register_operand" "0") | |
6710 | (const_int 8) | |
6711 | (const_int 8)) | |
6712 | (match_operand 2 "const_int_operand" "n"))) | |
6713 | (clobber (reg:CC 17))] | |
6714 | "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff" | |
6715 | "and{b}\\t{%2, %h0|%h0, %2}" | |
6ef67412 JH |
6716 | [(set_attr "type" "alu") |
6717 | (set_attr "length_immediate" "1") | |
6718 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
6719 | |
6720 | ;; Generated by peephole translating test to and. This shows up | |
6721 | ;; often in fp comparisons. | |
6722 | ||
6723 | (define_insn "*andqi_ext_0_cc" | |
16189740 RH |
6724 | [(set (reg 17) |
6725 | (compare | |
e075ae69 RH |
6726 | (and:SI |
6727 | (zero_extract:SI | |
084e679a | 6728 | (match_operand 1 "ext_register_operand" "0") |
d2836273 | 6729 | (const_int 8) |
e075ae69 RH |
6730 | (const_int 8)) |
6731 | (match_operand 2 "const_int_operand" "n")) | |
6732 | (const_int 0))) | |
d2836273 | 6733 | (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
6734 | (const_int 8) |
6735 | (const_int 8)) | |
6736 | (and:SI | |
6737 | (zero_extract:SI | |
6738 | (match_dup 1) | |
6739 | (const_int 8) | |
6740 | (const_int 8)) | |
6741 | (match_dup 2)))] | |
16189740 RH |
6742 | "ix86_match_ccmode (insn, CCNOmode) |
6743 | && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff" | |
e075ae69 | 6744 | "and{b}\\t{%2, %h0|%h0, %2}" |
6ef67412 JH |
6745 | [(set_attr "type" "alu") |
6746 | (set_attr "length_immediate" "1") | |
6747 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
6748 | |
6749 | (define_insn "*andqi_ext_1" | |
d2836273 | 6750 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
6751 | (const_int 8) |
6752 | (const_int 8)) | |
6753 | (and:SI | |
6754 | (zero_extract:SI | |
6755 | (match_operand 1 "ext_register_operand" "0") | |
6756 | (const_int 8) | |
6757 | (const_int 8)) | |
6758 | (zero_extend:SI | |
d2836273 | 6759 | (match_operand:QI 2 "general_operand" "Qm")))) |
e075ae69 | 6760 | (clobber (reg:CC 17))] |
d2836273 JH |
6761 | "!TARGET_64BIT" |
6762 | "and{b}\\t{%2, %h0|%h0, %2}" | |
6763 | [(set_attr "type" "alu") | |
6764 | (set_attr "length_immediate" "0") | |
6765 | (set_attr "mode" "QI")]) | |
6766 | ||
6767 | (define_insn "*andqi_ext_1_rex64" | |
6768 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
6769 | (const_int 8) | |
6770 | (const_int 8)) | |
6771 | (and:SI | |
6772 | (zero_extract:SI | |
6773 | (match_operand 1 "ext_register_operand" "0") | |
6774 | (const_int 8) | |
6775 | (const_int 8)) | |
6776 | (zero_extend:SI | |
6777 | (match_operand:QI 2 "ext_register_operand" "Q")))) | |
6778 | (clobber (reg:CC 17))] | |
6779 | "TARGET_64BIT" | |
e075ae69 | 6780 | "and{b}\\t{%2, %h0|%h0, %2}" |
6ef67412 JH |
6781 | [(set_attr "type" "alu") |
6782 | (set_attr "length_immediate" "0") | |
6783 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
6784 | |
6785 | (define_insn "*andqi_ext_2" | |
d2836273 | 6786 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
6787 | (const_int 8) |
6788 | (const_int 8)) | |
6789 | (and:SI | |
6790 | (zero_extract:SI | |
6791 | (match_operand 1 "ext_register_operand" "%0") | |
6792 | (const_int 8) | |
6793 | (const_int 8)) | |
6794 | (zero_extract:SI | |
d2836273 | 6795 | (match_operand 2 "ext_register_operand" "Q") |
e075ae69 RH |
6796 | (const_int 8) |
6797 | (const_int 8)))) | |
6798 | (clobber (reg:CC 17))] | |
6799 | "" | |
6800 | "and{b}\\t{%h2, %h0|%h0, %h2}" | |
6ef67412 JH |
6801 | [(set_attr "type" "alu") |
6802 | (set_attr "length_immediate" "0") | |
6803 | (set_attr "mode" "QI")]) | |
886c62d1 | 6804 | \f |
e075ae69 | 6805 | ;; Logical inclusive OR instructions |
57dbca5e | 6806 | |
e075ae69 RH |
6807 | ;; %%% This used to optimize known byte-wide and operations to memory. |
6808 | ;; If this is considered useful, it should be done with splitters. | |
6809 | ||
6810 | (define_expand "iorsi3" | |
6811 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
6812 | (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
6813 | (match_operand:SI 2 "general_operand" ""))) | |
6814 | (clobber (reg:CC 17))] | |
57dbca5e | 6815 | "" |
e075ae69 RH |
6816 | "ix86_expand_binary_operator (IOR, SImode, operands); DONE;") |
6817 | ||
6818 | (define_insn "*iorsi_1" | |
6819 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
6820 | (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
6821 | (match_operand:SI 2 "general_operand" "ri,rmi"))) | |
6822 | (clobber (reg:CC 17))] | |
6823 | "ix86_binary_operator_ok (IOR, SImode, operands)" | |
6824 | "or{l}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
6825 | [(set_attr "type" "alu") |
6826 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
6827 | |
6828 | (define_insn "*iorsi_2" | |
16189740 RH |
6829 | [(set (reg 17) |
6830 | (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
6831 | (match_operand:SI 2 "general_operand" "rim,ri")) | |
6832 | (const_int 0))) | |
e075ae69 RH |
6833 | (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") |
6834 | (ior:SI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
6835 | "ix86_match_ccmode (insn, CCNOmode) |
6836 | && ix86_binary_operator_ok (IOR, SImode, operands)" | |
e075ae69 | 6837 | "or{l}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
6838 | [(set_attr "type" "alu") |
6839 | (set_attr "mode" "SI")]) | |
e075ae69 | 6840 | |
d90ffc8d JH |
6841 | (define_insn "*iorsi_3" |
6842 | [(set (reg 17) | |
6843 | (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") | |
6844 | (match_operand:SI 2 "general_operand" "rim")) | |
6845 | (const_int 0))) | |
6846 | (clobber (match_scratch:SI 0 "=r"))] | |
6847 | "ix86_match_ccmode (insn, CCNOmode) | |
6848 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
6849 | "or{l}\\t{%2, %0|%0, %2}" | |
6850 | [(set_attr "type" "alu") | |
6851 | (set_attr "mode" "SI")]) | |
6852 | ||
e075ae69 RH |
6853 | (define_expand "iorhi3" |
6854 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
6855 | (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
6856 | (match_operand:HI 2 "general_operand" ""))) | |
6857 | (clobber (reg:CC 17))] | |
d9f32422 | 6858 | "TARGET_HIMODE_MATH" |
e075ae69 RH |
6859 | "ix86_expand_binary_operator (IOR, HImode, operands); DONE;") |
6860 | ||
6861 | (define_insn "*iorhi_1" | |
6862 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") | |
6863 | (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
6864 | (match_operand:HI 2 "general_operand" "rmi,ri"))) | |
6865 | (clobber (reg:CC 17))] | |
6866 | "ix86_binary_operator_ok (IOR, HImode, operands)" | |
6867 | "or{w}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
6868 | [(set_attr "type" "alu") |
6869 | (set_attr "mode" "HI")]) | |
e075ae69 | 6870 | |
e075ae69 | 6871 | (define_insn "*iorhi_2" |
16189740 RH |
6872 | [(set (reg 17) |
6873 | (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
6874 | (match_operand:HI 2 "general_operand" "rim,ri")) | |
6875 | (const_int 0))) | |
e075ae69 RH |
6876 | (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") |
6877 | (ior:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
6878 | "ix86_match_ccmode (insn, CCNOmode) |
6879 | && ix86_binary_operator_ok (IOR, HImode, operands)" | |
e075ae69 | 6880 | "or{w}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
6881 | [(set_attr "type" "alu") |
6882 | (set_attr "mode" "HI")]) | |
e075ae69 | 6883 | |
d90ffc8d JH |
6884 | (define_insn "*iorhi_3" |
6885 | [(set (reg 17) | |
6886 | (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") | |
6887 | (match_operand:HI 2 "general_operand" "rim")) | |
6888 | (const_int 0))) | |
6889 | (clobber (match_scratch:HI 0 "=r"))] | |
6890 | "ix86_match_ccmode (insn, CCNOmode) | |
6891 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
6892 | "or{w}\\t{%2, %0|%0, %2}" | |
6893 | [(set_attr "type" "alu") | |
6894 | (set_attr "mode" "HI")]) | |
6895 | ||
e075ae69 RH |
6896 | (define_expand "iorqi3" |
6897 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
6898 | (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
6899 | (match_operand:QI 2 "general_operand" ""))) | |
6900 | (clobber (reg:CC 17))] | |
d9f32422 | 6901 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
6902 | "ix86_expand_binary_operator (IOR, QImode, operands); DONE;") |
6903 | ||
6904 | ;; %%% Potential partial reg stall on alternative 2. What to do? | |
6905 | (define_insn "*iorqi_1" | |
7c6b971d | 6906 | [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") |
e075ae69 | 6907 | (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
7c6b971d | 6908 | (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) |
e075ae69 RH |
6909 | (clobber (reg:CC 17))] |
6910 | "ix86_binary_operator_ok (IOR, QImode, operands)" | |
6911 | "@ | |
6912 | or{b}\\t{%2, %0|%0, %2} | |
6913 | or{b}\\t{%2, %0|%0, %2} | |
6914 | or{l}\\t{%k2, %k0|%k0, %k2}" | |
6ef67412 | 6915 | [(set_attr "type" "alu") |
a1b8572c JH |
6916 | (set_attr "mode" "QI,QI,SI")]) |
6917 | ||
6918 | (define_insn "*iorqi_1_slp" | |
6919 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) | |
6920 | (ior:QI (match_dup 0) | |
6921 | (match_operand:QI 1 "general_operand" "qmi,qi"))) | |
6922 | (clobber (reg:CC 17))] | |
6923 | "" | |
6924 | "or{b}\\t{%1, %0|%0, %1}" | |
6925 | [(set_attr "type" "alu1") | |
6ef67412 | 6926 | (set_attr "mode" "QI")]) |
e075ae69 RH |
6927 | |
6928 | (define_insn "*iorqi_2" | |
16189740 RH |
6929 | [(set (reg 17) |
6930 | (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") | |
6931 | (match_operand:QI 2 "general_operand" "qim,qi")) | |
6932 | (const_int 0))) | |
e075ae69 RH |
6933 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") |
6934 | (ior:QI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
6935 | "ix86_match_ccmode (insn, CCNOmode) |
6936 | && ix86_binary_operator_ok (IOR, QImode, operands)" | |
e075ae69 | 6937 | "or{b}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
6938 | [(set_attr "type" "alu") |
6939 | (set_attr "mode" "QI")]) | |
d90ffc8d | 6940 | |
a1b8572c JH |
6941 | (define_insn "*iorqi_2_slp" |
6942 | [(set (reg 17) | |
6943 | (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") | |
6944 | (match_operand:QI 1 "general_operand" "qim,qi")) | |
6945 | (const_int 0))) | |
6946 | (set (strict_low_part (match_dup 0)) | |
6947 | (ior:QI (match_dup 0) (match_dup 1)))] | |
6948 | "ix86_match_ccmode (insn, CCNOmode)" | |
6949 | "or{b}\\t{%1, %0|%0, %1}" | |
6950 | [(set_attr "type" "alu1") | |
6951 | (set_attr "mode" "QI")]) | |
6952 | ||
d90ffc8d JH |
6953 | (define_insn "*iorqi_3" |
6954 | [(set (reg 17) | |
6955 | (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") | |
6956 | (match_operand:QI 2 "general_operand" "qim")) | |
6957 | (const_int 0))) | |
7e08e190 | 6958 | (clobber (match_scratch:QI 0 "=q"))] |
d90ffc8d JH |
6959 | "ix86_match_ccmode (insn, CCNOmode) |
6960 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
6961 | "or{b}\\t{%2, %0|%0, %2}" | |
6962 | [(set_attr "type" "alu") | |
6963 | (set_attr "mode" "QI")]) | |
6964 | ||
e075ae69 RH |
6965 | \f |
6966 | ;; Logical XOR instructions | |
a269a03c | 6967 | |
e075ae69 RH |
6968 | ;; %%% This used to optimize known byte-wide and operations to memory. |
6969 | ;; If this is considered useful, it should be done with splitters. | |
57dbca5e | 6970 | |
e075ae69 RH |
6971 | (define_expand "xorsi3" |
6972 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
6973 | (xor:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
6974 | (match_operand:SI 2 "general_operand" ""))) | |
6975 | (clobber (reg:CC 17))] | |
57dbca5e | 6976 | "" |
e075ae69 | 6977 | "ix86_expand_binary_operator (XOR, SImode, operands); DONE;") |
a269a03c | 6978 | |
e075ae69 RH |
6979 | (define_insn "*xorsi_1" |
6980 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
6981 | (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
6982 | (match_operand:SI 2 "general_operand" "ri,rm"))) | |
6983 | (clobber (reg:CC 17))] | |
6984 | "ix86_binary_operator_ok (XOR, SImode, operands)" | |
6985 | "xor{l}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
6986 | [(set_attr "type" "alu") |
6987 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
6988 | |
6989 | (define_insn "*xorsi_2" | |
16189740 RH |
6990 | [(set (reg 17) |
6991 | (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
6992 | (match_operand:SI 2 "general_operand" "rim,ri")) | |
6993 | (const_int 0))) | |
e075ae69 RH |
6994 | (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") |
6995 | (xor:SI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
6996 | "ix86_match_ccmode (insn, CCNOmode) |
6997 | && ix86_binary_operator_ok (XOR, SImode, operands)" | |
e075ae69 | 6998 | "xor{l}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
6999 | [(set_attr "type" "alu") |
7000 | (set_attr "mode" "SI")]) | |
e075ae69 | 7001 | |
d90ffc8d JH |
7002 | (define_insn "*xorsi_3" |
7003 | [(set (reg 17) | |
7004 | (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") | |
7005 | (match_operand:SI 2 "general_operand" "rim")) | |
7006 | (const_int 0))) | |
7007 | (clobber (match_scratch:SI 0 "=r"))] | |
7008 | "ix86_match_ccmode (insn, CCNOmode) | |
7009 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
7010 | "xor{l}\\t{%2, %0|%0, %2}" | |
7011 | [(set_attr "type" "alu") | |
7012 | (set_attr "mode" "SI")]) | |
7013 | ||
e075ae69 RH |
7014 | (define_expand "xorhi3" |
7015 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
7016 | (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7017 | (match_operand:HI 2 "general_operand" ""))) | |
7018 | (clobber (reg:CC 17))] | |
d9f32422 | 7019 | "TARGET_HIMODE_MATH" |
e075ae69 RH |
7020 | "ix86_expand_binary_operator (XOR, HImode, operands); DONE;") |
7021 | ||
7022 | (define_insn "*xorhi_1" | |
7023 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") | |
7024 | (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
7025 | (match_operand:HI 2 "general_operand" "rmi,ri"))) | |
7026 | (clobber (reg:CC 17))] | |
7027 | "ix86_binary_operator_ok (XOR, HImode, operands)" | |
7028 | "xor{w}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
7029 | [(set_attr "type" "alu") |
7030 | (set_attr "mode" "HI")]) | |
57dbca5e | 7031 | |
e075ae69 | 7032 | (define_insn "*xorhi_2" |
16189740 RH |
7033 | [(set (reg 17) |
7034 | (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
7035 | (match_operand:HI 2 "general_operand" "rim,ri")) | |
7036 | (const_int 0))) | |
e075ae69 RH |
7037 | (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") |
7038 | (xor:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
7039 | "ix86_match_ccmode (insn, CCNOmode) |
7040 | && ix86_binary_operator_ok (XOR, HImode, operands)" | |
e075ae69 | 7041 | "xor{w}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
7042 | [(set_attr "type" "alu") |
7043 | (set_attr "mode" "HI")]) | |
e075ae69 | 7044 | |
d90ffc8d JH |
7045 | (define_insn "*xorhi_3" |
7046 | [(set (reg 17) | |
7047 | (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") | |
7048 | (match_operand:HI 2 "general_operand" "rim")) | |
7049 | (const_int 0))) | |
7050 | (clobber (match_scratch:HI 0 "=r"))] | |
7051 | "ix86_match_ccmode (insn, CCNOmode) | |
7052 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
7053 | "xor{w}\\t{%2, %0|%0, %2}" | |
7054 | [(set_attr "type" "alu") | |
7055 | (set_attr "mode" "HI")]) | |
7056 | ||
e075ae69 RH |
7057 | (define_expand "xorqi3" |
7058 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
7059 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7060 | (match_operand:QI 2 "general_operand" ""))) | |
7061 | (clobber (reg:CC 17))] | |
d9f32422 | 7062 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
7063 | "ix86_expand_binary_operator (XOR, QImode, operands); DONE;") |
7064 | ||
7065 | ;; %%% Potential partial reg stall on alternative 2. What to do? | |
7066 | (define_insn "*xorqi_1" | |
7c6b971d | 7067 | [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") |
e075ae69 | 7068 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
7c6b971d | 7069 | (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) |
e075ae69 RH |
7070 | (clobber (reg:CC 17))] |
7071 | "ix86_binary_operator_ok (XOR, QImode, operands)" | |
7072 | "@ | |
7073 | xor{b}\\t{%2, %0|%0, %2} | |
7074 | xor{b}\\t{%2, %0|%0, %2} | |
7075 | xor{l}\\t{%k2, %k0|%k0, %k2}" | |
6ef67412 JH |
7076 | [(set_attr "type" "alu") |
7077 | (set_attr "mode" "QI,QI,SI")]) | |
7078 | ||
a4414093 | 7079 | (define_insn "*xorqi_ext_1" |
d2836273 | 7080 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
6ef67412 JH |
7081 | (const_int 8) |
7082 | (const_int 8)) | |
7083 | (xor:SI | |
7084 | (zero_extract:SI (match_operand 1 "ext_register_operand" "0") | |
7085 | (const_int 8) | |
7086 | (const_int 8)) | |
d2836273 | 7087 | (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") |
6ef67412 JH |
7088 | (const_int 8) |
7089 | (const_int 8)))) | |
7090 | (clobber (reg:CC 17))] | |
7091 | "" | |
7092 | "xor{b}\\t{%h2, %h0|%h0, %h2}" | |
7093 | [(set_attr "type" "alu") | |
7094 | (set_attr "length_immediate" "0") | |
7095 | (set_attr "mode" "QI")]) | |
e075ae69 | 7096 | |
7abd4e00 | 7097 | (define_insn "*xorqi_cc_1" |
16189740 RH |
7098 | [(set (reg 17) |
7099 | (compare | |
e075ae69 RH |
7100 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") |
7101 | (match_operand:QI 2 "general_operand" "qim,qi")) | |
7102 | (const_int 0))) | |
7103 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") | |
7104 | (xor:QI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
7105 | "ix86_match_ccmode (insn, CCNOmode) |
7106 | && ix86_binary_operator_ok (XOR, QImode, operands)" | |
e075ae69 | 7107 | "xor{b}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
7108 | [(set_attr "type" "alu") |
7109 | (set_attr "mode" "QI")]) | |
e075ae69 | 7110 | |
d90ffc8d JH |
7111 | (define_insn "*xorqi_cc_2" |
7112 | [(set (reg 17) | |
7113 | (compare | |
7114 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") | |
7115 | (match_operand:QI 2 "general_operand" "qim")) | |
7116 | (const_int 0))) | |
7e08e190 | 7117 | (clobber (match_scratch:QI 0 "=q"))] |
d90ffc8d JH |
7118 | "ix86_match_ccmode (insn, CCNOmode) |
7119 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
7120 | "xor{b}\\t{%2, %0|%0, %2}" | |
7121 | [(set_attr "type" "alu") | |
7122 | (set_attr "mode" "QI")]) | |
7123 | ||
9076b9c1 JH |
7124 | (define_insn "*xorqi_cc_ext_1" |
7125 | [(set (reg 17) | |
7126 | (compare | |
e075ae69 RH |
7127 | (xor:SI |
7128 | (zero_extract:SI | |
7129 | (match_operand 1 "ext_register_operand" "0") | |
7130 | (const_int 8) | |
7131 | (const_int 8)) | |
7132 | (match_operand:QI 2 "general_operand" "qmn")) | |
7133 | (const_int 0))) | |
7134 | (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") | |
7135 | (const_int 8) | |
7136 | (const_int 8)) | |
7137 | (xor:SI | |
7138 | (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) | |
7139 | (match_dup 2)))] | |
d2836273 JH |
7140 | "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" |
7141 | "xor{b}\\t{%2, %h0|%h0, %2}" | |
7142 | [(set_attr "type" "alu") | |
7143 | (set_attr "mode" "QI")]) | |
7144 | ||
7145 | (define_insn "*xorqi_cc_ext_1_rex64" | |
7146 | [(set (reg 17) | |
7147 | (compare | |
7148 | (xor:SI | |
7149 | (zero_extract:SI | |
7150 | (match_operand 1 "ext_register_operand" "0") | |
7151 | (const_int 8) | |
7152 | (const_int 8)) | |
7153 | (match_operand:QI 2 "nonmemory_operand" "Qn")) | |
7154 | (const_int 0))) | |
7155 | (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
7156 | (const_int 8) | |
7157 | (const_int 8)) | |
7158 | (xor:SI | |
7159 | (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) | |
7160 | (match_dup 2)))] | |
7161 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" | |
e075ae69 | 7162 | "xor{b}\\t{%2, %h0|%h0, %2}" |
6ef67412 JH |
7163 | [(set_attr "type" "alu") |
7164 | (set_attr "mode" "QI")]) | |
9076b9c1 JH |
7165 | |
7166 | (define_expand "xorqi_cc_ext_1" | |
7167 | [(parallel [ | |
7168 | (set (reg:CCNO 17) | |
7169 | (compare:CCNO | |
7170 | (xor:SI | |
7171 | (zero_extract:SI | |
7172 | (match_operand 1 "ext_register_operand" "") | |
7173 | (const_int 8) | |
7174 | (const_int 8)) | |
7175 | (match_operand:QI 2 "general_operand" "")) | |
7176 | (const_int 0))) | |
7177 | (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") | |
7178 | (const_int 8) | |
7179 | (const_int 8)) | |
7180 | (xor:SI | |
7181 | (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) | |
7182 | (match_dup 2)))])] | |
7183 | "" | |
7184 | "") | |
e075ae69 RH |
7185 | \f |
7186 | ;; Negation instructions | |
57dbca5e | 7187 | |
e075ae69 | 7188 | ;; %%% define_expand from the very first? |
886c62d1 | 7189 | |
06a964de JH |
7190 | (define_expand "negdi2" |
7191 | [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
2756c3d8 | 7192 | (neg:DI (match_operand:DI 1 "nonimmediate_operand" ""))) |
06a964de JH |
7193 | (clobber (reg:CC 17))])] |
7194 | "" | |
7195 | "ix86_expand_unary_operator (NEG, DImode, operands); DONE;") | |
7196 | ||
7197 | (define_insn "*negdi2_1" | |
e075ae69 RH |
7198 | [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") |
7199 | (neg:DI (match_operand:DI 1 "general_operand" "0"))) | |
7200 | (clobber (reg:CC 17))] | |
d2836273 JH |
7201 | "!TARGET_64BIT |
7202 | && ix86_unary_operator_ok (NEG, DImode, operands)" | |
e075ae69 | 7203 | "#") |
886c62d1 | 7204 | |
e075ae69 RH |
7205 | (define_split |
7206 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
7207 | (neg:DI (match_operand:DI 1 "general_operand" ""))) | |
7208 | (clobber (reg:CC 17))] | |
d2836273 JH |
7209 | "reload_completed |
7210 | && !TARGET_64BIT" | |
e075ae69 | 7211 | [(parallel |
16189740 RH |
7212 | [(set (reg:CCZ 17) |
7213 | (compare:CCZ (neg:SI (match_dup 2)) (const_int 0))) | |
e075ae69 RH |
7214 | (set (match_dup 0) (neg:SI (match_dup 2)))]) |
7215 | (parallel | |
7216 | [(set (match_dup 1) | |
7e08e190 | 7217 | (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0)) |
9dcbdc7e JH |
7218 | (match_dup 3)) |
7219 | (const_int 0))) | |
e075ae69 RH |
7220 | (clobber (reg:CC 17))]) |
7221 | (parallel | |
7222 | [(set (match_dup 1) | |
7223 | (neg:SI (match_dup 1))) | |
7224 | (clobber (reg:CC 17))])] | |
7225 | "split_di (operands+1, 1, operands+2, operands+3); | |
7226 | split_di (operands+0, 1, operands+0, operands+1);") | |
886c62d1 | 7227 | |
06a964de JH |
7228 | (define_expand "negsi2" |
7229 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
2756c3d8 | 7230 | (neg:SI (match_operand:SI 1 "nonimmediate_operand" ""))) |
06a964de JH |
7231 | (clobber (reg:CC 17))])] |
7232 | "" | |
7233 | "ix86_expand_unary_operator (NEG, SImode, operands); DONE;") | |
7234 | ||
7235 | (define_insn "*negsi2_1" | |
2ae0f82c | 7236 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
e075ae69 RH |
7237 | (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))) |
7238 | (clobber (reg:CC 17))] | |
06a964de | 7239 | "ix86_unary_operator_ok (NEG, SImode, operands)" |
e075ae69 | 7240 | "neg{l}\\t%0" |
6ef67412 JH |
7241 | [(set_attr "type" "negnot") |
7242 | (set_attr "mode" "SI")]) | |
e075ae69 | 7243 | |
16189740 RH |
7244 | ;; The problem with neg is that it does not perform (compare x 0), |
7245 | ;; it really performs (compare 0 x), which leaves us with the zero | |
7246 | ;; flag being the only useful item. | |
e075ae69 | 7247 | |
16189740 RH |
7248 | (define_insn "*negsi2_cmpz" |
7249 | [(set (reg:CCZ 17) | |
7250 | (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")) | |
7251 | (const_int 0))) | |
e075ae69 RH |
7252 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
7253 | (neg:SI (match_dup 1)))] | |
06a964de | 7254 | "ix86_unary_operator_ok (NEG, SImode, operands)" |
e075ae69 | 7255 | "neg{l}\\t%0" |
6ef67412 JH |
7256 | [(set_attr "type" "negnot") |
7257 | (set_attr "mode" "SI")]) | |
886c62d1 | 7258 | |
06a964de JH |
7259 | (define_expand "neghi2" |
7260 | [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
2756c3d8 | 7261 | (neg:HI (match_operand:HI 1 "nonimmediate_operand" ""))) |
06a964de | 7262 | (clobber (reg:CC 17))])] |
d9f32422 | 7263 | "TARGET_HIMODE_MATH" |
06a964de JH |
7264 | "ix86_expand_unary_operator (NEG, HImode, operands); DONE;") |
7265 | ||
7266 | (define_insn "*neghi2_1" | |
2ae0f82c | 7267 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
e075ae69 RH |
7268 | (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))) |
7269 | (clobber (reg:CC 17))] | |
06a964de | 7270 | "ix86_unary_operator_ok (NEG, HImode, operands)" |
e075ae69 | 7271 | "neg{w}\\t%0" |
6ef67412 JH |
7272 | [(set_attr "type" "negnot") |
7273 | (set_attr "mode" "HI")]) | |
e075ae69 | 7274 | |
16189740 RH |
7275 | (define_insn "*neghi2_cmpz" |
7276 | [(set (reg:CCZ 17) | |
7277 | (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")) | |
7278 | (const_int 0))) | |
e075ae69 RH |
7279 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
7280 | (neg:HI (match_dup 1)))] | |
06a964de | 7281 | "ix86_unary_operator_ok (NEG, HImode, operands)" |
e075ae69 | 7282 | "neg{w}\\t%0" |
6ef67412 JH |
7283 | [(set_attr "type" "negnot") |
7284 | (set_attr "mode" "HI")]) | |
886c62d1 | 7285 | |
06a964de JH |
7286 | (define_expand "negqi2" |
7287 | [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
2756c3d8 | 7288 | (neg:QI (match_operand:QI 1 "nonimmediate_operand" ""))) |
06a964de | 7289 | (clobber (reg:CC 17))])] |
d9f32422 | 7290 | "TARGET_QIMODE_MATH" |
06a964de JH |
7291 | "ix86_expand_unary_operator (NEG, QImode, operands); DONE;") |
7292 | ||
7293 | (define_insn "*negqi2_1" | |
2ae0f82c | 7294 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
e075ae69 RH |
7295 | (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))) |
7296 | (clobber (reg:CC 17))] | |
06a964de | 7297 | "ix86_unary_operator_ok (NEG, QImode, operands)" |
e075ae69 | 7298 | "neg{b}\\t%0" |
6ef67412 JH |
7299 | [(set_attr "type" "negnot") |
7300 | (set_attr "mode" "QI")]) | |
e075ae69 | 7301 | |
16189740 RH |
7302 | (define_insn "*negqi2_cmpz" |
7303 | [(set (reg:CCZ 17) | |
7304 | (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")) | |
7305 | (const_int 0))) | |
e075ae69 RH |
7306 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
7307 | (neg:QI (match_dup 1)))] | |
06a964de | 7308 | "ix86_unary_operator_ok (NEG, QImode, operands)" |
e075ae69 | 7309 | "neg{b}\\t%0" |
6ef67412 JH |
7310 | [(set_attr "type" "negnot") |
7311 | (set_attr "mode" "QI")]) | |
886c62d1 | 7312 | |
06a964de | 7313 | ;; Changing of sign for FP values is doable using integer unit too. |
1ce485ec | 7314 | |
06a964de JH |
7315 | (define_expand "negsf2" |
7316 | [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
2756c3d8 | 7317 | (neg:SF (match_operand:SF 1 "nonimmediate_operand" ""))) |
06a964de JH |
7318 | (clobber (reg:CC 17))])] |
7319 | "TARGET_80387" | |
7320 | "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;") | |
7321 | ||
e20440c1 JH |
7322 | ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems |
7323 | ;; because of secondary memory needed to reload from class FLOAT_INT_REGS | |
7324 | ;; to itself. | |
06a964de | 7325 | (define_insn "*negsf2_if" |
e20440c1 JH |
7326 | [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f") |
7327 | (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0"))) | |
1ce485ec | 7328 | (clobber (reg:CC 17))] |
06a964de | 7329 | "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)" |
1ce485ec JH |
7330 | "#") |
7331 | ||
7332 | (define_split | |
7333 | [(set (match_operand:SF 0 "register_operand" "") | |
7334 | (neg:SF (match_operand:SF 1 "register_operand" ""))) | |
7335 | (clobber (reg:CC 17))] | |
7336 | "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed" | |
7337 | [(set (match_dup 0) | |
7338 | (neg:SF (match_dup 1)))] | |
7339 | "") | |
7340 | ||
7341 | (define_split | |
7342 | [(set (match_operand:SF 0 "register_operand" "") | |
7343 | (neg:SF (match_operand:SF 1 "register_operand" ""))) | |
7344 | (clobber (reg:CC 17))] | |
7345 | "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))" | |
7346 | [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1))) | |
7347 | (clobber (reg:CC 17))])] | |
7348 | "operands[1] = GEN_INT (0x80000000); | |
7349 | operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));") | |
7350 | ||
7351 | (define_split | |
7352 | [(set (match_operand 0 "memory_operand" "") | |
7353 | (neg (match_operand 1 "memory_operand" ""))) | |
7354 | (clobber (reg:CC 17))] | |
7355 | "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))" | |
7356 | [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1))) | |
7357 | (clobber (reg:CC 17))])] | |
7358 | " | |
7359 | { | |
7360 | int size = GET_MODE_SIZE (GET_MODE (operands[1])); | |
7361 | ||
7362 | /* XFmode's size is 12, but only 10 bytes are used. */ | |
7363 | if (size == 12) | |
7364 | size = 10; | |
7365 | operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0)); | |
7366 | operands[0] = adj_offsettable_operand (operands[0], size - 1); | |
7367 | operands[1] = GEN_INT (0x80); | |
7368 | }") | |
7369 | ||
06a964de JH |
7370 | (define_expand "negdf2" |
7371 | [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
2756c3d8 | 7372 | (neg:DF (match_operand:DF 1 "nonimmediate_operand" ""))) |
06a964de JH |
7373 | (clobber (reg:CC 17))])] |
7374 | "TARGET_80387" | |
7375 | "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;") | |
7376 | ||
e20440c1 JH |
7377 | ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems |
7378 | ;; because of secondary memory needed to reload from class FLOAT_INT_REGS | |
7379 | ;; to itself. | |
06a964de | 7380 | (define_insn "*negdf2_if" |
e20440c1 JH |
7381 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f") |
7382 | (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0"))) | |
1ce485ec | 7383 | (clobber (reg:CC 17))] |
06a964de | 7384 | "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)" |
1ce485ec JH |
7385 | "#") |
7386 | ||
7387 | (define_split | |
7388 | [(set (match_operand:DF 0 "register_operand" "") | |
7389 | (neg:DF (match_operand:DF 1 "register_operand" ""))) | |
7390 | (clobber (reg:CC 17))] | |
7391 | "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed" | |
7392 | [(set (match_dup 0) | |
7393 | (neg:DF (match_dup 1)))] | |
7394 | "") | |
7395 | ||
7396 | (define_split | |
7397 | [(set (match_operand:DF 0 "register_operand" "") | |
7398 | (neg:DF (match_operand:DF 1 "register_operand" ""))) | |
7399 | (clobber (reg:CC 17))] | |
7400 | "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))" | |
7401 | [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4))) | |
7402 | (clobber (reg:CC 17))])] | |
7403 | "operands[4] = GEN_INT (0x80000000); | |
7404 | split_di (operands+0, 1, operands+2, operands+3);") | |
7405 | ||
06a964de JH |
7406 | (define_expand "negxf2" |
7407 | [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") | |
2756c3d8 | 7408 | (neg:XF (match_operand:XF 1 "nonimmediate_operand" ""))) |
06a964de | 7409 | (clobber (reg:CC 17))])] |
1e07edd3 | 7410 | "TARGET_80387 && !TARGET_64BIT" |
06a964de JH |
7411 | "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;") |
7412 | ||
2b589241 JH |
7413 | (define_expand "negtf2" |
7414 | [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
7415 | (neg:TF (match_operand:TF 1 "nonimmediate_operand" ""))) | |
7416 | (clobber (reg:CC 17))])] | |
7417 | "TARGET_80387" | |
7418 | "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;") | |
7419 | ||
e20440c1 JH |
7420 | ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems |
7421 | ;; because of secondary memory needed to reload from class FLOAT_INT_REGS | |
7422 | ;; to itself. | |
06a964de | 7423 | (define_insn "*negxf2_if" |
e20440c1 JH |
7424 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f") |
7425 | (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0"))) | |
1ce485ec | 7426 | (clobber (reg:CC 17))] |
1e07edd3 JH |
7427 | "TARGET_80387 && !TARGET_64BIT |
7428 | && ix86_unary_operator_ok (NEG, XFmode, operands)" | |
1ce485ec JH |
7429 | "#") |
7430 | ||
7431 | (define_split | |
7432 | [(set (match_operand:XF 0 "register_operand" "") | |
7433 | (neg:XF (match_operand:XF 1 "register_operand" ""))) | |
7434 | (clobber (reg:CC 17))] | |
7435 | "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed" | |
7436 | [(set (match_dup 0) | |
7437 | (neg:XF (match_dup 1)))] | |
7438 | "") | |
7439 | ||
7440 | (define_split | |
7441 | [(set (match_operand:XF 0 "register_operand" "") | |
7442 | (neg:XF (match_operand:XF 1 "register_operand" ""))) | |
7443 | (clobber (reg:CC 17))] | |
7444 | "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))" | |
7445 | [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1))) | |
7446 | (clobber (reg:CC 17))])] | |
7447 | "operands[1] = GEN_INT (0x8000); | |
7448 | operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);") | |
7449 | ||
2b589241 JH |
7450 | ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems |
7451 | ;; because of secondary memory needed to reload from class FLOAT_INT_REGS | |
7452 | ;; to itself. | |
7453 | (define_insn "*negtf2_if" | |
7454 | [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f") | |
7455 | (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0"))) | |
7456 | (clobber (reg:CC 17))] | |
7457 | "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)" | |
7458 | "#") | |
7459 | ||
7460 | (define_split | |
7461 | [(set (match_operand:TF 0 "register_operand" "") | |
7462 | (neg:TF (match_operand:TF 1 "register_operand" ""))) | |
7463 | (clobber (reg:CC 17))] | |
7464 | "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed" | |
7465 | [(set (match_dup 0) | |
7466 | (neg:TF (match_dup 1)))] | |
7467 | "") | |
7468 | ||
7469 | (define_split | |
7470 | [(set (match_operand:TF 0 "register_operand" "") | |
7471 | (neg:TF (match_operand:TF 1 "register_operand" ""))) | |
7472 | (clobber (reg:CC 17))] | |
7473 | "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))" | |
7474 | [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1))) | |
7475 | (clobber (reg:CC 17))])] | |
7476 | "operands[1] = GEN_INT (0x8000); | |
7477 | operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);") | |
7478 | ||
1ce485ec JH |
7479 | ;; Conditionize these after reload. If they matches before reload, we |
7480 | ;; lose the clobber and ability to use integer instructions. | |
7481 | ||
7482 | (define_insn "*negsf2_1" | |
886c62d1 | 7483 | [(set (match_operand:SF 0 "register_operand" "=f") |
2ae0f82c | 7484 | (neg:SF (match_operand:SF 1 "register_operand" "0")))] |
1ce485ec | 7485 | "TARGET_80387 && reload_completed" |
10195bd8 | 7486 | "fchs" |
e075ae69 | 7487 | [(set_attr "type" "fsgn") |
6ef67412 | 7488 | (set_attr "mode" "SF") |
e075ae69 | 7489 | (set_attr "ppro_uops" "few")]) |
886c62d1 | 7490 | |
1ce485ec | 7491 | (define_insn "*negdf2_1" |
886c62d1 | 7492 | [(set (match_operand:DF 0 "register_operand" "=f") |
2ae0f82c | 7493 | (neg:DF (match_operand:DF 1 "register_operand" "0")))] |
1ce485ec | 7494 | "TARGET_80387 && reload_completed" |
10195bd8 | 7495 | "fchs" |
e075ae69 | 7496 | [(set_attr "type" "fsgn") |
6ef67412 | 7497 | (set_attr "mode" "DF") |
e075ae69 | 7498 | (set_attr "ppro_uops" "few")]) |
886c62d1 | 7499 | |
6343a50e | 7500 | (define_insn "*negextendsfdf2" |
886c62d1 | 7501 | [(set (match_operand:DF 0 "register_operand" "=f") |
e075ae69 RH |
7502 | (neg:DF (float_extend:DF |
7503 | (match_operand:SF 1 "register_operand" "0"))))] | |
886c62d1 | 7504 | "TARGET_80387" |
10195bd8 | 7505 | "fchs" |
e075ae69 | 7506 | [(set_attr "type" "fsgn") |
6ef67412 | 7507 | (set_attr "mode" "DF") |
e075ae69 | 7508 | (set_attr "ppro_uops" "few")]) |
4fb21e90 | 7509 | |
1ce485ec | 7510 | (define_insn "*negxf2_1" |
4fb21e90 | 7511 | [(set (match_operand:XF 0 "register_operand" "=f") |
2ae0f82c | 7512 | (neg:XF (match_operand:XF 1 "register_operand" "0")))] |
1e07edd3 | 7513 | "TARGET_80387 && !TARGET_64BIT && reload_completed" |
10195bd8 | 7514 | "fchs" |
e075ae69 | 7515 | [(set_attr "type" "fsgn") |
6ef67412 | 7516 | (set_attr "mode" "XF") |
e075ae69 RH |
7517 | (set_attr "ppro_uops" "few")]) |
7518 | ||
6343a50e | 7519 | (define_insn "*negextenddfxf2" |
e075ae69 RH |
7520 | [(set (match_operand:XF 0 "register_operand" "=f") |
7521 | (neg:XF (float_extend:XF | |
7522 | (match_operand:DF 1 "register_operand" "0"))))] | |
1e07edd3 | 7523 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
7524 | "fchs" |
7525 | [(set_attr "type" "fsgn") | |
6ef67412 | 7526 | (set_attr "mode" "XF") |
e075ae69 | 7527 | (set_attr "ppro_uops" "few")]) |
4fb21e90 | 7528 | |
6343a50e | 7529 | (define_insn "*negextendsfxf2" |
4fb21e90 | 7530 | [(set (match_operand:XF 0 "register_operand" "=f") |
e075ae69 RH |
7531 | (neg:XF (float_extend:XF |
7532 | (match_operand:SF 1 "register_operand" "0"))))] | |
1e07edd3 | 7533 | "TARGET_80387 && !TARGET_64BIT" |
10195bd8 | 7534 | "fchs" |
e075ae69 | 7535 | [(set_attr "type" "fsgn") |
6ef67412 | 7536 | (set_attr "mode" "XF") |
e075ae69 | 7537 | (set_attr "ppro_uops" "few")]) |
2b589241 JH |
7538 | |
7539 | (define_insn "*negtf2_1" | |
7540 | [(set (match_operand:TF 0 "register_operand" "=f") | |
7541 | (neg:TF (match_operand:TF 1 "register_operand" "0")))] | |
7542 | "TARGET_80387 && reload_completed" | |
7543 | "fchs" | |
7544 | [(set_attr "type" "fsgn") | |
7545 | (set_attr "mode" "XF") | |
7546 | (set_attr "ppro_uops" "few")]) | |
7547 | ||
7548 | (define_insn "*negextenddftf2" | |
7549 | [(set (match_operand:TF 0 "register_operand" "=f") | |
7550 | (neg:TF (float_extend:TF | |
7551 | (match_operand:DF 1 "register_operand" "0"))))] | |
7552 | "TARGET_80387" | |
7553 | "fchs" | |
7554 | [(set_attr "type" "fsgn") | |
7555 | (set_attr "mode" "XF") | |
7556 | (set_attr "ppro_uops" "few")]) | |
7557 | ||
7558 | (define_insn "*negextendsftf2" | |
7559 | [(set (match_operand:TF 0 "register_operand" "=f") | |
7560 | (neg:TF (float_extend:TF | |
7561 | (match_operand:SF 1 "register_operand" "0"))))] | |
7562 | "TARGET_80387" | |
7563 | "fchs" | |
7564 | [(set_attr "type" "fsgn") | |
7565 | (set_attr "mode" "XF") | |
7566 | (set_attr "ppro_uops" "few")]) | |
886c62d1 JVA |
7567 | \f |
7568 | ;; Absolute value instructions | |
7569 | ||
06a964de JH |
7570 | (define_expand "abssf2" |
7571 | [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
2756c3d8 | 7572 | (neg:SF (match_operand:SF 1 "nonimmediate_operand" ""))) |
06a964de JH |
7573 | (clobber (reg:CC 17))])] |
7574 | "TARGET_80387" | |
ca29d1dc JH |
7575 | "if (TARGET_SSE) |
7576 | { | |
7577 | /* In case operand is in memory, we will not use SSE. */ | |
7578 | if (memory_operand (operands[0], VOIDmode) | |
7579 | && rtx_equal_p (operands[0], operands[1])) | |
7580 | emit_insn (gen_abssf2_memory (operands[0], operands[1])); | |
7581 | else | |
7582 | { | |
7583 | /* Using SSE is tricky, since we need bitwise negation of -0 | |
7584 | in register. */ | |
7585 | rtx reg = gen_reg_rtx (SFmode); | |
7586 | emit_move_insn (reg, gen_lowpart (SFmode, GEN_INT (0x80000000))); | |
7587 | emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg)); | |
7588 | } | |
7589 | DONE; | |
7590 | } | |
7591 | ix86_expand_unary_operator (ABS, SFmode, operands); DONE;") | |
7592 | ||
7593 | (define_insn "abssf2_memory" | |
7594 | [(set (match_operand:SF 0 "memory_operand" "=m") | |
7595 | (abs:SF (match_operand:SF 1 "memory_operand" "0"))) | |
7596 | (clobber (reg:CC 17))] | |
7597 | "ix86_unary_operator_ok (ABS, SFmode, operands)" | |
7598 | "#") | |
7599 | ||
7600 | (define_insn "abssf2_ifs" | |
7601 | [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,r#xf") | |
7602 | (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0"))) | |
7603 | (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*X#x,*X#x")) | |
7604 | (clobber (reg:CC 17))] | |
7605 | "TARGET_SSE" | |
7606 | "#") | |
7607 | ||
7608 | (define_split | |
7609 | [(set (match_operand:SF 0 "memory_operand" "") | |
7610 | (abs:SF (match_operand:SF 1 "memory_operand" ""))) | |
7611 | (use (match_operand:SF 2 "" "")) | |
7612 | (clobber (reg:CC 17))] | |
7613 | "" | |
7614 | [(parallel [(set (match_dup 0) | |
7615 | (abs:SF (match_dup 1))) | |
7616 | (clobber (reg:CC 17))])]) | |
7617 | ||
7618 | (define_split | |
7619 | [(set (match_operand:SF 0 "register_operand" "") | |
7620 | (abs:SF (match_operand:SF 1 "register_operand" ""))) | |
7621 | (use (match_operand:SF 2 "" "")) | |
7622 | (clobber (reg:CC 17))] | |
7623 | "reload_completed && !SSE_REG_P (operands[0])" | |
7624 | [(parallel [(set (match_dup 0) | |
7625 | (abs:SF (match_dup 1))) | |
7626 | (clobber (reg:CC 17))])]) | |
7627 | ||
7628 | (define_split | |
7629 | [(set (match_operand:SF 0 "register_operand" "") | |
7630 | (abs:SF (match_operand:SF 1 "register_operand" ""))) | |
7631 | (use (match_operand:SF 2 "register_operand" "")) | |
7632 | (clobber (reg:CC 17))] | |
7633 | "reload_completed && SSE_REG_P (operands[0])" | |
7634 | [(set (subreg:TI (match_dup 0) 0) | |
7635 | (and:TI (not:TI (subreg:TI (match_dup 2) 0)) | |
7636 | (subreg:TI (match_dup 1) 0)))]) | |
06a964de | 7637 | |
e20440c1 JH |
7638 | ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems |
7639 | ;; because of secondary memory needed to reload from class FLOAT_INT_REGS | |
7640 | ;; to itself. | |
06a964de | 7641 | (define_insn "*abssf2_if" |
e20440c1 JH |
7642 | [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f") |
7643 | (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0"))) | |
1ce485ec | 7644 | (clobber (reg:CC 17))] |
ca29d1dc | 7645 | "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE" |
1ce485ec JH |
7646 | "#") |
7647 | ||
7648 | (define_split | |
7649 | [(set (match_operand:SF 0 "register_operand" "") | |
7650 | (abs:SF (match_operand:SF 1 "register_operand" ""))) | |
7651 | (clobber (reg:CC 17))] | |
7652 | "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))" | |
7653 | [(set (match_dup 0) | |
7654 | (abs:SF (match_dup 1)))] | |
7655 | "") | |
7656 | ||
7657 | (define_split | |
7658 | [(set (match_operand:SF 0 "register_operand" "") | |
7659 | (abs:SF (match_operand:SF 1 "register_operand" ""))) | |
7660 | (clobber (reg:CC 17))] | |
7661 | "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))" | |
7662 | [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1))) | |
7663 | (clobber (reg:CC 17))])] | |
7664 | "operands[1] = GEN_INT (~0x80000000); | |
7665 | operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));") | |
7666 | ||
7667 | (define_split | |
7668 | [(set (match_operand 0 "memory_operand" "") | |
7669 | (abs (match_operand 1 "memory_operand" ""))) | |
7670 | (clobber (reg:CC 17))] | |
7671 | "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))" | |
7672 | [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1))) | |
7673 | (clobber (reg:CC 17))])] | |
7674 | " | |
7675 | { | |
7676 | int size = GET_MODE_SIZE (GET_MODE (operands[1])); | |
7677 | ||
7678 | /* XFmode's size is 12, but only 10 bytes are used. */ | |
7679 | if (size == 12) | |
7680 | size = 10; | |
7681 | operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0)); | |
7682 | operands[0] = adj_offsettable_operand (operands[0], size - 1); | |
7683 | operands[1] = GEN_INT (~0x80); | |
7684 | }") | |
7685 | ||
06a964de JH |
7686 | (define_expand "absdf2" |
7687 | [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
2756c3d8 | 7688 | (neg:DF (match_operand:DF 1 "nonimmediate_operand" ""))) |
06a964de | 7689 | (clobber (reg:CC 17))])] |
1ce485ec | 7690 | "TARGET_80387" |
ca29d1dc JH |
7691 | "if (TARGET_SSE2) |
7692 | { | |
7693 | /* In case operand is in memory, we will not use SSE. */ | |
7694 | if (memory_operand (operands[0], VOIDmode) | |
7695 | && rtx_equal_p (operands[0], operands[1])) | |
7696 | emit_insn (gen_absdf2_memory (operands[0], operands[1])); | |
7697 | else | |
7698 | { | |
7699 | /* Using SSE is tricky, since we need bitwise negation of -0 | |
7700 | in register. */ | |
7701 | rtx reg = gen_reg_rtx (DFmode); | |
7702 | #if HOST_BITS_PER_WIDE_INT >= 64 | |
7703 | rtx imm = gen_reg_rtx (GEN_INT (0x80000000)); | |
7704 | #else | |
7705 | rtx imm = immed_double_const (0, 0x80000000, DImode); | |
7706 | #endif | |
7707 | emit_move_insn (reg, gen_lowpart (DFmode, imm)); | |
7708 | emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg)); | |
7709 | } | |
7710 | DONE; | |
7711 | } | |
7712 | ix86_expand_unary_operator (ABS, DFmode, operands); DONE;") | |
7713 | ||
7714 | (define_insn "absdf2_memory" | |
7715 | [(set (match_operand:DF 0 "memory_operand" "=m") | |
7716 | (abs:DF (match_operand:DF 1 "memory_operand" "0"))) | |
7717 | (clobber (reg:CC 17))] | |
7718 | "ix86_unary_operator_ok (ABS, DFmode, operands)" | |
7719 | "#") | |
7720 | ||
7721 | (define_insn "absdf2_ifs" | |
7722 | [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,f#Yr,r#Yf") | |
7723 | (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0"))) | |
7724 | (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*X#Y,*X#Y")) | |
7725 | (clobber (reg:CC 17))] | |
7726 | "TARGET_SSE2" | |
7727 | "#") | |
7728 | ||
7729 | (define_split | |
7730 | [(set (match_operand:DF 0 "memory_operand" "") | |
7731 | (abs:DF (match_operand:DF 1 "memory_operand" ""))) | |
7732 | (use (match_operand:DF 2 "" "")) | |
7733 | (clobber (reg:CC 17))] | |
7734 | "" | |
7735 | [(parallel [(set (match_dup 0) | |
7736 | (abs:DF (match_dup 1))) | |
7737 | (clobber (reg:CC 17))])]) | |
7738 | ||
7739 | (define_split | |
7740 | [(set (match_operand:DF 0 "register_operand" "") | |
7741 | (abs:DF (match_operand:DF 1 "register_operand" ""))) | |
7742 | (use (match_operand:DF 2 "" "")) | |
7743 | (clobber (reg:CC 17))] | |
7744 | "reload_completed && !SSE_REG_P (operands[0])" | |
7745 | [(parallel [(set (match_dup 0) | |
7746 | (abs:DF (match_dup 1))) | |
7747 | (clobber (reg:CC 17))])]) | |
7748 | ||
7749 | (define_split | |
7750 | [(set (match_operand:DF 0 "register_operand" "") | |
7751 | (abs:DF (match_operand:DF 1 "register_operand" ""))) | |
7752 | (use (match_operand:DF 2 "register_operand" "")) | |
7753 | (clobber (reg:CC 17))] | |
7754 | "reload_completed && SSE_REG_P (operands[0])" | |
7755 | [(set (subreg:TI (match_dup 0) 0) | |
7756 | (and:TI (not:TI (subreg:TI (match_dup 2) 0)) | |
7757 | (subreg:TI (match_dup 1) 0)))]) | |
7758 | ||
06a964de | 7759 | |
e20440c1 JH |
7760 | ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems |
7761 | ;; because of secondary memory needed to reload from class FLOAT_INT_REGS | |
7762 | ;; to itself. | |
06a964de | 7763 | (define_insn "*absdf2_if" |
e20440c1 JH |
7764 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f") |
7765 | (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0"))) | |
06a964de JH |
7766 | (clobber (reg:CC 17))] |
7767 | "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)" | |
1ce485ec JH |
7768 | "#") |
7769 | ||
7770 | (define_split | |
7771 | [(set (match_operand:DF 0 "register_operand" "") | |
7772 | (abs:DF (match_operand:DF 1 "register_operand" ""))) | |
7773 | (clobber (reg:CC 17))] | |
7774 | "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed" | |
7775 | [(set (match_dup 0) | |
7776 | (abs:DF (match_dup 1)))] | |
7777 | "") | |
7778 | ||
7779 | (define_split | |
7780 | [(set (match_operand:DF 0 "register_operand" "") | |
7781 | (abs:DF (match_operand:DF 1 "register_operand" ""))) | |
7782 | (clobber (reg:CC 17))] | |
7783 | "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))" | |
7784 | [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4))) | |
7785 | (clobber (reg:CC 17))])] | |
7786 | "operands[4] = GEN_INT (~0x80000000); | |
7787 | split_di (operands+0, 1, operands+2, operands+3);") | |
7788 | ||
06a964de JH |
7789 | (define_expand "absxf2" |
7790 | [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") | |
2756c3d8 | 7791 | (neg:XF (match_operand:XF 1 "nonimmediate_operand" ""))) |
06a964de | 7792 | (clobber (reg:CC 17))])] |
1e07edd3 | 7793 | "TARGET_80387 && !TARGET_64BIT" |
06a964de JH |
7794 | "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;") |
7795 | ||
2b589241 JH |
7796 | (define_expand "abstf2" |
7797 | [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
7798 | (neg:TF (match_operand:TF 1 "nonimmediate_operand" ""))) | |
7799 | (clobber (reg:CC 17))])] | |
7800 | "TARGET_80387" | |
7801 | "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;") | |
7802 | ||
e20440c1 JH |
7803 | ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems |
7804 | ;; because of secondary memory needed to reload from class FLOAT_INT_REGS | |
7805 | ;; to itself. | |
06a964de | 7806 | (define_insn "*absxf2_if" |
e20440c1 JH |
7807 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f") |
7808 | (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0"))) | |
1ce485ec | 7809 | (clobber (reg:CC 17))] |
1e07edd3 JH |
7810 | "TARGET_80387 && !TARGET_64BIT |
7811 | && ix86_unary_operator_ok (ABS, XFmode, operands)" | |
1ce485ec JH |
7812 | "#") |
7813 | ||
7814 | (define_split | |
7815 | [(set (match_operand:XF 0 "register_operand" "") | |
7816 | (abs:XF (match_operand:XF 1 "register_operand" ""))) | |
7817 | (clobber (reg:CC 17))] | |
7818 | "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed" | |
7819 | [(set (match_dup 0) | |
7820 | (abs:XF (match_dup 1)))] | |
7821 | "") | |
7822 | ||
7823 | (define_split | |
7824 | [(set (match_operand:XF 0 "register_operand" "") | |
7825 | (abs:XF (match_operand:XF 1 "register_operand" ""))) | |
7826 | (clobber (reg:CC 17))] | |
7827 | "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))" | |
7828 | [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1))) | |
7829 | (clobber (reg:CC 17))])] | |
7830 | "operands[1] = GEN_INT (~0x8000); | |
7831 | operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);") | |
7832 | ||
2b589241 JH |
7833 | (define_insn "*abstf2_if" |
7834 | [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f") | |
7835 | (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0"))) | |
7836 | (clobber (reg:CC 17))] | |
7837 | "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)" | |
7838 | "#") | |
7839 | ||
7840 | (define_split | |
7841 | [(set (match_operand:TF 0 "register_operand" "") | |
7842 | (abs:TF (match_operand:TF 1 "register_operand" ""))) | |
7843 | (clobber (reg:CC 17))] | |
7844 | "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed" | |
7845 | [(set (match_dup 0) | |
7846 | (abs:TF (match_dup 1)))] | |
7847 | "") | |
7848 | ||
7849 | (define_split | |
7850 | [(set (match_operand:TF 0 "register_operand" "") | |
7851 | (abs:TF (match_operand:TF 1 "register_operand" ""))) | |
7852 | (clobber (reg:CC 17))] | |
7853 | "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))" | |
7854 | [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1))) | |
7855 | (clobber (reg:CC 17))])] | |
7856 | "operands[1] = GEN_INT (~0x8000); | |
7857 | operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);") | |
7858 | ||
1ce485ec | 7859 | (define_insn "*abssf2_1" |
886c62d1 | 7860 | [(set (match_operand:SF 0 "register_operand" "=f") |
2ae0f82c | 7861 | (abs:SF (match_operand:SF 1 "register_operand" "0")))] |
1ce485ec | 7862 | "TARGET_80387 && reload_completed" |
2ae0f82c | 7863 | "fabs" |
6ef67412 JH |
7864 | [(set_attr "type" "fsgn") |
7865 | (set_attr "mode" "SF")]) | |
886c62d1 | 7866 | |
1ce485ec | 7867 | (define_insn "*absdf2_1" |
886c62d1 | 7868 | [(set (match_operand:DF 0 "register_operand" "=f") |
2ae0f82c | 7869 | (abs:DF (match_operand:DF 1 "register_operand" "0")))] |
1ce485ec | 7870 | "TARGET_80387 && reload_completed" |
2ae0f82c | 7871 | "fabs" |
6ef67412 JH |
7872 | [(set_attr "type" "fsgn") |
7873 | (set_attr "mode" "DF")]) | |
886c62d1 | 7874 | |
6343a50e | 7875 | (define_insn "*absextendsfdf2" |
886c62d1 | 7876 | [(set (match_operand:DF 0 "register_operand" "=f") |
e075ae69 RH |
7877 | (abs:DF (float_extend:DF |
7878 | (match_operand:SF 1 "register_operand" "0"))))] | |
886c62d1 | 7879 | "TARGET_80387" |
2ae0f82c | 7880 | "fabs" |
6ef67412 JH |
7881 | [(set_attr "type" "fsgn") |
7882 | (set_attr "mode" "DF")]) | |
886c62d1 | 7883 | |
1ce485ec | 7884 | (define_insn "*absxf2_1" |
4fb21e90 | 7885 | [(set (match_operand:XF 0 "register_operand" "=f") |
2ae0f82c | 7886 | (abs:XF (match_operand:XF 1 "register_operand" "0")))] |
1e07edd3 | 7887 | "TARGET_80387 && !TARGET_64BIT && reload_completed" |
2ae0f82c | 7888 | "fabs" |
6ef67412 JH |
7889 | [(set_attr "type" "fsgn") |
7890 | (set_attr "mode" "DF")]) | |
4fb21e90 | 7891 | |
6343a50e | 7892 | (define_insn "*absextenddfxf2" |
4fb21e90 | 7893 | [(set (match_operand:XF 0 "register_operand" "=f") |
e075ae69 RH |
7894 | (abs:XF (float_extend:XF |
7895 | (match_operand:DF 1 "register_operand" "0"))))] | |
1e07edd3 | 7896 | "TARGET_80387 && !TARGET_64BIT" |
2ae0f82c | 7897 | "fabs" |
6ef67412 JH |
7898 | [(set_attr "type" "fsgn") |
7899 | (set_attr "mode" "XF")]) | |
a199fdd6 | 7900 | |
6343a50e | 7901 | (define_insn "*absextendsfxf2" |
58733f96 | 7902 | [(set (match_operand:XF 0 "register_operand" "=f") |
e075ae69 RH |
7903 | (abs:XF (float_extend:XF |
7904 | (match_operand:SF 1 "register_operand" "0"))))] | |
1e07edd3 | 7905 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 | 7906 | "fabs" |
6ef67412 JH |
7907 | [(set_attr "type" "fsgn") |
7908 | (set_attr "mode" "XF")]) | |
2b589241 JH |
7909 | |
7910 | (define_insn "*abstf2_1" | |
7911 | [(set (match_operand:TF 0 "register_operand" "=f") | |
7912 | (abs:TF (match_operand:TF 1 "register_operand" "0")))] | |
7913 | "TARGET_80387 && reload_completed" | |
7914 | "fabs" | |
7915 | [(set_attr "type" "fsgn") | |
7916 | (set_attr "mode" "DF")]) | |
7917 | ||
7918 | (define_insn "*absextenddftf2" | |
7919 | [(set (match_operand:TF 0 "register_operand" "=f") | |
7920 | (abs:TF (float_extend:TF | |
7921 | (match_operand:DF 1 "register_operand" "0"))))] | |
7922 | "TARGET_80387" | |
7923 | "fabs" | |
7924 | [(set_attr "type" "fsgn") | |
7925 | (set_attr "mode" "XF")]) | |
7926 | ||
7927 | (define_insn "*absextendsftf2" | |
7928 | [(set (match_operand:TF 0 "register_operand" "=f") | |
7929 | (abs:TF (float_extend:TF | |
7930 | (match_operand:SF 1 "register_operand" "0"))))] | |
7931 | "TARGET_80387" | |
7932 | "fabs" | |
7933 | [(set_attr "type" "fsgn") | |
7934 | (set_attr "mode" "XF")]) | |
886c62d1 | 7935 | \f |
e075ae69 | 7936 | ;; One complement instructions |
886c62d1 | 7937 | |
06a964de | 7938 | (define_expand "one_cmplsi2" |
a1cbdd7f JH |
7939 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
7940 | (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] | |
06a964de JH |
7941 | "" |
7942 | "ix86_expand_unary_operator (NOT, SImode, operands); DONE;") | |
7943 | ||
7944 | (define_insn "*one_cmplsi2_1" | |
2ae0f82c SC |
7945 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
7946 | (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] | |
a1cbdd7f | 7947 | "ix86_unary_operator_ok (NOT, SImode, operands)" |
e075ae69 | 7948 | "not{l}\\t%0" |
6ef67412 JH |
7949 | [(set_attr "type" "negnot") |
7950 | (set_attr "mode" "SI")]) | |
bb524860 | 7951 | |
06a964de | 7952 | (define_insn "*one_cmplsi2_2" |
16189740 RH |
7953 | [(set (reg 17) |
7954 | (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")) | |
7955 | (const_int 0))) | |
e075ae69 RH |
7956 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
7957 | (not:SI (match_dup 1)))] | |
16189740 RH |
7958 | "ix86_match_ccmode (insn, CCNOmode) |
7959 | && ix86_unary_operator_ok (NOT, SImode, operands)" | |
e075ae69 | 7960 | "#" |
6ef67412 JH |
7961 | [(set_attr "type" "alu1") |
7962 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
7963 | |
7964 | (define_split | |
16189740 RH |
7965 | [(set (reg 17) |
7966 | (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "")) | |
7967 | (const_int 0))) | |
e075ae69 RH |
7968 | (set (match_operand:SI 0 "nonimmediate_operand" "") |
7969 | (not:SI (match_dup 1)))] | |
16189740 | 7970 | "ix86_match_ccmode (insn, CCNOmode)" |
e075ae69 RH |
7971 | [(parallel [(set (reg:CCNO 17) |
7972 | (compare:CCNO (xor:SI (match_dup 1) (const_int -1)) | |
7973 | (const_int 0))) | |
7974 | (set (match_dup 0) | |
7975 | (xor:SI (match_dup 1) (const_int -1)))])] | |
7976 | "") | |
886c62d1 | 7977 | |
06a964de | 7978 | (define_expand "one_cmplhi2" |
a1cbdd7f JH |
7979 | [(set (match_operand:HI 0 "nonimmediate_operand" "") |
7980 | (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] | |
d9f32422 | 7981 | "TARGET_HIMODE_MATH" |
06a964de JH |
7982 | "ix86_expand_unary_operator (NOT, HImode, operands); DONE;") |
7983 | ||
7984 | (define_insn "*one_cmplhi2_1" | |
2ae0f82c SC |
7985 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
7986 | (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] | |
a1cbdd7f | 7987 | "ix86_unary_operator_ok (NOT, HImode, operands)" |
e075ae69 | 7988 | "not{w}\\t%0" |
6ef67412 JH |
7989 | [(set_attr "type" "negnot") |
7990 | (set_attr "mode" "HI")]) | |
bb524860 | 7991 | |
06a964de | 7992 | (define_insn "*one_cmplhi2_2" |
16189740 RH |
7993 | [(set (reg 17) |
7994 | (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")) | |
7995 | (const_int 0))) | |
e075ae69 RH |
7996 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
7997 | (not:HI (match_dup 1)))] | |
16189740 RH |
7998 | "ix86_match_ccmode (insn, CCNOmode) |
7999 | && ix86_unary_operator_ok (NEG, HImode, operands)" | |
e075ae69 | 8000 | "#" |
6ef67412 JH |
8001 | [(set_attr "type" "alu1") |
8002 | (set_attr "mode" "HI")]) | |
e075ae69 RH |
8003 | |
8004 | (define_split | |
16189740 RH |
8005 | [(set (reg 17) |
8006 | (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "")) | |
8007 | (const_int 0))) | |
e075ae69 RH |
8008 | (set (match_operand:HI 0 "nonimmediate_operand" "") |
8009 | (not:HI (match_dup 1)))] | |
16189740 | 8010 | "ix86_match_ccmode (insn, CCNOmode)" |
e075ae69 RH |
8011 | [(parallel [(set (reg:CCNO 17) |
8012 | (compare:CCNO (xor:HI (match_dup 1) (const_int -1)) | |
8013 | (const_int 0))) | |
8014 | (set (match_dup 0) | |
8015 | (xor:HI (match_dup 1) (const_int -1)))])] | |
8016 | "") | |
886c62d1 | 8017 | |
e075ae69 | 8018 | ;; %%% Potential partial reg stall on alternative 1. What to do? |
06a964de | 8019 | (define_expand "one_cmplqi2" |
a1cbdd7f JH |
8020 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
8021 | (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
d9f32422 | 8022 | "TARGET_QIMODE_MATH" |
06a964de JH |
8023 | "ix86_expand_unary_operator (NOT, QImode, operands); DONE;") |
8024 | ||
8025 | (define_insn "*one_cmplqi2_1" | |
7c6b971d | 8026 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") |
e075ae69 | 8027 | (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] |
a1cbdd7f | 8028 | "ix86_unary_operator_ok (NOT, QImode, operands)" |
e075ae69 RH |
8029 | "@ |
8030 | not{b}\\t%0 | |
8031 | not{l}\\t%k0" | |
6ef67412 JH |
8032 | [(set_attr "type" "negnot") |
8033 | (set_attr "mode" "QI,SI")]) | |
bb524860 | 8034 | |
06a964de | 8035 | (define_insn "*one_cmplqi2_2" |
16189740 RH |
8036 | [(set (reg 17) |
8037 | (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")) | |
8038 | (const_int 0))) | |
e075ae69 RH |
8039 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
8040 | (not:QI (match_dup 1)))] | |
16189740 RH |
8041 | "ix86_match_ccmode (insn, CCNOmode) |
8042 | && ix86_unary_operator_ok (NOT, QImode, operands)" | |
e075ae69 | 8043 | "#" |
6ef67412 JH |
8044 | [(set_attr "type" "alu1") |
8045 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
8046 | |
8047 | (define_split | |
16189740 RH |
8048 | [(set (reg 17) |
8049 | (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "")) | |
8050 | (const_int 0))) | |
e075ae69 RH |
8051 | (set (match_operand:QI 0 "nonimmediate_operand" "") |
8052 | (not:QI (match_dup 1)))] | |
16189740 | 8053 | "ix86_match_ccmode (insn, CCNOmode)" |
e075ae69 RH |
8054 | [(parallel [(set (reg:CCNO 17) |
8055 | (compare:CCNO (xor:QI (match_dup 1) (const_int -1)) | |
8056 | (const_int 0))) | |
8057 | (set (match_dup 0) | |
8058 | (xor:QI (match_dup 1) (const_int -1)))])] | |
8059 | "") | |
886c62d1 | 8060 | \f |
e075ae69 | 8061 | ;; Arithmetic shift instructions |
886c62d1 JVA |
8062 | |
8063 | ;; DImode shifts are implemented using the i386 "shift double" opcode, | |
8064 | ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count | |
8065 | ;; is variable, then the count is in %cl and the "imm" operand is dropped | |
8066 | ;; from the assembler input. | |
e075ae69 | 8067 | ;; |
886c62d1 JVA |
8068 | ;; This instruction shifts the target reg/mem as usual, but instead of |
8069 | ;; shifting in zeros, bits are shifted in from reg operand. If the insn | |
8070 | ;; is a left shift double, bits are taken from the high order bits of | |
8071 | ;; reg, else if the insn is a shift right double, bits are taken from the | |
8072 | ;; low order bits of reg. So if %eax is "1234" and %edx is "5678", | |
8073 | ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". | |
e075ae69 | 8074 | ;; |
886c62d1 JVA |
8075 | ;; Since sh[lr]d does not change the `reg' operand, that is done |
8076 | ;; separately, making all shifts emit pairs of shift double and normal | |
8077 | ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to | |
8078 | ;; support a 63 bit shift, each shift where the count is in a reg expands | |
f58acb67 | 8079 | ;; to a pair of shifts, a branch, a shift by 32 and a label. |
e075ae69 | 8080 | ;; |
886c62d1 JVA |
8081 | ;; If the shift count is a constant, we need never emit more than one |
8082 | ;; shift pair, instead using moves and sign extension for counts greater | |
8083 | ;; than 31. | |
8084 | ||
56c0e8fa | 8085 | (define_expand "ashldi3" |
3d117b30 JH |
8086 | [(parallel [(set (match_operand:DI 0 "register_operand" "") |
8087 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
8088 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
e075ae69 | 8089 | (clobber (reg:CC 17))])] |
56c0e8fa JVA |
8090 | "" |
8091 | " | |
8092 | { | |
3d117b30 | 8093 | if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) |
56c0e8fa | 8094 | { |
e075ae69 RH |
8095 | emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2])); |
8096 | DONE; | |
56c0e8fa | 8097 | } |
3d117b30 | 8098 | ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE; |
56c0e8fa JVA |
8099 | }") |
8100 | ||
e075ae69 RH |
8101 | (define_insn "ashldi3_1" |
8102 | [(set (match_operand:DI 0 "register_operand" "=r") | |
56c0e8fa | 8103 | (ashift:DI (match_operand:DI 1 "register_operand" "0") |
e075ae69 RH |
8104 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) |
8105 | (clobber (match_scratch:SI 3 "=&r")) | |
8106 | (clobber (reg:CC 17))] | |
8107 | "TARGET_CMOVE" | |
8108 | "#" | |
8109 | [(set_attr "type" "multi")]) | |
886c62d1 | 8110 | |
e075ae69 RH |
8111 | (define_insn "*ashldi3_2" |
8112 | [(set (match_operand:DI 0 "register_operand" "=r") | |
56c0e8fa | 8113 | (ashift:DI (match_operand:DI 1 "register_operand" "0") |
e075ae69 RH |
8114 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) |
8115 | (clobber (reg:CC 17))] | |
56c0e8fa | 8116 | "" |
e075ae69 RH |
8117 | "#" |
8118 | [(set_attr "type" "multi")]) | |
886c62d1 | 8119 | |
e075ae69 RH |
8120 | (define_split |
8121 | [(set (match_operand:DI 0 "register_operand" "") | |
8122 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
8123 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8124 | (clobber (match_scratch:SI 3 "")) | |
8125 | (clobber (reg:CC 17))] | |
d7a29404 | 8126 | "TARGET_CMOVE && reload_completed" |
e075ae69 RH |
8127 | [(const_int 0)] |
8128 | "ix86_split_ashldi (operands, operands[3]); DONE;") | |
47f59fd4 | 8129 | |
e075ae69 RH |
8130 | (define_split |
8131 | [(set (match_operand:DI 0 "register_operand" "") | |
8132 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
8133 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8134 | (clobber (reg:CC 17))] | |
d7a29404 | 8135 | "reload_completed" |
e075ae69 RH |
8136 | [(const_int 0)] |
8137 | "ix86_split_ashldi (operands, NULL_RTX); DONE;") | |
6ec6d558 | 8138 | |
e075ae69 RH |
8139 | (define_insn "x86_shld_1" |
8140 | [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") | |
8141 | (ior:SI (ashift:SI (match_dup 0) | |
8142 | (match_operand:QI 2 "nonmemory_operand" "I,c")) | |
8143 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") | |
8144 | (minus:QI (const_int 32) (match_dup 2))))) | |
8145 | (clobber (reg:CC 17))] | |
6ec6d558 | 8146 | "" |
e075ae69 RH |
8147 | "@ |
8148 | shld{l}\\t{%2, %1, %0|%0, %1, %2} | |
8149 | shld{l}\\t{%s2%1, %0|%0, %1, %2}" | |
8150 | [(set_attr "type" "ishift") | |
6ef67412 JH |
8151 | (set_attr "prefix_0f" "1") |
8152 | (set_attr "mode" "SI") | |
e075ae69 | 8153 | (set_attr "pent_pair" "np") |
309ada50 | 8154 | (set_attr "athlon_decode" "vector") |
e075ae69 RH |
8155 | (set_attr "ppro_uops" "few")]) |
8156 | ||
8157 | (define_expand "x86_shift_adj_1" | |
16189740 RH |
8158 | [(set (reg:CCZ 17) |
8159 | (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") | |
8160 | (const_int 32)) | |
8161 | (const_int 0))) | |
e075ae69 | 8162 | (set (match_operand:SI 0 "register_operand" "") |
16189740 | 8163 | (if_then_else:SI (ne (reg:CCZ 17) (const_int 0)) |
e075ae69 RH |
8164 | (match_operand:SI 1 "register_operand" "") |
8165 | (match_dup 0))) | |
8166 | (set (match_dup 1) | |
16189740 | 8167 | (if_then_else:SI (ne (reg:CCZ 17) (const_int 0)) |
e075ae69 RH |
8168 | (match_operand:SI 3 "register_operand" "r") |
8169 | (match_dup 1)))] | |
8170 | "TARGET_CMOVE" | |
6ec6d558 JH |
8171 | "") |
8172 | ||
e075ae69 RH |
8173 | (define_expand "x86_shift_adj_2" |
8174 | [(use (match_operand:SI 0 "register_operand" "")) | |
8175 | (use (match_operand:SI 1 "register_operand" "")) | |
8176 | (use (match_operand:QI 2 "register_operand" ""))] | |
886c62d1 | 8177 | "" |
e075ae69 RH |
8178 | " |
8179 | { | |
8180 | rtx label = gen_label_rtx (); | |
8181 | rtx tmp; | |
886c62d1 | 8182 | |
16189740 | 8183 | emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); |
886c62d1 | 8184 | |
16189740 | 8185 | tmp = gen_rtx_REG (CCZmode, FLAGS_REG); |
e075ae69 RH |
8186 | tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); |
8187 | tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, | |
8188 | gen_rtx_LABEL_REF (VOIDmode, label), | |
8189 | pc_rtx); | |
8190 | tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); | |
8191 | JUMP_LABEL (tmp) = label; | |
886c62d1 | 8192 | |
e075ae69 RH |
8193 | emit_move_insn (operands[0], operands[1]); |
8194 | emit_move_insn (operands[1], const0_rtx); | |
886c62d1 | 8195 | |
e075ae69 RH |
8196 | emit_label (label); |
8197 | LABEL_NUSES (label) = 1; | |
56c0e8fa JVA |
8198 | |
8199 | DONE; | |
8200 | }") | |
8201 | ||
d525dfdf JH |
8202 | (define_expand "ashlsi3" |
8203 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
8204 | (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
8205 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8206 | (clobber (reg:CC 17))] | |
8207 | "" | |
8208 | "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;") | |
8209 | ||
8210 | (define_insn "*ashlsi3_1" | |
e075ae69 RH |
8211 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
8212 | (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r") | |
8213 | (match_operand:QI 2 "nonmemory_operand" "cI,M"))) | |
8214 | (clobber (reg:CC 17))] | |
d525dfdf | 8215 | "ix86_binary_operator_ok (ASHIFT, SImode, operands)" |
2ae0f82c SC |
8216 | "* |
8217 | { | |
e075ae69 RH |
8218 | switch (get_attr_type (insn)) |
8219 | { | |
8220 | case TYPE_ALU: | |
8221 | if (operands[2] != const1_rtx) | |
8222 | abort (); | |
8223 | if (!rtx_equal_p (operands[0], operands[1])) | |
8224 | abort (); | |
8225 | return \"add{l}\\t{%0, %0|%0, %0}\"; | |
2ae0f82c | 8226 | |
e075ae69 | 8227 | case TYPE_LEA: |
3d117b30 | 8228 | return \"#\"; |
2ae0f82c | 8229 | |
e075ae69 RH |
8230 | default: |
8231 | if (REG_P (operands[2])) | |
8232 | return \"sal{l}\\t{%b2, %0|%0, %b2}\"; | |
8bad7136 JL |
8233 | else if (GET_CODE (operands[2]) == CONST_INT |
8234 | && INTVAL (operands[2]) == 1 | |
8235 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) | |
8236 | return \"sal{l}\\t%0\"; | |
e075ae69 RH |
8237 | else |
8238 | return \"sal{l}\\t{%2, %0|%0, %2}\"; | |
8239 | } | |
8240 | }" | |
8241 | [(set (attr "type") | |
8242 | (cond [(eq_attr "alternative" "1") | |
8243 | (const_string "lea") | |
8244 | (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
8245 | (const_int 0)) | |
8246 | (match_operand 0 "register_operand" "")) | |
8247 | (match_operand 2 "const1_operand" "")) | |
8248 | (const_string "alu") | |
8249 | ] | |
6ef67412 JH |
8250 | (const_string "ishift"))) |
8251 | (set_attr "mode" "SI")]) | |
e075ae69 | 8252 | |
1c27d4b2 JH |
8253 | ;; Convert lea to the lea pattern to avoid flags dependency. |
8254 | (define_split | |
58787064 JH |
8255 | [(set (match_operand 0 "register_operand" "") |
8256 | (ashift (match_operand 1 "register_operand" "") | |
ca4ae08d | 8257 | (match_operand:QI 2 "const_int_operand" ""))) |
1c27d4b2 | 8258 | (clobber (reg:CC 17))] |
abe24fb3 JH |
8259 | "reload_completed |
8260 | && true_regnum (operands[0]) != true_regnum (operands[1])" | |
58787064 JH |
8261 | [(const_int 0)] |
8262 | " | |
8263 | { | |
8264 | rtx pat; | |
8265 | operands[0] = gen_lowpart (SImode, operands[0]); | |
8266 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
8267 | operands[2] = GEN_INT (1 << INTVAL (operands[2])); | |
8268 | pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); | |
8269 | if (Pmode != SImode) | |
8270 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
8271 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
8272 | DONE; | |
8273 | }") | |
1c27d4b2 | 8274 | |
28cefcd2 BS |
8275 | ;; This pattern can't accept a variable shift count, since shifts by |
8276 | ;; zero don't affect the flags. We assume that shifts by constant | |
8277 | ;; zero are optimized away. | |
2c873473 | 8278 | (define_insn "*ashlsi3_cmp" |
16189740 RH |
8279 | [(set (reg 17) |
8280 | (compare | |
e075ae69 | 8281 | (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") |
28cefcd2 | 8282 | (match_operand:QI 2 "immediate_operand" "I")) |
e075ae69 RH |
8283 | (const_int 0))) |
8284 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
8285 | (ashift:SI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 8286 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 8287 | && ix86_binary_operator_ok (ASHIFT, SImode, operands)" |
886c62d1 JVA |
8288 | "* |
8289 | { | |
e075ae69 | 8290 | switch (get_attr_type (insn)) |
886c62d1 | 8291 | { |
e075ae69 RH |
8292 | case TYPE_ALU: |
8293 | if (operands[2] != const1_rtx) | |
8294 | abort (); | |
8295 | return \"add{l}\\t{%0, %0|%0, %0}\"; | |
886c62d1 | 8296 | |
e075ae69 RH |
8297 | default: |
8298 | if (REG_P (operands[2])) | |
8299 | return \"sal{l}\\t{%b2, %0|%0, %b2}\"; | |
8bad7136 JL |
8300 | else if (GET_CODE (operands[2]) == CONST_INT |
8301 | && INTVAL (operands[2]) == 1 | |
8302 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) | |
8303 | return \"sal{l}\\t%0\"; | |
e075ae69 RH |
8304 | else |
8305 | return \"sal{l}\\t{%2, %0|%0, %2}\"; | |
56c0e8fa | 8306 | } |
e075ae69 RH |
8307 | }" |
8308 | [(set (attr "type") | |
8309 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
8310 | (const_int 0)) | |
8311 | (match_operand 0 "register_operand" "")) | |
8312 | (match_operand 2 "const1_operand" "")) | |
8313 | (const_string "alu") | |
8314 | ] | |
6ef67412 JH |
8315 | (const_string "ishift"))) |
8316 | (set_attr "mode" "SI")]) | |
e075ae69 | 8317 | |
d525dfdf JH |
8318 | (define_expand "ashlhi3" |
8319 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
8320 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
8321 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8322 | (clobber (reg:CC 17))] | |
d9f32422 | 8323 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
8324 | "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;") |
8325 | ||
58787064 JH |
8326 | (define_insn "*ashlhi3_1_lea" |
8327 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
8328 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r") | |
8329 | (match_operand:QI 2 "nonmemory_operand" "cI,M"))) | |
8330 | (clobber (reg:CC 17))] | |
8331 | "!TARGET_PARTIAL_REG_STALL | |
8332 | && ix86_binary_operator_ok (ASHIFT, HImode, operands)" | |
8333 | "* | |
8334 | { | |
8335 | switch (get_attr_type (insn)) | |
8336 | { | |
8337 | case TYPE_LEA: | |
8338 | return \"#\"; | |
8339 | case TYPE_ALU: | |
8340 | if (operands[2] != const1_rtx) | |
8341 | abort (); | |
8342 | return \"add{w}\\t{%0, %0|%0, %0}\"; | |
8343 | ||
8344 | default: | |
8345 | if (REG_P (operands[2])) | |
8346 | return \"sal{w}\\t{%b2, %0|%0, %b2}\"; | |
8347 | else if (GET_CODE (operands[2]) == CONST_INT | |
8348 | && INTVAL (operands[2]) == 1 | |
8349 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) | |
8350 | return \"sal{w}\\t%0\"; | |
8351 | else | |
8352 | return \"sal{w}\\t{%2, %0|%0, %2}\"; | |
8353 | } | |
8354 | }" | |
8355 | [(set (attr "type") | |
8356 | (cond [(eq_attr "alternative" "1") | |
8357 | (const_string "lea") | |
8358 | (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
8359 | (const_int 0)) | |
8360 | (match_operand 0 "register_operand" "")) | |
8361 | (match_operand 2 "const1_operand" "")) | |
8362 | (const_string "alu") | |
8363 | ] | |
8364 | (const_string "ishift"))) | |
8365 | (set_attr "mode" "HI,SI")]) | |
8366 | ||
d525dfdf | 8367 | (define_insn "*ashlhi3_1" |
e075ae69 RH |
8368 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
8369 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
8370 | (match_operand:QI 2 "nonmemory_operand" "cI"))) | |
8371 | (clobber (reg:CC 17))] | |
58787064 JH |
8372 | "TARGET_PARTIAL_REG_STALL |
8373 | && ix86_binary_operator_ok (ASHIFT, HImode, operands)" | |
56c0e8fa JVA |
8374 | "* |
8375 | { | |
e075ae69 RH |
8376 | switch (get_attr_type (insn)) |
8377 | { | |
8378 | case TYPE_ALU: | |
8379 | if (operands[2] != const1_rtx) | |
8380 | abort (); | |
8381 | return \"add{w}\\t{%0, %0|%0, %0}\"; | |
886c62d1 | 8382 | |
e075ae69 RH |
8383 | default: |
8384 | if (REG_P (operands[2])) | |
8385 | return \"sal{w}\\t{%b2, %0|%0, %b2}\"; | |
8bad7136 JL |
8386 | else if (GET_CODE (operands[2]) == CONST_INT |
8387 | && INTVAL (operands[2]) == 1 | |
8388 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) | |
8389 | return \"sal{w}\\t%0\"; | |
e075ae69 RH |
8390 | else |
8391 | return \"sal{w}\\t{%2, %0|%0, %2}\"; | |
8392 | } | |
8393 | }" | |
8394 | [(set (attr "type") | |
8395 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
8396 | (const_int 0)) | |
8397 | (match_operand 0 "register_operand" "")) | |
8398 | (match_operand 2 "const1_operand" "")) | |
8399 | (const_string "alu") | |
8400 | ] | |
6ef67412 JH |
8401 | (const_string "ishift"))) |
8402 | (set_attr "mode" "HI")]) | |
bb62e19a | 8403 | |
28cefcd2 BS |
8404 | ;; This pattern can't accept a variable shift count, since shifts by |
8405 | ;; zero don't affect the flags. We assume that shifts by constant | |
8406 | ;; zero are optimized away. | |
2c873473 | 8407 | (define_insn "*ashlhi3_cmp" |
16189740 RH |
8408 | [(set (reg 17) |
8409 | (compare | |
e075ae69 | 8410 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") |
28cefcd2 | 8411 | (match_operand:QI 2 "immediate_operand" "I")) |
e075ae69 RH |
8412 | (const_int 0))) |
8413 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
8414 | (ashift:HI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 8415 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 8416 | && ix86_binary_operator_ok (ASHIFT, HImode, operands)" |
886c62d1 JVA |
8417 | "* |
8418 | { | |
e075ae69 RH |
8419 | switch (get_attr_type (insn)) |
8420 | { | |
8421 | case TYPE_ALU: | |
8422 | if (operands[2] != const1_rtx) | |
8423 | abort (); | |
8424 | return \"add{w}\\t{%0, %0|%0, %0}\"; | |
886c62d1 | 8425 | |
e075ae69 RH |
8426 | default: |
8427 | if (REG_P (operands[2])) | |
8428 | return \"sal{w}\\t{%b2, %0|%0, %b2}\"; | |
8bad7136 JL |
8429 | else if (GET_CODE (operands[2]) == CONST_INT |
8430 | && INTVAL (operands[2]) == 1 | |
8431 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) | |
8432 | return \"sal{w}\\t%0\"; | |
e075ae69 RH |
8433 | else |
8434 | return \"sal{w}\\t{%2, %0|%0, %2}\"; | |
8435 | } | |
8436 | }" | |
8437 | [(set (attr "type") | |
8438 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
8439 | (const_int 0)) | |
8440 | (match_operand 0 "register_operand" "")) | |
8441 | (match_operand 2 "const1_operand" "")) | |
8442 | (const_string "alu") | |
8443 | ] | |
6ef67412 JH |
8444 | (const_string "ishift"))) |
8445 | (set_attr "mode" "HI")]) | |
e075ae69 | 8446 | |
d525dfdf JH |
8447 | (define_expand "ashlqi3" |
8448 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
8449 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
8450 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8451 | (clobber (reg:CC 17))] | |
d9f32422 | 8452 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
8453 | "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;") |
8454 | ||
e075ae69 | 8455 | ;; %%% Potential partial reg stall on alternative 2. What to do? |
58787064 JH |
8456 | |
8457 | (define_insn "*ashlqi3_1_lea" | |
8458 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r") | |
8459 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r") | |
91f9a498 | 8460 | (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) |
58787064 JH |
8461 | (clobber (reg:CC 17))] |
8462 | "!TARGET_PARTIAL_REG_STALL | |
8463 | && ix86_binary_operator_ok (ASHIFT, QImode, operands)" | |
8464 | "* | |
8465 | { | |
8466 | switch (get_attr_type (insn)) | |
8467 | { | |
8468 | case TYPE_LEA: | |
8469 | return \"#\"; | |
8470 | case TYPE_ALU: | |
8471 | if (operands[2] != const1_rtx) | |
8472 | abort (); | |
1a06f5fe | 8473 | if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) |
58787064 JH |
8474 | return \"add{l}\\t{%k0, %k0|%k0, %k0}\"; |
8475 | else | |
8476 | return \"add{b}\\t{%0, %0|%0, %0}\"; | |
8477 | ||
8478 | default: | |
8479 | if (REG_P (operands[2])) | |
8480 | { | |
8481 | if (get_attr_mode (insn) == MODE_SI) | |
8482 | return \"sal{l}\\t{%b2, %k0|%k0, %b2}\"; | |
8483 | else | |
8484 | return \"sal{b}\\t{%b2, %0|%0, %b2}\"; | |
8485 | } | |
8486 | else if (GET_CODE (operands[2]) == CONST_INT | |
8487 | && INTVAL (operands[2]) == 1 | |
8488 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) | |
8489 | { | |
8490 | if (get_attr_mode (insn) == MODE_SI) | |
8491 | return \"sal{l}\\t%0\"; | |
8492 | else | |
8493 | return \"sal{b}\\t%0\"; | |
8494 | } | |
8495 | else | |
8496 | { | |
8497 | if (get_attr_mode (insn) == MODE_SI) | |
8498 | return \"sal{l}\\t{%2, %k0|%k0, %2}\"; | |
8499 | else | |
8500 | return \"sal{b}\\t{%2, %0|%0, %2}\"; | |
8501 | } | |
8502 | } | |
8503 | }" | |
8504 | [(set (attr "type") | |
8505 | (cond [(eq_attr "alternative" "2") | |
8506 | (const_string "lea") | |
8507 | (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
8508 | (const_int 0)) | |
8509 | (match_operand 0 "register_operand" "")) | |
8510 | (match_operand 2 "const1_operand" "")) | |
8511 | (const_string "alu") | |
8512 | ] | |
8513 | (const_string "ishift"))) | |
8514 | (set_attr "mode" "QI,SI,SI")]) | |
8515 | ||
d525dfdf JH |
8516 | (define_insn "*ashlqi3_1" |
8517 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") | |
e075ae69 RH |
8518 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") |
8519 | (match_operand:QI 2 "nonmemory_operand" "cI,cI"))) | |
8520 | (clobber (reg:CC 17))] | |
58787064 JH |
8521 | "TARGET_PARTIAL_REG_STALL |
8522 | && ix86_binary_operator_ok (ASHIFT, QImode, operands)" | |
886c62d1 JVA |
8523 | "* |
8524 | { | |
e075ae69 RH |
8525 | switch (get_attr_type (insn)) |
8526 | { | |
8527 | case TYPE_ALU: | |
8528 | if (operands[2] != const1_rtx) | |
8529 | abort (); | |
1a06f5fe | 8530 | if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) |
e075ae69 RH |
8531 | return \"add{l}\\t{%k0, %k0|%k0, %k0}\"; |
8532 | else | |
8533 | return \"add{b}\\t{%0, %0|%0, %0}\"; | |
886c62d1 | 8534 | |
e075ae69 RH |
8535 | default: |
8536 | if (REG_P (operands[2])) | |
8537 | { | |
1a06f5fe | 8538 | if (get_attr_mode (insn) == MODE_SI) |
f6fbeda8 | 8539 | return \"sal{l}\\t{%b2, %k0|%k0, %b2}\"; |
e075ae69 RH |
8540 | else |
8541 | return \"sal{b}\\t{%b2, %0|%0, %b2}\"; | |
8542 | } | |
8bad7136 JL |
8543 | else if (GET_CODE (operands[2]) == CONST_INT |
8544 | && INTVAL (operands[2]) == 1 | |
8545 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) | |
8546 | { | |
1a06f5fe | 8547 | if (get_attr_mode (insn) == MODE_SI) |
8bad7136 JL |
8548 | return \"sal{l}\\t%0\"; |
8549 | else | |
8550 | return \"sal{b}\\t%0\"; | |
8551 | } | |
e075ae69 RH |
8552 | else |
8553 | { | |
1a06f5fe | 8554 | if (get_attr_mode (insn) == MODE_SI) |
f6fbeda8 | 8555 | return \"sal{l}\\t{%2, %k0|%k0, %2}\"; |
e075ae69 RH |
8556 | else |
8557 | return \"sal{b}\\t{%2, %0|%0, %2}\"; | |
8558 | } | |
8559 | } | |
8560 | }" | |
8561 | [(set (attr "type") | |
8562 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
8563 | (const_int 0)) | |
8564 | (match_operand 0 "register_operand" "")) | |
8565 | (match_operand 2 "const1_operand" "")) | |
8566 | (const_string "alu") | |
8567 | ] | |
6ef67412 JH |
8568 | (const_string "ishift"))) |
8569 | (set_attr "mode" "QI,SI")]) | |
e075ae69 | 8570 | |
28cefcd2 BS |
8571 | ;; This pattern can't accept a variable shift count, since shifts by |
8572 | ;; zero don't affect the flags. We assume that shifts by constant | |
8573 | ;; zero are optimized away. | |
2c873473 | 8574 | (define_insn "*ashlqi3_cmp" |
16189740 RH |
8575 | [(set (reg 17) |
8576 | (compare | |
e075ae69 | 8577 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") |
28cefcd2 | 8578 | (match_operand:QI 2 "immediate_operand" "I")) |
e075ae69 RH |
8579 | (const_int 0))) |
8580 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
8581 | (ashift:QI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 8582 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 8583 | && ix86_binary_operator_ok (ASHIFT, QImode, operands)" |
886c62d1 JVA |
8584 | "* |
8585 | { | |
e075ae69 RH |
8586 | switch (get_attr_type (insn)) |
8587 | { | |
8588 | case TYPE_ALU: | |
8589 | if (operands[2] != const1_rtx) | |
8590 | abort (); | |
8591 | return \"add{b}\\t{%0, %0|%0, %0}\"; | |
8592 | ||
8593 | default: | |
8594 | if (REG_P (operands[2])) | |
8595 | return \"sal{b}\\t{%b2, %0|%0, %b2}\"; | |
8bad7136 JL |
8596 | else if (GET_CODE (operands[2]) == CONST_INT |
8597 | && INTVAL (operands[2]) == 1 | |
8598 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) | |
8599 | return \"sal{b}\\t%0\"; | |
e075ae69 RH |
8600 | else |
8601 | return \"sal{b}\\t{%2, %0|%0, %2}\"; | |
8602 | } | |
8603 | }" | |
8604 | [(set (attr "type") | |
8605 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
8606 | (const_int 0)) | |
8607 | (match_operand 0 "register_operand" "")) | |
8608 | (match_operand 2 "const1_operand" "")) | |
8609 | (const_string "alu") | |
8610 | ] | |
6ef67412 JH |
8611 | (const_string "ishift"))) |
8612 | (set_attr "mode" "QI")]) | |
886c62d1 JVA |
8613 | |
8614 | ;; See comment above `ashldi3' about how this works. | |
8615 | ||
e075ae69 RH |
8616 | (define_expand "ashrdi3" |
8617 | [(parallel [(set (match_operand:DI 0 "register_operand" "=r") | |
8618 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
8619 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) | |
8620 | (clobber (reg:CC 17))])] | |
56c0e8fa JVA |
8621 | "" |
8622 | " | |
8623 | { | |
e075ae69 | 8624 | if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) |
56c0e8fa | 8625 | { |
e075ae69 RH |
8626 | emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2])); |
8627 | DONE; | |
56c0e8fa | 8628 | } |
2ae0f82c SC |
8629 | }") |
8630 | ||
e075ae69 RH |
8631 | (define_insn "ashrdi3_1" |
8632 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8633 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
8634 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) | |
8635 | (clobber (match_scratch:SI 3 "=&r")) | |
8636 | (clobber (reg:CC 17))] | |
8637 | "TARGET_CMOVE" | |
8638 | "#" | |
8639 | [(set_attr "type" "multi")]) | |
886c62d1 | 8640 | |
e075ae69 RH |
8641 | (define_insn "*ashrdi3_2" |
8642 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8643 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
8644 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) | |
8645 | (clobber (reg:CC 17))] | |
56c0e8fa | 8646 | "" |
e075ae69 RH |
8647 | "#" |
8648 | [(set_attr "type" "multi")]) | |
886c62d1 | 8649 | |
e075ae69 RH |
8650 | (define_split |
8651 | [(set (match_operand:DI 0 "register_operand" "") | |
8652 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
8653 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8654 | (clobber (match_scratch:SI 3 "")) | |
8655 | (clobber (reg:CC 17))] | |
d7a29404 | 8656 | "TARGET_CMOVE && reload_completed" |
e075ae69 RH |
8657 | [(const_int 0)] |
8658 | "ix86_split_ashrdi (operands, operands[3]); DONE;") | |
886c62d1 | 8659 | |
e075ae69 RH |
8660 | (define_split |
8661 | [(set (match_operand:DI 0 "register_operand" "") | |
8662 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
8663 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8664 | (clobber (reg:CC 17))] | |
d7a29404 | 8665 | "reload_completed" |
e075ae69 RH |
8666 | [(const_int 0)] |
8667 | "ix86_split_ashrdi (operands, NULL_RTX); DONE;") | |
886c62d1 | 8668 | |
e075ae69 RH |
8669 | (define_insn "x86_shrd_1" |
8670 | [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") | |
8671 | (ior:SI (ashiftrt:SI (match_dup 0) | |
8672 | (match_operand:QI 2 "nonmemory_operand" "I,c")) | |
8673 | (ashift:SI (match_operand:SI 1 "register_operand" "r,r") | |
8674 | (minus:QI (const_int 32) (match_dup 2))))) | |
8675 | (clobber (reg:CC 17))] | |
886c62d1 | 8676 | "" |
e075ae69 RH |
8677 | "@ |
8678 | shrd{l}\\t{%2, %1, %0|%0, %1, %2} | |
8679 | shrd{l}\\t{%s2%1, %0|%0, %1, %2}" | |
8680 | [(set_attr "type" "ishift") | |
6ef67412 | 8681 | (set_attr "prefix_0f" "1") |
e075ae69 | 8682 | (set_attr "pent_pair" "np") |
6ef67412 JH |
8683 | (set_attr "ppro_uops" "few") |
8684 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
8685 | |
8686 | (define_expand "x86_shift_adj_3" | |
8687 | [(use (match_operand:SI 0 "register_operand" "")) | |
8688 | (use (match_operand:SI 1 "register_operand" "")) | |
8689 | (use (match_operand:QI 2 "register_operand" ""))] | |
8690 | "" | |
8691 | " | |
886c62d1 | 8692 | { |
e075ae69 RH |
8693 | rtx label = gen_label_rtx (); |
8694 | rtx tmp; | |
8695 | ||
16189740 | 8696 | emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); |
e075ae69 | 8697 | |
16189740 | 8698 | tmp = gen_rtx_REG (CCZmode, FLAGS_REG); |
e075ae69 RH |
8699 | tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); |
8700 | tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, | |
8701 | gen_rtx_LABEL_REF (VOIDmode, label), | |
8702 | pc_rtx); | |
8703 | tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); | |
8704 | JUMP_LABEL (tmp) = label; | |
8705 | ||
8706 | emit_move_insn (operands[0], operands[1]); | |
8707 | emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31))); | |
8708 | ||
8709 | emit_label (label); | |
8710 | LABEL_NUSES (label) = 1; | |
8711 | ||
8712 | DONE; | |
886c62d1 | 8713 | }") |
886c62d1 | 8714 | |
e075ae69 RH |
8715 | (define_insn "ashrsi3_31" |
8716 | [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") | |
8717 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") | |
8718 | (match_operand:SI 2 "const_int_operand" "i,i"))) | |
8719 | (clobber (reg:CC 17))] | |
d525dfdf JH |
8720 | "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size) |
8721 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" | |
e075ae69 RH |
8722 | "@ |
8723 | {cltd|cdq} | |
8724 | sar{l}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
8725 | [(set_attr "type" "imovx,ishift") |
8726 | (set_attr "prefix_0f" "0,*") | |
8727 | (set_attr "length_immediate" "0,*") | |
8728 | (set_attr "modrm" "0,1") | |
8729 | (set_attr "mode" "SI")]) | |
e075ae69 | 8730 | |
d525dfdf JH |
8731 | (define_expand "ashrsi3" |
8732 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
155d8a47 | 8733 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") |
d525dfdf JH |
8734 | (match_operand:QI 2 "nonmemory_operand" ""))) |
8735 | (clobber (reg:CC 17))] | |
8736 | "" | |
8737 | "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;") | |
8738 | ||
8bad7136 JL |
8739 | (define_insn "*ashrsi3_1_one_bit" |
8740 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
8741 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
8742 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
8743 | (clobber (reg:CC 17))] | |
8744 | "ix86_binary_operator_ok (ASHIFTRT, SImode, operands) | |
8745 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
8746 | "sar{l}\\t%0" | |
8747 | [(set_attr "type" "ishift") | |
8748 | (set (attr "length") | |
8749 | (if_then_else (match_operand:SI 0 "register_operand" "") | |
8750 | (const_string "2") | |
8751 | (const_string "*")))]) | |
8752 | ||
d525dfdf | 8753 | (define_insn "*ashrsi3_1" |
e075ae69 RH |
8754 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") |
8755 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
8756 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8757 | (clobber (reg:CC 17))] | |
d525dfdf | 8758 | "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
e075ae69 RH |
8759 | "@ |
8760 | sar{l}\\t{%2, %0|%0, %2} | |
8761 | sar{l}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
8762 | [(set_attr "type" "ishift") |
8763 | (set_attr "mode" "SI")]) | |
886c62d1 | 8764 | |
8bad7136 JL |
8765 | ;; This pattern can't accept a variable shift count, since shifts by |
8766 | ;; zero don't affect the flags. We assume that shifts by constant | |
8767 | ;; zero are optimized away. | |
2c873473 | 8768 | (define_insn "*ashrsi3_one_bit_cmp" |
8bad7136 JL |
8769 | [(set (reg 17) |
8770 | (compare | |
8771 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
8772 | (match_operand:QI 2 "const_int_1_operand" "")) | |
8773 | (const_int 0))) | |
8774 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
8775 | (ashiftrt:SI (match_dup 1) (match_dup 2)))] | |
2c873473 | 8776 | "ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 JL |
8777 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO) |
8778 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" | |
8779 | "sar{l}\\t%0" | |
8780 | [(set_attr "type" "ishift") | |
8781 | (set (attr "length") | |
8782 | (if_then_else (match_operand:SI 0 "register_operand" "") | |
8783 | (const_string "2") | |
8784 | (const_string "*")))]) | |
8785 | ||
28cefcd2 BS |
8786 | ;; This pattern can't accept a variable shift count, since shifts by |
8787 | ;; zero don't affect the flags. We assume that shifts by constant | |
8788 | ;; zero are optimized away. | |
2c873473 | 8789 | (define_insn "*ashrsi3_cmp" |
16189740 RH |
8790 | [(set (reg 17) |
8791 | (compare | |
28cefcd2 BS |
8792 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") |
8793 | (match_operand:QI 2 "immediate_operand" "I")) | |
e075ae69 | 8794 | (const_int 0))) |
28cefcd2 | 8795 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 8796 | (ashiftrt:SI (match_dup 1) (match_dup 2)))] |
2c873473 | 8797 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 8798 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
2bed3391 | 8799 | "sar{l}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
8800 | [(set_attr "type" "ishift") |
8801 | (set_attr "mode" "SI")]) | |
886c62d1 | 8802 | |
d525dfdf JH |
8803 | (define_expand "ashrhi3" |
8804 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
155d8a47 | 8805 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") |
d525dfdf JH |
8806 | (match_operand:QI 2 "nonmemory_operand" ""))) |
8807 | (clobber (reg:CC 17))] | |
d9f32422 | 8808 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
8809 | "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;") |
8810 | ||
8bad7136 JL |
8811 | (define_insn "*ashrhi3_1_one_bit" |
8812 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
8813 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
8814 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
8815 | (clobber (reg:CC 17))] | |
8816 | "ix86_binary_operator_ok (ASHIFTRT, HImode, operands) | |
8817 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
8818 | "sar{w}\\t%0" | |
8819 | [(set_attr "type" "ishift") | |
8820 | (set (attr "length") | |
3d117b30 | 8821 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
8822 | (const_string "2") |
8823 | (const_string "*")))]) | |
8824 | ||
d525dfdf | 8825 | (define_insn "*ashrhi3_1" |
e075ae69 RH |
8826 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") |
8827 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
8828 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8829 | (clobber (reg:CC 17))] | |
d525dfdf | 8830 | "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" |
e075ae69 RH |
8831 | "@ |
8832 | sar{w}\\t{%2, %0|%0, %2} | |
8833 | sar{w}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
8834 | [(set_attr "type" "ishift") |
8835 | (set_attr "mode" "HI")]) | |
886c62d1 | 8836 | |
8bad7136 JL |
8837 | ;; This pattern can't accept a variable shift count, since shifts by |
8838 | ;; zero don't affect the flags. We assume that shifts by constant | |
8839 | ;; zero are optimized away. | |
2c873473 | 8840 | (define_insn "*ashrhi3_one_bit_cmp" |
8bad7136 JL |
8841 | [(set (reg 17) |
8842 | (compare | |
8843 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
8844 | (match_operand:QI 2 "const_int_1_operand" "")) | |
8845 | (const_int 0))) | |
8846 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
8847 | (ashiftrt:HI (match_dup 1) (match_dup 2)))] | |
2c873473 | 8848 | "ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 JL |
8849 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO) |
8850 | && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" | |
8851 | "sar{w}\\t%0" | |
8852 | [(set_attr "type" "ishift") | |
8853 | (set (attr "length") | |
3d117b30 | 8854 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
8855 | (const_string "2") |
8856 | (const_string "*")))]) | |
8857 | ||
28cefcd2 BS |
8858 | ;; This pattern can't accept a variable shift count, since shifts by |
8859 | ;; zero don't affect the flags. We assume that shifts by constant | |
8860 | ;; zero are optimized away. | |
2c873473 | 8861 | (define_insn "*ashrhi3_cmp" |
16189740 RH |
8862 | [(set (reg 17) |
8863 | (compare | |
28cefcd2 BS |
8864 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") |
8865 | (match_operand:QI 2 "immediate_operand" "I")) | |
e075ae69 | 8866 | (const_int 0))) |
28cefcd2 | 8867 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 8868 | (ashiftrt:HI (match_dup 1) (match_dup 2)))] |
2c873473 | 8869 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 8870 | && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" |
2bed3391 | 8871 | "sar{w}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
8872 | [(set_attr "type" "ishift") |
8873 | (set_attr "mode" "HI")]) | |
886c62d1 | 8874 | |
d525dfdf JH |
8875 | (define_expand "ashrqi3" |
8876 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
155d8a47 | 8877 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") |
d525dfdf JH |
8878 | (match_operand:QI 2 "nonmemory_operand" ""))) |
8879 | (clobber (reg:CC 17))] | |
d9f32422 | 8880 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
8881 | "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;") |
8882 | ||
8bad7136 JL |
8883 | (define_insn "*ashrqi3_1_one_bit" |
8884 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
8885 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
8886 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
8887 | (clobber (reg:CC 17))] | |
8888 | "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) | |
8889 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
8890 | "sar{b}\\t%0" | |
8891 | [(set_attr "type" "ishift") | |
8892 | (set (attr "length") | |
3d117b30 | 8893 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
8894 | (const_string "2") |
8895 | (const_string "*")))]) | |
8896 | ||
d525dfdf | 8897 | (define_insn "*ashrqi3_1" |
e075ae69 RH |
8898 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") |
8899 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
8900 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8901 | (clobber (reg:CC 17))] | |
d525dfdf | 8902 | "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" |
e075ae69 RH |
8903 | "@ |
8904 | sar{b}\\t{%2, %0|%0, %2} | |
8905 | sar{b}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
8906 | [(set_attr "type" "ishift") |
8907 | (set_attr "mode" "QI")]) | |
886c62d1 | 8908 | |
8bad7136 JL |
8909 | ;; This pattern can't accept a variable shift count, since shifts by |
8910 | ;; zero don't affect the flags. We assume that shifts by constant | |
8911 | ;; zero are optimized away. | |
2c873473 | 8912 | (define_insn "*ashrqi3_one_bit_cmp" |
8bad7136 JL |
8913 | [(set (reg 17) |
8914 | (compare | |
8915 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
8916 | (match_operand:QI 2 "const_int_1_operand" "I")) | |
8917 | (const_int 0))) | |
8918 | (set (match_operand:QI 0 "nonimmediate_operand" "=rm") | |
8919 | (ashiftrt:QI (match_dup 1) (match_dup 2)))] | |
2c873473 | 8920 | "ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 JL |
8921 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO) |
8922 | && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" | |
8923 | "sar{b}\\t%0" | |
8924 | [(set_attr "type" "ishift") | |
8925 | (set (attr "length") | |
3d117b30 | 8926 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
8927 | (const_string "2") |
8928 | (const_string "*")))]) | |
8929 | ||
28cefcd2 BS |
8930 | ;; This pattern can't accept a variable shift count, since shifts by |
8931 | ;; zero don't affect the flags. We assume that shifts by constant | |
8932 | ;; zero are optimized away. | |
2c873473 | 8933 | (define_insn "*ashrqi3_cmp" |
16189740 RH |
8934 | [(set (reg 17) |
8935 | (compare | |
28cefcd2 BS |
8936 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") |
8937 | (match_operand:QI 2 "immediate_operand" "I")) | |
e075ae69 | 8938 | (const_int 0))) |
28cefcd2 | 8939 | (set (match_operand:QI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 8940 | (ashiftrt:QI (match_dup 1) (match_dup 2)))] |
2c873473 | 8941 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 8942 | && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" |
2bed3391 | 8943 | "sar{b}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
8944 | [(set_attr "type" "ishift") |
8945 | (set_attr "mode" "QI")]) | |
886c62d1 | 8946 | \f |
e075ae69 RH |
8947 | ;; Logical shift instructions |
8948 | ||
8949 | ;; See comment above `ashldi3' about how this works. | |
8950 | ||
8951 | (define_expand "lshrdi3" | |
8952 | [(parallel [(set (match_operand:DI 0 "register_operand" "=r") | |
8953 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
8954 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) | |
8955 | (clobber (reg:CC 17))])] | |
886c62d1 | 8956 | "" |
e075ae69 | 8957 | " |
886c62d1 | 8958 | { |
e075ae69 | 8959 | if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) |
886c62d1 | 8960 | { |
e075ae69 RH |
8961 | emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2])); |
8962 | DONE; | |
886c62d1 | 8963 | } |
886c62d1 | 8964 | }") |
886c62d1 | 8965 | |
e075ae69 RH |
8966 | (define_insn "lshrdi3_1" |
8967 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8968 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
8969 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) | |
8970 | (clobber (match_scratch:SI 3 "=&r")) | |
8971 | (clobber (reg:CC 17))] | |
1e07edd3 | 8972 | "!TARGET_64BIT && TARGET_CMOVE" |
e075ae69 RH |
8973 | "#" |
8974 | [(set_attr "type" "multi")]) | |
886c62d1 | 8975 | |
e075ae69 RH |
8976 | (define_insn "*lshrdi3_2" |
8977 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8978 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
8979 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) | |
8980 | (clobber (reg:CC 17))] | |
1e07edd3 | 8981 | "!TARGET_64BIT" |
e075ae69 RH |
8982 | "#" |
8983 | [(set_attr "type" "multi")]) | |
886c62d1 | 8984 | |
e075ae69 RH |
8985 | (define_split |
8986 | [(set (match_operand:DI 0 "register_operand" "") | |
8987 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
8988 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8989 | (clobber (match_scratch:SI 3 "")) | |
8990 | (clobber (reg:CC 17))] | |
1e07edd3 | 8991 | "!TARGET_64BIT && TARGET_CMOVE && reload_completed" |
e075ae69 RH |
8992 | [(const_int 0)] |
8993 | "ix86_split_lshrdi (operands, operands[3]); DONE;") | |
886c62d1 | 8994 | |
e075ae69 RH |
8995 | (define_split |
8996 | [(set (match_operand:DI 0 "register_operand" "") | |
8997 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
8998 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8999 | (clobber (reg:CC 17))] | |
1e07edd3 | 9000 | "!TARGET_64BIT && reload_completed" |
e075ae69 RH |
9001 | [(const_int 0)] |
9002 | "ix86_split_lshrdi (operands, NULL_RTX); DONE;") | |
886c62d1 | 9003 | |
d525dfdf JH |
9004 | (define_expand "lshrsi3" |
9005 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
9006 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
9007 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9008 | (clobber (reg:CC 17))] | |
9009 | "" | |
9010 | "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;") | |
9011 | ||
8bad7136 JL |
9012 | (define_insn "*lshrsi3_1_one_bit" |
9013 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
9014 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
9015 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9016 | (clobber (reg:CC 17))] | |
9017 | "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) | |
9018 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9019 | "shr{l}\\t%0" | |
9020 | [(set_attr "type" "ishift") | |
9021 | (set (attr "length") | |
9022 | (if_then_else (match_operand:SI 0 "register_operand" "") | |
9023 | (const_string "2") | |
9024 | (const_string "*")))]) | |
9025 | ||
d525dfdf | 9026 | (define_insn "*lshrsi3_1" |
e075ae69 RH |
9027 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") |
9028 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
9029 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9030 | (clobber (reg:CC 17))] | |
d525dfdf | 9031 | "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
e075ae69 RH |
9032 | "@ |
9033 | shr{l}\\t{%2, %0|%0, %2} | |
9034 | shr{l}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9035 | [(set_attr "type" "ishift") |
9036 | (set_attr "mode" "SI")]) | |
886c62d1 | 9037 | |
8bad7136 JL |
9038 | ;; This pattern can't accept a variable shift count, since shifts by |
9039 | ;; zero don't affect the flags. We assume that shifts by constant | |
9040 | ;; zero are optimized away. | |
2c873473 | 9041 | (define_insn "*lshrsi3_one_bit_cmp" |
8bad7136 JL |
9042 | [(set (reg 17) |
9043 | (compare | |
9044 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
9045 | (match_operand:QI 2 "const_int_1_operand" "")) | |
9046 | (const_int 0))) | |
9047 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
9048 | (lshiftrt:SI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 9049 | "ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 JL |
9050 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO) |
9051 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
9052 | "shr{l}\\t%0" | |
9053 | [(set_attr "type" "ishift") | |
9054 | (set (attr "length") | |
9055 | (if_then_else (match_operand:SI 0 "register_operand" "") | |
9056 | (const_string "2") | |
9057 | (const_string "*")))]) | |
9058 | ||
28cefcd2 BS |
9059 | ;; This pattern can't accept a variable shift count, since shifts by |
9060 | ;; zero don't affect the flags. We assume that shifts by constant | |
9061 | ;; zero are optimized away. | |
2c873473 | 9062 | (define_insn "*lshrsi3_cmp" |
16189740 RH |
9063 | [(set (reg 17) |
9064 | (compare | |
28cefcd2 BS |
9065 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") |
9066 | (match_operand:QI 2 "immediate_operand" "I")) | |
e075ae69 | 9067 | (const_int 0))) |
28cefcd2 | 9068 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 9069 | (lshiftrt:SI (match_dup 1) (match_dup 2)))] |
9076b9c1 | 9070 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 9071 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
2bed3391 | 9072 | "shr{l}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
9073 | [(set_attr "type" "ishift") |
9074 | (set_attr "mode" "SI")]) | |
886c62d1 | 9075 | |
d525dfdf JH |
9076 | (define_expand "lshrhi3" |
9077 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
9078 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
9079 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9080 | (clobber (reg:CC 17))] | |
d9f32422 | 9081 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
9082 | "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;") |
9083 | ||
8bad7136 JL |
9084 | (define_insn "*lshrhi3_1_one_bit" |
9085 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
9086 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
9087 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9088 | (clobber (reg:CC 17))] | |
9089 | "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) | |
9090 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9091 | "shr{w}\\t%0" | |
9092 | [(set_attr "type" "ishift") | |
9093 | (set (attr "length") | |
3d117b30 | 9094 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
9095 | (const_string "2") |
9096 | (const_string "*")))]) | |
9097 | ||
d525dfdf | 9098 | (define_insn "*lshrhi3_1" |
e075ae69 RH |
9099 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") |
9100 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
9101 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9102 | (clobber (reg:CC 17))] | |
d525dfdf | 9103 | "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
e075ae69 RH |
9104 | "@ |
9105 | shr{w}\\t{%2, %0|%0, %2} | |
9106 | shr{w}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9107 | [(set_attr "type" "ishift") |
9108 | (set_attr "mode" "HI")]) | |
886c62d1 | 9109 | |
8bad7136 JL |
9110 | ;; This pattern can't accept a variable shift count, since shifts by |
9111 | ;; zero don't affect the flags. We assume that shifts by constant | |
9112 | ;; zero are optimized away. | |
2c873473 | 9113 | (define_insn "*lshrhi3_one_bit_cmp" |
8bad7136 JL |
9114 | [(set (reg 17) |
9115 | (compare | |
9116 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
9117 | (match_operand:QI 2 "const_int_1_operand" "")) | |
9118 | (const_int 0))) | |
9119 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
9120 | (lshiftrt:HI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 9121 | "ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 JL |
9122 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO) |
9123 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
9124 | "shr{w}\\t%0" | |
9125 | [(set_attr "type" "ishift") | |
9126 | (set (attr "length") | |
9127 | (if_then_else (match_operand:SI 0 "register_operand" "") | |
9128 | (const_string "2") | |
9129 | (const_string "*")))]) | |
9130 | ||
28cefcd2 BS |
9131 | ;; This pattern can't accept a variable shift count, since shifts by |
9132 | ;; zero don't affect the flags. We assume that shifts by constant | |
9133 | ;; zero are optimized away. | |
2c873473 | 9134 | (define_insn "*lshrhi3_cmp" |
16189740 RH |
9135 | [(set (reg 17) |
9136 | (compare | |
28cefcd2 BS |
9137 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") |
9138 | (match_operand:QI 2 "immediate_operand" "I")) | |
e075ae69 | 9139 | (const_int 0))) |
28cefcd2 | 9140 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 9141 | (lshiftrt:HI (match_dup 1) (match_dup 2)))] |
9076b9c1 | 9142 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 9143 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
2bed3391 | 9144 | "shr{w}\\t{%2, %0|%0, %2}" |
6ef67412 JH |
9145 | [(set_attr "type" "ishift") |
9146 | (set_attr "mode" "HI")]) | |
886c62d1 | 9147 | |
d525dfdf JH |
9148 | (define_expand "lshrqi3" |
9149 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
9150 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
9151 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9152 | (clobber (reg:CC 17))] | |
d9f32422 | 9153 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
9154 | "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;") |
9155 | ||
8bad7136 JL |
9156 | (define_insn "*lshrqi3_1_one_bit" |
9157 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
9158 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
9159 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9160 | (clobber (reg:CC 17))] | |
9161 | "ix86_binary_operator_ok (LSHIFTRT, QImode, operands) | |
9162 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9163 | "shr{b}\\t%0" | |
9164 | [(set_attr "type" "ishift") | |
9165 | (set (attr "length") | |
3d117b30 | 9166 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
9167 | (const_string "2") |
9168 | (const_string "*")))]) | |
9169 | ||
d525dfdf | 9170 | (define_insn "*lshrqi3_1" |
e075ae69 RH |
9171 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") |
9172 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
9173 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9174 | (clobber (reg:CC 17))] | |
d525dfdf | 9175 | "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" |
e075ae69 RH |
9176 | "@ |
9177 | shr{b}\\t{%2, %0|%0, %2} | |
9178 | shr{b}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9179 | [(set_attr "type" "ishift") |
9180 | (set_attr "mode" "QI")]) | |
886c62d1 | 9181 | |
8bad7136 JL |
9182 | ;; This pattern can't accept a variable shift count, since shifts by |
9183 | ;; zero don't affect the flags. We assume that shifts by constant | |
9184 | ;; zero are optimized away. | |
2c873473 | 9185 | (define_insn "*lshrqi2_one_bit_cmp" |
8bad7136 JL |
9186 | [(set (reg 17) |
9187 | (compare | |
9188 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
9189 | (match_operand:QI 2 "const_int_1_operand" "")) | |
9190 | (const_int 0))) | |
9191 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
9192 | (lshiftrt:QI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 9193 | "ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 JL |
9194 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO) |
9195 | && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" | |
9196 | "shr{b}\\t%0" | |
9197 | [(set_attr "type" "ishift") | |
9198 | (set (attr "length") | |
9199 | (if_then_else (match_operand:SI 0 "register_operand" "") | |
9200 | (const_string "2") | |
9201 | (const_string "*")))]) | |
9202 | ||
28cefcd2 BS |
9203 | ;; This pattern can't accept a variable shift count, since shifts by |
9204 | ;; zero don't affect the flags. We assume that shifts by constant | |
9205 | ;; zero are optimized away. | |
2c873473 | 9206 | (define_insn "*lshrqi2_cmp" |
16189740 RH |
9207 | [(set (reg 17) |
9208 | (compare | |
28cefcd2 BS |
9209 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") |
9210 | (match_operand:QI 2 "immediate_operand" "I")) | |
e075ae69 | 9211 | (const_int 0))) |
122ddbf9 | 9212 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
e075ae69 | 9213 | (lshiftrt:QI (match_dup 1) (match_dup 2)))] |
9076b9c1 | 9214 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 RH |
9215 | && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" |
9216 | "shr{b}\\t{%2, %0|%0, %2}" | |
6ef67412 JH |
9217 | [(set_attr "type" "ishift") |
9218 | (set_attr "mode" "QI")]) | |
886c62d1 | 9219 | \f |
e075ae69 | 9220 | ;; Rotate instructions |
886c62d1 | 9221 | |
d525dfdf JH |
9222 | (define_expand "rotlsi3" |
9223 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
9224 | (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
9225 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9226 | (clobber (reg:CC 17))] | |
9227 | "" | |
9228 | "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") | |
9229 | ||
8bad7136 JL |
9230 | (define_insn "*rotlsi3_1_one_bit" |
9231 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
9232 | (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
9233 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9234 | (clobber (reg:CC 17))] | |
9235 | "ix86_binary_operator_ok (ROTATE, SImode, operands) | |
9236 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9237 | "rol{l}\\t%0" | |
9238 | [(set_attr "type" "ishift") | |
9239 | (set (attr "length") | |
9240 | (if_then_else (match_operand:SI 0 "register_operand" "") | |
9241 | (const_string "2") | |
9242 | (const_string "*")))]) | |
9243 | ||
d525dfdf | 9244 | (define_insn "*rotlsi3_1" |
e075ae69 RH |
9245 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") |
9246 | (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
9247 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9248 | (clobber (reg:CC 17))] | |
d525dfdf | 9249 | "ix86_binary_operator_ok (ROTATE, SImode, operands)" |
e075ae69 RH |
9250 | "@ |
9251 | rol{l}\\t{%2, %0|%0, %2} | |
9252 | rol{l}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9253 | [(set_attr "type" "ishift") |
9254 | (set_attr "mode" "SI")]) | |
b4ac57ab | 9255 | |
d525dfdf JH |
9256 | (define_expand "rotlhi3" |
9257 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
9258 | (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
9259 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9260 | (clobber (reg:CC 17))] | |
d9f32422 | 9261 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
9262 | "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") |
9263 | ||
8bad7136 JL |
9264 | (define_insn "*rotlhi3_1_one_bit" |
9265 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
9266 | (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
9267 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9268 | (clobber (reg:CC 17))] | |
9269 | "ix86_binary_operator_ok (ROTATE, HImode, operands) | |
9270 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9271 | "rol{w}\\t%0" | |
9272 | [(set_attr "type" "ishift") | |
9273 | (set (attr "length") | |
3d117b30 | 9274 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
9275 | (const_string "2") |
9276 | (const_string "*")))]) | |
9277 | ||
d525dfdf | 9278 | (define_insn "*rotlhi3_1" |
e075ae69 RH |
9279 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") |
9280 | (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
9281 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9282 | (clobber (reg:CC 17))] | |
d525dfdf | 9283 | "ix86_binary_operator_ok (ROTATE, HImode, operands)" |
e075ae69 RH |
9284 | "@ |
9285 | rol{w}\\t{%2, %0|%0, %2} | |
9286 | rol{w}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9287 | [(set_attr "type" "ishift") |
9288 | (set_attr "mode" "HI")]) | |
47af5d50 | 9289 | |
d525dfdf JH |
9290 | (define_expand "rotlqi3" |
9291 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
9292 | (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
9293 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9294 | (clobber (reg:CC 17))] | |
d9f32422 | 9295 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
9296 | "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") |
9297 | ||
8bad7136 JL |
9298 | (define_insn "*rotlqi3_1_one_bit" |
9299 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
9300 | (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
9301 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9302 | (clobber (reg:CC 17))] | |
9303 | "ix86_binary_operator_ok (ROTATE, QImode, operands) | |
9304 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9305 | "rol{b}\\t%0" | |
9306 | [(set_attr "type" "ishift") | |
9307 | (set (attr "length") | |
3d117b30 | 9308 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
9309 | (const_string "2") |
9310 | (const_string "*")))]) | |
9311 | ||
d525dfdf | 9312 | (define_insn "*rotlqi3_1" |
e075ae69 RH |
9313 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") |
9314 | (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
9315 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9316 | (clobber (reg:CC 17))] | |
d525dfdf | 9317 | "ix86_binary_operator_ok (ROTATE, QImode, operands)" |
e075ae69 RH |
9318 | "@ |
9319 | rol{b}\\t{%2, %0|%0, %2} | |
9320 | rol{b}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9321 | [(set_attr "type" "ishift") |
9322 | (set_attr "mode" "QI")]) | |
47af5d50 | 9323 | |
d525dfdf JH |
9324 | (define_expand "rotrsi3" |
9325 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
9326 | (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
9327 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9328 | (clobber (reg:CC 17))] | |
9329 | "" | |
9330 | "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") | |
9331 | ||
8bad7136 JL |
9332 | (define_insn "*rotrsi3_1_one_bit" |
9333 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
9334 | (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
9335 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9336 | (clobber (reg:CC 17))] | |
9337 | "ix86_binary_operator_ok (ROTATERT, SImode, operands) | |
9338 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9339 | "ror{l}\\t%0" | |
9340 | [(set_attr "type" "ishift") | |
9341 | (set (attr "length") | |
9342 | (if_then_else (match_operand:SI 0 "register_operand" "") | |
9343 | (const_string "2") | |
9344 | (const_string "*")))]) | |
9345 | ||
d525dfdf | 9346 | (define_insn "*rotrsi3_1" |
e075ae69 RH |
9347 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") |
9348 | (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
9349 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9350 | (clobber (reg:CC 17))] | |
d525dfdf | 9351 | "ix86_binary_operator_ok (ROTATERT, SImode, operands)" |
e075ae69 RH |
9352 | "@ |
9353 | ror{l}\\t{%2, %0|%0, %2} | |
9354 | ror{l}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9355 | [(set_attr "type" "ishift") |
9356 | (set_attr "mode" "SI")]) | |
47af5d50 | 9357 | |
d525dfdf JH |
9358 | (define_expand "rotrhi3" |
9359 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
9360 | (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
9361 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9362 | (clobber (reg:CC 17))] | |
d9f32422 | 9363 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
9364 | "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") |
9365 | ||
8bad7136 JL |
9366 | (define_insn "*rotrhi3_one_bit" |
9367 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
9368 | (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
9369 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9370 | (clobber (reg:CC 17))] | |
9371 | "ix86_binary_operator_ok (ROTATERT, HImode, operands) | |
9372 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9373 | "ror{w}\\t%0" | |
9374 | [(set_attr "type" "ishift") | |
9375 | (set (attr "length") | |
3d117b30 | 9376 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
9377 | (const_string "2") |
9378 | (const_string "*")))]) | |
9379 | ||
d525dfdf | 9380 | (define_insn "*rotrhi3" |
e075ae69 RH |
9381 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") |
9382 | (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
9383 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9384 | (clobber (reg:CC 17))] | |
d525dfdf | 9385 | "ix86_binary_operator_ok (ROTATERT, HImode, operands)" |
e075ae69 RH |
9386 | "@ |
9387 | ror{w}\\t{%2, %0|%0, %2} | |
9388 | ror{w}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9389 | [(set_attr "type" "ishift") |
9390 | (set_attr "mode" "HI")]) | |
a199fdd6 | 9391 | |
d525dfdf JH |
9392 | (define_expand "rotrqi3" |
9393 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
9394 | (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
9395 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
9396 | (clobber (reg:CC 17))] | |
d9f32422 | 9397 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
9398 | "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") |
9399 | ||
8bad7136 JL |
9400 | (define_insn "*rotrqi3_1_one_bit" |
9401 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
9402 | (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
9403 | (match_operand:QI 2 "const_int_1_operand" ""))) | |
9404 | (clobber (reg:CC 17))] | |
9405 | "ix86_binary_operator_ok (ROTATERT, QImode, operands) | |
9406 | && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" | |
9407 | "ror{b}\\t%0" | |
9408 | [(set_attr "type" "ishift") | |
9409 | (set (attr "length") | |
3d117b30 | 9410 | (if_then_else (match_operand 0 "register_operand" "") |
8bad7136 JL |
9411 | (const_string "2") |
9412 | (const_string "*")))]) | |
9413 | ||
d525dfdf | 9414 | (define_insn "*rotrqi3_1" |
e075ae69 RH |
9415 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") |
9416 | (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
9417 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
9418 | (clobber (reg:CC 17))] | |
d525dfdf | 9419 | "ix86_binary_operator_ok (ROTATERT, QImode, operands)" |
e075ae69 RH |
9420 | "@ |
9421 | ror{b}\\t{%2, %0|%0, %2} | |
9422 | ror{b}\\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
9423 | [(set_attr "type" "ishift") |
9424 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
9425 | \f |
9426 | ;; Bit set / bit test instructions | |
a199fdd6 | 9427 | |
e075ae69 RH |
9428 | (define_expand "extv" |
9429 | [(set (match_operand:SI 0 "register_operand" "") | |
9430 | (sign_extract:SI (match_operand:SI 1 "register_operand" "") | |
9431 | (match_operand:SI 2 "immediate_operand" "") | |
9432 | (match_operand:SI 3 "immediate_operand" "")))] | |
9433 | "" | |
9434 | " | |
9435 | { | |
9436 | /* Handle extractions from %ah et al. */ | |
9437 | if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) | |
9438 | FAIL; | |
a199fdd6 | 9439 | |
e075ae69 RH |
9440 | /* From mips.md: extract_bit_field doesn't verify that our source |
9441 | matches the predicate, so check it again here. */ | |
9442 | if (! register_operand (operands[1], VOIDmode)) | |
9443 | FAIL; | |
9444 | }") | |
a199fdd6 | 9445 | |
e075ae69 RH |
9446 | (define_expand "extzv" |
9447 | [(set (match_operand:SI 0 "register_operand" "") | |
9448 | (zero_extract:SI (match_operand 1 "ext_register_operand" "") | |
9449 | (match_operand:SI 2 "immediate_operand" "") | |
9450 | (match_operand:SI 3 "immediate_operand" "")))] | |
9451 | "" | |
9452 | " | |
9453 | { | |
9454 | /* Handle extractions from %ah et al. */ | |
9455 | if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) | |
9456 | FAIL; | |
a199fdd6 | 9457 | |
e075ae69 RH |
9458 | /* From mips.md: extract_bit_field doesn't verify that our source |
9459 | matches the predicate, so check it again here. */ | |
9460 | if (! register_operand (operands[1], VOIDmode)) | |
9461 | FAIL; | |
9462 | }") | |
a199fdd6 | 9463 | |
e075ae69 RH |
9464 | (define_expand "insv" |
9465 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "") | |
9466 | (match_operand:SI 1 "immediate_operand" "") | |
9467 | (match_operand:SI 2 "immediate_operand" "")) | |
9468 | (match_operand:SI 3 "register_operand" ""))] | |
9469 | "" | |
9470 | " | |
9471 | { | |
9472 | /* Handle extractions from %ah et al. */ | |
9473 | if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) | |
9474 | FAIL; | |
a199fdd6 | 9475 | |
e075ae69 RH |
9476 | /* From mips.md: insert_bit_field doesn't verify that our source |
9477 | matches the predicate, so check it again here. */ | |
9478 | if (! register_operand (operands[0], VOIDmode)) | |
9479 | FAIL; | |
a199fdd6 | 9480 | }") |
e075ae69 RH |
9481 | |
9482 | ;; %%% bts, btr, btc, bt. | |
886c62d1 JVA |
9483 | \f |
9484 | ;; Store-flag instructions. | |
9485 | ||
c572e5ba JVA |
9486 | ;; For all sCOND expanders, also expand the compare or test insn that |
9487 | ;; generates cc0. Generate an equality comparison if `seq' or `sne'. | |
9488 | ||
e075ae69 RH |
9489 | ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way |
9490 | ;; to avoid partial register stalls. Otherwise do things the setcc+movzx | |
9491 | ;; way, which can later delete the movzx if only QImode is needed. | |
9492 | ||
c572e5ba | 9493 | (define_expand "seq" |
e075ae69 RH |
9494 | [(set (match_operand:SI 0 "register_operand" "") |
9495 | (eq:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9496 | "" |
3a3677ff | 9497 | "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;") |
c572e5ba | 9498 | |
c572e5ba | 9499 | (define_expand "sne" |
e075ae69 RH |
9500 | [(set (match_operand:SI 0 "register_operand" "") |
9501 | (ne:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9502 | "" |
3a3677ff | 9503 | "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;") |
c572e5ba | 9504 | |
c572e5ba | 9505 | (define_expand "sgt" |
e075ae69 RH |
9506 | [(set (match_operand:SI 0 "register_operand" "") |
9507 | (gt:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9508 | "" |
3a3677ff | 9509 | "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;") |
c572e5ba | 9510 | |
c572e5ba | 9511 | (define_expand "sgtu" |
e075ae69 RH |
9512 | [(set (match_operand:SI 0 "register_operand" "") |
9513 | (gtu:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9514 | "" |
3a3677ff | 9515 | "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;") |
c572e5ba | 9516 | |
c572e5ba | 9517 | (define_expand "slt" |
e075ae69 RH |
9518 | [(set (match_operand:SI 0 "register_operand" "") |
9519 | (lt:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9520 | "" |
3a3677ff | 9521 | "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;") |
c572e5ba | 9522 | |
c572e5ba | 9523 | (define_expand "sltu" |
e075ae69 RH |
9524 | [(set (match_operand:SI 0 "register_operand" "") |
9525 | (ltu:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9526 | "" |
3a3677ff | 9527 | "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;") |
c572e5ba | 9528 | |
c572e5ba | 9529 | (define_expand "sge" |
e075ae69 RH |
9530 | [(set (match_operand:SI 0 "register_operand" "") |
9531 | (ge:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9532 | "" |
3a3677ff | 9533 | "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;") |
c572e5ba | 9534 | |
c572e5ba | 9535 | (define_expand "sgeu" |
e075ae69 RH |
9536 | [(set (match_operand:SI 0 "register_operand" "") |
9537 | (geu:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9538 | "" |
3a3677ff | 9539 | "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;") |
c572e5ba | 9540 | |
c572e5ba | 9541 | (define_expand "sle" |
e075ae69 RH |
9542 | [(set (match_operand:SI 0 "register_operand" "") |
9543 | (le:SI (reg:CC 17) (const_int 0)))] | |
c572e5ba | 9544 | "" |
3a3677ff | 9545 | "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;") |
c572e5ba | 9546 | |
c785c660 | 9547 | (define_expand "sleu" |
e075ae69 RH |
9548 | [(set (match_operand:SI 0 "register_operand" "") |
9549 | (leu:SI (reg:CC 17) (const_int 0)))] | |
c785c660 | 9550 | "" |
3a3677ff RH |
9551 | "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;") |
9552 | ||
9553 | (define_expand "sunordered" | |
9554 | [(set (match_operand:SI 0 "register_operand" "") | |
9555 | (unordered:SI (reg:CC 17) (const_int 0)))] | |
0644b628 | 9556 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9557 | "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;") |
9558 | ||
9559 | (define_expand "sordered" | |
9560 | [(set (match_operand:SI 0 "register_operand" "") | |
9561 | (ordered:SI (reg:CC 17) (const_int 0)))] | |
9562 | "TARGET_80387" | |
9563 | "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;") | |
9564 | ||
9565 | (define_expand "suneq" | |
9566 | [(set (match_operand:SI 0 "register_operand" "") | |
9567 | (uneq:SI (reg:CC 17) (const_int 0)))] | |
0644b628 | 9568 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9569 | "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;") |
9570 | ||
9571 | (define_expand "sunge" | |
9572 | [(set (match_operand:SI 0 "register_operand" "") | |
9573 | (unge:SI (reg:CC 17) (const_int 0)))] | |
0644b628 | 9574 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9575 | "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;") |
9576 | ||
9577 | (define_expand "sungt" | |
9578 | [(set (match_operand:SI 0 "register_operand" "") | |
9579 | (ungt:SI (reg:CC 17) (const_int 0)))] | |
0644b628 | 9580 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9581 | "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;") |
9582 | ||
9583 | (define_expand "sunle" | |
9584 | [(set (match_operand:SI 0 "register_operand" "") | |
9585 | (unle:SI (reg:CC 17) (const_int 0)))] | |
0644b628 | 9586 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9587 | "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;") |
9588 | ||
9589 | (define_expand "sunlt" | |
9590 | [(set (match_operand:SI 0 "register_operand" "") | |
9591 | (unlt:SI (reg:CC 17) (const_int 0)))] | |
0644b628 | 9592 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9593 | "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;") |
9594 | ||
9595 | (define_expand "sltgt" | |
9596 | [(set (match_operand:SI 0 "register_operand" "") | |
9597 | (ltgt:SI (reg:CC 17) (const_int 0)))] | |
0644b628 | 9598 | "TARGET_80387 || TARGET_SSE" |
3a3677ff | 9599 | "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;") |
c785c660 | 9600 | |
e075ae69 | 9601 | (define_insn "*setcc_1" |
a269a03c | 9602 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
9076b9c1 | 9603 | (match_operator:QI 1 "ix86_comparison_operator" |
e075ae69 RH |
9604 | [(reg 17) (const_int 0)]))] |
9605 | "" | |
9606 | "set%C1\\t%0" | |
6ef67412 JH |
9607 | [(set_attr "type" "setcc") |
9608 | (set_attr "mode" "QI")]) | |
a269a03c | 9609 | |
bd793c65 | 9610 | (define_insn "setcc_2" |
e075ae69 | 9611 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) |
9076b9c1 | 9612 | (match_operator:QI 1 "ix86_comparison_operator" |
e075ae69 RH |
9613 | [(reg 17) (const_int 0)]))] |
9614 | "" | |
9615 | "set%C1\\t%0" | |
6ef67412 JH |
9616 | [(set_attr "type" "setcc") |
9617 | (set_attr "mode" "QI")]) | |
e075ae69 | 9618 | |
a46d1d38 JH |
9619 | ;; The SSE store flag instructions saves 0 or 0xffffffff to the result. |
9620 | ;; subsequent logical operations are used to imitate conditional moves. | |
9621 | ;; 0xffffffff is NaN, but not in normalized form, so we can't represent | |
9622 | ;; it directly. Futher holding this value in pseudo register might bring | |
9623 | ;; problem in implicit normalization in spill code. | |
9624 | ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these | |
9625 | ;; instructions after reload by splitting the conditional move patterns. | |
9626 | ||
9627 | (define_insn "*sse_setccsf" | |
9628 | [(set (match_operand:SF 0 "register_operand" "=x") | |
9629 | (match_operator:SF 1 "sse_comparison_operator" | |
9630 | [(match_operand:SF 2 "register_operand" "0") | |
9631 | (match_operand:SF 3 "nonimmediate_operand" "xm")]))] | |
9632 | "TARGET_SSE && reload_completed" | |
9633 | "cmp%D1ss\\t{%3, %0|%0, %3}" | |
9634 | [(set_attr "type" "sse") | |
9635 | (set_attr "mode" "SF")]) | |
9636 | ||
9637 | (define_insn "*sse_setccdf" | |
9638 | [(set (match_operand:DF 0 "register_operand" "=Y") | |
9639 | (match_operator:DF 1 "sse_comparison_operator" | |
9640 | [(match_operand:DF 2 "register_operand" "0") | |
9641 | (match_operand:DF 3 "nonimmediate_operand" "Ym")]))] | |
9642 | "TARGET_SSE2 && reload_completed" | |
9643 | "cmp%D1sd\\t{%3, %0|%0, %3}" | |
9644 | [(set_attr "type" "sse") | |
9645 | (set_attr "mode" "DF")]) | |
886c62d1 JVA |
9646 | \f |
9647 | ;; Basic conditional jump instructions. | |
9648 | ;; We ignore the overflow flag for signed branch instructions. | |
9649 | ||
c572e5ba | 9650 | ;; For all bCOND expanders, also expand the compare or test insn that |
e075ae69 | 9651 | ;; generates reg 17. Generate an equality comparison if `beq' or `bne'. |
c572e5ba JVA |
9652 | |
9653 | (define_expand "beq" | |
e075ae69 RH |
9654 | [(set (pc) |
9655 | (if_then_else (match_dup 1) | |
c572e5ba JVA |
9656 | (label_ref (match_operand 0 "" "")) |
9657 | (pc)))] | |
9658 | "" | |
3a3677ff | 9659 | "ix86_expand_branch (EQ, operands[0]); DONE;") |
c572e5ba | 9660 | |
c572e5ba | 9661 | (define_expand "bne" |
e075ae69 RH |
9662 | [(set (pc) |
9663 | (if_then_else (match_dup 1) | |
c572e5ba JVA |
9664 | (label_ref (match_operand 0 "" "")) |
9665 | (pc)))] | |
9666 | "" | |
3a3677ff | 9667 | "ix86_expand_branch (NE, operands[0]); DONE;") |
886c62d1 | 9668 | |
c572e5ba | 9669 | (define_expand "bgt" |
e075ae69 RH |
9670 | [(set (pc) |
9671 | (if_then_else (match_dup 1) | |
c572e5ba JVA |
9672 | (label_ref (match_operand 0 "" "")) |
9673 | (pc)))] | |
9674 | "" | |
3a3677ff | 9675 | "ix86_expand_branch (GT, operands[0]); DONE;") |
c572e5ba | 9676 | |
c572e5ba | 9677 | (define_expand "bgtu" |
e075ae69 RH |
9678 | [(set (pc) |
9679 | (if_then_else (match_dup 1) | |
c572e5ba JVA |
9680 | (label_ref (match_operand 0 "" "")) |
9681 | (pc)))] | |
9682 | "" | |
3a3677ff | 9683 | "ix86_expand_branch (GTU, operands[0]); DONE;") |
886c62d1 | 9684 | |
886c62d1 | 9685 | (define_expand "blt" |
e075ae69 RH |
9686 | [(set (pc) |
9687 | (if_then_else (match_dup 1) | |
886c62d1 JVA |
9688 | (label_ref (match_operand 0 "" "")) |
9689 | (pc)))] | |
9690 | "" | |
3a3677ff | 9691 | "ix86_expand_branch (LT, operands[0]); DONE;") |
886c62d1 | 9692 | |
c572e5ba | 9693 | (define_expand "bltu" |
e075ae69 RH |
9694 | [(set (pc) |
9695 | (if_then_else (match_dup 1) | |
c572e5ba JVA |
9696 | (label_ref (match_operand 0 "" "")) |
9697 | (pc)))] | |
9698 | "" | |
3a3677ff | 9699 | "ix86_expand_branch (LTU, operands[0]); DONE;") |
c572e5ba | 9700 | |
c572e5ba | 9701 | (define_expand "bge" |
e075ae69 RH |
9702 | [(set (pc) |
9703 | (if_then_else (match_dup 1) | |
c572e5ba JVA |
9704 | (label_ref (match_operand 0 "" "")) |
9705 | (pc)))] | |
9706 | "" | |
3a3677ff | 9707 | "ix86_expand_branch (GE, operands[0]); DONE;") |
c572e5ba | 9708 | |
c572e5ba | 9709 | (define_expand "bgeu" |
e075ae69 RH |
9710 | [(set (pc) |
9711 | (if_then_else (match_dup 1) | |
c572e5ba JVA |
9712 | (label_ref (match_operand 0 "" "")) |
9713 | (pc)))] | |
9714 | "" | |
3a3677ff | 9715 | "ix86_expand_branch (GEU, operands[0]); DONE;") |
886c62d1 | 9716 | |
886c62d1 | 9717 | (define_expand "ble" |
e075ae69 RH |
9718 | [(set (pc) |
9719 | (if_then_else (match_dup 1) | |
886c62d1 JVA |
9720 | (label_ref (match_operand 0 "" "")) |
9721 | (pc)))] | |
9722 | "" | |
3a3677ff | 9723 | "ix86_expand_branch (LE, operands[0]); DONE;") |
886c62d1 | 9724 | |
c572e5ba | 9725 | (define_expand "bleu" |
e075ae69 RH |
9726 | [(set (pc) |
9727 | (if_then_else (match_dup 1) | |
c572e5ba JVA |
9728 | (label_ref (match_operand 0 "" "")) |
9729 | (pc)))] | |
9730 | "" | |
3a3677ff RH |
9731 | "ix86_expand_branch (LEU, operands[0]); DONE;") |
9732 | ||
9733 | (define_expand "bunordered" | |
9734 | [(set (pc) | |
9735 | (if_then_else (match_dup 1) | |
9736 | (label_ref (match_operand 0 "" "")) | |
9737 | (pc)))] | |
0644b628 | 9738 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9739 | "ix86_expand_branch (UNORDERED, operands[0]); DONE;") |
9740 | ||
9741 | (define_expand "bordered" | |
9742 | [(set (pc) | |
9743 | (if_then_else (match_dup 1) | |
9744 | (label_ref (match_operand 0 "" "")) | |
9745 | (pc)))] | |
0644b628 | 9746 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9747 | "ix86_expand_branch (ORDERED, operands[0]); DONE;") |
9748 | ||
9749 | (define_expand "buneq" | |
9750 | [(set (pc) | |
9751 | (if_then_else (match_dup 1) | |
9752 | (label_ref (match_operand 0 "" "")) | |
9753 | (pc)))] | |
0644b628 | 9754 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9755 | "ix86_expand_branch (UNEQ, operands[0]); DONE;") |
9756 | ||
9757 | (define_expand "bunge" | |
9758 | [(set (pc) | |
9759 | (if_then_else (match_dup 1) | |
9760 | (label_ref (match_operand 0 "" "")) | |
9761 | (pc)))] | |
0644b628 | 9762 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9763 | "ix86_expand_branch (UNGE, operands[0]); DONE;") |
9764 | ||
9765 | (define_expand "bungt" | |
9766 | [(set (pc) | |
9767 | (if_then_else (match_dup 1) | |
9768 | (label_ref (match_operand 0 "" "")) | |
9769 | (pc)))] | |
0644b628 | 9770 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9771 | "ix86_expand_branch (UNGT, operands[0]); DONE;") |
9772 | ||
9773 | (define_expand "bunle" | |
9774 | [(set (pc) | |
9775 | (if_then_else (match_dup 1) | |
9776 | (label_ref (match_operand 0 "" "")) | |
9777 | (pc)))] | |
0644b628 | 9778 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9779 | "ix86_expand_branch (UNLE, operands[0]); DONE;") |
9780 | ||
9781 | (define_expand "bunlt" | |
9782 | [(set (pc) | |
9783 | (if_then_else (match_dup 1) | |
9784 | (label_ref (match_operand 0 "" "")) | |
9785 | (pc)))] | |
0644b628 | 9786 | "TARGET_80387 || TARGET_SSE" |
3a3677ff RH |
9787 | "ix86_expand_branch (UNLT, operands[0]); DONE;") |
9788 | ||
9789 | (define_expand "bltgt" | |
9790 | [(set (pc) | |
9791 | (if_then_else (match_dup 1) | |
9792 | (label_ref (match_operand 0 "" "")) | |
9793 | (pc)))] | |
0644b628 | 9794 | "TARGET_80387 || TARGET_SSE" |
3a3677ff | 9795 | "ix86_expand_branch (LTGT, operands[0]); DONE;") |
886c62d1 | 9796 | |
e075ae69 RH |
9797 | (define_insn "*jcc_1" |
9798 | [(set (pc) | |
9076b9c1 | 9799 | (if_then_else (match_operator 1 "ix86_comparison_operator" |
e075ae69 | 9800 | [(reg 17) (const_int 0)]) |
6ef67412 | 9801 | (label_ref (match_operand 0 "" "")) |
e075ae69 RH |
9802 | (pc)))] |
9803 | "" | |
6ef67412 | 9804 | "j%C1\\t%l0" |
e075ae69 | 9805 | [(set_attr "type" "ibr") |
6ef67412 JH |
9806 | (set (attr "prefix_0f") |
9807 | (if_then_else (and (ge (minus (match_dup 0) (pc)) | |
9808 | (const_int -128)) | |
9809 | (lt (minus (match_dup 0) (pc)) | |
9810 | (const_int 124))) | |
9811 | (const_int 0) | |
9812 | (const_int 1)))]) | |
e075ae69 RH |
9813 | |
9814 | (define_insn "*jcc_2" | |
9815 | [(set (pc) | |
9076b9c1 | 9816 | (if_then_else (match_operator 1 "ix86_comparison_operator" |
e075ae69 RH |
9817 | [(reg 17) (const_int 0)]) |
9818 | (pc) | |
6ef67412 | 9819 | (label_ref (match_operand 0 "" ""))))] |
e075ae69 | 9820 | "" |
6ef67412 | 9821 | "j%c1\\t%l0" |
e075ae69 | 9822 | [(set_attr "type" "ibr") |
6ef67412 JH |
9823 | (set (attr "prefix_0f") |
9824 | (if_then_else (and (ge (minus (match_dup 0) (pc)) | |
9825 | (const_int -128)) | |
9826 | (lt (minus (match_dup 0) (pc)) | |
9827 | (const_int 124))) | |
9828 | (const_int 0) | |
9829 | (const_int 1)))]) | |
e075ae69 | 9830 | |
3a3677ff RH |
9831 | ;; Define combination compare-and-branch fp compare instructions to use |
9832 | ;; during early optimization. Splitting the operation apart early makes | |
9833 | ;; for bad code when we want to reverse the operation. | |
9834 | ||
9835 | (define_insn "*fp_jcc_1" | |
9836 | [(set (pc) | |
9837 | (if_then_else (match_operator 0 "comparison_operator" | |
9838 | [(match_operand 1 "register_operand" "f") | |
9839 | (match_operand 2 "register_operand" "f")]) | |
9840 | (label_ref (match_operand 3 "" "")) | |
9841 | (pc))) | |
9842 | (clobber (reg:CCFP 18)) | |
9843 | (clobber (reg:CCFP 17))] | |
9844 | "TARGET_CMOVE && TARGET_80387 | |
0644b628 | 9845 | && !SSE_FLOAT_MODE_P (GET_MODE (operands[1])) |
3a3677ff RH |
9846 | && FLOAT_MODE_P (GET_MODE (operands[1])) |
9847 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
9848 | "#") | |
9849 | ||
0644b628 JH |
9850 | (define_insn "*fp_jcc_1_sse" |
9851 | [(set (pc) | |
9852 | (if_then_else (match_operator 0 "comparison_operator" | |
9853 | [(match_operand 1 "register_operand" "f#x,x#f") | |
9854 | (match_operand 2 "nonimmediate_operand" "f#x,xm#f")]) | |
9855 | (label_ref (match_operand 3 "" "")) | |
9856 | (pc))) | |
9857 | (clobber (reg:CCFP 18)) | |
9858 | (clobber (reg:CCFP 17))] | |
9859 | "TARGET_80387 | |
9860 | && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) | |
9861 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
9862 | "#") | |
9863 | ||
9864 | (define_insn "*fp_jcc_1_sse_only" | |
9865 | [(set (pc) | |
9866 | (if_then_else (match_operator 0 "comparison_operator" | |
9867 | [(match_operand 1 "register_operand" "x") | |
9868 | (match_operand 2 "nonimmediate_operand" "xm")]) | |
9869 | (label_ref (match_operand 3 "" "")) | |
9870 | (pc))) | |
9871 | (clobber (reg:CCFP 18)) | |
9872 | (clobber (reg:CCFP 17))] | |
9873 | "SSE_FLOAT_MODE_P (GET_MODE (operands[1])) | |
9874 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
9875 | "#") | |
9876 | ||
3a3677ff RH |
9877 | (define_insn "*fp_jcc_2" |
9878 | [(set (pc) | |
9879 | (if_then_else (match_operator 0 "comparison_operator" | |
9880 | [(match_operand 1 "register_operand" "f") | |
9881 | (match_operand 2 "register_operand" "f")]) | |
9882 | (pc) | |
9883 | (label_ref (match_operand 3 "" "")))) | |
9884 | (clobber (reg:CCFP 18)) | |
9885 | (clobber (reg:CCFP 17))] | |
9886 | "TARGET_CMOVE && TARGET_80387 | |
0644b628 | 9887 | && !SSE_FLOAT_MODE_P (GET_MODE (operands[1])) |
3a3677ff RH |
9888 | && FLOAT_MODE_P (GET_MODE (operands[1])) |
9889 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
9890 | "#") | |
9891 | ||
0644b628 JH |
9892 | (define_insn "*fp_jcc_2_sse" |
9893 | [(set (pc) | |
9894 | (if_then_else (match_operator 0 "comparison_operator" | |
9895 | [(match_operand 1 "register_operand" "f#x,x#f") | |
9896 | (match_operand 2 "nonimmediate_operand" "f#x,xm#f")]) | |
9897 | (pc) | |
9898 | (label_ref (match_operand 3 "" "")))) | |
9899 | (clobber (reg:CCFP 18)) | |
9900 | (clobber (reg:CCFP 17))] | |
9901 | "TARGET_80387 | |
9902 | && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) | |
9903 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
9904 | "#") | |
9905 | ||
9906 | (define_insn "*fp_jcc_2_sse_only" | |
9907 | [(set (pc) | |
9908 | (if_then_else (match_operator 0 "comparison_operator" | |
9909 | [(match_operand 1 "register_operand" "x") | |
9910 | (match_operand 2 "nonimmediate_operand" "xm")]) | |
9911 | (pc) | |
9912 | (label_ref (match_operand 3 "" "")))) | |
9913 | (clobber (reg:CCFP 18)) | |
9914 | (clobber (reg:CCFP 17))] | |
9915 | "SSE_FLOAT_MODE_P (GET_MODE (operands[1])) | |
9916 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
9917 | "#") | |
9918 | ||
3a3677ff RH |
9919 | (define_insn "*fp_jcc_3" |
9920 | [(set (pc) | |
b1cdafbb | 9921 | (if_then_else (match_operator 0 "comparison_operator" |
3a3677ff RH |
9922 | [(match_operand 1 "register_operand" "f") |
9923 | (match_operand 2 "nonimmediate_operand" "fm")]) | |
9924 | (label_ref (match_operand 3 "" "")) | |
9925 | (pc))) | |
9926 | (clobber (reg:CCFP 18)) | |
9927 | (clobber (reg:CCFP 17)) | |
9928 | (clobber (match_scratch:HI 4 "=a"))] | |
9929 | "TARGET_80387 | |
9930 | && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) | |
a940d8bd | 9931 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
b1cdafbb JH |
9932 | && !ix86_use_fcomi_compare (GET_CODE (operands[0])) |
9933 | && SELECT_CC_MODE (GET_CODE (operands[0]), | |
9934 | operands[1], operands[2]) == CCFPmode" | |
3a3677ff RH |
9935 | "#") |
9936 | ||
9937 | (define_insn "*fp_jcc_4" | |
9938 | [(set (pc) | |
b1cdafbb | 9939 | (if_then_else (match_operator 0 "comparison_operator" |
3a3677ff RH |
9940 | [(match_operand 1 "register_operand" "f") |
9941 | (match_operand 2 "nonimmediate_operand" "fm")]) | |
9942 | (pc) | |
9943 | (label_ref (match_operand 3 "" "")))) | |
9944 | (clobber (reg:CCFP 18)) | |
9945 | (clobber (reg:CCFP 17)) | |
9946 | (clobber (match_scratch:HI 4 "=a"))] | |
9947 | "TARGET_80387 | |
9948 | && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) | |
a940d8bd | 9949 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
b1cdafbb JH |
9950 | && !ix86_use_fcomi_compare (GET_CODE (operands[0])) |
9951 | && SELECT_CC_MODE (GET_CODE (operands[0]), | |
9952 | operands[1], operands[2]) == CCFPmode" | |
3a3677ff RH |
9953 | "#") |
9954 | ||
9955 | (define_insn "*fp_jcc_5" | |
9956 | [(set (pc) | |
9957 | (if_then_else (match_operator 0 "comparison_operator" | |
9958 | [(match_operand 1 "register_operand" "f") | |
9959 | (match_operand 2 "register_operand" "f")]) | |
9960 | (label_ref (match_operand 3 "" "")) | |
9961 | (pc))) | |
9962 | (clobber (reg:CCFP 18)) | |
9963 | (clobber (reg:CCFP 17)) | |
9964 | (clobber (match_scratch:HI 4 "=a"))] | |
9965 | "TARGET_80387 | |
9966 | && FLOAT_MODE_P (GET_MODE (operands[1])) | |
9967 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
9968 | "#") | |
9969 | ||
9970 | (define_insn "*fp_jcc_6" | |
9971 | [(set (pc) | |
9972 | (if_then_else (match_operator 0 "comparison_operator" | |
9973 | [(match_operand 1 "register_operand" "f") | |
9974 | (match_operand 2 "register_operand" "f")]) | |
9975 | (pc) | |
9976 | (label_ref (match_operand 3 "" "")))) | |
9977 | (clobber (reg:CCFP 18)) | |
9978 | (clobber (reg:CCFP 17)) | |
9979 | (clobber (match_scratch:HI 4 "=a"))] | |
9980 | "TARGET_80387 | |
9981 | && FLOAT_MODE_P (GET_MODE (operands[1])) | |
9982 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
9983 | "#") | |
9984 | ||
9985 | (define_split | |
9986 | [(set (pc) | |
9987 | (if_then_else (match_operator 0 "comparison_operator" | |
9988 | [(match_operand 1 "register_operand" "") | |
9989 | (match_operand 2 "nonimmediate_operand" "")]) | |
9990 | (match_operand 3 "" "") | |
9991 | (match_operand 4 "" ""))) | |
9992 | (clobber (reg:CCFP 18)) | |
9993 | (clobber (reg:CCFP 17))] | |
9994 | "reload_completed" | |
9e7adcb3 | 9995 | [(const_int 0)] |
3a3677ff RH |
9996 | " |
9997 | { | |
9e7adcb3 JH |
9998 | ix86_split_fp_branch (operands[0], operands[1], operands[2], |
9999 | operands[3], operands[4], NULL_RTX); | |
10000 | DONE; | |
3a3677ff RH |
10001 | }") |
10002 | ||
10003 | (define_split | |
10004 | [(set (pc) | |
10005 | (if_then_else (match_operator 0 "comparison_operator" | |
10006 | [(match_operand 1 "register_operand" "") | |
10007 | (match_operand 2 "nonimmediate_operand" "")]) | |
10008 | (match_operand 3 "" "") | |
10009 | (match_operand 4 "" ""))) | |
10010 | (clobber (reg:CCFP 18)) | |
10011 | (clobber (reg:CCFP 17)) | |
10012 | (clobber (match_scratch:HI 5 "=a"))] | |
10013 | "reload_completed" | |
10014 | [(set (pc) | |
10015 | (if_then_else (match_dup 6) | |
10016 | (match_dup 3) | |
10017 | (match_dup 4)))] | |
10018 | " | |
10019 | { | |
9e7adcb3 JH |
10020 | ix86_split_fp_branch (operands[0], operands[1], operands[2], |
10021 | operands[3], operands[4], operands[5]); | |
10022 | DONE; | |
3a3677ff | 10023 | }") |
886c62d1 JVA |
10024 | \f |
10025 | ;; Unconditional and other jump instructions | |
10026 | ||
10027 | (define_insn "jump" | |
10028 | [(set (pc) | |
10029 | (label_ref (match_operand 0 "" "")))] | |
10030 | "" | |
e075ae69 | 10031 | "jmp\\t%l0" |
6ef67412 | 10032 | [(set_attr "type" "ibr")]) |
886c62d1 JVA |
10033 | |
10034 | (define_insn "indirect_jump" | |
2ae0f82c | 10035 | [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] |
886c62d1 | 10036 | "" |
fb204271 | 10037 | "jmp\\t%A0" |
6ef67412 JH |
10038 | [(set_attr "type" "ibr") |
10039 | (set_attr "length_immediate" "0")]) | |
4801403e | 10040 | |
e075ae69 RH |
10041 | (define_insn "tablejump" |
10042 | [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) | |
10043 | (use (label_ref (match_operand 1 "" "")))] | |
10044 | "! flag_pic" | |
fb204271 | 10045 | "jmp\\t%A0" |
6ef67412 JH |
10046 | [(set_attr "type" "ibr") |
10047 | (set_attr "length_immediate" "0")]) | |
4801403e | 10048 | |
2bb7a0f5 RS |
10049 | ;; Implement switch statements when generating PIC code. Switches are |
10050 | ;; implemented by `tablejump' when not using -fpic. | |
e075ae69 | 10051 | ;; |
2bb7a0f5 | 10052 | ;; Emit code here to do the range checking and make the index zero based. |
e075ae69 | 10053 | ;; |
2bb7a0f5 RS |
10054 | ;; Each entry in the "addr_diff_vec" looks like this as the result of the |
10055 | ;; two rules below: | |
10056 | ;; | |
10057 | ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2] | |
10058 | ;; | |
10059 | ;; 1. An expression involving an external reference may only use the | |
10060 | ;; addition operator, and only with an assembly-time constant. | |
10061 | ;; The example above satisfies this because ".-.L2" is a constant. | |
10062 | ;; | |
10063 | ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is | |
10064 | ;; given the value of "GOT - .", where GOT is the actual address of | |
10065 | ;; the Global Offset Table. Therefore, the .long above actually | |
10066 | ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The | |
10067 | ;; expression "GOT - .L2" by itself would generate an error from as(1). | |
10068 | ;; | |
10069 | ;; The pattern below emits code that looks like this: | |
10070 | ;; | |
10071 | ;; movl %ebx,reg | |
10072 | ;; subl TABLE@GOTOFF(%ebx,index,4),reg | |
10073 | ;; jmp reg | |
10074 | ;; | |
10075 | ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since | |
10076 | ;; the addr_diff_vec is known to be part of this module. | |
10077 | ;; | |
10078 | ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which | |
10079 | ;; evaluates to just ".L2". | |
10080 | ||
e075ae69 RH |
10081 | (define_expand "casesi" |
10082 | [(set (match_dup 5) | |
10083 | (match_operand:SI 0 "general_operand" "")) | |
10084 | (parallel [(set (match_dup 6) | |
10085 | (minus:SI (match_dup 5) | |
10086 | (match_operand:SI 1 "general_operand" ""))) | |
10087 | (clobber (reg:CC 17))]) | |
10088 | (set (reg:CC 17) | |
10089 | (compare:CC (match_dup 6) | |
10090 | (match_operand:SI 2 "general_operand" ""))) | |
10091 | (set (pc) | |
10092 | (if_then_else (gtu (reg:CC 17) | |
10093 | (const_int 0)) | |
10094 | (label_ref (match_operand 4 "" "")) | |
10095 | (pc))) | |
10096 | (parallel | |
10097 | [(set (match_dup 7) | |
10098 | (minus:SI (match_dup 8) | |
10099 | (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4)) | |
10100 | (match_dup 8)) | |
10101 | (const (unspec [(label_ref (match_operand 3 "" ""))] 7)))))) | |
10102 | (clobber (reg:CC 17))]) | |
10103 | (parallel [(set (pc) (match_dup 7)) | |
10104 | (use (label_ref (match_dup 3)))])] | |
10105 | "flag_pic" | |
10106 | " | |
2bb7a0f5 | 10107 | { |
e075ae69 RH |
10108 | operands[5] = gen_reg_rtx (SImode); |
10109 | operands[6] = gen_reg_rtx (SImode); | |
10110 | operands[7] = gen_reg_rtx (SImode); | |
10111 | operands[8] = pic_offset_table_rtx; | |
10112 | current_function_uses_pic_offset_table = 1; | |
2bb7a0f5 RS |
10113 | }") |
10114 | ||
6343a50e | 10115 | (define_insn "*tablejump_pic" |
2ae0f82c | 10116 | [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) |
886c62d1 JVA |
10117 | (use (label_ref (match_operand 1 "" "")))] |
10118 | "" | |
fb204271 | 10119 | "jmp\\t%A0" |
6ef67412 JH |
10120 | [(set_attr "type" "ibr") |
10121 | (set_attr "length_immediate" "0")]) | |
e075ae69 RH |
10122 | \f |
10123 | ;; Loop instruction | |
10124 | ;; | |
10125 | ;; This is all complicated by the fact that since this is a jump insn | |
10126 | ;; we must handle our own reloads. | |
10127 | ||
5527bf14 RH |
10128 | (define_expand "doloop_end" |
10129 | [(use (match_operand 0 "" "")) ; loop pseudo | |
10130 | (use (match_operand 1 "" "")) ; iterations; zero if unknown | |
10131 | (use (match_operand 2 "" "")) ; max iterations | |
10132 | (use (match_operand 3 "" "")) ; loop level | |
10133 | (use (match_operand 4 "" ""))] ; label | |
1e07edd3 | 10134 | "TARGET_USE_LOOP && !TARGET_64BIT" |
5527bf14 RH |
10135 | " |
10136 | { | |
10137 | /* Only use cloop on innermost loops. */ | |
10138 | if (INTVAL (operands[3]) > 1) | |
10139 | FAIL; | |
10140 | if (GET_MODE (operands[0]) != SImode) | |
10141 | FAIL; | |
10142 | emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0], | |
10143 | operands[0])); | |
10144 | DONE; | |
10145 | }") | |
e075ae69 | 10146 | |
5527bf14 | 10147 | (define_insn "doloop_end_internal" |
e075ae69 | 10148 | [(set (pc) |
5527bf14 | 10149 | (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r") |
e075ae69 RH |
10150 | (const_int 1)) |
10151 | (label_ref (match_operand 0 "" "")) | |
10152 | (pc))) | |
5527bf14 | 10153 | (set (match_operand:SI 2 "register_operand" "=1,1,*m*r") |
e075ae69 RH |
10154 | (plus:SI (match_dup 1) |
10155 | (const_int -1))) | |
10156 | (clobber (match_scratch:SI 3 "=X,X,r")) | |
10157 | (clobber (reg:CC 17))] | |
1e07edd3 | 10158 | "TARGET_USE_LOOP && !TARGET_64BIT" |
e075ae69 RH |
10159 | "* |
10160 | { | |
10161 | if (which_alternative != 0) | |
10162 | return \"#\"; | |
10163 | if (get_attr_length (insn) == 2) | |
10164 | return \"loop\\t%l0\"; | |
10165 | else | |
10166 | return \"dec{l}\\t%1\;jne\\t%l0\"; | |
10167 | }" | |
6ef67412 JH |
10168 | [(set_attr "ppro_uops" "many") |
10169 | (set (attr "type") | |
e075ae69 RH |
10170 | (if_then_else (and (eq_attr "alternative" "0") |
10171 | (and (ge (minus (match_dup 0) (pc)) | |
10172 | (const_int -128)) | |
10173 | (lt (minus (match_dup 0) (pc)) | |
10174 | (const_int 124)))) | |
6ef67412 JH |
10175 | (const_string "ibr") |
10176 | (const_string "multi")))]) | |
e075ae69 | 10177 | |
e075ae69 RH |
10178 | (define_split |
10179 | [(set (pc) | |
10180 | (if_then_else (ne (match_operand:SI 1 "register_operand" "") | |
10181 | (const_int 1)) | |
10182 | (match_operand 0 "" "") | |
10183 | (pc))) | |
5527bf14 | 10184 | (set (match_dup 1) |
e075ae69 RH |
10185 | (plus:SI (match_dup 1) |
10186 | (const_int -1))) | |
5527bf14 | 10187 | (clobber (match_scratch:SI 2 "")) |
e075ae69 | 10188 | (clobber (reg:CC 17))] |
1e07edd3 | 10189 | "TARGET_USE_LOOP && !TARGET_64BIT |
5527bf14 RH |
10190 | && reload_completed |
10191 | && REGNO (operands[1]) != 2" | |
10192 | [(parallel [(set (reg:CCZ 17) | |
10193 | (compare:CCZ (plus:SI (match_dup 1) (const_int -1)) | |
e075ae69 | 10194 | (const_int 0))) |
5527bf14 | 10195 | (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))]) |
16189740 | 10196 | (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0)) |
e075ae69 RH |
10197 | (match_dup 0) |
10198 | (pc)))] | |
10199 | "") | |
10200 | ||
10201 | (define_split | |
10202 | [(set (pc) | |
10203 | (if_then_else (ne (match_operand:SI 1 "register_operand" "") | |
10204 | (const_int 1)) | |
10205 | (match_operand 0 "" "") | |
10206 | (pc))) | |
5527bf14 | 10207 | (set (match_operand:SI 2 "nonimmediate_operand" "") |
e075ae69 RH |
10208 | (plus:SI (match_dup 1) |
10209 | (const_int -1))) | |
10210 | (clobber (match_scratch:SI 3 "")) | |
10211 | (clobber (reg:CC 17))] | |
1e07edd3 | 10212 | "TARGET_USE_LOOP && !TARGET_64BIT |
5527bf14 RH |
10213 | && reload_completed |
10214 | && (! REG_P (operands[2]) | |
10215 | || ! rtx_equal_p (operands[1], operands[2]))" | |
e075ae69 | 10216 | [(set (match_dup 3) (match_dup 1)) |
16189740 RH |
10217 | (parallel [(set (reg:CCZ 17) |
10218 | (compare:CCZ (plus:SI (match_dup 3) (const_int -1)) | |
10219 | (const_int 0))) | |
e075ae69 RH |
10220 | (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))]) |
10221 | (set (match_dup 2) (match_dup 3)) | |
16189740 | 10222 | (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0)) |
e075ae69 RH |
10223 | (match_dup 0) |
10224 | (pc)))] | |
10225 | "") | |
e075ae69 RH |
10226 | \f |
10227 | ;; Call instructions. | |
2bb7a0f5 | 10228 | |
cbbf65e0 RH |
10229 | ;; The predicates normally associated with named expanders are not properly |
10230 | ;; checked for calls. This is a bug in the generic code, but it isn't that | |
10231 | ;; easy to fix. Ignore it for now and be prepared to fix things up. | |
2bb7a0f5 | 10232 | |
886c62d1 JVA |
10233 | ;; Call subroutine returning no value. |
10234 | ||
2bb7a0f5 | 10235 | (define_expand "call_pop" |
cbbf65e0 RH |
10236 | [(parallel [(call (match_operand:QI 0 "" "") |
10237 | (match_operand:SI 1 "" "")) | |
2bb7a0f5 RS |
10238 | (set (reg:SI 7) |
10239 | (plus:SI (reg:SI 7) | |
cbbf65e0 | 10240 | (match_operand:SI 3 "" "")))])] |
1e07edd3 | 10241 | "!TARGET_64BIT" |
2bb7a0f5 RS |
10242 | " |
10243 | { | |
35e2d030 RH |
10244 | if (operands[3] == const0_rtx) |
10245 | { | |
10246 | emit_insn (gen_call (operands[0], operands[1])); | |
10247 | DONE; | |
10248 | } | |
b848ded1 JH |
10249 | /* Static functions and indirect calls don't need |
10250 | current_function_uses_pic_offset_table. */ | |
10251 | if (flag_pic | |
2a4bbffa RH |
10252 | && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF |
10253 | && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0))) | |
2bb7a0f5 | 10254 | current_function_uses_pic_offset_table = 1; |
e1ff012c | 10255 | if (! call_insn_operand (XEXP (operands[0], 0), Pmode)) |
cbbf65e0 | 10256 | XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); |
1e07edd3 JH |
10257 | if (TARGET_64BIT) |
10258 | abort(); | |
2bb7a0f5 RS |
10259 | }") |
10260 | ||
94bb5d0c | 10261 | (define_insn "*call_pop_0" |
e1ff012c | 10262 | [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) |
94bb5d0c RH |
10263 | (match_operand:SI 1 "" "")) |
10264 | (set (reg:SI 7) (plus:SI (reg:SI 7) | |
90d10fb9 | 10265 | (match_operand:SI 2 "immediate_operand" "")))] |
1e07edd3 | 10266 | "!TARGET_64BIT" |
94bb5d0c RH |
10267 | "* |
10268 | { | |
10269 | if (SIBLING_CALL_P (insn)) | |
10270 | return \"jmp\\t%P0\"; | |
10271 | else | |
10272 | return \"call\\t%P0\"; | |
10273 | }" | |
10274 | [(set_attr "type" "call")]) | |
10275 | ||
cbbf65e0 | 10276 | (define_insn "*call_pop_1" |
e1ff012c | 10277 | [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) |
94bb5d0c | 10278 | (match_operand:SI 1 "" "")) |
886c62d1 | 10279 | (set (reg:SI 7) (plus:SI (reg:SI 7) |
90d10fb9 | 10280 | (match_operand:SI 2 "immediate_operand" "i")))] |
1e07edd3 | 10281 | "!TARGET_64BIT" |
886c62d1 JVA |
10282 | "* |
10283 | { | |
e1ff012c | 10284 | if (constant_call_address_operand (operands[0], Pmode)) |
94bb5d0c RH |
10285 | { |
10286 | if (SIBLING_CALL_P (insn)) | |
10287 | return \"jmp\\t%P0\"; | |
10288 | else | |
10289 | return \"call\\t%P0\"; | |
10290 | } | |
94bb5d0c | 10291 | if (SIBLING_CALL_P (insn)) |
fb204271 | 10292 | return \"jmp\\t%A0\"; |
94bb5d0c | 10293 | else |
fb204271 | 10294 | return \"call\\t%A0\"; |
e075ae69 RH |
10295 | }" |
10296 | [(set_attr "type" "call")]) | |
886c62d1 | 10297 | |
2bb7a0f5 | 10298 | (define_expand "call" |
cbbf65e0 RH |
10299 | [(call (match_operand:QI 0 "" "") |
10300 | (match_operand:SI 1 "" ""))] | |
2bb7a0f5 RS |
10301 | ;; Operand 1 not used on the i386. |
10302 | "" | |
10303 | " | |
10304 | { | |
b848ded1 JH |
10305 | /* Static functions and indirect calls don't need |
10306 | current_function_uses_pic_offset_table. */ | |
10307 | if (flag_pic | |
2a4bbffa RH |
10308 | && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF |
10309 | && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0))) | |
2bb7a0f5 | 10310 | current_function_uses_pic_offset_table = 1; |
e1ff012c | 10311 | if (! call_insn_operand (XEXP (operands[0], 0), Pmode)) |
cbbf65e0 | 10312 | XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); |
2bb7a0f5 RS |
10313 | }") |
10314 | ||
94bb5d0c | 10315 | (define_insn "*call_0" |
e1ff012c | 10316 | [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) |
94bb5d0c RH |
10317 | (match_operand:SI 1 "" ""))] |
10318 | "" | |
10319 | "* | |
10320 | { | |
10321 | if (SIBLING_CALL_P (insn)) | |
10322 | return \"jmp\\t%P0\"; | |
10323 | else | |
10324 | return \"call\\t%P0\"; | |
10325 | }" | |
10326 | [(set_attr "type" "call")]) | |
10327 | ||
cbbf65e0 | 10328 | (define_insn "*call_1" |
e1ff012c | 10329 | [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) |
94bb5d0c | 10330 | (match_operand:SI 1 "" ""))] |
886c62d1 JVA |
10331 | "" |
10332 | "* | |
10333 | { | |
94bb5d0c | 10334 | if (constant_call_address_operand (operands[0], QImode)) |
cbbf65e0 RH |
10335 | { |
10336 | if (SIBLING_CALL_P (insn)) | |
10337 | return \"jmp\\t%P0\"; | |
10338 | else | |
10339 | return \"call\\t%P0\"; | |
10340 | } | |
cbbf65e0 | 10341 | if (SIBLING_CALL_P (insn)) |
fb204271 | 10342 | return \"jmp\\t%A0\"; |
cbbf65e0 | 10343 | else |
fb204271 | 10344 | return \"call\\t%A0\"; |
e075ae69 RH |
10345 | }" |
10346 | [(set_attr "type" "call")]) | |
886c62d1 JVA |
10347 | |
10348 | ;; Call subroutine, returning value in operand 0 | |
10349 | ;; (which must be a hard register). | |
10350 | ||
2bb7a0f5 RS |
10351 | (define_expand "call_value_pop" |
10352 | [(parallel [(set (match_operand 0 "" "") | |
cbbf65e0 RH |
10353 | (call (match_operand:QI 1 "" "") |
10354 | (match_operand:SI 2 "" ""))) | |
2bb7a0f5 RS |
10355 | (set (reg:SI 7) |
10356 | (plus:SI (reg:SI 7) | |
cbbf65e0 | 10357 | (match_operand:SI 4 "" "")))])] |
1e07edd3 | 10358 | "!TARGET_64BIT" |
2bb7a0f5 RS |
10359 | " |
10360 | { | |
35e2d030 RH |
10361 | if (operands[4] == const0_rtx) |
10362 | { | |
10363 | emit_insn (gen_call_value (operands[0], operands[1], operands[2])); | |
10364 | DONE; | |
10365 | } | |
b848ded1 JH |
10366 | /* Static functions and indirect calls don't need |
10367 | current_function_uses_pic_offset_table. */ | |
10368 | if (flag_pic | |
2a4bbffa RH |
10369 | && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF |
10370 | && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0))) | |
2bb7a0f5 | 10371 | current_function_uses_pic_offset_table = 1; |
e1ff012c | 10372 | if (! call_insn_operand (XEXP (operands[1], 0), Pmode)) |
cbbf65e0 | 10373 | XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); |
2bb7a0f5 RS |
10374 | }") |
10375 | ||
2bb7a0f5 RS |
10376 | (define_expand "call_value" |
10377 | [(set (match_operand 0 "" "") | |
cbbf65e0 RH |
10378 | (call (match_operand:QI 1 "" "") |
10379 | (match_operand:SI 2 "" "")))] | |
2bb7a0f5 RS |
10380 | ;; Operand 2 not used on the i386. |
10381 | "" | |
10382 | " | |
10383 | { | |
b848ded1 JH |
10384 | /* Static functions and indirect calls don't need |
10385 | current_function_uses_pic_offset_table. */ | |
10386 | if (flag_pic | |
2a4bbffa RH |
10387 | && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF |
10388 | && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0))) | |
2bb7a0f5 | 10389 | current_function_uses_pic_offset_table = 1; |
e1ff012c | 10390 | if (! call_insn_operand (XEXP (operands[1], 0), Pmode)) |
cbbf65e0 | 10391 | XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); |
2bb7a0f5 RS |
10392 | }") |
10393 | ||
b840bfb0 MM |
10394 | ;; Call subroutine returning any type. |
10395 | ||
576182a3 | 10396 | (define_expand "untyped_call" |
b840bfb0 | 10397 | [(parallel [(call (match_operand 0 "" "") |
576182a3 | 10398 | (const_int 0)) |
b840bfb0 | 10399 | (match_operand 1 "" "") |
576182a3 TW |
10400 | (match_operand 2 "" "")])] |
10401 | "" | |
10402 | " | |
10403 | { | |
b840bfb0 | 10404 | int i; |
576182a3 | 10405 | |
d8b679b9 RK |
10406 | /* In order to give reg-stack an easier job in validating two |
10407 | coprocessor registers as containing a possible return value, | |
10408 | simply pretend the untyped call returns a complex long double | |
10409 | value. */ | |
74775c7a | 10410 | |
d8b679b9 | 10411 | emit_call_insn (TARGET_80387 |
f64cecad JC |
10412 | ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG), |
10413 | operands[0], const0_rtx) | |
d8b679b9 | 10414 | : gen_call (operands[0], const0_rtx)); |
576182a3 | 10415 | |
b840bfb0 | 10416 | for (i = 0; i < XVECLEN (operands[2], 0); i++) |
576182a3 | 10417 | { |
b840bfb0 MM |
10418 | rtx set = XVECEXP (operands[2], 0, i); |
10419 | emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
576182a3 | 10420 | } |
576182a3 | 10421 | |
b840bfb0 MM |
10422 | /* The optimizer does not know that the call sets the function value |
10423 | registers we stored in the result block. We avoid problems by | |
10424 | claiming that all hard registers are used and clobbered at this | |
10425 | point. */ | |
10426 | emit_insn (gen_blockage ()); | |
576182a3 TW |
10427 | |
10428 | DONE; | |
10429 | }") | |
e075ae69 RH |
10430 | \f |
10431 | ;; Prologue and epilogue instructions | |
576182a3 | 10432 | |
b840bfb0 MM |
10433 | ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and |
10434 | ;; all of memory. This blocks insns from being moved across this point. | |
10435 | ||
10436 | (define_insn "blockage" | |
10437 | [(unspec_volatile [(const_int 0)] 0)] | |
576182a3 | 10438 | "" |
90aec2cf | 10439 | "" |
e075ae69 | 10440 | [(set_attr "length" "0")]) |
576182a3 | 10441 | |
886c62d1 JVA |
10442 | ;; Insn emitted into the body of a function to return from a function. |
10443 | ;; This is only done if the function's epilogue is known to be simple. | |
182a4620 | 10444 | ;; See comments for ix86_can_use_return_insn_p in i386.c. |
886c62d1 | 10445 | |
5f3d14e3 | 10446 | (define_expand "return" |
886c62d1 | 10447 | [(return)] |
5f3d14e3 | 10448 | "ix86_can_use_return_insn_p ()" |
9a7372d6 RH |
10449 | " |
10450 | { | |
10451 | if (current_function_pops_args) | |
10452 | { | |
10453 | rtx popc = GEN_INT (current_function_pops_args); | |
10454 | emit_jump_insn (gen_return_pop_internal (popc)); | |
10455 | DONE; | |
10456 | } | |
10457 | }") | |
5f3d14e3 SC |
10458 | |
10459 | (define_insn "return_internal" | |
10460 | [(return)] | |
10461 | "reload_completed" | |
90aec2cf | 10462 | "ret" |
6ef67412 JH |
10463 | [(set_attr "length" "1") |
10464 | (set_attr "length_immediate" "0") | |
10465 | (set_attr "modrm" "0")]) | |
5f3d14e3 | 10466 | |
6cd96118 SC |
10467 | (define_insn "return_pop_internal" |
10468 | [(return) | |
10469 | (use (match_operand:SI 0 "const_int_operand" ""))] | |
10470 | "reload_completed" | |
e075ae69 | 10471 | "ret\\t%0" |
6ef67412 JH |
10472 | [(set_attr "length" "3") |
10473 | (set_attr "length_immediate" "2") | |
10474 | (set_attr "modrm" "0")]) | |
6cd96118 | 10475 | |
11837777 RH |
10476 | (define_insn "return_indirect_internal" |
10477 | [(return) | |
10478 | (use (match_operand:SI 0 "register_operand" "r"))] | |
10479 | "reload_completed" | |
fb204271 | 10480 | "jmp\\t%A0" |
11837777 RH |
10481 | [(set_attr "type" "ibr") |
10482 | (set_attr "length_immediate" "0")]) | |
10483 | ||
5f3d14e3 SC |
10484 | (define_insn "nop" |
10485 | [(const_int 0)] | |
10486 | "" | |
90aec2cf | 10487 | "nop" |
e075ae69 | 10488 | [(set_attr "length" "1") |
6ef67412 JH |
10489 | (set_attr "length_immediate" "0") |
10490 | (set_attr "modrm" "0") | |
e075ae69 | 10491 | (set_attr "ppro_uops" "one")]) |
5f3d14e3 SC |
10492 | |
10493 | (define_expand "prologue" | |
10494 | [(const_int 1)] | |
10495 | "" | |
e075ae69 | 10496 | "ix86_expand_prologue (); DONE;") |
5f3d14e3 | 10497 | |
e075ae69 | 10498 | (define_insn "prologue_set_got" |
69404d6f | 10499 | [(set (match_operand:SI 0 "register_operand" "=r") |
c76aab11 | 10500 | (unspec_volatile:SI |
e075ae69 RH |
10501 | [(plus:SI (match_dup 0) |
10502 | (plus:SI (match_operand:SI 1 "symbolic_operand" "") | |
10503 | (minus:SI (pc) (match_operand 2 "" ""))))] 1)) | |
10504 | (clobber (reg:CC 17))] | |
47d36400 BS |
10505 | "" |
10506 | "* | |
10507 | { | |
e075ae69 RH |
10508 | if (GET_CODE (operands[2]) == LABEL_REF) |
10509 | operands[2] = XEXP (operands[2], 0); | |
10510 | if (TARGET_DEEP_BRANCH_PREDICTION) | |
10511 | return \"add{l}\\t{%1, %0|%0, %1}\"; | |
10512 | else | |
10513 | return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\"; | |
90aec2cf | 10514 | }" |
6ef67412 | 10515 | [(set_attr "type" "alu") |
d731a1da JH |
10516 | ; Since this insn may have two constant operands, we must set the |
10517 | ; length manually. | |
10518 | (set_attr "length_immediate" "4") | |
6ef67412 | 10519 | (set_attr "mode" "SI")]) |
47d36400 | 10520 | |
e075ae69 | 10521 | (define_insn "prologue_get_pc" |
69404d6f | 10522 | [(set (match_operand:SI 0 "register_operand" "=r") |
c76aab11 | 10523 | (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))] |
1e07edd3 | 10524 | "!TARGET_64BIT" |
886c62d1 JVA |
10525 | "* |
10526 | { | |
e075ae69 RH |
10527 | if (GET_CODE (operands[1]) == LABEL_REF) |
10528 | operands[1] = XEXP (operands[1], 0); | |
10529 | output_asm_insn (\"call\\t%X1\", operands); | |
10530 | if (! TARGET_DEEP_BRANCH_PREDICTION) | |
10531 | { | |
10532 | ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", | |
10533 | CODE_LABEL_NUMBER (operands[1])); | |
10534 | } | |
10535 | RET; | |
10536 | }" | |
10537 | [(set_attr "type" "multi")]) | |
5f3d14e3 | 10538 | |
e075ae69 RH |
10539 | (define_expand "epilogue" |
10540 | [(const_int 1)] | |
10541 | "" | |
cbbf65e0 RH |
10542 | "ix86_expand_epilogue (1); DONE;") |
10543 | ||
10544 | (define_expand "sibcall_epilogue" | |
10545 | [(const_int 1)] | |
10546 | "" | |
10547 | "ix86_expand_epilogue (0); DONE;") | |
e075ae69 RH |
10548 | |
10549 | (define_insn "leave" | |
10550 | [(set (reg:SI 7) (reg:SI 6)) | |
10551 | (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))] | |
1e07edd3 | 10552 | "!TARGET_64BIT" |
e075ae69 | 10553 | "leave" |
6ef67412 JH |
10554 | [(set_attr "length_immediate" "0") |
10555 | (set_attr "length" "1") | |
10556 | (set_attr "modrm" "0") | |
10557 | (set_attr "modrm" "0") | |
0b5107cf | 10558 | (set_attr "athlon_decode" "vector") |
e075ae69 RH |
10559 | (set_attr "ppro_uops" "few")]) |
10560 | \f | |
10561 | (define_expand "ffssi2" | |
4cbfbb1b | 10562 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
e075ae69 RH |
10563 | (ffs:SI (match_operand:SI 1 "general_operand" "")))] |
10564 | "" | |
10565 | " | |
10566 | { | |
10567 | rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode); | |
10568 | rtx in = operands[1]; | |
10569 | ||
10570 | if (TARGET_CMOVE) | |
5f3d14e3 | 10571 | { |
e075ae69 RH |
10572 | emit_move_insn (tmp, constm1_rtx); |
10573 | emit_insn (gen_ffssi_1 (out, in)); | |
10574 | emit_insn (gen_rtx_SET (VOIDmode, out, | |
10575 | gen_rtx_IF_THEN_ELSE (SImode, | |
16189740 | 10576 | gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG), |
e075ae69 RH |
10577 | const0_rtx), |
10578 | tmp, | |
10579 | out))); | |
e0dc26ff JH |
10580 | emit_insn (gen_addsi3 (out, out, const1_rtx)); |
10581 | emit_move_insn (operands[0], out); | |
10582 | } | |
10583 | ||
16189740 RH |
10584 | /* Pentium bsf instruction is extremly slow. The following code is |
10585 | recommended by the Intel Optimizing Manual as a reasonable replacement: | |
e0dc26ff JH |
10586 | TEST EAX,EAX |
10587 | JZ SHORT BS2 | |
10588 | XOR ECX,ECX | |
10589 | MOV DWORD PTR [TEMP+4],ECX | |
10590 | SUB ECX,EAX | |
10591 | AND EAX,ECX | |
10592 | MOV DWORD PTR [TEMP],EAX | |
10593 | FILD QWORD PTR [TEMP] | |
10594 | FSTP QWORD PTR [TEMP] | |
10595 | WAIT ; WAIT only needed for compatibility with | |
10596 | ; earlier processors | |
10597 | MOV ECX, DWORD PTR [TEMP+4] | |
10598 | SHR ECX,20 | |
10599 | SUB ECX,3FFH | |
10600 | TEST EAX,EAX ; clear zero flag | |
10601 | BS2: | |
10602 | Following piece of code expand ffs to similar beast. | |
10603 | */ | |
10604 | ||
10605 | else if (TARGET_PENTIUM && !optimize_size && TARGET_80387) | |
10606 | { | |
10607 | rtx label = gen_label_rtx (); | |
10608 | rtx lo, hi; | |
10609 | rtx mem = assign_386_stack_local (DImode, 0); | |
10610 | rtx fptmp = gen_reg_rtx (DFmode); | |
10611 | split_di (&mem, 1, &lo, &hi); | |
10612 | ||
10613 | emit_move_insn (out, const0_rtx); | |
10614 | ||
10615 | emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label); | |
10616 | ||
10617 | emit_move_insn (hi, out); | |
10618 | emit_insn (gen_subsi3 (out, out, in)); | |
10619 | emit_insn (gen_andsi3 (out, out, in)); | |
10620 | emit_move_insn (lo, out); | |
10621 | emit_insn (gen_floatdidf2 (fptmp,mem)); | |
10622 | emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp); | |
10623 | emit_move_insn (out, hi); | |
10624 | emit_insn (gen_lshrsi3 (out, out, GEN_INT (20))); | |
16189740 | 10625 | emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1))); |
e0dc26ff JH |
10626 | |
10627 | emit_label (label); | |
10628 | LABEL_NUSES (label) = 1; | |
10629 | ||
10630 | emit_move_insn (operands[0], out); | |
5f3d14e3 | 10631 | } |
e075ae69 | 10632 | else |
5f3d14e3 | 10633 | { |
e075ae69 RH |
10634 | emit_move_insn (tmp, const0_rtx); |
10635 | emit_insn (gen_ffssi_1 (out, in)); | |
10636 | emit_insn (gen_rtx_SET (VOIDmode, | |
10637 | gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)), | |
16189740 | 10638 | gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG), |
e075ae69 RH |
10639 | const0_rtx))); |
10640 | emit_insn (gen_negsi2 (tmp, tmp)); | |
10641 | emit_insn (gen_iorsi3 (out, out, tmp)); | |
e0dc26ff JH |
10642 | emit_insn (gen_addsi3 (out, out, const1_rtx)); |
10643 | emit_move_insn (operands[0], out); | |
e075ae69 | 10644 | } |
e075ae69 | 10645 | DONE; |
886c62d1 JVA |
10646 | }") |
10647 | ||
e075ae69 | 10648 | (define_insn "ffssi_1" |
16189740 RH |
10649 | [(set (reg:CCZ 17) |
10650 | (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") | |
10651 | (const_int 0))) | |
e075ae69 RH |
10652 | (set (match_operand:SI 0 "register_operand" "=r") |
10653 | (unspec:SI [(match_dup 1)] 5))] | |
10654 | "" | |
10655 | "bsf{l}\\t{%1, %0|%0, %1}" | |
6ef67412 | 10656 | [(set_attr "prefix_0f" "1") |
e075ae69 RH |
10657 | (set_attr "ppro_uops" "few")]) |
10658 | ||
10659 | ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger | |
10660 | ;; and slower than the two-byte movzx insn needed to do the work in SImode. | |
10661 | \f | |
10662 | ;; These patterns match the binary 387 instructions for addM3, subM3, | |
10663 | ;; mulM3 and divM3. There are three patterns for each of DFmode and | |
10664 | ;; SFmode. The first is the normal insn, the second the same insn but | |
10665 | ;; with one operand a conversion, and the third the same insn but with | |
10666 | ;; the other operand a conversion. The conversion may be SFmode or | |
10667 | ;; SImode if the target mode DFmode, but only SImode if the target mode | |
10668 | ;; is SFmode. | |
10669 | ||
caa6ec8d JH |
10670 | ;; Gcc is slightly more smart about handling normal two address instructions |
10671 | ;; so use special patterns for add and mull. | |
10672 | (define_insn "*fop_sf_comm" | |
1deaa899 | 10673 | [(set (match_operand:SF 0 "register_operand" "=f#x,x#f") |
caa6ec8d | 10674 | (match_operator:SF 3 "binary_fp_operator" |
1deaa899 JH |
10675 | [(match_operand:SF 1 "register_operand" "%0,0") |
10676 | (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))] | |
10677 | "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387) | |
10678 | && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'" | |
caa6ec8d JH |
10679 | "* return output_387_binary_op (insn, operands);" |
10680 | [(set (attr "type") | |
1deaa899 JH |
10681 | (if_then_else (eq_attr "alternative" "1") |
10682 | (const_string "sse") | |
10683 | (if_then_else (match_operand:SF 3 "mult_operator" "") | |
10684 | (const_string "fmul") | |
10685 | (const_string "fop")))) | |
10686 | (set_attr "mode" "SF")]) | |
10687 | ||
10688 | (define_insn "*fop_sf_comm_sse" | |
10689 | [(set (match_operand:SF 0 "register_operand" "=x") | |
10690 | (match_operator:SF 3 "binary_fp_operator" | |
10691 | [(match_operand:SF 1 "register_operand" "%0") | |
10692 | (match_operand:SF 2 "nonimmediate_operand" "xm")]))] | |
10693 | "TARGET_SSE && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'" | |
10694 | "* return output_387_binary_op (insn, operands);" | |
10695 | [(set_attr "type" "sse") | |
6ef67412 | 10696 | (set_attr "mode" "SF")]) |
caa6ec8d JH |
10697 | |
10698 | (define_insn "*fop_df_comm" | |
1deaa899 | 10699 | [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f") |
caa6ec8d | 10700 | (match_operator:DF 3 "binary_fp_operator" |
1deaa899 JH |
10701 | [(match_operand:DF 1 "register_operand" "%0,0") |
10702 | (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))] | |
10703 | "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387) | |
10704 | && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'" | |
caa6ec8d JH |
10705 | "* return output_387_binary_op (insn, operands);" |
10706 | [(set (attr "type") | |
1deaa899 JH |
10707 | (if_then_else (eq_attr "alternative" "1") |
10708 | (const_string "sse") | |
10709 | (if_then_else (match_operand:SF 3 "mult_operator" "") | |
10710 | (const_string "fmul") | |
10711 | (const_string "fop")))) | |
10712 | (set_attr "mode" "DF")]) | |
10713 | ||
10714 | (define_insn "*fop_df_comm_sse" | |
10715 | [(set (match_operand:DF 0 "register_operand" "=Y") | |
10716 | (match_operator:DF 3 "binary_fp_operator" | |
10717 | [(match_operand:DF 1 "register_operand" "%0") | |
10718 | (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] | |
10719 | "TARGET_SSE2 | |
10720 | && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'" | |
10721 | "* return output_387_binary_op (insn, operands);" | |
10722 | [(set_attr "type" "sse") | |
6ef67412 | 10723 | (set_attr "mode" "DF")]) |
caa6ec8d JH |
10724 | |
10725 | (define_insn "*fop_xf_comm" | |
10726 | [(set (match_operand:XF 0 "register_operand" "=f") | |
10727 | (match_operator:XF 3 "binary_fp_operator" | |
10728 | [(match_operand:XF 1 "register_operand" "%0") | |
10729 | (match_operand:XF 2 "register_operand" "f")]))] | |
1e07edd3 JH |
10730 | "TARGET_80387 && !TARGET_64BIT |
10731 | && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'" | |
caa6ec8d JH |
10732 | "* return output_387_binary_op (insn, operands);" |
10733 | [(set (attr "type") | |
10734 | (if_then_else (match_operand:XF 3 "mult_operator" "") | |
10735 | (const_string "fmul") | |
6ef67412 JH |
10736 | (const_string "fop"))) |
10737 | (set_attr "mode" "XF")]) | |
caa6ec8d | 10738 | |
2b589241 JH |
10739 | (define_insn "*fop_tf_comm" |
10740 | [(set (match_operand:TF 0 "register_operand" "=f") | |
10741 | (match_operator:TF 3 "binary_fp_operator" | |
10742 | [(match_operand:TF 1 "register_operand" "%0") | |
10743 | (match_operand:TF 2 "register_operand" "f")]))] | |
10744 | "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'" | |
10745 | "* return output_387_binary_op (insn, operands);" | |
10746 | [(set (attr "type") | |
10747 | (if_then_else (match_operand:TF 3 "mult_operator" "") | |
10748 | (const_string "fmul") | |
10749 | (const_string "fop"))) | |
10750 | (set_attr "mode" "XF")]) | |
10751 | ||
e075ae69 | 10752 | (define_insn "*fop_sf_1" |
1deaa899 | 10753 | [(set (match_operand:SF 0 "register_operand" "=f,f,x") |
e075ae69 | 10754 | (match_operator:SF 3 "binary_fp_operator" |
1deaa899 JH |
10755 | [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0") |
10756 | (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))] | |
10757 | "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387) | |
caa6ec8d | 10758 | && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c' |
f97d9ec3 | 10759 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" |
e075ae69 RH |
10760 | "* return output_387_binary_op (insn, operands);" |
10761 | [(set (attr "type") | |
1deaa899 JH |
10762 | (cond [(eq_attr "alternative" "2") |
10763 | (const_string "sse") | |
10764 | (match_operand:SF 3 "mult_operator" "") | |
e075ae69 RH |
10765 | (const_string "fmul") |
10766 | (match_operand:SF 3 "div_operator" "") | |
10767 | (const_string "fdiv") | |
10768 | ] | |
6ef67412 JH |
10769 | (const_string "fop"))) |
10770 | (set_attr "mode" "SF")]) | |
e075ae69 | 10771 | |
1deaa899 JH |
10772 | (define_insn "*fop_sf_1_sse" |
10773 | [(set (match_operand:SF 0 "register_operand" "=x") | |
10774 | (match_operator:SF 3 "binary_fp_operator" | |
10775 | [(match_operand:SF 1 "register_operand" "0") | |
10776 | (match_operand:SF 2 "nonimmediate_operand" "xm")]))] | |
10777 | "TARGET_SSE | |
10778 | && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'" | |
10779 | "* return output_387_binary_op (insn, operands);" | |
10780 | [(set_attr "type" "sse") | |
10781 | (set_attr "mode" "SF")]) | |
10782 | ||
10783 | ;; ??? Add SSE splitters for these! | |
e075ae69 RH |
10784 | (define_insn "*fop_sf_2" |
10785 | [(set (match_operand:SF 0 "register_operand" "=f,f") | |
10786 | (match_operator:SF 3 "binary_fp_operator" | |
10787 | [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")) | |
10788 | (match_operand:SF 2 "register_operand" "0,0")]))] | |
1deaa899 | 10789 | "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE" |
e075ae69 RH |
10790 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
10791 | [(set (attr "type") | |
10792 | (cond [(match_operand:SF 3 "mult_operator" "") | |
10793 | (const_string "fmul") | |
10794 | (match_operand:SF 3 "div_operator" "") | |
10795 | (const_string "fdiv") | |
10796 | ] | |
10797 | (const_string "fop"))) | |
10798 | (set_attr "fp_int_src" "true") | |
6ef67412 JH |
10799 | (set_attr "ppro_uops" "many") |
10800 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
10801 | |
10802 | (define_insn "*fop_sf_3" | |
10803 | [(set (match_operand:SF 0 "register_operand" "=f,f") | |
10804 | (match_operator:SF 3 "binary_fp_operator" | |
10805 | [(match_operand:SF 1 "register_operand" "0,0") | |
10806 | (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))] | |
1deaa899 | 10807 | "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE" |
e075ae69 RH |
10808 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
10809 | [(set (attr "type") | |
10810 | (cond [(match_operand:SF 3 "mult_operator" "") | |
10811 | (const_string "fmul") | |
10812 | (match_operand:SF 3 "div_operator" "") | |
10813 | (const_string "fdiv") | |
10814 | ] | |
10815 | (const_string "fop"))) | |
10816 | (set_attr "fp_int_src" "true") | |
6ef67412 JH |
10817 | (set_attr "ppro_uops" "many") |
10818 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
10819 | |
10820 | (define_insn "*fop_df_1" | |
1deaa899 | 10821 | [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f") |
e075ae69 | 10822 | (match_operator:DF 3 "binary_fp_operator" |
1deaa899 JH |
10823 | [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0") |
10824 | (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))] | |
10825 | "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387) | |
caa6ec8d | 10826 | && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c' |
f97d9ec3 | 10827 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" |
e075ae69 RH |
10828 | "* return output_387_binary_op (insn, operands);" |
10829 | [(set (attr "type") | |
1deaa899 JH |
10830 | (cond [(eq_attr "alternative" "2") |
10831 | (const_string "sse") | |
10832 | (match_operand:DF 3 "mult_operator" "") | |
e075ae69 RH |
10833 | (const_string "fmul") |
10834 | (match_operand:DF 3 "div_operator" "") | |
10835 | (const_string "fdiv") | |
10836 | ] | |
6ef67412 JH |
10837 | (const_string "fop"))) |
10838 | (set_attr "mode" "DF")]) | |
e075ae69 | 10839 | |
1deaa899 JH |
10840 | (define_insn "*fop_df_1_sse" |
10841 | [(set (match_operand:DF 0 "register_operand" "=Y") | |
10842 | (match_operator:DF 3 "binary_fp_operator" | |
10843 | [(match_operand:DF 1 "register_operand" "0") | |
10844 | (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] | |
10845 | "TARGET_SSE | |
10846 | && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'" | |
10847 | "* return output_387_binary_op (insn, operands);" | |
10848 | [(set_attr "type" "sse")]) | |
10849 | ||
10850 | ;; ??? Add SSE splitters for these! | |
e075ae69 RH |
10851 | (define_insn "*fop_df_2" |
10852 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
10853 | (match_operator:DF 3 "binary_fp_operator" | |
10854 | [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")) | |
10855 | (match_operand:DF 2 "register_operand" "0,0")]))] | |
1deaa899 | 10856 | "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2" |
e075ae69 RH |
10857 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
10858 | [(set (attr "type") | |
10859 | (cond [(match_operand:DF 3 "mult_operator" "") | |
10860 | (const_string "fmul") | |
10861 | (match_operand:DF 3 "div_operator" "") | |
10862 | (const_string "fdiv") | |
10863 | ] | |
10864 | (const_string "fop"))) | |
10865 | (set_attr "fp_int_src" "true") | |
6ef67412 JH |
10866 | (set_attr "ppro_uops" "many") |
10867 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
10868 | |
10869 | (define_insn "*fop_df_3" | |
10870 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
10871 | (match_operator:DF 3 "binary_fp_operator" | |
10872 | [(match_operand:DF 1 "register_operand" "0,0") | |
10873 | (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))] | |
1deaa899 | 10874 | "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2" |
e075ae69 RH |
10875 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
10876 | [(set (attr "type") | |
10877 | (cond [(match_operand:DF 3 "mult_operator" "") | |
10878 | (const_string "fmul") | |
10879 | (match_operand:DF 3 "div_operator" "") | |
10880 | (const_string "fdiv") | |
10881 | ] | |
10882 | (const_string "fop"))) | |
10883 | (set_attr "fp_int_src" "true") | |
6ef67412 JH |
10884 | (set_attr "ppro_uops" "many") |
10885 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
10886 | |
10887 | (define_insn "*fop_df_4" | |
10888 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
10889 | (match_operator:DF 3 "binary_fp_operator" | |
10890 | [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) | |
10891 | (match_operand:DF 2 "register_operand" "0,f")]))] | |
f97d9ec3 JH |
10892 | "TARGET_80387 |
10893 | && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" | |
e075ae69 RH |
10894 | "* return output_387_binary_op (insn, operands);" |
10895 | [(set (attr "type") | |
10896 | (cond [(match_operand:DF 3 "mult_operator" "") | |
10897 | (const_string "fmul") | |
10898 | (match_operand:DF 3 "div_operator" "") | |
10899 | (const_string "fdiv") | |
10900 | ] | |
6ef67412 JH |
10901 | (const_string "fop"))) |
10902 | (set_attr "mode" "SF")]) | |
e075ae69 RH |
10903 | |
10904 | (define_insn "*fop_df_5" | |
10905 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
10906 | (match_operator:DF 3 "binary_fp_operator" | |
10907 | [(match_operand:DF 1 "register_operand" "0,f") | |
10908 | (float_extend:DF | |
10909 | (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] | |
1deaa899 | 10910 | "TARGET_80387 && !TARGET_SSE2" |
e075ae69 RH |
10911 | "* return output_387_binary_op (insn, operands);" |
10912 | [(set (attr "type") | |
10913 | (cond [(match_operand:DF 3 "mult_operator" "") | |
10914 | (const_string "fmul") | |
10915 | (match_operand:DF 3 "div_operator" "") | |
10916 | (const_string "fdiv") | |
10917 | ] | |
6ef67412 JH |
10918 | (const_string "fop"))) |
10919 | (set_attr "mode" "SF")]) | |
e075ae69 RH |
10920 | |
10921 | (define_insn "*fop_xf_1" | |
10922 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
10923 | (match_operator:XF 3 "binary_fp_operator" | |
10924 | [(match_operand:XF 1 "register_operand" "0,f") | |
10925 | (match_operand:XF 2 "register_operand" "f,0")]))] | |
1e07edd3 | 10926 | "TARGET_80387 && !TARGET_64BIT |
caa6ec8d | 10927 | && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'" |
e075ae69 RH |
10928 | "* return output_387_binary_op (insn, operands);" |
10929 | [(set (attr "type") | |
ca285e07 | 10930 | (cond [(match_operand:XF 3 "mult_operator" "") |
e075ae69 | 10931 | (const_string "fmul") |
ca285e07 | 10932 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
10933 | (const_string "fdiv") |
10934 | ] | |
6ef67412 JH |
10935 | (const_string "fop"))) |
10936 | (set_attr "mode" "XF")]) | |
e075ae69 | 10937 | |
2b589241 JH |
10938 | (define_insn "*fop_tf_1" |
10939 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
10940 | (match_operator:TF 3 "binary_fp_operator" | |
10941 | [(match_operand:TF 1 "register_operand" "0,f") | |
10942 | (match_operand:TF 2 "register_operand" "f,0")]))] | |
10943 | "TARGET_80387 | |
10944 | && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'" | |
10945 | "* return output_387_binary_op (insn, operands);" | |
10946 | [(set (attr "type") | |
10947 | (cond [(match_operand:TF 3 "mult_operator" "") | |
10948 | (const_string "fmul") | |
10949 | (match_operand:TF 3 "div_operator" "") | |
10950 | (const_string "fdiv") | |
10951 | ] | |
10952 | (const_string "fop"))) | |
10953 | (set_attr "mode" "XF")]) | |
10954 | ||
e075ae69 RH |
10955 | (define_insn "*fop_xf_2" |
10956 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
10957 | (match_operator:XF 3 "binary_fp_operator" | |
10958 | [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")) | |
10959 | (match_operand:XF 2 "register_operand" "0,0")]))] | |
1e07edd3 | 10960 | "TARGET_80387 && !TARGET_64BIT && TARGET_USE_FIOP" |
e075ae69 RH |
10961 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
10962 | [(set (attr "type") | |
ca285e07 | 10963 | (cond [(match_operand:XF 3 "mult_operator" "") |
e075ae69 | 10964 | (const_string "fmul") |
ca285e07 | 10965 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
10966 | (const_string "fdiv") |
10967 | ] | |
10968 | (const_string "fop"))) | |
10969 | (set_attr "fp_int_src" "true") | |
6ef67412 | 10970 | (set_attr "mode" "SI") |
e075ae69 RH |
10971 | (set_attr "ppro_uops" "many")]) |
10972 | ||
2b589241 JH |
10973 | (define_insn "*fop_tf_2" |
10974 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
10975 | (match_operator:TF 3 "binary_fp_operator" | |
10976 | [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r")) | |
10977 | (match_operand:TF 2 "register_operand" "0,0")]))] | |
10978 | "TARGET_80387 && TARGET_USE_FIOP" | |
10979 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" | |
10980 | [(set (attr "type") | |
10981 | (cond [(match_operand:TF 3 "mult_operator" "") | |
10982 | (const_string "fmul") | |
10983 | (match_operand:TF 3 "div_operator" "") | |
10984 | (const_string "fdiv") | |
10985 | ] | |
10986 | (const_string "fop"))) | |
10987 | (set_attr "fp_int_src" "true") | |
10988 | (set_attr "mode" "SI") | |
10989 | (set_attr "ppro_uops" "many")]) | |
10990 | ||
e075ae69 RH |
10991 | (define_insn "*fop_xf_3" |
10992 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
10993 | (match_operator:XF 3 "binary_fp_operator" | |
10994 | [(match_operand:XF 1 "register_operand" "0,0") | |
10995 | (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))] | |
1e07edd3 | 10996 | "TARGET_80387 && !TARGET_64BIT && TARGET_USE_FIOP" |
e075ae69 RH |
10997 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
10998 | [(set (attr "type") | |
ca285e07 | 10999 | (cond [(match_operand:XF 3 "mult_operator" "") |
e075ae69 | 11000 | (const_string "fmul") |
ca285e07 | 11001 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
11002 | (const_string "fdiv") |
11003 | ] | |
11004 | (const_string "fop"))) | |
11005 | (set_attr "fp_int_src" "true") | |
6ef67412 | 11006 | (set_attr "mode" "SI") |
e075ae69 RH |
11007 | (set_attr "ppro_uops" "many")]) |
11008 | ||
2b589241 JH |
11009 | (define_insn "*fop_tf_3" |
11010 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
11011 | (match_operator:TF 3 "binary_fp_operator" | |
11012 | [(match_operand:TF 1 "register_operand" "0,0") | |
11013 | (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))] | |
11014 | "TARGET_80387 && TARGET_USE_FIOP" | |
11015 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" | |
11016 | [(set (attr "type") | |
11017 | (cond [(match_operand:TF 3 "mult_operator" "") | |
11018 | (const_string "fmul") | |
11019 | (match_operand:TF 3 "div_operator" "") | |
11020 | (const_string "fdiv") | |
11021 | ] | |
11022 | (const_string "fop"))) | |
11023 | (set_attr "fp_int_src" "true") | |
11024 | (set_attr "mode" "SI") | |
11025 | (set_attr "ppro_uops" "many")]) | |
11026 | ||
e075ae69 RH |
11027 | (define_insn "*fop_xf_4" |
11028 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
11029 | (match_operator:XF 3 "binary_fp_operator" | |
11030 | [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) | |
11031 | (match_operand:XF 2 "register_operand" "0,f")]))] | |
1e07edd3 | 11032 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
11033 | "* return output_387_binary_op (insn, operands);" |
11034 | [(set (attr "type") | |
ca285e07 | 11035 | (cond [(match_operand:XF 3 "mult_operator" "") |
e075ae69 | 11036 | (const_string "fmul") |
ca285e07 | 11037 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
11038 | (const_string "fdiv") |
11039 | ] | |
6ef67412 JH |
11040 | (const_string "fop"))) |
11041 | (set_attr "mode" "SF")]) | |
e075ae69 | 11042 | |
2b589241 JH |
11043 | (define_insn "*fop_tf_4" |
11044 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
11045 | (match_operator:TF 3 "binary_fp_operator" | |
11046 | [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) | |
11047 | (match_operand:TF 2 "register_operand" "0,f")]))] | |
11048 | "TARGET_80387" | |
11049 | "* return output_387_binary_op (insn, operands);" | |
11050 | [(set (attr "type") | |
11051 | (cond [(match_operand:TF 3 "mult_operator" "") | |
11052 | (const_string "fmul") | |
11053 | (match_operand:TF 3 "div_operator" "") | |
11054 | (const_string "fdiv") | |
11055 | ] | |
11056 | (const_string "fop"))) | |
11057 | (set_attr "mode" "SF")]) | |
11058 | ||
e075ae69 RH |
11059 | (define_insn "*fop_xf_5" |
11060 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
11061 | (match_operator:XF 3 "binary_fp_operator" | |
11062 | [(match_operand:XF 1 "register_operand" "0,f") | |
11063 | (float_extend:XF | |
11064 | (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] | |
1e07edd3 | 11065 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
11066 | "* return output_387_binary_op (insn, operands);" |
11067 | [(set (attr "type") | |
ca285e07 | 11068 | (cond [(match_operand:XF 3 "mult_operator" "") |
e075ae69 | 11069 | (const_string "fmul") |
ca285e07 | 11070 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
11071 | (const_string "fdiv") |
11072 | ] | |
6ef67412 JH |
11073 | (const_string "fop"))) |
11074 | (set_attr "mode" "SF")]) | |
e075ae69 | 11075 | |
2b589241 JH |
11076 | (define_insn "*fop_tf_5" |
11077 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
11078 | (match_operator:TF 3 "binary_fp_operator" | |
11079 | [(match_operand:TF 1 "register_operand" "0,f") | |
11080 | (float_extend:TF | |
11081 | (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] | |
11082 | "TARGET_80387" | |
11083 | "* return output_387_binary_op (insn, operands);" | |
11084 | [(set (attr "type") | |
11085 | (cond [(match_operand:TF 3 "mult_operator" "") | |
11086 | (const_string "fmul") | |
11087 | (match_operand:TF 3 "div_operator" "") | |
11088 | (const_string "fdiv") | |
11089 | ] | |
11090 | (const_string "fop"))) | |
11091 | (set_attr "mode" "SF")]) | |
11092 | ||
e075ae69 RH |
11093 | (define_insn "*fop_xf_6" |
11094 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
11095 | (match_operator:XF 3 "binary_fp_operator" | |
11096 | [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0")) | |
11097 | (match_operand:XF 2 "register_operand" "0,f")]))] | |
1e07edd3 | 11098 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
11099 | "* return output_387_binary_op (insn, operands);" |
11100 | [(set (attr "type") | |
ca285e07 | 11101 | (cond [(match_operand:XF 3 "mult_operator" "") |
e075ae69 | 11102 | (const_string "fmul") |
ca285e07 | 11103 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
11104 | (const_string "fdiv") |
11105 | ] | |
6ef67412 JH |
11106 | (const_string "fop"))) |
11107 | (set_attr "mode" "DF")]) | |
e075ae69 | 11108 | |
2b589241 JH |
11109 | (define_insn "*fop_tf_6" |
11110 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
11111 | (match_operator:TF 3 "binary_fp_operator" | |
11112 | [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0")) | |
11113 | (match_operand:TF 2 "register_operand" "0,f")]))] | |
11114 | "TARGET_80387" | |
11115 | "* return output_387_binary_op (insn, operands);" | |
11116 | [(set (attr "type") | |
11117 | (cond [(match_operand:TF 3 "mult_operator" "") | |
11118 | (const_string "fmul") | |
11119 | (match_operand:TF 3 "div_operator" "") | |
11120 | (const_string "fdiv") | |
11121 | ] | |
11122 | (const_string "fop"))) | |
11123 | (set_attr "mode" "DF")]) | |
11124 | ||
e075ae69 RH |
11125 | (define_insn "*fop_xf_7" |
11126 | [(set (match_operand:XF 0 "register_operand" "=f,f") | |
11127 | (match_operator:XF 3 "binary_fp_operator" | |
11128 | [(match_operand:XF 1 "register_operand" "0,f") | |
11129 | (float_extend:XF | |
11130 | (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))] | |
1e07edd3 | 11131 | "TARGET_80387 && !TARGET_64BIT" |
e075ae69 RH |
11132 | "* return output_387_binary_op (insn, operands);" |
11133 | [(set (attr "type") | |
ca285e07 | 11134 | (cond [(match_operand:XF 3 "mult_operator" "") |
e075ae69 | 11135 | (const_string "fmul") |
ca285e07 | 11136 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
11137 | (const_string "fdiv") |
11138 | ] | |
6ef67412 JH |
11139 | (const_string "fop"))) |
11140 | (set_attr "mode" "DF")]) | |
e075ae69 | 11141 | |
2b589241 JH |
11142 | (define_insn "*fop_tf_7" |
11143 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
11144 | (match_operator:TF 3 "binary_fp_operator" | |
11145 | [(match_operand:TF 1 "register_operand" "0,f") | |
11146 | (float_extend:TF | |
11147 | (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))] | |
11148 | "TARGET_80387" | |
11149 | "* return output_387_binary_op (insn, operands);" | |
11150 | [(set (attr "type") | |
11151 | (cond [(match_operand:TF 3 "mult_operator" "") | |
11152 | (const_string "fmul") | |
11153 | (match_operand:TF 3 "div_operator" "") | |
11154 | (const_string "fdiv") | |
11155 | ] | |
11156 | (const_string "fop"))) | |
11157 | (set_attr "mode" "DF")]) | |
11158 | ||
e075ae69 RH |
11159 | (define_split |
11160 | [(set (match_operand 0 "register_operand" "") | |
11161 | (match_operator 3 "binary_fp_operator" | |
11162 | [(float (match_operand:SI 1 "register_operand" "")) | |
11163 | (match_operand 2 "register_operand" "")]))] | |
11164 | "TARGET_80387 && reload_completed | |
11165 | && FLOAT_MODE_P (GET_MODE (operands[0]))" | |
4211a8fb JH |
11166 | [(const_int 0)] |
11167 | " | |
11168 | { | |
11169 | operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); | |
11170 | operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); | |
11171 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
11172 | gen_rtx_fmt_ee (GET_CODE (operands[3]), | |
11173 | GET_MODE (operands[3]), | |
11174 | operands[4], | |
11175 | operands[2]))); | |
11176 | ix86_free_from_memory (GET_MODE (operands[1])); | |
11177 | DONE; | |
11178 | }") | |
e075ae69 RH |
11179 | |
11180 | (define_split | |
11181 | [(set (match_operand 0 "register_operand" "") | |
11182 | (match_operator 3 "binary_fp_operator" | |
11183 | [(match_operand 1 "register_operand" "") | |
11184 | (float (match_operand:SI 2 "register_operand" ""))]))] | |
11185 | "TARGET_80387 && reload_completed | |
11186 | && FLOAT_MODE_P (GET_MODE (operands[0]))" | |
4211a8fb JH |
11187 | [(const_int 0)] |
11188 | " | |
11189 | { | |
11190 | operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); | |
11191 | operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); | |
11192 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
2b66da3c | 11193 | gen_rtx_fmt_ee (GET_CODE (operands[3]), |
4211a8fb JH |
11194 | GET_MODE (operands[3]), |
11195 | operands[1], | |
11196 | operands[4]))); | |
11197 | ix86_free_from_memory (GET_MODE (operands[2])); | |
11198 | DONE; | |
11199 | }") | |
e075ae69 RH |
11200 | \f |
11201 | ;; FPU special functions. | |
11202 | ||
a8083431 JH |
11203 | (define_expand "sqrtsf2" |
11204 | [(set (match_operand:SF 0 "register_operand" "") | |
11205 | (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))] | |
ca9a9b12 | 11206 | "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE" |
a8083431 JH |
11207 | " |
11208 | { | |
11209 | if (!TARGET_SSE) | |
11210 | operands[1] = force_reg (SFmode, operands[1]); | |
11211 | }") | |
11212 | ||
11213 | (define_insn "sqrtsf2_1" | |
ca9a9b12 JH |
11214 | [(set (match_operand:SF 0 "register_operand" "=f#x,x#f") |
11215 | (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))] | |
a8083431 JH |
11216 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11217 | && (TARGET_SSE && TARGET_MIX_SSE_I387)" | |
11218 | "@ | |
11219 | fsqrt | |
11220 | sqrtss\\t{%1, %0|%0, %1}" | |
11221 | [(set_attr "type" "fpspc,sse") | |
11222 | (set_attr "mode" "SF,SF") | |
11223 | (set_attr "athlon_decode" "direct,*")]) | |
11224 | ||
11225 | (define_insn "sqrtsf2_1_sse_only" | |
ca9a9b12 JH |
11226 | [(set (match_operand:SF 0 "register_operand" "=x") |
11227 | (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))] | |
a8083431 JH |
11228 | "TARGET_SSE && (!TARGET_80387 || !TARGET_MIX_SSE_I387)" |
11229 | "sqrtss\\t{%1, %0|%0, %1}" | |
11230 | [(set_attr "type" "sse") | |
11231 | (set_attr "mode" "SF") | |
11232 | (set_attr "athlon_decode" "*")]) | |
11233 | ||
11234 | (define_insn "sqrtsf2_i387" | |
e075ae69 RH |
11235 | [(set (match_operand:SF 0 "register_operand" "=f") |
11236 | (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] | |
a8083431 JH |
11237 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11238 | && (!TARGET_SSE && !TARGET_MIX_SSE_I387)" | |
e075ae69 | 11239 | "fsqrt" |
0b5107cf | 11240 | [(set_attr "type" "fpspc") |
6ef67412 | 11241 | (set_attr "mode" "SF") |
0b5107cf | 11242 | (set_attr "athlon_decode" "direct")]) |
e075ae69 | 11243 | |
a8083431 JH |
11244 | (define_expand "sqrtdf2" |
11245 | [(set (match_operand:DF 0 "register_operand" "") | |
11246 | (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))] | |
11247 | "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE2" | |
11248 | " | |
11249 | { | |
11250 | if (!TARGET_SSE2) | |
11251 | operands[1] = force_reg (SFmode, operands[1]); | |
11252 | }") | |
11253 | ||
11254 | (define_insn "sqrtdf2_1" | |
11255 | [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f") | |
11256 | (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))] | |
11257 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 | |
11258 | && (TARGET_SSE2 && TARGET_MIX_SSE_I387)" | |
11259 | "@ | |
11260 | fsqrt | |
11261 | sqrtsd\\t{%1, %0|%0, %1}" | |
11262 | [(set_attr "type" "fpspc,sse") | |
11263 | (set_attr "mode" "DF,DF") | |
11264 | (set_attr "athlon_decode" "direct,*")]) | |
11265 | ||
11266 | (define_insn "sqrtdf2_1_sse_only" | |
11267 | [(set (match_operand:DF 0 "register_operand" "=Y") | |
11268 | (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))] | |
11269 | "TARGET_SSE2 && (!TARGET_80387 || !TARGET_MIX_SSE_I387)" | |
11270 | "sqrtsd\\t{%1, %0|%0, %1}" | |
11271 | [(set_attr "type" "sse") | |
11272 | (set_attr "mode" "DF") | |
11273 | (set_attr "athlon_decode" "*")]) | |
11274 | ||
11275 | (define_insn "sqrtdf2_i387" | |
e075ae69 RH |
11276 | [(set (match_operand:DF 0 "register_operand" "=f") |
11277 | (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] | |
11278 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 | |
a8083431 | 11279 | && (!TARGET_SSE2 && !TARGET_MIX_SSE_I387)" |
e075ae69 | 11280 | "fsqrt" |
0b5107cf | 11281 | [(set_attr "type" "fpspc") |
6ef67412 | 11282 | (set_attr "mode" "DF") |
0b5107cf | 11283 | (set_attr "athlon_decode" "direct")]) |
e075ae69 | 11284 | |
6343a50e | 11285 | (define_insn "*sqrtextendsfdf2" |
e075ae69 RH |
11286 | [(set (match_operand:DF 0 "register_operand" "=f") |
11287 | (sqrt:DF (float_extend:DF | |
11288 | (match_operand:SF 1 "register_operand" "0"))))] | |
ca9a9b12 | 11289 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_SSE2" |
e075ae69 | 11290 | "fsqrt" |
0b5107cf | 11291 | [(set_attr "type" "fpspc") |
6ef67412 | 11292 | (set_attr "mode" "DF") |
0b5107cf | 11293 | (set_attr "athlon_decode" "direct")]) |
e075ae69 RH |
11294 | |
11295 | (define_insn "sqrtxf2" | |
11296 | [(set (match_operand:XF 0 "register_operand" "=f") | |
11297 | (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] | |
1e07edd3 | 11298 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT |
de6c5979 | 11299 | && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) " |
e075ae69 | 11300 | "fsqrt" |
0b5107cf | 11301 | [(set_attr "type" "fpspc") |
6ef67412 | 11302 | (set_attr "mode" "XF") |
0b5107cf | 11303 | (set_attr "athlon_decode" "direct")]) |
e075ae69 | 11304 | |
2b589241 JH |
11305 | (define_insn "sqrttf2" |
11306 | [(set (match_operand:TF 0 "register_operand" "=f") | |
11307 | (sqrt:TF (match_operand:TF 1 "register_operand" "0")))] | |
11308 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 | |
de6c5979 | 11309 | && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) " |
2b589241 JH |
11310 | "fsqrt" |
11311 | [(set_attr "type" "fpspc") | |
11312 | (set_attr "mode" "XF") | |
11313 | (set_attr "athlon_decode" "direct")]) | |
11314 | ||
6343a50e | 11315 | (define_insn "*sqrtextenddfxf2" |
e075ae69 RH |
11316 | [(set (match_operand:XF 0 "register_operand" "=f") |
11317 | (sqrt:XF (float_extend:XF | |
11318 | (match_operand:DF 1 "register_operand" "0"))))] | |
1e07edd3 | 11319 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT" |
e075ae69 | 11320 | "fsqrt" |
0b5107cf | 11321 | [(set_attr "type" "fpspc") |
6ef67412 | 11322 | (set_attr "mode" "XF") |
0b5107cf | 11323 | (set_attr "athlon_decode" "direct")]) |
e075ae69 | 11324 | |
2b589241 JH |
11325 | (define_insn "*sqrtextenddftf2" |
11326 | [(set (match_operand:TF 0 "register_operand" "=f") | |
11327 | (sqrt:TF (float_extend:TF | |
11328 | (match_operand:DF 1 "register_operand" "0"))))] | |
11329 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" | |
11330 | "fsqrt" | |
11331 | [(set_attr "type" "fpspc") | |
11332 | (set_attr "mode" "XF") | |
11333 | (set_attr "athlon_decode" "direct")]) | |
11334 | ||
6343a50e | 11335 | (define_insn "*sqrtextendsfxf2" |
e075ae69 RH |
11336 | [(set (match_operand:XF 0 "register_operand" "=f") |
11337 | (sqrt:XF (float_extend:XF | |
11338 | (match_operand:SF 1 "register_operand" "0"))))] | |
1e07edd3 | 11339 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT" |
e075ae69 | 11340 | "fsqrt" |
0b5107cf | 11341 | [(set_attr "type" "fpspc") |
6ef67412 | 11342 | (set_attr "mode" "XF") |
0b5107cf | 11343 | (set_attr "athlon_decode" "direct")]) |
e075ae69 | 11344 | |
2b589241 JH |
11345 | (define_insn "*sqrtextendsftf2" |
11346 | [(set (match_operand:TF 0 "register_operand" "=f") | |
11347 | (sqrt:TF (float_extend:TF | |
11348 | (match_operand:SF 1 "register_operand" "0"))))] | |
11349 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" | |
11350 | "fsqrt" | |
11351 | [(set_attr "type" "fpspc") | |
11352 | (set_attr "mode" "XF") | |
11353 | (set_attr "athlon_decode" "direct")]) | |
11354 | ||
e075ae69 RH |
11355 | (define_insn "sindf2" |
11356 | [(set (match_operand:DF 0 "register_operand" "=f") | |
11357 | (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))] | |
de6c5979 BL |
11358 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11359 | && flag_unsafe_math_optimizations" | |
e075ae69 | 11360 | "fsin" |
6ef67412 JH |
11361 | [(set_attr "type" "fpspc") |
11362 | (set_attr "mode" "DF")]) | |
e075ae69 RH |
11363 | |
11364 | (define_insn "sinsf2" | |
11365 | [(set (match_operand:SF 0 "register_operand" "=f") | |
11366 | (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))] | |
de6c5979 BL |
11367 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11368 | && flag_unsafe_math_optimizations" | |
e075ae69 | 11369 | "fsin" |
6ef67412 JH |
11370 | [(set_attr "type" "fpspc") |
11371 | (set_attr "mode" "SF")]) | |
5f3d14e3 | 11372 | |
6343a50e | 11373 | (define_insn "*sinextendsfdf2" |
e075ae69 RH |
11374 | [(set (match_operand:DF 0 "register_operand" "=f") |
11375 | (unspec:DF [(float_extend:DF | |
11376 | (match_operand:SF 1 "register_operand" "0"))] 1))] | |
de6c5979 BL |
11377 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11378 | && flag_unsafe_math_optimizations" | |
e075ae69 | 11379 | "fsin" |
6ef67412 JH |
11380 | [(set_attr "type" "fpspc") |
11381 | (set_attr "mode" "DF")]) | |
4f9ca067 | 11382 | |
e075ae69 RH |
11383 | (define_insn "sinxf2" |
11384 | [(set (match_operand:XF 0 "register_operand" "=f") | |
11385 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))] | |
1e07edd3 | 11386 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT |
de6c5979 | 11387 | && flag_unsafe_math_optimizations" |
e075ae69 | 11388 | "fsin" |
6ef67412 JH |
11389 | [(set_attr "type" "fpspc") |
11390 | (set_attr "mode" "XF")]) | |
5f3d14e3 | 11391 | |
2b589241 JH |
11392 | (define_insn "sintf2" |
11393 | [(set (match_operand:TF 0 "register_operand" "=f") | |
11394 | (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))] | |
de6c5979 BL |
11395 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11396 | && flag_unsafe_math_optimizations" | |
2b589241 JH |
11397 | "fsin" |
11398 | [(set_attr "type" "fpspc") | |
11399 | (set_attr "mode" "XF")]) | |
11400 | ||
e075ae69 RH |
11401 | (define_insn "cosdf2" |
11402 | [(set (match_operand:DF 0 "register_operand" "=f") | |
11403 | (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))] | |
de6c5979 BL |
11404 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11405 | && flag_unsafe_math_optimizations" | |
e075ae69 | 11406 | "fcos" |
6ef67412 JH |
11407 | [(set_attr "type" "fpspc") |
11408 | (set_attr "mode" "DF")]) | |
bca7cce2 | 11409 | |
e075ae69 RH |
11410 | (define_insn "cossf2" |
11411 | [(set (match_operand:SF 0 "register_operand" "=f") | |
11412 | (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))] | |
de6c5979 BL |
11413 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11414 | && flag_unsafe_math_optimizations" | |
e075ae69 | 11415 | "fcos" |
6ef67412 JH |
11416 | [(set_attr "type" "fpspc") |
11417 | (set_attr "mode" "SF")]) | |
bca7cce2 | 11418 | |
6343a50e | 11419 | (define_insn "*cosextendsfdf2" |
e075ae69 RH |
11420 | [(set (match_operand:DF 0 "register_operand" "=f") |
11421 | (unspec:DF [(float_extend:DF | |
11422 | (match_operand:SF 1 "register_operand" "0"))] 2))] | |
de6c5979 BL |
11423 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11424 | && flag_unsafe_math_optimizations" | |
e075ae69 | 11425 | "fcos" |
6ef67412 JH |
11426 | [(set_attr "type" "fpspc") |
11427 | (set_attr "mode" "DF")]) | |
5f3d14e3 | 11428 | |
e075ae69 RH |
11429 | (define_insn "cosxf2" |
11430 | [(set (match_operand:XF 0 "register_operand" "=f") | |
11431 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))] | |
1e07edd3 | 11432 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
de6c5979 | 11433 | && flag_unsafe_math_optimizations" |
e075ae69 | 11434 | "fcos" |
6ef67412 JH |
11435 | [(set_attr "type" "fpspc") |
11436 | (set_attr "mode" "XF")]) | |
2b589241 JH |
11437 | |
11438 | (define_insn "costf2" | |
11439 | [(set (match_operand:TF 0 "register_operand" "=f") | |
11440 | (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))] | |
de6c5979 BL |
11441 | "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 |
11442 | && flag_unsafe_math_optimizations" | |
2b589241 JH |
11443 | "fcos" |
11444 | [(set_attr "type" "fpspc") | |
11445 | (set_attr "mode" "XF")]) | |
e075ae69 RH |
11446 | \f |
11447 | ;; Block operation instructions | |
886c62d1 | 11448 | |
7c7ef435 JH |
11449 | (define_insn "cld" |
11450 | [(set (reg:SI 19) (const_int 0))] | |
11451 | "" | |
11452 | "cld" | |
11453 | [(set_attr "type" "cld")]) | |
11454 | ||
886c62d1 | 11455 | (define_expand "movstrsi" |
f90800f8 JH |
11456 | [(use (match_operand:BLK 0 "memory_operand" "")) |
11457 | (use (match_operand:BLK 1 "memory_operand" "")) | |
79f05c19 | 11458 | (use (match_operand:SI 2 "nonmemory_operand" "")) |
f90800f8 | 11459 | (use (match_operand:SI 3 "const_int_operand" ""))] |
886c62d1 JVA |
11460 | "" |
11461 | " | |
11462 | { | |
f90800f8 | 11463 | rtx srcreg, destreg, countreg; |
79f05c19 JH |
11464 | int align = 0; |
11465 | int count = -1; | |
0e4970d7 RK |
11466 | rtx insns; |
11467 | ||
11468 | start_sequence (); | |
664921b4 | 11469 | |
79f05c19 JH |
11470 | if (GET_CODE (operands[3]) == CONST_INT) |
11471 | align = INTVAL (operands[3]); | |
11472 | ||
11473 | /* This simple hack avoids all inlining code and simplifies code bellow. */ | |
11474 | if (!TARGET_ALIGN_STRINGOPS) | |
11475 | align = 32; | |
11476 | ||
11477 | if (GET_CODE (operands[2]) == CONST_INT) | |
11478 | count = INTVAL (operands[2]); | |
664921b4 | 11479 | |
f90800f8 JH |
11480 | destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); |
11481 | srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); | |
664921b4 | 11482 | |
0e4970d7 | 11483 | emit_insn (gen_cld ()); |
79f05c19 | 11484 | |
e2e52e1b JH |
11485 | /* When optimizing for size emit simple rep ; movsb instruction for |
11486 | counts not divisible by 4. */ | |
79f05c19 JH |
11487 | |
11488 | if ((!optimize || optimize_size) | |
11489 | && (count < 0 || (count & 0x03))) | |
f90800f8 JH |
11490 | { |
11491 | countreg = copy_to_mode_reg (SImode, operands[2]); | |
11492 | emit_insn (gen_rep_movqi (destreg, srcreg, countreg, | |
11493 | destreg, srcreg, countreg)); | |
11494 | } | |
79f05c19 JH |
11495 | |
11496 | /* For constant aligned (or small unaligned) copies use rep movsl | |
11497 | followed by code copying the rest. For PentiumPro ensure 8 byte | |
11498 | alignment to allow rep movsl acceleration. */ | |
11499 | ||
11500 | else if (count >= 0 | |
11501 | && (align >= 8 | |
11502 | || (!TARGET_PENTIUMPRO && align >= 4) | |
11503 | || optimize_size || count < 64)) | |
f90800f8 | 11504 | { |
79f05c19 | 11505 | if (count & ~0x03) |
f90800f8 JH |
11506 | { |
11507 | countreg = copy_to_mode_reg (SImode, | |
79f05c19 | 11508 | GEN_INT ((count >> 2) |
f90800f8 JH |
11509 | & 0x3fffffff)); |
11510 | emit_insn (gen_rep_movsi (destreg, srcreg, countreg, | |
11511 | destreg, srcreg, countreg)); | |
11512 | } | |
79f05c19 | 11513 | if (count & 0x02) |
f90800f8 | 11514 | emit_insn (gen_strmovhi (destreg, srcreg)); |
79f05c19 | 11515 | if (count & 0x01) |
f90800f8 JH |
11516 | emit_insn (gen_strmovqi (destreg, srcreg)); |
11517 | } | |
79f05c19 JH |
11518 | /* The generic code based on the glibc implementation: |
11519 | - align destination to 4 bytes (8 byte alignment is used for PentiumPro | |
11520 | allowing accelerated copying there) | |
11521 | - copy the data using rep movsl | |
11522 | - copy the rest. */ | |
11523 | else | |
11524 | { | |
11525 | rtx countreg2; | |
11526 | rtx label = NULL; | |
11527 | ||
11528 | /* In case we don't know anything about the alignment, default to | |
11529 | library version, since it is usually equally fast and result in | |
11530 | shorter code. */ | |
11531 | if (!TARGET_INLINE_ALL_STRINGOPS && align < 4) | |
4ddb47b3 RK |
11532 | { |
11533 | end_sequence (); | |
11534 | FAIL; | |
11535 | } | |
79f05c19 JH |
11536 | |
11537 | if (TARGET_SINGLE_STRINGOP) | |
4ddb47b3 | 11538 | emit_insn (gen_cld ()); |
79f05c19 JH |
11539 | |
11540 | countreg2 = gen_reg_rtx (SImode); | |
11541 | countreg = copy_to_mode_reg (SImode, operands[2]); | |
11542 | ||
11543 | /* We don't use loops to align destination and to copy parts smaller | |
11544 | than 4 bytes, because gcc is able to optimize such code better (in | |
11545 | the case the destination or the count really is aligned, gcc is often | |
11546 | able to predict the branches) and also it is friendlier to the | |
11547 | hardware branch prediction. | |
11548 | ||
11549 | Using loops is benefical for generic case, because we can | |
11550 | handle small counts using the loops. Many CPUs (such as Athlon) | |
11551 | have large REP prefix setup costs. | |
11552 | ||
11553 | This is quite costy. Maybe we can revisit this decision later or | |
11554 | add some customizability to this code. */ | |
11555 | ||
11556 | if (count < 0 | |
11557 | && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4)) | |
11558 | { | |
11559 | label = gen_label_rtx (); | |
11560 | emit_cmp_and_jump_insns (countreg, GEN_INT (3), | |
11561 | LEU, 0, SImode, 1, 0, label); | |
11562 | } | |
11563 | if (align <= 1) | |
11564 | { | |
11565 | rtx label = gen_label_rtx (); | |
11566 | rtx tmpcount = gen_reg_rtx (SImode); | |
11567 | emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1))); | |
11568 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11569 | SImode, 1, 0, label); | |
11570 | emit_insn (gen_strmovqi (destreg, srcreg)); | |
11571 | emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx)); | |
11572 | emit_label (label); | |
11573 | LABEL_NUSES (label) = 1; | |
11574 | } | |
11575 | if (align <= 2) | |
11576 | { | |
11577 | rtx label = gen_label_rtx (); | |
11578 | rtx tmpcount = gen_reg_rtx (SImode); | |
11579 | emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2))); | |
11580 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11581 | SImode, 1, 0, label); | |
11582 | emit_insn (gen_strmovhi (destreg, srcreg)); | |
11583 | emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2))); | |
11584 | emit_label (label); | |
11585 | LABEL_NUSES (label) = 1; | |
11586 | } | |
11587 | if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260)) | |
11588 | { | |
11589 | rtx label = gen_label_rtx (); | |
11590 | rtx tmpcount = gen_reg_rtx (SImode); | |
11591 | emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4))); | |
11592 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11593 | SImode, 1, 0, label); | |
11594 | emit_insn (gen_strmovsi (destreg, srcreg)); | |
11595 | emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4))); | |
11596 | emit_label (label); | |
11597 | LABEL_NUSES (label) = 1; | |
11598 | } | |
11599 | ||
11600 | if (!TARGET_SINGLE_STRINGOP) | |
11601 | emit_insn (gen_cld()); | |
11602 | emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2))); | |
11603 | emit_insn (gen_rep_movsi (destreg, srcreg, countreg2, | |
11604 | destreg, srcreg, countreg2)); | |
11605 | ||
11606 | if (label) | |
11607 | { | |
11608 | emit_label (label); | |
11609 | LABEL_NUSES (label) = 1; | |
11610 | } | |
11611 | if (align > 2 && count > 0 && (count & 2)) | |
11612 | emit_insn (gen_strmovhi (destreg, srcreg)); | |
11613 | if (align <= 2 || count < 0) | |
11614 | { | |
11615 | rtx label = gen_label_rtx (); | |
11616 | rtx tmpcount = gen_reg_rtx (SImode); | |
11617 | emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2))); | |
11618 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11619 | SImode, 1, 0, label); | |
11620 | emit_insn (gen_strmovhi (destreg, srcreg)); | |
11621 | emit_label (label); | |
11622 | LABEL_NUSES (label) = 1; | |
11623 | } | |
11624 | if (align > 1 && count > 0 && (count & 1)) | |
11625 | emit_insn (gen_strmovsi (destreg, srcreg)); | |
11626 | if (align <= 1 || count < 0) | |
11627 | { | |
11628 | rtx label = gen_label_rtx (); | |
11629 | rtx tmpcount = gen_reg_rtx (SImode); | |
11630 | emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1))); | |
11631 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11632 | SImode, 1, 0, label); | |
11633 | emit_insn (gen_strmovqi (destreg, srcreg)); | |
11634 | emit_label (label); | |
11635 | LABEL_NUSES (label) = 1; | |
11636 | } | |
11637 | } | |
0e4970d7 RK |
11638 | |
11639 | insns = get_insns (); | |
11640 | end_sequence (); | |
11641 | ||
11642 | ix86_set_move_mem_attrs (insns, operands[0], operands[1], destreg, srcreg); | |
11643 | emit_insns (insns); | |
f90800f8 | 11644 | DONE; |
886c62d1 JVA |
11645 | }") |
11646 | ||
f90800f8 JH |
11647 | ;; Most CPUs don't like single string operations |
11648 | ;; Handle this case here to simplify previous expander. | |
56c0e8fa | 11649 | |
79f05c19 JH |
11650 | (define_expand "strmovsi" |
11651 | [(set (match_dup 2) | |
11652 | (mem:SI (match_operand:SI 1 "register_operand" ""))) | |
11653 | (set (mem:SI (match_operand:SI 0 "register_operand" "")) | |
11654 | (match_dup 2)) | |
11655 | (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4))) | |
11656 | (clobber (reg:CC 17))]) | |
11657 | (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4))) | |
11658 | (clobber (reg:CC 17))])] | |
11659 | "" | |
11660 | " | |
11661 | { | |
11662 | if (TARGET_SINGLE_STRINGOP || optimize_size) | |
11663 | { | |
11664 | emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0], | |
11665 | operands[1])); | |
11666 | DONE; | |
11667 | } | |
11668 | else | |
11669 | operands[2] = gen_reg_rtx (SImode); | |
11670 | }") | |
11671 | ||
f90800f8 JH |
11672 | (define_expand "strmovhi" |
11673 | [(set (match_dup 2) | |
11674 | (mem:HI (match_operand:SI 1 "register_operand" ""))) | |
11675 | (set (mem:HI (match_operand:SI 0 "register_operand" "")) | |
11676 | (match_dup 2)) | |
11677 | (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2))) | |
11678 | (clobber (reg:CC 17))]) | |
11679 | (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2))) | |
11680 | (clobber (reg:CC 17))])] | |
886c62d1 | 11681 | "" |
f90800f8 | 11682 | " |
886c62d1 | 11683 | { |
f90800f8 | 11684 | if (TARGET_SINGLE_STRINGOP || optimize_size) |
886c62d1 | 11685 | { |
f90800f8 JH |
11686 | emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0], |
11687 | operands[1])); | |
11688 | DONE; | |
11689 | } | |
11690 | else | |
11691 | operands[2] = gen_reg_rtx (HImode); | |
11692 | }") | |
886c62d1 | 11693 | |
f90800f8 JH |
11694 | (define_expand "strmovqi" |
11695 | [(set (match_dup 2) | |
11696 | (mem:QI (match_operand:SI 1 "register_operand" ""))) | |
11697 | (set (mem:QI (match_operand:SI 0 "register_operand" "")) | |
11698 | (match_dup 2)) | |
11699 | (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) | |
11700 | (clobber (reg:CC 17))]) | |
11701 | (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1))) | |
11702 | (clobber (reg:CC 17))])] | |
11703 | "" | |
11704 | " | |
11705 | { | |
11706 | if (TARGET_SINGLE_STRINGOP || optimize_size) | |
11707 | { | |
11708 | emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0], | |
11709 | operands[1])); | |
11710 | DONE; | |
886c62d1 | 11711 | } |
f90800f8 JH |
11712 | else |
11713 | operands[2] = gen_reg_rtx (QImode); | |
11714 | }") | |
11715 | ||
79f05c19 JH |
11716 | (define_insn "strmovsi_1" |
11717 | [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) | |
11718 | (mem:SI (match_operand:SI 3 "register_operand" "1"))) | |
11719 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 11720 | (plus:SI (match_dup 2) |
79f05c19 JH |
11721 | (const_int 4))) |
11722 | (set (match_operand:SI 1 "register_operand" "=S") | |
b1cdafbb | 11723 | (plus:SI (match_dup 3) |
79f05c19 JH |
11724 | (const_int 4))) |
11725 | (use (reg:SI 19))] | |
11726 | "TARGET_SINGLE_STRINGOP || optimize_size" | |
11727 | "movsl" | |
11728 | [(set_attr "type" "str") | |
6ef67412 | 11729 | (set_attr "mode" "SI") |
79f05c19 JH |
11730 | (set_attr "memory" "both")]) |
11731 | ||
f90800f8 JH |
11732 | (define_insn "strmovhi_1" |
11733 | [(set (mem:HI (match_operand:SI 2 "register_operand" "0")) | |
11734 | (mem:HI (match_operand:SI 3 "register_operand" "1"))) | |
11735 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 11736 | (plus:SI (match_dup 2) |
f90800f8 JH |
11737 | (const_int 2))) |
11738 | (set (match_operand:SI 1 "register_operand" "=S") | |
b1cdafbb | 11739 | (plus:SI (match_dup 3) |
f90800f8 JH |
11740 | (const_int 2))) |
11741 | (use (reg:SI 19))] | |
11742 | "TARGET_SINGLE_STRINGOP || optimize_size" | |
11743 | "movsw" | |
11744 | [(set_attr "type" "str") | |
11745 | (set_attr "memory" "both") | |
6ef67412 | 11746 | (set_attr "mode" "HI")]) |
f90800f8 JH |
11747 | |
11748 | (define_insn "strmovqi_1" | |
11749 | [(set (mem:QI (match_operand:SI 2 "register_operand" "0")) | |
11750 | (mem:QI (match_operand:SI 3 "register_operand" "1"))) | |
11751 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 11752 | (plus:SI (match_dup 2) |
f90800f8 JH |
11753 | (const_int 1))) |
11754 | (set (match_operand:SI 1 "register_operand" "=S") | |
b1cdafbb | 11755 | (plus:SI (match_dup 3) |
f90800f8 JH |
11756 | (const_int 1))) |
11757 | (use (reg:SI 19))] | |
11758 | "TARGET_SINGLE_STRINGOP || optimize_size" | |
11759 | "movsb" | |
11760 | [(set_attr "type" "str") | |
6ef67412 JH |
11761 | (set_attr "memory" "both") |
11762 | (set_attr "mode" "QI")]) | |
f90800f8 | 11763 | |
f90800f8 JH |
11764 | (define_insn "rep_movsi" |
11765 | [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) | |
f90800f8 | 11766 | (set (match_operand:SI 0 "register_operand" "=D") |
b1cdafbb JH |
11767 | (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2") |
11768 | (const_int 2)) | |
11769 | (match_operand:SI 3 "register_operand" "0"))) | |
f90800f8 | 11770 | (set (match_operand:SI 1 "register_operand" "=S") |
b1cdafbb JH |
11771 | (plus:SI (ashift:SI (match_dup 5) (const_int 2)) |
11772 | (match_operand:SI 4 "register_operand" "1"))) | |
f90800f8 JH |
11773 | (set (mem:BLK (match_dup 3)) |
11774 | (mem:BLK (match_dup 4))) | |
b1cdafbb | 11775 | (use (match_dup 5)) |
f90800f8 JH |
11776 | (use (reg:SI 19))] |
11777 | "" | |
11778 | "rep\;movsl|rep movsd" | |
11779 | [(set_attr "type" "str") | |
6ef67412 JH |
11780 | (set_attr "prefix_rep" "1") |
11781 | (set_attr "memory" "both") | |
11782 | (set_attr "mode" "SI")]) | |
f90800f8 JH |
11783 | |
11784 | (define_insn "rep_movqi" | |
11785 | [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) | |
f90800f8 | 11786 | (set (match_operand:SI 0 "register_operand" "=D") |
b1cdafbb JH |
11787 | (plus:SI (match_operand:SI 3 "register_operand" "0") |
11788 | (match_operand:SI 5 "register_operand" "2"))) | |
f90800f8 | 11789 | (set (match_operand:SI 1 "register_operand" "=S") |
b1cdafbb | 11790 | (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5))) |
f90800f8 JH |
11791 | (set (mem:BLK (match_dup 3)) |
11792 | (mem:BLK (match_dup 4))) | |
b1cdafbb | 11793 | (use (match_dup 5)) |
f90800f8 JH |
11794 | (use (reg:SI 19))] |
11795 | "" | |
11796 | "rep\;movsb|rep movsb" | |
11797 | [(set_attr "type" "str") | |
6ef67412 JH |
11798 | (set_attr "prefix_rep" "1") |
11799 | (set_attr "memory" "both") | |
11800 | (set_attr "mode" "SI")]) | |
886c62d1 | 11801 | |
0ae40045 | 11802 | (define_expand "clrstrsi" |
e2e52e1b | 11803 | [(use (match_operand:BLK 0 "memory_operand" "")) |
79f05c19 | 11804 | (use (match_operand:SI 1 "nonmemory_operand" "")) |
e2e52e1b | 11805 | (use (match_operand:SI 2 "const_int_operand" ""))] |
0ae40045 RK |
11806 | "" |
11807 | " | |
11808 | { | |
79f05c19 JH |
11809 | /* See comments in movstr expanders. The code is mostly identical. */ |
11810 | ||
e2e52e1b | 11811 | rtx destreg, zeroreg, countreg; |
79f05c19 JH |
11812 | int align = 0; |
11813 | int count = -1; | |
4082ab0f RK |
11814 | rtx insns; |
11815 | ||
11816 | start_sequence (); | |
0ae40045 | 11817 | |
79f05c19 JH |
11818 | if (GET_CODE (operands[2]) == CONST_INT) |
11819 | align = INTVAL (operands[2]); | |
11820 | ||
11821 | /* This simple hack avoids all inlining code and simplifies code bellow. */ | |
11822 | if (!TARGET_ALIGN_STRINGOPS) | |
11823 | align = 32; | |
11824 | ||
11825 | if (GET_CODE (operands[1]) == CONST_INT) | |
11826 | count = INTVAL (operands[1]); | |
0ae40045 | 11827 | |
e2e52e1b JH |
11828 | destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); |
11829 | ||
4082ab0f | 11830 | emit_insn (gen_cld ()); |
e2e52e1b JH |
11831 | |
11832 | /* When optimizing for size emit simple rep ; movsb instruction for | |
11833 | counts not divisible by 4. */ | |
79f05c19 JH |
11834 | |
11835 | if ((!optimize || optimize_size) | |
11836 | && (count < 0 || (count & 0x03))) | |
e2e52e1b JH |
11837 | { |
11838 | countreg = copy_to_mode_reg (SImode, operands[1]); | |
11839 | zeroreg = copy_to_mode_reg (QImode, const0_rtx); | |
11840 | emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg, | |
11841 | destreg, countreg)); | |
11842 | } | |
79f05c19 JH |
11843 | else if (count >= 0 |
11844 | && (align >= 8 | |
11845 | || (!TARGET_PENTIUMPRO && align >= 4) | |
11846 | || optimize_size || count < 64)) | |
e2e52e1b JH |
11847 | { |
11848 | zeroreg = copy_to_mode_reg (SImode, const0_rtx); | |
11849 | if (INTVAL (operands[1]) & ~0x03) | |
11850 | { | |
11851 | countreg = copy_to_mode_reg (SImode, | |
11852 | GEN_INT ((INTVAL (operands[1]) >> 2) | |
11853 | & 0x3fffffff)); | |
11854 | emit_insn (gen_rep_stossi (destreg, countreg, zeroreg, | |
11855 | destreg, countreg)); | |
11856 | } | |
11857 | if (INTVAL (operands[1]) & 0x02) | |
11858 | emit_insn (gen_strsethi (destreg, | |
11859 | gen_rtx_SUBREG (HImode, zeroreg, 0))); | |
11860 | if (INTVAL (operands[1]) & 0x01) | |
11861 | emit_insn (gen_strsetqi (destreg, | |
11862 | gen_rtx_SUBREG (QImode, zeroreg, 0))); | |
11863 | } | |
79f05c19 JH |
11864 | else |
11865 | { | |
11866 | rtx countreg2; | |
11867 | rtx label = NULL; | |
11868 | ||
11869 | /* In case we don't know anything about the alignment, default to | |
11870 | library version, since it is usually equally fast and result in | |
11871 | shorter code. */ | |
11872 | if (!TARGET_INLINE_ALL_STRINGOPS && align < 4) | |
4082ab0f RK |
11873 | { |
11874 | end_sequence (); | |
11875 | FAIL; | |
11876 | } | |
79f05c19 JH |
11877 | |
11878 | if (TARGET_SINGLE_STRINGOP) | |
4082ab0f | 11879 | emit_insn (gen_cld ()); |
79f05c19 JH |
11880 | |
11881 | countreg2 = gen_reg_rtx (SImode); | |
11882 | countreg = copy_to_mode_reg (SImode, operands[1]); | |
11883 | zeroreg = copy_to_mode_reg (SImode, const0_rtx); | |
11884 | ||
11885 | if (count < 0 | |
11886 | && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4)) | |
11887 | { | |
11888 | label = gen_label_rtx (); | |
11889 | emit_cmp_and_jump_insns (countreg, GEN_INT (3), | |
11890 | LEU, 0, SImode, 1, 0, label); | |
11891 | } | |
11892 | if (align <= 1) | |
11893 | { | |
11894 | rtx label = gen_label_rtx (); | |
11895 | rtx tmpcount = gen_reg_rtx (SImode); | |
11896 | emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1))); | |
11897 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11898 | SImode, 1, 0, label); | |
11899 | emit_insn (gen_strsetqi (destreg, | |
11900 | gen_rtx_SUBREG (QImode, zeroreg, 0))); | |
11901 | emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx)); | |
11902 | emit_label (label); | |
11903 | LABEL_NUSES (label) = 1; | |
11904 | } | |
11905 | if (align <= 2) | |
11906 | { | |
11907 | rtx label = gen_label_rtx (); | |
11908 | rtx tmpcount = gen_reg_rtx (SImode); | |
11909 | emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2))); | |
11910 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11911 | SImode, 1, 0, label); | |
11912 | emit_insn (gen_strsethi (destreg, | |
11913 | gen_rtx_SUBREG (HImode, zeroreg, 0))); | |
11914 | emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2))); | |
11915 | emit_label (label); | |
11916 | LABEL_NUSES (label) = 1; | |
11917 | } | |
11918 | if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260)) | |
11919 | { | |
11920 | rtx label = gen_label_rtx (); | |
11921 | rtx tmpcount = gen_reg_rtx (SImode); | |
11922 | emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4))); | |
11923 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11924 | SImode, 1, 0, label); | |
4a92092a | 11925 | emit_insn (gen_strsetsi (destreg, zeroreg)); |
79f05c19 JH |
11926 | emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4))); |
11927 | emit_label (label); | |
11928 | LABEL_NUSES (label) = 1; | |
11929 | } | |
11930 | ||
11931 | if (!TARGET_SINGLE_STRINGOP) | |
11932 | emit_insn (gen_cld()); | |
11933 | emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2))); | |
11934 | emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg, | |
11935 | destreg, countreg2)); | |
11936 | ||
11937 | if (label) | |
11938 | { | |
11939 | emit_label (label); | |
11940 | LABEL_NUSES (label) = 1; | |
11941 | } | |
11942 | if (align > 2 && count > 0 && (count & 2)) | |
11943 | emit_insn (gen_strsethi (destreg, | |
11944 | gen_rtx_SUBREG (HImode, zeroreg, 0))); | |
11945 | if (align <= 2 || count < 0) | |
11946 | { | |
11947 | rtx label = gen_label_rtx (); | |
11948 | rtx tmpcount = gen_reg_rtx (SImode); | |
11949 | emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2))); | |
11950 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11951 | SImode, 1, 0, label); | |
11952 | emit_insn (gen_strsethi (destreg, | |
11953 | gen_rtx_SUBREG (HImode, zeroreg, 0))); | |
11954 | emit_label (label); | |
11955 | LABEL_NUSES (label) = 1; | |
11956 | } | |
11957 | if (align > 1 && count > 0 && (count & 1)) | |
11958 | emit_insn (gen_strsetqi (destreg, | |
11959 | gen_rtx_SUBREG (QImode, zeroreg, 0))); | |
11960 | if (align <= 1 || count < 0) | |
11961 | { | |
11962 | rtx label = gen_label_rtx (); | |
11963 | rtx tmpcount = gen_reg_rtx (SImode); | |
11964 | emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1))); | |
11965 | emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0, | |
11966 | SImode, 1, 0, label); | |
11967 | emit_insn (gen_strsetqi (destreg, | |
11968 | gen_rtx_SUBREG (QImode, zeroreg, 0))); | |
11969 | emit_label (label); | |
11970 | LABEL_NUSES (label) = 1; | |
11971 | } | |
11972 | } | |
4082ab0f RK |
11973 | |
11974 | insns = get_insns (); | |
11975 | end_sequence (); | |
11976 | ||
11977 | ix86_set_move_mem_attrs (insns, operands[0], operands[0], destreg, destreg); | |
11978 | emit_insns (insns); | |
11979 | ||
e2e52e1b JH |
11980 | DONE; |
11981 | }") | |
11982 | ||
11983 | ;; Most CPUs don't like single string operations | |
11984 | ;; Handle this case here to simplify previous expander. | |
0ae40045 | 11985 | |
79f05c19 JH |
11986 | (define_expand "strsetsi" |
11987 | [(set (mem:SI (match_operand:SI 0 "register_operand" "")) | |
11988 | (match_operand:SI 1 "register_operand" "")) | |
11989 | (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4))) | |
11990 | (clobber (reg:CC 17))])] | |
11991 | "" | |
11992 | " | |
11993 | { | |
11994 | if (TARGET_SINGLE_STRINGOP || optimize_size) | |
11995 | { | |
11996 | emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1])); | |
11997 | DONE; | |
11998 | } | |
11999 | }") | |
12000 | ||
e2e52e1b JH |
12001 | (define_expand "strsethi" |
12002 | [(set (mem:HI (match_operand:SI 0 "register_operand" "")) | |
12003 | (match_operand:HI 1 "register_operand" "")) | |
12004 | (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2))) | |
12005 | (clobber (reg:CC 17))])] | |
12006 | "" | |
12007 | " | |
12008 | { | |
12009 | if (TARGET_SINGLE_STRINGOP || optimize_size) | |
12010 | { | |
12011 | emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1])); | |
12012 | DONE; | |
12013 | } | |
12014 | }") | |
0ae40045 | 12015 | |
e2e52e1b JH |
12016 | (define_expand "strsetqi" |
12017 | [(set (mem:QI (match_operand:SI 0 "register_operand" "")) | |
12018 | (match_operand:QI 1 "register_operand" "")) | |
12019 | (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) | |
12020 | (clobber (reg:CC 17))])] | |
12021 | "" | |
12022 | " | |
12023 | { | |
12024 | if (TARGET_SINGLE_STRINGOP || optimize_size) | |
12025 | { | |
12026 | emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1])); | |
12027 | DONE; | |
12028 | } | |
0ae40045 RK |
12029 | }") |
12030 | ||
79f05c19 JH |
12031 | (define_insn "strsetsi_1" |
12032 | [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) | |
12033 | (match_operand:SI 2 "register_operand" "a")) | |
12034 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 12035 | (plus:SI (match_dup 1) |
79f05c19 JH |
12036 | (const_int 4))) |
12037 | (use (reg:SI 19))] | |
12038 | "TARGET_SINGLE_STRINGOP || optimize_size" | |
12039 | "stosl" | |
12040 | [(set_attr "type" "str") | |
6ef67412 JH |
12041 | (set_attr "memory" "store") |
12042 | (set_attr "mode" "SI")]) | |
79f05c19 | 12043 | |
e2e52e1b JH |
12044 | (define_insn "strsethi_1" |
12045 | [(set (mem:HI (match_operand:SI 1 "register_operand" "0")) | |
12046 | (match_operand:HI 2 "register_operand" "a")) | |
12047 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 12048 | (plus:SI (match_dup 1) |
e2e52e1b JH |
12049 | (const_int 2))) |
12050 | (use (reg:SI 19))] | |
12051 | "TARGET_SINGLE_STRINGOP || optimize_size" | |
12052 | "stosw" | |
12053 | [(set_attr "type" "str") | |
12054 | (set_attr "memory" "store") | |
6ef67412 | 12055 | (set_attr "mode" "HI")]) |
e2e52e1b JH |
12056 | |
12057 | (define_insn "strsetqi_1" | |
12058 | [(set (mem:QI (match_operand:SI 1 "register_operand" "0")) | |
12059 | (match_operand:QI 2 "register_operand" "a")) | |
12060 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 12061 | (plus:SI (match_dup 1) |
e2e52e1b JH |
12062 | (const_int 1))) |
12063 | (use (reg:SI 19))] | |
12064 | "TARGET_SINGLE_STRINGOP || optimize_size" | |
12065 | "stosb" | |
12066 | [(set_attr "type" "str") | |
6ef67412 JH |
12067 | (set_attr "memory" "store") |
12068 | (set_attr "mode" "QI")]) | |
e2e52e1b | 12069 | |
e2e52e1b JH |
12070 | (define_insn "rep_stossi" |
12071 | [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) | |
e2e52e1b | 12072 | (set (match_operand:SI 0 "register_operand" "=D") |
b1cdafbb JH |
12073 | (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1") |
12074 | (const_int 2)) | |
12075 | (match_operand:SI 3 "register_operand" "0"))) | |
e2e52e1b | 12076 | (set (mem:BLK (match_dup 3)) |
0ae40045 | 12077 | (const_int 0)) |
b1cdafbb JH |
12078 | (use (match_operand:SI 2 "register_operand" "a")) |
12079 | (use (match_dup 4)) | |
e2e52e1b | 12080 | (use (reg:SI 19))] |
0ae40045 | 12081 | "" |
e2e52e1b JH |
12082 | "rep\;stosl|rep stosd" |
12083 | [(set_attr "type" "str") | |
6ef67412 JH |
12084 | (set_attr "prefix_rep" "1") |
12085 | (set_attr "memory" "store") | |
12086 | (set_attr "mode" "SI")]) | |
0ae40045 | 12087 | |
e2e52e1b JH |
12088 | (define_insn "rep_stosqi" |
12089 | [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) | |
e2e52e1b | 12090 | (set (match_operand:SI 0 "register_operand" "=D") |
b1cdafbb JH |
12091 | (plus:SI (match_operand:SI 3 "register_operand" "0") |
12092 | (match_operand:SI 4 "register_operand" "1"))) | |
e2e52e1b JH |
12093 | (set (mem:BLK (match_dup 3)) |
12094 | (const_int 0)) | |
b1cdafbb JH |
12095 | (use (match_operand:QI 2 "register_operand" "a")) |
12096 | (use (match_dup 4)) | |
e2e52e1b JH |
12097 | (use (reg:SI 19))] |
12098 | "" | |
12099 | "rep\;stosb|rep stosb" | |
12100 | [(set_attr "type" "str") | |
6ef67412 JH |
12101 | (set_attr "prefix_rep" "1") |
12102 | (set_attr "memory" "store") | |
12103 | (set_attr "mode" "QI")]) | |
0ae40045 | 12104 | |
886c62d1 | 12105 | (define_expand "cmpstrsi" |
e075ae69 RH |
12106 | [(set (match_operand:SI 0 "register_operand" "") |
12107 | (compare:SI (match_operand:BLK 1 "general_operand" "") | |
12108 | (match_operand:BLK 2 "general_operand" ""))) | |
12109 | (use (match_operand:SI 3 "general_operand" "")) | |
12110 | (use (match_operand:SI 4 "immediate_operand" ""))] | |
886c62d1 JVA |
12111 | "" |
12112 | " | |
12113 | { | |
e075ae69 RH |
12114 | rtx addr1, addr2, out, outlow, count, countreg, align; |
12115 | ||
12116 | out = operands[0]; | |
12117 | if (GET_CODE (out) != REG) | |
12118 | out = gen_reg_rtx (SImode); | |
783cdf65 JVA |
12119 | |
12120 | addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); | |
12121 | addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); | |
e075ae69 RH |
12122 | |
12123 | count = operands[3]; | |
12124 | countreg = copy_to_mode_reg (SImode, count); | |
12125 | ||
12126 | /* %%% Iff we are testing strict equality, we can use known alignment | |
12127 | to good advantage. This may be possible with combine, particularly | |
12128 | once cc0 is dead. */ | |
12129 | align = operands[4]; | |
783cdf65 | 12130 | |
7c7ef435 | 12131 | emit_insn (gen_cld ()); |
e075ae69 RH |
12132 | if (GET_CODE (count) == CONST_INT) |
12133 | { | |
12134 | if (INTVAL (count) == 0) | |
12135 | { | |
12136 | emit_move_insn (operands[0], const0_rtx); | |
12137 | DONE; | |
12138 | } | |
b1cdafbb JH |
12139 | emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align, |
12140 | addr1, addr2, countreg)); | |
e075ae69 RH |
12141 | } |
12142 | else | |
e2e52e1b JH |
12143 | { |
12144 | emit_insn (gen_cmpsi_1 (countreg, countreg)); | |
b1cdafbb JH |
12145 | emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align, |
12146 | addr1, addr2, countreg)); | |
e2e52e1b | 12147 | } |
e075ae69 RH |
12148 | |
12149 | outlow = gen_lowpart (QImode, out); | |
12150 | emit_insn (gen_cmpintqi (outlow)); | |
12151 | emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); | |
783cdf65 | 12152 | |
e075ae69 RH |
12153 | if (operands[0] != out) |
12154 | emit_move_insn (operands[0], out); | |
783cdf65 | 12155 | |
e075ae69 | 12156 | DONE; |
886c62d1 JVA |
12157 | }") |
12158 | ||
e075ae69 RH |
12159 | ;; Produce a tri-state integer (-1, 0, 1) from condition codes. |
12160 | ||
12161 | (define_expand "cmpintqi" | |
12162 | [(set (match_dup 1) | |
12163 | (gtu:QI (reg:CC 17) (const_int 0))) | |
12164 | (set (match_dup 2) | |
12165 | (ltu:QI (reg:CC 17) (const_int 0))) | |
12166 | (parallel [(set (match_operand:QI 0 "register_operand" "") | |
12167 | (minus:QI (match_dup 1) | |
12168 | (match_dup 2))) | |
12169 | (clobber (reg:CC 17))])] | |
12170 | "" | |
12171 | "operands[1] = gen_reg_rtx (QImode); | |
12172 | operands[2] = gen_reg_rtx (QImode);") | |
12173 | ||
f76e3b05 JVA |
12174 | ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is |
12175 | ;; zero. Emit extra code to make sure that a zero-length compare is EQ. | |
56c0e8fa | 12176 | |
e075ae69 RH |
12177 | (define_insn "cmpstrsi_nz_1" |
12178 | [(set (reg:CC 17) | |
b1cdafbb JH |
12179 | (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) |
12180 | (mem:BLK (match_operand:SI 5 "register_operand" "1")))) | |
12181 | (use (match_operand:SI 6 "register_operand" "2")) | |
886c62d1 | 12182 | (use (match_operand:SI 3 "immediate_operand" "i")) |
7c7ef435 | 12183 | (use (reg:SI 19)) |
b1cdafbb JH |
12184 | (clobber (match_operand:SI 0 "register_operand" "=S")) |
12185 | (clobber (match_operand:SI 1 "register_operand" "=D")) | |
12186 | (clobber (match_operand:SI 2 "register_operand" "=c"))] | |
886c62d1 | 12187 | "" |
7c7ef435 | 12188 | "repz{\;| }cmpsb" |
e2e52e1b | 12189 | [(set_attr "type" "str") |
6ef67412 JH |
12190 | (set_attr "mode" "QI") |
12191 | (set_attr "prefix_rep" "1")]) | |
886c62d1 | 12192 | |
e075ae69 | 12193 | ;; The same, but the count is not known to not be zero. |
886c62d1 | 12194 | |
e075ae69 RH |
12195 | (define_insn "cmpstrsi_1" |
12196 | [(set (reg:CC 17) | |
b1cdafbb | 12197 | (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2") |
e075ae69 | 12198 | (const_int 0)) |
2bed3391 | 12199 | (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) |
b1cdafbb | 12200 | (mem:BLK (match_operand:SI 5 "register_operand" "1"))) |
e075ae69 RH |
12201 | (const_int 0))) |
12202 | (use (match_operand:SI 3 "immediate_operand" "i")) | |
e2e52e1b | 12203 | (use (reg:CC 17)) |
7c7ef435 | 12204 | (use (reg:SI 19)) |
b1cdafbb JH |
12205 | (clobber (match_operand:SI 0 "register_operand" "=S")) |
12206 | (clobber (match_operand:SI 1 "register_operand" "=D")) | |
12207 | (clobber (match_operand:SI 2 "register_operand" "=c"))] | |
886c62d1 | 12208 | "" |
e2e52e1b JH |
12209 | "repz{\;| }cmpsb" |
12210 | [(set_attr "type" "str") | |
6ef67412 JH |
12211 | (set_attr "mode" "QI") |
12212 | (set_attr "prefix_rep" "1")]) | |
886c62d1 | 12213 | |
e075ae69 RH |
12214 | (define_expand "strlensi" |
12215 | [(set (match_operand:SI 0 "register_operand" "") | |
12216 | (unspec:SI [(match_operand:BLK 1 "general_operand" "") | |
12217 | (match_operand:QI 2 "immediate_operand" "") | |
12218 | (match_operand:SI 3 "immediate_operand" "")] 0))] | |
886c62d1 | 12219 | "" |
ce193852 | 12220 | " |
886c62d1 | 12221 | { |
c5aa680d RH |
12222 | rtx out, addr, scratch1, scratch2, scratch3; |
12223 | rtx eoschar = operands[2]; | |
12224 | rtx align = operands[3]; | |
886c62d1 | 12225 | |
79f05c19 JH |
12226 | /* The generic case of strlen expander is long. Avoid it's |
12227 | expanding unless TARGET_INLINE_ALL_STRINGOPS. */ | |
12228 | ||
12229 | if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1 | |
d9f32422 | 12230 | && !TARGET_INLINE_ALL_STRINGOPS |
79f05c19 JH |
12231 | && !optimize_size |
12232 | && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)) | |
12233 | FAIL; | |
12234 | ||
e075ae69 RH |
12235 | out = operands[0]; |
12236 | addr = force_reg (Pmode, XEXP (operands[1], 0)); | |
e075ae69 | 12237 | scratch1 = gen_reg_rtx (SImode); |
886c62d1 | 12238 | |
e2e52e1b JH |
12239 | if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1 |
12240 | && !optimize_size) | |
628448b3 | 12241 | { |
e075ae69 | 12242 | /* Well it seems that some optimizer does not combine a call like |
628448b3 | 12243 | foo(strlen(bar), strlen(bar)); |
e075ae69 RH |
12244 | when the move and the subtraction is done here. It does calculate |
12245 | the length just once when these instructions are done inside of | |
12246 | output_strlen_unroll(). But I think since &bar[strlen(bar)] is | |
12247 | often used and I use one fewer register for the lifetime of | |
12248 | output_strlen_unroll() this is better. */ | |
12249 | ||
12250 | if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4) | |
12251 | emit_move_insn (scratch1, addr); | |
79f05c19 | 12252 | |
e075ae69 RH |
12253 | emit_move_insn (out, addr); |
12254 | ||
12255 | ix86_expand_strlensi_unroll_1 (out, align, scratch1); | |
12256 | ||
12257 | /* strlensi_unroll_1 returns the address of the zero at the end of | |
12258 | the string, like memchr(), so compute the length by subtracting | |
12259 | the start address. */ | |
12260 | emit_insn (gen_subsi3 (out, out, addr)); | |
628448b3 | 12261 | } |
e075ae69 RH |
12262 | else |
12263 | { | |
12264 | scratch2 = gen_reg_rtx (SImode); | |
12265 | scratch3 = gen_reg_rtx (SImode); | |
628448b3 | 12266 | |
e075ae69 RH |
12267 | emit_move_insn (scratch3, addr); |
12268 | ||
7c7ef435 | 12269 | emit_insn (gen_cld ()); |
e075ae69 | 12270 | emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar, |
b1cdafbb | 12271 | align, constm1_rtx, scratch3)); |
e075ae69 RH |
12272 | emit_insn (gen_one_cmplsi2 (scratch2, scratch1)); |
12273 | emit_insn (gen_addsi3 (out, scratch2, constm1_rtx)); | |
12274 | } | |
12275 | DONE; | |
19c3fc24 RS |
12276 | }") |
12277 | ||
e075ae69 RH |
12278 | (define_insn "strlensi_1" |
12279 | [(set (match_operand:SI 0 "register_operand" "=&c") | |
b1cdafbb | 12280 | (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1")) |
e075ae69 RH |
12281 | (match_operand:QI 2 "general_operand" "a") |
12282 | (match_operand:SI 3 "immediate_operand" "i") | |
12283 | (match_operand:SI 4 "immediate_operand" "0")] 0)) | |
7c7ef435 | 12284 | (use (reg:SI 19)) |
b1cdafbb | 12285 | (clobber (match_operand:SI 1 "register_operand" "=D")) |
e075ae69 RH |
12286 | (clobber (reg:CC 17))] |
12287 | "" | |
7c7ef435 | 12288 | "repnz{\;| }scasb" |
e2e52e1b | 12289 | [(set_attr "type" "str") |
6ef67412 JH |
12290 | (set_attr "mode" "QI") |
12291 | (set_attr "prefix_rep" "1")]) | |
e075ae69 RH |
12292 | \f |
12293 | ;; Conditional move instructions. | |
726e2d54 | 12294 | |
e075ae69 | 12295 | (define_expand "movsicc" |
6a4a5d95 | 12296 | [(set (match_operand:SI 0 "register_operand" "") |
e075ae69 RH |
12297 | (if_then_else:SI (match_operand 1 "comparison_operator" "") |
12298 | (match_operand:SI 2 "general_operand" "") | |
12299 | (match_operand:SI 3 "general_operand" "")))] | |
12300 | "" | |
12301 | "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") | |
726e2d54 | 12302 | |
e075ae69 RH |
12303 | ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing |
12304 | ;; the register first winds up with `sbbl $0,reg', which is also weird. | |
12305 | ;; So just document what we're doing explicitly. | |
12306 | ||
12307 | (define_insn "x86_movsicc_0_m1" | |
12308 | [(set (match_operand:SI 0 "register_operand" "=r") | |
12309 | (if_then_else:SI (ltu (reg:CC 17) (const_int 0)) | |
12310 | (const_int -1) | |
12311 | (const_int 0))) | |
12312 | (clobber (reg:CC 17))] | |
12313 | "" | |
12314 | "sbb{l}\\t%0, %0" | |
12315 | ; Since we don't have the proper number of operands for an alu insn, | |
12316 | ; fill in all the blanks. | |
12317 | [(set_attr "type" "alu") | |
12318 | (set_attr "memory" "none") | |
12319 | (set_attr "imm_disp" "false") | |
6ef67412 JH |
12320 | (set_attr "mode" "SI") |
12321 | (set_attr "length_immediate" "0")]) | |
e075ae69 | 12322 | |
6343a50e | 12323 | (define_insn "*movsicc_noc" |
e075ae69 | 12324 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
9076b9c1 | 12325 | (if_then_else:SI (match_operator 1 "ix86_comparison_operator" |
e075ae69 RH |
12326 | [(reg 17) (const_int 0)]) |
12327 | (match_operand:SI 2 "nonimmediate_operand" "rm,0") | |
12328 | (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] | |
d525dfdf JH |
12329 | "TARGET_CMOVE |
12330 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" | |
e075ae69 RH |
12331 | "@ |
12332 | cmov%C1\\t{%2, %0|%0, %2} | |
12333 | cmov%c1\\t{%3, %0|%0, %3}" | |
6ef67412 JH |
12334 | [(set_attr "type" "icmov") |
12335 | (set_attr "mode" "SI")]) | |
726e2d54 | 12336 | |
726e2d54 JW |
12337 | (define_expand "movhicc" |
12338 | [(set (match_operand:HI 0 "register_operand" "") | |
12339 | (if_then_else:HI (match_operand 1 "comparison_operator" "") | |
12340 | (match_operand:HI 2 "nonimmediate_operand" "") | |
12341 | (match_operand:HI 3 "nonimmediate_operand" "")))] | |
d9f32422 | 12342 | "TARGET_CMOVE && TARGET_HIMODE_MATH" |
e075ae69 | 12343 | "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") |
726e2d54 | 12344 | |
6343a50e | 12345 | (define_insn "*movhicc_noc" |
e075ae69 | 12346 | [(set (match_operand:HI 0 "register_operand" "=r,r") |
9076b9c1 | 12347 | (if_then_else:HI (match_operator 1 "ix86_comparison_operator" |
e075ae69 RH |
12348 | [(reg 17) (const_int 0)]) |
12349 | (match_operand:HI 2 "nonimmediate_operand" "rm,0") | |
12350 | (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] | |
d525dfdf JH |
12351 | "TARGET_CMOVE |
12352 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" | |
e075ae69 RH |
12353 | "@ |
12354 | cmov%C1\\t{%2, %0|%0, %2} | |
12355 | cmov%c1\\t{%3, %0|%0, %3}" | |
6ef67412 JH |
12356 | [(set_attr "type" "icmov") |
12357 | (set_attr "mode" "HI")]) | |
726e2d54 | 12358 | |
56710e42 | 12359 | (define_expand "movsfcc" |
726e2d54 | 12360 | [(set (match_operand:SF 0 "register_operand" "") |
56710e42 | 12361 | (if_then_else:SF (match_operand 1 "comparison_operator" "") |
e5e809f4 JL |
12362 | (match_operand:SF 2 "register_operand" "") |
12363 | (match_operand:SF 3 "register_operand" "")))] | |
726e2d54 | 12364 | "TARGET_CMOVE" |
e075ae69 | 12365 | "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") |
726e2d54 | 12366 | |
6343a50e | 12367 | (define_insn "*movsfcc_1" |
7093c9ea | 12368 | [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") |
e075ae69 RH |
12369 | (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" |
12370 | [(reg 17) (const_int 0)]) | |
7093c9ea JH |
12371 | (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") |
12372 | (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] | |
12373 | "TARGET_CMOVE | |
12374 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" | |
e075ae69 RH |
12375 | "@ |
12376 | fcmov%F1\\t{%2, %0|%0, %2} | |
7093c9ea JH |
12377 | fcmov%f1\\t{%3, %0|%0, %3} |
12378 | cmov%C1\\t{%2, %0|%0, %2} | |
12379 | cmov%c1\\t{%3, %0|%0, %3}" | |
12380 | [(set_attr "type" "fcmov,fcmov,icmov,icmov") | |
12381 | (set_attr "mode" "SF,SF,SI,SI")]) | |
56710e42 SC |
12382 | |
12383 | (define_expand "movdfcc" | |
726e2d54 | 12384 | [(set (match_operand:DF 0 "register_operand" "") |
56710e42 | 12385 | (if_then_else:DF (match_operand 1 "comparison_operator" "") |
e5e809f4 JL |
12386 | (match_operand:DF 2 "register_operand" "") |
12387 | (match_operand:DF 3 "register_operand" "")))] | |
726e2d54 | 12388 | "TARGET_CMOVE" |
e075ae69 | 12389 | "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") |
726e2d54 | 12390 | |
6343a50e | 12391 | (define_insn "*movdfcc_1" |
7093c9ea | 12392 | [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") |
e075ae69 RH |
12393 | (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" |
12394 | [(reg 17) (const_int 0)]) | |
7093c9ea JH |
12395 | (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") |
12396 | (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] | |
1e07edd3 | 12397 | "TARGET_CMOVE && !TARGET_64BIT |
7093c9ea | 12398 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" |
e075ae69 RH |
12399 | "@ |
12400 | fcmov%F1\\t{%2, %0|%0, %2} | |
7093c9ea JH |
12401 | fcmov%f1\\t{%3, %0|%0, %3} |
12402 | # | |
12403 | #" | |
12404 | [(set_attr "type" "fcmov,fcmov,multi,multi") | |
6ef67412 | 12405 | (set_attr "mode" "DF")]) |
56710e42 | 12406 | |
1e07edd3 JH |
12407 | (define_insn "*movdfcc_1_rex64" |
12408 | [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") | |
12409 | (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" | |
12410 | [(reg 17) (const_int 0)]) | |
12411 | (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") | |
12412 | (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] | |
12413 | "TARGET_CMOVE && TARGET_64BIT | |
12414 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" | |
12415 | "@ | |
12416 | fcmov%F1\\t{%2, %0|%0, %2} | |
12417 | fcmov%f1\\t{%3, %0|%0, %3} | |
12418 | cmov%C1\\t{%2, %0|%0, %2} | |
12419 | cmov%c1\\t{%3, %0|%0, %3}" | |
12420 | [(set_attr "type" "fcmov,fcmov,icmov,icmov") | |
12421 | (set_attr "mode" "DF")]) | |
12422 | ||
7093c9ea JH |
12423 | (define_split |
12424 | [(set (match_operand:DF 0 "register_operand" "") | |
12425 | (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" | |
12426 | [(match_operand 4 "" "") (const_int 0)]) | |
12427 | (match_operand:DF 2 "nonimmediate_operand" "") | |
12428 | (match_operand:DF 3 "nonimmediate_operand" "")))] | |
1e07edd3 | 12429 | "!ANY_FP_REG_P (operands[0]) && reload_completed && !TARGET_64BIT" |
7093c9ea JH |
12430 | [(set (match_dup 2) |
12431 | (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) | |
12432 | (match_dup 5) | |
12433 | (match_dup 7))) | |
12434 | (set (match_dup 3) | |
12435 | (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) | |
12436 | (match_dup 6) | |
12437 | (match_dup 8)))] | |
12438 | "split_di (operands+2, 1, operands+5, operands+6); | |
12439 | split_di (operands+3, 1, operands+7, operands+8); | |
12440 | split_di (operands, 1, operands+2, operands+3);") | |
12441 | ||
56710e42 | 12442 | (define_expand "movxfcc" |
726e2d54 | 12443 | [(set (match_operand:XF 0 "register_operand" "") |
56710e42 | 12444 | (if_then_else:XF (match_operand 1 "comparison_operator" "") |
e5e809f4 JL |
12445 | (match_operand:XF 2 "register_operand" "") |
12446 | (match_operand:XF 3 "register_operand" "")))] | |
1e07edd3 | 12447 | "TARGET_CMOVE && !TARGET_64BIT" |
e075ae69 | 12448 | "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") |
726e2d54 | 12449 | |
2b589241 JH |
12450 | (define_expand "movtfcc" |
12451 | [(set (match_operand:TF 0 "register_operand" "") | |
12452 | (if_then_else:TF (match_operand 1 "comparison_operator" "") | |
12453 | (match_operand:TF 2 "register_operand" "") | |
12454 | (match_operand:TF 3 "register_operand" "")))] | |
12455 | "TARGET_CMOVE" | |
12456 | "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") | |
12457 | ||
6343a50e | 12458 | (define_insn "*movxfcc_1" |
3aeae608 | 12459 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
e075ae69 RH |
12460 | (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" |
12461 | [(reg 17) (const_int 0)]) | |
3aeae608 JW |
12462 | (match_operand:XF 2 "register_operand" "f,0") |
12463 | (match_operand:XF 3 "register_operand" "0,f")))] | |
1e07edd3 | 12464 | "TARGET_CMOVE && !TARGET_64BIT" |
e075ae69 RH |
12465 | "@ |
12466 | fcmov%F1\\t{%2, %0|%0, %2} | |
12467 | fcmov%f1\\t{%3, %0|%0, %3}" | |
6ef67412 JH |
12468 | [(set_attr "type" "fcmov") |
12469 | (set_attr "mode" "XF")]) | |
2b589241 JH |
12470 | |
12471 | (define_insn "*movtfcc_1" | |
12472 | [(set (match_operand:TF 0 "register_operand" "=f,f") | |
12473 | (if_then_else:TF (match_operator 1 "fcmov_comparison_operator" | |
12474 | [(reg 17) (const_int 0)]) | |
12475 | (match_operand:TF 2 "register_operand" "f,0") | |
12476 | (match_operand:TF 3 "register_operand" "0,f")))] | |
12477 | "TARGET_CMOVE" | |
12478 | "@ | |
12479 | fcmov%F1\\t{%2, %0|%0, %2} | |
12480 | fcmov%f1\\t{%3, %0|%0, %3}" | |
12481 | [(set_attr "type" "fcmov") | |
12482 | (set_attr "mode" "XF")]) | |
7ada6625 JH |
12483 | |
12484 | (define_expand "minsf3" | |
12485 | [(parallel [ | |
12486 | (set (match_operand:SF 0 "register_operand" "") | |
12487 | (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "") | |
12488 | (match_operand:SF 2 "nonimmediate_operand" "")) | |
12489 | (match_dup 1) | |
12490 | (match_dup 2))) | |
12491 | (clobber (reg:CC 17))])] | |
12492 | "TARGET_SSE" | |
12493 | "") | |
12494 | ||
12495 | (define_insn "*minsf" | |
12496 | [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x") | |
12497 | (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x") | |
12498 | (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0")) | |
12499 | (match_dup 1) | |
12500 | (match_dup 2))) | |
12501 | (clobber (reg:CC 17))] | |
12502 | "TARGET_SSE && TARGET_IEEE_FP" | |
12503 | "#") | |
12504 | ||
12505 | (define_insn "*minsf_nonieee" | |
12506 | [(set (match_operand:SF 0 "register_operand" "=x#f,f#x") | |
12507 | (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0") | |
12508 | (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x")) | |
12509 | (match_dup 1) | |
12510 | (match_dup 2))) | |
12511 | (clobber (reg:CC 17))] | |
12512 | "TARGET_SSE && !TARGET_IEEE_FP" | |
12513 | "#") | |
12514 | ||
12515 | (define_split | |
12516 | [(set (match_operand:SF 0 "register_operand" "") | |
12517 | (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "") | |
12518 | (match_operand:SF 2 "nonimmediate_operand" "")) | |
12519 | (match_dup 1) | |
12520 | (match_dup 2))) | |
12521 | (clobber (reg:CC 17))] | |
12522 | "SSE_REG_P (operands[0]) && reload_completed" | |
12523 | [(set (match_dup 0) | |
12524 | (if_then_else:SF (lt (match_dup 1) | |
12525 | (match_dup 2)) | |
12526 | (match_dup 1) | |
12527 | (match_dup 2)))]) | |
12528 | ||
12529 | ;; We can't represent the LT test directly. Do this by swapping the operands. | |
12530 | (define_split | |
12531 | [(set (match_operand:SF 0 "register_operand" "") | |
12532 | (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "") | |
12533 | (match_operand:SF 2 "register_operand" "")) | |
12534 | (match_dup 1) | |
12535 | (match_dup 2))) | |
12536 | (clobber (reg:CC 17))] | |
12537 | "FP_REG_P (operands[0]) && reload_completed" | |
12538 | [(set (reg:CCFP 17) | |
12539 | (compare:CCFP (match_dup 2) | |
12540 | (match_dup 1))) | |
12541 | (set (match_dup 0) | |
12542 | (if_then_else:SF (ge (reg:CCFP 17) (const_int 0)) | |
12543 | (match_dup 1) | |
12544 | (match_dup 2)))]) | |
12545 | ||
12546 | (define_insn "*minsf_sse" | |
12547 | [(set (match_operand:SF 0 "register_operand" "=x") | |
12548 | (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0") | |
12549 | (match_operand:SF 2 "nonimmediate_operand" "xm")) | |
12550 | (match_dup 1) | |
12551 | (match_dup 2)))] | |
12552 | "TARGET_SSE && reload_completed" | |
12553 | "minss\\t{%2, %0|%0, %2}" | |
12554 | [(set_attr "type" "sse") | |
12555 | (set_attr "mode" "SF")]) | |
12556 | ||
12557 | (define_expand "mindf3" | |
12558 | [(parallel [ | |
12559 | (set (match_operand:DF 0 "register_operand" "") | |
12560 | (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "") | |
12561 | (match_operand:DF 2 "nonimmediate_operand" "")) | |
12562 | (match_dup 1) | |
12563 | (match_dup 2))) | |
12564 | (clobber (reg:CC 17))])] | |
12565 | "TARGET_SSE2" | |
12566 | "#") | |
12567 | ||
12568 | (define_insn "*mindf" | |
12569 | [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y") | |
12570 | (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y") | |
12571 | (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0")) | |
12572 | (match_dup 1) | |
12573 | (match_dup 2))) | |
12574 | (clobber (reg:CC 17))] | |
12575 | "TARGET_SSE2 && TARGET_IEEE_FP" | |
12576 | "#") | |
12577 | ||
12578 | (define_insn "*mindf_nonieee" | |
12579 | [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y") | |
12580 | (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0") | |
12581 | (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y")) | |
12582 | (match_dup 1) | |
12583 | (match_dup 2))) | |
12584 | (clobber (reg:CC 17))] | |
12585 | "TARGET_SSE2 && !TARGET_IEEE_FP" | |
12586 | "#") | |
12587 | ||
12588 | (define_split | |
12589 | [(set (match_operand:DF 0 "register_operand" "") | |
12590 | (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "") | |
12591 | (match_operand:DF 2 "nonimmediate_operand" "")) | |
12592 | (match_dup 1) | |
12593 | (match_dup 2))) | |
12594 | (clobber (reg:CC 17))] | |
12595 | "SSE_REG_P (operands[0]) && reload_completed" | |
12596 | [(set (match_dup 0) | |
12597 | (if_then_else:DF (lt (match_dup 1) | |
12598 | (match_dup 2)) | |
12599 | (match_dup 1) | |
12600 | (match_dup 2)))]) | |
12601 | ||
12602 | ;; We can't represent the LT test directly. Do this by swapping the operands. | |
12603 | (define_split | |
12604 | [(set (match_operand:DF 0 "register_operand" "") | |
12605 | (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "") | |
12606 | (match_operand:DF 2 "register_operand" "")) | |
12607 | (match_dup 1) | |
12608 | (match_dup 2))) | |
12609 | (clobber (reg:CC 17))] | |
12610 | "FP_REG_P (operands[0]) && reload_completed" | |
12611 | [(set (reg:CCFP 17) | |
12612 | (compare:CCFP (match_dup 2) | |
12613 | (match_dup 2))) | |
12614 | (set (match_dup 0) | |
12615 | (if_then_else:DF (ge (reg:CCFP 17) (const_int 0)) | |
12616 | (match_dup 1) | |
12617 | (match_dup 2)))]) | |
12618 | ||
12619 | (define_insn "*mindf_sse" | |
12620 | [(set (match_operand:DF 0 "register_operand" "=Y") | |
12621 | (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0") | |
12622 | (match_operand:DF 2 "nonimmediate_operand" "Ym")) | |
12623 | (match_dup 1) | |
12624 | (match_dup 2)))] | |
12625 | "TARGET_SSE2 && reload_completed" | |
12626 | "minsd\\t{%2, %0|%0, %2}" | |
12627 | [(set_attr "type" "sse") | |
12628 | (set_attr "mode" "DF")]) | |
12629 | ||
12630 | (define_expand "maxsf3" | |
12631 | [(parallel [ | |
12632 | (set (match_operand:SF 0 "register_operand" "") | |
12633 | (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "") | |
12634 | (match_operand:SF 2 "nonimmediate_operand" "")) | |
12635 | (match_dup 1) | |
12636 | (match_dup 2))) | |
12637 | (clobber (reg:CC 17))])] | |
12638 | "TARGET_SSE" | |
12639 | "#") | |
12640 | ||
12641 | (define_insn "*maxsf" | |
12642 | [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x") | |
12643 | (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x") | |
12644 | (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x,0")) | |
12645 | (match_dup 1) | |
12646 | (match_dup 2))) | |
12647 | (clobber (reg:CC 17))] | |
12648 | "TARGET_SSE && TARGET_IEEE_FP" | |
12649 | "#") | |
12650 | ||
12651 | (define_insn "*maxsf_nonieee" | |
12652 | [(set (match_operand:SF 0 "register_operand" "=x#f,f#x") | |
12653 | (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0") | |
12654 | (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x")) | |
12655 | (match_dup 1) | |
12656 | (match_dup 2))) | |
12657 | (clobber (reg:CC 17))] | |
12658 | "TARGET_SSE && !TARGET_IEEE_FP" | |
12659 | "#") | |
12660 | ||
12661 | (define_split | |
12662 | [(set (match_operand:SF 0 "register_operand" "") | |
12663 | (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "") | |
12664 | (match_operand:SF 2 "nonimmediate_operand" "")) | |
12665 | (match_dup 1) | |
12666 | (match_dup 2))) | |
12667 | (clobber (reg:CC 17))] | |
12668 | "SSE_REG_P (operands[0]) && reload_completed" | |
12669 | [(set (match_dup 0) | |
12670 | (if_then_else:SF (gt (match_dup 1) | |
12671 | (match_dup 2)) | |
12672 | (match_dup 1) | |
12673 | (match_dup 2)))]) | |
12674 | ||
12675 | (define_split | |
12676 | [(set (match_operand:SF 0 "register_operand" "") | |
12677 | (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "") | |
12678 | (match_operand:SF 2 "register_operand" "")) | |
12679 | (match_dup 1) | |
12680 | (match_dup 2))) | |
12681 | (clobber (reg:CC 17))] | |
12682 | "FP_REG_P (operands[0]) && reload_completed" | |
12683 | [(set (reg:CCFP 17) | |
12684 | (compare:CCFP (match_dup 1) | |
12685 | (match_dup 2))) | |
12686 | (set (match_dup 0) | |
12687 | (if_then_else:SF (gt (reg:CCFP 17) (const_int 0)) | |
12688 | (match_dup 1) | |
12689 | (match_dup 2)))]) | |
12690 | ||
12691 | (define_insn "*maxsf_sse" | |
12692 | [(set (match_operand:SF 0 "register_operand" "=x") | |
12693 | (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0") | |
12694 | (match_operand:SF 2 "nonimmediate_operand" "xm")) | |
12695 | (match_dup 1) | |
12696 | (match_dup 2)))] | |
12697 | "TARGET_SSE && reload_completed" | |
12698 | "maxss\\t{%2, %0|%0, %2}" | |
12699 | [(set_attr "type" "sse") | |
12700 | (set_attr "mode" "SF")]) | |
12701 | ||
12702 | (define_expand "maxdf3" | |
12703 | [(parallel [ | |
12704 | (set (match_operand:DF 0 "register_operand" "") | |
12705 | (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "") | |
12706 | (match_operand:DF 2 "nonimmediate_operand" "")) | |
12707 | (match_dup 1) | |
12708 | (match_dup 2))) | |
12709 | (clobber (reg:CC 17))])] | |
12710 | "TARGET_SSE2" | |
12711 | "#") | |
12712 | ||
12713 | (define_insn "*maxdf" | |
12714 | [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y") | |
12715 | (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y") | |
12716 | (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y,0")) | |
12717 | (match_dup 1) | |
12718 | (match_dup 2))) | |
12719 | (clobber (reg:CC 17))] | |
12720 | "TARGET_SSE2 && TARGET_IEEE_FP" | |
12721 | "#") | |
12722 | ||
12723 | (define_insn "*maxdf_nonieee" | |
12724 | [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y") | |
12725 | (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0") | |
12726 | (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y")) | |
12727 | (match_dup 1) | |
12728 | (match_dup 2))) | |
12729 | (clobber (reg:CC 17))] | |
12730 | "TARGET_SSE2 && !TARGET_IEEE_FP" | |
12731 | "#") | |
12732 | ||
12733 | (define_split | |
12734 | [(set (match_operand:DF 0 "register_operand" "") | |
12735 | (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "") | |
12736 | (match_operand:DF 2 "nonimmediate_operand" "")) | |
12737 | (match_dup 1) | |
12738 | (match_dup 2))) | |
12739 | (clobber (reg:CC 17))] | |
12740 | "SSE_REG_P (operands[0]) && reload_completed" | |
12741 | [(set (match_dup 0) | |
12742 | (if_then_else:DF (gt (match_dup 1) | |
12743 | (match_dup 2)) | |
12744 | (match_dup 1) | |
12745 | (match_dup 2)))]) | |
12746 | ||
12747 | (define_split | |
12748 | [(set (match_operand:DF 0 "register_operand" "") | |
12749 | (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "") | |
12750 | (match_operand:DF 2 "register_operand" "")) | |
12751 | (match_dup 1) | |
12752 | (match_dup 2))) | |
12753 | (clobber (reg:CC 17))] | |
12754 | "FP_REG_P (operands[0]) && reload_completed" | |
12755 | [(set (reg:CCFP 17) | |
12756 | (compare:CCFP (match_dup 1) | |
12757 | (match_dup 2))) | |
12758 | (set (match_dup 0) | |
12759 | (if_then_else:DF (gt (reg:CCFP 17) (const_int 0)) | |
12760 | (match_dup 1) | |
12761 | (match_dup 2)))]) | |
12762 | ||
12763 | (define_insn "*maxdf_sse" | |
12764 | [(set (match_operand:DF 0 "register_operand" "=Y") | |
12765 | (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0") | |
12766 | (match_operand:DF 2 "nonimmediate_operand" "Ym")) | |
12767 | (match_dup 1) | |
12768 | (match_dup 2)))] | |
12769 | "TARGET_SSE2 && reload_completed" | |
12770 | "maxsd\\t{%2, %0|%0, %2}" | |
12771 | [(set_attr "type" "sse") | |
12772 | (set_attr "mode" "DF")]) | |
e075ae69 RH |
12773 | \f |
12774 | ;; Misc patterns (?) | |
726e2d54 | 12775 | |
e075ae69 RH |
12776 | ;; This pattern exists to put a dependancy on all ebp-based memory accesses. |
12777 | ;; Otherwise there will be nothing to keep | |
12778 | ;; | |
12779 | ;; [(set (reg ebp) (reg esp))] | |
12780 | ;; [(set (reg esp) (plus (reg esp) (const_int -160000))) | |
12781 | ;; (clobber (eflags)] | |
12782 | ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] | |
12783 | ;; | |
12784 | ;; in proper program order. | |
726e2d54 | 12785 | |
1c71e60e JH |
12786 | (define_insn "pro_epilogue_adjust_stack" |
12787 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
12788 | (plus:SI (match_operand:SI 1 "register_operand" "0,r") | |
12789 | (match_operand:SI 2 "immediate_operand" "i,i"))) | |
12790 | (set (match_operand:SI 3 "register_operand" "+r,r") | |
e075ae69 RH |
12791 | (match_dup 3)) |
12792 | (clobber (reg:CC 17))] | |
12793 | "" | |
12794 | "* | |
12795 | { | |
1c71e60e | 12796 | switch (get_attr_type (insn)) |
e075ae69 | 12797 | { |
1c71e60e JH |
12798 | case TYPE_IMOV: |
12799 | return \"mov{l}\\t{%1, %0|%0, %1}\"; | |
12800 | ||
12801 | case TYPE_ALU: | |
12802 | if (GET_CODE (operands[2]) == CONST_INT | |
12803 | && (INTVAL (operands[2]) == 128 | |
12804 | || (INTVAL (operands[2]) < 0 | |
12805 | && INTVAL (operands[2]) != -128))) | |
12806 | { | |
12807 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
12808 | return \"sub{l}\\t{%2, %0|%0, %2}\"; | |
12809 | } | |
12810 | return \"add{l}\\t{%2, %0|%0, %2}\"; | |
12811 | ||
12812 | case TYPE_LEA: | |
12813 | operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); | |
12814 | return \"lea{l}\\t{%a2, %0|%0, %a2}\"; | |
12815 | ||
12816 | default: | |
12817 | abort (); | |
e075ae69 | 12818 | } |
e075ae69 | 12819 | }" |
1c71e60e JH |
12820 | [(set (attr "type") |
12821 | (cond [(eq_attr "alternative" "0") | |
12822 | (const_string "alu") | |
12823 | (match_operand:SI 2 "const0_operand" "") | |
12824 | (const_string "imov") | |
12825 | ] | |
6ef67412 JH |
12826 | (const_string "lea"))) |
12827 | (set_attr "mode" "SI")]) | |
578b58f5 | 12828 | |
0073023d JH |
12829 | ;; Placeholder for the conditional moves. This one is split eighter to SSE |
12830 | ;; based moves emulation or to usual cmove sequence. Little bit unfortunate | |
12831 | ;; fact is that compares supported by the cmp??ss instructions are exactly | |
12832 | ;; swapped of those supported by cmove sequence. | |
fa9f36a1 JH |
12833 | ;; The EQ/NE comparisons also needs bit care, since they are not directly |
12834 | ;; supported by i387 comparisons and we do need to emit two conditional moves | |
12835 | ;; in tandem. | |
0073023d JH |
12836 | |
12837 | (define_insn "sse_movsfcc" | |
12838 | [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf") | |
12839 | (if_then_else:SF (match_operator 1 "sse_comparison_operator" | |
12840 | [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f") | |
12841 | (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")]) | |
12842 | (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx") | |
12843 | (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx"))) | |
bf71a4f8 | 12844 | (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X")) |
0073023d | 12845 | (clobber (reg:CC 17))] |
fa9f36a1 JH |
12846 | "TARGET_SSE |
12847 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM) | |
12848 | && (!TARGET_IEEE_FP | |
12849 | || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))" | |
12850 | "#") | |
12851 | ||
12852 | (define_insn "sse_movsfcc_eq" | |
12853 | [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf") | |
12854 | (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f") | |
12855 | (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f")) | |
12856 | (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx") | |
12857 | (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx"))) | |
12858 | (clobber (match_scratch:SF 5 "=1,&4,X,X,X,X")) | |
12859 | (clobber (reg:CC 17))] | |
0073023d JH |
12860 | "TARGET_SSE |
12861 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" | |
12862 | "#") | |
12863 | ||
12864 | (define_insn "sse_movdfcc" | |
12865 | [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf") | |
12866 | (if_then_else:DF (match_operator 1 "sse_comparison_operator" | |
12867 | [(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f") | |
12868 | (match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")]) | |
12869 | (match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx") | |
12870 | (match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx"))) | |
bf71a4f8 | 12871 | (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X")) |
0073023d JH |
12872 | (clobber (reg:CC 17))] |
12873 | "TARGET_SSE2 | |
fa9f36a1 JH |
12874 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM) |
12875 | && (!TARGET_IEEE_FP | |
12876 | || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))" | |
12877 | "#") | |
12878 | ||
12879 | (define_insn "sse_movdfcc_eq" | |
12880 | [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf") | |
12881 | (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f") | |
12882 | (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f")) | |
12883 | (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx") | |
12884 | (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx"))) | |
12885 | (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X")) | |
12886 | (clobber (reg:CC 17))] | |
12887 | "TARGET_SSE | |
0073023d JH |
12888 | && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" |
12889 | "#") | |
12890 | ||
12891 | ;; For non-sse moves just expand the usual cmove sequence. | |
12892 | (define_split | |
12893 | [(set (match_operand 0 "register_operand" "") | |
12894 | (if_then_else (match_operator 1 "comparison_operator" | |
12895 | [(match_operand 4 "nonimmediate_operand" "") | |
12896 | (match_operand 5 "register_operand" "")]) | |
12897 | (match_operand 2 "nonimmediate_operand" "") | |
12898 | (match_operand 3 "nonimmediate_operand" ""))) | |
12899 | (clobber (match_operand 6 "" "")) | |
12900 | (clobber (reg:CC 17))] | |
12901 | "!SSE_REG_P (operands[0]) && reload_completed | |
12902 | && VALID_SSE_REG_MODE (GET_MODE (operands[0]))" | |
12903 | [(const_int 0)] | |
12904 | " | |
12905 | { | |
12906 | ix86_compare_op0 = operands[5]; | |
12907 | ix86_compare_op1 = operands[4]; | |
12908 | operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])), | |
12909 | VOIDmode, operands[5], operands[4]); | |
12910 | ix86_expand_fp_movcc (operands); | |
12911 | DONE; | |
12912 | }") | |
12913 | ||
12914 | ;; Split SSE based conditional move into seqence: | |
12915 | ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison | |
12916 | ;; and op2, op0 - zero op2 if comparison was false | |
12917 | ;; nand op0, op3 - load op3 to op0 if comparison was false | |
12918 | ;; or op2, op0 - get the non-zero one into the result. | |
12919 | (define_split | |
12920 | [(set (match_operand 0 "register_operand" "") | |
12921 | (if_then_else (match_operator 1 "sse_comparison_operator" | |
12922 | [(match_operand 4 "register_operand" "") | |
12923 | (match_operand 5 "nonimmediate_operand" "")]) | |
12924 | (match_operand 2 "register_operand" "") | |
12925 | (match_operand 3 "register_operand" ""))) | |
bf71a4f8 | 12926 | (clobber (match_operand 6 "" "")) |
0073023d JH |
12927 | (clobber (reg:CC 17))] |
12928 | "SSE_REG_P (operands[0]) && reload_completed" | |
12929 | [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)])) | |
12930 | (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0) | |
12931 | (subreg:TI (match_dup 0) 0))) | |
12932 | (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 0) 0)) | |
12933 | (subreg:TI (match_dup 3) 0))) | |
12934 | (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0) | |
12935 | (subreg:TI (match_dup 7) 0)))] | |
12936 | " | |
12937 | { | |
12938 | PUT_MODE (operands[1], GET_MODE (operands[0])); | |
12939 | if (rtx_equal_p (operands[0], operands[4])) | |
12940 | operands[6] = operands[4], operands[7] = operands[2]; | |
12941 | else | |
12942 | operands[6] = operands[2], operands[7] = operands[0]; | |
12943 | }") | |
12944 | ||
12945 | ;; Special case of conditional move we can handle effectivly. | |
12946 | ;; Do not brother with the integer/floating point case, since these are | |
12947 | ;; bot considerably slower, unlike in the generic case. | |
12948 | (define_insn "*sse_movsfcc_const0_1" | |
12949 | [(set (match_operand:SF 0 "register_operand" "=x") | |
12950 | (if_then_else:SF (match_operator 1 "sse_comparison_operator" | |
12951 | [(match_operand:SF 4 "register_operand" "0") | |
12952 | (match_operand:SF 5 "nonimmediate_operand" "xm")]) | |
12953 | (match_operand:SF 2 "register_operand" "x") | |
12954 | (match_operand:SF 3 "const0_operand" "X")))] | |
12955 | "TARGET_SSE" | |
12956 | "#") | |
12957 | ||
12958 | (define_insn "*sse_movsfcc_const0_2" | |
12959 | [(set (match_operand:SF 0 "register_operand" "=x") | |
12960 | (if_then_else:SF (match_operator 1 "sse_comparison_operator" | |
12961 | [(match_operand:SF 4 "register_operand" "0") | |
12962 | (match_operand:SF 5 "nonimmediate_operand" "xm")]) | |
12963 | (match_operand:SF 2 "const0_operand" "x") | |
12964 | (match_operand:SF 3 "register_operand" "X")))] | |
12965 | "TARGET_SSE" | |
12966 | "#") | |
12967 | ||
12968 | (define_insn "*sse_movsfcc_const0_3" | |
12969 | [(set (match_operand:SF 0 "register_operand" "=x") | |
12970 | (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" | |
12971 | [(match_operand:SF 4 "nonimmediate_operand" "xm") | |
12972 | (match_operand:SF 5 "register_operand" "0")]) | |
12973 | (match_operand:SF 2 "register_operand" "x") | |
12974 | (match_operand:SF 3 "const0_operand" "X")))] | |
12975 | "TARGET_SSE" | |
12976 | "#") | |
12977 | ||
12978 | (define_insn "*sse_movsfcc_const0_4" | |
12979 | [(set (match_operand:SF 0 "register_operand" "=x") | |
12980 | (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" | |
12981 | [(match_operand:SF 4 "nonimmediate_operand" "xm") | |
12982 | (match_operand:SF 5 "register_operand" "0")]) | |
12983 | (match_operand:SF 2 "const0_operand" "x") | |
12984 | (match_operand:SF 3 "register_operand" "X")))] | |
12985 | "TARGET_SSE" | |
12986 | "#") | |
12987 | ||
12988 | (define_insn "*sse_movdfcc_const0_1" | |
12989 | [(set (match_operand:SF 0 "register_operand" "=x") | |
12990 | (if_then_else:SF (match_operator 1 "sse_comparison_operator" | |
12991 | [(match_operand:SF 4 "register_operand" "0") | |
12992 | (match_operand:SF 5 "nonimmediate_operand" "xm")]) | |
12993 | (match_operand:SF 2 "register_operand" "x") | |
12994 | (match_operand:SF 3 "const0_operand" "X")))] | |
12995 | "TARGET_SSE2" | |
12996 | "#") | |
12997 | ||
12998 | (define_insn "*sse_movdfcc_const0_2" | |
12999 | [(set (match_operand:SF 0 "register_operand" "=x") | |
13000 | (if_then_else:SF (match_operator 1 "sse_comparison_operator" | |
13001 | [(match_operand:SF 4 "register_operand" "0") | |
13002 | (match_operand:SF 5 "nonimmediate_operand" "xm")]) | |
13003 | (match_operand:SF 2 "const0_operand" "x") | |
13004 | (match_operand:SF 3 "register_operand" "X")))] | |
13005 | "TARGET_SSE2" | |
13006 | "#") | |
13007 | ||
13008 | (define_insn "*sse_movdfcc_const0_3" | |
13009 | [(set (match_operand:SF 0 "register_operand" "=x") | |
13010 | (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" | |
13011 | [(match_operand:SF 4 "nonimmediate_operand" "xm") | |
13012 | (match_operand:SF 5 "register_operand" "0")]) | |
13013 | (match_operand:SF 2 "register_operand" "x") | |
13014 | (match_operand:SF 3 "const0_operand" "X")))] | |
13015 | "TARGET_SSE2" | |
13016 | "#") | |
13017 | ||
13018 | (define_insn "*sse_movdfcc_const0_4" | |
13019 | [(set (match_operand:SF 0 "register_operand" "=x") | |
13020 | (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" | |
13021 | [(match_operand:SF 4 "nonimmediate_operand" "xm") | |
13022 | (match_operand:SF 5 "register_operand" "0")]) | |
13023 | (match_operand:SF 2 "const0_operand" "x") | |
13024 | (match_operand:SF 3 "register_operand" "X")))] | |
13025 | "TARGET_SSE2" | |
13026 | "#") | |
13027 | ||
13028 | (define_split | |
13029 | [(set (match_operand 0 "register_operand" "") | |
13030 | (if_then_else (match_operator 1 "comparison_operator" | |
13031 | [(match_operand 4 "register_operand" "") | |
13032 | (match_operand 5 "nonimmediate_operand" "")]) | |
13033 | (match_operand 2 "nonmemory_operand" "") | |
13034 | (match_operand 3 "nonmemory_operand" "")))] | |
13035 | "SSE_REG_P (operands[0]) && reload_completed | |
13036 | && (const0_operand (operands[2], GET_MODE (operands[0])) | |
13037 | || const0_operand (operands[3], GET_MODE (operands[0])))" | |
13038 | [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)])) | |
13039 | (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6) | |
13040 | (subreg:TI (match_dup 7) 0)))] | |
13041 | " | |
13042 | { | |
13043 | PUT_MODE (operands[1], GET_MODE (operands[0])); | |
13044 | if (!sse_comparison_operator (operands[1], VOIDmode)) | |
13045 | { | |
13046 | rtx tmp = operands[5]; | |
13047 | operands[5] = operands[4]; | |
13048 | operands[4] = tmp; | |
13049 | PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1]))); | |
13050 | } | |
13051 | if (const0_operand (operands[2], GET_MODE (operands[0]))) | |
13052 | { | |
13053 | operands[7] = operands[3]; | |
13054 | operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0], | |
13055 | 0)); | |
13056 | } | |
13057 | else | |
13058 | { | |
13059 | operands[7] = operands[2]; | |
13060 | operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0); | |
13061 | } | |
13062 | }") | |
13063 | ||
578b58f5 RK |
13064 | (define_insn "allocate_stack_worker" |
13065 | [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3) | |
13066 | (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0))) | |
e075ae69 RH |
13067 | (clobber (match_dup 0)) |
13068 | (clobber (reg:CC 17))] | |
578b58f5 | 13069 | "TARGET_STACK_PROBE" |
e075ae69 RH |
13070 | "call\\t__alloca" |
13071 | [(set_attr "type" "multi") | |
13072 | (set_attr "length" "5")]) | |
578b58f5 RK |
13073 | |
13074 | (define_expand "allocate_stack" | |
e075ae69 RH |
13075 | [(parallel [(set (match_operand:SI 0 "register_operand" "=r") |
13076 | (minus:SI (reg:SI 7) | |
13077 | (match_operand:SI 1 "general_operand" ""))) | |
13078 | (clobber (reg:CC 17))]) | |
13079 | (parallel [(set (reg:SI 7) | |
13080 | (minus:SI (reg:SI 7) (match_dup 1))) | |
13081 | (clobber (reg:CC 17))])] | |
13082 | "TARGET_STACK_PROBE" | |
578b58f5 RK |
13083 | " |
13084 | { | |
13085 | #ifdef CHECK_STACK_LIMIT | |
e9a25f70 JL |
13086 | if (GET_CODE (operands[1]) == CONST_INT |
13087 | && INTVAL (operands[1]) < CHECK_STACK_LIMIT) | |
578b58f5 | 13088 | emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, |
e9a25f70 | 13089 | operands[1])); |
578b58f5 RK |
13090 | else |
13091 | #endif | |
13092 | emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode, | |
e9a25f70 | 13093 | operands[1]))); |
578b58f5 | 13094 | |
e9a25f70 JL |
13095 | emit_move_insn (operands[0], virtual_stack_dynamic_rtx); |
13096 | DONE; | |
13097 | }") | |
e31ca113 JW |
13098 | |
13099 | (define_expand "exception_receiver" | |
13100 | [(const_int 0)] | |
13101 | "flag_pic" | |
13102 | " | |
13103 | { | |
6baf1cc8 | 13104 | load_pic_register (); |
e31ca113 JW |
13105 | DONE; |
13106 | }") | |
fb754025 AG |
13107 | |
13108 | (define_expand "builtin_setjmp_receiver" | |
13109 | [(label_ref (match_operand 0 "" ""))] | |
13110 | "flag_pic" | |
13111 | " | |
13112 | { | |
13113 | load_pic_register (); | |
13114 | DONE; | |
13115 | }") | |
e9e80858 JH |
13116 | \f |
13117 | ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. | |
13118 | ||
13119 | (define_split | |
13120 | [(set (match_operand 0 "register_operand" "") | |
13121 | (match_operator 3 "promotable_binary_operator" | |
13122 | [(match_operand 1 "register_operand" "") | |
2247f6ed | 13123 | (match_operand 2 "aligned_operand" "")])) |
e9e80858 JH |
13124 | (clobber (reg:CC 17))] |
13125 | "! TARGET_PARTIAL_REG_STALL && reload_completed | |
13126 | && ((GET_MODE (operands[0]) == HImode | |
13127 | && (!optimize_size || GET_CODE (operands[2]) != CONST_INT | |
13128 | || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))) | |
13129 | || (GET_MODE (operands[0]) == QImode | |
13130 | && (TARGET_PROMOTE_QImode || optimize_size)))" | |
13131 | [(parallel [(set (match_dup 0) | |
13132 | (match_op_dup 3 [(match_dup 1) (match_dup 2)])) | |
13133 | (clobber (reg:CC 17))])] | |
13134 | "operands[0] = gen_lowpart (SImode, operands[0]); | |
13135 | operands[1] = gen_lowpart (SImode, operands[1]); | |
13136 | if (GET_CODE (operands[3]) != ASHIFT) | |
13137 | operands[2] = gen_lowpart (SImode, operands[2]); | |
dbbbbf3b | 13138 | PUT_MODE (operands[3], SImode);") |
e9e80858 JH |
13139 | |
13140 | (define_split | |
16189740 RH |
13141 | [(set (reg 17) |
13142 | (compare (and (match_operand 1 "aligned_operand" "") | |
13143 | (match_operand 2 "const_int_operand" "")) | |
13144 | (const_int 0))) | |
e9e80858 JH |
13145 | (set (match_operand 0 "register_operand" "") |
13146 | (and (match_dup 1) (match_dup 2)))] | |
13147 | "! TARGET_PARTIAL_REG_STALL && reload_completed | |
16189740 | 13148 | && ix86_match_ccmode (insn, CCNOmode) |
e9e80858 JH |
13149 | && (GET_MODE (operands[0]) == HImode |
13150 | || (GET_MODE (operands[0]) == QImode | |
13151 | && (TARGET_PROMOTE_QImode || optimize_size)))" | |
13152 | [(parallel [(set (reg:CCNO 17) | |
13153 | (compare:CCNO (and:SI (match_dup 1) (match_dup 2)) | |
13154 | (const_int 0))) | |
13155 | (set (match_dup 0) | |
13156 | (and:SI (match_dup 1) (match_dup 2)))])] | |
d9f0b960 RH |
13157 | "operands[2] |
13158 | = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0]))); | |
13159 | operands[0] = gen_lowpart (SImode, operands[0]); | |
13160 | operands[1] = gen_lowpart (SImode, operands[1]);") | |
e9e80858 JH |
13161 | |
13162 | (define_split | |
16189740 RH |
13163 | [(set (reg 17) |
13164 | (compare (and (match_operand 0 "aligned_operand" "") | |
13165 | (match_operand 1 "const_int_operand" "")) | |
13166 | (const_int 0)))] | |
e9e80858 | 13167 | "! TARGET_PARTIAL_REG_STALL && reload_completed |
16189740 | 13168 | && ix86_match_ccmode (insn, CCNOmode) |
e9e80858 JH |
13169 | && (GET_MODE (operands[0]) == HImode |
13170 | || (GET_MODE (operands[0]) == QImode | |
13171 | && (TARGET_PROMOTE_QImode || optimize_size)))" | |
13172 | [(set (reg:CCNO 17) | |
13173 | (compare:CCNO (and:SI (match_dup 0) (match_dup 1)) | |
13174 | (const_int 0)))] | |
d9f0b960 RH |
13175 | "operands[1] |
13176 | = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0]))); | |
13177 | operands[0] = gen_lowpart (SImode, operands[0]);") | |
e9e80858 JH |
13178 | |
13179 | (define_split | |
13180 | [(set (match_operand 0 "register_operand" "") | |
13181 | (neg (match_operand 1 "register_operand" ""))) | |
13182 | (clobber (reg:CC 17))] | |
13183 | "! TARGET_PARTIAL_REG_STALL && reload_completed | |
13184 | && (GET_MODE (operands[0]) == HImode | |
13185 | || (GET_MODE (operands[0]) == QImode | |
13186 | && (TARGET_PROMOTE_QImode || optimize_size)))" | |
13187 | [(parallel [(set (match_dup 0) | |
13188 | (neg:SI (match_dup 1))) | |
13189 | (clobber (reg:CC 17))])] | |
13190 | "operands[0] = gen_lowpart (SImode, operands[0]); | |
13191 | operands[1] = gen_lowpart (SImode, operands[1]);") | |
13192 | ||
13193 | (define_split | |
13194 | [(set (match_operand 0 "register_operand" "") | |
13195 | (not (match_operand 1 "register_operand" "")))] | |
13196 | "! TARGET_PARTIAL_REG_STALL && reload_completed | |
13197 | && (GET_MODE (operands[0]) == HImode | |
13198 | || (GET_MODE (operands[0]) == QImode | |
13199 | && (TARGET_PROMOTE_QImode || optimize_size)))" | |
13200 | [(set (match_dup 0) | |
13201 | (not:SI (match_dup 1)))] | |
13202 | "operands[0] = gen_lowpart (SImode, operands[0]); | |
13203 | operands[1] = gen_lowpart (SImode, operands[1]);") | |
13204 | ||
13205 | (define_split | |
13206 | [(set (match_operand 0 "register_operand" "") | |
13207 | (if_then_else (match_operator 1 "comparison_operator" | |
13208 | [(reg 17) (const_int 0)]) | |
13209 | (match_operand 2 "register_operand" "") | |
13210 | (match_operand 3 "register_operand" "")))] | |
13211 | "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE | |
13212 | && (GET_MODE (operands[0]) == HImode | |
13213 | || (GET_MODE (operands[0]) == QImode | |
13214 | && (TARGET_PROMOTE_QImode || optimize_size)))" | |
13215 | [(set (match_dup 0) | |
13216 | (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] | |
13217 | "operands[0] = gen_lowpart (SImode, operands[0]); | |
13218 | operands[2] = gen_lowpart (SImode, operands[2]); | |
13219 | operands[3] = gen_lowpart (SImode, operands[3]);") | |
13220 | ||
e075ae69 RH |
13221 | \f |
13222 | ;; RTL Peephole optimizations, run before sched2. These primarily look to | |
13223 | ;; transform a complex memory operation into two memory to register operations. | |
13224 | ||
13225 | ;; Don't push memory operands | |
13226 | (define_peephole2 | |
3071fab5 RH |
13227 | [(set (match_operand:SI 0 "push_operand" "") |
13228 | (match_operand:SI 1 "memory_operand" "")) | |
13229 | (match_scratch:SI 2 "r")] | |
e075ae69 RH |
13230 | "! optimize_size && ! TARGET_PUSH_MEMORY" |
13231 | [(set (match_dup 2) (match_dup 1)) | |
13232 | (set (match_dup 0) (match_dup 2))] | |
13233 | "") | |
13234 | ||
e9e80858 JH |
13235 | ;; We need to handle SFmode only, because DFmode and XFmode is split to |
13236 | ;; SImode pushes. | |
13237 | (define_peephole2 | |
13238 | [(set (match_operand:SF 0 "push_operand" "") | |
13239 | (match_operand:SF 1 "memory_operand" "")) | |
13240 | (match_scratch:SF 2 "r")] | |
13241 | "! optimize_size && ! TARGET_PUSH_MEMORY" | |
13242 | [(set (match_dup 2) (match_dup 1)) | |
13243 | (set (match_dup 0) (match_dup 2))] | |
13244 | "") | |
13245 | ||
e075ae69 | 13246 | (define_peephole2 |
3071fab5 RH |
13247 | [(set (match_operand:HI 0 "push_operand" "") |
13248 | (match_operand:HI 1 "memory_operand" "")) | |
13249 | (match_scratch:HI 2 "r")] | |
e075ae69 RH |
13250 | "! optimize_size && ! TARGET_PUSH_MEMORY" |
13251 | [(set (match_dup 2) (match_dup 1)) | |
13252 | (set (match_dup 0) (match_dup 2))] | |
13253 | "") | |
13254 | ||
13255 | (define_peephole2 | |
3071fab5 RH |
13256 | [(set (match_operand:QI 0 "push_operand" "") |
13257 | (match_operand:QI 1 "memory_operand" "")) | |
13258 | (match_scratch:QI 2 "q")] | |
e075ae69 RH |
13259 | "! optimize_size && ! TARGET_PUSH_MEMORY" |
13260 | [(set (match_dup 2) (match_dup 1)) | |
13261 | (set (match_dup 0) (match_dup 2))] | |
13262 | "") | |
13263 | ||
13264 | ;; Don't move an immediate directly to memory when the instruction | |
13265 | ;; gets too big. | |
13266 | (define_peephole2 | |
13267 | [(match_scratch:SI 1 "r") | |
13268 | (set (match_operand:SI 0 "memory_operand" "") | |
13269 | (const_int 0))] | |
23280139 | 13270 | "! optimize_size |
591702de | 13271 | && ! TARGET_USE_MOV0 |
23280139 RH |
13272 | && TARGET_SPLIT_LONG_MOVES |
13273 | && get_attr_length (insn) >= ix86_cost->large_insn | |
13274 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
e075ae69 RH |
13275 | [(parallel [(set (match_dup 1) (const_int 0)) |
13276 | (clobber (reg:CC 17))]) | |
13277 | (set (match_dup 0) (match_dup 1))] | |
13278 | "") | |
13279 | ||
13280 | (define_peephole2 | |
13281 | [(match_scratch:HI 1 "r") | |
13282 | (set (match_operand:HI 0 "memory_operand" "") | |
13283 | (const_int 0))] | |
23280139 | 13284 | "! optimize_size |
591702de | 13285 | && ! TARGET_USE_MOV0 |
23280139 RH |
13286 | && TARGET_SPLIT_LONG_MOVES |
13287 | && get_attr_length (insn) >= ix86_cost->large_insn | |
13288 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
591702de | 13289 | [(parallel [(set (match_dup 2) (const_int 0)) |
e075ae69 RH |
13290 | (clobber (reg:CC 17))]) |
13291 | (set (match_dup 0) (match_dup 1))] | |
591702de | 13292 | "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));") |
e075ae69 RH |
13293 | |
13294 | (define_peephole2 | |
13295 | [(match_scratch:QI 1 "q") | |
13296 | (set (match_operand:QI 0 "memory_operand" "") | |
13297 | (const_int 0))] | |
23280139 | 13298 | "! optimize_size |
591702de | 13299 | && ! TARGET_USE_MOV0 |
23280139 RH |
13300 | && TARGET_SPLIT_LONG_MOVES |
13301 | && get_attr_length (insn) >= ix86_cost->large_insn | |
13302 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
591702de | 13303 | [(parallel [(set (match_dup 2) (const_int 0)) |
e075ae69 RH |
13304 | (clobber (reg:CC 17))]) |
13305 | (set (match_dup 0) (match_dup 1))] | |
591702de | 13306 | "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));") |
e075ae69 RH |
13307 | |
13308 | (define_peephole2 | |
13309 | [(match_scratch:SI 2 "r") | |
13310 | (set (match_operand:SI 0 "memory_operand" "") | |
13311 | (match_operand:SI 1 "immediate_operand" ""))] | |
23280139 RH |
13312 | "! optimize_size |
13313 | && get_attr_length (insn) >= ix86_cost->large_insn | |
13314 | && TARGET_SPLIT_LONG_MOVES" | |
e075ae69 RH |
13315 | [(set (match_dup 2) (match_dup 1)) |
13316 | (set (match_dup 0) (match_dup 2))] | |
13317 | "") | |
13318 | ||
13319 | (define_peephole2 | |
13320 | [(match_scratch:HI 2 "r") | |
13321 | (set (match_operand:HI 0 "memory_operand" "") | |
13322 | (match_operand:HI 1 "immediate_operand" ""))] | |
13323 | "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn | |
13324 | && TARGET_SPLIT_LONG_MOVES" | |
13325 | [(set (match_dup 2) (match_dup 1)) | |
13326 | (set (match_dup 0) (match_dup 2))] | |
13327 | "") | |
13328 | ||
13329 | (define_peephole2 | |
13330 | [(match_scratch:QI 2 "q") | |
13331 | (set (match_operand:QI 0 "memory_operand" "") | |
13332 | (match_operand:QI 1 "immediate_operand" ""))] | |
13333 | "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn | |
13334 | && TARGET_SPLIT_LONG_MOVES" | |
13335 | [(set (match_dup 2) (match_dup 1)) | |
13336 | (set (match_dup 0) (match_dup 2))] | |
13337 | "") | |
13338 | ||
13339 | ;; Don't compare memory with zero, load and use a test instead. | |
13340 | (define_peephole2 | |
16189740 RH |
13341 | [(set (reg 17) |
13342 | (compare (match_operand:SI 0 "memory_operand" "") | |
13343 | (const_int 0))) | |
3071fab5 | 13344 | (match_scratch:SI 3 "r")] |
16189740 RH |
13345 | "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size" |
13346 | [(set (match_dup 3) (match_dup 0)) | |
13347 | (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))] | |
e075ae69 RH |
13348 | "") |
13349 | ||
13350 | ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. | |
13351 | ;; Don't split NOTs with a displacement operand, because resulting XOR | |
13352 | ;; will not be pariable anyway. | |
13353 | ;; | |
13354 | ;; On AMD K6, NOT is vector decoded with memory operand that can not be | |
13355 | ;; represented using a modRM byte. The XOR replacement is long decoded, | |
13356 | ;; so this split helps here as well. | |
13357 | ;; | |
23280139 RH |
13358 | ;; Note: Can't do this as a regular split because we can't get proper |
13359 | ;; lifetime information then. | |
e075ae69 RH |
13360 | |
13361 | (define_peephole2 | |
13362 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
13363 | (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] | |
13364 | "!optimize_size | |
23280139 | 13365 | && peep2_regno_dead_p (0, FLAGS_REG) |
e075ae69 RH |
13366 | && ((TARGET_PENTIUM |
13367 | && (GET_CODE (operands[0]) != MEM | |
13368 | || !memory_displacement_operand (operands[0], SImode))) | |
13369 | || (TARGET_K6 && long_memory_operand (operands[0], SImode)))" | |
13370 | [(parallel [(set (match_dup 0) | |
13371 | (xor:SI (match_dup 1) (const_int -1))) | |
13372 | (clobber (reg:CC 17))])] | |
13373 | "") | |
13374 | ||
13375 | (define_peephole2 | |
13376 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
13377 | (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] | |
13378 | "!optimize_size | |
23280139 | 13379 | && peep2_regno_dead_p (0, FLAGS_REG) |
e075ae69 RH |
13380 | && ((TARGET_PENTIUM |
13381 | && (GET_CODE (operands[0]) != MEM | |
13382 | || !memory_displacement_operand (operands[0], HImode))) | |
13383 | || (TARGET_K6 && long_memory_operand (operands[0], HImode)))" | |
13384 | [(parallel [(set (match_dup 0) | |
13385 | (xor:HI (match_dup 1) (const_int -1))) | |
13386 | (clobber (reg:CC 17))])] | |
13387 | "") | |
13388 | ||
13389 | (define_peephole2 | |
13390 | [(set (match_operand:QI 0 "nonimmediate_operand" "=rm") | |
13391 | (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] | |
13392 | "!optimize_size | |
23280139 | 13393 | && peep2_regno_dead_p (0, FLAGS_REG) |
e075ae69 RH |
13394 | && ((TARGET_PENTIUM |
13395 | && (GET_CODE (operands[0]) != MEM | |
13396 | || !memory_displacement_operand (operands[0], QImode))) | |
13397 | || (TARGET_K6 && long_memory_operand (operands[0], QImode)))" | |
13398 | [(parallel [(set (match_dup 0) | |
13399 | (xor:QI (match_dup 1) (const_int -1))) | |
13400 | (clobber (reg:CC 17))])] | |
13401 | "") | |
13402 | ||
13403 | ;; Non pairable "test imm, reg" instructions can be translated to | |
13404 | ;; "and imm, reg" if reg dies. The "and" form is also shorter (one | |
13405 | ;; byte opcode instead of two, have a short form for byte operands), | |
13406 | ;; so do it for other CPUs as well. Given that the value was dead, | |
13407 | ;; this should not create any new dependancies. Pass on the sub-word | |
13408 | ;; versions if we're concerned about partial register stalls. | |
13409 | ||
13410 | (define_peephole2 | |
16189740 RH |
13411 | [(set (reg 17) |
13412 | (compare (and:SI (match_operand:SI 0 "register_operand" "") | |
13413 | (match_operand:SI 1 "immediate_operand" "")) | |
13414 | (const_int 0)))] | |
13415 | "ix86_match_ccmode (insn, CCNOmode) | |
13416 | && (true_regnum (operands[0]) != 0 | |
13417 | || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')) | |
e075ae69 RH |
13418 | && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))" |
13419 | [(parallel | |
13420 | [(set (reg:CCNO 17) | |
13421 | (compare:CCNO (and:SI (match_dup 0) | |
13422 | (match_dup 1)) | |
13423 | (const_int 0))) | |
13424 | (set (match_dup 0) | |
13425 | (and:SI (match_dup 0) (match_dup 1)))])] | |
13426 | "") | |
13427 | ||
e9e80858 JH |
13428 | ;; We don't need to handle HImode case, because it will be promoted to SImode |
13429 | ;; on ! TARGET_PARTIAL_REG_STALL | |
e075ae69 RH |
13430 | |
13431 | (define_peephole2 | |
16189740 RH |
13432 | [(set (reg 17) |
13433 | (compare (and:QI (match_operand:QI 0 "register_operand" "") | |
13434 | (match_operand:QI 1 "immediate_operand" "")) | |
13435 | (const_int 0)))] | |
e075ae69 | 13436 | "! TARGET_PARTIAL_REG_STALL |
16189740 | 13437 | && ix86_match_ccmode (insn, CCNOmode) |
e075ae69 RH |
13438 | && true_regnum (operands[0]) != 0 |
13439 | && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))" | |
13440 | [(parallel | |
13441 | [(set (reg:CCNO 17) | |
13442 | (compare:CCNO (and:QI (match_dup 0) | |
13443 | (match_dup 1)) | |
13444 | (const_int 0))) | |
13445 | (set (match_dup 0) | |
13446 | (and:QI (match_dup 0) (match_dup 1)))])] | |
13447 | "") | |
13448 | ||
13449 | (define_peephole2 | |
16189740 RH |
13450 | [(set (reg 17) |
13451 | (compare | |
e075ae69 RH |
13452 | (and:SI |
13453 | (zero_extract:SI | |
13454 | (match_operand 0 "ext_register_operand" "q") | |
13455 | (const_int 8) | |
13456 | (const_int 8)) | |
13457 | (match_operand 1 "const_int_operand" "n")) | |
13458 | (const_int 0)))] | |
13459 | "! TARGET_PARTIAL_REG_STALL | |
16189740 | 13460 | && ix86_match_ccmode (insn, CCNOmode) |
e075ae69 RH |
13461 | && true_regnum (operands[0]) != 0 |
13462 | && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))" | |
13463 | [(parallel [(set (reg:CCNO 17) | |
13464 | (compare:CCNO | |
13465 | (and:SI | |
13466 | (zero_extract:SI | |
13467 | (match_dup 0) | |
13468 | (const_int 8) | |
13469 | (const_int 8)) | |
13470 | (match_dup 1)) | |
13471 | (const_int 0))) | |
13472 | (set (zero_extract:SI (match_dup 0) | |
13473 | (const_int 8) | |
13474 | (const_int 8)) | |
13475 | (and:SI | |
13476 | (zero_extract:SI | |
13477 | (match_dup 0) | |
13478 | (const_int 8) | |
13479 | (const_int 8)) | |
13480 | (match_dup 1)))])] | |
13481 | "") | |
13482 | ||
13483 | ;; Don't do logical operations with memory inputs. | |
13484 | (define_peephole2 | |
13485 | [(match_scratch:SI 2 "r") | |
13486 | (parallel [(set (match_operand:SI 0 "register_operand" "") | |
13487 | (match_operator:SI 3 "arith_or_logical_operator" | |
13488 | [(match_dup 0) | |
13489 | (match_operand:SI 1 "memory_operand" "")])) | |
13490 | (clobber (reg:CC 17))])] | |
13491 | "! optimize_size && ! TARGET_READ_MODIFY" | |
13492 | [(set (match_dup 2) (match_dup 1)) | |
13493 | (parallel [(set (match_dup 0) | |
13494 | (match_op_dup 3 [(match_dup 0) (match_dup 2)])) | |
13495 | (clobber (reg:CC 17))])] | |
13496 | "") | |
13497 | ||
13498 | (define_peephole2 | |
13499 | [(match_scratch:SI 2 "r") | |
13500 | (parallel [(set (match_operand:SI 0 "register_operand" "") | |
13501 | (match_operator:SI 3 "arith_or_logical_operator" | |
13502 | [(match_operand:SI 1 "memory_operand" "") | |
13503 | (match_dup 0)])) | |
13504 | (clobber (reg:CC 17))])] | |
13505 | "! optimize_size && ! TARGET_READ_MODIFY" | |
13506 | [(set (match_dup 2) (match_dup 1)) | |
13507 | (parallel [(set (match_dup 0) | |
13508 | (match_op_dup 3 [(match_dup 2) (match_dup 0)])) | |
13509 | (clobber (reg:CC 17))])] | |
13510 | "") | |
13511 | ||
13512 | ; Don't do logical operations with memory outputs | |
13513 | ; | |
13514 | ; These two don't make sense for PPro/PII -- we're expanding a 4-uop | |
13515 | ; instruction into two 1-uop insns plus a 2-uop insn. That last has | |
13516 | ; the same decoder scheduling characteristics as the original. | |
13517 | ||
13518 | (define_peephole2 | |
13519 | [(match_scratch:SI 2 "r") | |
13520 | (parallel [(set (match_operand:SI 0 "memory_operand" "") | |
13521 | (match_operator:SI 3 "arith_or_logical_operator" | |
13522 | [(match_dup 0) | |
13523 | (match_operand:SI 1 "nonmemory_operand" "")])) | |
13524 | (clobber (reg:CC 17))])] | |
13525 | "! optimize_size && ! TARGET_READ_MODIFY_WRITE" | |
13526 | [(set (match_dup 2) (match_dup 0)) | |
13527 | (parallel [(set (match_dup 2) | |
13528 | (match_op_dup 3 [(match_dup 2) (match_dup 1)])) | |
13529 | (clobber (reg:CC 17))]) | |
13530 | (set (match_dup 0) (match_dup 2))] | |
13531 | "") | |
13532 | ||
13533 | (define_peephole2 | |
13534 | [(match_scratch:SI 2 "r") | |
13535 | (parallel [(set (match_operand:SI 0 "memory_operand" "") | |
13536 | (match_operator:SI 3 "arith_or_logical_operator" | |
13537 | [(match_operand:SI 1 "nonmemory_operand" "") | |
13538 | (match_dup 0)])) | |
13539 | (clobber (reg:CC 17))])] | |
13540 | "! optimize_size && ! TARGET_READ_MODIFY_WRITE" | |
13541 | [(set (match_dup 2) (match_dup 0)) | |
13542 | (parallel [(set (match_dup 2) | |
13543 | (match_op_dup 3 [(match_dup 1) (match_dup 2)])) | |
13544 | (clobber (reg:CC 17))]) | |
13545 | (set (match_dup 0) (match_dup 2))] | |
13546 | "") | |
13547 | ||
13548 | ;; Attempt to always use XOR for zeroing registers. | |
13549 | (define_peephole2 | |
13550 | [(set (match_operand 0 "register_operand" "") | |
13551 | (const_int 0))] | |
13552 | "(GET_MODE (operands[0]) == QImode | |
13553 | || GET_MODE (operands[0]) == HImode | |
13554 | || GET_MODE (operands[0]) == SImode) | |
13555 | && (! TARGET_USE_MOV0 || optimize_size) | |
23280139 | 13556 | && peep2_regno_dead_p (0, FLAGS_REG)" |
e075ae69 RH |
13557 | [(parallel [(set (match_dup 0) (const_int 0)) |
13558 | (clobber (reg:CC 17))])] | |
591702de | 13559 | "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));") |
d3a923ee | 13560 | |
6ef67412 JH |
13561 | (define_peephole2 |
13562 | [(set (strict_low_part (match_operand 0 "register_operand" "")) | |
13563 | (const_int 0))] | |
13564 | "(GET_MODE (operands[0]) == QImode | |
13565 | || GET_MODE (operands[0]) == HImode) | |
13566 | && (! TARGET_USE_MOV0 || optimize_size) | |
13567 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
13568 | [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) | |
13569 | (clobber (reg:CC 17))])]) | |
13570 | ||
e075ae69 RH |
13571 | ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg. |
13572 | (define_peephole2 | |
591702de | 13573 | [(set (match_operand 0 "register_operand" "") |
e075ae69 | 13574 | (const_int -1))] |
591702de JH |
13575 | "(GET_MODE (operands[0]) == HImode |
13576 | || GET_MODE (operands[0]) == SImode) | |
13577 | && (optimize_size || TARGET_PENTIUM) | |
23280139 | 13578 | && peep2_regno_dead_p (0, FLAGS_REG)" |
591702de | 13579 | [(parallel [(set (match_dup 0) (const_int -1)) |
e075ae69 | 13580 | (clobber (reg:CC 17))])] |
591702de | 13581 | "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));") |
1c27d4b2 JH |
13582 | |
13583 | ;; Attempt to convert simple leas to adds. These can be created by | |
13584 | ;; move expanders. | |
13585 | (define_peephole2 | |
13586 | [(set (match_operand:SI 0 "register_operand" "") | |
13587 | (plus:SI (match_dup 0) | |
13588 | (match_operand:SI 1 "nonmemory_operand" "")))] | |
23280139 | 13589 | "peep2_regno_dead_p (0, FLAGS_REG)" |
1c27d4b2 JH |
13590 | [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) |
13591 | (clobber (reg:CC 17))])] | |
13592 | "") | |
13593 | ||
13594 | (define_peephole2 | |
13595 | [(set (match_operand:SI 0 "register_operand" "") | |
13596 | (mult:SI (match_dup 0) | |
13597 | (match_operand:SI 1 "immediate_operand" "")))] | |
23280139 RH |
13598 | "exact_log2 (INTVAL (operands[1])) >= 0 |
13599 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
1c27d4b2 JH |
13600 | [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) |
13601 | (clobber (reg:CC 17))])] | |
13602 | "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") | |
bdeb029c JH |
13603 | |
13604 | ;; The ESP adjustments can be done by the push and pop instructions. Resulting | |
13605 | ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On | |
13606 | ;; many CPUs it is also faster, since special hardware to avoid esp | |
13607 | ;; dependancies is present. | |
13608 | ||
13609 | ;; While some of these converisons may be done using splitters, we use peepholes | |
13610 | ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL. | |
13611 | ||
13612 | ;; Convert prologue esp substractions to push. | |
13613 | ;; We need register to push. In order to keep verify_flow_info happy we have | |
13614 | ;; two choices | |
13615 | ;; - use scratch and clobber it in order to avoid dependencies | |
13616 | ;; - use already live register | |
13617 | ;; We can't use the second way right now, since there is no reliable way how to | |
13618 | ;; verify that given register is live. First choice will also most likely in | |
13619 | ;; fewer dependencies. On the place of esp adjustments it is very likely that | |
13620 | ;; call clobbered registers are dead. We may want to use base pointer as an | |
13621 | ;; alternative when no register is available later. | |
13622 | ||
13623 | (define_peephole2 | |
13624 | [(match_scratch:SI 0 "r") | |
13625 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4))) | |
13626 | (set (reg:SI 6) (reg:SI 6)) | |
13627 | (clobber (reg:CC 17))])] | |
13628 | "optimize_size || !TARGET_SUB_ESP_4" | |
13629 | [(clobber (match_dup 0)) | |
13630 | (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0)) | |
13631 | (set (reg:SI 6) (reg:SI 6))])]) | |
13632 | ||
13633 | (define_peephole2 | |
13634 | [(match_scratch:SI 0 "r") | |
13635 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8))) | |
13636 | (set (reg:SI 6) (reg:SI 6)) | |
13637 | (clobber (reg:CC 17))])] | |
13638 | "optimize_size || !TARGET_SUB_ESP_8" | |
13639 | [(clobber (match_dup 0)) | |
13640 | (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0)) | |
13641 | (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0)) | |
13642 | (set (reg:SI 6) (reg:SI 6))])]) | |
13643 | ||
13644 | ;; Convert esp substractions to push. | |
13645 | (define_peephole2 | |
13646 | [(match_scratch:SI 0 "r") | |
13647 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4))) | |
13648 | (clobber (reg:CC 17))])] | |
13649 | "optimize_size || !TARGET_SUB_ESP_4" | |
13650 | [(clobber (match_dup 0)) | |
13651 | (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))]) | |
13652 | ||
13653 | (define_peephole2 | |
13654 | [(match_scratch:SI 0 "r") | |
13655 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8))) | |
13656 | (clobber (reg:CC 17))])] | |
13657 | "optimize_size || !TARGET_SUB_ESP_8" | |
13658 | [(clobber (match_dup 0)) | |
13659 | (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0)) | |
13660 | (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))]) | |
13661 | ||
13662 | ;; Convert epilogue deallocator to pop. | |
13663 | (define_peephole2 | |
13664 | [(match_scratch:SI 0 "r") | |
13665 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4))) | |
13666 | (set (reg:SI 6) (reg:SI 6)) | |
13667 | (clobber (reg:CC 17))])] | |
13668 | "optimize_size || !TARGET_ADD_ESP_4" | |
13669 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7))) | |
13670 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4))) | |
13671 | (set (reg:SI 6) (reg:SI 6))])] | |
13672 | "") | |
13673 | ||
13674 | ;; Two pops case is tricky, since pop causes dependency on destination register. | |
13675 | ;; We use two registers if available. | |
13676 | (define_peephole2 | |
13677 | [(match_scratch:SI 0 "r") | |
13678 | (match_scratch:SI 1 "r") | |
13679 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8))) | |
13680 | (set (reg:SI 6) (reg:SI 6)) | |
13681 | (clobber (reg:CC 17))])] | |
13682 | "optimize_size || !TARGET_ADD_ESP_8" | |
13683 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7))) | |
13684 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4))) | |
13685 | (set (reg:SI 6) (reg:SI 6))]) | |
13686 | (parallel [(set (match_dup 1) (mem:SI (reg:SI 7))) | |
13687 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])] | |
13688 | "") | |
13689 | ||
13690 | (define_peephole2 | |
13691 | [(match_scratch:SI 0 "r") | |
13692 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8))) | |
13693 | (set (reg:SI 6) (reg:SI 6)) | |
13694 | (clobber (reg:CC 17))])] | |
13695 | "optimize_size" | |
13696 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7))) | |
13697 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4))) | |
13698 | (set (reg:SI 6) (reg:SI 6))]) | |
13699 | (parallel [(set (match_dup 0) (mem:SI (reg:SI 7))) | |
13700 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])] | |
13701 | "") | |
13702 | ||
13703 | ;; Convert esp additions to pop. | |
13704 | (define_peephole2 | |
13705 | [(match_scratch:SI 0 "r") | |
13706 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4))) | |
13707 | (clobber (reg:CC 17))])] | |
13708 | "" | |
13709 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7))) | |
13710 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])] | |
13711 | "") | |
13712 | ||
13713 | ;; Two pops case is tricky, since pop causes dependency on destination register. | |
13714 | ;; We use two registers if available. | |
13715 | (define_peephole2 | |
13716 | [(match_scratch:SI 0 "r") | |
13717 | (match_scratch:SI 1 "r") | |
13718 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8))) | |
13719 | (clobber (reg:CC 17))])] | |
13720 | "" | |
13721 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7))) | |
13722 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]) | |
13723 | (parallel [(set (match_dup 1) (mem:SI (reg:SI 7))) | |
13724 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])] | |
13725 | "") | |
13726 | ||
13727 | (define_peephole2 | |
13728 | [(match_scratch:SI 0 "r") | |
13729 | (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8))) | |
13730 | (clobber (reg:CC 17))])] | |
13731 | "optimize_size" | |
13732 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7))) | |
13733 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]) | |
13734 | (parallel [(set (match_dup 0) (mem:SI (reg:SI 7))) | |
13735 | (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])] | |
13736 | "") | |
69404d6f | 13737 | \f |
9dcbdc7e JH |
13738 | ;; Convert compares with 1 to shorter inc/dec operations when CF is not |
13739 | ;; required and register dies. | |
13740 | (define_peephole2 | |
13741 | [(set (reg 17) | |
13742 | (compare (match_operand:SI 0 "register_operand" "") | |
13743 | (match_operand:SI 1 "incdec_operand" "")))] | |
13744 | "ix86_match_ccmode (insn, CCGCmode) | |
13745 | && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))" | |
13746 | [(parallel [(set (reg:CCGC 17) | |
265dab10 | 13747 | (compare:CCGC (match_dup 0) |
7e08e190 | 13748 | (match_dup 1))) |
9dcbdc7e | 13749 | (clobber (match_dup 0))])] |
7e08e190 | 13750 | "") |
9dcbdc7e JH |
13751 | |
13752 | (define_peephole2 | |
13753 | [(set (reg 17) | |
13754 | (compare (match_operand:HI 0 "register_operand" "") | |
13755 | (match_operand:HI 1 "incdec_operand" "")))] | |
13756 | "ix86_match_ccmode (insn, CCGCmode) | |
13757 | && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))" | |
13758 | [(parallel [(set (reg:CCGC 17) | |
265dab10 | 13759 | (compare:CCGC (match_dup 0) |
7e08e190 | 13760 | (match_dup 1))) |
9dcbdc7e | 13761 | (clobber (match_dup 0))])] |
7e08e190 | 13762 | "") |
9dcbdc7e JH |
13763 | |
13764 | (define_peephole2 | |
13765 | [(set (reg 17) | |
13766 | (compare (match_operand:QI 0 "register_operand" "") | |
13767 | (match_operand:QI 1 "incdec_operand" "")))] | |
13768 | "ix86_match_ccmode (insn, CCGCmode) | |
13769 | && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))" | |
13770 | [(parallel [(set (reg:CCGC 17) | |
265dab10 | 13771 | (compare:CCGC (match_dup 0) |
7e08e190 | 13772 | (match_dup 1))) |
9dcbdc7e | 13773 | (clobber (match_dup 0))])] |
7e08e190 | 13774 | "") |
9dcbdc7e JH |
13775 | |
13776 | ;; Convert compares with 128 to shorter add -128 | |
13777 | (define_peephole2 | |
13778 | [(set (reg 17) | |
13779 | (compare (match_operand:SI 0 "register_operand" "") | |
13780 | (const_int 128)))] | |
7e08e190 | 13781 | "ix86_match_ccmode (insn, CCGCmode) |
9dcbdc7e | 13782 | && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))" |
7e08e190 JH |
13783 | [(parallel [(set (reg:CCGC 17) |
13784 | (compare:CCGC (match_dup 0) | |
13785 | (const_int 128))) | |
9dcbdc7e JH |
13786 | (clobber (match_dup 0))])] |
13787 | "") | |
13788 | ||
13789 | (define_peephole2 | |
13790 | [(set (reg 17) | |
13791 | (compare (match_operand:HI 0 "register_operand" "") | |
13792 | (const_int 128)))] | |
7e08e190 | 13793 | "ix86_match_ccmode (insn, CCGCmode) |
9dcbdc7e | 13794 | && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))" |
7e08e190 JH |
13795 | [(parallel [(set (reg:CCGC 17) |
13796 | (compare:CCGC (match_dup 0) | |
13797 | (const_int 128))) | |
9dcbdc7e JH |
13798 | (clobber (match_dup 0))])] |
13799 | "") | |
13800 | \f | |
69404d6f RH |
13801 | ;; Call-value patterns last so that the wildcard operand does not |
13802 | ;; disrupt insn-recog's switch tables. | |
13803 | ||
94bb5d0c RH |
13804 | (define_insn "*call_value_pop_0" |
13805 | [(set (match_operand 0 "" "") | |
e1ff012c | 13806 | (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) |
94bb5d0c RH |
13807 | (match_operand:SI 2 "" ""))) |
13808 | (set (reg:SI 7) (plus:SI (reg:SI 7) | |
90d10fb9 | 13809 | (match_operand:SI 3 "immediate_operand" "")))] |
1e07edd3 | 13810 | "!TARGET_64BIT" |
94bb5d0c RH |
13811 | "* |
13812 | { | |
13813 | if (SIBLING_CALL_P (insn)) | |
13814 | return \"jmp\\t%P1\"; | |
13815 | else | |
13816 | return \"call\\t%P1\"; | |
13817 | }" | |
13818 | [(set_attr "type" "callv")]) | |
13819 | ||
69404d6f RH |
13820 | (define_insn "*call_value_pop_1" |
13821 | [(set (match_operand 0 "" "") | |
e1ff012c | 13822 | (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) |
94bb5d0c | 13823 | (match_operand:SI 2 "" ""))) |
69404d6f | 13824 | (set (reg:SI 7) (plus:SI (reg:SI 7) |
90d10fb9 | 13825 | (match_operand:SI 3 "immediate_operand" "i")))] |
1e07edd3 | 13826 | "!TARGET_64BIT" |
69404d6f RH |
13827 | "* |
13828 | { | |
94bb5d0c RH |
13829 | if (constant_call_address_operand (operands[1], QImode)) |
13830 | { | |
13831 | if (SIBLING_CALL_P (insn)) | |
13832 | return \"jmp\\t%P1\"; | |
13833 | else | |
13834 | return \"call\\t%P1\"; | |
13835 | } | |
94bb5d0c | 13836 | if (SIBLING_CALL_P (insn)) |
fb204271 | 13837 | return \"jmp\\t%A1\"; |
94bb5d0c | 13838 | else |
fb204271 | 13839 | return \"call\\t%A1\"; |
94bb5d0c RH |
13840 | }" |
13841 | [(set_attr "type" "callv")]) | |
13842 | ||
13843 | (define_insn "*call_value_0" | |
13844 | [(set (match_operand 0 "" "") | |
e1ff012c | 13845 | (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) |
94bb5d0c RH |
13846 | (match_operand:SI 2 "" "")))] |
13847 | "" | |
13848 | "* | |
13849 | { | |
13850 | if (SIBLING_CALL_P (insn)) | |
13851 | return \"jmp\\t%P1\"; | |
13852 | else | |
13853 | return \"call\\t%P1\"; | |
69404d6f RH |
13854 | }" |
13855 | [(set_attr "type" "callv")]) | |
13856 | ||
69404d6f RH |
13857 | (define_insn "*call_value_1" |
13858 | [(set (match_operand 0 "" "") | |
e1ff012c | 13859 | (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) |
94bb5d0c | 13860 | (match_operand:SI 2 "" "")))] |
69404d6f RH |
13861 | "" |
13862 | "* | |
13863 | { | |
94bb5d0c | 13864 | if (constant_call_address_operand (operands[1], QImode)) |
cbbf65e0 RH |
13865 | { |
13866 | if (SIBLING_CALL_P (insn)) | |
13867 | return \"jmp\\t%P1\"; | |
13868 | else | |
13869 | return \"call\\t%P1\"; | |
13870 | } | |
cbbf65e0 | 13871 | if (SIBLING_CALL_P (insn)) |
fb204271 | 13872 | return \"jmp\\t%A1\"; |
cbbf65e0 | 13873 | else |
fb204271 | 13874 | return \"call\\t%A1\"; |
69404d6f RH |
13875 | }" |
13876 | [(set_attr "type" "callv")]) | |
9e3e266c GM |
13877 | \f |
13878 | (define_insn "trap" | |
13879 | [(trap_if (const_int 1) (const_int 5))] | |
13880 | "" | |
13881 | "int\\t$5") | |
13882 | ||
13883 | ;;; ix86 doesn't have conditional trap instructions, but we fake them | |
13884 | ;;; for the sake of bounds checking. By emitting bounds checks as | |
13885 | ;;; conditional traps rather than as conditional jumps around | |
13886 | ;;; unconditional traps we avoid introducing spurious basic-block | |
13887 | ;;; boundaries and facilitate elimination of redundant checks. In | |
13888 | ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use | |
13889 | ;;; interrupt 5. | |
13890 | ;;; | |
13891 | ;;; FIXME: Static branch prediction rules for ix86 are such that | |
13892 | ;;; forward conditional branches predict as untaken. As implemented | |
13893 | ;;; below, pseudo conditional traps violate that rule. We should use | |
13894 | ;;; .pushsection/.popsection to place all of the `int 5's in a special | |
13895 | ;;; section loaded at the end of the text segment and branch forward | |
13896 | ;;; there on bounds-failure, and then jump back immediately (in case | |
13897 | ;;; the system chooses to ignore bounds violations, or to report | |
13898 | ;;; violations and continue execution). | |
13899 | ||
13900 | (define_expand "conditional_trap" | |
13901 | [(trap_if (match_operator 0 "comparison_operator" | |
13902 | [(match_dup 2) (const_int 0)]) | |
13903 | (match_operand 1 "const_int_operand" ""))] | |
13904 | "" | |
13905 | " | |
13906 | { | |
13907 | emit_insn (gen_rtx_TRAP_IF (VOIDmode, | |
a1b8572c JH |
13908 | ix86_expand_compare (GET_CODE (operands[0]), |
13909 | NULL_RTX, NULL_RTX), | |
9e3e266c GM |
13910 | operands[1])); |
13911 | DONE; | |
13912 | }") | |
13913 | ||
13914 | (define_insn "" | |
13915 | [(trap_if (match_operator 0 "comparison_operator" | |
13916 | [(reg 17) (const_int 0)]) | |
13917 | (match_operand 1 "const_int_operand" ""))] | |
13918 | "" | |
13919 | "* | |
13920 | { | |
13921 | operands[2] = gen_label_rtx (); | |
13922 | output_asm_insn (\"j%c0\\t%l2\; int\\t%1\", operands); | |
13923 | ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", | |
13924 | CODE_LABEL_NUMBER (operands[2])); | |
13925 | RET; | |
13926 | }") | |
915119a5 BS |
13927 | |
13928 | ;; Pentium III SIMD instructions. | |
13929 | ||
13930 | ;; Moves for SSE/MMX regs. | |
13931 | ||
13932 | (define_insn "movv4sf_internal" | |
13933 | [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m") | |
13934 | (match_operand:V4SF 1 "general_operand" "xm,x"))] | |
13935 | "TARGET_SSE" | |
13936 | ;; @@@ let's try to use movaps here. | |
13937 | "movaps\\t{%1, %0|%0, %1}" | |
13938 | [(set_attr "type" "sse")]) | |
13939 | ||
13940 | (define_insn "movv4si_internal" | |
13941 | [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m") | |
13942 | (match_operand:V4SI 1 "general_operand" "xm,x"))] | |
13943 | "TARGET_SSE" | |
13944 | ;; @@@ let's try to use movaps here. | |
13945 | "movaps\\t{%1, %0|%0, %1}" | |
13946 | [(set_attr "type" "sse")]) | |
13947 | ||
13948 | (define_insn "movv8qi_internal" | |
13949 | [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m") | |
13950 | (match_operand:V8QI 1 "general_operand" "ym,y"))] | |
13951 | "TARGET_MMX" | |
13952 | "movq\\t{%1, %0|%0, %1}" | |
13953 | [(set_attr "type" "mmx")]) | |
13954 | ||
13955 | (define_insn "movv4hi_internal" | |
13956 | [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m") | |
13957 | (match_operand:V4HI 1 "general_operand" "ym,y"))] | |
13958 | "TARGET_MMX" | |
13959 | "movq\\t{%1, %0|%0, %1}" | |
13960 | [(set_attr "type" "mmx")]) | |
13961 | ||
13962 | (define_insn "movv2si_internal" | |
13963 | [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m") | |
13964 | (match_operand:V2SI 1 "general_operand" "ym,y"))] | |
13965 | "TARGET_MMX" | |
13966 | "movq\\t{%1, %0|%0, %1}" | |
13967 | [(set_attr "type" "mmx")]) | |
13968 | ||
13969 | (define_expand "movti" | |
13970 | [(set (match_operand:TI 0 "general_operand" "") | |
13971 | (match_operand:TI 1 "general_operand" ""))] | |
13972 | "TARGET_SSE" | |
13973 | " | |
13974 | { | |
13975 | /* For constants other than zero into memory. We do not know how the | |
13976 | instructions used to build constants modify the upper 64 bits | |
13977 | of the register, once we have that information we may be able | |
13978 | to handle some of them more efficiently. */ | |
13979 | if ((reload_in_progress | reload_completed) == 0 | |
13980 | && register_operand (operands[0], TImode) | |
13981 | && CONSTANT_P (operands[1])) | |
13982 | { | |
13983 | rtx addr = gen_reg_rtx (Pmode); | |
13984 | ||
13985 | emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0)); | |
13986 | operands[1] = gen_rtx_MEM (TImode, addr); | |
13987 | } | |
13988 | ||
13989 | /* Make operand1 a register if it isn't already. */ | |
13990 | if ((reload_in_progress | reload_completed) == 0 | |
13991 | && !register_operand (operands[0], TImode) | |
13992 | && !register_operand (operands[1], TImode) | |
13993 | && operands[1] != CONST0_RTX (TImode)) | |
13994 | { | |
13995 | rtx temp = force_reg (TImode, operands[1]); | |
13996 | emit_move_insn (operands[0], temp); | |
13997 | DONE; | |
13998 | } | |
13999 | }") | |
14000 | ||
14001 | (define_expand "movv4sf" | |
14002 | [(set (match_operand:V4SF 0 "general_operand" "") | |
14003 | (match_operand:V4SF 1 "general_operand" ""))] | |
14004 | "TARGET_SSE" | |
14005 | " | |
14006 | { | |
14007 | /* For constants other than zero into memory. We do not know how the | |
14008 | instructions used to build constants modify the upper 64 bits | |
14009 | of the register, once we have that information we may be able | |
14010 | to handle some of them more efficiently. */ | |
14011 | if ((reload_in_progress | reload_completed) == 0 | |
14012 | && register_operand (operands[0], V4SFmode) | |
14013 | && CONSTANT_P (operands[1])) | |
14014 | { | |
14015 | rtx addr = gen_reg_rtx (Pmode); | |
14016 | ||
14017 | emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0)); | |
14018 | operands[1] = gen_rtx_MEM (V4SFmode, addr); | |
14019 | } | |
14020 | ||
14021 | /* Make operand1 a register if it isn't already. */ | |
14022 | if ((reload_in_progress | reload_completed) == 0 | |
14023 | && !register_operand (operands[0], V4SFmode) | |
14024 | && !register_operand (operands[1], V4SFmode) | |
14025 | && operands[1] != CONST0_RTX (V4SFmode)) | |
14026 | { | |
14027 | rtx temp = force_reg (V4SFmode, operands[1]); | |
14028 | emit_move_insn (operands[0], temp); | |
14029 | DONE; | |
14030 | } | |
14031 | }") | |
14032 | ||
14033 | (define_expand "movv4si" | |
14034 | [(set (match_operand:V4SI 0 "general_operand" "") | |
14035 | (match_operand:V4SI 1 "general_operand" ""))] | |
14036 | "TARGET_MMX" | |
14037 | " | |
14038 | { | |
14039 | /* For constants other than zero into memory. We do not know how the | |
14040 | instructions used to build constants modify the upper 64 bits | |
14041 | of the register, once we have that information we may be able | |
14042 | to handle some of them more efficiently. */ | |
14043 | if ((reload_in_progress | reload_completed) == 0 | |
14044 | && register_operand (operands[0], V4SImode) | |
14045 | && CONSTANT_P (operands[1])) | |
14046 | { | |
14047 | rtx addr = gen_reg_rtx (Pmode); | |
14048 | ||
14049 | emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0)); | |
14050 | operands[1] = gen_rtx_MEM (V4SImode, addr); | |
14051 | } | |
14052 | ||
14053 | /* Make operand1 a register if it isn't already. */ | |
14054 | if ((reload_in_progress | reload_completed) == 0 | |
14055 | && !register_operand (operands[0], V4SImode) | |
14056 | && !register_operand (operands[1], V4SImode) | |
14057 | && operands[1] != CONST0_RTX (V4SImode)) | |
14058 | { | |
14059 | rtx temp = force_reg (V4SImode, operands[1]); | |
14060 | emit_move_insn (operands[0], temp); | |
14061 | DONE; | |
14062 | } | |
14063 | }") | |
14064 | ||
14065 | (define_expand "movv2si" | |
14066 | [(set (match_operand:V2SI 0 "general_operand" "") | |
14067 | (match_operand:V2SI 1 "general_operand" ""))] | |
14068 | "TARGET_MMX" | |
14069 | " | |
14070 | { | |
14071 | /* For constants other than zero into memory. We do not know how the | |
14072 | instructions used to build constants modify the upper 64 bits | |
14073 | of the register, once we have that information we may be able | |
14074 | to handle some of them more efficiently. */ | |
14075 | if ((reload_in_progress | reload_completed) == 0 | |
14076 | && register_operand (operands[0], V2SImode) | |
14077 | && CONSTANT_P (operands[1])) | |
14078 | { | |
14079 | rtx addr = gen_reg_rtx (Pmode); | |
14080 | ||
14081 | emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0)); | |
14082 | operands[1] = gen_rtx_MEM (V2SImode, addr); | |
14083 | } | |
14084 | ||
14085 | /* Make operand1 a register if it isn't already. */ | |
14086 | if ((reload_in_progress | reload_completed) == 0 | |
14087 | && !register_operand (operands[0], V2SImode) | |
14088 | && !register_operand (operands[1], V2SImode) | |
14089 | && operands[1] != CONST0_RTX (V2SImode)) | |
14090 | { | |
14091 | rtx temp = force_reg (V2SImode, operands[1]); | |
14092 | emit_move_insn (operands[0], temp); | |
14093 | DONE; | |
14094 | } | |
14095 | }") | |
14096 | ||
14097 | (define_expand "movv4hi" | |
14098 | [(set (match_operand:V4HI 0 "general_operand" "") | |
14099 | (match_operand:V4HI 1 "general_operand" ""))] | |
14100 | "TARGET_MMX" | |
14101 | " | |
14102 | { | |
14103 | /* For constants other than zero into memory. We do not know how the | |
14104 | instructions used to build constants modify the upper 64 bits | |
14105 | of the register, once we have that information we may be able | |
14106 | to handle some of them more efficiently. */ | |
14107 | if ((reload_in_progress | reload_completed) == 0 | |
14108 | && register_operand (operands[0], V4HImode) | |
14109 | && CONSTANT_P (operands[1])) | |
14110 | { | |
14111 | rtx addr = gen_reg_rtx (Pmode); | |
14112 | ||
14113 | emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0)); | |
14114 | operands[1] = gen_rtx_MEM (V4HImode, addr); | |
14115 | } | |
14116 | ||
14117 | /* Make operand1 a register if it isn't already. */ | |
14118 | if ((reload_in_progress | reload_completed) == 0 | |
14119 | && !register_operand (operands[0], V4HImode) | |
14120 | && !register_operand (operands[1], V4HImode) | |
14121 | && operands[1] != CONST0_RTX (V4HImode)) | |
14122 | { | |
14123 | rtx temp = force_reg (V4HImode, operands[1]); | |
14124 | emit_move_insn (operands[0], temp); | |
14125 | DONE; | |
14126 | } | |
14127 | }") | |
14128 | ||
14129 | (define_expand "movv8qi" | |
14130 | [(set (match_operand:V8QI 0 "general_operand" "") | |
14131 | (match_operand:V8QI 1 "general_operand" ""))] | |
14132 | "TARGET_MMX" | |
14133 | " | |
14134 | { | |
14135 | /* For constants other than zero into memory. We do not know how the | |
14136 | instructions used to build constants modify the upper 64 bits | |
14137 | of the register, once we have that information we may be able | |
14138 | to handle some of them more efficiently. */ | |
14139 | if ((reload_in_progress | reload_completed) == 0 | |
14140 | && register_operand (operands[0], V8QImode) | |
14141 | && CONSTANT_P (operands[1])) | |
14142 | { | |
14143 | rtx addr = gen_reg_rtx (Pmode); | |
14144 | ||
14145 | emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0)); | |
14146 | operands[1] = gen_rtx_MEM (V8QImode, addr); | |
14147 | } | |
14148 | ||
14149 | /* Make operand1 a register if it isn't already. */ | |
14150 | if ((reload_in_progress | reload_completed) == 0 | |
14151 | && !register_operand (operands[0], V8QImode) | |
14152 | && !register_operand (operands[1], V8QImode) | |
14153 | && operands[1] != CONST0_RTX (V8QImode)) | |
14154 | { | |
14155 | rtx temp = force_reg (V8QImode, operands[1]); | |
14156 | emit_move_insn (operands[0], temp); | |
14157 | DONE; | |
14158 | } | |
14159 | }") | |
14160 | ||
14161 | (define_insn_and_split "*pushti" | |
14162 | [(set (match_operand:TI 0 "push_operand" "=<") | |
14163 | (match_operand:TI 1 "nonmemory_operand" "x"))] | |
14164 | "TARGET_SSE" | |
14165 | "#" | |
14166 | "" | |
14167 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16))) | |
14168 | (set (mem:TI (reg:SI 7)) (match_dup 1))] | |
14169 | "" | |
14170 | [(set_attr "type" "sse")]) | |
14171 | ||
14172 | (define_insn_and_split "*pushv4sf" | |
14173 | [(set (match_operand:V4SF 0 "push_operand" "=<") | |
14174 | (match_operand:V4SF 1 "nonmemory_operand" "x"))] | |
14175 | "TARGET_SSE" | |
14176 | "#" | |
14177 | "" | |
14178 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16))) | |
14179 | (set (mem:V4SF (reg:SI 7)) (match_dup 1))] | |
14180 | "" | |
14181 | [(set_attr "type" "sse")]) | |
14182 | ||
14183 | (define_insn_and_split "*pushv4si" | |
14184 | [(set (match_operand:V4SI 0 "push_operand" "=<") | |
14185 | (match_operand:V4SI 1 "nonmemory_operand" "x"))] | |
14186 | "TARGET_SSE" | |
14187 | "#" | |
14188 | "" | |
14189 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16))) | |
14190 | (set (mem:V4SI (reg:SI 7)) (match_dup 1))] | |
14191 | "" | |
14192 | [(set_attr "type" "sse")]) | |
14193 | ||
14194 | (define_insn_and_split "*pushv2si" | |
14195 | [(set (match_operand:V2SI 0 "push_operand" "=<") | |
14196 | (match_operand:V2SI 1 "nonmemory_operand" "y"))] | |
14197 | "TARGET_MMX" | |
14198 | "#" | |
14199 | "" | |
14200 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8))) | |
14201 | (set (mem:V2SI (reg:SI 7)) (match_dup 1))] | |
14202 | "" | |
14203 | [(set_attr "type" "mmx")]) | |
14204 | ||
14205 | (define_insn_and_split "*pushv4hi" | |
14206 | [(set (match_operand:V4HI 0 "push_operand" "=<") | |
14207 | (match_operand:V4HI 1 "nonmemory_operand" "y"))] | |
14208 | "TARGET_MMX" | |
14209 | "#" | |
14210 | "" | |
14211 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8))) | |
14212 | (set (mem:V4HI (reg:SI 7)) (match_dup 1))] | |
14213 | "" | |
14214 | [(set_attr "type" "mmx")]) | |
14215 | ||
14216 | (define_insn_and_split "*pushv8qi" | |
14217 | [(set (match_operand:V8QI 0 "push_operand" "=<") | |
14218 | (match_operand:V8QI 1 "nonmemory_operand" "y"))] | |
14219 | "TARGET_MMX" | |
14220 | "#" | |
14221 | "" | |
14222 | [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8))) | |
14223 | (set (mem:V8QI (reg:SI 7)) (match_dup 1))] | |
14224 | "" | |
14225 | [(set_attr "type" "mmx")]) | |
14226 | ||
14227 | (define_insn "movti_internal" | |
14228 | [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m") | |
14229 | (match_operand:TI 1 "general_operand" "xm,x"))] | |
14230 | "TARGET_SSE" | |
14231 | "@ | |
14232 | movaps\\t{%1, %0|%0, %1} | |
14233 | movaps\\t{%1, %0|%0, %1}" | |
14234 | [(set_attr "type" "sse")]) | |
14235 | ||
14236 | ;; These two patterns are useful for specifying exactly whether to use | |
14237 | ;; movaps or movups | |
14238 | (define_insn "sse_movaps" | |
14239 | [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m") | |
14240 | (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))] | |
14241 | "TARGET_SSE" | |
14242 | "@ | |
14243 | movaps\\t{%1, %0|%0, %1} | |
14244 | movaps\\t{%1, %0|%0, %1}" | |
14245 | [(set_attr "type" "sse")]) | |
14246 | ||
14247 | (define_insn "sse_movups" | |
14248 | [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m") | |
14249 | (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))] | |
14250 | "TARGET_SSE" | |
14251 | "@ | |
14252 | movups\\t{%1, %0|%0, %1} | |
14253 | movups\\t{%1, %0|%0, %1}" | |
14254 | [(set_attr "type" "sse")]) | |
14255 | ||
14256 | ||
14257 | ;; SSE Strange Moves. | |
14258 | ||
14259 | (define_insn "sse_movmskps" | |
14260 | [(set (match_operand:SI 0 "register_operand" "=r") | |
14261 | (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))] | |
14262 | "TARGET_SSE" | |
14263 | "movmskps\\t{%1, %0|%0, %1}" | |
14264 | [(set_attr "type" "sse")]) | |
14265 | ||
14266 | (define_insn "mmx_pmovmskb" | |
14267 | [(set (match_operand:SI 0 "register_operand" "=r") | |
14268 | (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))] | |
14269 | "TARGET_SSE" | |
14270 | "pmovmskb\\t{%1, %0|%0, %1}" | |
14271 | [(set_attr "type" "sse")]) | |
14272 | ||
14273 | (define_insn "mmx_maskmovq" | |
14274 | [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D")) | |
14275 | (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") | |
14276 | (match_operand:V8QI 2 "register_operand" "y")] 32))] | |
14277 | "TARGET_SSE" | |
14278 | ;; @@@ check ordering of operands in intel/nonintel syntax | |
14279 | "maskmovq\\t{%2, %1|%1, %2}" | |
14280 | [(set_attr "type" "sse")]) | |
14281 | ||
14282 | (define_insn "sse_movntv4sf" | |
14283 | [(set (match_operand:V4SF 0 "memory_operand" "=m") | |
14284 | (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))] | |
14285 | "TARGET_SSE" | |
14286 | "movntps\\t{%1, %0|%0, %1}" | |
14287 | [(set_attr "type" "sse")]) | |
14288 | ||
14289 | (define_insn "sse_movntdi" | |
14290 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
332316cd | 14291 | (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))] |
915119a5 BS |
14292 | "TARGET_SSE" |
14293 | "movntq\\t{%1, %0|%0, %1}" | |
14294 | [(set_attr "type" "sse")]) | |
14295 | ||
14296 | (define_insn "sse_movhlps" | |
14297 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14298 | (vec_merge:V4SF | |
14299 | (match_operand:V4SF 1 "register_operand" "0") | |
14300 | (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x") | |
14301 | (parallel [(const_int 2) | |
14302 | (const_int 3) | |
14303 | (const_int 0) | |
14304 | (const_int 1)])) | |
14305 | (const_int 3)))] | |
14306 | "TARGET_SSE" | |
14307 | "movhlps\\t{%2, %0|%0, %2}" | |
14308 | [(set_attr "type" "sse")]) | |
14309 | ||
14310 | (define_insn "sse_movlhps" | |
14311 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14312 | (vec_merge:V4SF | |
14313 | (match_operand:V4SF 1 "register_operand" "0") | |
14314 | (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x") | |
14315 | (parallel [(const_int 2) | |
14316 | (const_int 3) | |
14317 | (const_int 0) | |
14318 | (const_int 1)])) | |
14319 | (const_int 12)))] | |
14320 | "TARGET_SSE" | |
14321 | "movlhps\\t{%2, %0|%0, %2}" | |
14322 | [(set_attr "type" "sse")]) | |
14323 | ||
14324 | (define_insn "sse_movhps" | |
14325 | [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m") | |
14326 | (vec_merge:V4SF | |
14327 | (match_operand:V4SF 1 "nonimmediate_operand" "0,0") | |
14328 | (match_operand:V4SF 2 "nonimmediate_operand" "m,x") | |
14329 | (const_int 12)))] | |
14330 | "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)" | |
14331 | "movhps\\t{%2, %0|%0, %2}" | |
14332 | [(set_attr "type" "sse")]) | |
14333 | ||
14334 | (define_insn "sse_movlps" | |
14335 | [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m") | |
14336 | (vec_merge:V4SF | |
14337 | (match_operand:V4SF 1 "nonimmediate_operand" "0,0") | |
14338 | (match_operand:V4SF 2 "nonimmediate_operand" "m,x") | |
14339 | (const_int 3)))] | |
14340 | "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)" | |
14341 | "movlps\\t{%2, %0|%0, %2}" | |
14342 | [(set_attr "type" "sse")]) | |
14343 | ||
14344 | (define_insn "sse_loadss" | |
14345 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14346 | (vec_merge:V4SF | |
14347 | (match_operand:V4SF 1 "memory_operand" "m") | |
14348 | (vec_duplicate:V4SF (float:SF (const_int 0))) | |
14349 | (const_int 1)))] | |
14350 | "TARGET_SSE" | |
14351 | "movss\\t{%1, %0|%0, %1}" | |
14352 | [(set_attr "type" "sse")]) | |
14353 | ||
14354 | (define_insn "sse_movss" | |
14355 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14356 | (vec_merge:V4SF | |
14357 | (match_operand:V4SF 1 "register_operand" "0") | |
14358 | (match_operand:V4SF 2 "register_operand" "x") | |
14359 | (const_int 1)))] | |
14360 | "TARGET_SSE" | |
14361 | "movss\\t{%2, %0|%0, %2}" | |
14362 | [(set_attr "type" "sse")]) | |
14363 | ||
14364 | (define_insn "sse_storess" | |
14365 | [(set (match_operand:SF 0 "memory_operand" "=m") | |
14366 | (vec_select:SF | |
14367 | (match_operand:V4SF 1 "register_operand" "x") | |
14368 | (parallel [(const_int 0)])))] | |
14369 | "TARGET_SSE" | |
14370 | "movss\\t{%1, %0|%0, %1}" | |
14371 | [(set_attr "type" "sse")]) | |
14372 | ||
14373 | (define_insn "sse_shufps" | |
14374 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14375 | (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0") | |
14376 | (match_operand:V4SF 2 "nonimmediate_operand" "xm") | |
14377 | (match_operand:SI 3 "immediate_operand" "i")] 41))] | |
14378 | "TARGET_SSE" | |
14379 | ;; @@@ check operand order for intel/nonintel syntax | |
14380 | "shufps\\t{%3, %2, %0|%0, %2, %3}" | |
14381 | [(set_attr "type" "sse")]) | |
14382 | ||
14383 | ||
14384 | ;; SSE arithmetic | |
14385 | ||
14386 | (define_insn "addv4sf3" | |
14387 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14388 | (plus:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14389 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] | |
14390 | "TARGET_SSE" | |
14391 | "addps\\t{%2, %0|%0, %2}" | |
14392 | [(set_attr "type" "sse")]) | |
14393 | ||
14394 | (define_insn "vmaddv4sf3" | |
14395 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14396 | (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14397 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")) | |
14398 | (match_dup 1) | |
14399 | (const_int 1)))] | |
14400 | "TARGET_SSE" | |
14401 | "addss\\t{%2, %0|%0, %2}" | |
14402 | [(set_attr "type" "sse")]) | |
14403 | ||
14404 | (define_insn "subv4sf3" | |
14405 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14406 | (minus:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14407 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] | |
14408 | "TARGET_SSE" | |
14409 | "subps\\t{%2, %0|%0, %2}" | |
14410 | [(set_attr "type" "sse")]) | |
14411 | ||
14412 | (define_insn "vmsubv4sf3" | |
14413 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14414 | (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14415 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")) | |
14416 | (match_dup 1) | |
14417 | (const_int 1)))] | |
14418 | "TARGET_SSE" | |
14419 | "subss\\t{%2, %0|%0, %2}" | |
14420 | [(set_attr "type" "sse")]) | |
14421 | ||
14422 | (define_insn "mulv4sf3" | |
14423 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14424 | (mult:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14425 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] | |
14426 | "TARGET_SSE" | |
14427 | "mulps\\t{%2, %0|%0, %2}" | |
14428 | [(set_attr "type" "sse")]) | |
14429 | ||
14430 | (define_insn "vmmulv4sf3" | |
14431 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14432 | (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14433 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")) | |
14434 | (match_dup 1) | |
14435 | (const_int 1)))] | |
14436 | "TARGET_SSE" | |
14437 | "mulss\\t{%2, %0|%0, %2}" | |
14438 | [(set_attr "type" "sse")]) | |
14439 | ||
14440 | (define_insn "divv4sf3" | |
14441 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14442 | (div:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14443 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] | |
14444 | "TARGET_SSE" | |
14445 | "divps\\t{%2, %0|%0, %2}" | |
14446 | [(set_attr "type" "sse")]) | |
14447 | ||
14448 | (define_insn "vmdivv4sf3" | |
14449 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14450 | (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14451 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")) | |
14452 | (match_dup 1) | |
14453 | (const_int 1)))] | |
14454 | "TARGET_SSE" | |
14455 | "divss\\t{%2, %0|%0, %2}" | |
14456 | [(set_attr "type" "sse")]) | |
14457 | ||
14458 | ||
14459 | ;; SSE square root/reciprocal | |
14460 | ||
14461 | (define_insn "rcpv4sf2" | |
14462 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14463 | (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))] | |
14464 | "TARGET_SSE" | |
14465 | "rcpps\\t{%1, %0|%0, %1}" | |
14466 | [(set_attr "type" "sse")]) | |
14467 | ||
14468 | (define_insn "vmrcpv4sf2" | |
14469 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14470 | (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42) | |
14471 | (match_operand:V4SF 2 "register_operand" "0") | |
14472 | (const_int 1)))] | |
14473 | "TARGET_SSE" | |
14474 | "rcpss\\t{%1, %0|%0, %1}" | |
14475 | [(set_attr "type" "sse")]) | |
14476 | ||
14477 | (define_insn "rsqrtv4sf2" | |
14478 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14479 | (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))] | |
14480 | "TARGET_SSE" | |
14481 | "rsqrtps\\t{%1, %0|%0, %1}" | |
14482 | [(set_attr "type" "sse")]) | |
14483 | ||
14484 | (define_insn "vmrsqrtv4sf2" | |
14485 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14486 | (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43) | |
14487 | (match_operand:V4SF 2 "register_operand" "0") | |
14488 | (const_int 1)))] | |
14489 | "TARGET_SSE" | |
14490 | "rsqrtss\\t{%1, %0|%0, %1}" | |
14491 | [(set_attr "type" "sse")]) | |
14492 | ||
14493 | (define_insn "sqrtv4sf2" | |
14494 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14495 | (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))] | |
14496 | "TARGET_SSE" | |
14497 | "sqrtps\\t{%1, %0|%0, %1}" | |
14498 | [(set_attr "type" "sse")]) | |
14499 | ||
14500 | (define_insn "vmsqrtv4sf2" | |
14501 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14502 | (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")) | |
14503 | (match_operand:V4SF 2 "register_operand" "0") | |
14504 | (const_int 1)))] | |
14505 | "TARGET_SSE" | |
14506 | "sqrtss\\t{%1, %0|%0, %1}" | |
14507 | [(set_attr "type" "sse")]) | |
14508 | ||
14509 | ||
14510 | ;; SSE logical operations. | |
14511 | ||
14512 | ;; These are not called andti3 etc. because we really really don't want | |
14513 | ;; the compiler to widen DImode ands to TImode ands and then try to move | |
14514 | ;; into DImode subregs of SSE registers, and them together, and move out | |
14515 | ;; of DImode subregs again! | |
14516 | ||
c679d048 JH |
14517 | (define_insn "*sse_andti3_df_1" |
14518 | [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0) | |
14519 | (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0) | |
14520 | (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))] | |
14521 | "TARGET_SSE2" | |
14522 | "andpd\\t{%2, %0|%0, %2}" | |
14523 | [(set_attr "type" "sse")]) | |
14524 | ||
14525 | (define_insn "*sse_andti3_df_2" | |
14526 | [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0) | |
14527 | (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0) | |
14528 | (match_operand:TI 2 "nonimmediate_operand" "Ym")))] | |
14529 | "TARGET_SSE2" | |
14530 | "andpd\\t{%2, %0|%0, %2}" | |
14531 | [(set_attr "type" "sse")]) | |
14532 | ||
14533 | (define_insn "*sse_andti3_sf_1" | |
14534 | [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) | |
14535 | (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0) | |
14536 | (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))] | |
14537 | "TARGET_SSE" | |
14538 | "andps\\t{%2, %0|%0, %2}" | |
14539 | [(set_attr "type" "sse")]) | |
14540 | ||
14541 | (define_insn "*sse_andti3_sf_2" | |
14542 | [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) | |
14543 | (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0) | |
14544 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
14545 | "TARGET_SSE" | |
14546 | "andps\\t{%2, %0|%0, %2}" | |
14547 | [(set_attr "type" "sse")]) | |
14548 | ||
915119a5 BS |
14549 | (define_insn "sse_andti3" |
14550 | [(set (match_operand:TI 0 "register_operand" "=x") | |
c679d048 | 14551 | (and:TI (match_operand:TI 1 "register_operand" "%0") |
915119a5 | 14552 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] |
c679d048 | 14553 | "TARGET_SSE && !TARGET_SSE2" |
915119a5 BS |
14554 | "andps\\t{%2, %0|%0, %2}" |
14555 | [(set_attr "type" "sse")]) | |
14556 | ||
c679d048 JH |
14557 | (define_insn "*sse_andti3_sse2" |
14558 | [(set (match_operand:TI 0 "register_operand" "=x") | |
14559 | (and:TI (match_operand:TI 1 "register_operand" "%0") | |
14560 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
14561 | "TARGET_SSE2" | |
14562 | "pand\\t{%2, %0|%0, %2}" | |
14563 | [(set_attr "type" "sse")]) | |
14564 | ||
14565 | (define_insn "*sse_nandti3_df" | |
14566 | [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0) | |
14567 | (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)) | |
14568 | (match_operand:TI 2 "nonimmediate_operand" "Ym")))] | |
14569 | "TARGET_SSE2" | |
14570 | "andnpd\\t{%2, %0|%0, %2}" | |
14571 | [(set_attr "type" "sse")]) | |
14572 | ||
14573 | (define_insn "*sse_nandti3_sf" | |
14574 | [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) | |
14575 | (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)) | |
14576 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
14577 | "TARGET_SSE" | |
14578 | "andnps\\t{%2, %0|%0, %2}" | |
14579 | [(set_attr "type" "sse")]) | |
14580 | ||
915119a5 BS |
14581 | (define_insn "sse_nandti3" |
14582 | [(set (match_operand:TI 0 "register_operand" "=x") | |
14583 | (and:TI (not:TI (match_operand:TI 1 "register_operand" "0")) | |
14584 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
c679d048 | 14585 | "TARGET_SSE && !TARGET_SSE2" |
915119a5 BS |
14586 | "andnps\\t{%2, %0|%0, %2}" |
14587 | [(set_attr "type" "sse")]) | |
14588 | ||
c679d048 JH |
14589 | (define_insn "*sse_nandti3_sse2" |
14590 | [(set (match_operand:TI 0 "register_operand" "=x") | |
14591 | (and:TI (not:TI (match_operand:TI 1 "register_operand" "0")) | |
14592 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
14593 | "TARGET_SSE2" | |
14594 | "pnand\\t{%2, %0|%0, %2}" | |
14595 | [(set_attr "type" "sse")]) | |
14596 | ||
14597 | (define_insn "*sse_iorti3_df_1" | |
14598 | [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0) | |
14599 | (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0) | |
14600 | (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))] | |
14601 | "TARGET_SSE2" | |
14602 | "orpd\\t{%2, %0|%0, %2}" | |
14603 | [(set_attr "type" "sse")]) | |
14604 | ||
14605 | (define_insn "*sse_iorti3_df_2" | |
14606 | [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0) | |
14607 | (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0) | |
14608 | (match_operand:TI 2 "nonimmediate_operand" "Ym")))] | |
14609 | "TARGET_SSE2" | |
14610 | "orpd\\t{%2, %0|%0, %2}" | |
14611 | [(set_attr "type" "sse")]) | |
14612 | ||
14613 | (define_insn "*sse_iorti3_sf_1" | |
14614 | [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) | |
14615 | (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0) | |
14616 | (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))] | |
14617 | "TARGET_SSE" | |
14618 | "orps\\t{%2, %0|%0, %2}" | |
14619 | [(set_attr "type" "sse")]) | |
14620 | ||
14621 | (define_insn "*sse_iorti3_sf_2" | |
14622 | [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) | |
14623 | (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0) | |
14624 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
14625 | "TARGET_SSE" | |
14626 | "orps\\t{%2, %0|%0, %2}" | |
14627 | [(set_attr "type" "sse")]) | |
14628 | ||
915119a5 BS |
14629 | (define_insn "sse_iorti3" |
14630 | [(set (match_operand:TI 0 "register_operand" "=x") | |
c679d048 JH |
14631 | (ior:TI (match_operand:TI 1 "register_operand" "%0") |
14632 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
14633 | "TARGET_SSE && !TARGET_SSE2" | |
14634 | "orps\\t{%2, %0|%0, %2}" | |
14635 | [(set_attr "type" "sse")]) | |
14636 | ||
14637 | (define_insn "*sse_iorti3_sse2" | |
14638 | [(set (match_operand:TI 0 "register_operand" "=x") | |
14639 | (ior:TI (match_operand:TI 1 "register_operand" "%0") | |
14640 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
14641 | "TARGET_SSE2" | |
14642 | "por\\t{%2, %0|%0, %2}" | |
14643 | [(set_attr "type" "sse")]) | |
14644 | ||
14645 | (define_insn "*sse_xorti3_df_1" | |
14646 | [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0) | |
14647 | (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0) | |
14648 | (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))] | |
14649 | "TARGET_SSE2" | |
14650 | "xorpd\\t{%2, %0|%0, %2}" | |
14651 | [(set_attr "type" "sse")]) | |
14652 | ||
14653 | (define_insn "*sse_xorti3_df_2" | |
14654 | [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0) | |
14655 | (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0) | |
14656 | (match_operand:TI 2 "nonimmediate_operand" "Ym")))] | |
14657 | "TARGET_SSE2" | |
14658 | "xorpd\\t{%2, %0|%0, %2}" | |
14659 | [(set_attr "type" "sse")]) | |
14660 | ||
14661 | (define_insn "*sse_xorti3_sf_1" | |
14662 | [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) | |
14663 | (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0) | |
14664 | (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))] | |
14665 | "TARGET_SSE" | |
14666 | "xorps\\t{%2, %0|%0, %2}" | |
14667 | [(set_attr "type" "sse")]) | |
14668 | ||
14669 | (define_insn "*sse_xorti3_sf_2" | |
14670 | [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) | |
14671 | (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0) | |
915119a5 BS |
14672 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] |
14673 | "TARGET_SSE" | |
c679d048 | 14674 | "xorps\\t{%2, %0|%0, %2}" |
915119a5 BS |
14675 | [(set_attr "type" "sse")]) |
14676 | ||
14677 | (define_insn "sse_xorti3" | |
14678 | [(set (match_operand:TI 0 "register_operand" "=x") | |
c679d048 | 14679 | (xor:TI (match_operand:TI 1 "register_operand" "%0") |
915119a5 | 14680 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] |
c679d048 | 14681 | "TARGET_SSE && !TARGET_SSE2" |
915119a5 BS |
14682 | "xorps\\t{%2, %0|%0, %2}" |
14683 | [(set_attr "type" "sse")]) | |
14684 | ||
c679d048 JH |
14685 | (define_insn "*sse_xorti3_sse2" |
14686 | [(set (match_operand:TI 0 "register_operand" "=x") | |
14687 | (xor:TI (match_operand:TI 1 "register_operand" "%0") | |
14688 | (match_operand:TI 2 "nonimmediate_operand" "xm")))] | |
14689 | "TARGET_SSE2" | |
14690 | "pxor\\t{%2, %0|%0, %2}" | |
14691 | [(set_attr "type" "sse")]) | |
14692 | ||
915119a5 BS |
14693 | ;; Use xor, but don't show input operands so they aren't live before |
14694 | ;; this insn. | |
14695 | (define_insn "sse_clrti" | |
14696 | [(set (match_operand:TI 0 "register_operand" "=x") | |
14697 | (unspec:TI [(const_int 0)] 45))] | |
14698 | "TARGET_SSE" | |
14699 | "xorps\\t{%0, %0|%0, %0}" | |
14700 | [(set_attr "type" "sse")]) | |
14701 | ||
14702 | ||
14703 | ;; SSE mask-generating compares | |
14704 | ||
14705 | (define_insn "maskcmpv4sf3" | |
14706 | [(set (match_operand:V4SI 0 "register_operand" "=x") | |
14707 | (match_operator:V4SI 3 "sse_comparison_operator" | |
14708 | [(match_operand:V4SF 1 "register_operand" "0") | |
14709 | (match_operand:V4SF 2 "nonimmediate_operand" "x")]))] | |
14710 | "TARGET_SSE" | |
a46d1d38 | 14711 | "cmp%D3ps\\t{%2, %0|%0, %2}" |
915119a5 BS |
14712 | [(set_attr "type" "sse")]) |
14713 | ||
14714 | (define_insn "maskncmpv4sf3" | |
14715 | [(set (match_operand:V4SI 0 "register_operand" "=x") | |
14716 | (not:V4SI | |
14717 | (match_operator:V4SI 3 "sse_comparison_operator" | |
14718 | [(match_operand:V4SF 1 "register_operand" "0") | |
14719 | (match_operand:V4SF 2 "nonimmediate_operand" "x")])))] | |
14720 | "TARGET_SSE" | |
a46d1d38 | 14721 | "cmpn%D3ps\\t{%2, %0|%0, %2}" |
915119a5 BS |
14722 | [(set_attr "type" "sse")]) |
14723 | ||
14724 | (define_insn "vmmaskcmpv4sf3" | |
14725 | [(set (match_operand:V4SI 0 "register_operand" "=x") | |
14726 | (vec_merge:V4SI | |
14727 | (match_operator:V4SI 3 "sse_comparison_operator" | |
14728 | [(match_operand:V4SF 1 "register_operand" "0") | |
14729 | (match_operand:V4SF 2 "nonimmediate_operand" "x")]) | |
14730 | (match_dup 1) | |
14731 | (const_int 1)))] | |
14732 | "TARGET_SSE" | |
a46d1d38 | 14733 | "cmp%D3ss\\t{%2, %0|%0, %2}" |
915119a5 BS |
14734 | [(set_attr "type" "sse")]) |
14735 | ||
14736 | (define_insn "vmmaskncmpv4sf3" | |
14737 | [(set (match_operand:V4SI 0 "register_operand" "=x") | |
14738 | (vec_merge:V4SI | |
14739 | (not:V4SI | |
14740 | (match_operator:V4SI 3 "sse_comparison_operator" | |
14741 | [(match_operand:V4SF 1 "register_operand" "0") | |
14742 | (match_operand:V4SF 2 "nonimmediate_operand" "x")])) | |
14743 | (subreg:V4SI (match_dup 1) 0) | |
14744 | (const_int 1)))] | |
14745 | "TARGET_SSE" | |
a46d1d38 | 14746 | "cmp%D3ss\\t{%2, %0|%0, %2}" |
915119a5 BS |
14747 | [(set_attr "type" "sse")]) |
14748 | ||
14749 | (define_insn "sse_comi" | |
14750 | [(set (reg:CCFP 17) | |
14751 | (match_operator:CCFP 2 "sse_comparison_operator" | |
14752 | [(vec_select:SF | |
14753 | (match_operand:V4SF 0 "register_operand" "x") | |
14754 | (parallel [(const_int 0)])) | |
14755 | (vec_select:SF | |
14756 | (match_operand:V4SF 1 "register_operand" "x") | |
14757 | (parallel [(const_int 0)]))]))] | |
14758 | "TARGET_SSE" | |
14759 | "comiss\\t{%2, %0|%0, %2}" | |
14760 | [(set_attr "type" "sse")]) | |
14761 | ||
14762 | (define_insn "sse_ucomi" | |
14763 | [(set (reg:CCFPU 17) | |
14764 | (match_operator:CCFPU 2 "sse_comparison_operator" | |
14765 | [(vec_select:SF | |
14766 | (match_operand:V4SF 0 "register_operand" "x") | |
14767 | (parallel [(const_int 0)])) | |
14768 | (vec_select:SF | |
14769 | (match_operand:V4SF 1 "register_operand" "x") | |
14770 | (parallel [(const_int 0)]))]))] | |
14771 | "TARGET_SSE" | |
14772 | "ucomiss\\t{%2, %0|%0, %2}" | |
14773 | [(set_attr "type" "sse")]) | |
14774 | ||
14775 | ||
14776 | ;; SSE unpack | |
14777 | ||
14778 | (define_insn "sse_unpckhps" | |
14779 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14780 | (vec_merge:V4SF | |
14781 | (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14782 | (parallel [(const_int 2) | |
14783 | (const_int 0) | |
14784 | (const_int 3) | |
14785 | (const_int 1)])) | |
14786 | (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x") | |
14787 | (parallel [(const_int 0) | |
14788 | (const_int 2) | |
14789 | (const_int 1) | |
14790 | (const_int 3)])) | |
14791 | (const_int 5)))] | |
14792 | "TARGET_SSE" | |
14793 | "unpckhps\\t{%2, %0|%0, %2}" | |
14794 | [(set_attr "type" "sse")]) | |
14795 | ||
14796 | (define_insn "sse_unpcklps" | |
14797 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14798 | (vec_merge:V4SF | |
14799 | (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14800 | (parallel [(const_int 0) | |
14801 | (const_int 2) | |
14802 | (const_int 1) | |
14803 | (const_int 3)])) | |
14804 | (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x") | |
14805 | (parallel [(const_int 2) | |
14806 | (const_int 0) | |
14807 | (const_int 3) | |
14808 | (const_int 1)])) | |
14809 | (const_int 5)))] | |
14810 | "TARGET_SSE" | |
14811 | "unpcklps\\t{%2, %0|%0, %2}" | |
14812 | [(set_attr "type" "sse")]) | |
14813 | ||
14814 | ||
14815 | ;; SSE min/max | |
14816 | ||
14817 | (define_insn "smaxv4sf3" | |
14818 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14819 | (smax:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14820 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] | |
14821 | "TARGET_SSE" | |
14822 | "maxps\\t{%2, %0|%0, %2}" | |
14823 | [(set_attr "type" "sse")]) | |
14824 | ||
14825 | (define_insn "vmsmaxv4sf3" | |
14826 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14827 | (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14828 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")) | |
14829 | (match_dup 1) | |
14830 | (const_int 1)))] | |
14831 | "TARGET_SSE" | |
14832 | "maxss\\t{%2, %0|%0, %2}" | |
14833 | [(set_attr "type" "sse")]) | |
14834 | ||
14835 | (define_insn "sminv4sf3" | |
14836 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14837 | (smin:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14838 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] | |
14839 | "TARGET_SSE" | |
14840 | "minps\\t{%2, %0|%0, %2}" | |
14841 | [(set_attr "type" "sse")]) | |
14842 | ||
14843 | (define_insn "vmsminv4sf3" | |
14844 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14845 | (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14846 | (match_operand:V4SF 2 "nonimmediate_operand" "xm")) | |
14847 | (match_dup 1) | |
14848 | (const_int 1)))] | |
14849 | "TARGET_SSE" | |
14850 | "minss\\t{%2, %0|%0, %2}" | |
14851 | [(set_attr "type" "sse")]) | |
14852 | ||
14853 | ||
14854 | ;; SSE <-> integer/MMX conversions | |
14855 | ||
14856 | (define_insn "cvtpi2ps" | |
14857 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14858 | (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14859 | (vec_duplicate:V4SF | |
14860 | (float:V2SF (match_operand:V2SI 2 "register_operand" "ym"))) | |
14861 | (const_int 12)))] | |
14862 | "TARGET_SSE" | |
14863 | "cvtpi2ps\\t{%2, %0|%0, %2}" | |
14864 | [(set_attr "type" "sse")]) | |
14865 | ||
14866 | (define_insn "cvtps2pi" | |
14867 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
14868 | (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm")) | |
14869 | (parallel | |
14870 | [(const_int 0) | |
14871 | (const_int 1)])))] | |
14872 | "TARGET_SSE" | |
14873 | "cvtps2pi\\t{%1, %0|%0, %1}" | |
14874 | [(set_attr "type" "sse")]) | |
14875 | ||
14876 | (define_insn "cvttps2pi" | |
14877 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
14878 | (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30) | |
14879 | (parallel | |
14880 | [(const_int 0) | |
14881 | (const_int 1)])))] | |
14882 | "TARGET_SSE" | |
14883 | "cvttps2pi\\t{%1, %0|%0, %1}" | |
14884 | [(set_attr "type" "sse")]) | |
14885 | ||
14886 | (define_insn "cvtsi2ss" | |
14887 | [(set (match_operand:V4SF 0 "register_operand" "=x") | |
14888 | (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0") | |
14889 | (vec_duplicate:V4SF | |
14890 | (float:SF (match_operand:SI 2 "register_operand" "rm"))) | |
14891 | (const_int 15)))] | |
14892 | "TARGET_SSE" | |
14893 | "cvtsi2ss\\t{%2, %0|%0, %2}" | |
14894 | [(set_attr "type" "sse")]) | |
14895 | ||
14896 | (define_insn "cvtss2si" | |
14897 | [(set (match_operand:SI 0 "register_operand" "=y") | |
14898 | (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm")) | |
14899 | (parallel [(const_int 0)])))] | |
14900 | "TARGET_SSE" | |
14901 | "cvtss2si\\t{%1, %0|%0, %1}" | |
14902 | [(set_attr "type" "sse")]) | |
14903 | ||
14904 | (define_insn "cvttss2si" | |
14905 | [(set (match_operand:SI 0 "register_operand" "=y") | |
14906 | (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30) | |
14907 | (parallel [(const_int 0)])))] | |
14908 | "TARGET_SSE" | |
14909 | "cvttss2si\\t{%1, %0|%0, %1}" | |
14910 | [(set_attr "type" "sse")]) | |
14911 | ||
14912 | ||
14913 | ;; MMX insns | |
14914 | ||
14915 | ;; MMX arithmetic | |
14916 | ||
14917 | (define_insn "addv8qi3" | |
14918 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
14919 | (plus:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
14920 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
14921 | "TARGET_MMX" | |
14922 | "paddb\\t{%2, %0|%0, %2}" | |
14923 | [(set_attr "type" "mmx")]) | |
14924 | ||
14925 | (define_insn "addv4hi3" | |
14926 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
14927 | (plus:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
14928 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
14929 | "TARGET_MMX" | |
14930 | "paddw\\t{%2, %0|%0, %2}" | |
14931 | [(set_attr "type" "mmx")]) | |
14932 | ||
14933 | (define_insn "addv2si3" | |
14934 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
14935 | (plus:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
14936 | (match_operand:V2SI 2 "nonimmediate_operand" "ym")))] | |
14937 | "TARGET_MMX" | |
14938 | "paddd\\t{%2, %0|%0, %2}" | |
14939 | [(set_attr "type" "mmx")]) | |
14940 | ||
14941 | (define_insn "ssaddv8qi3" | |
14942 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
14943 | (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
14944 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
14945 | "TARGET_MMX" | |
14946 | "paddsb\\t{%2, %0|%0, %2}" | |
14947 | [(set_attr "type" "mmx")]) | |
14948 | ||
14949 | (define_insn "ssaddv4hi3" | |
14950 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
14951 | (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
14952 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
14953 | "TARGET_MMX" | |
14954 | "paddsw\\t{%2, %0|%0, %2}" | |
14955 | [(set_attr "type" "mmx")]) | |
14956 | ||
14957 | (define_insn "usaddv8qi3" | |
14958 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
14959 | (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
14960 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
14961 | "TARGET_MMX" | |
14962 | "paddusb\\t{%2, %0|%0, %2}" | |
14963 | [(set_attr "type" "mmx")]) | |
14964 | ||
14965 | (define_insn "usaddv4hi3" | |
14966 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
14967 | (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
14968 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
14969 | "TARGET_MMX" | |
14970 | "paddusw\\t{%2, %0|%0, %2}" | |
14971 | [(set_attr "type" "mmx")]) | |
14972 | ||
14973 | (define_insn "subv8qi3" | |
14974 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
14975 | (minus:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
14976 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
14977 | "TARGET_MMX" | |
14978 | "psubb\\t{%2, %0|%0, %2}" | |
14979 | [(set_attr "type" "mmx")]) | |
14980 | ||
14981 | (define_insn "subv4hi3" | |
14982 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
14983 | (minus:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
14984 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
14985 | "TARGET_MMX" | |
14986 | "psubw\\t{%2, %0|%0, %2}" | |
14987 | [(set_attr "type" "mmx")]) | |
14988 | ||
14989 | (define_insn "subv2si3" | |
14990 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
14991 | (minus:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
14992 | (match_operand:V2SI 2 "nonimmediate_operand" "ym")))] | |
14993 | "TARGET_MMX" | |
14994 | "psubd\\t{%2, %0|%0, %2}" | |
14995 | [(set_attr "type" "mmx")]) | |
14996 | ||
14997 | (define_insn "sssubv8qi3" | |
14998 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
14999 | (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
15000 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
15001 | "TARGET_MMX" | |
15002 | "psubsb\\t{%2, %0|%0, %2}" | |
15003 | [(set_attr "type" "mmx")]) | |
15004 | ||
15005 | (define_insn "sssubv4hi3" | |
15006 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15007 | (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15008 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
15009 | "TARGET_MMX" | |
15010 | "psubsw\\t{%2, %0|%0, %2}" | |
15011 | [(set_attr "type" "mmx")]) | |
15012 | ||
15013 | (define_insn "ussubv8qi3" | |
15014 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15015 | (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
15016 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
15017 | "TARGET_MMX" | |
15018 | "psubusb\\t{%2, %0|%0, %2}" | |
15019 | [(set_attr "type" "mmx")]) | |
15020 | ||
15021 | (define_insn "ussubv4hi3" | |
15022 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15023 | (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15024 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
15025 | "TARGET_MMX" | |
15026 | "psubusw\\t{%2, %0|%0, %2}" | |
15027 | [(set_attr "type" "mmx")]) | |
15028 | ||
15029 | (define_insn "mulv4hi3" | |
15030 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15031 | (mult:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15032 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
15033 | "TARGET_MMX" | |
15034 | "pmullw\\t{%2, %0|%0, %2}" | |
15035 | [(set_attr "type" "mmx")]) | |
15036 | ||
15037 | (define_insn "smulv4hi3_highpart" | |
15038 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15039 | (truncate:V4HI | |
15040 | (lshiftrt:V4SI | |
15041 | (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0")) | |
15042 | (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) | |
15043 | (const_int 16))))] | |
15044 | "TARGET_MMX" | |
15045 | "pmulhw\\t{%2, %0|%0, %2}" | |
15046 | [(set_attr "type" "mmx")]) | |
15047 | ||
15048 | (define_insn "umulv4hi3_highpart" | |
15049 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15050 | (truncate:V4HI | |
15051 | (lshiftrt:V4SI | |
15052 | (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0")) | |
15053 | (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) | |
15054 | (const_int 16))))] | |
15055 | "TARGET_MMX" | |
15056 | "pmulhuw\\t{%2, %0|%0, %2}" | |
15057 | [(set_attr "type" "mmx")]) | |
15058 | ||
15059 | (define_insn "mmx_pmaddwd" | |
15060 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
15061 | (plus:V2SI | |
15062 | (mult:V2SI | |
15063 | (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0") | |
15064 | (parallel [(const_int 0) | |
15065 | (const_int 2)]))) | |
15066 | (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym") | |
15067 | (parallel [(const_int 0) | |
15068 | (const_int 2)])))) | |
15069 | (mult:V2SI | |
15070 | (sign_extend:V2SI (vec_select:V2HI (match_dup 1) | |
15071 | (parallel [(const_int 1) | |
15072 | (const_int 3)]))) | |
15073 | (sign_extend:V2SI (vec_select:V2HI (match_dup 2) | |
15074 | (parallel [(const_int 1) | |
15075 | (const_int 3)]))))))] | |
15076 | "TARGET_MMX" | |
15077 | "pmaddwd\\t{%2, %0|%0, %2}" | |
15078 | [(set_attr "type" "mmx")]) | |
15079 | ||
15080 | ||
15081 | ;; MMX logical operations | |
15082 | ;; Note we don't want to declare these as regular iordi3 insns to prevent | |
15083 | ;; normal code that also wants to use the FPU from getting broken. | |
15084 | ;; The UNSPECs are there to prevent the combiner from getting overly clever. | |
15085 | (define_insn "mmx_iordi3" | |
15086 | [(set (match_operand:DI 0 "register_operand" "=y") | |
15087 | (unspec:DI | |
15088 | [(ior:DI (match_operand:DI 1 "register_operand" "0") | |
15089 | (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))] | |
15090 | "TARGET_MMX" | |
15091 | "por\\t{%2, %0|%0, %2}" | |
15092 | [(set_attr "type" "mmx")]) | |
15093 | ||
15094 | (define_insn "mmx_xordi3" | |
15095 | [(set (match_operand:DI 0 "register_operand" "=y") | |
15096 | (unspec:DI | |
15097 | [(xor:DI (match_operand:DI 1 "register_operand" "0") | |
15098 | (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))] | |
15099 | "TARGET_MMX" | |
15100 | "pxor\\t{%2, %0|%0, %2}" | |
15101 | [(set_attr "type" "mmx")]) | |
15102 | ||
15103 | ;; Same as pxor, but don't show input operands so that we don't think | |
15104 | ;; they are live. | |
15105 | (define_insn "mmx_clrdi" | |
15106 | [(set (match_operand:DI 0 "register_operand" "=y") | |
15107 | (unspec:DI [(const_int 0)] 45))] | |
15108 | "TARGET_MMX" | |
15109 | "pxor\\t{%0, %0|%0, %0}" | |
15110 | [(set_attr "type" "mmx")]) | |
15111 | ||
15112 | (define_insn "mmx_anddi3" | |
15113 | [(set (match_operand:DI 0 "register_operand" "=y") | |
15114 | (unspec:DI | |
15115 | [(and:DI (match_operand:DI 1 "register_operand" "0") | |
15116 | (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))] | |
15117 | "TARGET_MMX" | |
15118 | "pand\\t{%2, %0|%0, %2}" | |
15119 | [(set_attr "type" "mmx")]) | |
15120 | ||
15121 | (define_insn "mmx_nanddi3" | |
15122 | [(set (match_operand:DI 0 "register_operand" "=y") | |
15123 | (unspec:DI | |
15124 | [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0")) | |
15125 | (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))] | |
15126 | "TARGET_MMX" | |
15127 | "pandn\\t{%2, %0|%0, %2}" | |
15128 | [(set_attr "type" "mmx")]) | |
15129 | ||
15130 | ||
15131 | ;; MMX unsigned averages/sum of absolute differences | |
15132 | ||
15133 | (define_insn "mmx_uavgv8qi3" | |
15134 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15135 | (ashiftrt:V8QI | |
15136 | (plus:V8QI (plus:V8QI | |
15137 | (match_operand:V8QI 1 "register_operand" "0") | |
15138 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")) | |
15139 | (vec_const:V8QI (parallel [(const_int 1) | |
15140 | (const_int 1) | |
15141 | (const_int 1) | |
15142 | (const_int 1) | |
15143 | (const_int 1) | |
15144 | (const_int 1) | |
15145 | (const_int 1) | |
15146 | (const_int 1)]))) | |
15147 | (const_int 1)))] | |
15148 | "TARGET_SSE" | |
332316cd | 15149 | "pavgb\\t{%2, %0|%0, %2}" |
915119a5 BS |
15150 | [(set_attr "type" "sse")]) |
15151 | ||
15152 | (define_insn "mmx_uavgv4hi3" | |
15153 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15154 | (ashiftrt:V4HI | |
15155 | (plus:V4HI (plus:V4HI | |
15156 | (match_operand:V4HI 1 "register_operand" "0") | |
15157 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")) | |
15158 | (vec_const:V4HI (parallel [(const_int 1) | |
15159 | (const_int 1) | |
15160 | (const_int 1) | |
15161 | (const_int 1)]))) | |
15162 | (const_int 1)))] | |
15163 | "TARGET_SSE" | |
332316cd | 15164 | "pavgw\\t{%2, %0|%0, %2}" |
915119a5 BS |
15165 | [(set_attr "type" "sse")]) |
15166 | ||
15167 | (define_insn "mmx_psadbw" | |
15168 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
332316cd BS |
15169 | (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0") |
15170 | (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))] | |
915119a5 | 15171 | "TARGET_SSE" |
332316cd | 15172 | "psadbw\\t{%2, %0|%0, %2}" |
915119a5 BS |
15173 | [(set_attr "type" "sse")]) |
15174 | ||
15175 | ||
15176 | ;; MMX insert/extract/shuffle | |
15177 | ||
15178 | (define_insn "mmx_pinsrw" | |
15179 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15180 | (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15181 | (vec_duplicate:V4HI | |
15182 | (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm"))) | |
15183 | (match_operand:SI 3 "immediate_operand" "i")))] | |
15184 | "TARGET_SSE" | |
6a4afa6c | 15185 | "pinsrw\\t{%3, %2, %0|%0, %2, %3}" |
915119a5 BS |
15186 | [(set_attr "type" "sse")]) |
15187 | ||
15188 | (define_insn "mmx_pextrw" | |
15189 | [(set (match_operand:SI 0 "register_operand" "=r") | |
15190 | (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y") | |
15191 | (parallel | |
15192 | [(match_operand:SI 2 "immediate_operand" "i")]))))] | |
15193 | "TARGET_SSE" | |
6a4afa6c | 15194 | "pextrw\\t{%2, %1, %0|%0, %1, %2}" |
915119a5 BS |
15195 | [(set_attr "type" "sse")]) |
15196 | ||
15197 | (define_insn "mmx_pshufw" | |
15198 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15199 | (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0") | |
15200 | (match_operand:V4HI 2 "nonimmediate_operand" "ym") | |
15201 | (match_operand:SI 3 "immediate_operand" "i")] 41))] | |
15202 | "TARGET_SSE" | |
6a4afa6c | 15203 | "pshufw\\t{%3, %2, %0|%0, %2, %3}" |
915119a5 BS |
15204 | [(set_attr "type" "sse")]) |
15205 | ||
15206 | ||
15207 | ;; MMX mask-generating comparisons | |
15208 | ||
15209 | (define_insn "eqv8qi3" | |
15210 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15211 | (eq:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
15212 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
15213 | "TARGET_MMX" | |
15214 | "pcmpeqb\\t{%2, %0|%0, %2}" | |
15215 | [(set_attr "type" "mmx")]) | |
15216 | ||
15217 | (define_insn "eqv4hi3" | |
15218 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15219 | (eq:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15220 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
15221 | "TARGET_MMX" | |
15222 | "pcmpeqw\\t{%2, %0|%0, %2}" | |
15223 | [(set_attr "type" "mmx")]) | |
15224 | ||
15225 | (define_insn "eqv2si3" | |
15226 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
15227 | (eq:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
15228 | (match_operand:V2SI 2 "nonimmediate_operand" "ym")))] | |
15229 | "TARGET_MMX" | |
15230 | "pcmpeqd\\t{%2, %0|%0, %2}" | |
15231 | [(set_attr "type" "mmx")]) | |
15232 | ||
15233 | (define_insn "gtv8qi3" | |
15234 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15235 | (gt:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
15236 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
15237 | "TARGET_MMX" | |
15238 | "pcmpgtb\\t{%2, %0|%0, %2}" | |
15239 | [(set_attr "type" "mmx")]) | |
15240 | ||
15241 | (define_insn "gtv4hi3" | |
15242 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15243 | (gt:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15244 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
15245 | "TARGET_MMX" | |
15246 | "pcmpgtw\\t{%2, %0|%0, %2}" | |
15247 | [(set_attr "type" "mmx")]) | |
15248 | ||
15249 | (define_insn "gtv2si3" | |
15250 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
15251 | (gt:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
15252 | (match_operand:V2SI 2 "nonimmediate_operand" "ym")))] | |
15253 | "TARGET_MMX" | |
15254 | "pcmpgtd\\t{%2, %0|%0, %2}" | |
15255 | [(set_attr "type" "mmx")]) | |
15256 | ||
15257 | ||
15258 | ;; MMX max/min insns | |
15259 | ||
15260 | (define_insn "umaxv8qi3" | |
15261 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15262 | (umax:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
15263 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
15264 | "TARGET_SSE" | |
15265 | "pmaxub\\t{%2, %0|%0, %2}" | |
15266 | [(set_attr "type" "sse")]) | |
15267 | ||
15268 | (define_insn "smaxv4hi3" | |
15269 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15270 | (smax:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15271 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
15272 | "TARGET_SSE" | |
15273 | "pmaxsw\\t{%2, %0|%0, %2}" | |
15274 | [(set_attr "type" "sse")]) | |
15275 | ||
15276 | (define_insn "uminv8qi3" | |
15277 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15278 | (umin:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
15279 | (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
15280 | "TARGET_SSE" | |
15281 | "pminub\\t{%2, %0|%0, %2}" | |
15282 | [(set_attr "type" "sse")]) | |
15283 | ||
15284 | (define_insn "sminv4hi3" | |
15285 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15286 | (smin:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15287 | (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
15288 | "TARGET_SSE" | |
15289 | "pminsw\\t{%2, %0|%0, %2}" | |
15290 | [(set_attr "type" "sse")]) | |
15291 | ||
15292 | ||
15293 | ;; MMX shifts | |
15294 | ||
15295 | (define_insn "ashrv4hi3" | |
15296 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15297 | (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15298 | (match_operand:DI 2 "nonmemory_operand" "yi")))] | |
15299 | "TARGET_MMX" | |
15300 | "psraw\\t{%2, %0|%0, %2}" | |
15301 | [(set_attr "type" "mmx")]) | |
15302 | ||
15303 | (define_insn "ashrv2si3" | |
15304 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
15305 | (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
15306 | (match_operand:DI 2 "nonmemory_operand" "yi")))] | |
15307 | "TARGET_MMX" | |
15308 | "psrad\\t{%2, %0|%0, %2}" | |
15309 | [(set_attr "type" "mmx")]) | |
15310 | ||
15311 | (define_insn "lshrv4hi3" | |
15312 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15313 | (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15314 | (match_operand:DI 2 "nonmemory_operand" "yi")))] | |
15315 | "TARGET_MMX" | |
15316 | "psrlw\\t{%2, %0|%0, %2}" | |
15317 | [(set_attr "type" "mmx")]) | |
15318 | ||
15319 | (define_insn "lshrv2si3" | |
15320 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
15321 | (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
15322 | (match_operand:DI 2 "nonmemory_operand" "yi")))] | |
15323 | "TARGET_MMX" | |
15324 | "psrld\\t{%2, %0|%0, %2}" | |
15325 | [(set_attr "type" "mmx")]) | |
15326 | ||
15327 | ;; See logical MMX insns. | |
15328 | (define_insn "mmx_lshrdi3" | |
15329 | [(set (match_operand:DI 0 "register_operand" "=y") | |
2b71bf37 JH |
15330 | (unspec:DI |
15331 | [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
15332 | (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))] | |
915119a5 BS |
15333 | "TARGET_MMX" |
15334 | "psrlq\\t{%2, %0|%0, %2}" | |
15335 | [(set_attr "type" "mmx")]) | |
15336 | ||
15337 | (define_insn "ashlv4hi3" | |
15338 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15339 | (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15340 | (match_operand:DI 2 "nonmemory_operand" "yi")))] | |
15341 | "TARGET_MMX" | |
15342 | "psllw\\t{%2, %0|%0, %2}" | |
15343 | [(set_attr "type" "mmx")]) | |
15344 | ||
15345 | (define_insn "ashlv2si3" | |
15346 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
15347 | (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
15348 | (match_operand:DI 2 "nonmemory_operand" "yi")))] | |
15349 | "TARGET_MMX" | |
15350 | "pslld\\t{%2, %0|%0, %2}" | |
15351 | [(set_attr "type" "mmx")]) | |
15352 | ||
15353 | ;; See logical MMX insns. | |
15354 | (define_insn "mmx_ashldi3" | |
15355 | [(set (match_operand:DI 0 "register_operand" "=y") | |
2b71bf37 JH |
15356 | (unspec:DI |
15357 | [(ashift:DI (match_operand:DI 1 "register_operand" "0") | |
15358 | (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))] | |
915119a5 BS |
15359 | "TARGET_MMX" |
15360 | "psllq\\t{%2, %0|%0, %2}" | |
15361 | [(set_attr "type" "mmx")]) | |
15362 | ||
15363 | ||
15364 | ;; MMX pack/unpack insns. | |
15365 | ||
15366 | (define_insn "mmx_packsswb" | |
15367 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15368 | (vec_concat:V8QI | |
15369 | (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0")) | |
15370 | (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))] | |
15371 | "TARGET_MMX" | |
15372 | "packsswb\\t{%2, %0|%0, %2}" | |
15373 | [(set_attr "type" "mmx")]) | |
15374 | ||
15375 | (define_insn "mmx_packssdw" | |
15376 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15377 | (vec_concat:V4HI | |
15378 | (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0")) | |
15379 | (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))] | |
15380 | "TARGET_MMX" | |
15381 | "packssdw\\t{%2, %0|%0, %2}" | |
15382 | [(set_attr "type" "mmx")]) | |
15383 | ||
15384 | (define_insn "mmx_packuswb" | |
15385 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15386 | (vec_concat:V8QI | |
15387 | (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0")) | |
15388 | (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))] | |
15389 | "TARGET_MMX" | |
15390 | "packuswb\\t{%2, %0|%0, %2}" | |
15391 | [(set_attr "type" "mmx")]) | |
15392 | ||
15393 | (define_insn "mmx_punpckhbw" | |
15394 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15395 | (vec_merge:V8QI | |
15396 | (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
15397 | (parallel [(const_int 4) | |
15398 | (const_int 0) | |
15399 | (const_int 5) | |
15400 | (const_int 1) | |
15401 | (const_int 6) | |
15402 | (const_int 2) | |
15403 | (const_int 7) | |
15404 | (const_int 3)])) | |
15405 | (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y") | |
15406 | (parallel [(const_int 0) | |
15407 | (const_int 4) | |
15408 | (const_int 1) | |
15409 | (const_int 5) | |
15410 | (const_int 2) | |
15411 | (const_int 6) | |
15412 | (const_int 3) | |
15413 | (const_int 7)])) | |
15414 | (const_int 85)))] | |
15415 | "TARGET_MMX" | |
15416 | "punpckhbw\\t{%2, %0|%0, %2}" | |
15417 | [(set_attr "type" "mmx")]) | |
15418 | ||
15419 | (define_insn "mmx_punpckhwd" | |
15420 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15421 | (vec_merge:V4HI | |
15422 | (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15423 | (parallel [(const_int 0) | |
15424 | (const_int 2) | |
15425 | (const_int 1) | |
15426 | (const_int 3)])) | |
15427 | (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y") | |
15428 | (parallel [(const_int 2) | |
15429 | (const_int 0) | |
15430 | (const_int 3) | |
15431 | (const_int 1)])) | |
15432 | (const_int 5)))] | |
15433 | "TARGET_MMX" | |
332316cd | 15434 | "punpckhwd\\t{%2, %0|%0, %2}" |
915119a5 BS |
15435 | [(set_attr "type" "mmx")]) |
15436 | ||
15437 | (define_insn "mmx_punpckhdq" | |
15438 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
15439 | (vec_merge:V2SI | |
15440 | (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
15441 | (parallel [(const_int 0) | |
15442 | (const_int 1)])) | |
15443 | (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y") | |
15444 | (parallel [(const_int 1) | |
15445 | (const_int 0)])) | |
15446 | (const_int 1)))] | |
15447 | "TARGET_MMX" | |
332316cd | 15448 | "punpckhdq\\t{%2, %0|%0, %2}" |
915119a5 BS |
15449 | [(set_attr "type" "mmx")]) |
15450 | ||
15451 | (define_insn "mmx_punpcklbw" | |
15452 | [(set (match_operand:V8QI 0 "register_operand" "=y") | |
15453 | (vec_merge:V8QI | |
15454 | (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0") | |
15455 | (parallel [(const_int 0) | |
15456 | (const_int 4) | |
15457 | (const_int 1) | |
15458 | (const_int 5) | |
15459 | (const_int 2) | |
15460 | (const_int 6) | |
15461 | (const_int 3) | |
15462 | (const_int 7)])) | |
15463 | (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y") | |
15464 | (parallel [(const_int 4) | |
15465 | (const_int 0) | |
15466 | (const_int 5) | |
15467 | (const_int 1) | |
15468 | (const_int 6) | |
15469 | (const_int 2) | |
15470 | (const_int 7) | |
15471 | (const_int 3)])) | |
15472 | (const_int 85)))] | |
15473 | "TARGET_MMX" | |
15474 | "punpcklbw\\t{%2, %0|%0, %2}" | |
15475 | [(set_attr "type" "mmx")]) | |
15476 | ||
15477 | (define_insn "mmx_punpcklwd" | |
15478 | [(set (match_operand:V4HI 0 "register_operand" "=y") | |
15479 | (vec_merge:V4HI | |
15480 | (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0") | |
15481 | (parallel [(const_int 2) | |
15482 | (const_int 0) | |
15483 | (const_int 3) | |
15484 | (const_int 1)])) | |
15485 | (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y") | |
15486 | (parallel [(const_int 0) | |
15487 | (const_int 2) | |
15488 | (const_int 1) | |
15489 | (const_int 3)])) | |
15490 | (const_int 5)))] | |
15491 | "TARGET_MMX" | |
332316cd | 15492 | "punpcklwd\\t{%2, %0|%0, %2}" |
915119a5 BS |
15493 | [(set_attr "type" "mmx")]) |
15494 | ||
15495 | (define_insn "mmx_punpckldq" | |
15496 | [(set (match_operand:V2SI 0 "register_operand" "=y") | |
15497 | (vec_merge:V2SI | |
15498 | (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0") | |
15499 | (parallel [(const_int 1) | |
15500 | (const_int 0)])) | |
15501 | (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y") | |
15502 | (parallel [(const_int 0) | |
15503 | (const_int 1)])) | |
15504 | (const_int 1)))] | |
15505 | "TARGET_MMX" | |
332316cd | 15506 | "punpckldq\\t{%2, %0|%0, %2}" |
915119a5 BS |
15507 | [(set_attr "type" "mmx")]) |
15508 | ||
15509 | ||
15510 | ;; Miscellaneous stuff | |
15511 | ||
15512 | (define_insn "emms" | |
15513 | [(unspec_volatile [(const_int 0)] 31) | |
15514 | (clobber (reg:XF 8)) | |
15515 | (clobber (reg:XF 9)) | |
15516 | (clobber (reg:XF 10)) | |
15517 | (clobber (reg:XF 11)) | |
15518 | (clobber (reg:XF 12)) | |
15519 | (clobber (reg:XF 13)) | |
15520 | (clobber (reg:XF 14)) | |
15521 | (clobber (reg:XF 15)) | |
915119a5 BS |
15522 | (clobber (reg:DI 29)) |
15523 | (clobber (reg:DI 30)) | |
15524 | (clobber (reg:DI 31)) | |
15525 | (clobber (reg:DI 32)) | |
15526 | (clobber (reg:DI 33)) | |
bd793c65 BS |
15527 | (clobber (reg:DI 34)) |
15528 | (clobber (reg:DI 35)) | |
15529 | (clobber (reg:DI 36))] | |
915119a5 BS |
15530 | "TARGET_MMX" |
15531 | "emms" | |
bd793c65 BS |
15532 | [(set_attr "type" "mmx") |
15533 | (set_attr "memory" "unknown")]) | |
915119a5 BS |
15534 | |
15535 | (define_insn "ldmxcsr" | |
15536 | [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)] | |
15537 | "TARGET_MMX" | |
15538 | "ldmxcsr\\t%0" | |
15539 | [(set_attr "type" "mmx")]) | |
15540 | ||
15541 | (define_insn "stmxcsr" | |
15542 | [(set (match_operand:SI 0 "memory_operand" "=m") | |
15543 | (unspec_volatile:SI [(const_int 0)] 40))] | |
15544 | "TARGET_MMX" | |
15545 | "stmxcsr\\t%0" | |
15546 | [(set_attr "type" "mmx")]) | |
15547 | ||
15548 | (define_expand "sfence" | |
15549 | [(set (match_dup 0) | |
15550 | (unspec:BLK [(match_dup 0)] 44))] | |
15551 | "TARGET_SSE" | |
15552 | " | |
15553 | { | |
15554 | operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); | |
15555 | MEM_VOLATILE_P (operands[0]) = 1; | |
15556 | }") | |
15557 | ||
15558 | (define_insn "*sfence_insn" | |
15559 | [(set (match_operand:BLK 0 "" "") | |
15560 | (unspec:BLK [(match_dup 0)] 44))] | |
15561 | "TARGET_SSE" | |
15562 | "sfence" | |
bd793c65 BS |
15563 | [(set_attr "type" "sse") |
15564 | (set_attr "memory" "unknown")]) | |
915119a5 BS |
15565 | |
15566 | (define_insn "prefetch" | |
15567 | [(unspec [(match_operand:SI 0 "address_operand" "p") | |
332316cd | 15568 | (match_operand:SI 1 "immediate_operand" "n")] 35)] |
915119a5 BS |
15569 | "TARGET_SSE" |
15570 | "* | |
15571 | { | |
15572 | switch (INTVAL (operands[1])) | |
15573 | { | |
15574 | case 0: | |
332316cd | 15575 | return \"prefetchnta\\t%a0\"; |
915119a5 | 15576 | case 1: |
332316cd | 15577 | return \"prefetcht0\\t%a0\"; |
915119a5 | 15578 | case 2: |
332316cd | 15579 | return \"prefetcht1\\t%a0\"; |
915119a5 | 15580 | case 3: |
332316cd | 15581 | return \"prefetcht2\\t%a0\"; |
915119a5 BS |
15582 | default: |
15583 | abort (); | |
15584 | } | |
15585 | }" | |
15586 | [(set_attr "type" "sse")]) | |
15587 |