]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.md
Daily bump.
[gcc.git] / gcc / config / i386 / i386.md
CommitLineData
f25aca7a 1; GCC machine description for Intel X86.
270fc2ae 2;; Copyright (C) 1988, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
886c62d1
JVA
3;; Mostly by William Schelter.
4
5;; This file is part of GNU CC.
6
7;; GNU CC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; GNU CC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU CC; see the file COPYING. If not, write to
3f63df56 19;; the Free Software Foundation, 59 Temple Place - Suite 330,
2ae0f82c 20;; Boston, MA 02111-1307, USA. */
886c62d1 21
4af3895e
JVA
22;; The original PO technology requires these to be ordered by speed,
23;; so that assigner will pick the fastest.
886c62d1 24
4af3895e 25;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
886c62d1 26
4af3895e
JVA
27;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
28;; updates for most instructions.
886c62d1 29
4af3895e
JVA
30;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31;; constraint letters.
886c62d1
JVA
32
33;; the special asm out single letter directives following a '%' are:
4af3895e
JVA
34;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35;; operands[1].
36;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38;; 'B' Print the opcode suffix for an 8-bit integer opcode.
4af3895e 39;; 'Q' Print the opcode suffix for a 64-bit float opcode.
56710e42 40;; 'S' Print the opcode suffix for a 32-bit float opcode.
b08de47e
MM
41;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42;; 'J' Print the appropriate jump operand.
4af3895e
JVA
43
44;; 'b' Print the QImode name of the register for the indicated operand.
45;; %b0 would print %al if operands[0] is reg 0.
46;; 'w' Likewise, print the HImode name of the register.
47;; 'k' Likewise, print the SImode name of the register.
48;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49;; 'y' Print "st(0)" instead of "st" as a register.
50
51;; UNSPEC usage:
52;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
53;; operand 0 is the memory address to scan.
54;; operand 1 is a register containing the value to scan for. The mode
55;; of the scas opcode will be the same as the mode of this operand.
56;; operand 2 is the known alignment of operand 0.
a199fdd6
JVA
57;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
58;; operand 0 is the argument for `sin'.
59;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
60;; operand 0 is the argument for `cos'.
578b58f5
RK
61;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
62;; always SImode. operand 0 is the size of the stack allocation.
47d36400
BS
63;; 4 This is the source of a fake SET of the frame pointer which is used to
64;; prevent insns referencing it being scheduled across the initial
65;; decrement of the stack pointer.
ce193852 66;; 5 This is a `bsf' operation.
91bb873f
RH
67;; 6 This is the @GOT offset of a PIC address.
68;; 7 This is the @GOTOFF offset of a PIC address.
69;; 8 This is a reference to a symbol's @PLT address.
2ae0f82c
SC
70\f
71;; This shadows the processor_type enumeration, so changes must be made
72;; to i386.h at the same time.
73
a269a03c
JC
74(define_attr "type"
75 "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul"
2ae0f82c
SC
76 (const_string "integer"))
77
a269a03c
JC
78(define_attr "memory" "none,load,store"
79 (cond [(eq_attr "type" "idiv,lea")
80 (const_string "none")
81
82 (eq_attr "type" "fld")
83 (const_string "load")
84
85 (eq_attr "type" "test")
86 (if_then_else (match_operand 0 "memory_operand" "")
87 (const_string "load")
88 (const_string "none"))
89
90 (eq_attr "type" "compare,fcompare")
91 (if_then_else (ior (match_operand 0 "memory_operand" "")
92 (match_operand 1 "memory_operand" ""))
93 (const_string "load")
94 (const_string "none"))
95
96 (and (eq_attr "type" "integer,memory,fpop")
97 (match_operand 0 "memory_operand" ""))
98 (const_string "store")
99
100 (and (eq_attr "type" "integer,memory,fpop")
101 (match_operand 1 "memory_operand" ""))
102 (const_string "load")
103
104 (and (eq_attr "type" "binary,imul,fpmul,fpdiv")
105 (ior (match_operand 1 "memory_operand" "")
106 (match_operand 2 "memory_operand" "")))
107 (const_string "load")]
108
109 (const_string "none")))
110
2ae0f82c
SC
111;; Functional units
112
36cf4bcf
SC
113; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
114; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
115
116; pentiumpro has a reservation station with 5 ports
117; port 0 has integer, float add, integer divide, float divide, float
118; multiply, and shifter units.
119; port 1 has integer, and jump units.
120; port 2 has the load address generation unit
121; ports 3 and 4 have the store address generation units
122
123; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
124; and a float pipeline
125
2ae0f82c
SC
126;; Floating point
127
128(define_function_unit "fp" 1 0
a269a03c 129 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486"))
2ae0f82c
SC
130 5 5)
131
132(define_function_unit "fp" 1 0
a269a03c 133 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro"))
2ae0f82c
SC
134 3 0)
135
36cf4bcf
SC
136(define_function_unit "fp" 1 0
137 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium"))
138 7 0)
139
140(define_function_unit "fp" 1 0
141 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro"))
142 5 0)
143
144(define_function_unit "fp" 1 0
145 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro"))
146 10 10)
147
148(define_function_unit "fp" 1 0
149 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro"))
150 6 0)
151
2ae0f82c
SC
152(define_function_unit "fp" 1 0
153 (eq_attr "type" "fpdiv")
154 10 10)
155
156(define_function_unit "fp" 1 0
a269a03c 157 (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6"))
2ae0f82c
SC
158 1 0)
159
a269a03c
JC
160;; K6 FPU is not pipelined.
161(define_function_unit "fp" 1 0
162 (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6"))
163 2 2)
164
165;; i386 and i486 have one integer unit, which need not be modeled
166
167(define_function_unit "integer" 2 0
168 (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro"))
169 1 0)
170
171(define_function_unit "integer" 2 0
172 (and (eq_attr "cpu" "k6")
173 (and (eq_attr "type" "integer,binary,test,compare")
174 (eq_attr "memory" "!load")))
175 1 0)
176
177;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles)
178;; and a register operation (1 cycle).
179(define_function_unit "integer" 2 0
180 (and (eq_attr "cpu" "k6")
181 (and (eq_attr "type" "integer,binary,test,compare")
182 (eq_attr "memory" "load")))
183 3 0)
184
185;; Multiplies use one of the integer units
186(define_function_unit "integer" 2 0
187 (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul"))
188 11 11)
189
190(define_function_unit "integer" 2 0
191 (and (eq_attr "cpu" "k6") (eq_attr "type" "imul"))
192 2 2)
193
194(define_function_unit "integer" 2 0
195 (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv"))
196 25 25)
197
198(define_function_unit "integer" 2 0
199 (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv"))
200 17 17)
201
202;; Pentium Pro and K6 have a separate load unit.
203(define_function_unit "load" 1 0
204 (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load"))
205 3 0)
206
207(define_function_unit "load" 1 0
208 (and (eq_attr "cpu" "k6") (eq_attr "memory" "load"))
209 2 0)
210
211;; Pentium Pro and K6 have a separate store unit.
212(define_function_unit "store" 1 0
213 (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store"))
214 1 0)
215
216;; lea executes in the K6 store unit with 1 cycle latency
217(define_function_unit "store" 1 0
218 (and (eq_attr "cpu" "k6") (eq_attr "type" "lea"))
219 1 0)
2ae0f82c 220
886c62d1 221\f
886c62d1
JVA
222;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
223;; But restricting MEM here would mean that gcc could not remove a redundant
224;; test in cases like "incl MEM / je TARGET".
225;;
226;; We don't want to allow a constant operand for test insns because
227;; (set (cc0) (const_int foo)) has no mode information. Such insns will
228;; be folded while optimizing anyway.
229
c572e5ba
JVA
230;; All test insns have expanders that save the operands away without
231;; actually generating RTL. The bCOND or sCOND (emitted immediately
232;; after the tstM or cmp) will actually emit the tstM or cmpM.
233
268bfa44 234;; Processor type -- this attribute must exactly match the processor_type
926b3fae 235;; enumeration in i386.h.
268bfa44 236
a269a03c 237(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6"
2ae0f82c 238 (const (symbol_ref "ix86_cpu")))
268bfa44 239
fe4435d9 240(define_insn "tstsi_1"
886c62d1
JVA
241 [(set (cc0)
242 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
243 ""
244 "*
245{
246 if (REG_P (operands[0]))
247 return AS2 (test%L0,%0,%0);
248
249 operands[1] = const0_rtx;
250 return AS2 (cmp%L0,%1,%0);
a269a03c
JC
251}"
252 [(set_attr "type" "test")])
886c62d1 253
c572e5ba
JVA
254(define_expand "tstsi"
255 [(set (cc0)
256 (match_operand:SI 0 "nonimmediate_operand" ""))]
257 ""
258 "
259{
fe4435d9 260 i386_compare_gen = gen_tstsi_1;
c572e5ba 261 i386_compare_op0 = operands[0];
726e2d54 262 i386_compare_op1 = const0_rtx;
c572e5ba
JVA
263 DONE;
264}")
265
fe4435d9 266(define_insn "tsthi_1"
886c62d1
JVA
267 [(set (cc0)
268 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
269 ""
270 "*
271{
272 if (REG_P (operands[0]))
273 return AS2 (test%W0,%0,%0);
274
275 operands[1] = const0_rtx;
276 return AS2 (cmp%W0,%1,%0);
a269a03c
JC
277}"
278 [(set_attr "type" "test")])
886c62d1 279
c572e5ba
JVA
280(define_expand "tsthi"
281 [(set (cc0)
282 (match_operand:HI 0 "nonimmediate_operand" ""))]
283 ""
284 "
285{
fe4435d9 286 i386_compare_gen = gen_tsthi_1;
c572e5ba 287 i386_compare_op0 = operands[0];
726e2d54 288 i386_compare_op1 = const0_rtx;
c572e5ba
JVA
289 DONE;
290}")
291
fe4435d9 292(define_insn "tstqi_1"
886c62d1
JVA
293 [(set (cc0)
294 (match_operand:QI 0 "nonimmediate_operand" "qm"))]
295 ""
296 "*
297{
298 if (REG_P (operands[0]))
299 return AS2 (test%B0,%0,%0);
300
301 operands[1] = const0_rtx;
302 return AS2 (cmp%B0,%1,%0);
a269a03c
JC
303}"
304 [(set_attr "type" "test")])
886c62d1 305
c572e5ba
JVA
306(define_expand "tstqi"
307 [(set (cc0)
308 (match_operand:QI 0 "nonimmediate_operand" ""))]
309 ""
310 "
311{
fe4435d9 312 i386_compare_gen = gen_tstqi_1;
c572e5ba 313 i386_compare_op0 = operands[0];
726e2d54 314 i386_compare_op1 = const0_rtx;
c572e5ba
JVA
315 DONE;
316}")
317
318(define_insn "tstsf_cc"
886c62d1
JVA
319 [(set (cc0)
320 (match_operand:SF 0 "register_operand" "f"))
321 (clobber (match_scratch:HI 1 "=a"))]
c572e5ba 322 "TARGET_80387 && ! TARGET_IEEE_FP"
886c62d1
JVA
323 "*
324{
325 if (! STACK_TOP_P (operands[0]))
326 abort ();
327
328 output_asm_insn (\"ftst\", operands);
886c62d1
JVA
329
330 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
331 output_asm_insn (AS1 (fstp,%y0), operands);
332
2f2a49e8 333 return output_fp_cc0_set (insn);
a269a03c
JC
334}"
335 [(set_attr "type" "test")])
c572e5ba
JVA
336
337;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
338;; isn't IEEE compliant.
886c62d1 339
c572e5ba
JVA
340(define_expand "tstsf"
341 [(parallel [(set (cc0)
342 (match_operand:SF 0 "register_operand" ""))
343 (clobber (match_scratch:HI 1 ""))])]
344 "TARGET_80387 && ! TARGET_IEEE_FP"
345 "
346{
347 i386_compare_gen = gen_tstsf_cc;
348 i386_compare_op0 = operands[0];
726e2d54 349 i386_compare_op1 = const0_rtx;
c572e5ba 350 DONE;
886c62d1
JVA
351}")
352
c572e5ba 353(define_insn "tstdf_cc"
886c62d1
JVA
354 [(set (cc0)
355 (match_operand:DF 0 "register_operand" "f"))
356 (clobber (match_scratch:HI 1 "=a"))]
c572e5ba 357 "TARGET_80387 && ! TARGET_IEEE_FP"
886c62d1
JVA
358 "*
359{
360 if (! STACK_TOP_P (operands[0]))
361 abort ();
362
363 output_asm_insn (\"ftst\", operands);
886c62d1
JVA
364
365 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
366 output_asm_insn (AS1 (fstp,%y0), operands);
367
2f2a49e8 368 return output_fp_cc0_set (insn);
a269a03c
JC
369}"
370 [(set_attr "type" "test")])
886c62d1 371
c572e5ba
JVA
372;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
373;; isn't IEEE compliant.
374
375(define_expand "tstdf"
376 [(parallel [(set (cc0)
377 (match_operand:DF 0 "register_operand" ""))
378 (clobber (match_scratch:HI 1 ""))])]
379 "TARGET_80387 && ! TARGET_IEEE_FP"
380 "
381{
382 i386_compare_gen = gen_tstdf_cc;
383 i386_compare_op0 = operands[0];
726e2d54 384 i386_compare_op1 = const0_rtx;
c572e5ba 385 DONE;
886c62d1 386}")
4fb21e90
JVA
387
388(define_insn "tstxf_cc"
389 [(set (cc0)
390 (match_operand:XF 0 "register_operand" "f"))
391 (clobber (match_scratch:HI 1 "=a"))]
392 "TARGET_80387 && ! TARGET_IEEE_FP"
393 "*
394{
395 if (! STACK_TOP_P (operands[0]))
396 abort ();
397
398 output_asm_insn (\"ftst\", operands);
399
400 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
401 output_asm_insn (AS1 (fstp,%y0), operands);
402
2f2a49e8 403 return output_fp_cc0_set (insn);
a269a03c
JC
404}"
405 [(set_attr "type" "test")])
4fb21e90 406
2ae0f82c 407;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
4fb21e90
JVA
408;; isn't IEEE compliant.
409
410(define_expand "tstxf"
411 [(parallel [(set (cc0)
412 (match_operand:XF 0 "register_operand" ""))
413 (clobber (match_scratch:HI 1 ""))])]
414 "TARGET_80387 && ! TARGET_IEEE_FP"
415 "
416{
417 i386_compare_gen = gen_tstxf_cc;
418 i386_compare_op0 = operands[0];
726e2d54 419 i386_compare_op1 = const0_rtx;
4fb21e90
JVA
420 DONE;
421}")
886c62d1 422\f
c572e5ba
JVA
423;;- compare instructions. See comments above tstM patterns about
424;; expansion of these insns.
886c62d1 425
fe4435d9 426(define_insn "cmpsi_1"
886c62d1 427 [(set (cc0)
fe4435d9
JVA
428 (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
429 (match_operand:SI 1 "general_operand" "ri,mr")))]
430 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
a269a03c
JC
431 "* return AS2 (cmp%L0,%1,%0);"
432 [(set_attr "type" "compare")])
886c62d1 433
c572e5ba 434(define_expand "cmpsi"
886c62d1 435 [(set (cc0)
fe4435d9
JVA
436 (compare (match_operand:SI 0 "nonimmediate_operand" "")
437 (match_operand:SI 1 "general_operand" "")))]
c572e5ba
JVA
438 ""
439 "
440{
fe4435d9
JVA
441 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
442 operands[0] = force_reg (SImode, operands[0]);
443
444 i386_compare_gen = gen_cmpsi_1;
c572e5ba
JVA
445 i386_compare_op0 = operands[0];
446 i386_compare_op1 = operands[1];
447 DONE;
448}")
449
fe4435d9 450(define_insn "cmphi_1"
c572e5ba 451 [(set (cc0)
fe4435d9
JVA
452 (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
453 (match_operand:HI 1 "general_operand" "ri,mr")))]
454 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
a269a03c
JC
455 "* return AS2 (cmp%W0,%1,%0);"
456 [(set_attr "type" "compare")])
886c62d1 457
c572e5ba 458(define_expand "cmphi"
886c62d1 459 [(set (cc0)
fe4435d9
JVA
460 (compare (match_operand:HI 0 "nonimmediate_operand" "")
461 (match_operand:HI 1 "general_operand" "")))]
c572e5ba
JVA
462 ""
463 "
464{
fe4435d9
JVA
465 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
466 operands[0] = force_reg (HImode, operands[0]);
467
468 i386_compare_gen = gen_cmphi_1;
c572e5ba
JVA
469 i386_compare_op0 = operands[0];
470 i386_compare_op1 = operands[1];
471 DONE;
472}")
473
fe4435d9 474(define_insn "cmpqi_1"
c572e5ba 475 [(set (cc0)
fe4435d9
JVA
476 (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
477 (match_operand:QI 1 "general_operand" "qm,nq")))]
478 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
a269a03c
JC
479 "* return AS2 (cmp%B0,%1,%0);"
480 [(set_attr "type" "compare")])
886c62d1 481
c572e5ba
JVA
482(define_expand "cmpqi"
483 [(set (cc0)
fe4435d9
JVA
484 (compare (match_operand:QI 0 "nonimmediate_operand" "")
485 (match_operand:QI 1 "general_operand" "")))]
c572e5ba
JVA
486 ""
487 "
488{
fe4435d9
JVA
489 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
490 operands[0] = force_reg (QImode, operands[0]);
491
492 i386_compare_gen = gen_cmpqi_1;
c572e5ba
JVA
493 i386_compare_op0 = operands[0];
494 i386_compare_op1 = operands[1];
495 DONE;
496}")
497
886c62d1
JVA
498;; These implement float point compares. For each of DFmode and
499;; SFmode, there is the normal insn, and an insn where the second operand
500;; is converted to the desired mode.
501
4fb21e90
JVA
502(define_insn ""
503 [(set (cc0)
504 (match_operator 2 "VOIDmode_compare_op"
cac58785
SC
505 [(match_operand:XF 0 "register_operand" "f")
506 (match_operand:XF 1 "register_operand" "f")]))
507 (clobber (match_scratch:HI 3 "=a"))]
508 "TARGET_80387"
a269a03c
JC
509 "* return output_float_compare (insn, operands);"
510 [(set_attr "type" "fcompare")])
4fb21e90 511
4fb21e90
JVA
512(define_insn ""
513 [(set (cc0)
514 (match_operator 2 "VOIDmode_compare_op"
515 [(match_operand:XF 0 "register_operand" "f")
516 (float_extend:XF
517 (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
518 (clobber (match_scratch:HI 3 "=a"))]
519 "TARGET_80387"
a269a03c
JC
520 "* return output_float_compare (insn, operands);"
521 [(set_attr "type" "fcompare")])
4fb21e90 522
926b3fae
SC
523(define_insn ""
524 [(set (cc0)
525 (match_operator 2 "VOIDmode_compare_op"
526 [(float_extend:XF
9ec36da5
JL
527 (match_operand:DF 0 "nonimmediate_operand" "fm"))
528 (match_operand:XF 1 "register_operand" "f")]))
926b3fae
SC
529 (clobber (match_scratch:HI 3 "=a"))]
530 "TARGET_80387"
a269a03c
JC
531 "* return output_float_compare (insn, operands);"
532 [(set_attr "type" "fcompare")])
926b3fae 533
4fb21e90
JVA
534(define_insn ""
535 [(set (cc0)
536 (match_operator 2 "VOIDmode_compare_op"
537 [(match_operand:XF 0 "register_operand" "f")
538 (float_extend:XF
539 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
540 (clobber (match_scratch:HI 3 "=a"))]
541 "TARGET_80387"
a269a03c
JC
542 "* return output_float_compare (insn, operands);"
543 [(set_attr "type" "fcompare")])
4fb21e90 544
9ec36da5
JL
545(define_insn ""
546 [(set (cc0)
547 (match_operator 2 "VOIDmode_compare_op"
548 [(float_extend:XF
549 (match_operand:SF 0 "nonimmediate_operand" "fm"))
550 (match_operand:XF 1 "register_operand" "f")]))
551 (clobber (match_scratch:HI 3 "=a"))]
552 "TARGET_80387"
a269a03c
JC
553 "* return output_float_compare (insn, operands);"
554 [(set_attr "type" "fcompare")])
9ec36da5 555
4fb21e90
JVA
556(define_insn ""
557 [(set (cc0)
558 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
559 (match_operand:XF 1 "register_operand" "f")))
560 (clobber (match_scratch:HI 2 "=a"))]
561 "TARGET_80387"
a269a03c
JC
562 "* return output_float_compare (insn, operands);"
563 [(set_attr "type" "fcompare")])
4fb21e90 564
fe4435d9 565(define_insn ""
08a7baac 566 [(set (cc0)
fe4435d9
JVA
567 (match_operator 2 "VOIDmode_compare_op"
568 [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
569 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
570 (clobber (match_scratch:HI 3 "=a,a"))]
08a7baac
JVA
571 "TARGET_80387
572 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
a269a03c
JC
573 "* return output_float_compare (insn, operands);"
574 [(set_attr "type" "fcompare")])
08a7baac 575
c572e5ba
JVA
576(define_insn ""
577 [(set (cc0)
fe4435d9
JVA
578 (match_operator 2 "VOIDmode_compare_op"
579 [(match_operand:DF 0 "register_operand" "f")
580 (float_extend:DF
581 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
582 (clobber (match_scratch:HI 3 "=a"))]
08a7baac 583 "TARGET_80387"
a269a03c
JC
584 "* return output_float_compare (insn, operands);"
585 [(set_attr "type" "fcompare")])
08a7baac
JVA
586
587(define_insn ""
588 [(set (cc0)
fe4435d9
JVA
589 (match_operator 2 "VOIDmode_compare_op"
590 [(float_extend:DF
591 (match_operand:SF 0 "nonimmediate_operand" "fm"))
592 (match_operand:DF 1 "register_operand" "f")]))
593 (clobber (match_scratch:HI 3 "=a"))]
c572e5ba 594 "TARGET_80387"
a269a03c
JC
595 "* return output_float_compare (insn, operands);"
596 [(set_attr "type" "fcompare")])
2bb7a0f5 597
2ae0f82c
SC
598(define_insn ""
599 [(set (cc0)
600 (match_operator 2 "VOIDmode_compare_op"
601 [(float_extend:DF
602 (match_operand:SF 0 "register_operand" "f"))
603 (match_operand:DF 1 "nonimmediate_operand" "fm")]))
604 (clobber (match_scratch:HI 3 "=a"))]
605 "TARGET_80387"
a269a03c
JC
606 "* return output_float_compare (insn, operands);"
607 [(set_attr "type" "fcompare")])
2ae0f82c 608
886c62d1
JVA
609(define_insn ""
610 [(set (cc0)
c572e5ba
JVA
611 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
612 (match_operand:DF 1 "register_operand" "f")))
886c62d1
JVA
613 (clobber (match_scratch:HI 2 "=a"))]
614 "TARGET_80387"
a269a03c
JC
615 "* return output_float_compare (insn, operands);"
616 [(set_attr "type" "fcompare")])
886c62d1 617
fe4435d9
JVA
618;; These two insns will never be generated by combine due to the mode of
619;; the COMPARE.
620;(define_insn ""
621; [(set (cc0)
622; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
623; (float_extend:DF
624; (match_operand:SF 1 "register_operand" "f"))))
625; (clobber (match_scratch:HI 2 "=a"))]
626; "TARGET_80387"
2f2a49e8 627; "* return output_float_compare (insn, operands);")
fe4435d9
JVA
628;
629;(define_insn ""
630; [(set (cc0)
631; (compare:CCFPEQ (float_extend:DF
632; (match_operand:SF 0 "register_operand" "f"))
633; (match_operand:DF 1 "register_operand" "f")))
634; (clobber (match_scratch:HI 2 "=a"))]
635; "TARGET_80387"
2f2a49e8 636; "* return output_float_compare (insn, operands);")
fe4435d9 637
a269a03c 638(define_insn "*cmpsf_cc_1"
08a7baac 639 [(set (cc0)
fe4435d9
JVA
640 (match_operator 2 "VOIDmode_compare_op"
641 [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
642 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
643 (clobber (match_scratch:HI 3 "=a,a"))]
08a7baac
JVA
644 "TARGET_80387
645 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
a269a03c
JC
646 "* return output_float_compare (insn, operands);"
647 [(set_attr "type" "fcompare")])
08a7baac 648
886c62d1
JVA
649(define_insn ""
650 [(set (cc0)
c572e5ba
JVA
651 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
652 (match_operand:SF 1 "register_operand" "f")))
886c62d1
JVA
653 (clobber (match_scratch:HI 2 "=a"))]
654 "TARGET_80387"
a269a03c
JC
655 "* return output_float_compare (insn, operands);"
656 [(set_attr "type" "fcompare")])
886c62d1 657
4fb21e90
JVA
658(define_expand "cmpxf"
659 [(set (cc0)
660 (compare (match_operand:XF 0 "register_operand" "")
cac58785 661 (match_operand:XF 1 "register_operand" "")))]
4fb21e90
JVA
662 "TARGET_80387"
663 "
664{
665 i386_compare_gen = gen_cmpxf_cc;
666 i386_compare_gen_eq = gen_cmpxf_ccfpeq;
667 i386_compare_op0 = operands[0];
cac58785 668 i386_compare_op1 = operands[1];
4fb21e90
JVA
669 DONE;
670}")
671
c572e5ba 672(define_expand "cmpdf"
886c62d1 673 [(set (cc0)
fe4435d9 674 (compare (match_operand:DF 0 "register_operand" "")
2ae0f82c 675 (match_operand:DF 1 "general_operand" "")))]
886c62d1 676 "TARGET_80387"
c572e5ba
JVA
677 "
678{
679 i386_compare_gen = gen_cmpdf_cc;
680 i386_compare_gen_eq = gen_cmpdf_ccfpeq;
681 i386_compare_op0 = operands[0];
2ae0f82c
SC
682 i386_compare_op1 = (immediate_operand (operands[1], DFmode))
683 ? copy_to_mode_reg (DFmode, operands[1]) : operands[1];
c572e5ba
JVA
684 DONE;
685}")
686
687(define_expand "cmpsf"
688 [(set (cc0)
fe4435d9 689 (compare (match_operand:SF 0 "register_operand" "")
2ae0f82c 690 (match_operand:SF 1 "general_operand" "")))]
c572e5ba
JVA
691 "TARGET_80387"
692 "
693{
694 i386_compare_gen = gen_cmpsf_cc;
695 i386_compare_gen_eq = gen_cmpsf_ccfpeq;
696 i386_compare_op0 = operands[0];
2ae0f82c
SC
697 i386_compare_op1 = (immediate_operand (operands[1], SFmode))
698 ? copy_to_mode_reg (SFmode, operands[1]) : operands[1];
c572e5ba
JVA
699 DONE;
700}")
701
4fb21e90
JVA
702(define_expand "cmpxf_cc"
703 [(parallel [(set (cc0)
704 (compare (match_operand:XF 0 "register_operand" "")
705 (match_operand:XF 1 "register_operand" "")))
706 (clobber (match_scratch:HI 2 ""))])]
707 "TARGET_80387"
708 "")
709
710(define_expand "cmpxf_ccfpeq"
711 [(parallel [(set (cc0)
712 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
713 (match_operand:XF 1 "register_operand" "")))
714 (clobber (match_scratch:HI 2 ""))])]
715 "TARGET_80387"
cac58785 716 "")
4fb21e90 717
fe4435d9
JVA
718(define_expand "cmpdf_cc"
719 [(parallel [(set (cc0)
720 (compare (match_operand:DF 0 "register_operand" "")
721 (match_operand:DF 1 "register_operand" "")))
722 (clobber (match_scratch:HI 2 ""))])]
723 "TARGET_80387"
724 "")
725
c572e5ba
JVA
726(define_expand "cmpdf_ccfpeq"
727 [(parallel [(set (cc0)
728 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
729 (match_operand:DF 1 "register_operand" "")))
730 (clobber (match_scratch:HI 2 ""))])]
731 "TARGET_80387"
732 "
733{
734 if (! register_operand (operands[1], DFmode))
735 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
736}")
737
fe4435d9
JVA
738(define_expand "cmpsf_cc"
739 [(parallel [(set (cc0)
740 (compare (match_operand:SF 0 "register_operand" "")
741 (match_operand:SF 1 "register_operand" "")))
742 (clobber (match_scratch:HI 2 ""))])]
743 "TARGET_80387"
744 "")
745
c572e5ba
JVA
746(define_expand "cmpsf_ccfpeq"
747 [(parallel [(set (cc0)
748 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
749 (match_operand:SF 1 "register_operand" "")))
750 (clobber (match_scratch:HI 2 ""))])]
751 "TARGET_80387"
752 "
753{
754 if (! register_operand (operands[1], SFmode))
755 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
756}")
886c62d1
JVA
757\f
758;; logical compare
759
886c62d1
JVA
760(define_insn ""
761 [(set (cc0)
b4ac57ab 762 (and:SI (match_operand:SI 0 "general_operand" "%ro")
2ae0f82c 763 (match_operand:SI 1 "nonmemory_operand" "ri")))]
886c62d1
JVA
764 ""
765 "*
766{
767 /* For small integers, we may actually use testb. */
768 if (GET_CODE (operands[1]) == CONST_INT
b4ac57ab 769 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
a199fdd6 770 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
886c62d1
JVA
771 {
772 /* We may set the sign bit spuriously. */
886c62d1 773
b4ac57ab
RS
774 if ((INTVAL (operands[1]) & ~0xff) == 0)
775 {
776 cc_status.flags |= CC_NOT_NEGATIVE;
777 return AS2 (test%B0,%1,%b0);
778 }
886c62d1 779
b4ac57ab 780 if ((INTVAL (operands[1]) & ~0xff00) == 0)
886c62d1 781 {
b4ac57ab 782 cc_status.flags |= CC_NOT_NEGATIVE;
a199fdd6 783 operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
b4ac57ab
RS
784
785 if (QI_REG_P (operands[0]))
786 return AS2 (test%B0,%1,%h0);
787 else
788 {
789 operands[0] = adj_offsettable_operand (operands[0], 1);
790 return AS2 (test%B0,%1,%b0);
791 }
792 }
793
794 if (GET_CODE (operands[0]) == MEM
795 && (INTVAL (operands[1]) & ~0xff0000) == 0)
796 {
797 cc_status.flags |= CC_NOT_NEGATIVE;
a199fdd6 798 operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
b4ac57ab
RS
799 operands[0] = adj_offsettable_operand (operands[0], 2);
800 return AS2 (test%B0,%1,%b0);
801 }
802
803 if (GET_CODE (operands[0]) == MEM
804 && (INTVAL (operands[1]) & ~0xff000000) == 0)
805 {
a199fdd6 806 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
b4ac57ab
RS
807 operands[0] = adj_offsettable_operand (operands[0], 3);
808 return AS2 (test%B0,%1,%b0);
886c62d1
JVA
809 }
810 }
811
812 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
813 return AS2 (test%L0,%1,%0);
814
815 return AS2 (test%L1,%0,%1);
a269a03c
JC
816}"
817 [(set_attr "type" "compare")])
886c62d1
JVA
818
819(define_insn ""
820 [(set (cc0)
b4ac57ab 821 (and:HI (match_operand:HI 0 "general_operand" "%ro")
2ae0f82c 822 (match_operand:HI 1 "nonmemory_operand" "ri")))]
886c62d1
JVA
823 ""
824 "*
825{
826 if (GET_CODE (operands[1]) == CONST_INT
b4ac57ab 827 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
a199fdd6 828 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
886c62d1 829 {
b4ac57ab 830 if ((INTVAL (operands[1]) & 0xff00) == 0)
886c62d1 831 {
b4ac57ab 832 /* ??? This might not be necessary. */
886c62d1 833 if (INTVAL (operands[1]) & 0xffff0000)
a199fdd6 834 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
886c62d1
JVA
835
836 /* We may set the sign bit spuriously. */
837 cc_status.flags |= CC_NOT_NEGATIVE;
838 return AS2 (test%B0,%1,%b0);
839 }
840
b4ac57ab 841 if ((INTVAL (operands[1]) & 0xff) == 0)
886c62d1 842 {
a199fdd6 843 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
b4ac57ab
RS
844
845 if (QI_REG_P (operands[0]))
846 return AS2 (test%B0,%1,%h0);
847 else
848 {
849 operands[0] = adj_offsettable_operand (operands[0], 1);
850 return AS2 (test%B0,%1,%b0);
851 }
886c62d1
JVA
852 }
853 }
854
5bc7cd8e
SC
855 /* use 32-bit test instruction if there are no sign issues */
856 if (GET_CODE (operands[1]) == CONST_INT
857 && !(INTVAL (operands[1]) & ~0x7fff)
858 && i386_aligned_p (operands[0]))
859 return AS2 (test%L0,%1,%k0);
860
886c62d1
JVA
861 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
862 return AS2 (test%W0,%1,%0);
863
864 return AS2 (test%W1,%0,%1);
a269a03c
JC
865}"
866 [(set_attr "type" "compare")])
886c62d1
JVA
867
868(define_insn ""
869 [(set (cc0)
2ae0f82c
SC
870 (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
871 (match_operand:QI 1 "nonmemory_operand" "qi")))]
886c62d1
JVA
872 ""
873 "*
874{
875 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
876 return AS2 (test%B0,%1,%0);
877
878 return AS2 (test%B1,%0,%1);
a269a03c
JC
879}"
880 [(set_attr "type" "compare")])
886c62d1
JVA
881\f
882;; move instructions.
883;; There is one for each machine mode,
884;; and each is preceded by a corresponding push-insn pattern
885;; (since pushes are not general_operands on the 386).
886
685885b7
RH
887(define_insn ""
888 [(set (match_operand:SI 0 "push_operand" "=<")
889 (match_operand:SI 1 "nonmemory_operand" "rn"))]
890 "flag_pic"
a269a03c
JC
891 "* return AS1 (push%L0,%1);"
892 [(set_attr "memory" "store")])
685885b7 893
2f2a49e8
MM
894(define_insn ""
895 [(set (match_operand:SI 0 "push_operand" "=<")
896 (match_operand:SI 1 "nonmemory_operand" "ri"))]
685885b7 897 "!flag_pic"
a269a03c
JC
898 "* return AS1 (push%L0,%1);"
899 [(set_attr "memory" "store")])
2f2a49e8 900
ca097615
JW
901;; On a 386, it is faster to push MEM directly.
902
886c62d1
JVA
903(define_insn ""
904 [(set (match_operand:SI 0 "push_operand" "=<")
ca097615
JW
905 (match_operand:SI 1 "memory_operand" "m"))]
906 "TARGET_PUSH_MEMORY"
a269a03c
JC
907 "* return AS1 (push%L0,%1);"
908 [(set_attr "type" "memory")
909 (set_attr "memory" "load")])
886c62d1
JVA
910
911;; General case of fullword move.
912
2bb7a0f5
RS
913;; If generating PIC code and operands[1] is a symbolic CONST, emit a
914;; move to get the address of the symbolic object from the GOT.
915
916(define_expand "movsi"
917 [(set (match_operand:SI 0 "general_operand" "")
918 (match_operand:SI 1 "general_operand" ""))]
919 ""
920 "
921{
922 extern int flag_pic;
923
924 if (flag_pic && SYMBOLIC_CONST (operands[1]))
925 emit_pic_move (operands, SImode);
2f2a49e8
MM
926
927 /* Don't generate memory->memory moves, go through a register */
928 else if (TARGET_MOVE
61a1397b 929 && no_new_pseudos == 0
2f2a49e8 930 && GET_CODE (operands[0]) == MEM
91f0226f 931 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
932 {
933 operands[1] = force_reg (SImode, operands[1]);
934 }
2bb7a0f5
RS
935}")
936
886c62d1
JVA
937;; On i486, incl reg is faster than movl $1,reg.
938
2bb7a0f5 939(define_insn ""
a269a03c
JC
940 [(set (match_operand:SI 0 "general_operand" "=g,r,r")
941 (match_operand:SI 1 "general_operand" "rn,i,m"))]
685885b7
RH
942 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
943 || (GET_CODE (operands[1]) != MEM))
944 && flag_pic"
886c62d1
JVA
945 "*
946{
947 rtx link;
a269a03c
JC
948
949 /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes
950 longer. */
951 if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
952 && operands[1] == const0_rtx && REG_P (operands[0]))
886c62d1
JVA
953 return AS2 (xor%L0,%0,%0);
954
955 if (operands[1] == const1_rtx
a269a03c
JC
956 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
957 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
886c62d1
JVA
958 && (link = find_reg_note (insn, REG_WAS_0, 0))
959 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 960 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
961 && GET_CODE (XEXP (link, 0)) != NOTE
962 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
963 && no_labels_between_p (XEXP (link, 0), insn)
964 /* Make sure the reg hasn't been clobbered. */
965 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
886c62d1
JVA
966 /* Fastest way to change a 0 to a 1. */
967 return AS1 (inc%L0,%0);
968
685885b7 969 if (SYMBOLIC_CONST (operands[1]))
b840bfb0
MM
970 return AS2 (lea%L0,%a1,%0);
971
886c62d1 972 return AS2 (mov%L0,%1,%0);
a269a03c
JC
973}"
974 [(set_attr "type" "integer,integer,memory")
975 (set_attr "memory" "*,*,load")])
886c62d1 976
685885b7
RH
977(define_insn ""
978 [(set (match_operand:SI 0 "general_operand" "=g,r")
979 (match_operand:SI 1 "general_operand" "ri,m"))]
980 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
981 || (GET_CODE (operands[1]) != MEM))
982 && !flag_pic"
983 "*
984{
985 rtx link;
a269a03c
JC
986 if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
987 && operands[1] == const0_rtx && REG_P (operands[0]))
685885b7
RH
988 return AS2 (xor%L0,%0,%0);
989
990 if (operands[1] == const1_rtx
a269a03c
JC
991 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
992 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
685885b7
RH
993 && (link = find_reg_note (insn, REG_WAS_0, 0))
994 /* Make sure the insn that stored the 0 is still present. */
995 && ! INSN_DELETED_P (XEXP (link, 0))
996 && GET_CODE (XEXP (link, 0)) != NOTE
997 /* Make sure cross jumping didn't happen here. */
998 && no_labels_between_p (XEXP (link, 0), insn)
999 /* Make sure the reg hasn't been clobbered. */
1000 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1001 /* Fastest way to change a 0 to a 1. */
1002 return AS1 (inc%L0,%0);
1003
1004 return AS2 (mov%L0,%1,%0);
a269a03c
JC
1005}"
1006 [(set_attr "type" "integer,memory")
1007 (set_attr "memory" "*,load")])
685885b7 1008
2f2a49e8
MM
1009(define_insn ""
1010 [(set (match_operand:HI 0 "push_operand" "=<")
1011 (match_operand:HI 1 "nonmemory_operand" "ri"))]
ca097615 1012 ""
a269a03c
JC
1013 "* return AS1 (push%W0,%1);"
1014 [(set_attr "type" "memory")
1015 (set_attr "memory" "store")])
2f2a49e8
MM
1016
1017(define_insn ""
1018 [(set (match_operand:HI 0 "push_operand" "=<")
ca097615
JW
1019 (match_operand:HI 1 "memory_operand" "m"))]
1020 "TARGET_PUSH_MEMORY"
a269a03c
JC
1021 "* return AS1 (push%W0,%1);"
1022 [(set_attr "type" "memory")
1023 (set_attr "memory" "load")])
886c62d1
JVA
1024
1025;; On i486, an incl and movl are both faster than incw and movw.
1026
2f2a49e8
MM
1027(define_expand "movhi"
1028 [(set (match_operand:HI 0 "general_operand" "")
1029 (match_operand:HI 1 "general_operand" ""))]
1030 ""
1031 "
1032{
1033 /* Don't generate memory->memory moves, go through a register */
1034 if (TARGET_MOVE
61a1397b 1035 && no_new_pseudos == 0
2f2a49e8 1036 && GET_CODE (operands[0]) == MEM
91f0226f 1037 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
1038 {
1039 operands[1] = force_reg (HImode, operands[1]);
1040 }
1041}")
1042
1043(define_insn ""
886c62d1
JVA
1044 [(set (match_operand:HI 0 "general_operand" "=g,r")
1045 (match_operand:HI 1 "general_operand" "ri,m"))]
2f2a49e8 1046 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1047 "*
1048{
1049 rtx link;
1050 if (REG_P (operands[0]) && operands[1] == const0_rtx)
1051 return AS2 (xor%L0,%k0,%k0);
1052
1053 if (REG_P (operands[0]) && operands[1] == const1_rtx
a269a03c
JC
1054 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1055 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
886c62d1
JVA
1056 && (link = find_reg_note (insn, REG_WAS_0, 0))
1057 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 1058 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
1059 && GET_CODE (XEXP (link, 0)) != NOTE
1060 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
1061 && no_labels_between_p (XEXP (link, 0), insn)
1062 /* Make sure the reg hasn't been clobbered. */
1063 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
886c62d1
JVA
1064 /* Fastest way to change a 0 to a 1. */
1065 return AS1 (inc%L0,%k0);
1066
1067 if (REG_P (operands[0]))
1068 {
5bc7cd8e
SC
1069 if (i386_aligned_p (operands[1]))
1070 {
1071 operands[1] = i386_sext16_if_const (operands[1]);
1072 return AS2 (mov%L0,%k1,%k0);
1073 }
a269a03c 1074 if (! TARGET_ZERO_EXTEND_WITH_AND)
5bc7cd8e
SC
1075 {
1076 /* movzwl is faster than movw on the Pentium Pro,
1077 * although not as fast as an aligned movl. */
1078#ifdef INTEL_SYNTAX
1079 return AS2 (movzx,%1,%k0);
1080#else
1081 return AS2 (movz%W0%L0,%1,%k0);
1082#endif
1083 }
886c62d1
JVA
1084 }
1085
1086 return AS2 (mov%W0,%1,%0);
a269a03c
JC
1087}"
1088 [(set_attr "type" "integer,memory")
1089 (set_attr "memory" "*,load")])
886c62d1 1090
2f2a49e8
MM
1091(define_expand "movstricthi"
1092 [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
1093 (match_operand:HI 1 "general_operand" ""))]
1094 ""
1095 "
1096{
1097 /* Don't generate memory->memory moves, go through a register */
1098 if (TARGET_MOVE
61a1397b 1099 && no_new_pseudos == 0
2f2a49e8 1100 && GET_CODE (operands[0]) == MEM
91f0226f 1101 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
1102 {
1103 operands[1] = force_reg (HImode, operands[1]);
1104 }
1105}")
1106
1107(define_insn ""
886c62d1
JVA
1108 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
1109 (match_operand:HI 1 "general_operand" "ri,m"))]
2f2a49e8 1110 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1111 "*
1112{
1113 rtx link;
a269a03c
JC
1114 if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
1115 && operands[1] == const0_rtx && REG_P (operands[0]))
886c62d1
JVA
1116 return AS2 (xor%W0,%0,%0);
1117
1118 if (operands[1] == const1_rtx
a269a03c
JC
1119 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1120 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
886c62d1
JVA
1121 && (link = find_reg_note (insn, REG_WAS_0, 0))
1122 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 1123 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
1124 && GET_CODE (XEXP (link, 0)) != NOTE
1125 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
1126 && no_labels_between_p (XEXP (link, 0), insn)
1127 /* Make sure the reg hasn't been clobbered. */
1128 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
886c62d1
JVA
1129 /* Fastest way to change a 0 to a 1. */
1130 return AS1 (inc%W0,%0);
1131
1132 return AS2 (mov%W0,%1,%0);
a269a03c
JC
1133}"
1134 [(set_attr "type" "integer,memory")])
886c62d1
JVA
1135
1136;; emit_push_insn when it calls move_by_pieces
1137;; requires an insn to "push a byte".
1138;; But actually we use pushw, which has the effect of rounding
1139;; the amount pushed up to a halfword.
1140(define_insn ""
1141 [(set (match_operand:QI 0 "push_operand" "=<")
2ae0f82c 1142 (match_operand:QI 1 "const_int_operand" "n"))]
886c62d1 1143 ""
ae0d310d 1144 "* return AS1(push%W0,%1);")
2f2a49e8
MM
1145
1146(define_insn ""
1147 [(set (match_operand:QI 0 "push_operand" "=<")
1148 (match_operand:QI 1 "register_operand" "q"))]
ca097615 1149 ""
886c62d1
JVA
1150 "*
1151{
f64cecad 1152 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]));
886c62d1
JVA
1153 return AS1 (push%W0,%1);
1154}")
1155
1156;; On i486, incb reg is faster than movb $1,reg.
1157
1158;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1159;; or writes %ah, %bh, %ch, %dh.
1160
2f2a49e8
MM
1161(define_expand "movqi"
1162 [(set (match_operand:QI 0 "general_operand" "")
1163 (match_operand:QI 1 "general_operand" ""))]
1164 ""
1165 "
1166{
1167 /* Don't generate memory->memory moves, go through a register */
1168 if (TARGET_MOVE
61a1397b 1169 && no_new_pseudos == 0
2f2a49e8 1170 && GET_CODE (operands[0]) == MEM
91f0226f 1171 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
1172 {
1173 operands[1] = force_reg (QImode, operands[1]);
1174 }
1175}")
1176
1177(define_insn ""
2ae0f82c 1178 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm")
52c18286 1179 (match_operand:QI 1 "general_operand" "*g,*rn,qn"))]
2f2a49e8 1180 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1181 "*
1182{
1183 rtx link;
a269a03c
JC
1184
1185 /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.
1186 It is at least as fast as xor on any processor except a Pentium. */
886c62d1
JVA
1187
1188 if (operands[1] == const1_rtx
bb62e19a 1189 && TARGET_PENTIUM
886c62d1
JVA
1190 && (link = find_reg_note (insn, REG_WAS_0, 0))
1191 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 1192 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
1193 && GET_CODE (XEXP (link, 0)) != NOTE
1194 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
1195 && no_labels_between_p (XEXP (link, 0), insn)
1196 /* Make sure the reg hasn't been clobbered. */
1197 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
b76c90cf
L
1198 {
1199 /* Fastest way to change a 0 to a 1.
1200 If inc%B0 isn't allowed, use inc%L0. */
1201 if (NON_QI_REG_P (operands[0]))
fe9f823f 1202 return AS1 (inc%L0,%k0);
b76c90cf
L
1203 else
1204 return AS1 (inc%B0,%0);
1205 }
886c62d1
JVA
1206
1207 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1208 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1209 return (AS2 (mov%L0,%k1,%k0));
1210
1211 return (AS2 (mov%B0,%1,%0));
1212}")
1213
1214;; If it becomes necessary to support movstrictqi into %esi or %edi,
1215;; use the insn sequence:
1216;;
1217;; shrdl $8,srcreg,dstreg
1218;; rorl $24,dstreg
1219;;
1220;; If operands[1] is a constant, then an andl/orl sequence would be
1221;; faster.
1222
2f2a49e8
MM
1223(define_expand "movstrictqi"
1224 [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1225 (match_operand:QI 1 "general_operand" ""))]
1226 ""
1227 "
1228{
1229 /* Don't generate memory->memory moves, go through a register */
1230 if (TARGET_MOVE
61a1397b 1231 && no_new_pseudos == 0
2f2a49e8 1232 && GET_CODE (operands[0]) == MEM
91f0226f 1233 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
1234 {
1235 operands[1] = force_reg (QImode, operands[1]);
1236 }
1237}")
1238
1239(define_insn ""
2ae0f82c 1240 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
c0f06344 1241 (match_operand:QI 1 "general_operand" "*qn,m"))]
2f2a49e8 1242 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1243 "*
1244{
1245 rtx link;
a269a03c
JC
1246
1247 /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */
886c62d1
JVA
1248
1249 if (operands[1] == const1_rtx
bb62e19a 1250 && TARGET_PENTIUM
b76c90cf 1251 && ! NON_QI_REG_P (operands[0])
886c62d1
JVA
1252 && (link = find_reg_note (insn, REG_WAS_0, 0))
1253 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 1254 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
1255 && GET_CODE (XEXP (link, 0)) != NOTE
1256 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
1257 && no_labels_between_p (XEXP (link, 0), insn)
1258 /* Make sure the reg hasn't been clobbered. */
1259 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
886c62d1
JVA
1260 /* Fastest way to change a 0 to a 1. */
1261 return AS1 (inc%B0,%0);
1262
c0f06344 1263 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
886c62d1
JVA
1264 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1265 {
1266 abort ();
1267 return (AS2 (mov%L0,%k1,%k0));
1268 }
1269
1270 return AS2 (mov%B0,%1,%0);
1271}")
1272
f31fce3f
JW
1273(define_insn "movsf_push"
1274 [(set (match_operand:SF 0 "push_operand" "=<,<")
dc0f0eb8
JW
1275 (match_operand:SF 1 "general_operand" "*rfF,m"))]
1276 "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
f31fce3f
JW
1277 "*
1278{
1279 if (STACK_REG_P (operands[1]))
1280 {
1281 rtx xops[3];
1282
1283 if (! STACK_TOP_P (operands[1]))
1284 abort ();
1285
1286 xops[0] = AT_SP (SFmode);
1287 xops[1] = GEN_INT (4);
1288 xops[2] = stack_pointer_rtx;
1289
1290 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1291
1292 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1293 output_asm_insn (AS1 (fstp%S0,%0), xops);
1294 else
1295 output_asm_insn (AS1 (fst%S0,%0), xops);
1296
1297 RET;
1298 }
dc0f0eb8 1299
f31fce3f
JW
1300 return AS1 (push%L0,%1);
1301}")
1302
1303(define_insn "movsf_push_memory"
1304 [(set (match_operand:SF 0 "push_operand" "=<")
1305 (match_operand:SF 1 "memory_operand" "m"))]
1306 "TARGET_PUSH_MEMORY"
1307 "* return AS1 (push%L0,%1);")
1308
0be5d99f
MM
1309(define_expand "movsf"
1310 [(set (match_operand:SF 0 "general_operand" "")
1311 (match_operand:SF 1 "general_operand" ""))]
1312 ""
1313 "
1314{
f31fce3f 1315 /* Don't generate memory->memory moves, go through a register */
0be5d99f 1316 if (TARGET_MOVE
61a1397b 1317 && no_new_pseudos == 0
0be5d99f 1318 && GET_CODE (operands[0]) == MEM
f31fce3f 1319 && GET_CODE (operands[1]) == MEM)
0be5d99f 1320 {
f31fce3f 1321 operands[1] = force_reg (SFmode, operands[1]);
0be5d99f 1322 }
0bb6c81b 1323
2ae0f82c 1324 /* If we are loading a floating point constant that isn't 0 or 1
55953cea
RH
1325 into a register, force the value to memory now, since we'll
1326 get better code out the back end. */
f31fce3f 1327 else if ((reload_in_progress | reload_completed) == 0
55953cea
RH
1328 && GET_CODE (operands[0]) != MEM
1329 && GET_CODE (operands[1]) == CONST_DOUBLE
1330 && !standard_80387_constant_p (operands[1]))
0bb6c81b 1331 {
55953cea 1332 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
0bb6c81b 1333 }
0be5d99f
MM
1334}")
1335
0be5d99f 1336;; For the purposes of regclass, prefer FLOAT_REGS.
f31fce3f 1337(define_insn ""
9f567f56
JW
1338 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m")
1339 (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))]
f58acb67 1340 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1341 "*
1342{
1343 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1344
1345 /* First handle a `pop' insn or a `fld %st(0)' */
1346
1347 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1348 {
1349 if (stack_top_dies)
1350 return AS1 (fstp,%y0);
1351 else
1352 return AS1 (fld,%y0);
1353 }
1354
886c62d1
JVA
1355 /* Handle other kinds of writes from the 387 */
1356
1357 if (STACK_TOP_P (operands[1]))
1358 {
1359 if (stack_top_dies)
1360 return AS1 (fstp%z0,%y0);
1361 else
1362 return AS1 (fst%z0,%y0);
1363 }
1364
1365 /* Handle other kinds of reads to the 387 */
1366
1367 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
2f2a49e8 1368 return output_move_const_single (operands);
886c62d1
JVA
1369
1370 if (STACK_TOP_P (operands[0]))
1371 return AS1 (fld%z1,%y1);
1372
1373 /* Handle all SFmode moves not involving the 387 */
1374
2f2a49e8 1375 return singlemove_string (operands);
2ae0f82c
SC
1376}"
1377 [(set_attr "type" "fld")])
1378
886c62d1 1379
0be5d99f
MM
1380(define_insn "swapsf"
1381 [(set (match_operand:SF 0 "register_operand" "f")
1382 (match_operand:SF 1 "register_operand" "f"))
1383 (set (match_dup 1)
1384 (match_dup 0))]
1385 ""
1386 "*
1387{
1388 if (STACK_TOP_P (operands[0]))
1389 return AS1 (fxch,%1);
1390 else
1391 return AS1 (fxch,%0);
1392}")
1393
55953cea 1394
f31fce3f
JW
1395(define_insn "movdf_push"
1396 [(set (match_operand:DF 0 "push_operand" "=<,<")
dc0f0eb8
JW
1397 (match_operand:DF 1 "general_operand" "*rfF,o"))]
1398 "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
f31fce3f
JW
1399 "*
1400{
1401 if (STACK_REG_P (operands[1]))
1402 {
1403 rtx xops[3];
1404
1405 xops[0] = AT_SP (DFmode);
1406 xops[1] = GEN_INT (8);
1407 xops[2] = stack_pointer_rtx;
1408
1409 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1410
1411 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1412 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1413 else
1414 output_asm_insn (AS1 (fst%Q0,%0), xops);
1415
1416 RET;
1417 }
dc0f0eb8
JW
1418
1419 if (which_alternative == 1)
1420 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 0, 0);
1421
f31fce3f
JW
1422 return output_move_double (operands);
1423}")
1424
1425(define_insn "movdf_push_memory"
1426 [(set (match_operand:DF 0 "push_operand" "=<")
1427 (match_operand:DF 1 "memory_operand" "o"))]
1428 "TARGET_PUSH_MEMORY"
1429 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),0,0);")
1430
0be5d99f
MM
1431(define_expand "movdf"
1432 [(set (match_operand:DF 0 "general_operand" "")
1433 (match_operand:DF 1 "general_operand" ""))]
1434 ""
1435 "
1436{
f31fce3f 1437 /* Don't generate memory->memory moves, go through a register */
0be5d99f 1438 if (TARGET_MOVE
61a1397b 1439 && no_new_pseudos == 0
0be5d99f 1440 && GET_CODE (operands[0]) == MEM
f31fce3f 1441 && GET_CODE (operands[1]) == MEM)
0be5d99f 1442 {
f31fce3f 1443 operands[1] = force_reg (DFmode, operands[1]);
0be5d99f 1444 }
0bb6c81b 1445
83199882
RK
1446 /* If we are loading a floating point constant that isn't 0 or 1 into a
1447 register, indicate we need the pic register loaded. This could be
1448 optimized into stores of constants if the target eventually moves to
1449 memory, but better safe than sorry. */
f31fce3f 1450 else if ((reload_in_progress | reload_completed) == 0
55953cea
RH
1451 && GET_CODE (operands[0]) != MEM
1452 && GET_CODE (operands[1]) == CONST_DOUBLE
1453 && !standard_80387_constant_p (operands[1]))
0bb6c81b 1454 {
55953cea 1455 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
0bb6c81b 1456 }
0be5d99f
MM
1457}")
1458
0be5d99f 1459;; For the purposes of regclass, prefer FLOAT_REGS.
83199882 1460(define_insn ""
9f567f56
JW
1461 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1462 (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))]
f58acb67
SC
1463 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1464 || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1465 "*
1466{
1467 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1468
1469 /* First handle a `pop' insn or a `fld %st(0)' */
1470
1471 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1472 {
1473 if (stack_top_dies)
1474 return AS1 (fstp,%y0);
1475 else
1476 return AS1 (fld,%y0);
1477 }
1478
886c62d1
JVA
1479 /* Handle other kinds of writes from the 387 */
1480
1481 if (STACK_TOP_P (operands[1]))
1482 {
1483 if (stack_top_dies)
1484 return AS1 (fstp%z0,%y0);
1485 else
1486 return AS1 (fst%z0,%y0);
1487 }
1488
1489 /* Handle other kinds of reads to the 387 */
1490
1491 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
2f2a49e8 1492 return output_move_const_single (operands);
886c62d1
JVA
1493
1494 if (STACK_TOP_P (operands[0]))
1495 return AS1 (fld%z1,%y1);
1496
1497 /* Handle all DFmode moves not involving the 387 */
1498
2f2a49e8 1499 return output_move_double (operands);
2ae0f82c 1500}"
36cf4bcf 1501 [(set_attr "type" "fld")])
2ae0f82c
SC
1502
1503
886c62d1 1504
0be5d99f
MM
1505(define_insn "swapdf"
1506 [(set (match_operand:DF 0 "register_operand" "f")
1507 (match_operand:DF 1 "register_operand" "f"))
1508 (set (match_dup 1)
1509 (match_dup 0))]
1510 ""
1511 "*
1512{
1513 if (STACK_TOP_P (operands[0]))
1514 return AS1 (fxch,%1);
1515 else
1516 return AS1 (fxch,%0);
1517}")
1518
f31fce3f
JW
1519(define_insn "movxf_push"
1520 [(set (match_operand:XF 0 "push_operand" "=<,<")
dc0f0eb8
JW
1521 (match_operand:XF 1 "general_operand" "*rfF,o"))]
1522 "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
f31fce3f
JW
1523 "*
1524{
1525 if (STACK_REG_P (operands[1]))
1526 {
1527 rtx xops[3];
1528
1529 xops[0] = AT_SP (XFmode);
1530 xops[1] = GEN_INT (12);
1531 xops[2] = stack_pointer_rtx;
1532
1533 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1534
1535 output_asm_insn (AS1 (fstp%T0,%0), xops);
1536 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1537 output_asm_insn (AS1 (fld%T0,%0), xops);
1538
1539 RET;
1540 }
dc0f0eb8
JW
1541
1542 if (which_alternative == 1)
1543 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 0, 0);
1544
f31fce3f
JW
1545 return output_move_double (operands);
1546 }")
1547
1548(define_insn "movxf_push_memory"
1549 [(set (match_operand:XF 0 "push_operand" "=<")
1550 (match_operand:XF 1 "memory_operand" "o"))]
1551 "TARGET_PUSH_MEMORY"
1552 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),0,0);")
1553
0be5d99f
MM
1554(define_expand "movxf"
1555 [(set (match_operand:XF 0 "general_operand" "")
1556 (match_operand:XF 1 "general_operand" ""))]
1557 ""
1558 "
1559{
f31fce3f 1560 /* Don't generate memory->memory moves, go through a register */
0be5d99f 1561 if (TARGET_MOVE
61a1397b 1562 && no_new_pseudos == 0
0be5d99f 1563 && GET_CODE (operands[0]) == MEM
f31fce3f 1564 && GET_CODE (operands[1]) == MEM)
0be5d99f 1565 {
f31fce3f 1566 operands[1] = force_reg (XFmode, operands[1]);
0be5d99f 1567 }
0bb6c81b 1568
2ae0f82c 1569 /* If we are loading a floating point constant that isn't 0 or 1
83199882
RK
1570 into a register, indicate we need the pic register loaded. This could
1571 be optimized into stores of constants if the target eventually moves
1572 to memory, but better safe than sorry. */
f31fce3f 1573 else if ((reload_in_progress | reload_completed) == 0
55953cea
RH
1574 && GET_CODE (operands[0]) != MEM
1575 && GET_CODE (operands[1]) == CONST_DOUBLE
1576 && !standard_80387_constant_p (operands[1]))
0bb6c81b 1577 {
55953cea 1578 operands[1] = validize_mem (force_const_mem (XFmode, operands[1]));
0bb6c81b 1579 }
0be5d99f
MM
1580}")
1581
c1450f19 1582
83199882 1583(define_insn ""
9f567f56
JW
1584 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1585 (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))]
f58acb67
SC
1586 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1587 || (GET_CODE (operands[1]) != MEM)"
4fb21e90
JVA
1588 "*
1589{
1590 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1591
1592 /* First handle a `pop' insn or a `fld %st(0)' */
1593
1594 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1595 {
1596 if (stack_top_dies)
1597 return AS1 (fstp,%y0);
1598 else
1599 return AS1 (fld,%y0);
1600 }
1601
4fb21e90
JVA
1602 /* Handle other kinds of writes from the 387 */
1603
1604 if (STACK_TOP_P (operands[1]))
1605 {
2f17722a
JVA
1606 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1607 if (! stack_top_dies)
1608 return AS1 (fld%z0,%y0);
1609
1610 RET;
4fb21e90
JVA
1611 }
1612
1613 /* Handle other kinds of reads to the 387 */
1614
1615 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
2f2a49e8 1616 return output_move_const_single (operands);
4fb21e90
JVA
1617
1618 if (STACK_TOP_P (operands[0]))
1619 return AS1 (fld%z1,%y1);
1620
1621 /* Handle all XFmode moves not involving the 387 */
1622
2f2a49e8 1623 return output_move_double (operands);
4fb21e90
JVA
1624}")
1625
2ae0f82c 1626(define_insn "swapxf"
0be5d99f
MM
1627 [(set (match_operand:XF 0 "register_operand" "f")
1628 (match_operand:XF 1 "register_operand" "f"))
1629 (set (match_dup 1)
1630 (match_dup 0))]
1631 ""
1632 "*
1633{
1634 if (STACK_TOP_P (operands[0]))
1635 return AS1 (fxch,%1);
1636 else
1637 return AS1 (fxch,%0);
1638}")
1639
b840bfb0 1640(define_insn ""
d2f2cb19
JW
1641 [(set (match_operand:DI 0 "push_operand" "=<")
1642 (match_operand:DI 1 "general_operand" "riF"))]
c1450f19 1643 ""
d2f2cb19 1644 "* return output_move_double (operands);")
2f2a49e8 1645
d2f2cb19
JW
1646(define_insn ""
1647 [(set (match_operand:DI 0 "push_operand" "=<")
1648 (match_operand:DI 1 "memory_operand" "o"))]
1649 "TARGET_PUSH_MEMORY"
1650 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),0,0);")
886c62d1 1651
d2f2cb19
JW
1652(define_expand "movdi"
1653 [(set (match_operand:DI 0 "general_operand" "")
1654 (match_operand:DI 1 "general_operand" ""))]
2f2a49e8 1655 ""
d2f2cb19 1656 "
2f2a49e8 1657{
d2f2cb19
JW
1658 /* Don't generate memory->memory moves, go through a register */
1659 if (TARGET_MOVE
61a1397b 1660 && no_new_pseudos == 0
d2f2cb19
JW
1661 && GET_CODE (operands[0]) == MEM
1662 && GET_CODE (operands[1]) == MEM)
1663 {
1664 operands[1] = force_reg (DImode, operands[1]);
1665 }
886c62d1 1666}")
0be5d99f 1667
d2f2cb19
JW
1668(define_insn ""
1669 [(set (match_operand:DI 0 "general_operand" "=g,r")
1670 (match_operand:DI 1 "general_operand" "riF,m"))]
1671 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1672 || (GET_CODE (operands[1]) != MEM)"
a269a03c
JC
1673 "* return output_move_double (operands);"
1674 [(set_attr "type" "integer,memory")
1675 (set_attr "memory" "*,load")])
d2f2cb19 1676
886c62d1
JVA
1677\f
1678;;- conversion instructions
1679;;- NONE
1680
886c62d1
JVA
1681;;- zero extension instructions
1682;; See comments by `andsi' for when andl is faster than movzx.
1683
d626200a
JL
1684(define_expand "zero_extendhisi2"
1685 [(set (match_operand:SI 0 "register_operand" "")
1686 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1687 ""
1688 "")
1689
1690;; When optimizing for the PPro/PII or code size, always use movzwl.
1691;; We want to use a different pattern so we can use different constraints
1692;; than the generic pattern.
1693(define_insn ""
1694 [(set (match_operand:SI 0 "register_operand" "=r")
1695 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1696 "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1697 "* return AS2 (movz%W0%L0,%1,%0);")
1698
1699(define_insn ""
2ae0f82c
SC
1700 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1701 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
d626200a 1702 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
886c62d1 1703 "*
2ae0f82c
SC
1704 {
1705 rtx xops[2];
1706
1707 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
886c62d1
JVA
1708 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1709 {
886c62d1 1710 xops[0] = operands[0];
a199fdd6 1711 xops[1] = GEN_INT (0xffff);
886c62d1
JVA
1712 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1713 RET;
1714 }
2ae0f82c
SC
1715 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1716 {
1717 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1718 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1719 RET;
1720 }
1721
1722 if (TARGET_ZERO_EXTEND_WITH_AND)
1723 {
1724 xops[0] = operands[0];
f64cecad 1725 xops[1] = GEN_INT (0xffff);
5bc7cd8e
SC
1726 if (i386_aligned_p (operands[1]))
1727 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1728 else
1729 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
2ae0f82c
SC
1730 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1731 RET;
1732 }
886c62d1
JVA
1733
1734#ifdef INTEL_SYNTAX
1735 return AS2 (movzx,%1,%0);
1736#else
1737 return AS2 (movz%W0%L0,%1,%0);
1738#endif
1739}")
1740
2ae0f82c
SC
1741(define_split
1742 [(set (match_operand:SI 0 "register_operand" "")
1743 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1744 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1745 [(set (match_dup 0)
1746 (const_int 0))
1747 (set (strict_low_part (match_dup 2))
1748 (match_dup 1))]
f64cecad 1749 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
2ae0f82c
SC
1750
1751
1752(define_split
1753 [(set (match_operand:SI 0 "register_operand" "")
1754 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1755 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1756 [(set (strict_low_part (match_dup 2))
1757 (match_dup 1))
1758 (set (match_dup 0)
1759 (and:SI (match_dup 0)
1760 (const_int 65535)))]
f64cecad 1761 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
2ae0f82c 1762
d626200a
JL
1763(define_expand "zero_extendqihi2"
1764 [(set (match_operand:HI 0 "register_operand" "")
1765 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1766 ""
1767 "")
1768
1769(define_insn ""
1770 [(set (match_operand:HI 0 "register_operand" "=r")
1771 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1772 "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1773
1774 "* return AS2 (movz%B0%W0,%1,%0);")
1775
1776(define_insn ""
2ae0f82c
SC
1777 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1778 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
d626200a 1779 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
886c62d1 1780 "*
2ae0f82c
SC
1781 {
1782 rtx xops[2];
1783
268bfa44 1784 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
2ae0f82c
SC
1785 && REG_P (operands[1])
1786 && REGNO (operands[0]) == REGNO (operands[1]))
886c62d1 1787 {
886c62d1 1788 xops[0] = operands[0];
a199fdd6 1789 xops[1] = GEN_INT (0xff);
886c62d1
JVA
1790 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1791 RET;
1792 }
2ae0f82c
SC
1793 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1794 {
1795 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1796 {
1797 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1798 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1799 }
1800 else
1801 {
1802 xops[0] = operands[0];
f64cecad 1803 xops[1] = GEN_INT (0xff);
2ae0f82c
SC
1804 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1805 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1806 }
1807 RET;
1808 }
1809
886c62d1
JVA
1810#ifdef INTEL_SYNTAX
1811 return AS2 (movzx,%1,%0);
1812#else
1813 return AS2 (movz%B0%W0,%1,%0);
1814#endif
1815}")
1816
2ae0f82c
SC
1817(define_split
1818 [(set (match_operand:HI 0 "register_operand" "")
1819 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1820 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1821 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1822 [(set (match_dup 0)
1823 (const_int 0))
1824 (set (strict_low_part (match_dup 2))
1825 (match_dup 1))]
f64cecad 1826 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2ae0f82c
SC
1827
1828
1829(define_split
1830 [(set (match_operand:HI 0 "register_operand" "")
1831 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1832 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1833 && reg_overlap_mentioned_p (operands[0], operands[1])"
1834 [(set (strict_low_part (match_dup 2))
1835 (match_dup 1))
1836 (set (match_dup 0)
1837 (and:HI (match_dup 0)
1838 (const_int 255)))]
f64cecad 1839 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2ae0f82c
SC
1840
1841(define_split
1842 [(set (match_operand:HI 0 "register_operand" "")
1843 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2d204901 1844 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
2ae0f82c
SC
1845 [(set (match_dup 0)
1846 (match_dup 2))
1847 (set (match_dup 0)
1848 (and:HI (match_dup 0)
1849 (const_int 255)))]
2d204901
RK
1850 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1851 operands[1] = SUBREG_REG (operands[1]);
1852 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1853 || REGNO (operands[0]) == REGNO (operands[1]))
1854 FAIL;
f64cecad 1855 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
2ae0f82c 1856
d626200a
JL
1857(define_expand "zero_extendqisi2"
1858 [(set (match_operand:SI 0 "register_operand" "")
1859 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1860 ""
1861 "")
1862
1863(define_insn ""
1864 [(set (match_operand:SI 0 "register_operand" "=r")
1865 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1866 "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1867 "* return AS2 (movz%B0%L0,%1,%0);")
1868
1869(define_insn ""
2ae0f82c
SC
1870 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1871 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
d626200a 1872 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
886c62d1 1873 "*
2ae0f82c
SC
1874 {
1875 rtx xops[2];
1876
268bfa44 1877 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
2ae0f82c
SC
1878 && REG_P (operands[1])
1879 && REGNO (operands[0]) == REGNO (operands[1]))
886c62d1 1880 {
886c62d1 1881 xops[0] = operands[0];
a199fdd6 1882 xops[1] = GEN_INT (0xff);
886c62d1
JVA
1883 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1884 RET;
1885 }
2ae0f82c
SC
1886 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1887 {
1888 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1889 {
1890 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1891 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1892 }
1893 else
1894 {
1895 xops[0] = operands[0];
f64cecad 1896 xops[1] = GEN_INT (0xff);
2ae0f82c
SC
1897 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1898 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1899 }
1900 RET;
1901 }
1902
1903 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1904 {
1905 xops[0] = operands[0];
f64cecad
JC
1906 xops[1] = GEN_INT (0xff);
1907 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
2ae0f82c
SC
1908 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1909 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1910 RET;
1911 }
886c62d1
JVA
1912
1913#ifdef INTEL_SYNTAX
1914 return AS2 (movzx,%1,%0);
1915#else
1916 return AS2 (movz%B0%L0,%1,%0);
1917#endif
1918}")
9c530261 1919
2ae0f82c
SC
1920(define_split
1921 [(set (match_operand:SI 0 "register_operand" "")
1922 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1923 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1924 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1925 [(set (match_dup 0)
1926 (const_int 0))
1927 (set (strict_low_part (match_dup 2))
1928 (match_dup 1))]
f64cecad 1929 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2ae0f82c
SC
1930
1931
1932(define_split
1933 [(set (match_operand:SI 0 "register_operand" "")
1934 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
1935 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1936 && reg_overlap_mentioned_p (operands[0], operands[1])"
1937 [(set (strict_low_part (match_dup 2))
1938 (match_dup 1))
1939 (set (match_dup 0)
1940 (and:SI (match_dup 0)
1941 (const_int 255)))]
f64cecad 1942 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2ae0f82c
SC
1943
1944(define_split
1945 [(set (match_operand:SI 0 "register_operand" "")
1946 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3bc97c56
SC
1947 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
1948 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2ae0f82c
SC
1949 [(set (match_dup 0)
1950 (match_dup 2))
1951 (set (match_dup 0)
1952 (and:SI (match_dup 0)
1953 (const_int 255)))]
f64cecad 1954 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
2ae0f82c 1955
9c530261 1956(define_insn "zero_extendsidi2"
bb62e19a
JH
1957 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
1958 (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
9c530261 1959 ""
bb62e19a 1960 "#")
2ae0f82c 1961
bb62e19a
JH
1962(define_split
1963 [(set (match_operand:DI 0 "register_operand" "")
1964 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
1965 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
1966 [(set (match_dup 4) (const_int 0))]
1967 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
1968
1969(define_split
1970 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
1972 "reload_completed"
1973 [(set (match_dup 3) (match_dup 1))
1974 (set (match_dup 4) (const_int 0))]
1975 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
886c62d1
JVA
1976\f
1977;;- sign extension instructions
1978
886c62d1 1979(define_insn "extendsidi2"
724d568a
JH
1980 [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o")
1981 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r")))
1982 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
886c62d1 1983 ""
724d568a
JH
1984 "#")
1985
1986;; Extend to memory case when source register does die.
1987(define_split
1988 [(set (match_operand:DI 0 "memory_operand" "")
1989 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
1990 (clobber (match_operand:SI 2 "register_operand" ""))]
1991 "(flow2_completed
1992 && dead_or_set_p (insn, operands[1])
1993 && !reg_mentioned_p (operands[1], operands[0]))"
1994 [(set (match_dup 3) (match_dup 1))
1995 (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
1996 (set (match_dup 4) (match_dup 1))]
1997 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
1998
1999;; Extend to memory case when source register does not die.
2000(define_split
2001 [(set (match_operand:DI 0 "memory_operand" "")
2002 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2003 (clobber (match_operand:SI 2 "register_operand" ""))]
2004 "flow2_completed"
2005 [(const_int 0)]
2006 "
9c530261 2007{
724d568a
JH
2008 split_di (&operands[0], 1, &operands[3], &operands[4]);
2009
2010 emit_move_insn (operands[3], operands[1]);
2011
2012 /* Generate a cltd if possible and doing so it profitable. */
2013 if (true_regnum (operands[1]) == 0
2014 && true_regnum (operands[2]) == 1
2015 && (optimize_size || !TARGET_PENTIUM))
71a247f0 2016 {
724d568a
JH
2017 emit_insn (gen_ashrsi3_31 (operands[2], operands[1]));
2018 }
2019 else
2020 {
2021 emit_move_insn (operands[2], operands[1]);
2022 emit_insn (gen_ashrsi3_31 (operands[2], operands[2]));
71a247f0 2023 }
724d568a
JH
2024 emit_move_insn (operands[4], operands[2]);
2025 DONE;
2026}")
9c530261 2027
724d568a
JH
2028;; Extend to register case. Optimize case where source and destination
2029;; registers match and cases where we can use cltd.
2030(define_split
2031 [(set (match_operand:DI 0 "register_operand" "")
2032 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2033 (clobber (match_scratch:SI 2 ""))]
2034 "reload_completed"
2035 [(const_int 0)]
2036 "
2037{
2038 split_di (&operands[0], 1, &operands[3], &operands[4]);
2039
2040 if (true_regnum (operands[3]) != true_regnum (operands[1]))
2041 emit_move_insn (operands[3], operands[1]);
9c530261 2042
724d568a
JH
2043 /* Generate a cltd if possible and doing so it profitable. */
2044 if (true_regnum (operands[3]) == 0
2045 && (optimize_size || !TARGET_PENTIUM))
2046 {
2047 emit_insn (gen_ashrsi3_31 (operands[4], operands[3]));
2048 DONE;
2049 }
2050
2051 if (true_regnum (operands[4]) != true_regnum (operands[1]))
2052 emit_move_insn (operands[4], operands[1]);
2053
2054 emit_insn (gen_ashrsi3_31 (operands[4], operands[4]));
2055 DONE;
9c530261 2056}")
886c62d1
JVA
2057
2058;; Note that the i386 programmers' manual says that the opcodes
2059;; are named movsx..., but the assembler on Unix does not accept that.
2060;; We use what the Unix assembler expects.
2061
2062(define_insn "extendhisi2"
2ae0f82c
SC
2063 [(set (match_operand:SI 0 "register_operand" "=r")
2064 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
886c62d1
JVA
2065 ""
2066 "*
2067{
2068 if (REGNO (operands[0]) == 0
2069 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2070#ifdef INTEL_SYNTAX
2071 return \"cwde\";
2072#else
2073 return \"cwtl\";
2074#endif
2075
2076#ifdef INTEL_SYNTAX
2077 return AS2 (movsx,%1,%0);
2078#else
2079 return AS2 (movs%W0%L0,%1,%0);
2080#endif
2081}")
2082
2083(define_insn "extendqihi2"
2ae0f82c
SC
2084 [(set (match_operand:HI 0 "register_operand" "=r")
2085 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1
JVA
2086 ""
2087 "*
2088{
2089 if (REGNO (operands[0]) == 0
2090 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2091 return \"cbtw\";
2092
2093#ifdef INTEL_SYNTAX
2094 return AS2 (movsx,%1,%0);
2095#else
2096 return AS2 (movs%B0%W0,%1,%0);
2097#endif
2098}")
2099
2100(define_insn "extendqisi2"
2ae0f82c
SC
2101 [(set (match_operand:SI 0 "register_operand" "=r")
2102 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1
JVA
2103 ""
2104 "*
2105{
2106#ifdef INTEL_SYNTAX
2107 return AS2 (movsx,%1,%0);
2108#else
2109 return AS2 (movs%B0%L0,%1,%0);
2110#endif
2111}")
2ae0f82c
SC
2112
2113\f
2114;; Truncation of long long -> 32 bit
2115
2116(define_expand "truncdisi2"
2117 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2118 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2119 ""
2120 "
2121{
2122 /* Don't generate memory->memory moves, go through a register */
2123 if (TARGET_MOVE
2124 && (reload_in_progress | reload_completed) == 0
2125 && GET_CODE (operands[0]) == MEM
2126 && GET_CODE (operands[1]) == MEM)
2127 {
2128 rtx target = gen_reg_rtx (SImode);
2129 emit_insn (gen_truncdisi2 (target, operands[1]));
2130 emit_move_insn (operands[0], target);
2131 DONE;
2132 }
2133}")
2134
2135(define_insn ""
2136 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2137 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2138 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2139 "*
2140{
2141 rtx low[2], high[2], xops[2];
2142
2143 split_di (&operands[1], 1, low, high);
2144 xops[0] = operands[0];
2145 xops[1] = low[0];
2146 if (!rtx_equal_p (xops[0], xops[1]))
2147 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2148
2149 RET;
2150}")
2151
2152(define_insn ""
2153 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2154 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2155 (const_int 32))))]
2156 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2157 "*
2158{
2159 rtx low[2], high[2], xops[2];
2160
2161 split_di (&operands[1], 1, low, high);
2162 xops[0] = operands[0];
2163 xops[1] = high[0];
2164 if (!rtx_equal_p (xops[0], xops[1]))
2165 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2166
2167 RET;
2168}")
2169
2170
886c62d1
JVA
2171\f
2172;; Conversions between float and double.
2173
2174(define_insn "extendsfdf2"
2ae0f82c 2175 [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f")
886c62d1 2176 (float_extend:DF
2ae0f82c 2177 (match_operand:SF 1 "nonimmediate_operand" "f,fm")))]
886c62d1
JVA
2178 "TARGET_80387"
2179 "*
2180{
2181 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2182
2183 if (NON_STACK_REG_P (operands[1]))
2184 {
2185 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2186 RET;
2187 }
2188
2189 if (NON_STACK_REG_P (operands[0]))
2190 {
f25aca7a 2191 output_to_reg (operands[0], stack_top_dies, 0);
886c62d1
JVA
2192 RET;
2193 }
2194
2195 if (STACK_TOP_P (operands[0]))
2196 return AS1 (fld%z1,%y1);
2197
2198 if (GET_CODE (operands[0]) == MEM)
2199 {
2200 if (stack_top_dies)
2201 return AS1 (fstp%z0,%y0);
2202 else
2203 return AS1 (fst%z0,%y0);
2204 }
2205
2206 abort ();
2207}")
2208
4fb21e90 2209(define_insn "extenddfxf2"
2ae0f82c 2210 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
4fb21e90 2211 (float_extend:XF
2ae0f82c 2212 (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
4fb21e90
JVA
2213 "TARGET_80387"
2214 "*
2215{
2216 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2217
2218 if (NON_STACK_REG_P (operands[1]))
2219 {
2220 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2221 RET;
2222 }
2223
2224 if (NON_STACK_REG_P (operands[0]))
2225 {
f25aca7a 2226 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
2227 RET;
2228 }
2229
2230 if (STACK_TOP_P (operands[0]))
2231 return AS1 (fld%z1,%y1);
2232
2233 if (GET_CODE (operands[0]) == MEM)
2234 {
2f17722a
JVA
2235 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2236 if (! stack_top_dies)
2237 return AS1 (fld%z0,%y0);
2238 RET;
4fb21e90
JVA
2239 }
2240
2241 abort ();
2242}")
2243
2244(define_insn "extendsfxf2"
2ae0f82c 2245 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
4fb21e90 2246 (float_extend:XF
2ae0f82c 2247 (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
4fb21e90
JVA
2248 "TARGET_80387"
2249 "*
2250{
2251 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2252
2253 if (NON_STACK_REG_P (operands[1]))
2254 {
2255 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2256 RET;
2257 }
2258
2259 if (NON_STACK_REG_P (operands[0]))
2260 {
f25aca7a 2261 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
2262 RET;
2263 }
2264
2265 if (STACK_TOP_P (operands[0]))
2266 return AS1 (fld%z1,%y1);
2267
2268 if (GET_CODE (operands[0]) == MEM)
2269 {
2f17722a
JVA
2270 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2271 if (! stack_top_dies)
2272 return AS1 (fld%z0,%y0);
2273 RET;
4fb21e90
JVA
2274 }
2275
2276 abort ();
2277}")
2278
0fcad513
JVA
2279(define_expand "truncdfsf2"
2280 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2281 (float_truncate:SF
2282 (match_operand:DF 1 "register_operand" "")))
2283 (clobber (match_dup 2))])]
2284 "TARGET_80387"
2285 "
2286{
2287 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2288}")
2289
886c62d1
JVA
2290;; This cannot output into an f-reg because there is no way to be sure
2291;; of truncating in that case. Otherwise this is just like a simple move
0fcad513
JVA
2292;; insn. So we pretend we can output to a reg in order to get better
2293;; register preferencing, but we really use a stack slot.
886c62d1 2294
0fcad513 2295(define_insn ""
fe4435d9 2296 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
886c62d1 2297 (float_truncate:SF
0fcad513
JVA
2298 (match_operand:DF 1 "register_operand" "0,f")))
2299 (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
886c62d1
JVA
2300 "TARGET_80387"
2301 "*
2302{
2303 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2304
fe4435d9 2305 if (GET_CODE (operands[0]) == MEM)
886c62d1
JVA
2306 {
2307 if (stack_top_dies)
2308 return AS1 (fstp%z0,%0);
2309 else
2310 return AS1 (fst%z0,%0);
2311 }
fe4435d9
JVA
2312 else if (STACK_TOP_P (operands[0]))
2313 {
0fcad513
JVA
2314 output_asm_insn (AS1 (fstp%z2,%y2), operands);
2315 return AS1 (fld%z2,%y2);
fe4435d9 2316 }
886c62d1
JVA
2317 else
2318 abort ();
2319}")
4fb21e90
JVA
2320
2321(define_insn "truncxfsf2"
2ae0f82c 2322 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
4fb21e90
JVA
2323 (float_truncate:SF
2324 (match_operand:XF 1 "register_operand" "f,f")))]
2325 "TARGET_80387"
2326 "*
2327{
2328 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2329
2330 if (NON_STACK_REG_P (operands[0]))
2331 {
2332 if (stack_top_dies == 0)
2333 {
2334 output_asm_insn (AS1 (fld,%y1), operands);
2335 stack_top_dies = 1;
2336 }
f25aca7a 2337 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
2338 RET;
2339 }
2340 else if (GET_CODE (operands[0]) == MEM)
2341 {
2342 if (stack_top_dies)
2343 return AS1 (fstp%z0,%0);
2344 else
2345 {
2346 output_asm_insn (AS1 (fld,%y1), operands);
2347 return AS1 (fstp%z0,%0);
2348 }
2349 }
2350 else
2351 abort ();
2352}")
2353
2354(define_insn "truncxfdf2"
2ae0f82c 2355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
4fb21e90
JVA
2356 (float_truncate:DF
2357 (match_operand:XF 1 "register_operand" "f,f")))]
2358 "TARGET_80387"
2359 "*
2360{
2361 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2362
2363 if (NON_STACK_REG_P (operands[0]))
2364 {
2365 if (stack_top_dies == 0)
2366 {
2367 output_asm_insn (AS1 (fld,%y1), operands);
2368 stack_top_dies = 1;
2369 }
f25aca7a 2370 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
2371 RET;
2372 }
2373 else if (GET_CODE (operands[0]) == MEM)
2374 {
2375 if (stack_top_dies)
2376 return AS1 (fstp%z0,%0);
2377 else
2378 {
2379 output_asm_insn (AS1 (fld,%y1), operands);
2380 return AS1 (fstp%z0,%0);
2381 }
2382 }
2383 else
2384 abort ();
2385}")
2386
886c62d1
JVA
2387\f
2388;; The 387 requires that the stack top dies after converting to DImode.
2389
2390;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
2391;; doing a signed conversion to DImode, and then taking just the low
2392;; part.
2393
4fb21e90
JVA
2394(define_expand "fixuns_truncxfsi2"
2395 [(set (match_dup 4)
2396 (match_operand:XF 1 "register_operand" ""))
2397 (parallel [(set (match_dup 2)
2398 (fix:DI (fix:XF (match_dup 4))))
2399 (clobber (match_dup 4))
2400 (clobber (match_dup 5))
2401 (clobber (match_dup 6))
2402 (clobber (match_scratch:SI 7 ""))])
2403 (set (match_operand:SI 0 "general_operand" "")
2404 (match_dup 3))]
2405 "TARGET_80387"
2406 "
2407{
2408 operands[2] = gen_reg_rtx (DImode);
2409 operands[3] = gen_lowpart (SImode, operands[2]);
2410 operands[4] = gen_reg_rtx (XFmode);
2411 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2412 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
4fb21e90
JVA
2413}")
2414
886c62d1 2415(define_expand "fixuns_truncdfsi2"
0fcad513 2416 [(set (match_dup 4)
eb085d72 2417 (match_operand:DF 1 "register_operand" ""))
0fcad513
JVA
2418 (parallel [(set (match_dup 2)
2419 (fix:DI (fix:DF (match_dup 4))))
2420 (clobber (match_dup 4))
2421 (clobber (match_dup 5))
2422 (clobber (match_dup 6))
2423 (clobber (match_scratch:SI 7 ""))])
886c62d1 2424 (set (match_operand:SI 0 "general_operand" "")
0fcad513 2425 (match_dup 3))]
886c62d1
JVA
2426 "TARGET_80387"
2427 "
2428{
0fcad513
JVA
2429 operands[2] = gen_reg_rtx (DImode);
2430 operands[3] = gen_lowpart (SImode, operands[2]);
2431 operands[4] = gen_reg_rtx (DFmode);
2432 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2433 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
886c62d1
JVA
2434}")
2435
2436(define_expand "fixuns_truncsfsi2"
0fcad513 2437 [(set (match_dup 4)
eb085d72 2438 (match_operand:SF 1 "register_operand" ""))
0fcad513
JVA
2439 (parallel [(set (match_dup 2)
2440 (fix:DI (fix:SF (match_dup 4))))
2441 (clobber (match_dup 4))
2442 (clobber (match_dup 5))
2443 (clobber (match_dup 6))
2444 (clobber (match_scratch:SI 7 ""))])
886c62d1 2445 (set (match_operand:SI 0 "general_operand" "")
0fcad513 2446 (match_dup 3))]
886c62d1
JVA
2447 "TARGET_80387"
2448 "
2449{
0fcad513
JVA
2450 operands[2] = gen_reg_rtx (DImode);
2451 operands[3] = gen_lowpart (SImode, operands[2]);
2452 operands[4] = gen_reg_rtx (SFmode);
2453 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2454 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
886c62d1
JVA
2455}")
2456
2457;; Signed conversion to DImode.
2458
4fb21e90 2459(define_expand "fix_truncxfdi2"
eb085d72
MM
2460 [(set (match_dup 2)
2461 (match_operand:XF 1 "register_operand" ""))
2462 (parallel [(set (match_operand:DI 0 "general_operand" "")
2463 (fix:DI (fix:XF (match_dup 2))))
2464 (clobber (match_dup 2))
2465 (clobber (match_dup 3))
2466 (clobber (match_dup 4))
2467 (clobber (match_scratch:SI 5 ""))])]
4fb21e90
JVA
2468 "TARGET_80387"
2469 "
2470{
eb085d72
MM
2471 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2472 operands[2] = gen_reg_rtx (XFmode);
2473 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2474 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
4fb21e90
JVA
2475}")
2476
886c62d1 2477(define_expand "fix_truncdfdi2"
eb085d72
MM
2478 [(set (match_dup 2)
2479 (match_operand:DF 1 "register_operand" ""))
2480 (parallel [(set (match_operand:DI 0 "general_operand" "")
2481 (fix:DI (fix:DF (match_dup 2))))
2482 (clobber (match_dup 2))
2483 (clobber (match_dup 3))
2484 (clobber (match_dup 4))
2485 (clobber (match_scratch:SI 5 ""))])]
886c62d1
JVA
2486 "TARGET_80387"
2487 "
2488{
eb085d72
MM
2489 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2490 operands[2] = gen_reg_rtx (DFmode);
2491 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2492 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
886c62d1
JVA
2493}")
2494
2495(define_expand "fix_truncsfdi2"
eb085d72
MM
2496 [(set (match_dup 2)
2497 (match_operand:SF 1 "register_operand" ""))
2498 (parallel [(set (match_operand:DI 0 "general_operand" "")
2499 (fix:DI (fix:SF (match_dup 2))))
2500 (clobber (match_dup 2))
2501 (clobber (match_dup 3))
2502 (clobber (match_dup 4))
2503 (clobber (match_scratch:SI 5 ""))])]
886c62d1
JVA
2504 "TARGET_80387"
2505 "
2506{
eb085d72
MM
2507 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2508 operands[2] = gen_reg_rtx (SFmode);
2509 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2510 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
886c62d1
JVA
2511}")
2512
b4ac57ab 2513;; These match a signed conversion of either DFmode or SFmode to DImode.
886c62d1 2514
eb085d72 2515(define_insn ""
2ae0f82c 2516 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
7beb6381 2517 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f"))))
4fb21e90
JVA
2518 (clobber (match_dup 1))
2519 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2520 (clobber (match_operand:DI 3 "memory_operand" "m"))
4fb21e90
JVA
2521 (clobber (match_scratch:SI 4 "=&q"))]
2522 "TARGET_80387"
2f2a49e8 2523 "* return output_fix_trunc (insn, operands);")
4fb21e90 2524
eb085d72 2525(define_insn ""
2ae0f82c 2526 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
7beb6381 2527 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f"))))
0fcad513
JVA
2528 (clobber (match_dup 1))
2529 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2530 (clobber (match_operand:DI 3 "memory_operand" "m"))
0fcad513 2531 (clobber (match_scratch:SI 4 "=&q"))]
886c62d1 2532 "TARGET_80387"
2f2a49e8 2533 "* return output_fix_trunc (insn, operands);")
886c62d1 2534
eb085d72 2535(define_insn ""
2ae0f82c 2536 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
7beb6381 2537 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f"))))
0fcad513
JVA
2538 (clobber (match_dup 1))
2539 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2540 (clobber (match_operand:DI 3 "memory_operand" "m"))
0fcad513 2541 (clobber (match_scratch:SI 4 "=&q"))]
886c62d1 2542 "TARGET_80387"
2f2a49e8 2543 "* return output_fix_trunc (insn, operands);")
886c62d1
JVA
2544
2545;; Signed MODE_FLOAT conversion to SImode.
2546
4fb21e90
JVA
2547(define_expand "fix_truncxfsi2"
2548 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2549 (fix:SI
2550 (fix:XF (match_operand:XF 1 "register_operand" ""))))
2551 (clobber (match_dup 2))
2552 (clobber (match_dup 3))
2553 (clobber (match_scratch:SI 4 ""))])]
2554 "TARGET_80387"
2555 "
2556{
2557 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2558 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
4fb21e90
JVA
2559}")
2560
886c62d1
JVA
2561(define_expand "fix_truncdfsi2"
2562 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2563 (fix:SI
2564 (fix:DF (match_operand:DF 1 "register_operand" ""))))
0fcad513
JVA
2565 (clobber (match_dup 2))
2566 (clobber (match_dup 3))
2567 (clobber (match_scratch:SI 4 ""))])]
886c62d1 2568 "TARGET_80387"
0fcad513
JVA
2569 "
2570{
2571 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2572 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
0fcad513 2573}")
886c62d1
JVA
2574
2575(define_expand "fix_truncsfsi2"
2576 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2577 (fix:SI
2578 (fix:SF (match_operand:SF 1 "register_operand" ""))))
0fcad513
JVA
2579 (clobber (match_dup 2))
2580 (clobber (match_dup 3))
2581 (clobber (match_scratch:SI 4 ""))])]
886c62d1 2582 "TARGET_80387"
0fcad513
JVA
2583 "
2584{
2585 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2586 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
0fcad513 2587}")
886c62d1 2588
4fb21e90 2589(define_insn ""
2ae0f82c 2590 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4fb21e90
JVA
2591 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2592 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2593 (clobber (match_operand:DI 3 "memory_operand" "m"))
4fb21e90
JVA
2594 (clobber (match_scratch:SI 4 "=&q"))]
2595 "TARGET_80387"
2f2a49e8 2596 "* return output_fix_trunc (insn, operands);")
4fb21e90 2597
886c62d1 2598(define_insn ""
2ae0f82c 2599 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
08a7baac 2600 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
0fcad513 2601 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2602 (clobber (match_operand:DI 3 "memory_operand" "m"))
0fcad513 2603 (clobber (match_scratch:SI 4 "=&q"))]
886c62d1 2604 "TARGET_80387"
2f2a49e8 2605 "* return output_fix_trunc (insn, operands);")
886c62d1
JVA
2606
2607(define_insn ""
2ae0f82c 2608 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
08a7baac 2609 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
0fcad513 2610 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2611 (clobber (match_operand:DI 3 "memory_operand" "m"))
0fcad513 2612 (clobber (match_scratch:SI 4 "=&q"))]
886c62d1 2613 "TARGET_80387"
2f2a49e8 2614 "* return output_fix_trunc (insn, operands);")
886c62d1
JVA
2615\f
2616;; Conversion between fixed point and floating point.
886c62d1 2617
b4ac57ab 2618;; ??? Possibly represent floatunssidf2 here in gcc2.
886c62d1
JVA
2619
2620(define_expand "floatsisf2"
bc725565
JW
2621 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2622 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))
2623 (clobber (match_dup 2))])]
886c62d1 2624 "TARGET_80387"
bc725565
JW
2625 "operands[2] = assign_386_stack_local (SImode, 0);")
2626
2627(define_insn ""
2628 [(set (match_operand:SF 0 "register_operand" "=f,f")
2629 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
2630 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
2631 "TARGET_80387"
2632 "#")
2633
2634(define_split
2635 [(set (match_operand:SF 0 "register_operand" "=f")
2636 (float:SF (match_operand:SI 1 "memory_operand" "m")))
2637 (clobber (match_operand:SI 2 "memory_operand" "m"))]
2638 "TARGET_80387 && reload_completed"
2639 [(set (match_dup 0)
2640 (float:SF (match_dup 1)))]
2641 "")
2642
2643(define_split
2644 [(set (match_operand:SF 0 "register_operand" "=f")
2645 (float:SF (match_operand:SI 1 "register_operand" "r")))
2646 (clobber (match_operand:SI 2 "memory_operand" "m"))]
2647 "TARGET_80387 && reload_completed"
2648 [(set (match_dup 2)
2649 (match_dup 1))
2650 (set (match_dup 0)
2651 (float:SF (match_dup 2)))]
886c62d1
JVA
2652 "")
2653
bc725565
JW
2654(define_insn ""
2655 [(set (match_operand:SF 0 "register_operand" "=f")
2656 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
2657 "TARGET_80387"
2658 "* return AS1 (fild%z1,%1);"
2659 [(set_attr "type" "fpop")])
2660
886c62d1 2661(define_expand "floatdisf2"
bc725565
JW
2662 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2663 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))
2664 (clobber (match_dup 2))])]
886c62d1 2665 "TARGET_80387"
bc725565 2666 "operands[2] = assign_386_stack_local (DImode, 0);")
886c62d1 2667
bc725565
JW
2668(define_insn ""
2669 [(set (match_operand:SF 0 "register_operand" "=f,f")
2670 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
2671 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
886c62d1 2672 "TARGET_80387"
bc725565
JW
2673 "#")
2674
2675(define_split
2676 [(set (match_operand:SF 0 "register_operand" "=f")
2677 (float:SF (match_operand:DI 1 "memory_operand" "m")))
2678 (clobber (match_operand:DI 2 "memory_operand" "m"))]
2679 "TARGET_80387 && reload_completed"
2680 [(set (match_dup 0)
2681 (float:SF (match_dup 1)))]
886c62d1
JVA
2682 "")
2683
bc725565
JW
2684(define_split
2685 [(set (match_operand:SF 0 "register_operand" "=f")
2686 (float:SF (match_operand:DI 1 "register_operand" "r")))
2687 (clobber (match_operand:DI 2 "memory_operand" "o"))]
2688 "TARGET_80387 && reload_completed"
2689 [(set (match_dup 2)
2690 (match_dup 1))
2691 (set (match_dup 0)
2692 (float:SF (match_dup 2)))]
886c62d1
JVA
2693 "")
2694
bc725565
JW
2695(define_insn ""
2696 [(set (match_operand:SF 0 "register_operand" "=f")
2697 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
4fb21e90 2698 "TARGET_80387"
bc725565
JW
2699 "* return AS1 (fild%z1,%1);"
2700 [(set_attr "type" "fpop")])
2701
2702(define_expand "floatsidf2"
2703 [(parallel [(set (match_operand:DF 0 "register_operand" "")
2704 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
2705 (clobber (match_dup 2))])]
2706 "TARGET_80387"
2707 "operands[2] = assign_386_stack_local (SImode, 0);")
2708
2709(define_insn ""
2710 [(set (match_operand:DF 0 "register_operand" "=f,f")
2711 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
2712 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
2713 "TARGET_80387"
2714 "#")
2715
2716(define_split
2717 [(set (match_operand:DF 0 "register_operand" "=f")
2718 (float:DF (match_operand:SI 1 "memory_operand" "m")))
2719 (clobber (match_operand:SI 2 "memory_operand" "m"))]
2720 "TARGET_80387 && reload_completed"
2721 [(set (match_dup 0)
2722 (float:DF (match_dup 1)))]
4fb21e90
JVA
2723 "")
2724
bc725565
JW
2725(define_split
2726 [(set (match_operand:DF 0 "register_operand" "=f")
2727 (float:DF (match_operand:SI 1 "register_operand" "r")))
2728 (clobber (match_operand:SI 2 "memory_operand" "m"))]
2729 "TARGET_80387 && reload_completed"
2730 [(set (match_dup 2)
2731 (match_dup 1))
2732 (set (match_dup 0)
2733 (float:DF (match_dup 2)))]
4fb21e90
JVA
2734 "")
2735
bc725565
JW
2736(define_insn ""
2737 [(set (match_operand:DF 0 "register_operand" "=f")
2738 (float:DF (match_operand:SI 1 "memory_operand" "m")))]
2739 "TARGET_80387"
2740 "* return AS1 (fild%z1,%1);"
2741 [(set_attr "type" "fpop")])
2742
2743(define_expand "floatdidf2"
2744 [(parallel [(set (match_operand:DF 0 "register_operand" "")
2745 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))
2746 (clobber (match_dup 2))])]
2747 "TARGET_80387"
2748 "operands[2] = assign_386_stack_local (DImode, 0);")
886c62d1 2749
4fb21e90 2750(define_insn ""
bc725565
JW
2751 [(set (match_operand:DF 0 "register_operand" "=f,f")
2752 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
2753 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
4fb21e90 2754 "TARGET_80387"
bc725565
JW
2755 "#")
2756
2757(define_split
2758 [(set (match_operand:DF 0 "register_operand" "=f")
2759 (float:DF (match_operand:DI 1 "memory_operand" "m")))
2760 (clobber (match_operand:DI 2 "memory_operand" "m"))]
2761 "TARGET_80387 && reload_completed"
2762 [(set (match_dup 0)
2763 (float:DF (match_dup 1)))]
2764 "")
2765
2766(define_split
2767 [(set (match_operand:DF 0 "register_operand" "=f")
2768 (float:DF (match_operand:DI 1 "register_operand" "r")))
2769 (clobber (match_operand:DI 2 "memory_operand" "o"))]
2770 "TARGET_80387 && reload_completed"
2771 [(set (match_dup 2)
2772 (match_dup 1))
2773 (set (match_dup 0)
2774 (float:DF (match_dup 2)))]
2775 "")
4fb21e90 2776
886c62d1 2777(define_insn ""
08a7baac 2778 [(set (match_operand:DF 0 "register_operand" "=f")
bc725565 2779 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
e1f998ad 2780 "TARGET_80387"
bc725565
JW
2781 "* return AS1 (fild%z1,%1);"
2782 [(set_attr "type" "fpop")])
2783
2784(define_expand "floatsixf2"
2785 [(parallel [(set (match_operand:XF 0 "register_operand" "")
2786 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))
2787 (clobber (match_dup 2))])]
2788 "TARGET_80387"
2789 "operands[2] = assign_386_stack_local (SImode, 0);")
886c62d1
JVA
2790
2791(define_insn ""
bc725565
JW
2792 [(set (match_operand:XF 0 "register_operand" "=f,f")
2793 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
2794 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
e1f998ad 2795 "TARGET_80387"
bc725565
JW
2796 "#")
2797
2798(define_split
2799 [(set (match_operand:XF 0 "register_operand" "=f")
2800 (float:XF (match_operand:SI 1 "memory_operand" "m")))
2801 (clobber (match_operand:SI 2 "memory_operand" "m"))]
2802 "TARGET_80387 && reload_completed"
2803 [(set (match_dup 0)
2804 (float:XF (match_dup 1)))]
2805 "")
2806
2807(define_split
2808 [(set (match_operand:XF 0 "register_operand" "=f")
2809 (float:XF (match_operand:SI 1 "register_operand" "r")))
2810 (clobber (match_operand:SI 2 "memory_operand" "m"))]
2811 "TARGET_80387 && reload_completed"
2812 [(set (match_dup 2)
2813 (match_dup 1))
2814 (set (match_dup 0)
2815 (float:XF (match_dup 2)))]
2816 "")
e1f998ad
JVA
2817
2818(define_insn ""
bc725565
JW
2819 [(set (match_operand:XF 0 "register_operand" "=f")
2820 (float:XF (match_operand:SI 1 "memory_operand" "m")))]
e1f998ad 2821 "TARGET_80387"
bc725565
JW
2822 "* return AS1 (fild%z1,%1);"
2823 [(set_attr "type" "fpop")])
2824
2825(define_expand "floatdixf2"
2826 [(parallel [(set (match_operand:XF 0 "register_operand" "")
2827 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))
2828 (clobber (match_dup 2))])]
2829 "TARGET_80387"
2830 "operands[2] = assign_386_stack_local (DImode, 0);")
e1f998ad 2831
4fb21e90
JVA
2832(define_insn ""
2833 [(set (match_operand:XF 0 "register_operand" "=f,f")
bc725565
JW
2834 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
2835 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
4fb21e90 2836 "TARGET_80387"
bc725565
JW
2837 "#")
2838
2839(define_split
2840 [(set (match_operand:XF 0 "register_operand" "=f")
2841 (float:XF (match_operand:DI 1 "memory_operand" "m")))
2842 (clobber (match_operand:DI 2 "memory_operand" "m"))]
2843 "TARGET_80387 && reload_completed"
2844 [(set (match_dup 0)
2845 (float:XF (match_dup 1)))]
2846 "")
2847
2848(define_split
2849 [(set (match_operand:XF 0 "register_operand" "=f")
2850 (float:XF (match_operand:DI 1 "register_operand" "r")))
2851 (clobber (match_operand:DI 2 "memory_operand" "o"))]
2852 "TARGET_80387 && reload_completed"
2853 [(set (match_dup 2)
2854 (match_dup 1))
2855 (set (match_dup 0)
2856 (float:XF (match_dup 2)))]
2857 "")
4fb21e90 2858
e1f998ad 2859(define_insn ""
bc725565
JW
2860 [(set (match_operand:XF 0 "register_operand" "=f")
2861 (float:XF (match_operand:DI 1 "memory_operand" "m")))]
e1f998ad 2862 "TARGET_80387"
bc725565
JW
2863 "* return AS1 (fild%z1,%1);"
2864 [(set_attr "type" "fpop")])
886c62d1
JVA
2865\f
2866;;- add instructions
2867
a269a03c 2868(define_insn "*addsidi3_1"
f58acb67 2869 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
2ae0f82c
SC
2870 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
2871 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
2872 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
f58acb67 2873 ""
2ae0f82c
SC
2874 "*
2875{
dae0d63a 2876 rtx low[3], high[3], xops[7];
2ae0f82c
SC
2877
2878 CC_STATUS_INIT;
2879
2880 split_di (operands, 2, low, high);
2881 high[2] = const0_rtx;
2882 low[2] = operands[2];
2883
2884 if (!rtx_equal_p (operands[0], operands[1]))
2885 {
2886 xops[0] = high[0];
2887 xops[1] = low[0];
2888 xops[2] = high[1];
2889 xops[3] = low[1];
2890
2891 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2892 {
2893 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2894 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2895 }
2896 else
2897 {
2898 xops[4] = high[2];
2899 xops[5] = low[2];
2900 xops[6] = operands[3];
2901 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2902 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2903 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2904 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2905 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2906 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2907 RET;
2908 }
2909 }
2910
2911 output_asm_insn (AS2 (add%L0,%2,%0), low);
2912 output_asm_insn (AS2 (adc%L0,%2,%0), high);
a269a03c
JC
2913 cc_status.value1 = high[0];
2914 cc_status.flags = CC_NO_OVERFLOW;
2ae0f82c 2915 RET;
a269a03c
JC
2916}"
2917 [(set_attr "type" "binary")])
2ae0f82c 2918
f58acb67 2919(define_insn "addsidi3_2"
5bc7cd8e 2920 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
f58acb67
SC
2921 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
2922 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
2923 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
2924 ""
2ae0f82c
SC
2925 "*
2926{
dae0d63a 2927 rtx low[3], high[3], xops[7];
2ae0f82c
SC
2928
2929 CC_STATUS_INIT;
2930
2931 split_di (operands, 2, low, high);
2932 high[2] = const0_rtx;
2933 low[2] = operands[2];
2934
2935 if (!rtx_equal_p (operands[0], operands[1]))
2936 {
2937 xops[0] = high[0];
2938 xops[1] = low[0];
2939 xops[2] = high[1];
2940 xops[3] = low[1];
2941
2942 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2943 {
70cff8f5
RK
2944 if (rtx_equal_p (low[0], operands[2]))
2945 {
2946 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2947 output_asm_insn (AS2 (add%L0,%1,%0), low);
2948 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2949 RET;
2950 }
2951 if (rtx_equal_p (high[0], operands[2]))
2952 {
2953 if (GET_CODE (operands[0]) != MEM)
2954 {
2955 output_asm_insn (AS2 (mov%L0,%2,%0), low);
2956 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2957 output_asm_insn (AS2 (add%L0,%1,%0), low);
2958 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2959 }
2960 else
2961 {
2962 /* It's too late to ask for a scratch now - but this
2963 will probably not happen too often. */
2964 output_asm_insn (AS2 (add%L1,%2,%1), low);
2965 output_asm_insn (AS2 (mov%L0,%1,%0), low);
2966 output_asm_insn (AS2 (mov%L1,%2,%1), low);
2967 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2968 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2969 output_asm_insn (AS2 (sub%L1,%0,%1), low);
2970 output_asm_insn (AS1 (neg%L1,%1), low);
2971 }
2972 RET;
2973 }
2ae0f82c
SC
2974 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2975 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2976 }
2977 else
2978 {
2979 xops[4] = high[2];
2980 xops[5] = low[2];
2981 xops[6] = operands[3];
2982 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2983 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2984 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2985 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2986 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2987 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2988 RET;
2989 }
2990 }
2991
2992 output_asm_insn (AS2 (add%L0,%2,%0), low);
2993 output_asm_insn (AS2 (adc%L0,%2,%0), high);
a269a03c
JC
2994 cc_status.value1 = high[0];
2995 cc_status.flags = CC_NO_OVERFLOW;
2ae0f82c 2996 RET;
a269a03c
JC
2997}"
2998 [(set_attr "type" "binary")])
2ae0f82c 2999
f58acb67 3000(define_insn "adddi3"
93f83bd5
R
3001 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
3002 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
3003 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
3004 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
886c62d1
JVA
3005 ""
3006 "*
3007{
f94bdcb6 3008 rtx low[3], high[3], xops[7], temp;
886c62d1
JVA
3009
3010 CC_STATUS_INIT;
3011
f94bdcb6
MM
3012 if (rtx_equal_p (operands[0], operands[2]))
3013 {
3014 temp = operands[1];
3015 operands[1] = operands[2];
3016 operands[2] = temp;
3017 }
886c62d1 3018
f94bdcb6 3019 split_di (operands, 3, low, high);
96f218bb
MM
3020 if (!rtx_equal_p (operands[0], operands[1]))
3021 {
3022 xops[0] = high[0];
3023 xops[1] = low[0];
3024 xops[2] = high[1];
3025 xops[3] = low[1];
3026
8ff9a9d1 3027 if (GET_CODE (operands[0]) != MEM)
96f218bb
MM
3028 {
3029 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3030 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3031 }
3032 else
3033 {
3034 xops[4] = high[2];
3035 xops[5] = low[2];
3036 xops[6] = operands[3];
3037 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3038 output_asm_insn (AS2 (add%L6,%5,%6), xops);
3039 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3040 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3041 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3042 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3043 RET;
3044 }
3045 }
3046
a269a03c
JC
3047 cc_status.value1 = high[0];
3048 cc_status.flags = CC_NO_OVERFLOW;
3049
f94bdcb6 3050 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
96f218bb
MM
3051 {
3052 xops[0] = high[0];
3053 xops[1] = low[0];
3054 xops[2] = high[2];
3055 xops[3] = low[2];
3056 xops[4] = operands[3];
3057
3058 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3059 output_asm_insn (AS2 (add%L1,%4,%1), xops);
3060 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3061 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
3062 }
3063
3064 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
9c530261
JVA
3065 {
3066 output_asm_insn (AS2 (add%L0,%2,%0), low);
3067 output_asm_insn (AS2 (adc%L0,%2,%0), high);
3068 }
96f218bb 3069
9c530261
JVA
3070 else
3071 output_asm_insn (AS2 (add%L0,%2,%0), high);
96f218bb 3072
886c62d1 3073 RET;
a269a03c
JC
3074}"
3075 [(set_attr "type" "binary")])
886c62d1
JVA
3076
3077;; On a 486, it is faster to do movl/addl than to do a single leal if
3078;; operands[1] and operands[2] are both registers.
3079
2ae0f82c
SC
3080(define_expand "addsi3"
3081 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3082 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3083 (match_operand:SI 2 "general_operand" "")))]
886c62d1 3084 ""
2ae0f82c
SC
3085 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
3086
3087(define_insn ""
3088 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3089 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3090 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
3091 "ix86_binary_operator_ok (PLUS, SImode, operands)"
886c62d1
JVA
3092 "*
3093{
2ae0f82c 3094 if (REG_P (operands[0]) && REG_P (operands[1])
2e79e5cb 3095 && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
2ae0f82c 3096 && REGNO (operands[0]) != REGNO (operands[1]))
886c62d1
JVA
3097 {
3098 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3099 return AS2 (add%L0,%1,%0);
3100
c1450f19
MM
3101 if (operands[2] == stack_pointer_rtx)
3102 {
3103 rtx temp;
44242645 3104
c1450f19
MM
3105 temp = operands[1];
3106 operands[1] = operands[2];
3107 operands[2] = temp;
3108 }
44242645 3109
c1450f19
MM
3110 if (operands[2] != stack_pointer_rtx)
3111 {
3112 CC_STATUS_INIT;
3113 operands[1] = SET_SRC (PATTERN (insn));
3114 return AS2 (lea%L0,%a1,%0);
886c62d1 3115 }
886c62d1
JVA
3116 }
3117
2ae0f82c
SC
3118 if (!rtx_equal_p (operands[0], operands[1]))
3119 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3120
886c62d1
JVA
3121 if (operands[2] == const1_rtx)
3122 return AS1 (inc%L0,%0);
3123
3124 if (operands[2] == constm1_rtx)
3125 return AS1 (dec%L0,%0);
3126
5bc7cd8e
SC
3127 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
3128 if (GET_CODE (operands[2]) == CONST_INT
3129 && INTVAL (operands[2]) == 128)
3130 {
3131 /* This doesn't compute the carry bit in the same way
3132 * as add%L0, but we use inc and dec above and they
3133 * don't set the carry bit at all. If inc/dec don't need
3134 * a CC_STATUS_INIT, this doesn't either... */
3135 operands[2] = GEN_INT (-128);
3136 return AS2 (sub%L0,%2,%0);
3137 }
3138
886c62d1 3139 return AS2 (add%L0,%2,%0);
a269a03c
JC
3140}"
3141 [(set_attr "type" "binary")])
886c62d1 3142
2ae0f82c
SC
3143;; addsi3 is faster, so put this after.
3144
3145(define_insn "movsi_lea"
3146 [(set (match_operand:SI 0 "register_operand" "=r")
3147 (match_operand:QI 1 "address_operand" "p"))]
3148 ""
3149 "*
3150{
3151 /* Adding a constant to a register is faster with an add. */
3152 /* ??? can this ever happen? */
3153 if (GET_CODE (operands[1]) == PLUS
3154 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
3155 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
3156 {
3157 operands[1] = XEXP (operands[1], 1);
3158
3159 if (operands[1] == const1_rtx)
3160 return AS1 (inc%L0,%0);
3161
3162 if (operands[1] == constm1_rtx)
3163 return AS1 (dec%L0,%0);
3164
3165 return AS2 (add%L0,%1,%0);
3166 }
3167
3168 CC_STATUS_INIT;
3169 return AS2 (lea%L0,%a1,%0);
a269a03c
JC
3170}"
3171 [(set_attr "type" "lea")])
2ae0f82c 3172
886c62d1
JVA
3173;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
3174;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
3175;; able to handle the operand. But leal always works?
3176
2ae0f82c
SC
3177(define_expand "addhi3"
3178 [(set (match_operand:HI 0 "general_operand" "")
3179 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3180 (match_operand:HI 2 "general_operand" "")))]
886c62d1 3181 ""
2ae0f82c
SC
3182 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
3183
3184(define_insn ""
3185 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3186 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3187 (match_operand:HI 2 "general_operand" "ri,rm")))]
3188 "ix86_binary_operator_ok (PLUS, HImode, operands)"
886c62d1
JVA
3189 "*
3190{
b980bec0 3191 /* ??? what about offsettable memory references? */
5bc7cd8e
SC
3192 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
3193 && QI_REG_P (operands[0])
b980bec0 3194 && GET_CODE (operands[2]) == CONST_INT
5bc7cd8e
SC
3195 && (INTVAL (operands[2]) & 0xff) == 0
3196 && i386_cc_probably_useless_p (insn))
b980bec0 3197 {
c64ca3e9 3198 int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
b980bec0
JVA
3199 CC_STATUS_INIT;
3200
c64ca3e9 3201 if (byteval == 1)
b980bec0 3202 return AS1 (inc%B0,%h0);
c64ca3e9 3203 else if (byteval == 255)
b980bec0
JVA
3204 return AS1 (dec%B0,%h0);
3205
c64ca3e9 3206 operands[2] = GEN_INT (byteval);
b980bec0
JVA
3207 return AS2 (add%B0,%2,%h0);
3208 }
3209
5bc7cd8e
SC
3210 /* Use a 32-bit operation when possible, to avoid the prefix penalty. */
3211 if (REG_P (operands[0])
3212 && i386_aligned_p (operands[2])
3213 && i386_cc_probably_useless_p (insn))
3214 {
3215 CC_STATUS_INIT;
3216
3217 if (GET_CODE (operands[2]) == CONST_INT)
3218 {
3219 HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]);
3220
3221 if (intval == 1)
3222 return AS1 (inc%L0,%k0);
3223
3224 if (intval == 0xffff)
3225 return AS1 (dec%L0,%k0);
3226
3227 operands[2] = i386_sext16_if_const (operands[2]);
3228 }
3229 return AS2 (add%L0,%k2,%k0);
3230 }
3231
886c62d1
JVA
3232 if (operands[2] == const1_rtx)
3233 return AS1 (inc%W0,%0);
3234
c64ca3e9
RK
3235 if (operands[2] == constm1_rtx
3236 || (GET_CODE (operands[2]) == CONST_INT
3237 && INTVAL (operands[2]) == 65535))
886c62d1
JVA
3238 return AS1 (dec%W0,%0);
3239
3240 return AS2 (add%W0,%2,%0);
a269a03c
JC
3241}"
3242 [(set_attr "type" "binary")])
886c62d1 3243
2ae0f82c
SC
3244(define_expand "addqi3"
3245 [(set (match_operand:QI 0 "general_operand" "")
3246 (plus:QI (match_operand:QI 1 "general_operand" "")
3247 (match_operand:QI 2 "general_operand" "")))]
886c62d1 3248 ""
2ae0f82c
SC
3249 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3250
3251(define_insn ""
3252 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3253 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3254 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3255 "ix86_binary_operator_ok (PLUS, QImode, operands)"
886c62d1
JVA
3256 "*
3257{
3258 if (operands[2] == const1_rtx)
3259 return AS1 (inc%B0,%0);
3260
c64ca3e9
RK
3261 if (operands[2] == constm1_rtx
3262 || (GET_CODE (operands[2]) == CONST_INT
3263 && INTVAL (operands[2]) == 255))
886c62d1
JVA
3264 return AS1 (dec%B0,%0);
3265
3266 return AS2 (add%B0,%2,%0);
a269a03c
JC
3267}"
3268 [(set_attr "type" "binary")])
886c62d1
JVA
3269
3270;Lennart Augustsson <augustss@cs.chalmers.se>
3271;says this pattern just makes slower code:
3272; pushl %ebp
3273; addl $-80,(%esp)
3274;instead of
3275; leal -80(%ebp),%eax
3276; pushl %eax
3277;
3278;(define_insn ""
3279; [(set (match_operand:SI 0 "push_operand" "=<")
2ae0f82c
SC
3280; (plus:SI (match_operand:SI 1 "register_operand" "%r")
3281; (match_operand:SI 2 "nonmemory_operand" "ri")))]
886c62d1
JVA
3282; ""
3283; "*
3284;{
3285; rtx xops[4];
3286; xops[0] = operands[0];
3287; xops[1] = operands[1];
3288; xops[2] = operands[2];
f64cecad 3289; xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
886c62d1
JVA
3290; output_asm_insn (\"push%z1 %1\", xops);
3291; output_asm_insn (AS2 (add%z3,%2,%3), xops);
3292; RET;
3293;}")
3294
886c62d1
JVA
3295;; The patterns that match these are at the end of this file.
3296
4fb21e90
JVA
3297(define_expand "addxf3"
3298 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
3299 (plus:XF (match_operand:XF 1 "register_operand" "")
3300 (match_operand:XF 2 "register_operand" "")))]
4fb21e90
JVA
3301 "TARGET_80387"
3302 "")
3303
886c62d1
JVA
3304(define_expand "adddf3"
3305 [(set (match_operand:DF 0 "register_operand" "")
3306 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3307 (match_operand:DF 2 "nonimmediate_operand" "")))]
3308 "TARGET_80387"
3309 "")
3310
3311(define_expand "addsf3"
3312 [(set (match_operand:SF 0 "register_operand" "")
3313 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3314 (match_operand:SF 2 "nonimmediate_operand" "")))]
3315 "TARGET_80387"
3316 "")
3317\f
3318;;- subtract instructions
3319
f58acb67
SC
3320(define_insn "subsidi3"
3321 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3322 (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o")
3323 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3324 (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))]
3325 ""
2ae0f82c
SC
3326 "*
3327{
3328 rtx low[3], high[3], xops[7];
3329
3330 CC_STATUS_INIT;
3331
3332 split_di (operands, 2, low, high);
3333 high[2] = const0_rtx;
3334 low[2] = operands[2];
3335
3336 if (!rtx_equal_p (operands[0], operands[1]))
3337 {
3338 xops[0] = high[0];
3339 xops[1] = low[0];
3340 xops[2] = high[1];
3341 xops[3] = low[1];
3342
3343 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3344 {
3345 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3346 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3347 }
3348 else
3349 {
3350 xops[4] = high[2];
3351 xops[5] = low[2];
3352 xops[6] = operands[3];
3353 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3354 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3355 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3356 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3357 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3358 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3359 RET;
3360 }
3361 }
3362
3363 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3364 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
a269a03c
JC
3365 cc_status.value1 = high[0];
3366 cc_status.flags = CC_NO_OVERFLOW;
3367
2ae0f82c 3368 RET;
a269a03c
JC
3369}"
3370 [(set_attr "type" "binary")])
2ae0f82c 3371
f58acb67
SC
3372(define_insn "subdi3"
3373 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3374 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF")
3375 (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3376 (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
acb94fa1 3377 ""
886c62d1
JVA
3378 "*
3379{
96f218bb 3380 rtx low[3], high[3], xops[7];
886c62d1
JVA
3381
3382 CC_STATUS_INIT;
3383
3384 split_di (operands, 3, low, high);
3385
96f218bb
MM
3386 if (!rtx_equal_p (operands[0], operands[1]))
3387 {
3388 xops[0] = high[0];
3389 xops[1] = low[0];
3390 xops[2] = high[1];
3391 xops[3] = low[1];
3392
dee6d39e 3393 if (GET_CODE (operands[0]) != MEM)
96f218bb
MM
3394 {
3395 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3396 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3397 }
3398 else
3399 {
3400 xops[4] = high[2];
3401 xops[5] = low[2];
3402 xops[6] = operands[3];
3403 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3404 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3405 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3406 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3407 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3408 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3409 RET;
3410 }
3411 }
3412
a269a03c
JC
3413 cc_status.value1 = high[0];
3414 cc_status.flags = CC_NO_OVERFLOW;
3415
96f218bb
MM
3416 if (GET_CODE (operands[3]) == REG)
3417 {
3418 xops[0] = high[0];
3419 xops[1] = low[0];
3420 xops[2] = high[2];
3421 xops[3] = low[2];
3422 xops[4] = operands[3];
3423
3424 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3425 output_asm_insn (AS2 (sub%L1,%4,%1), xops);
3426 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3427 output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
3428 }
3429
3430 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
9c530261
JVA
3431 {
3432 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3433 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3434 }
96f218bb 3435
9c530261 3436 else
a269a03c
JC
3437 output_asm_insn (AS2 (sub%L0,%2,%0), high);
3438
9c530261 3439
886c62d1 3440 RET;
a269a03c
JC
3441}"
3442 [(set_attr "type" "binary")])
886c62d1 3443
2ae0f82c
SC
3444(define_expand "subsi3"
3445 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3446 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3447 (match_operand:SI 2 "general_operand" "")))]
886c62d1 3448 ""
2ae0f82c
SC
3449 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3450
3451(define_insn ""
3452 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3453 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3454 (match_operand:SI 2 "general_operand" "ri,rm")))]
3455 "ix86_binary_operator_ok (MINUS, SImode, operands)"
a269a03c
JC
3456 "* return AS2 (sub%L0,%2,%0);"
3457 [(set_attr "type" "binary")])
886c62d1 3458
2ae0f82c
SC
3459(define_expand "subhi3"
3460 [(set (match_operand:HI 0 "general_operand" "")
3461 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3462 (match_operand:HI 2 "general_operand" "")))]
886c62d1 3463 ""
2ae0f82c
SC
3464 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3465
3466(define_insn ""
3467 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
87fd1847 3468 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
2ae0f82c
SC
3469 (match_operand:HI 2 "general_operand" "ri,rm")))]
3470 "ix86_binary_operator_ok (MINUS, HImode, operands)"
5bc7cd8e
SC
3471 "*
3472{
3473 if (REG_P (operands[0])
3474 && i386_aligned_p (operands[2])
3475 && i386_cc_probably_useless_p (insn))
3476 {
3477 CC_STATUS_INIT;
3478 operands[2] = i386_sext16_if_const (operands[2]);
3479 return AS2 (sub%L0,%k2,%k0);
3480 }
3481 return AS2 (sub%W0,%2,%0);
a269a03c
JC
3482}"
3483 [(set_attr "type" "binary")])
886c62d1 3484
2ae0f82c
SC
3485(define_expand "subqi3"
3486 [(set (match_operand:QI 0 "general_operand" "")
3487 (minus:QI (match_operand:QI 1 "general_operand" "")
3488 (match_operand:QI 2 "general_operand" "")))]
886c62d1 3489 ""
2ae0f82c
SC
3490 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3491
3492(define_insn ""
3493 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3494 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3495 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3496 "ix86_binary_operator_ok (MINUS, QImode, operands)"
a269a03c
JC
3497 "* return AS2 (sub%B0,%2,%0);"
3498 [(set_attr "type" "binary")])
2ae0f82c 3499
886c62d1
JVA
3500;; The patterns that match these are at the end of this file.
3501
4fb21e90
JVA
3502(define_expand "subxf3"
3503 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
3504 (minus:XF (match_operand:XF 1 "register_operand" "")
3505 (match_operand:XF 2 "register_operand" "")))]
4fb21e90
JVA
3506 "TARGET_80387"
3507 "")
3508
886c62d1
JVA
3509(define_expand "subdf3"
3510 [(set (match_operand:DF 0 "register_operand" "")
3511 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3512 (match_operand:DF 2 "nonimmediate_operand" "")))]
3513 "TARGET_80387"
3514 "")
3515
3516(define_expand "subsf3"
3517 [(set (match_operand:SF 0 "register_operand" "")
3518 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3519 (match_operand:SF 2 "nonimmediate_operand" "")))]
3520 "TARGET_80387"
3521 "")
3522\f
3523;;- multiply instructions
3524
3525;(define_insn "mulqi3"
2ae0f82c
SC
3526; [(set (match_operand:QI 0 "register_operand" "=a")
3527; (mult:QI (match_operand:QI 1 "register_operand" "%0")
3528; (match_operand:QI 2 "nonimmediate_operand" "qm")))]
886c62d1
JVA
3529; ""
3530; "imul%B0 %2,%0")
3531
886c62d1 3532(define_insn "mulhi3"
2ae0f82c
SC
3533 [(set (match_operand:HI 0 "register_operand" "=r,r")
3534 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm")
886c62d1
JVA
3535 (match_operand:HI 2 "general_operand" "g,i")))]
3536 ""
3537 "*
3538{
3539 if (GET_CODE (operands[1]) == REG
3540 && REGNO (operands[1]) == REGNO (operands[0])
3541 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3542 /* Assembler has weird restrictions. */
3543 return AS2 (imul%W0,%2,%0);
3544 return AS3 (imul%W0,%2,%1,%0);
36cf4bcf
SC
3545}"
3546 [(set_attr "type" "imul")])
886c62d1 3547
886c62d1 3548(define_insn "mulsi3"
2ae0f82c
SC
3549 [(set (match_operand:SI 0 "register_operand" "=r,r")
3550 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
886c62d1
JVA
3551 (match_operand:SI 2 "general_operand" "g,i")))]
3552 ""
3553 "*
3554{
3555 if (GET_CODE (operands[1]) == REG
3556 && REGNO (operands[1]) == REGNO (operands[0])
3557 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3558 /* Assembler has weird restrictions. */
3559 return AS2 (imul%L0,%2,%0);
3560 return AS3 (imul%L0,%2,%1,%0);
36cf4bcf
SC
3561}"
3562 [(set_attr "type" "imul")])
886c62d1 3563
4b71cd6e 3564(define_insn "umulqihi3"
2ae0f82c
SC
3565 [(set (match_operand:HI 0 "register_operand" "=a")
3566 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4b71cd6e 3567 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
886c62d1 3568 ""
36cf4bcf
SC
3569 "mul%B0 %2"
3570 [(set_attr "type" "imul")])
886c62d1 3571
4b71cd6e 3572(define_insn "mulqihi3"
2ae0f82c
SC
3573 [(set (match_operand:HI 0 "register_operand" "=a")
3574 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4b71cd6e
MM
3575 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3576 ""
36cf4bcf
SC
3577 "imul%B0 %2"
3578 [(set_attr "type" "imul")])
4b71cd6e
MM
3579
3580(define_insn "umulsidi3"
3581 [(set (match_operand:DI 0 "register_operand" "=A")
3582 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3583 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
2f2a49e8 3584 "TARGET_WIDE_MULTIPLY"
36cf4bcf
SC
3585 "mul%L0 %2"
3586 [(set_attr "type" "imul")])
4b71cd6e
MM
3587
3588(define_insn "mulsidi3"
3589 [(set (match_operand:DI 0 "register_operand" "=A")
3590 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3591 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
2f2a49e8 3592 "TARGET_WIDE_MULTIPLY"
36cf4bcf
SC
3593 "imul%L0 %2"
3594 [(set_attr "type" "imul")])
2f2a49e8
MM
3595
3596(define_insn "umulsi3_highpart"
3597 [(set (match_operand:SI 0 "register_operand" "=d")
3598 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
3599 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
3600 (const_int 32))))
3601 (clobber (match_scratch:SI 3 "=a"))]
3602 "TARGET_WIDE_MULTIPLY"
36cf4bcf
SC
3603 "mul%L0 %2"
3604 [(set_attr "type" "imul")])
2f2a49e8
MM
3605
3606(define_insn "smulsi3_highpart"
3607 [(set (match_operand:SI 0 "register_operand" "=d")
3608 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
3609 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
3610 (const_int 32))))
3611 (clobber (match_scratch:SI 3 "=a"))]
3612 "TARGET_WIDE_MULTIPLY"
36cf4bcf
SC
3613 "imul%L0 %2"
3614 [(set_attr "type" "imul")])
4b71cd6e 3615
886c62d1
JVA
3616;; The patterns that match these are at the end of this file.
3617
4fb21e90
JVA
3618(define_expand "mulxf3"
3619 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
3620 (mult:XF (match_operand:XF 1 "register_operand" "")
3621 (match_operand:XF 2 "register_operand" "")))]
4fb21e90
JVA
3622 "TARGET_80387"
3623 "")
3624
886c62d1
JVA
3625(define_expand "muldf3"
3626 [(set (match_operand:DF 0 "register_operand" "")
2ae0f82c 3627 (mult:DF (match_operand:DF 1 "register_operand" "")
886c62d1
JVA
3628 (match_operand:DF 2 "nonimmediate_operand" "")))]
3629 "TARGET_80387"
3630 "")
3631
3632(define_expand "mulsf3"
3633 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 3634 (mult:SF (match_operand:SF 1 "register_operand" "")
886c62d1
JVA
3635 (match_operand:SF 2 "nonimmediate_operand" "")))]
3636 "TARGET_80387"
3637 "")
3638\f
3639;;- divide instructions
3640
3641(define_insn "divqi3"
2ae0f82c
SC
3642 [(set (match_operand:QI 0 "register_operand" "=a")
3643 (div:QI (match_operand:HI 1 "register_operand" "0")
3644 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
886c62d1
JVA
3645 ""
3646 "idiv%B0 %2")
3647
3648(define_insn "udivqi3"
2ae0f82c
SC
3649 [(set (match_operand:QI 0 "register_operand" "=a")
3650 (udiv:QI (match_operand:HI 1 "register_operand" "0")
3651 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
886c62d1 3652 ""
36cf4bcf
SC
3653 "div%B0 %2"
3654 [(set_attr "type" "idiv")])
886c62d1
JVA
3655
3656;; The patterns that match these are at the end of this file.
3657
4fb21e90
JVA
3658(define_expand "divxf3"
3659 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
3660 (div:XF (match_operand:XF 1 "register_operand" "")
3661 (match_operand:XF 2 "register_operand" "")))]
886c62d1
JVA
3662 "TARGET_80387"
3663 "")
3664
a78cb986
SC
3665(define_expand "divdf3"
3666 [(set (match_operand:DF 0 "register_operand" "")
3667 (div:DF (match_operand:DF 1 "register_operand" "")
3668 (match_operand:DF 2 "nonimmediate_operand" "")))]
3669 "TARGET_80387"
3670 "")
3671
886c62d1
JVA
3672(define_expand "divsf3"
3673 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 3674 (div:SF (match_operand:SF 1 "register_operand" "")
886c62d1
JVA
3675 (match_operand:SF 2 "nonimmediate_operand" "")))]
3676 "TARGET_80387"
3677 "")
3678\f
3679;; Remainder instructions.
3680
3681(define_insn "divmodsi4"
2bb7a0f5
RS
3682 [(set (match_operand:SI 0 "register_operand" "=a")
3683 (div:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 3684 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3685 (set (match_operand:SI 3 "register_operand" "=&d")
886c62d1
JVA
3686 (mod:SI (match_dup 1) (match_dup 2)))]
3687 ""
3688 "*
3689{
3690#ifdef INTEL_SYNTAX
3691 output_asm_insn (\"cdq\", operands);
3692#else
3693 output_asm_insn (\"cltd\", operands);
3694#endif
3695 return AS1 (idiv%L0,%2);
36cf4bcf
SC
3696}"
3697 [(set_attr "type" "idiv")])
886c62d1
JVA
3698
3699(define_insn "divmodhi4"
2bb7a0f5
RS
3700 [(set (match_operand:HI 0 "register_operand" "=a")
3701 (div:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 3702 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3703 (set (match_operand:HI 3 "register_operand" "=&d")
886c62d1
JVA
3704 (mod:HI (match_dup 1) (match_dup 2)))]
3705 ""
36cf4bcf
SC
3706 "cwtd\;idiv%W0 %2"
3707 [(set_attr "type" "idiv")])
886c62d1
JVA
3708
3709;; ??? Can we make gcc zero extend operand[0]?
3710(define_insn "udivmodsi4"
2bb7a0f5
RS
3711 [(set (match_operand:SI 0 "register_operand" "=a")
3712 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 3713 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3714 (set (match_operand:SI 3 "register_operand" "=&d")
886c62d1
JVA
3715 (umod:SI (match_dup 1) (match_dup 2)))]
3716 ""
3717 "*
3718{
3719 output_asm_insn (AS2 (xor%L3,%3,%3), operands);
3720 return AS1 (div%L0,%2);
36cf4bcf
SC
3721}"
3722 [(set_attr "type" "idiv")])
886c62d1
JVA
3723
3724;; ??? Can we make gcc zero extend operand[0]?
3725(define_insn "udivmodhi4"
2bb7a0f5
RS
3726 [(set (match_operand:HI 0 "register_operand" "=a")
3727 (udiv:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 3728 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3729 (set (match_operand:HI 3 "register_operand" "=&d")
886c62d1
JVA
3730 (umod:HI (match_dup 1) (match_dup 2)))]
3731 ""
3732 "*
3733{
3734 output_asm_insn (AS2 (xor%W0,%3,%3), operands);
3735 return AS1 (div%W0,%2);
36cf4bcf
SC
3736}"
3737 [(set_attr "type" "idiv")])
886c62d1
JVA
3738
3739/*
3740;;this should be a valid double division which we may want to add
3741
3742(define_insn ""
2bb7a0f5
RS
3743 [(set (match_operand:SI 0 "register_operand" "=a")
3744 (udiv:DI (match_operand:DI 1 "register_operand" "a")
2ae0f82c 3745 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3746 (set (match_operand:SI 3 "register_operand" "=d")
886c62d1
JVA
3747 (umod:SI (match_dup 1) (match_dup 2)))]
3748 ""
36cf4bcf
SC
3749 "div%L0 %2,%0"
3750 [(set_attr "type" "idiv")])
886c62d1
JVA
3751*/
3752\f
3753;;- and instructions
3754
3755;; On i386,
3756;; movzbl %bl,%ebx
3757;; is faster than
3758;; andl $255,%ebx
3759;;
3760;; but if the reg is %eax, then the "andl" is faster.
3761;;
3762;; On i486, the "andl" is always faster than the "movzbl".
3763;;
3764;; On both i386 and i486, a three operand AND is as fast with movzbl or
3765;; movzwl as with andl, if operands[0] != operands[1].
3766
3767;; The `r' in `rm' for operand 3 looks redundant, but it causes
3768;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
3769
886c62d1 3770(define_insn "andsi3"
2ae0f82c
SC
3771 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3772 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3773 (match_operand:SI 2 "general_operand" "ri,rm")))]
886c62d1
JVA
3774 ""
3775 "*
3776{
5bc7cd8e 3777 HOST_WIDE_INT intval;
2ae0f82c
SC
3778 if (!rtx_equal_p (operands[0], operands[1])
3779 && rtx_equal_p (operands[0], operands[2]))
3780 {
3781 rtx tmp;
3782 tmp = operands[1];
3783 operands[1] = operands[2];
3784 operands[2] = tmp;
3785 }
5bc7cd8e 3786 switch (GET_CODE (operands[2]))
886c62d1 3787 {
5bc7cd8e
SC
3788 case CONST_INT:
3789 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3790 break;
3791 intval = INTVAL (operands[2]);
3792 /* zero-extend 16->32? */
3793 if (intval == 0xffff && REG_P (operands[0])
886c62d1
JVA
3794 && (! REG_P (operands[1])
3795 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
268bfa44 3796 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
886c62d1
JVA
3797 {
3798 /* ??? tege: Should forget CC_STATUS only if we clobber a
3799 remembered operand. Fix that later. */
3800 CC_STATUS_INIT;
3801#ifdef INTEL_SYNTAX
3802 return AS2 (movzx,%w1,%0);
3803#else
3804 return AS2 (movz%W0%L0,%w1,%0);
3805#endif
3806 }
3807
5bc7cd8e
SC
3808 /* zero extend 8->32? */
3809 if (intval == 0xff && REG_P (operands[0])
886c62d1
JVA
3810 && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
3811 && (! REG_P (operands[1])
3812 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
268bfa44 3813 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
886c62d1
JVA
3814 {
3815 /* ??? tege: Should forget CC_STATUS only if we clobber a
3816 remembered operand. Fix that later. */
3817 CC_STATUS_INIT;
3818#ifdef INTEL_SYNTAX
3819 return AS2 (movzx,%b1,%0);
3820#else
3821 return AS2 (movz%B0%L0,%b1,%0);
3822#endif
3823 }
3824
5bc7cd8e
SC
3825 /* Check partial bytes.. non-QI-regs are not available */
3826 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3827 break;
886c62d1 3828
5bc7cd8e
SC
3829 /* only low byte has zero bits? */
3830 if (~(intval | 0xff) == 0)
3831 {
3832 intval &= 0xff;
3833 if (REG_P (operands[0]))
886c62d1 3834 {
5bc7cd8e
SC
3835 if (intval == 0)
3836 {
3837 CC_STATUS_INIT;
3838 return AS2 (xor%B0,%b0,%b0);
3839 }
3840
3841 /* we're better off with the 32-bit version if reg != EAX */
3842 /* the value is sign-extended in 8 bits */
3843 if (REGNO (operands[0]) != 0 && (intval & 0x80))
3844 break;
886c62d1
JVA
3845 }
3846
5bc7cd8e
SC
3847 CC_STATUS_INIT;
3848
3849 operands[2] = GEN_INT (intval);
3850
3851 if (intval == 0)
3852 return AS2 (mov%B0,%2,%b0);
3853
886c62d1
JVA
3854 return AS2 (and%B0,%2,%b0);
3855 }
3856
5bc7cd8e
SC
3857 /* only second byte has zero? */
3858 if (~(intval | 0xff00) == 0)
886c62d1
JVA
3859 {
3860 CC_STATUS_INIT;
3861
5bc7cd8e
SC
3862 intval = (intval >> 8) & 0xff;
3863 operands[2] = GEN_INT (intval);
3864 if (intval == 0)
886c62d1 3865 {
5bc7cd8e
SC
3866 if (REG_P (operands[0]))
3867 return AS2 (xor%B0,%h0,%h0);
3868 operands[0] = adj_offsettable_operand (operands[0], 1);
3869 return AS2 (mov%B0,%2,%b0);
886c62d1
JVA
3870 }
3871
5bc7cd8e
SC
3872 if (REG_P (operands[0]))
3873 return AS2 (and%B0,%2,%h0);
3874
3875 operands[0] = adj_offsettable_operand (operands[0], 1);
3876 return AS2 (and%B0,%2,%b0);
886c62d1
JVA
3877 }
3878
5bc7cd8e
SC
3879 if (REG_P (operands[0]))
3880 break;
3881
3882 /* third byte has zero bits? */
3883 if (~(intval | 0xff0000) == 0)
3884 {
3885 intval = (intval >> 16) & 0xff;
3886 operands[0] = adj_offsettable_operand (operands[0], 2);
3887byte_and_operation:
3888 CC_STATUS_INIT;
3889 operands[2] = GEN_INT (intval);
3890 if (intval == 0)
3891 return AS2 (mov%B0,%2,%b0);
3892 return AS2 (and%B0,%2,%b0);
3893 }
3894
3895 /* fourth byte has zero bits? */
3896 if (~(intval | 0xff000000) == 0)
3897 {
3898 intval = (intval >> 24) & 0xff;
3899 operands[0] = adj_offsettable_operand (operands[0], 3);
3900 goto byte_and_operation;
3901 }
3902
3903 /* Low word is zero? */
3904 if (intval == 0xffff0000)
886c62d1 3905 {
5bc7cd8e
SC
3906word_zero_and_operation:
3907 CC_STATUS_INIT;
886c62d1
JVA
3908 operands[2] = const0_rtx;
3909 return AS2 (mov%W0,%2,%w0);
3910 }
5bc7cd8e
SC
3911
3912 /* High word is zero? */
3913 if (intval == 0x0000ffff)
3914 {
3915 operands[0] = adj_offsettable_operand (operands[0], 2);
3916 goto word_zero_and_operation;
3917 }
4fce8e83
MH
3918
3919 default:
3920 break;
886c62d1
JVA
3921 }
3922
3923 return AS2 (and%L0,%2,%0);
a269a03c
JC
3924}"
3925 [(set_attr "type" "binary")])
886c62d1
JVA
3926
3927(define_insn "andhi3"
2ae0f82c
SC
3928 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3929 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
3930 (match_operand:HI 2 "general_operand" "ri,rm")))]
3931 ""
3932 "*
3933{
3934 if (GET_CODE (operands[2]) == CONST_INT
3935 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3936 {
3937 /* Can we ignore the upper byte? */
a199fdd6 3938 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
886c62d1
JVA
3939 && (INTVAL (operands[2]) & 0xff00) == 0xff00)
3940 {
3941 CC_STATUS_INIT;
3942
3943 if ((INTVAL (operands[2]) & 0xff) == 0)
3944 {
3945 operands[2] = const0_rtx;
3946 return AS2 (mov%B0,%2,%b0);
3947 }
3948
a199fdd6 3949 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
886c62d1
JVA
3950 return AS2 (and%B0,%2,%b0);
3951 }
3952
3953 /* Can we ignore the lower byte? */
3954 /* ??? what about offsettable memory references? */
3955 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
3956 {
3957 CC_STATUS_INIT;
3958
3959 if ((INTVAL (operands[2]) & 0xff00) == 0)
3960 {
3961 operands[2] = const0_rtx;
3962 return AS2 (mov%B0,%2,%h0);
3963 }
3964
a199fdd6 3965 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
886c62d1
JVA
3966 return AS2 (and%B0,%2,%h0);
3967 }
5bc7cd8e
SC
3968
3969 /* use 32-bit ops on registers when there are no sign issues.. */
3970 if (REG_P (operands[0]))
3971 {
3972 if (!(INTVAL (operands[2]) & ~0x7fff))
3973 return AS2 (and%L0,%2,%k0);
3974 }
3975 }
3976
3977 if (REG_P (operands[0])
3978 && i386_aligned_p (operands[2]))
3979 {
3980 CC_STATUS_INIT;
3981 /* If op[2] is constant, we should zero-extend it and */
3982 /* make a note that op[0] has been zero-extended, so */
3983 /* that we could use 32-bit ops on it forthwith, but */
3984 /* there is no such reg-note available. Instead we do */
3985 /* a sign extension as that can result in shorter asm */
3986 operands[2] = i386_sext16_if_const (operands[2]);
3987 return AS2 (and%L0,%k2,%k0);
3988 }
3989
3990 /* Use a 32-bit word with the upper bits set, invalidate CC */
3991 if (GET_CODE (operands[2]) == CONST_INT
3992 && i386_aligned_p (operands[0]))
3993 {
3994 HOST_WIDE_INT val = INTVAL (operands[2]);
3995 CC_STATUS_INIT;
3996 val |= ~0xffff;
3997 if (val != INTVAL (operands[2]))
3998 operands[2] = GEN_INT (val);
3999 return AS2 (and%L0,%k2,%k0);
886c62d1
JVA
4000 }
4001
4002 return AS2 (and%W0,%2,%0);
a269a03c
JC
4003}"
4004 [(set_attr "type" "binary")])
886c62d1
JVA
4005
4006(define_insn "andqi3"
2ae0f82c
SC
4007 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4008 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4009 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4010 ""
a269a03c
JC
4011 "* return AS2 (and%B0,%2,%0);"
4012 [(set_attr "type" "binary")])
886c62d1
JVA
4013
4014/* I am nervous about these two.. add them later..
4015;I presume this means that we have something in say op0= eax which is small
4016;and we want to and it with memory so we can do this by just an
4017;andb m,%al and have success.
4018(define_insn ""
4019 [(set (match_operand:SI 0 "general_operand" "=r")
4020 (and:SI (zero_extend:SI
4021 (match_operand:HI 1 "nonimmediate_operand" "rm"))
4022 (match_operand:SI 2 "general_operand" "0")))]
4023 "GET_CODE (operands[2]) == CONST_INT
4024 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
4025 "and%W0 %1,%0")
4026
4027(define_insn ""
2ae0f82c 4028 [(set (match_operand:SI 0 "register_operand" "=q")
886c62d1
JVA
4029 (and:SI
4030 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
2ae0f82c 4031 (match_operand:SI 2 "register_operand" "0")))]
886c62d1
JVA
4032 "GET_CODE (operands[2]) == CONST_INT
4033 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
4034 "and%L0 %1,%0")
4035
4036*/
4037\f
4038;;- Bit set (inclusive or) instructions
4039
5bc7cd8e
SC
4040;; This optimizes known byte-wide operations to memory, and in some cases
4041;; to QI registers.. Note that we don't want to use the QI registers too
4042;; aggressively, because often the 32-bit register instruction is the same
4043;; size, and likely to be faster on PentiumPro.
886c62d1 4044(define_insn "iorsi3"
2ae0f82c
SC
4045 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4046 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4047 (match_operand:SI 2 "general_operand" "ri,rm")))]
4048 ""
4049 "*
4050{
5bc7cd8e
SC
4051 HOST_WIDE_INT intval;
4052 switch (GET_CODE (operands[2]))
886c62d1 4053 {
5bc7cd8e 4054 case CONST_INT:
886c62d1 4055
5bc7cd8e
SC
4056 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4057 break;
4058
4059 /* don't try to optimize volatile accesses */
4060 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4061 break;
4062
4063 intval = INTVAL (operands[2]);
4064 if ((intval & ~0xff) == 0)
4065 {
4066 if (REG_P (operands[0]))
4067 {
4068 /* Do low byte access only for %eax or when high bit is set */
4069 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4070 break;
4071 }
886c62d1 4072
5bc7cd8e
SC
4073byte_or_operation:
4074 CC_STATUS_INIT;
4075
4076 if (intval != INTVAL (operands[2]))
4077 operands[2] = GEN_INT (intval);
4078
4079 if (intval == 0xff)
4080 return AS2 (mov%B0,%2,%b0);
4081
4082 return AS2 (or%B0,%2,%b0);
886c62d1
JVA
4083 }
4084
5bc7cd8e
SC
4085 /* second byte? */
4086 if ((intval & ~0xff00) == 0)
886c62d1 4087 {
5bc7cd8e 4088 intval >>= 8;
886c62d1 4089
5bc7cd8e
SC
4090 if (REG_P (operands[0]))
4091 {
4092 CC_STATUS_INIT;
4093 operands[2] = GEN_INT (intval);
4094 if (intval == 0xff)
4095 return AS2 (mov%B0,%2,%h0);
886c62d1 4096
5bc7cd8e
SC
4097 return AS2 (or%B0,%2,%h0);
4098 }
4099
4100 operands[0] = adj_offsettable_operand (operands[0], 1);
4101 goto byte_or_operation;
4102 }
4103
4104 if (REG_P (operands[0]))
4105 break;
4106
4107 /* third byte? */
4108 if ((intval & ~0xff0000) == 0)
4109 {
4110 intval >>= 16;
4111 operands[0] = adj_offsettable_operand (operands[0], 2);
4112 goto byte_or_operation;
4113 }
4114
4115 /* fourth byte? */
4116 if ((intval & ~0xff000000) == 0)
4117 {
4118 intval = (intval >> 24) & 0xff;
4119 operands[0] = adj_offsettable_operand (operands[0], 3);
4120 goto byte_or_operation;
886c62d1 4121 }
4fce8e83
MH
4122
4123 default:
4124 break;
886c62d1
JVA
4125 }
4126
4127 return AS2 (or%L0,%2,%0);
a269a03c
JC
4128}"
4129 [(set_attr "type" "binary")])
886c62d1
JVA
4130
4131(define_insn "iorhi3"
2ae0f82c
SC
4132 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4133 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4134 (match_operand:HI 2 "general_operand" "ri,rm")))]
4135 ""
4136 "*
4137{
5bc7cd8e
SC
4138 HOST_WIDE_INT intval;
4139 switch (GET_CODE (operands[2]))
886c62d1 4140 {
5bc7cd8e 4141 case CONST_INT:
886c62d1 4142
5bc7cd8e
SC
4143 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4144 break;
4145
4146 /* don't try to optimize volatile accesses */
4147 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4148 break;
4149
4150 intval = 0xffff & INTVAL (operands[2]);
4151
4152 if ((intval & 0xff00) == 0)
4153 {
4154 if (REG_P (operands[0]))
4155 {
4156 /* Do low byte access only for %eax or when high bit is set */
4157 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4158 break;
4159 }
4160
4161byte_or_operation:
4162 CC_STATUS_INIT;
4163
4164 if (intval == 0xff)
4165 return AS2 (mov%B0,%2,%b0);
886c62d1 4166
5bc7cd8e 4167 return AS2 (or%B0,%2,%b0);
886c62d1
JVA
4168 }
4169
5bc7cd8e
SC
4170 /* high byte? */
4171 if ((intval & 0xff) == 0)
886c62d1 4172 {
5bc7cd8e
SC
4173 intval >>= 8;
4174 operands[2] = GEN_INT (intval);
886c62d1 4175
5bc7cd8e
SC
4176 if (REG_P (operands[0]))
4177 {
4178 CC_STATUS_INIT;
4179 if (intval == 0xff)
4180 return AS2 (mov%B0,%2,%h0);
4181
4182 return AS2 (or%B0,%2,%h0);
4183 }
4184
4185 operands[0] = adj_offsettable_operand (operands[0], 1);
886c62d1 4186
5bc7cd8e 4187 goto byte_or_operation;
886c62d1 4188 }
4fce8e83
MH
4189
4190 default:
4191 break;
886c62d1
JVA
4192 }
4193
5bc7cd8e
SC
4194 if (REG_P (operands[0])
4195 && i386_aligned_p (operands[2]))
4196 {
4197 CC_STATUS_INIT;
4198 operands[2] = i386_sext16_if_const (operands[2]);
4199 return AS2 (or%L0,%k2,%k0);
4200 }
4201
4202 if (GET_CODE (operands[2]) == CONST_INT
4203 && i386_aligned_p (operands[0]))
4204 {
4205 CC_STATUS_INIT;
4206 intval = 0xffff & INTVAL (operands[2]);
4207 if (intval != INTVAL (operands[2]))
4208 operands[2] = GEN_INT (intval);
4209 return AS2 (or%L0,%2,%k0);
4210 }
4211
886c62d1 4212 return AS2 (or%W0,%2,%0);
a269a03c
JC
4213}"
4214 [(set_attr "type" "binary")])
886c62d1
JVA
4215
4216(define_insn "iorqi3"
2ae0f82c
SC
4217 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4218 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4219 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4220 ""
a269a03c
JC
4221 "* return AS2 (or%B0,%2,%0);"
4222 [(set_attr "type" "binary")])
886c62d1
JVA
4223\f
4224;;- xor instructions
4225
886c62d1 4226(define_insn "xorsi3"
2ae0f82c
SC
4227 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4228 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4229 (match_operand:SI 2 "general_operand" "ri,rm")))]
4230 ""
4231 "*
4232{
5bc7cd8e
SC
4233 HOST_WIDE_INT intval;
4234 switch (GET_CODE (operands[2]))
886c62d1 4235 {
5bc7cd8e 4236 case CONST_INT:
886c62d1 4237
5bc7cd8e
SC
4238 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4239 break;
886c62d1 4240
5bc7cd8e
SC
4241 /* don't try to optimize volatile accesses */
4242 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4243 break;
4244
4245 intval = INTVAL (operands[2]);
4246 if ((intval & ~0xff) == 0)
4247 {
4248 if (REG_P (operands[0]))
4249 {
4250 /* Do low byte access only for %eax or when high bit is set */
4251 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4252 break;
4253 }
4254
4255byte_xor_operation:
4256 CC_STATUS_INIT;
4257
4258 if (intval == 0xff)
4259 return AS1 (not%B0,%b0);
4260
4261 if (intval != INTVAL (operands[2]))
4262 operands[2] = GEN_INT (intval);
4263 return AS2 (xor%B0,%2,%b0);
886c62d1
JVA
4264 }
4265
5bc7cd8e
SC
4266 /* second byte? */
4267 if ((intval & ~0xff00) == 0)
886c62d1 4268 {
5bc7cd8e 4269 intval >>= 8;
886c62d1 4270
5bc7cd8e
SC
4271 if (REG_P (operands[0]))
4272 {
4273 CC_STATUS_INIT;
4274 if (intval == 0xff)
4275 return AS1 (not%B0,%h0);
886c62d1 4276
5bc7cd8e
SC
4277 operands[2] = GEN_INT (intval);
4278 return AS2 (xor%B0,%2,%h0);
4279 }
4280
4281 operands[0] = adj_offsettable_operand (operands[0], 1);
4282
4283 goto byte_xor_operation;
4284 }
4285
4286 if (REG_P (operands[0]))
4287 break;
4288
4289 /* third byte? */
4290 if ((intval & ~0xff0000) == 0)
4291 {
4292 intval >>= 16;
4293 operands[0] = adj_offsettable_operand (operands[0], 2);
4294 goto byte_xor_operation;
4295 }
4296
4297 /* fourth byte? */
4298 if ((intval & ~0xff000000) == 0)
4299 {
4300 intval = (intval >> 24) & 0xff;
4301 operands[0] = adj_offsettable_operand (operands[0], 3);
4302 goto byte_xor_operation;
886c62d1 4303 }
4fce8e83
MH
4304
4305 default:
4306 break;
886c62d1
JVA
4307 }
4308
4309 return AS2 (xor%L0,%2,%0);
a269a03c
JC
4310}"
4311 [(set_attr "type" "binary")])
886c62d1
JVA
4312
4313(define_insn "xorhi3"
2ae0f82c
SC
4314 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4315 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4316 (match_operand:HI 2 "general_operand" "ri,rm")))]
4317 ""
4318 "*
4319{
4320 if (GET_CODE (operands[2]) == CONST_INT
4321 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4322 {
4323 /* Can we ignore the upper byte? */
a199fdd6 4324 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
886c62d1
JVA
4325 && (INTVAL (operands[2]) & 0xff00) == 0)
4326 {
4327 CC_STATUS_INIT;
4328 if (INTVAL (operands[2]) & 0xffff0000)
a199fdd6 4329 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
886c62d1
JVA
4330
4331 if (INTVAL (operands[2]) == 0xff)
b4ac57ab 4332 return AS1 (not%B0,%b0);
886c62d1
JVA
4333
4334 return AS2 (xor%B0,%2,%b0);
4335 }
4336
4337 /* Can we ignore the lower byte? */
4338 /* ??? what about offsettable memory references? */
4339 if (QI_REG_P (operands[0])
4340 && (INTVAL (operands[2]) & 0xff) == 0)
4341 {
4342 CC_STATUS_INIT;
a199fdd6 4343 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
886c62d1
JVA
4344
4345 if (INTVAL (operands[2]) == 0xff)
4346 return AS1 (not%B0,%h0);
4347
4348 return AS2 (xor%B0,%2,%h0);
4349 }
4350 }
4351
5bc7cd8e
SC
4352 if (REG_P (operands[0])
4353 && i386_aligned_p (operands[2]))
4354 {
4355 CC_STATUS_INIT;
4356 operands[2] = i386_sext16_if_const (operands[2]);
4357 return AS2 (xor%L0,%k2,%k0);
4358 }
4359
4360 if (GET_CODE (operands[2]) == CONST_INT
4361 && i386_aligned_p (operands[0]))
4362 {
4363 HOST_WIDE_INT intval;
4364 CC_STATUS_INIT;
4365 intval = 0xffff & INTVAL (operands[2]);
4366 if (intval != INTVAL (operands[2]))
4367 operands[2] = GEN_INT (intval);
4368 return AS2 (xor%L0,%2,%k0);
4369 }
4370
886c62d1 4371 return AS2 (xor%W0,%2,%0);
a269a03c
JC
4372}"
4373 [(set_attr "type" "binary")])
886c62d1
JVA
4374
4375(define_insn "xorqi3"
2ae0f82c
SC
4376 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4377 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4378 (match_operand:QI 2 "general_operand" "qn,qm")))]
4379 ""
a269a03c
JC
4380 "* return AS2 (xor%B0,%2,%0);"
4381 [(set_attr "type" "binary")])
886c62d1 4382\f
57dbca5e
BS
4383;; logical operations for DImode
4384
57dbca5e 4385(define_insn "anddi3"
a269a03c
JC
4386 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4387 (and:DI (match_operand:DI 1 "general_operand" "0,0")
4388 (match_operand:DI 2 "general_operand" "oriF,riF")))]
57dbca5e 4389 ""
a269a03c
JC
4390 "#"
4391 [(set_attr "type" "binary")])
4392
57dbca5e
BS
4393
4394(define_insn "iordi3"
a269a03c
JC
4395 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4396 (ior:DI (match_operand:DI 1 "general_operand" "0,0")
4397 (match_operand:DI 2 "general_operand" "oriF,riF")))]
57dbca5e 4398 ""
a269a03c
JC
4399 "#"
4400 [(set_attr "type" "binary")])
4401
57dbca5e 4402(define_insn "xordi3"
a269a03c
JC
4403 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4404 (xor:DI (match_operand:DI 1 "general_operand" "0,0")
4405 (match_operand:DI 2 "general_operand" "oriF,riF")))]
57dbca5e 4406 ""
a269a03c
JC
4407 "#"
4408 [(set_attr "type" "binary")])
57dbca5e
BS
4409
4410(define_split
a269a03c
JC
4411 [(set (match_operand:DI 0 "general_operand" "")
4412 (match_operator:DI 3 "ix86_logical_operator"
4413 [(match_operand:DI 1 "general_operand" "")
4414 (match_operand:DI 2 "general_operand" "")]))]
4415 ""
4416 [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)]))
4417 (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))]
4418 "split_di (&operands[0], 1, &operands[4], &operands[5]);
4419 split_di (&operands[1], 1, &operands[6], &operands[7]);
4420 split_di (&operands[2], 1, &operands[8], &operands[9]);")
57dbca5e 4421
886c62d1
JVA
4422;;- negation instructions
4423
4424(define_insn "negdi2"
4425 [(set (match_operand:DI 0 "general_operand" "=&ro")
4426 (neg:DI (match_operand:DI 1 "general_operand" "0")))]
4427 ""
4428 "*
4429{
4430 rtx xops[2], low[1], high[1];
4431
4432 CC_STATUS_INIT;
4433
4434 split_di (operands, 1, low, high);
4435 xops[0] = const0_rtx;
4436 xops[1] = high[0];
4437
4438 output_asm_insn (AS1 (neg%L0,%0), low);
4439 output_asm_insn (AS2 (adc%L1,%0,%1), xops);
4440 output_asm_insn (AS1 (neg%L0,%0), high);
4441 RET;
4442}")
4443
4444(define_insn "negsi2"
2ae0f82c
SC
4445 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4446 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
886c62d1
JVA
4447 ""
4448 "neg%L0 %0")
4449
4450(define_insn "neghi2"
2ae0f82c
SC
4451 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4452 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
886c62d1
JVA
4453 ""
4454 "neg%W0 %0")
4455
4456(define_insn "negqi2"
2ae0f82c
SC
4457 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4458 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
886c62d1
JVA
4459 ""
4460 "neg%B0 %0")
4461
4462(define_insn "negsf2"
4463 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c 4464 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
886c62d1
JVA
4465 "TARGET_80387"
4466 "fchs")
4467
4468(define_insn "negdf2"
4469 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 4470 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
886c62d1
JVA
4471 "TARGET_80387"
4472 "fchs")
4473
4474(define_insn ""
4475 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 4476 (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
886c62d1
JVA
4477 "TARGET_80387"
4478 "fchs")
4fb21e90
JVA
4479
4480(define_insn "negxf2"
4481 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 4482 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
4fb21e90
JVA
4483 "TARGET_80387"
4484 "fchs")
4485
4486(define_insn ""
4487 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 4488 (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4fb21e90
JVA
4489 "TARGET_80387"
4490 "fchs")
886c62d1
JVA
4491\f
4492;; Absolute value instructions
4493
4494(define_insn "abssf2"
4495 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c 4496 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
886c62d1 4497 "TARGET_80387"
2ae0f82c
SC
4498 "fabs"
4499 [(set_attr "type" "fpop")])
886c62d1
JVA
4500
4501(define_insn "absdf2"
4502 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 4503 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
886c62d1 4504 "TARGET_80387"
2ae0f82c
SC
4505 "fabs"
4506 [(set_attr "type" "fpop")])
886c62d1
JVA
4507
4508(define_insn ""
4509 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 4510 (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
886c62d1 4511 "TARGET_80387"
2ae0f82c
SC
4512 "fabs"
4513 [(set_attr "type" "fpop")])
886c62d1 4514
4fb21e90
JVA
4515(define_insn "absxf2"
4516 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 4517 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
4fb21e90 4518 "TARGET_80387"
2ae0f82c
SC
4519 "fabs"
4520 [(set_attr "type" "fpop")])
4fb21e90
JVA
4521
4522(define_insn ""
4523 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 4524 (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4fb21e90 4525 "TARGET_80387"
2ae0f82c
SC
4526 "fabs"
4527 [(set_attr "type" "fpop")])
4fb21e90 4528
886c62d1
JVA
4529(define_insn "sqrtsf2"
4530 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c
SC
4531 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
4532 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
886c62d1
JVA
4533 "fsqrt")
4534
4535(define_insn "sqrtdf2"
4536 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 4537 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
157735e8
RK
4538 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4539 && (TARGET_IEEE_FP || flag_fast_math) "
886c62d1
JVA
4540 "fsqrt")
4541
4542(define_insn ""
4543 [(set (match_operand:DF 0 "register_operand" "=f")
4544 (sqrt:DF (float_extend:DF
2ae0f82c
SC
4545 (match_operand:SF 1 "register_operand" "0"))))]
4546 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
886c62d1 4547 "fsqrt")
a199fdd6 4548
4fb21e90
JVA
4549(define_insn "sqrtxf2"
4550 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 4551 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
157735e8
RK
4552 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4553 && (TARGET_IEEE_FP || flag_fast_math) "
4fb21e90
JVA
4554 "fsqrt")
4555
4556(define_insn ""
4557 [(set (match_operand:XF 0 "register_operand" "=f")
4558 (sqrt:XF (float_extend:XF
2ae0f82c
SC
4559 (match_operand:DF 1 "register_operand" "0"))))]
4560 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4fb21e90
JVA
4561 "fsqrt")
4562
4563(define_insn ""
4564 [(set (match_operand:XF 0 "register_operand" "=f")
4565 (sqrt:XF (float_extend:XF
2ae0f82c
SC
4566 (match_operand:SF 1 "register_operand" "0"))))]
4567 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4fb21e90
JVA
4568 "fsqrt")
4569
a199fdd6
JVA
4570(define_insn "sindf2"
4571 [(set (match_operand:DF 0 "register_operand" "=f")
4572 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
2ae0f82c 4573 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
a199fdd6
JVA
4574 "fsin")
4575
4576(define_insn "sinsf2"
4577 [(set (match_operand:SF 0 "register_operand" "=f")
4578 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
2ae0f82c 4579 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
a199fdd6
JVA
4580 "fsin")
4581
4582(define_insn ""
4583 [(set (match_operand:DF 0 "register_operand" "=f")
4584 (unspec:DF [(float_extend:DF
4585 (match_operand:SF 1 "register_operand" "0"))] 1))]
2ae0f82c 4586 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
a199fdd6
JVA
4587 "fsin")
4588
58733f96
MM
4589(define_insn "sinxf2"
4590 [(set (match_operand:XF 0 "register_operand" "=f")
4591 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
2ae0f82c 4592 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
58733f96
MM
4593 "fsin")
4594
a199fdd6
JVA
4595(define_insn "cosdf2"
4596 [(set (match_operand:DF 0 "register_operand" "=f")
4597 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
2ae0f82c 4598 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
a199fdd6
JVA
4599 "fcos")
4600
4601(define_insn "cossf2"
4602 [(set (match_operand:SF 0 "register_operand" "=f")
4603 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
2ae0f82c 4604 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
a199fdd6
JVA
4605 "fcos")
4606
4607(define_insn ""
4608 [(set (match_operand:DF 0 "register_operand" "=f")
4609 (unspec:DF [(float_extend:DF
4610 (match_operand:SF 1 "register_operand" "0"))] 2))]
2ae0f82c 4611 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
a199fdd6 4612 "fcos")
58733f96
MM
4613
4614(define_insn "cosxf2"
4615 [(set (match_operand:XF 0 "register_operand" "=f")
4616 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
2ae0f82c 4617 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
58733f96 4618 "fcos")
886c62d1
JVA
4619\f
4620;;- one complement instructions
4621
4622(define_insn "one_cmplsi2"
2ae0f82c
SC
4623 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4624 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
886c62d1
JVA
4625 ""
4626 "not%L0 %0")
4627
4628(define_insn "one_cmplhi2"
2ae0f82c
SC
4629 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4630 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
886c62d1
JVA
4631 ""
4632 "not%W0 %0")
4633
4634(define_insn "one_cmplqi2"
2ae0f82c
SC
4635 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4636 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
886c62d1
JVA
4637 ""
4638 "not%B0 %0")
4639\f
4640;;- arithmetic shift instructions
4641
4642;; DImode shifts are implemented using the i386 "shift double" opcode,
4643;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
4644;; is variable, then the count is in %cl and the "imm" operand is dropped
4645;; from the assembler input.
4646
4647;; This instruction shifts the target reg/mem as usual, but instead of
4648;; shifting in zeros, bits are shifted in from reg operand. If the insn
4649;; is a left shift double, bits are taken from the high order bits of
4650;; reg, else if the insn is a shift right double, bits are taken from the
4651;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
4652;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
4653
4654;; Since sh[lr]d does not change the `reg' operand, that is done
4655;; separately, making all shifts emit pairs of shift double and normal
4656;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
4657;; support a 63 bit shift, each shift where the count is in a reg expands
f58acb67 4658;; to a pair of shifts, a branch, a shift by 32 and a label.
886c62d1
JVA
4659
4660;; If the shift count is a constant, we need never emit more than one
4661;; shift pair, instead using moves and sign extension for counts greater
4662;; than 31.
4663
56c0e8fa
JVA
4664(define_expand "ashldi3"
4665 [(set (match_operand:DI 0 "register_operand" "")
4666 (ashift:DI (match_operand:DI 1 "register_operand" "")
4667 (match_operand:QI 2 "nonmemory_operand" "")))]
4668 ""
4669 "
4670{
10f4f53f 4671 if (GET_CODE (operands[2]) != CONST_INT
56c0e8fa
JVA
4672 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4673 {
4674 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4675 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
4676 operands[2]));
4677 }
4678 else
4679 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
4680
4681 DONE;
4682}")
4683
4684(define_insn "ashldi3_const_int"
4685 [(set (match_operand:DI 0 "register_operand" "=&r")
4686 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4687 (match_operand:QI 2 "const_int_operand" "J")))]
dd9f586e 4688 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
886c62d1
JVA
4689 "*
4690{
4691 rtx xops[4], low[1], high[1];
4692
4693 CC_STATUS_INIT;
4694
4695 split_di (operands, 1, low, high);
4696 xops[0] = operands[2];
4697 xops[1] = const1_rtx;
4698 xops[2] = low[0];
4699 xops[3] = high[0];
4700
56c0e8fa 4701 if (INTVAL (xops[0]) > 31)
886c62d1 4702 {
56c0e8fa
JVA
4703 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4704 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
886c62d1 4705
56c0e8fa
JVA
4706 if (INTVAL (xops[0]) > 32)
4707 {
a199fdd6 4708 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
56c0e8fa
JVA
4709 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
4710 }
4711 }
4712 else
4713 {
4714 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
886c62d1 4715 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
56c0e8fa
JVA
4716 }
4717 RET;
4718}")
886c62d1 4719
56c0e8fa
JVA
4720(define_insn "ashldi3_non_const_int"
4721 [(set (match_operand:DI 0 "register_operand" "=&r")
4722 (ashift:DI (match_operand:DI 1 "register_operand" "0")
f58acb67 4723 (match_operand:QI 2 "register_operand" "c")))]
56c0e8fa
JVA
4724 ""
4725 "*
4726{
270fc2ae 4727 rtx xops[5], low[1], high[1];
886c62d1 4728
56c0e8fa 4729 CC_STATUS_INIT;
886c62d1 4730
56c0e8fa
JVA
4731 split_di (operands, 1, low, high);
4732 xops[0] = operands[2];
f58acb67 4733 xops[1] = GEN_INT (32);
56c0e8fa
JVA
4734 xops[2] = low[0];
4735 xops[3] = high[0];
270fc2ae 4736 xops[4] = gen_label_rtx ();
886c62d1 4737
56c0e8fa
JVA
4738 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
4739 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
f58acb67 4740 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
270fc2ae 4741 output_asm_insn (AS1 (je,%X4), xops);
f58acb67
SC
4742 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4743 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
270fc2ae
JL
4744 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4745 CODE_LABEL_NUMBER (xops[4]));
886c62d1
JVA
4746 RET;
4747}")
4748
47f59fd4
JL
4749(define_expand "ashlsi3"
4750 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4751 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4752 (match_operand:SI 2 "nonmemory_operand" "")))]
4753 ""
4754 "")
4755
0a726ef1
JL
4756;; Pattern for shifts which can be encoded into an lea instruction.
4757;; This is kept as a separate pattern so that regmove can optimize cases
4758;; where we know the source and destination must match.
24883a4a 4759;;
0a726ef1
JL
4760;; Do not expose this pattern when optimizing for size since we never want
4761;; to use lea when optimizing for size since mov+sal is smaller than lea.
47f59fd4 4762(define_insn ""
0a726ef1 4763 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
24883a4a 4764 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
0a726ef1
JL
4765 (match_operand:SI 2 "small_shift_operand" "M,M")))]
4766 "! optimize_size"
4767 "* return output_ashlsi3 (operands);")
24883a4a 4768
0a726ef1
JL
4769;; Generic left shift pattern to catch all cases not handled by the
4770;; shift pattern above.
24883a4a 4771(define_insn ""
0a726ef1
JL
4772 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4773 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4774 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4775 ""
4776 "* return output_ashlsi3 (operands);")
886c62d1
JVA
4777
4778(define_insn "ashlhi3"
2ae0f82c
SC
4779 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4780 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
56c0e8fa 4781 (match_operand:HI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
4782 ""
4783 "*
4784{
4785 if (REG_P (operands[2]))
4786 return AS2 (sal%W0,%b2,%0);
4787
4788 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4789 return AS2 (add%W0,%0,%0);
4790
4791 return AS2 (sal%W0,%2,%0);
4792}")
4793
4794(define_insn "ashlqi3"
2ae0f82c
SC
4795 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4796 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
56c0e8fa 4797 (match_operand:QI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
4798 ""
4799 "*
4800{
4801 if (REG_P (operands[2]))
4802 return AS2 (sal%B0,%b2,%0);
4803
4804 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4805 return AS2 (add%B0,%0,%0);
4806
4807 return AS2 (sal%B0,%2,%0);
4808}")
4809
4810;; See comment above `ashldi3' about how this works.
4811
56c0e8fa
JVA
4812(define_expand "ashrdi3"
4813 [(set (match_operand:DI 0 "register_operand" "")
4814 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4815 (match_operand:QI 2 "nonmemory_operand" "")))]
4816 ""
4817 "
4818{
10f4f53f 4819 if (GET_CODE (operands[2]) != CONST_INT
56c0e8fa
JVA
4820 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4821 {
4822 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4823 emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
4824 operands[2]));
4825 }
4826 else
4827 emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
4828
4829 DONE;
4830}")
4831
2ae0f82c
SC
4832(define_insn "ashldi3_32"
4833 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4834 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
4835 (const_int 32)))]
4836 ""
4837 "*
4838{
4839 rtx low[2], high[2], xops[4];
4840
4841 split_di (operands, 2, low, high);
4842 xops[0] = high[0];
4843 xops[1] = low[1];
4844 xops[2] = low[0];
4845 xops[3] = const0_rtx;
4846 if (!rtx_equal_p (xops[0], xops[1]))
4847 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
4848
4849 if (GET_CODE (low[0]) == MEM)
4850 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4851 else
4852 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4853
4854 RET;
4855}")
4856
56c0e8fa
JVA
4857(define_insn "ashrdi3_const_int"
4858 [(set (match_operand:DI 0 "register_operand" "=&r")
4859 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
4860 (match_operand:QI 2 "const_int_operand" "J")))]
926b3fae 4861 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
886c62d1
JVA
4862 "*
4863{
56c0e8fa 4864 rtx xops[4], low[1], high[1];
886c62d1
JVA
4865
4866 CC_STATUS_INIT;
4867
4868 split_di (operands, 1, low, high);
4869 xops[0] = operands[2];
4870 xops[1] = const1_rtx;
4871 xops[2] = low[0];
4872 xops[3] = high[0];
4873
56c0e8fa 4874 if (INTVAL (xops[0]) > 31)
886c62d1 4875 {
a199fdd6 4876 xops[1] = GEN_INT (31);
56c0e8fa
JVA
4877 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4878 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
886c62d1 4879
56c0e8fa
JVA
4880 if (INTVAL (xops[0]) > 32)
4881 {
a199fdd6 4882 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
207f8358 4883 output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
56c0e8fa
JVA
4884 }
4885 }
4886 else
4887 {
4888 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
886c62d1 4889 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
56c0e8fa 4890 }
886c62d1 4891
56c0e8fa
JVA
4892 RET;
4893}")
886c62d1 4894
56c0e8fa
JVA
4895(define_insn "ashrdi3_non_const_int"
4896 [(set (match_operand:DI 0 "register_operand" "=&r")
4897 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
f58acb67 4898 (match_operand:QI 2 "register_operand" "c")))]
56c0e8fa
JVA
4899 ""
4900 "*
4901{
270fc2ae 4902 rtx xops[5], low[1], high[1];
886c62d1 4903
56c0e8fa 4904 CC_STATUS_INIT;
886c62d1 4905
56c0e8fa
JVA
4906 split_di (operands, 1, low, high);
4907 xops[0] = operands[2];
f58acb67 4908 xops[1] = GEN_INT (32);
56c0e8fa
JVA
4909 xops[2] = low[0];
4910 xops[3] = high[0];
270fc2ae 4911 xops[4] = gen_label_rtx ();
56c0e8fa 4912
56c0e8fa
JVA
4913 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
4914 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
f58acb67 4915 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
270fc2ae 4916 output_asm_insn (AS1 (je,%X4), xops);
f58acb67
SC
4917 xops[1] = GEN_INT (31);
4918 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4919 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
270fc2ae
JL
4920 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4921 CODE_LABEL_NUMBER (xops[4]));
886c62d1
JVA
4922 RET;
4923}")
4924
bb62e19a
JH
4925(define_insn "ashrsi3_31"
4926 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
4927 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
4928 (const_int 31)))]
4929 "!TARGET_PENTIUM || optimize_size"
4930 "@
4931 sar%L0 $31,%0
4932 cltd")
4933
886c62d1 4934(define_insn "ashrsi3"
2ae0f82c
SC
4935 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4936 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
56c0e8fa 4937 (match_operand:SI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
4938 ""
4939 "*
4940{
4941 if (REG_P (operands[2]))
4942 return AS2 (sar%L0,%b2,%0);
4943 else
4944 return AS2 (sar%L0,%2,%0);
4945}")
4946
4947(define_insn "ashrhi3"
2ae0f82c
SC
4948 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4949 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
56c0e8fa 4950 (match_operand:HI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
4951 ""
4952 "*
4953{
4954 if (REG_P (operands[2]))
4955 return AS2 (sar%W0,%b2,%0);
4956 else
4957 return AS2 (sar%W0,%2,%0);
4958}")
4959
4960(define_insn "ashrqi3"
2ae0f82c
SC
4961 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4962 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
56c0e8fa 4963 (match_operand:QI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
4964 ""
4965 "*
4966{
4967 if (REG_P (operands[2]))
4968 return AS2 (sar%B0,%b2,%0);
4969 else
4970 return AS2 (sar%B0,%2,%0);
4971}")
4972\f
4973;;- logical shift instructions
4974
4975;; See comment above `ashldi3' about how this works.
4976
56c0e8fa
JVA
4977(define_expand "lshrdi3"
4978 [(set (match_operand:DI 0 "register_operand" "")
4979 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4980 (match_operand:QI 2 "nonmemory_operand" "")))]
4981 ""
4982 "
4983{
10f4f53f 4984 if (GET_CODE (operands[2]) != CONST_INT
56c0e8fa
JVA
4985 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4986 {
4987 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4988 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
4989 operands[2]));
4990 }
4991 else
4992 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
4993
4994 DONE;
4995}")
4996
2ae0f82c
SC
4997(define_insn "lshrdi3_32"
4998 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4999 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5000 (const_int 32)))]
5001 ""
5002 "*
5003{
5004 rtx low[2], high[2], xops[4];
5005
5006 split_di (operands, 2, low, high);
5007 xops[0] = low[0];
5008 xops[1] = high[1];
5009 xops[2] = high[0];
5010 xops[3] = const0_rtx;
5011 if (!rtx_equal_p (xops[0], xops[1]))
5012 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5013
5014 if (GET_CODE (low[0]) == MEM)
5015 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5016 else
5017 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5018
5019 RET;
5020}")
5021
56c0e8fa
JVA
5022(define_insn "lshrdi3_const_int"
5023 [(set (match_operand:DI 0 "register_operand" "=&r")
5024 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5025 (match_operand:QI 2 "const_int_operand" "J")))]
926b3fae 5026 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
886c62d1
JVA
5027 "*
5028{
56c0e8fa 5029 rtx xops[4], low[1], high[1];
886c62d1
JVA
5030
5031 CC_STATUS_INIT;
5032
5033 split_di (operands, 1, low, high);
5034 xops[0] = operands[2];
5035 xops[1] = const1_rtx;
5036 xops[2] = low[0];
5037 xops[3] = high[0];
5038
56c0e8fa 5039 if (INTVAL (xops[0]) > 31)
886c62d1 5040 {
56c0e8fa
JVA
5041 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
5042 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
886c62d1 5043
56c0e8fa
JVA
5044 if (INTVAL (xops[0]) > 32)
5045 {
a199fdd6 5046 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
207f8358 5047 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
56c0e8fa
JVA
5048 }
5049 }
5050 else
5051 {
5052 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
886c62d1 5053 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
56c0e8fa 5054 }
886c62d1 5055
56c0e8fa
JVA
5056 RET;
5057}")
886c62d1 5058
56c0e8fa
JVA
5059(define_insn "lshrdi3_non_const_int"
5060 [(set (match_operand:DI 0 "register_operand" "=&r")
5061 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
f58acb67 5062 (match_operand:QI 2 "register_operand" "c")))]
56c0e8fa
JVA
5063 ""
5064 "*
5065{
270fc2ae 5066 rtx xops[5], low[1], high[1];
886c62d1 5067
56c0e8fa 5068 CC_STATUS_INIT;
886c62d1 5069
56c0e8fa
JVA
5070 split_di (operands, 1, low, high);
5071 xops[0] = operands[2];
f58acb67 5072 xops[1] = GEN_INT (32);
56c0e8fa
JVA
5073 xops[2] = low[0];
5074 xops[3] = high[0];
270fc2ae 5075 xops[4] = gen_label_rtx ();
56c0e8fa 5076
56c0e8fa
JVA
5077 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5078 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
f58acb67 5079 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
270fc2ae 5080 output_asm_insn (AS1 (je,%X4), xops);
f58acb67
SC
5081 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
5082 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
270fc2ae
JL
5083 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5084 CODE_LABEL_NUMBER (xops[4]));
886c62d1
JVA
5085 RET;
5086}")
5087
5088(define_insn "lshrsi3"
2ae0f82c
SC
5089 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5090 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
56c0e8fa 5091 (match_operand:SI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5092 ""
5093 "*
5094{
5095 if (REG_P (operands[2]))
5096 return AS2 (shr%L0,%b2,%0);
5097 else
5098 return AS2 (shr%L0,%2,%1);
5099}")
5100
5101(define_insn "lshrhi3"
2ae0f82c
SC
5102 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5103 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
56c0e8fa 5104 (match_operand:HI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5105 ""
5106 "*
5107{
5108 if (REG_P (operands[2]))
5109 return AS2 (shr%W0,%b2,%0);
5110 else
5111 return AS2 (shr%W0,%2,%0);
5112}")
5113
5114(define_insn "lshrqi3"
2ae0f82c
SC
5115 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5116 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
56c0e8fa 5117 (match_operand:QI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5118 ""
5119 "*
5120{
5121 if (REG_P (operands[2]))
5122 return AS2 (shr%B0,%b2,%0);
5123 else
5124 return AS2 (shr%B0,%2,%0);
5125}")
5126\f
5127;;- rotate instructions
5128
5129(define_insn "rotlsi3"
2ae0f82c
SC
5130 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5131 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
56c0e8fa 5132 (match_operand:SI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5133 ""
5134 "*
5135{
5136 if (REG_P (operands[2]))
5137 return AS2 (rol%L0,%b2,%0);
5138 else
5139 return AS2 (rol%L0,%2,%0);
5140}")
5141
5142(define_insn "rotlhi3"
2ae0f82c
SC
5143 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5144 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
56c0e8fa 5145 (match_operand:HI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5146 ""
5147 "*
5148{
5149 if (REG_P (operands[2]))
5150 return AS2 (rol%W0,%b2,%0);
5151 else
5152 return AS2 (rol%W0,%2,%0);
5153}")
5154
5155(define_insn "rotlqi3"
2ae0f82c
SC
5156 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5157 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
56c0e8fa 5158 (match_operand:QI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5159 ""
5160 "*
5161{
5162 if (REG_P (operands[2]))
5163 return AS2 (rol%B0,%b2,%0);
5164 else
5165 return AS2 (rol%B0,%2,%0);
5166}")
5167
5168(define_insn "rotrsi3"
2ae0f82c
SC
5169 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5170 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
56c0e8fa 5171 (match_operand:SI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5172 ""
5173 "*
5174{
5175 if (REG_P (operands[2]))
5176 return AS2 (ror%L0,%b2,%0);
5177 else
5178 return AS2 (ror%L0,%2,%0);
5179}")
5180
5181(define_insn "rotrhi3"
2ae0f82c
SC
5182 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5183 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
56c0e8fa 5184 (match_operand:HI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5185 ""
5186 "*
5187{
5188 if (REG_P (operands[2]))
5189 return AS2 (ror%W0,%b2,%0);
5190 else
5191 return AS2 (ror%W0,%2,%0);
5192}")
5193
5194(define_insn "rotrqi3"
2ae0f82c
SC
5195 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5196 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
56c0e8fa 5197 (match_operand:QI 2 "nonmemory_operand" "cI")))]
886c62d1
JVA
5198 ""
5199 "*
5200{
5201 if (REG_P (operands[2]))
5202 return AS2 (ror%B0,%b2,%0);
5203 else
5204 return AS2 (ror%B0,%2,%0);
5205}")
5206\f
5207/*
5208;; This usually looses. But try a define_expand to recognize a few case
5209;; we can do efficiently, such as accessing the "high" QImode registers,
5210;; %ah, %bh, %ch, %dh.
83199882
RK
5211;; ??? Note this has a botch on the mode of operand 0, which needs to be
5212;; fixed if this is ever enabled.
886c62d1
JVA
5213(define_insn "insv"
5214 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
2ae0f82c
SC
5215 (match_operand:SI 1 "immediate_operand" "i")
5216 (match_operand:SI 2 "immediate_operand" "i"))
5217 (match_operand:SI 3 "nonmemory_operand" "ri"))]
886c62d1
JVA
5218 ""
5219 "*
5220{
5221 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5222 abort ();
5223 if (GET_CODE (operands[3]) == CONST_INT)
5224 {
5225 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
a199fdd6 5226 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
886c62d1 5227 output_asm_insn (AS2 (and%L0,%1,%0), operands);
a199fdd6 5228 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
886c62d1
JVA
5229 output_asm_insn (AS2 (or%L0,%3,%0), operands);
5230 }
5231 else
5232 {
f64cecad 5233 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
886c62d1
JVA
5234 if (INTVAL (operands[2]))
5235 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5236 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
a199fdd6 5237 operands[2] = GEN_INT (BITS_PER_WORD
886c62d1
JVA
5238 - INTVAL (operands[1]) - INTVAL (operands[2]));
5239 if (INTVAL (operands[2]))
5240 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5241 }
5242 RET;
5243}")
5244*/
5245/*
5246;; ??? There are problems with the mode of operand[3]. The point of this
5247;; is to represent an HImode move to a "high byte" register.
5248
5249(define_expand "insv"
5250 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5251 (match_operand:SI 1 "immediate_operand" "")
5252 (match_operand:SI 2 "immediate_operand" ""))
2ae0f82c 5253 (match_operand:QI 3 "nonmemory_operand" "ri"))]
886c62d1
JVA
5254 ""
5255 "
5256{
5257 if (GET_CODE (operands[1]) != CONST_INT
5258 || GET_CODE (operands[2]) != CONST_INT)
5259 FAIL;
5260
5261 if (! (INTVAL (operands[1]) == 8
5262 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5263 && ! INTVAL (operands[1]) == 1)
5264 FAIL;
5265}")
0c055827 5266*/
886c62d1 5267
886c62d1
JVA
5268;; On i386, the register count for a bit operation is *not* truncated,
5269;; so SHIFT_COUNT_TRUNCATED must not be defined.
5270
5271;; On i486, the shift & or/and code is faster than bts or btr. If
5272;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5273
5274;; On i386, bts is a little faster if operands[0] is a reg, and a
5275;; little slower if operands[0] is a MEM, than the shift & or/and code.
5276;; Use bts & btr, since they reload better.
5277
5278;; General bit set and clear.
5279(define_insn ""
83199882 5280 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
886c62d1 5281 (const_int 1)
2ae0f82c 5282 (match_operand:SI 2 "register_operand" "r"))
56c0e8fa 5283 (match_operand:SI 3 "const_int_operand" "n"))]
628448b3 5284 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
886c62d1
JVA
5285 "*
5286{
5287 CC_STATUS_INIT;
5288
5289 if (INTVAL (operands[3]) == 1)
5290 return AS2 (bts%L0,%2,%0);
5291 else
5292 return AS2 (btr%L0,%2,%0);
5293}")
5294
5295;; Bit complement. See comments on previous pattern.
5296;; ??? Is this really worthwhile?
5297(define_insn ""
2ae0f82c 5298 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
886c62d1 5299 (xor:SI (ashift:SI (const_int 1)
2ae0f82c
SC
5300 (match_operand:SI 1 "register_operand" "r"))
5301 (match_operand:SI 2 "nonimmediate_operand" "0")))]
628448b3 5302 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
886c62d1
JVA
5303 "*
5304{
5305 CC_STATUS_INIT;
5306
5307 return AS2 (btc%L0,%1,%0);
5308}")
5309
886c62d1 5310(define_insn ""
2ae0f82c
SC
5311 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5312 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
47af5d50 5313 (ashift:SI (const_int 1)
2ae0f82c 5314 (match_operand:SI 2 "register_operand" "r"))))]
628448b3 5315 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
886c62d1
JVA
5316 "*
5317{
5318 CC_STATUS_INIT;
5319
47af5d50 5320 return AS2 (btc%L0,%2,%0);
886c62d1 5321}")
886c62d1
JVA
5322\f
5323;; Recognizers for bit-test instructions.
5324
5325;; The bt opcode allows a MEM in operands[0]. But on both i386 and
5326;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5327;; bt on the MEM directly.
5328
b4ac57ab
RS
5329;; ??? The first argument of a zero_extract must not be reloaded, so
5330;; don't allow a MEM in the operand predicate without allowing it in the
5331;; constraint.
5332
47af5d50
JVA
5333(define_insn ""
5334 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5335 (const_int 1)
2ae0f82c 5336 (match_operand:SI 1 "register_operand" "r")))]
47af5d50
JVA
5337 "GET_CODE (operands[1]) != CONST_INT"
5338 "*
5339{
5340 cc_status.flags |= CC_Z_IN_NOT_C;
5341 return AS2 (bt%L0,%1,%0);
5342}")
5343
5344(define_insn ""
5345 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5346 (match_operand:SI 1 "const_int_operand" "n")
5347 (match_operand:SI 2 "const_int_operand" "n")))]
5348 ""
5349 "*
5350{
5351 unsigned int mask;
5352
5353 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5354 operands[1] = GEN_INT (mask);
5355
5356 if (QI_REG_P (operands[0]))
5357 {
5358 if ((mask & ~0xff) == 0)
5359 {
5360 cc_status.flags |= CC_NOT_NEGATIVE;
5361 return AS2 (test%B0,%1,%b0);
5362 }
5363
5364 if ((mask & ~0xff00) == 0)
5365 {
5366 cc_status.flags |= CC_NOT_NEGATIVE;
5367 operands[1] = GEN_INT (mask >> 8);
5368 return AS2 (test%B0,%1,%h0);
5369 }
5370 }
5371
5372 return AS2 (test%L0,%1,%0);
5373}")
5374
a199fdd6 5375;; ??? All bets are off if operand 0 is a volatile MEM reference.
47af5d50 5376;; The CPU may access unspecified bytes around the actual target byte.
a199fdd6
JVA
5377
5378(define_insn ""
83199882 5379 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
a199fdd6
JVA
5380 (match_operand:SI 1 "const_int_operand" "n")
5381 (match_operand:SI 2 "const_int_operand" "n")))]
47af5d50 5382 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
a199fdd6
JVA
5383 "*
5384{
5385 unsigned int mask;
5386
5387 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5388 operands[1] = GEN_INT (mask);
5389
5390 if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
5391 {
a199fdd6
JVA
5392 if ((mask & ~0xff) == 0)
5393 {
5394 cc_status.flags |= CC_NOT_NEGATIVE;
5395 return AS2 (test%B0,%1,%b0);
5396 }
5397
5398 if ((mask & ~0xff00) == 0)
5399 {
5400 cc_status.flags |= CC_NOT_NEGATIVE;
5401 operands[1] = GEN_INT (mask >> 8);
5402
5403 if (QI_REG_P (operands[0]))
5404 return AS2 (test%B0,%1,%h0);
5405 else
5406 {
5407 operands[0] = adj_offsettable_operand (operands[0], 1);
5408 return AS2 (test%B0,%1,%b0);
5409 }
5410 }
5411
5412 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5413 {
5414 cc_status.flags |= CC_NOT_NEGATIVE;
5415 operands[1] = GEN_INT (mask >> 16);
5416 operands[0] = adj_offsettable_operand (operands[0], 2);
5417 return AS2 (test%B0,%1,%b0);
5418 }
5419
5420 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5421 {
5422 cc_status.flags |= CC_NOT_NEGATIVE;
5423 operands[1] = GEN_INT (mask >> 24);
5424 operands[0] = adj_offsettable_operand (operands[0], 3);
5425 return AS2 (test%B0,%1,%b0);
5426 }
5427 }
5428
5429 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5430 return AS2 (test%L0,%1,%0);
5431
5432 return AS2 (test%L1,%0,%1);
5433}")
886c62d1
JVA
5434\f
5435;; Store-flag instructions.
5436
c572e5ba
JVA
5437;; For all sCOND expanders, also expand the compare or test insn that
5438;; generates cc0. Generate an equality comparison if `seq' or `sne'.
5439
5440(define_expand "seq"
5441 [(match_dup 1)
afc2c5a7 5442 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5443 (eq:QI (cc0) (const_int 0)))]
5444 ""
5445 "
5446{
5447 if (TARGET_IEEE_FP
5448 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5449 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5450 else
5451 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5452}")
5453
c572e5ba
JVA
5454(define_expand "sne"
5455 [(match_dup 1)
afc2c5a7 5456 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5457 (ne:QI (cc0) (const_int 0)))]
5458 ""
5459 "
5460{
5461 if (TARGET_IEEE_FP
5462 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5463 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5464 else
5465 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5466}")
5467
c572e5ba
JVA
5468(define_expand "sgt"
5469 [(match_dup 1)
afc2c5a7 5470 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5471 (gt:QI (cc0) (const_int 0)))]
5472 ""
5473 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5474
c572e5ba
JVA
5475(define_expand "sgtu"
5476 [(match_dup 1)
afc2c5a7 5477 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5478 (gtu:QI (cc0) (const_int 0)))]
5479 ""
5480 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5481
c572e5ba
JVA
5482(define_expand "slt"
5483 [(match_dup 1)
afc2c5a7 5484 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5485 (lt:QI (cc0) (const_int 0)))]
5486 ""
5487 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5488
c572e5ba
JVA
5489(define_expand "sltu"
5490 [(match_dup 1)
afc2c5a7 5491 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5492 (ltu:QI (cc0) (const_int 0)))]
5493 ""
5494 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5495
c572e5ba
JVA
5496(define_expand "sge"
5497 [(match_dup 1)
afc2c5a7 5498 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5499 (ge:QI (cc0) (const_int 0)))]
5500 ""
5501 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5502
c572e5ba
JVA
5503(define_expand "sgeu"
5504 [(match_dup 1)
afc2c5a7 5505 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5506 (geu:QI (cc0) (const_int 0)))]
5507 ""
5508 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5509
c572e5ba
JVA
5510(define_expand "sle"
5511 [(match_dup 1)
afc2c5a7 5512 (set (match_operand:QI 0 "register_operand" "")
c572e5ba
JVA
5513 (le:QI (cc0) (const_int 0)))]
5514 ""
5515 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5516
c785c660
JVA
5517(define_expand "sleu"
5518 [(match_dup 1)
afc2c5a7 5519 (set (match_operand:QI 0 "register_operand" "")
c785c660
JVA
5520 (leu:QI (cc0) (const_int 0)))]
5521 ""
5522 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5523
a269a03c
JC
5524;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
5525;; not have any input reloads. A MEM write might need an input reload
5526;; for the address of the MEM. So don't allow MEM as the SET_DEST.
5527
5528(define_insn "*setcc"
5529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5530 (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))]
5531 "reload_completed || register_operand (operands[0], QImode)"
5532 "*
5533{
5534 enum rtx_code code = GET_CODE (operands[1]);
5535 if (cc_prev_status.flags & CC_TEST_AX)
5536 {
5537 int eq;
5538 HOST_WIDE_INT c;
5539 operands[2] = gen_rtx_REG (SImode, 0);
5540 switch (code)
5541 {
5542 case EQ:
5543 c = 0x4000;
5544 eq = 0;
5545 break;
5546 case NE:
5547 c = 0x4000;
5548 eq = 1;
5549 break;
5550 case GT:
5551 c = 0x4100;
5552 eq = 1;
5553 break;
5554 case LT:
5555 c = 0x100;
5556 eq = 0;
5557 break;
5558 case GE:
5559 c = 0x100;
5560 eq = 1;
5561 break;
5562 case LE:
5563 c = 0x4100;
5564 eq = 0;
5565 break;
5566 default:
5567 abort ();
5568 }
5569 operands[3] = GEN_INT (c);
5570 output_asm_insn (AS2 (testl,%3,%2), operands);
5571 return eq ? AS1 (sete,%0) : AS1 (setne, %0);
5572 }
5573
5574 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
5575 return (char *)0;
5576 return AS1(set%D1,%0);
5577}")
5578
886c62d1
JVA
5579\f
5580;; Basic conditional jump instructions.
5581;; We ignore the overflow flag for signed branch instructions.
5582
c572e5ba
JVA
5583;; For all bCOND expanders, also expand the compare or test insn that
5584;; generates cc0. Generate an equality comparison if `beq' or `bne'.
5585
5586(define_expand "beq"
5587 [(match_dup 1)
5588 (set (pc)
5589 (if_then_else (eq (cc0)
5590 (const_int 0))
5591 (label_ref (match_operand 0 "" ""))
5592 (pc)))]
5593 ""
5594 "
5595{
5596 if (TARGET_IEEE_FP
5597 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5598 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5599 else
5600 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5601}")
5602
c572e5ba
JVA
5603(define_expand "bne"
5604 [(match_dup 1)
5605 (set (pc)
5606 (if_then_else (ne (cc0)
5607 (const_int 0))
5608 (label_ref (match_operand 0 "" ""))
5609 (pc)))]
5610 ""
5611 "
5612{
5613 if (TARGET_IEEE_FP
5614 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5615 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5616 else
5617 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5618}")
5619
886c62d1 5620
c572e5ba
JVA
5621(define_expand "bgt"
5622 [(match_dup 1)
5623 (set (pc)
5624 (if_then_else (gt (cc0)
5625 (const_int 0))
5626 (label_ref (match_operand 0 "" ""))
5627 (pc)))]
5628 ""
5629 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5630
c572e5ba
JVA
5631(define_expand "bgtu"
5632 [(match_dup 1)
5633 (set (pc)
5634 (if_then_else (gtu (cc0)
5635 (const_int 0))
5636 (label_ref (match_operand 0 "" ""))
5637 (pc)))]
5638 ""
5639 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
886c62d1 5640
886c62d1 5641(define_expand "blt"
c572e5ba
JVA
5642 [(match_dup 1)
5643 (set (pc)
886c62d1
JVA
5644 (if_then_else (lt (cc0)
5645 (const_int 0))
5646 (label_ref (match_operand 0 "" ""))
5647 (pc)))]
5648 ""
c572e5ba 5649 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
886c62d1 5650
886c62d1 5651
c572e5ba
JVA
5652(define_expand "bltu"
5653 [(match_dup 1)
5654 (set (pc)
5655 (if_then_else (ltu (cc0)
5656 (const_int 0))
5657 (label_ref (match_operand 0 "" ""))
5658 (pc)))]
5659 ""
5660 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5661
c572e5ba
JVA
5662(define_expand "bge"
5663 [(match_dup 1)
5664 (set (pc)
5665 (if_then_else (ge (cc0)
5666 (const_int 0))
5667 (label_ref (match_operand 0 "" ""))
5668 (pc)))]
5669 ""
5670 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5671
c572e5ba
JVA
5672(define_expand "bgeu"
5673 [(match_dup 1)
5674 (set (pc)
5675 (if_then_else (geu (cc0)
5676 (const_int 0))
5677 (label_ref (match_operand 0 "" ""))
5678 (pc)))]
5679 ""
5680 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
886c62d1 5681
886c62d1 5682(define_expand "ble"
c572e5ba
JVA
5683 [(match_dup 1)
5684 (set (pc)
886c62d1
JVA
5685 (if_then_else (le (cc0)
5686 (const_int 0))
5687 (label_ref (match_operand 0 "" ""))
5688 (pc)))]
5689 ""
c572e5ba 5690 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
886c62d1 5691
c572e5ba
JVA
5692(define_expand "bleu"
5693 [(match_dup 1)
5694 (set (pc)
5695 (if_then_else (leu (cc0)
5696 (const_int 0))
5697 (label_ref (match_operand 0 "" ""))
5698 (pc)))]
5699 ""
5700 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
886c62d1 5701
c572e5ba 5702(define_insn ""
886c62d1 5703 [(set (pc)
a269a03c
JC
5704 (if_then_else (match_operator 0 "comparison_operator"
5705 [(cc0) (const_int 0)])
5706 (label_ref (match_operand 1 "" ""))
886c62d1
JVA
5707 (pc)))]
5708 ""
886c62d1
JVA
5709 "*
5710{
a269a03c 5711 enum rtx_code code = GET_CODE (operands[0]);
2ae0f82c
SC
5712 if (cc_prev_status.flags & CC_TEST_AX)
5713 {
a269a03c
JC
5714 int eq;
5715 HOST_WIDE_INT c;
5716 operands[2] = gen_rtx_REG (SImode, 0);
5717 switch (code)
5718 {
5719 case EQ:
5720 c = 0x4000;
5721 eq = 0;
5722 break;
5723 case NE:
5724 c = 0x4000;
5725 eq = 1;
5726 break;
5727 case GT:
5728 c = 0x4100;
5729 eq = 1;
5730 break;
5731 case LT:
5732 c = 0x100;
5733 eq = 0;
5734 break;
5735 case GE:
5736 c = 0x100;
5737 eq = 1;
5738 break;
5739 case LE:
5740 c = 0x4100;
5741 eq = 0;
5742 break;
5743 default:
5744 abort ();
5745 }
5746 operands[3] = GEN_INT (c);
5747 output_asm_insn (AS2 (testl,%3,%2), operands);
5748 return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
2ae0f82c 5749 }
a269a03c
JC
5750 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
5751 return (char *)0;
c572e5ba 5752
a269a03c 5753 return AS1(j%D0,%l1);
c572e5ba 5754}")
886c62d1
JVA
5755
5756(define_insn ""
5757 [(set (pc)
a269a03c
JC
5758 (if_then_else (match_operator 0 "comparison_operator"
5759 [(cc0) (const_int 0)])
886c62d1 5760 (pc)
a269a03c 5761 (label_ref (match_operand 1 "" ""))))]
886c62d1 5762 ""
c572e5ba
JVA
5763 "*
5764{
a269a03c 5765 enum rtx_code code = GET_CODE (operands[0]);
2ae0f82c
SC
5766 if (cc_prev_status.flags & CC_TEST_AX)
5767 {
a269a03c
JC
5768 int eq;
5769 HOST_WIDE_INT c;
5770 operands[2] = gen_rtx_REG (SImode, 0);
5771 switch (code)
5772 {
5773 case EQ:
5774 c = 0x4000;
5775 eq = 1;
5776 break;
5777 case NE:
5778 c = 0x4000;
5779 eq = 0;
5780 break;
5781 case GT:
5782 c = 0x4100;
5783 eq = 0;
5784 break;
5785 case LT:
5786 c = 0x100;
5787 eq = 1;
5788 break;
5789 case GE:
5790 c = 0x100;
5791 eq = 0;
5792 break;
5793 case LE:
5794 c = 0x4100;
5795 eq = 1;
5796 break;
5797 default:
5798 abort ();
5799 }
5800 operands[3] = GEN_INT (c);
5801 output_asm_insn (AS2 (testl,%3,%2), operands);
5802 return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
2ae0f82c 5803 }
a269a03c
JC
5804 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
5805 return (char *)0;
c572e5ba 5806
a269a03c 5807 return AS1(j%d0,%l1);
c572e5ba 5808}")
886c62d1
JVA
5809\f
5810;; Unconditional and other jump instructions
5811
5812(define_insn "jump"
5813 [(set (pc)
5814 (label_ref (match_operand 0 "" "")))]
5815 ""
90aec2cf
JL
5816 "jmp %l0"
5817 [(set_attr "memory" "none")])
886c62d1
JVA
5818
5819(define_insn "indirect_jump"
2ae0f82c 5820 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
886c62d1
JVA
5821 ""
5822 "*
5823{
5824 CC_STATUS_INIT;
5825
5826 return AS1 (jmp,%*%0);
90aec2cf
JL
5827}"
5828 [(set_attr "memory" "none")])
886c62d1 5829
63835b87
RK
5830;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
5831;; if S does not change i
5832
b08de47e
MM
5833(define_expand "decrement_and_branch_until_zero"
5834 [(parallel [(set (pc)
5835 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
5836 (const_int -1))
5837 (const_int 0))
5838 (label_ref (match_operand 1 "" ""))
5839 (pc)))
5840 (set (match_dup 0)
5841 (plus:SI (match_dup 0)
5842 (const_int -1)))])]
5843 ""
5844 "")
5845
5846(define_insn ""
5847 [(set (pc)
63835b87 5848 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
a269a03c 5849 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m")
b08de47e
MM
5850 (match_operand:SI 2 "general_operand" "rmi,ri"))
5851 (const_int 0)])
5852 (label_ref (match_operand 3 "" ""))
5853 (pc)))
5854 (set (match_dup 1)
5855 (plus:SI (match_dup 1)
5856 (match_dup 2)))]
5857 ""
5858 "*
5859{
5860 CC_STATUS_INIT;
a269a03c
JC
5861
5862 if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 &&
5863 operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6)
5864 return \"loop %l3\";
5865
b08de47e
MM
5866 if (operands[2] == constm1_rtx)
5867 output_asm_insn (AS1 (dec%L1,%1), operands);
5868
f647b9f2 5869 else if (operands[2] == const1_rtx)
b08de47e
MM
5870 output_asm_insn (AS1 (inc%L1,%1), operands);
5871
5872 else
5873 output_asm_insn (AS2 (add%L1,%2,%1), operands);
5874
5875 return AS1 (%J0,%l3);
5876}")
5877
5878(define_insn ""
5879 [(set (pc)
63835b87 5880 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
2ae0f82c 5881 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
b08de47e
MM
5882 (match_operand:SI 2 "general_operand" "rmi,ri"))
5883 (const_int 0)])
5884 (label_ref (match_operand 3 "" ""))
5885 (pc)))
5886 (set (match_dup 1)
5887 (minus:SI (match_dup 1)
5888 (match_dup 2)))]
5889 ""
5890 "*
5891{
5892 CC_STATUS_INIT;
5893 if (operands[2] == const1_rtx)
5894 output_asm_insn (AS1 (dec%L1,%1), operands);
5895
5896 else if (operands[1] == constm1_rtx)
5897 output_asm_insn (AS1 (inc%L1,%1), operands);
5898
5899 else
5900 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
5901
5902 return AS1 (%J0,%l3);
5903}")
5904
4801403e
TG
5905(define_insn ""
5906 [(set (pc)
c346547a 5907 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
4801403e
TG
5908 (const_int 0))
5909 (label_ref (match_operand 1 "" ""))
5910 (pc)))
5911 (set (match_dup 0)
5912 (plus:SI (match_dup 0)
5913 (const_int -1)))]
5914 ""
5915 "*
5916{
3cd3e833 5917 CC_STATUS_INIT;
4801403e
TG
5918 operands[2] = const1_rtx;
5919 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
5920 return \"jnc %l1\";
5921}")
5922
5923(define_insn ""
5924 [(set (pc)
c346547a 5925 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
4801403e
TG
5926 (const_int 0))
5927 (label_ref (match_operand 1 "" ""))
5928 (pc)))
5929 (set (match_dup 0)
5930 (plus:SI (match_dup 0)
5931 (const_int -1)))]
5932 ""
5933 "*
5934{
3cd3e833 5935 CC_STATUS_INIT;
4801403e
TG
5936 operands[2] = const1_rtx;
5937 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
5938 return \"jc %l1\";
5939}")
5940
5e645e50
TG
5941(define_insn ""
5942 [(set (pc)
c346547a 5943 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
5e645e50
TG
5944 (const_int 1))
5945 (label_ref (match_operand 1 "" ""))
5946 (pc)))
5947 (set (match_dup 0)
5948 (plus:SI (match_dup 0)
5949 (const_int -1)))]
5950 ""
5951 "*
5952{
3cd3e833 5953 CC_STATUS_INIT;
5e645e50
TG
5954 output_asm_insn (AS1 (dec%L0,%0), operands);
5955 return \"jnz %l1\";
5956}")
5957
5958(define_insn ""
5959 [(set (pc)
c346547a 5960 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
5e645e50
TG
5961 (const_int 1))
5962 (label_ref (match_operand 1 "" ""))
5963 (pc)))
5964 (set (match_dup 0)
5965 (plus:SI (match_dup 0)
5966 (const_int -1)))]
5967 ""
5968 "*
5969{
3cd3e833 5970 CC_STATUS_INIT;
5e645e50
TG
5971 output_asm_insn (AS1 (dec%L0,%0), operands);
5972 return \"jz %l1\";
5973}")
5974
4801403e
TG
5975(define_insn ""
5976 [(set (pc)
c346547a 5977 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
ed9a2f57 5978 (const_int -1))
4801403e
TG
5979 (label_ref (match_operand 1 "" ""))
5980 (pc)))
5981 (set (match_dup 0)
5982 (plus:SI (match_dup 0)
5983 (const_int 1)))]
5984 ""
5985 "*
5986{
3cd3e833 5987 CC_STATUS_INIT;
5e645e50
TG
5988 output_asm_insn (AS1 (inc%L0,%0), operands);
5989 return \"jnz %l1\";
4801403e
TG
5990}")
5991
5992(define_insn ""
5993 [(set (pc)
c346547a 5994 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
ed9a2f57 5995 (const_int -1))
4801403e
TG
5996 (label_ref (match_operand 1 "" ""))
5997 (pc)))
5998 (set (match_dup 0)
5999 (plus:SI (match_dup 0)
6000 (const_int 1)))]
6001 ""
6002 "*
6003{
3cd3e833 6004 CC_STATUS_INIT;
5e645e50
TG
6005 output_asm_insn (AS1 (inc%L0,%0), operands);
6006 return \"jz %l1\";
4801403e
TG
6007}")
6008
2bb7a0f5
RS
6009;; Implement switch statements when generating PIC code. Switches are
6010;; implemented by `tablejump' when not using -fpic.
6011
6012;; Emit code here to do the range checking and make the index zero based.
6013
6014(define_expand "casesi"
b4ac57ab 6015 [(set (match_dup 5)
7e10a919
SC
6016 (match_operand:SI 0 "general_operand" ""))
6017 (set (match_dup 6)
6018 (minus:SI (match_dup 5)
b4ac57ab
RS
6019 (match_operand:SI 1 "general_operand" "")))
6020 (set (cc0)
7e10a919 6021 (compare:CC (match_dup 6)
c572e5ba 6022 (match_operand:SI 2 "general_operand" "")))
b4ac57ab
RS
6023 (set (pc)
6024 (if_then_else (gtu (cc0)
6025 (const_int 0))
6026 (label_ref (match_operand 4 "" ""))
6027 (pc)))
6028 (parallel
2bb7a0f5 6029 [(set (pc)
b4ac57ab 6030 (minus:SI (reg:SI 3)
7e10a919 6031 (mem:SI (plus:SI (mult:SI (match_dup 6)
b4ac57ab
RS
6032 (const_int 4))
6033 (label_ref (match_operand 3 "" ""))))))
7e10a919 6034 (clobber (match_scratch:SI 7 ""))])]
2bb7a0f5
RS
6035 "flag_pic"
6036 "
6037{
b4ac57ab 6038 operands[5] = gen_reg_rtx (SImode);
7e10a919 6039 operands[6] = gen_reg_rtx (SImode);
2bb7a0f5 6040 current_function_uses_pic_offset_table = 1;
2bb7a0f5
RS
6041}")
6042
6043;; Implement a casesi insn.
6044
6045;; Each entry in the "addr_diff_vec" looks like this as the result of the
6046;; two rules below:
6047;;
6048;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6049;;
6050;; 1. An expression involving an external reference may only use the
6051;; addition operator, and only with an assembly-time constant.
6052;; The example above satisfies this because ".-.L2" is a constant.
6053;;
6054;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6055;; given the value of "GOT - .", where GOT is the actual address of
6056;; the Global Offset Table. Therefore, the .long above actually
6057;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
6058;; expression "GOT - .L2" by itself would generate an error from as(1).
6059;;
6060;; The pattern below emits code that looks like this:
6061;;
6062;; movl %ebx,reg
6063;; subl TABLE@GOTOFF(%ebx,index,4),reg
6064;; jmp reg
6065;;
6066;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6067;; the addr_diff_vec is known to be part of this module.
6068;;
6069;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6070;; evaluates to just ".L2".
6071
6072(define_insn ""
6073 [(set (pc)
b4ac57ab
RS
6074 (minus:SI (reg:SI 3)
6075 (mem:SI (plus:SI
6076 (mult:SI (match_operand:SI 0 "register_operand" "r")
6077 (const_int 4))
6078 (label_ref (match_operand 1 "" ""))))))
6079 (clobber (match_scratch:SI 2 "=&r"))]
2bb7a0f5
RS
6080 ""
6081 "*
6082{
6083 rtx xops[4];
6084
b4ac57ab
RS
6085 xops[0] = operands[0];
6086 xops[1] = operands[1];
6087 xops[2] = operands[2];
6088 xops[3] = pic_offset_table_rtx;
2bb7a0f5 6089
b4ac57ab
RS
6090 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
6091 output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
6092 output_asm_insn (AS1 (jmp,%*%2), xops);
fc470718 6093 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
2bb7a0f5
RS
6094 RET;
6095}")
6096
886c62d1 6097(define_insn "tablejump"
2ae0f82c 6098 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
886c62d1
JVA
6099 (use (label_ref (match_operand 1 "" "")))]
6100 ""
6101 "*
6102{
6103 CC_STATUS_INIT;
6104
6105 return AS1 (jmp,%*%0);
6106}")
6107
2bb7a0f5
RS
6108;; Call insns.
6109
6110;; If generating PIC code, the predicate indirect_operand will fail
6111;; for operands[0] containing symbolic references on all of the named
6112;; call* patterns. Each named pattern is followed by an unnamed pattern
6113;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
6114;; unnamed patterns are only used while generating PIC code, because
6115;; otherwise the named patterns match.
6116
886c62d1
JVA
6117;; Call subroutine returning no value.
6118
2bb7a0f5
RS
6119(define_expand "call_pop"
6120 [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
6121 (match_operand:SI 1 "general_operand" ""))
6122 (set (reg:SI 7)
6123 (plus:SI (reg:SI 7)
6124 (match_operand:SI 3 "immediate_operand" "")))])]
6125 ""
6126 "
6127{
c2177307
MM
6128 rtx addr;
6129
35e2d030
RH
6130 if (operands[3] == const0_rtx)
6131 {
6132 emit_insn (gen_call (operands[0], operands[1]));
6133 DONE;
6134 }
6135
2bb7a0f5
RS
6136 if (flag_pic)
6137 current_function_uses_pic_offset_table = 1;
c2177307
MM
6138
6139 /* With half-pic, force the address into a register. */
6140 addr = XEXP (operands[0], 0);
6141 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6142 XEXP (operands[0], 0) = force_reg (Pmode, addr);
387dc8a8 6143
0eb60d83 6144 if (! expander_call_insn_operand (operands[0], QImode))
387dc8a8
RS
6145 operands[0]
6146 = change_address (operands[0], VOIDmode,
6147 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2bb7a0f5
RS
6148}")
6149
6150(define_insn ""
387dc8a8 6151 [(call (match_operand:QI 0 "call_insn_operand" "m")
886c62d1
JVA
6152 (match_operand:SI 1 "general_operand" "g"))
6153 (set (reg:SI 7) (plus:SI (reg:SI 7)
6154 (match_operand:SI 3 "immediate_operand" "i")))]
6155 ""
6156 "*
6157{
6158 if (GET_CODE (operands[0]) == MEM
6159 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6160 {
6161 operands[0] = XEXP (operands[0], 0);
6162 return AS1 (call,%*%0);
6163 }
6164 else
6165 return AS1 (call,%P0);
6166}")
6167
2bb7a0f5
RS
6168(define_insn ""
6169 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6170 (match_operand:SI 1 "general_operand" "g"))
6171 (set (reg:SI 7) (plus:SI (reg:SI 7)
6172 (match_operand:SI 3 "immediate_operand" "i")))]
c2177307 6173 "!HALF_PIC_P ()"
2bb7a0f5
RS
6174 "call %P0")
6175
6176(define_expand "call"
6177 [(call (match_operand:QI 0 "indirect_operand" "")
6178 (match_operand:SI 1 "general_operand" ""))]
6179 ;; Operand 1 not used on the i386.
6180 ""
6181 "
6182{
c2177307
MM
6183 rtx addr;
6184
2bb7a0f5
RS
6185 if (flag_pic)
6186 current_function_uses_pic_offset_table = 1;
c2177307
MM
6187
6188 /* With half-pic, force the address into a register. */
6189 addr = XEXP (operands[0], 0);
6190 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6191 XEXP (operands[0], 0) = force_reg (Pmode, addr);
387dc8a8 6192
0eb60d83 6193 if (! expander_call_insn_operand (operands[0], QImode))
387dc8a8
RS
6194 operands[0]
6195 = change_address (operands[0], VOIDmode,
6196 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2bb7a0f5
RS
6197}")
6198
6199(define_insn ""
387dc8a8 6200 [(call (match_operand:QI 0 "call_insn_operand" "m")
886c62d1
JVA
6201 (match_operand:SI 1 "general_operand" "g"))]
6202 ;; Operand 1 not used on the i386.
6203 ""
6204 "*
6205{
6206 if (GET_CODE (operands[0]) == MEM
6207 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6208 {
6209 operands[0] = XEXP (operands[0], 0);
6210 return AS1 (call,%*%0);
6211 }
6212 else
6213 return AS1 (call,%P0);
6214}")
6215
2bb7a0f5
RS
6216(define_insn ""
6217 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6218 (match_operand:SI 1 "general_operand" "g"))]
6219 ;; Operand 1 not used on the i386.
c2177307 6220 "!HALF_PIC_P ()"
2bb7a0f5
RS
6221 "call %P0")
6222
886c62d1
JVA
6223;; Call subroutine, returning value in operand 0
6224;; (which must be a hard register).
6225
2bb7a0f5
RS
6226(define_expand "call_value_pop"
6227 [(parallel [(set (match_operand 0 "" "")
6228 (call (match_operand:QI 1 "indirect_operand" "")
6229 (match_operand:SI 2 "general_operand" "")))
6230 (set (reg:SI 7)
6231 (plus:SI (reg:SI 7)
6232 (match_operand:SI 4 "immediate_operand" "")))])]
6233 ""
6234 "
6235{
c2177307
MM
6236 rtx addr;
6237
35e2d030
RH
6238 if (operands[4] == const0_rtx)
6239 {
6240 emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
6241 DONE;
6242 }
6243
2bb7a0f5
RS
6244 if (flag_pic)
6245 current_function_uses_pic_offset_table = 1;
c2177307
MM
6246
6247 /* With half-pic, force the address into a register. */
6248 addr = XEXP (operands[1], 0);
6249 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6250 XEXP (operands[1], 0) = force_reg (Pmode, addr);
387dc8a8 6251
0eb60d83 6252 if (! expander_call_insn_operand (operands[1], QImode))
387dc8a8
RS
6253 operands[1]
6254 = change_address (operands[1], VOIDmode,
6255 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2bb7a0f5
RS
6256}")
6257
6258(define_insn ""
886c62d1 6259 [(set (match_operand 0 "" "=rf")
387dc8a8 6260 (call (match_operand:QI 1 "call_insn_operand" "m")
886c62d1
JVA
6261 (match_operand:SI 2 "general_operand" "g")))
6262 (set (reg:SI 7) (plus:SI (reg:SI 7)
6263 (match_operand:SI 4 "immediate_operand" "i")))]
6264 ""
6265 "*
6266{
6267 if (GET_CODE (operands[1]) == MEM
6268 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6269 {
6270 operands[1] = XEXP (operands[1], 0);
6271 output_asm_insn (AS1 (call,%*%1), operands);
6272 }
6273 else
6274 output_asm_insn (AS1 (call,%P1), operands);
6275
6276 RET;
6277}")
6278
2bb7a0f5
RS
6279(define_insn ""
6280 [(set (match_operand 0 "" "=rf")
6281 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6282 (match_operand:SI 2 "general_operand" "g")))
6283 (set (reg:SI 7) (plus:SI (reg:SI 7)
6284 (match_operand:SI 4 "immediate_operand" "i")))]
c2177307 6285 "!HALF_PIC_P ()"
2bb7a0f5
RS
6286 "call %P1")
6287
6288(define_expand "call_value"
6289 [(set (match_operand 0 "" "")
6290 (call (match_operand:QI 1 "indirect_operand" "")
6291 (match_operand:SI 2 "general_operand" "")))]
6292 ;; Operand 2 not used on the i386.
6293 ""
6294 "
6295{
c2177307
MM
6296 rtx addr;
6297
2bb7a0f5
RS
6298 if (flag_pic)
6299 current_function_uses_pic_offset_table = 1;
c2177307
MM
6300
6301 /* With half-pic, force the address into a register. */
6302 addr = XEXP (operands[1], 0);
6303 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6304 XEXP (operands[1], 0) = force_reg (Pmode, addr);
387dc8a8 6305
0eb60d83 6306 if (! expander_call_insn_operand (operands[1], QImode))
387dc8a8
RS
6307 operands[1]
6308 = change_address (operands[1], VOIDmode,
6309 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2bb7a0f5
RS
6310}")
6311
6312(define_insn ""
886c62d1 6313 [(set (match_operand 0 "" "=rf")
387dc8a8 6314 (call (match_operand:QI 1 "call_insn_operand" "m")
886c62d1
JVA
6315 (match_operand:SI 2 "general_operand" "g")))]
6316 ;; Operand 2 not used on the i386.
6317 ""
6318 "*
6319{
6320 if (GET_CODE (operands[1]) == MEM
6321 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6322 {
6323 operands[1] = XEXP (operands[1], 0);
6324 output_asm_insn (AS1 (call,%*%1), operands);
6325 }
6326 else
6327 output_asm_insn (AS1 (call,%P1), operands);
6328
6329 RET;
6330}")
6331
2bb7a0f5
RS
6332(define_insn ""
6333 [(set (match_operand 0 "" "=rf")
6334 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6335 (match_operand:SI 2 "general_operand" "g")))]
6336 ;; Operand 2 not used on the i386.
c2177307 6337 "!HALF_PIC_P ()"
2bb7a0f5
RS
6338 "call %P1")
6339
b840bfb0
MM
6340;; Call subroutine returning any type.
6341
576182a3 6342(define_expand "untyped_call"
b840bfb0 6343 [(parallel [(call (match_operand 0 "" "")
576182a3 6344 (const_int 0))
b840bfb0 6345 (match_operand 1 "" "")
576182a3
TW
6346 (match_operand 2 "" "")])]
6347 ""
6348 "
6349{
b840bfb0 6350 int i;
576182a3 6351
d8b679b9
RK
6352 /* In order to give reg-stack an easier job in validating two
6353 coprocessor registers as containing a possible return value,
6354 simply pretend the untyped call returns a complex long double
6355 value. */
74775c7a 6356
d8b679b9 6357 emit_call_insn (TARGET_80387
f64cecad
JC
6358 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6359 operands[0], const0_rtx)
d8b679b9 6360 : gen_call (operands[0], const0_rtx));
576182a3 6361
b840bfb0 6362 for (i = 0; i < XVECLEN (operands[2], 0); i++)
576182a3 6363 {
b840bfb0
MM
6364 rtx set = XVECEXP (operands[2], 0, i);
6365 emit_move_insn (SET_DEST (set), SET_SRC (set));
576182a3 6366 }
576182a3 6367
b840bfb0
MM
6368 /* The optimizer does not know that the call sets the function value
6369 registers we stored in the result block. We avoid problems by
6370 claiming that all hard registers are used and clobbered at this
6371 point. */
6372 emit_insn (gen_blockage ());
576182a3
TW
6373
6374 DONE;
6375}")
6376
b840bfb0
MM
6377;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6378;; all of memory. This blocks insns from being moved across this point.
6379
6380(define_insn "blockage"
6381 [(unspec_volatile [(const_int 0)] 0)]
576182a3 6382 ""
90aec2cf
JL
6383 ""
6384 [(set_attr "memory" "none")])
576182a3 6385
886c62d1
JVA
6386;; Insn emitted into the body of a function to return from a function.
6387;; This is only done if the function's epilogue is known to be simple.
6388;; See comments for simple_386_epilogue in i386.c.
6389
5f3d14e3 6390(define_expand "return"
886c62d1 6391 [(return)]
5f3d14e3
SC
6392 "ix86_can_use_return_insn_p ()"
6393 "")
6394
6395(define_insn "return_internal"
6396 [(return)]
6397 "reload_completed"
90aec2cf
JL
6398 "ret"
6399 [(set_attr "memory" "none")])
5f3d14e3 6400
6cd96118
SC
6401(define_insn "return_pop_internal"
6402 [(return)
6403 (use (match_operand:SI 0 "const_int_operand" ""))]
6404 "reload_completed"
90aec2cf
JL
6405 "ret %0"
6406 [(set_attr "memory" "none")])
6cd96118 6407
5f3d14e3
SC
6408(define_insn "nop"
6409 [(const_int 0)]
6410 ""
90aec2cf
JL
6411 "nop"
6412 [(set_attr "memory" "none")])
5f3d14e3
SC
6413
6414(define_expand "prologue"
6415 [(const_int 1)]
6416 ""
6417 "
6418{
6419 ix86_expand_prologue ();
6420 DONE;
6421}")
6422
47d36400
BS
6423;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6424;; to itself would be enough. But this way we are safe even if some optimizer
6425;; becomes too clever in the future.
6426(define_insn "prologue_set_stack_ptr"
6427 [(set (reg:SI 7)
6428 (minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i")))
6429 (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))]
6430 ""
6431 "*
6432{
6433 rtx xops [2];
6434
6435 xops[0] = operands[0];
6436 xops[1] = stack_pointer_rtx;
6437 output_asm_insn (AS2 (sub%L1,%0,%1), xops);
6438 RET;
90aec2cf
JL
6439}"
6440 [(set_attr "memory" "none")])
47d36400 6441
5f3d14e3
SC
6442(define_insn "prologue_set_got"
6443 [(set (match_operand:SI 0 "" "")
4f9ca067
JW
6444 (unspec_volatile
6445 [(plus:SI (match_dup 0)
6446 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
6447 (minus:SI (pc) (match_operand 2 "" ""))))] 1))]
5f3d14e3 6448 ""
886c62d1
JVA
6449 "*
6450{
5f3d14e3
SC
6451 char buffer[64];
6452
6453 if (TARGET_DEEP_BRANCH_PREDICTION)
6454 {
6455 sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0));
6456 output_asm_insn (buffer, operands);
6457 }
6458 else
6459 {
5cb6195d 6460 sprintf (buffer, \"addl %s+[.-%%X2],%%0\", XSTR (operands[1], 0));
5f3d14e3
SC
6461 output_asm_insn (buffer, operands);
6462 }
886c62d1
JVA
6463 RET;
6464}")
6465
5f3d14e3
SC
6466(define_insn "prologue_get_pc"
6467 [(set (match_operand:SI 0 "" "")
4f9ca067 6468 (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
886c62d1 6469 ""
5f3d14e3
SC
6470 "*
6471{
5cb6195d 6472 output_asm_insn (AS1 (call,%X1), operands);
5f3d14e3
SC
6473 if (! TARGET_DEEP_BRANCH_PREDICTION)
6474 {
e9a25f70 6475 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
5f3d14e3
SC
6476 }
6477 RET;
90aec2cf
JL
6478}"
6479 [(set_attr "memory" "none")])
5f3d14e3 6480
4f9ca067
JW
6481(define_insn "prologue_get_pc_and_set_got"
6482 [(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
6483 ""
6484 "*
6485{
6486 operands[1] = gen_label_rtx ();
5cb6195d 6487 output_asm_insn (AS1 (call,%X1), operands);
4f9ca067
JW
6488 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6489 CODE_LABEL_NUMBER (operands[1]));
6490 output_asm_insn (AS1 (pop%L0,%0), operands);
5cb6195d 6491 output_asm_insn (\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
4f9ca067 6492 RET;
90aec2cf
JL
6493}"
6494 [(set_attr "memory" "none")])
4f9ca067 6495
5f3d14e3
SC
6496(define_expand "epilogue"
6497 [(const_int 1)]
6498 ""
6499 "
6500{
6501 ix86_expand_epilogue ();
6502 DONE;
6503}")
6504
bca7cce2
SC
6505(define_insn "epilogue_set_stack_ptr"
6506 [(set (reg:SI 7) (reg:SI 6))
6507 (clobber (reg:SI 6))]
6508 ""
6509 "*
6510{
6511 rtx xops [2];
6512
6513 xops[0] = frame_pointer_rtx;
6514 xops[1] = stack_pointer_rtx;
6515 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
6516 RET;
90aec2cf
JL
6517}"
6518 [(set_attr "memory" "none")])
bca7cce2 6519
5f3d14e3 6520(define_insn "leave"
60665aab
SC
6521 [(const_int 2)
6522 (clobber (reg:SI 6))
6523 (clobber (reg:SI 7))]
5f3d14e3 6524 ""
90aec2cf
JL
6525 "leave"
6526 [(set_attr "memory" "none")])
5f3d14e3
SC
6527
6528(define_insn "pop"
6529 [(set (match_operand:SI 0 "register_operand" "r")
6530 (mem:SI (reg:SI 7)))
47d36400 6531 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]
5f3d14e3
SC
6532 ""
6533 "*
6534{
5f3d14e3
SC
6535 output_asm_insn (AS1 (pop%L0,%P0), operands);
6536 RET;
90aec2cf
JL
6537}"
6538 [(set_attr "memory" "load")])
886c62d1
JVA
6539
6540(define_expand "movstrsi"
664921b4
JVA
6541 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6542 (match_operand:BLK 1 "memory_operand" ""))
56c0e8fa
JVA
6543 (use (match_operand:SI 2 "const_int_operand" ""))
6544 (use (match_operand:SI 3 "const_int_operand" ""))
6545 (clobber (match_scratch:SI 4 ""))
664921b4
JVA
6546 (clobber (match_dup 5))
6547 (clobber (match_dup 6))])]
886c62d1
JVA
6548 ""
6549 "
6550{
664921b4
JVA
6551 rtx addr0, addr1;
6552
886c62d1
JVA
6553 if (GET_CODE (operands[2]) != CONST_INT)
6554 FAIL;
664921b4
JVA
6555
6556 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
6557 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
6558
6559 operands[5] = addr0;
6560 operands[6] = addr1;
6561
e9a25f70
JL
6562 operands[0] = change_address (operands[0], VOIDmode, addr0);
6563 operands[1] = change_address (operands[1], VOIDmode, addr1);
886c62d1
JVA
6564}")
6565
56c0e8fa
JVA
6566;; It might seem that operands 0 & 1 could use predicate register_operand.
6567;; But strength reduction might offset the MEM expression. So we let
6568;; reload put the address into %edi & %esi.
6569
886c62d1 6570(define_insn ""
56c0e8fa
JVA
6571 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
6572 (mem:BLK (match_operand:SI 1 "address_operand" "S")))
6573 (use (match_operand:SI 2 "const_int_operand" "n"))
886c62d1 6574 (use (match_operand:SI 3 "immediate_operand" "i"))
56c0e8fa
JVA
6575 (clobber (match_scratch:SI 4 "=&c"))
6576 (clobber (match_dup 0))
6577 (clobber (match_dup 1))]
886c62d1
JVA
6578 ""
6579 "*
6580{
6581 rtx xops[2];
6582
e8375399 6583 output_asm_insn (\"cld\", operands);
886c62d1
JVA
6584 if (GET_CODE (operands[2]) == CONST_INT)
6585 {
6586 if (INTVAL (operands[2]) & ~0x03)
6587 {
d0099910 6588 xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
56c0e8fa 6589 xops[1] = operands[4];
886c62d1
JVA
6590
6591 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
6592#ifdef INTEL_SYNTAX
6593 output_asm_insn (\"rep movsd\", xops);
6594#else
0e52f7f5 6595 output_asm_insn (\"rep\;movsl\", xops);
886c62d1
JVA
6596#endif
6597 }
6598 if (INTVAL (operands[2]) & 0x02)
6599 output_asm_insn (\"movsw\", operands);
6600 if (INTVAL (operands[2]) & 0x01)
6601 output_asm_insn (\"movsb\", operands);
6602 }
6603 else
6604 abort ();
6605 RET;
6606}")
6607
0ae40045
RK
6608(define_expand "clrstrsi"
6609 [(set (match_dup 3) (const_int 0))
6610 (parallel [(set (match_operand:BLK 0 "memory_operand" "")
6611 (const_int 0))
6612 (use (match_operand:SI 1 "const_int_operand" ""))
6613 (use (match_operand:SI 2 "const_int_operand" ""))
6614 (use (match_dup 3))
6615 (clobber (match_scratch:SI 4 ""))
6616 (clobber (match_dup 5))])]
6617 ""
6618 "
6619{
dae0d63a 6620 rtx addr0;
0ae40045 6621
578b58f5 6622 if (GET_CODE (operands[1]) != CONST_INT)
0ae40045
RK
6623 FAIL;
6624
6625 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
6626
6627 operands[3] = gen_reg_rtx (SImode);
6628 operands[5] = addr0;
6629
f64cecad 6630 operands[0] = gen_rtx_MEM (BLKmode, addr0);
0ae40045
RK
6631}")
6632
6633;; It might seem that operand 0 could use predicate register_operand.
6634;; But strength reduction might offset the MEM expression. So we let
6635;; reload put the address into %edi.
6636
a269a03c 6637(define_insn "*bzero"
0ae40045
RK
6638 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
6639 (const_int 0))
6640 (use (match_operand:SI 1 "const_int_operand" "n"))
6641 (use (match_operand:SI 2 "immediate_operand" "i"))
6642 (use (match_operand:SI 3 "register_operand" "a"))
6643 (clobber (match_scratch:SI 4 "=&c"))
6644 (clobber (match_dup 0))]
6645 ""
6646 "*
6647{
6648 rtx xops[2];
6649
6650 output_asm_insn (\"cld\", operands);
6651 if (GET_CODE (operands[1]) == CONST_INT)
6652 {
a269a03c
JC
6653 unsigned int count = INTVAL (operands[1]) & 0xffffffff;
6654 if (count & ~0x03)
0ae40045 6655 {
a269a03c 6656 xops[0] = GEN_INT (count / 4);
0ae40045
RK
6657 xops[1] = operands[4];
6658
a269a03c
JC
6659 /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles.
6660 80386: 4/5+5n (+2 for set of ecx)
6661 80486: 5/7+5n (+1 for set of ecx)
6662 */
6663 if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6))
6664 {
6665 do
0ae40045 6666#ifdef INTEL_SYNTAX
a269a03c 6667 output_asm_insn (\"stosd\", xops);
0ae40045 6668#else
a269a03c 6669 output_asm_insn (\"stosl\", xops);
0ae40045 6670#endif
a269a03c
JC
6671 while ((count -= 4) > 3);
6672 }
6673 else
6674 {
6675 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
6676#ifdef INTEL_SYNTAX
6677 output_asm_insn (\"rep stosd\", xops);
6678#else
6679 output_asm_insn (\"rep\;stosl\", xops);
6680#endif
6681 }
0ae40045
RK
6682 }
6683 if (INTVAL (operands[1]) & 0x02)
6684 output_asm_insn (\"stosw\", operands);
6685 if (INTVAL (operands[1]) & 0x01)
6686 output_asm_insn (\"stosb\", operands);
6687 }
6688 else
6689 abort ();
6690 RET;
6691}")
6692
886c62d1 6693(define_expand "cmpstrsi"
98166149 6694 [(parallel [(set (match_operand:SI 0 "general_operand" "")
1dde5fd2 6695 (compare:SI (match_operand:BLK 1 "general_operand" "")
783cdf65 6696 (match_operand:BLK 2 "general_operand" "")))
886c62d1
JVA
6697 (use (match_operand:SI 3 "general_operand" ""))
6698 (use (match_operand:SI 4 "immediate_operand" ""))
783cdf65
JVA
6699 (clobber (match_dup 5))
6700 (clobber (match_dup 6))
f76e3b05 6701 (clobber (match_dup 3))])]
886c62d1
JVA
6702 ""
6703 "
6704{
783cdf65
JVA
6705 rtx addr1, addr2;
6706
6707 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
6708 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
886c62d1 6709 operands[3] = copy_to_mode_reg (SImode, operands[3]);
783cdf65
JVA
6710
6711 operands[5] = addr1;
6712 operands[6] = addr2;
6713
f64cecad
JC
6714 operands[1] = gen_rtx_MEM (BLKmode, addr1);
6715 operands[2] = gen_rtx_MEM (BLKmode, addr2);
783cdf65 6716
886c62d1
JVA
6717}")
6718
f76e3b05
JVA
6719;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
6720;; zero. Emit extra code to make sure that a zero-length compare is EQ.
6721
56c0e8fa
JVA
6722;; It might seem that operands 0 & 1 could use predicate register_operand.
6723;; But strength reduction might offset the MEM expression. So we let
6724;; reload put the address into %edi & %esi.
6725
f76e3b05
JVA
6726;; ??? Most comparisons have a constant length, and it's therefore
6727;; possible to know that the length is non-zero, and to avoid the extra
6728;; code to handle zero-length compares.
6729
886c62d1 6730(define_insn ""
2ae0f82c 6731 [(set (match_operand:SI 0 "register_operand" "=&r")
1dde5fd2 6732 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
56c0e8fa
JVA
6733 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
6734 (use (match_operand:SI 3 "register_operand" "c"))
886c62d1
JVA
6735 (use (match_operand:SI 4 "immediate_operand" "i"))
6736 (clobber (match_dup 1))
6737 (clobber (match_dup 2))
f76e3b05 6738 (clobber (match_dup 3))]
886c62d1
JVA
6739 ""
6740 "*
6741{
2ae0f82c 6742 rtx xops[2], label;
2aa8f23f
JVA
6743
6744 label = gen_label_rtx ();
886c62d1 6745
e8375399 6746 output_asm_insn (\"cld\", operands);
98166149 6747 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
886c62d1 6748 output_asm_insn (\"repz\;cmps%B2\", operands);
2aa8f23f 6749 output_asm_insn (\"je %l0\", &label);
886c62d1
JVA
6750
6751 xops[0] = operands[0];
2ae0f82c
SC
6752 xops[1] = const1_rtx;
6753 output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
6754 if (QI_REG_P (xops[0]))
6755 output_asm_insn (AS2 (or%B0,%1,%b0), xops);
6756 else
6757 output_asm_insn (AS2 (or%L0,%1,%0), xops);
6758
2aa8f23f 6759 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
886c62d1
JVA
6760 RET;
6761}")
6762
6763(define_insn ""
6764 [(set (cc0)
1dde5fd2 6765 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
56c0e8fa
JVA
6766 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
6767 (use (match_operand:SI 2 "register_operand" "c"))
886c62d1
JVA
6768 (use (match_operand:SI 3 "immediate_operand" "i"))
6769 (clobber (match_dup 0))
6770 (clobber (match_dup 1))
f76e3b05 6771 (clobber (match_dup 2))]
886c62d1 6772 ""
2aa8f23f
JVA
6773 "*
6774{
f76e3b05
JVA
6775 rtx xops[2];
6776
98166149
JVA
6777 cc_status.flags |= CC_NOT_SIGNED;
6778
f64cecad 6779 xops[0] = gen_rtx_REG (QImode, 0);
f76e3b05
JVA
6780 xops[1] = CONST0_RTX (QImode);
6781
e8375399 6782 output_asm_insn (\"cld\", operands);
f76e3b05 6783 output_asm_insn (AS2 (test%B0,%1,%0), xops);
2aa8f23f
JVA
6784 return \"repz\;cmps%B2\";
6785}")
886c62d1 6786
2ae0f82c 6787\f
ad626759
MM
6788;; Note, you cannot optimize away the branch following the bsfl by assuming
6789;; that the destination is not modified if the input is 0, since not all
6790;; x86 implementations do this.
6791
ce193852
RH
6792(define_expand "ffssi2"
6793 [(set (match_operand:SI 0 "general_operand" "")
6794 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
886c62d1 6795 ""
ce193852 6796 "
886c62d1 6797{
ce193852 6798 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
886c62d1 6799
ce193852
RH
6800 emit_insn (gen_ffssi_1 (temp, operands[1]));
6801 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
6802 emit_jump_insn (gen_bne (label));
6803 emit_move_insn (temp, constm1_rtx);
6804 emit_label (label);
6805 temp = expand_binop (SImode, add_optab, temp, const1_rtx,
6806 operands[0], 0, OPTAB_WIDEN);
6d7512e4 6807
ce193852
RH
6808 if (temp != operands[0])
6809 emit_move_insn (operands[0], temp);
6810 DONE;
886c62d1
JVA
6811}")
6812
ce193852
RH
6813(define_insn "ffssi_1"
6814 [(set (match_operand:SI 0 "register_operand" "=r")
6815 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
886c62d1 6816 ""
ce193852 6817 "* return AS2 (bsf%L0,%1,%0);")
886c62d1 6818
ce193852
RH
6819(define_expand "ffshi2"
6820 [(set (match_operand:SI 0 "general_operand" "")
6821 (ffs:HI (match_operand:HI 1 "general_operand" "")))]
886c62d1 6822 ""
ce193852 6823 "
886c62d1 6824{
ce193852 6825 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
886c62d1 6826
ce193852
RH
6827 emit_insn (gen_ffshi_1 (temp, operands[1]));
6828 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
6829 emit_jump_insn (gen_bne (label));
6830 emit_move_insn (temp, constm1_rtx);
6831 emit_label (label);
6832 temp = expand_binop (HImode, add_optab, temp, const1_rtx,
6833 operands[0], 0, OPTAB_WIDEN);
6d7512e4 6834
ce193852
RH
6835 if (temp != operands[0])
6836 emit_move_insn (operands[0], temp);
6837 DONE;
886c62d1 6838}")
ce193852
RH
6839
6840(define_insn "ffshi_1"
6841 [(set (match_operand:HI 0 "register_operand" "=r")
6842 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6843 ""
6844 "* return AS2 (bsf%W0,%1,%0);")
886c62d1
JVA
6845\f
6846;; These patterns match the binary 387 instructions for addM3, subM3,
6847;; mulM3 and divM3. There are three patterns for each of DFmode and
6848;; SFmode. The first is the normal insn, the second the same insn but
6849;; with one operand a conversion, and the third the same insn but with
87aa5246 6850;; the other operand a conversion.
886c62d1
JVA
6851
6852(define_insn ""
6853 [(set (match_operand:DF 0 "register_operand" "=f,f")
6854 (match_operator:DF 3 "binary_387_op"
08a7baac
JVA
6855 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
6856 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
886c62d1 6857 "TARGET_80387"
2ae0f82c
SC
6858 "* return output_387_binary_op (insn, operands);"
6859 [(set (attr "type")
6860 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6861 (const_string "fpmul")
2ae0f82c
SC
6862 (match_operand:DF 3 "is_div" "")
6863 (const_string "fpdiv")
6864 ]
6865 (const_string "fpop")
6866 )
6867 )])
886c62d1 6868
4fb21e90
JVA
6869(define_insn ""
6870 [(set (match_operand:XF 0 "register_operand" "=f,f")
6871 (match_operator:XF 3 "binary_387_op"
2ae0f82c
SC
6872 [(match_operand:XF 1 "register_operand" "0,f")
6873 (match_operand:XF 2 "register_operand" "f,0")]))]
4fb21e90 6874 "TARGET_80387"
2ae0f82c
SC
6875 "* return output_387_binary_op (insn, operands);"
6876 [(set (attr "type")
6877 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6878 (const_string "fpmul")
2ae0f82c
SC
6879 (match_operand:DF 3 "is_div" "")
6880 (const_string "fpdiv")
6881 ]
6882 (const_string "fpop")
6883 )
6884 )])
4fb21e90 6885
4fb21e90
JVA
6886(define_insn ""
6887 [(set (match_operand:XF 0 "register_operand" "=f,f")
6888 (match_operator:XF 3 "binary_387_op"
2ae0f82c
SC
6889 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
6890 (match_operand:XF 2 "register_operand" "0,f")]))]
4fb21e90 6891 "TARGET_80387"
2ae0f82c
SC
6892 "* return output_387_binary_op (insn, operands);"
6893 [(set (attr "type")
6894 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6895 (const_string "fpmul")
2ae0f82c
SC
6896 (match_operand:DF 3 "is_div" "")
6897 (const_string "fpdiv")
6898 ]
6899 (const_string "fpop")
6900 )
6901 )])
4fb21e90 6902
4fb21e90
JVA
6903(define_insn ""
6904 [(set (match_operand:XF 0 "register_operand" "=f,f")
6905 (match_operator:XF 3 "binary_387_op"
2ae0f82c 6906 [(match_operand:XF 1 "register_operand" "0,f")
4fb21e90 6907 (float_extend:XF
2ae0f82c 6908 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
4fb21e90 6909 "TARGET_80387"
2ae0f82c
SC
6910 "* return output_387_binary_op (insn, operands);"
6911 [(set (attr "type")
6912 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6913 (const_string "fpmul")
2ae0f82c
SC
6914 (match_operand:DF 3 "is_div" "")
6915 (const_string "fpdiv")
6916 ]
6917 (const_string "fpop")
6918 )
6919 )])
886c62d1
JVA
6920
6921(define_insn ""
08a7baac 6922 [(set (match_operand:DF 0 "register_operand" "=f,f")
886c62d1 6923 (match_operator:DF 3 "binary_387_op"
2ae0f82c
SC
6924 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
6925 (match_operand:DF 2 "register_operand" "0,f")]))]
886c62d1 6926 "TARGET_80387"
2ae0f82c
SC
6927 "* return output_387_binary_op (insn, operands);"
6928 [(set (attr "type")
6929 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6930 (const_string "fpmul")
2ae0f82c
SC
6931 (match_operand:DF 3 "is_div" "")
6932 (const_string "fpdiv")
6933 ]
6934 (const_string "fpop")
6935 )
6936 )])
886c62d1 6937
886c62d1 6938(define_insn ""
08a7baac 6939 [(set (match_operand:DF 0 "register_operand" "=f,f")
886c62d1 6940 (match_operator:DF 3 "binary_387_op"
2ae0f82c 6941 [(match_operand:DF 1 "register_operand" "0,f")
886c62d1 6942 (float_extend:DF
2ae0f82c 6943 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
886c62d1 6944 "TARGET_80387"
2ae0f82c
SC
6945 "* return output_387_binary_op (insn, operands);"
6946 [(set (attr "type")
6947 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6948 (const_string "fpmul")
2ae0f82c
SC
6949 (match_operand:DF 3 "is_div" "")
6950 (const_string "fpdiv")
6951 ]
6952 (const_string "fpop")
6953 )
6954 )])
886c62d1
JVA
6955
6956(define_insn ""
6957 [(set (match_operand:SF 0 "register_operand" "=f,f")
6958 (match_operator:SF 3 "binary_387_op"
08a7baac
JVA
6959 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
6960 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
886c62d1 6961 "TARGET_80387"
2ae0f82c
SC
6962 "* return output_387_binary_op (insn, operands);"
6963 [(set (attr "type")
6964 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6965 (const_string "fpmul")
2ae0f82c
SC
6966 (match_operand:DF 3 "is_div" "")
6967 (const_string "fpdiv")
6968 ]
6969 (const_string "fpop")
6970 )
6971 )])
886c62d1 6972\f
19c3fc24
RS
6973(define_expand "strlensi"
6974 [(parallel [(set (match_dup 4)
6975 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
628448b3 6976 (match_operand:QI 2 "immediate_operand" "")
19c3fc24
RS
6977 (match_operand:SI 3 "immediate_operand" "")] 0))
6978 (clobber (match_dup 1))])
6979 (set (match_dup 5)
6980 (not:SI (match_dup 4)))
6981 (set (match_operand:SI 0 "register_operand" "")
628448b3
SC
6982 (plus:SI (match_dup 5)
6983 (const_int -1)))]
19c3fc24
RS
6984 ""
6985 "
6986{
628448b3
SC
6987 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
6988 {
6989 rtx address;
6990 rtx scratch;
6991
6992 /* well it seems that some optimizer does not combine a call like
6993 foo(strlen(bar), strlen(bar));
6994 when the move and the subtraction is done here. It does calculate
6995 the length just once when these instructions are done inside of
6996 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
6997 often used and I use one fewer register for the lifetime of
6998 output_strlen_unroll() this is better. */
6999 scratch = gen_reg_rtx (SImode);
7000 address = force_reg (SImode, XEXP (operands[1], 0));
7001
7002 /* move address to scratch-register
7003 this is done here because the i586 can do the following and
7004 in the same cycle with the following move. */
7005 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7006 emit_insn (gen_movsi (scratch, address));
7007
7008 emit_insn (gen_movsi (operands[0], address));
7009
7010 if(TARGET_USE_Q_REG)
7011 emit_insn (gen_strlensi_unroll5 (operands[0],
7012 operands[3],
7013 scratch,
7014 operands[0]));
7015 else
7016 emit_insn (gen_strlensi_unroll4 (operands[0],
7017 operands[3],
7018 scratch,
7019 operands[0]));
7020
7021 /* gen_strlensi_unroll[45] returns the address of the zero
7022 at the end of the string, like memchr(), so compute the
7023 length by subtracting the startaddress. */
7024 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7025 DONE;
7026 }
7027
19c3fc24
RS
7028 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7029 operands[4] = gen_reg_rtx (SImode);
7030 operands[5] = gen_reg_rtx (SImode);
7031}")
7032
56c0e8fa
JVA
7033;; It might seem that operands 0 & 1 could use predicate register_operand.
7034;; But strength reduction might offset the MEM expression. So we let
08a7baac 7035;; reload put the address into %edi.
56c0e8fa 7036
19c3fc24
RS
7037(define_insn ""
7038 [(set (match_operand:SI 0 "register_operand" "=&c")
56c0e8fa 7039 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
628448b3 7040 (match_operand:QI 2 "immediate_operand" "a")
19c3fc24
RS
7041 (match_operand:SI 3 "immediate_operand" "i")] 0))
7042 (clobber (match_dup 1))]
7043 ""
7044 "*
7045{
7046 rtx xops[2];
7047
7048 xops[0] = operands[0];
7049 xops[1] = constm1_rtx;
e8375399 7050 output_asm_insn (\"cld\", operands);
19c3fc24
RS
7051 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7052 return \"repnz\;scas%B2\";
7053}")
628448b3 7054
926b3fae
SC
7055/* Conditional move define_insns. */
7056
7057(define_expand "movsicc"
726e2d54 7058 [(set (match_operand:SI 0 "register_operand" "")
926b3fae 7059 (if_then_else:SI (match_operand 1 "comparison_operator" "")
726e2d54
JW
7060 (match_operand:SI 2 "nonimmediate_operand" "")
7061 (match_operand:SI 3 "nonimmediate_operand" "")))]
7062 "TARGET_CMOVE"
926b3fae
SC
7063 "
7064{
726e2d54
JW
7065 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7066 FAIL;
926b3fae 7067
726e2d54
JW
7068 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7069 GET_MODE (i386_compare_op0),
7070 i386_compare_op0, i386_compare_op1);
926b3fae
SC
7071}")
7072
726e2d54 7073(define_insn ""
3aeae608 7074 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
726e2d54 7075 (if_then_else:SI (match_operator 1 "comparison_operator"
3aeae608
JW
7076 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7077 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7078 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7079 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
726e2d54
JW
7080 "TARGET_CMOVE"
7081 "#")
7082
7083(define_insn ""
3aeae608 7084 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
726e2d54 7085 (if_then_else:SI (match_operator 1 "comparison_operator"
3aeae608
JW
7086 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7087 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7088 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7089 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
726e2d54
JW
7090 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7091 "#")
7092
7093(define_split
3aeae608 7094 [(set (match_operand:SI 0 "register_operand" "=r,r")
726e2d54
JW
7095 (if_then_else:SI (match_operator 1 "comparison_operator"
7096 [(match_operand 2 "nonimmediate_operand" "")
7097 (const_int 0)])
3aeae608
JW
7098 (match_operand:SI 3 "nonimmediate_operand" "rm,0")
7099 (match_operand:SI 4 "nonimmediate_operand" "0,rm")))]
726e2d54
JW
7100 "TARGET_CMOVE && reload_completed"
7101 [(set (cc0)
7102 (match_dup 2))
7103 (set (match_dup 0)
7104 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7105 (match_dup 3) (match_dup 4)))]
7106 "")
7107
7108(define_split
3aeae608 7109 [(set (match_operand:SI 0 "register_operand" "=r,r")
726e2d54
JW
7110 (if_then_else:SI (match_operator 1 "comparison_operator"
7111 [(match_operand 2 "nonimmediate_operand" "")
7112 (match_operand 3 "general_operand" "")])
3aeae608
JW
7113 (match_operand:SI 4 "nonimmediate_operand" "rm,0")
7114 (match_operand:SI 5 "nonimmediate_operand" "0,rm")))]
726e2d54
JW
7115 "TARGET_CMOVE && reload_completed"
7116 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7117 (set (match_dup 0)
7118 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7119 (match_dup 4) (match_dup 5)))]
7120 "")
7121
7122(define_insn ""
3aeae608 7123 [(set (match_operand:SI 0 "register_operand" "=r,r")
926b3fae 7124 (if_then_else:SI (match_operator 1 "comparison_operator"
b76c90cf 7125 [(cc0) (const_int 0)])
3aeae608
JW
7126 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
7127 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
726e2d54 7128 "TARGET_CMOVE && reload_completed"
b657fc39 7129 "* return output_int_conditional_move (which_alternative, operands);")
926b3fae 7130
726e2d54
JW
7131(define_expand "movhicc"
7132 [(set (match_operand:HI 0 "register_operand" "")
7133 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7134 (match_operand:HI 2 "nonimmediate_operand" "")
7135 (match_operand:HI 3 "nonimmediate_operand" "")))]
7136 "TARGET_CMOVE"
7137 "
7138{
7139 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7140 FAIL;
7141
7142 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7143 GET_MODE (i386_compare_op0),
7144 i386_compare_op0, i386_compare_op1);
7145}")
7146
7147(define_insn ""
3aeae608 7148 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
726e2d54 7149 (if_then_else:HI (match_operator 1 "comparison_operator"
3aeae608
JW
7150 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7151 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7152 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7153 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
726e2d54
JW
7154 "TARGET_CMOVE"
7155 "#")
7156
7157(define_insn ""
3aeae608 7158 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
726e2d54 7159 (if_then_else:HI (match_operator 1 "comparison_operator"
3aeae608
JW
7160 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7161 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7162 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7163 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
726e2d54
JW
7164 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7165 "#")
7166
7167(define_split
3aeae608 7168 [(set (match_operand:HI 0 "register_operand" "=r,r")
726e2d54
JW
7169 (if_then_else:HI (match_operator 1 "comparison_operator"
7170 [(match_operand 2 "nonimmediate_operand" "")
7171 (const_int 0)])
3aeae608
JW
7172 (match_operand:HI 3 "nonimmediate_operand" "rm,0")
7173 (match_operand:HI 4 "nonimmediate_operand" "0,rm")))]
726e2d54
JW
7174 "TARGET_CMOVE && reload_completed"
7175 [(set (cc0)
7176 (match_dup 2))
7177 (set (match_dup 0)
7178 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7179 (match_dup 3) (match_dup 4)))]
7180 "")
7181
7182(define_split
3aeae608 7183 [(set (match_operand:HI 0 "register_operand" "=r,r")
726e2d54
JW
7184 (if_then_else:HI (match_operator 1 "comparison_operator"
7185 [(match_operand 2 "nonimmediate_operand" "")
7186 (match_operand 3 "general_operand" "")])
3aeae608
JW
7187 (match_operand:HI 4 "nonimmediate_operand" "rm,0")
7188 (match_operand:HI 5 "nonimmediate_operand" "0,rm")))]
726e2d54
JW
7189 "TARGET_CMOVE && reload_completed"
7190 [(set (cc0)
7191 (compare (match_dup 2) (match_dup 3)))
7192 (set (match_dup 0)
7193 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7194 (match_dup 4) (match_dup 5)))]
7195 "")
7196
7197(define_insn ""
3aeae608 7198 [(set (match_operand:HI 0 "register_operand" "=r,r")
926b3fae 7199 (if_then_else:HI (match_operator 1 "comparison_operator"
b76c90cf 7200 [(cc0) (const_int 0)])
3aeae608
JW
7201 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
7202 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
726e2d54 7203 "TARGET_CMOVE && reload_completed"
b657fc39 7204 "* return output_int_conditional_move (which_alternative, operands);")
e5e809f4 7205
56710e42 7206(define_expand "movsfcc"
726e2d54 7207 [(set (match_operand:SF 0 "register_operand" "")
56710e42 7208 (if_then_else:SF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
7209 (match_operand:SF 2 "register_operand" "")
7210 (match_operand:SF 3 "register_operand" "")))]
726e2d54 7211 "TARGET_CMOVE"
56710e42
SC
7212 "
7213{
bbe8497f
JW
7214 rtx temp;
7215
726e2d54
JW
7216 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7217 FAIL;
7218
bbe8497f
JW
7219 /* The floating point conditional move instructions don't directly
7220 support conditions resulting from a signed integer comparison. */
7221
7222 switch (GET_CODE (operands[1]))
7223 {
7224 case LT:
7225 case LE:
7226 case GE:
7227 case GT:
7228 temp = emit_store_flag (gen_reg_rtx (QImode),
7229 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7230 VOIDmode, 0, 0);
7231
7232 if (!temp)
7233 FAIL;
7234
7235 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7236 break;
7237
7238 default:
7239 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
726e2d54
JW
7240 GET_MODE (i386_compare_op0),
7241 i386_compare_op0, i386_compare_op1);
bbe8497f
JW
7242 break;
7243 }
726e2d54
JW
7244}")
7245
7246(define_insn ""
3aeae608 7247 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
726e2d54 7248 (if_then_else:SF (match_operator 1 "comparison_operator"
3aeae608
JW
7249 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7250 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7251 (match_operand:SF 4 "register_operand" "f,f,0,0")
7252 (match_operand:SF 5 "register_operand" "0,0,f,f")))]
bbe8497f
JW
7253 "TARGET_CMOVE
7254 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7255 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7256 "#")
7257
7258(define_insn ""
3aeae608 7259 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
726e2d54 7260 (if_then_else:SF (match_operator 1 "comparison_operator"
3aeae608
JW
7261 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7262 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7263 (match_operand:SF 4 "register_operand" "f,f,0,0")
7264 (match_operand:SF 5 "register_operand" "0,0,f,f")))]
bbe8497f
JW
7265 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7266 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7267 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7268 "#")
7269
7270(define_split
3aeae608 7271 [(set (match_operand:SF 0 "register_operand" "=f,f")
726e2d54
JW
7272 (if_then_else:SF (match_operator 1 "comparison_operator"
7273 [(match_operand 2 "nonimmediate_operand" "")
7274 (const_int 0)])
3aeae608
JW
7275 (match_operand:SF 3 "register_operand" "f,0")
7276 (match_operand:SF 4 "register_operand" "0,f")))]
726e2d54
JW
7277 "TARGET_CMOVE && reload_completed"
7278 [(set (cc0)
7279 (match_dup 2))
7280 (set (match_dup 0)
7281 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7282 (match_dup 3) (match_dup 4)))]
7283 "")
7284
7285(define_split
3aeae608 7286 [(set (match_operand:SF 0 "register_operand" "=f,f")
726e2d54
JW
7287 (if_then_else:SF (match_operator 1 "comparison_operator"
7288 [(match_operand 2 "nonimmediate_operand" "")
7289 (match_operand 3 "general_operand" "")])
3aeae608
JW
7290 (match_operand:SF 4 "register_operand" "f,0")
7291 (match_operand:SF 5 "register_operand" "0,f")))]
726e2d54
JW
7292 "TARGET_CMOVE && reload_completed"
7293 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7294 (set (match_dup 0)
7295 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7296 (match_dup 4) (match_dup 5)))]
7297 "")
7298
7299(define_insn ""
3aeae608 7300 [(set (match_operand:SF 0 "register_operand" "=f,f")
726e2d54
JW
7301 (if_then_else:SF (match_operator 1 "comparison_operator"
7302 [(cc0) (const_int 0)])
3aeae608
JW
7303 (match_operand:SF 2 "register_operand" "f,0")
7304 (match_operand:SF 3 "register_operand" "0,f")))]
726e2d54 7305 "TARGET_CMOVE && reload_completed"
b657fc39 7306 "* return output_fp_conditional_move (which_alternative, operands);")
56710e42
SC
7307
7308(define_expand "movdfcc"
726e2d54 7309 [(set (match_operand:DF 0 "register_operand" "")
56710e42 7310 (if_then_else:DF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
7311 (match_operand:DF 2 "register_operand" "")
7312 (match_operand:DF 3 "register_operand" "")))]
726e2d54 7313 "TARGET_CMOVE"
56710e42
SC
7314 "
7315{
bbe8497f
JW
7316 rtx temp;
7317
726e2d54
JW
7318 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7319 FAIL;
7320
bbe8497f
JW
7321 /* The floating point conditional move instructions don't directly
7322 support conditions resulting from a signed integer comparison. */
1c5d60f5
JW
7323
7324 switch (GET_CODE (operands[1]))
7325 {
7326 case LT:
7327 case LE:
7328 case GE:
7329 case GT:
bbe8497f
JW
7330 temp = emit_store_flag (gen_reg_rtx (QImode),
7331 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7332 VOIDmode, 0, 0);
1c5d60f5 7333
bbe8497f
JW
7334 if (!temp)
7335 FAIL;
7336
7337 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
1c5d60f5 7338 break;
1c5d60f5 7339
bbe8497f
JW
7340 default:
7341 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
726e2d54
JW
7342 GET_MODE (i386_compare_op0),
7343 i386_compare_op0, i386_compare_op1);
bbe8497f
JW
7344 break;
7345 }
726e2d54
JW
7346}")
7347
7348(define_insn ""
3aeae608 7349 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
726e2d54 7350 (if_then_else:DF (match_operator 1 "comparison_operator"
3aeae608
JW
7351 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7352 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7353 (match_operand:DF 4 "register_operand" "f,f,0,0")
7354 (match_operand:DF 5 "register_operand" "0,0,f,f")))]
bbe8497f
JW
7355 "TARGET_CMOVE
7356 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7357 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7358 "#")
7359
7360(define_insn ""
3aeae608 7361 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
726e2d54 7362 (if_then_else:DF (match_operator 1 "comparison_operator"
3aeae608
JW
7363 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7364 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7365 (match_operand:DF 4 "register_operand" "f,f,0,0")
7366 (match_operand:DF 5 "register_operand" "0,0,f,f")))]
bbe8497f
JW
7367 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7368 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7369 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7370 "#")
7371
7372(define_split
3aeae608 7373 [(set (match_operand:DF 0 "register_operand" "=f,f")
726e2d54
JW
7374 (if_then_else:DF (match_operator 1 "comparison_operator"
7375 [(match_operand 2 "nonimmediate_operand" "")
7376 (const_int 0)])
3aeae608
JW
7377 (match_operand:DF 3 "register_operand" "f,0")
7378 (match_operand:DF 4 "register_operand" "0,f")))]
726e2d54
JW
7379 "TARGET_CMOVE && reload_completed"
7380 [(set (cc0)
7381 (match_dup 2))
7382 (set (match_dup 0)
7383 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7384 (match_dup 3) (match_dup 4)))]
7385 "")
7386
7387(define_split
3aeae608 7388 [(set (match_operand:DF 0 "register_operand" "=f,f")
726e2d54
JW
7389 (if_then_else:DF (match_operator 1 "comparison_operator"
7390 [(match_operand 2 "nonimmediate_operand" "")
7391 (match_operand 3 "general_operand" "")])
3aeae608
JW
7392 (match_operand:DF 4 "register_operand" "f,0")
7393 (match_operand:DF 5 "register_operand" "0,f")))]
726e2d54
JW
7394 "TARGET_CMOVE && reload_completed"
7395 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7396 (set (match_dup 0)
7397 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7398 (match_dup 4) (match_dup 5)))]
7399 "")
7400
7401(define_insn ""
3aeae608 7402 [(set (match_operand:DF 0 "register_operand" "=f,f")
726e2d54
JW
7403 (if_then_else:DF (match_operator 1 "comparison_operator"
7404 [(cc0) (const_int 0)])
3aeae608
JW
7405 (match_operand:DF 2 "register_operand" "f,0")
7406 (match_operand:DF 3 "register_operand" "0,f")))]
726e2d54 7407 "TARGET_CMOVE && reload_completed"
b657fc39 7408 "* return output_fp_conditional_move (which_alternative, operands);")
56710e42
SC
7409
7410(define_expand "movxfcc"
726e2d54 7411 [(set (match_operand:XF 0 "register_operand" "")
56710e42 7412 (if_then_else:XF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
7413 (match_operand:XF 2 "register_operand" "")
7414 (match_operand:XF 3 "register_operand" "")))]
726e2d54 7415 "TARGET_CMOVE"
56710e42
SC
7416 "
7417{
bbe8497f
JW
7418 rtx temp;
7419
726e2d54
JW
7420 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7421 FAIL;
7422
bbe8497f
JW
7423 /* The floating point conditional move instructions don't directly
7424 support conditions resulting from a signed integer comparison. */
1c5d60f5
JW
7425
7426 switch (GET_CODE (operands[1]))
7427 {
7428 case LT:
7429 case LE:
7430 case GE:
7431 case GT:
bbe8497f
JW
7432 temp = emit_store_flag (gen_reg_rtx (QImode),
7433 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7434 VOIDmode, 0, 0);
1c5d60f5 7435
bbe8497f
JW
7436 if (!temp)
7437 FAIL;
7438
7439 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
1c5d60f5 7440 break;
1c5d60f5 7441
bbe8497f
JW
7442 default:
7443 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
726e2d54
JW
7444 GET_MODE (i386_compare_op0),
7445 i386_compare_op0, i386_compare_op1);
bbe8497f
JW
7446 break;
7447 }
56710e42
SC
7448}")
7449
726e2d54 7450(define_insn ""
3aeae608 7451 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
726e2d54 7452 (if_then_else:XF (match_operator 1 "comparison_operator"
3aeae608
JW
7453 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7454 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7455 (match_operand:XF 4 "register_operand" "f,f,0,0")
7456 (match_operand:XF 5 "register_operand" "0,0,f,f")))]
bbe8497f
JW
7457 "TARGET_CMOVE
7458 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7459 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7460 "#")
7461
7462(define_insn ""
3aeae608 7463 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
726e2d54 7464 (if_then_else:XF (match_operator 1 "comparison_operator"
3aeae608
JW
7465 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7466 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7467 (match_operand:XF 4 "register_operand" "f,f,0,0")
7468 (match_operand:XF 5 "register_operand" "0,0,f,f")))]
bbe8497f
JW
7469 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7470 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7471 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7472 "#")
7473
7474(define_split
3aeae608 7475 [(set (match_operand:XF 0 "register_operand" "=f,f")
726e2d54
JW
7476 (if_then_else:XF (match_operator 1 "comparison_operator"
7477 [(match_operand 2 "nonimmediate_operand" "")
7478 (const_int 0)])
3aeae608
JW
7479 (match_operand:XF 3 "register_operand" "f,0")
7480 (match_operand:XF 4 "register_operand" "0,f")))]
726e2d54
JW
7481 "TARGET_CMOVE && reload_completed"
7482 [(set (cc0)
7483 (match_dup 2))
7484 (set (match_dup 0)
7485 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
7486 (match_dup 3) (match_dup 4)))]
7487 "")
7488
7489(define_split
3aeae608 7490 [(set (match_operand:XF 0 "register_operand" "=f,f")
726e2d54
JW
7491 (if_then_else:XF (match_operator 1 "comparison_operator"
7492 [(match_operand 2 "nonimmediate_operand" "")
7493 (match_operand 3 "general_operand" "")])
3aeae608
JW
7494 (match_operand:XF 4 "register_operand" "f,0")
7495 (match_operand:XF 5 "register_operand" "0,f")))]
726e2d54
JW
7496 "TARGET_CMOVE && reload_completed"
7497 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7498 (set (match_dup 0)
7499 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
7500 (match_dup 4) (match_dup 5)))]
7501 "")
7502
7503(define_insn ""
3aeae608 7504 [(set (match_operand:XF 0 "register_operand" "=f,f")
726e2d54
JW
7505 (if_then_else:XF (match_operator 1 "comparison_operator"
7506 [(cc0) (const_int 0)])
3aeae608
JW
7507 (match_operand:XF 2 "register_operand" "f,0")
7508 (match_operand:XF 3 "register_operand" "0,f")))]
726e2d54 7509 "TARGET_CMOVE && reload_completed"
b657fc39 7510 "* return output_fp_conditional_move (which_alternative, operands);")
56710e42 7511
726e2d54
JW
7512(define_expand "movdicc"
7513 [(set (match_operand:DI 0 "register_operand" "")
7514 (if_then_else:DI (match_operand 1 "comparison_operator" "")
7515 (match_operand:DI 2 "nonimmediate_operand" "")
7516 (match_operand:DI 3 "nonimmediate_operand" "")))]
7517 "TARGET_CMOVE"
7518 "
7519{
7520 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7521 FAIL;
7522
7523 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7524 GET_MODE (i386_compare_op0),
7525 i386_compare_op0, i386_compare_op1);
7526}")
7527
7528(define_insn ""
3aeae608 7529 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
726e2d54 7530 (if_then_else:DI (match_operator 1 "comparison_operator"
3aeae608
JW
7531 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7532 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7533 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
7534 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
726e2d54
JW
7535 "TARGET_CMOVE"
7536 "#")
7537
7538(define_insn ""
3aeae608 7539 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
726e2d54 7540 (if_then_else:DI (match_operator 1 "comparison_operator"
3aeae608
JW
7541 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7542 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7543 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
7544 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
726e2d54
JW
7545 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7546 "#")
7547
7548(define_split
3aeae608 7549 [(set (match_operand:DI 0 "register_operand" "=&r,&r")
726e2d54
JW
7550 (if_then_else:DI (match_operator 1 "comparison_operator"
7551 [(match_operand 2 "nonimmediate_operand" "")
7552 (const_int 0)])
3aeae608
JW
7553 (match_operand:DI 3 "nonimmediate_operand" "ro,0")
7554 (match_operand:DI 4 "nonimmediate_operand" "0,ro")))]
726e2d54
JW
7555 "TARGET_CMOVE && reload_completed"
7556 [(set (cc0)
7557 (match_dup 2))
94b596a7
JW
7558 (set (match_dup 5)
7559 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7560 (match_dup 7) (match_dup 9)))
7561 (set (match_dup 6)
7562 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7563 (match_dup 8) (match_dup 10)))]
7564 "split_di (&operands[0], 1, &operands[5], &operands[6]);
7565 split_di (&operands[3], 1, &operands[7], &operands[8]);
7566 split_di (&operands[4], 1, &operands[9], &operands[10]);")
726e2d54
JW
7567
7568(define_split
3aeae608 7569 [(set (match_operand:DI 0 "register_operand" "=&r,&r")
726e2d54
JW
7570 (if_then_else:DI (match_operator 1 "comparison_operator"
7571 [(match_operand 2 "nonimmediate_operand" "")
7572 (match_operand 3 "general_operand" "")])
3aeae608
JW
7573 (match_operand:DI 4 "nonimmediate_operand" "ro,0")
7574 (match_operand:DI 5 "nonimmediate_operand" "0,ro")))]
726e2d54
JW
7575 "TARGET_CMOVE && reload_completed"
7576 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
94b596a7
JW
7577 (set (match_dup 6)
7578 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7579 (match_dup 8) (match_dup 10)))
7580 (set (match_dup 7)
7581 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7582 (match_dup 9) (match_dup 11)))]
7583 "split_di (&operands[0], 1, &operands[6], &operands[7]);
7584 split_di (&operands[4], 1, &operands[8], &operands[9]);
7585 split_di (&operands[5], 1, &operands[10], &operands[11]);")
926b3fae 7586
2ae0f82c
SC
7587(define_insn "strlensi_unroll"
7588 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
7589 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
7590 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
7591 (clobber (match_scratch:SI 3 "=&q,&r"))]
7592 "optimize > 1"
7593 "* return output_strlen_unroll (operands);")
7594
628448b3
SC
7595;; the only difference between the following patterns is the register preference
7596;; on a pentium using a q-register saves one clock cycle per 4 characters
7597
7598(define_insn "strlensi_unroll4"
7599 [(set (match_operand:SI 0 "register_operand" "=r,r")
7600 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
7601 (match_operand:SI 1 "immediate_operand" "i,i")
d9118e7b 7602 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
628448b3
SC
7603 (clobber (match_dup 2))]
7604 "(TARGET_USE_ANY_REG && optimize > 1)"
7605 "* return output_strlen_unroll (operands);")
7606
7607(define_insn "strlensi_unroll5"
7608 [(set (match_operand:SI 0 "register_operand" "=r")
7609 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
7610 (match_operand:SI 1 "immediate_operand" "i")
d9118e7b 7611 (match_operand:SI 2 "register_operand" "+q")] 0))
628448b3
SC
7612 (clobber (match_dup 2))]
7613 "(TARGET_USE_Q_REG && optimize > 1)"
5f3d14e3
SC
7614 "* return output_strlen_unroll (operands);"
7615)
578b58f5
RK
7616
7617(define_insn "allocate_stack_worker"
7618 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
7619 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
7620 (clobber (match_dup 0))]
7621 "TARGET_STACK_PROBE"
90aec2cf
JL
7622 "* return AS1(call,__alloca);"
7623 [(set_attr "memory" "none")])
578b58f5
RK
7624
7625(define_expand "allocate_stack"
e9a25f70
JL
7626 [(set (match_operand:SI 0 "register_operand" "=r")
7627 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
7628 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
7629 "TARGET_STACK_PROBE"
578b58f5
RK
7630 "
7631{
7632#ifdef CHECK_STACK_LIMIT
e9a25f70
JL
7633 if (GET_CODE (operands[1]) == CONST_INT
7634 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
578b58f5 7635 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
e9a25f70 7636 operands[1]));
578b58f5
RK
7637 else
7638#endif
7639 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
e9a25f70 7640 operands[1])));
578b58f5 7641
e9a25f70
JL
7642 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7643 DONE;
7644}")
e31ca113
JW
7645
7646(define_expand "exception_receiver"
7647 [(const_int 0)]
7648 "flag_pic"
7649 "
7650{
7651 load_pic_register (1);
7652 DONE;
7653}")
This page took 1.590753 seconds and 5 git commands to generate.