summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>1999-10-16 08:12:02 +0000
committerobrien <obrien@FreeBSD.org>1999-10-16 08:12:02 +0000
commitcf3ead1aa14fb8a108742968f0ed7193a40d4c4c (patch)
treefd1e7e3bd409eb407afa30602e78eb317297a1c0 /contrib/gcc/config
parent4e49c9209be2fc3db0687c7a3375c00fc4bde682 (diff)
downloadFreeBSD-src-cf3ead1aa14fb8a108742968f0ed7193a40d4c4c.zip
FreeBSD-src-cf3ead1aa14fb8a108742968f0ed7193a40d4c4c.tar.gz
Use the stock file here. I cannot determine if our previous (rev 1.2)
changes for ObjC are still appropriate.
Diffstat (limited to 'contrib/gcc/config')
-rw-r--r--contrib/gcc/config/i386/i386.md3359
1 files changed, 1869 insertions, 1490 deletions
diff --git a/contrib/gcc/config/i386/i386.md b/contrib/gcc/config/i386/i386.md
index f85992f..aa3f07e 100644
--- a/contrib/gcc/config/i386/i386.md
+++ b/contrib/gcc/config/i386/i386.md
@@ -64,13 +64,52 @@
;; prevent insns referencing it being scheduled across the initial
;; decrement of the stack pointer.
;; 5 This is a `bsf' operation.
+;; 6 This is the @GOT offset of a PIC address.
+;; 7 This is the @GOTOFF offset of a PIC address.
+;; 8 This is a reference to a symbol's @PLT address.
;; This shadows the processor_type enumeration, so changes must be made
;; to i386.h at the same time.
-(define_attr "type" "integer,idiv,imul,fld,fpop,fpdiv,fpmul"
+;; $FreeBSD$
+
+(define_attr "type"
+ "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul"
(const_string "integer"))
+(define_attr "memory" "none,load,store"
+ (cond [(eq_attr "type" "idiv,lea")
+ (const_string "none")
+
+ (eq_attr "type" "fld")
+ (const_string "load")
+
+ (eq_attr "type" "test")
+ (if_then_else (match_operand 0 "memory_operand" "")
+ (const_string "load")
+ (const_string "none"))
+
+ (eq_attr "type" "compare,fcompare")
+ (if_then_else (ior (match_operand 0 "memory_operand" "")
+ (match_operand 1 "memory_operand" ""))
+ (const_string "load")
+ (const_string "none"))
+
+ (and (eq_attr "type" "integer,memory,fpop")
+ (match_operand 0 "memory_operand" ""))
+ (const_string "store")
+
+ (and (eq_attr "type" "integer,memory,fpop")
+ (match_operand 1 "memory_operand" ""))
+ (const_string "load")
+
+ (and (eq_attr "type" "binary,imul,fpmul,fpdiv")
+ (ior (match_operand 1 "memory_operand" "")
+ (match_operand 2 "memory_operand" "")))
+ (const_string "load")]
+
+ (const_string "none")))
+
;; Functional units
; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
@@ -89,11 +128,11 @@
;; Floating point
(define_function_unit "fp" 1 0
- (and (eq_attr "type" "fpop") (eq_attr "cpu" "i386,i486"))
+ (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486"))
5 5)
(define_function_unit "fp" 1 0
- (and (eq_attr "type" "fpop") (eq_attr "cpu" "pentium,pentiumpro"))
+ (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro"))
3 0)
(define_function_unit "fp" 1 0
@@ -117,12 +156,69 @@
10 10)
(define_function_unit "fp" 1 0
- (eq_attr "type" "fld")
+ (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6"))
1 0)
-(define_function_unit "integer" 1 0
- (and (eq_attr "type" "integer") (eq_attr "cpu" "!i386"))
- 2 0)
+;; K6 FPU is not pipelined.
+(define_function_unit "fp" 1 0
+ (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6"))
+ 2 2)
+
+;; i386 and i486 have one integer unit, which need not be modeled
+
+(define_function_unit "integer" 2 0
+ (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro"))
+ 1 0)
+
+(define_function_unit "integer" 2 0
+ (and (eq_attr "cpu" "k6")
+ (and (eq_attr "type" "integer,binary,test,compare")
+ (eq_attr "memory" "!load")))
+ 1 0)
+
+;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles)
+;; and a register operation (1 cycle).
+(define_function_unit "integer" 2 0
+ (and (eq_attr "cpu" "k6")
+ (and (eq_attr "type" "integer,binary,test,compare")
+ (eq_attr "memory" "load")))
+ 3 0)
+
+;; Multiplies use one of the integer units
+(define_function_unit "integer" 2 0
+ (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul"))
+ 11 11)
+
+(define_function_unit "integer" 2 0
+ (and (eq_attr "cpu" "k6") (eq_attr "type" "imul"))
+ 2 2)
+
+(define_function_unit "integer" 2 0
+ (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv"))
+ 25 25)
+
+(define_function_unit "integer" 2 0
+ (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv"))
+ 17 17)
+
+;; Pentium Pro and K6 have a separate load unit.
+(define_function_unit "load" 1 0
+ (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load"))
+ 3 0)
+
+(define_function_unit "load" 1 0
+ (and (eq_attr "cpu" "k6") (eq_attr "memory" "load"))
+ 2 0)
+
+;; Pentium Pro and K6 have a separate store unit.
+(define_function_unit "store" 1 0
+ (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store"))
+ 1 0)
+
+;; lea executes in the K6 store unit with 1 cycle latency
+(define_function_unit "store" 1 0
+ (and (eq_attr "cpu" "k6") (eq_attr "type" "lea"))
+ 1 0)
;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
@@ -140,7 +236,7 @@
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in i386.h.
-(define_attr "cpu" "i386,i486,pentium,pentiumpro"
+(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6"
(const (symbol_ref "ix86_cpu")))
(define_insn "tstsi_1"
@@ -154,7 +250,8 @@
operands[1] = const0_rtx;
return AS2 (cmp%L0,%1,%0);
-}")
+}"
+ [(set_attr "type" "test")])
(define_expand "tstsi"
[(set (cc0)
@@ -179,7 +276,8 @@
operands[1] = const0_rtx;
return AS2 (cmp%W0,%1,%0);
-}")
+}"
+ [(set_attr "type" "test")])
(define_expand "tsthi"
[(set (cc0)
@@ -204,7 +302,8 @@
operands[1] = const0_rtx;
return AS2 (cmp%B0,%1,%0);
-}")
+}"
+ [(set_attr "type" "test")])
(define_expand "tstqi"
[(set (cc0)
@@ -234,7 +333,8 @@
output_asm_insn (AS1 (fstp,%y0), operands);
return output_fp_cc0_set (insn);
-}")
+}"
+ [(set_attr "type" "test")])
;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
;; isn't IEEE compliant.
@@ -268,7 +368,8 @@
output_asm_insn (AS1 (fstp,%y0), operands);
return output_fp_cc0_set (insn);
-}")
+}"
+ [(set_attr "type" "test")])
;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
;; isn't IEEE compliant.
@@ -302,7 +403,8 @@
output_asm_insn (AS1 (fstp,%y0), operands);
return output_fp_cc0_set (insn);
-}")
+}"
+ [(set_attr "type" "test")])
;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
;; isn't IEEE compliant.
@@ -328,7 +430,8 @@
(compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
(match_operand:SI 1 "general_operand" "ri,mr")))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
- "* return AS2 (cmp%L0,%1,%0);")
+ "* return AS2 (cmp%L0,%1,%0);"
+ [(set_attr "type" "compare")])
(define_expand "cmpsi"
[(set (cc0)
@@ -351,7 +454,8 @@
(compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
(match_operand:HI 1 "general_operand" "ri,mr")))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
- "* return AS2 (cmp%W0,%1,%0);")
+ "* return AS2 (cmp%W0,%1,%0);"
+ [(set_attr "type" "compare")])
(define_expand "cmphi"
[(set (cc0)
@@ -374,7 +478,8 @@
(compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
(match_operand:QI 1 "general_operand" "qm,nq")))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
- "* return AS2 (cmp%B0,%1,%0);")
+ "* return AS2 (cmp%B0,%1,%0);"
+ [(set_attr "type" "compare")])
(define_expand "cmpqi"
[(set (cc0)
@@ -403,27 +508,8 @@
(match_operand:XF 1 "register_operand" "f")]))
(clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
-
-(define_insn ""
- [(set (cc0)
- (match_operator 2 "VOIDmode_compare_op"
- [(match_operand:XF 0 "register_operand" "f")
- (float:XF
- (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
- (clobber (match_scratch:HI 3 "=a"))]
- "TARGET_80387"
- "* return output_float_compare (insn, operands);")
-
-(define_insn ""
- [(set (cc0)
- (match_operator 2 "VOIDmode_compare_op"
- [(float:XF
- (match_operand:SI 0 "nonimmediate_operand" "rm"))
- (match_operand:XF 1 "register_operand" "f")]))
- (clobber (match_scratch:HI 3 "=a"))]
- "TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -433,7 +519,8 @@
(match_operand:DF 1 "nonimmediate_operand" "fm"))]))
(clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -443,7 +530,8 @@
(match_operand:XF 1 "register_operand" "f")]))
(clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -453,7 +541,8 @@
(match_operand:SF 1 "nonimmediate_operand" "fm"))]))
(clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -463,7 +552,8 @@
(match_operand:XF 1 "register_operand" "f")]))
(clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -471,7 +561,8 @@
(match_operand:XF 1 "register_operand" "f")))
(clobber (match_scratch:HI 2 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -481,27 +572,8 @@
(clobber (match_scratch:HI 3 "=a,a"))]
"TARGET_80387
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "* return output_float_compare (insn, operands);")
-
-(define_insn ""
- [(set (cc0)
- (match_operator 2 "VOIDmode_compare_op"
- [(match_operand:DF 0 "register_operand" "f")
- (float:DF
- (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
- (clobber (match_scratch:HI 3 "=a"))]
- "TARGET_80387"
- "* return output_float_compare (insn, operands);")
-
-(define_insn ""
- [(set (cc0)
- (match_operator 2 "VOIDmode_compare_op"
- [(float:DF
- (match_operand:SI 0 "nonimmediate_operand" "rm"))
- (match_operand:DF 1 "register_operand" "f")]))
- (clobber (match_scratch:HI 3 "=a"))]
- "TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -511,7 +583,8 @@
(match_operand:SF 1 "nonimmediate_operand" "fm"))]))
(clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -521,7 +594,8 @@
(match_operand:DF 1 "register_operand" "f")]))
(clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -531,7 +605,8 @@
(match_operand:DF 1 "nonimmediate_operand" "fm")]))
(clobber (match_scratch:HI 3 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -539,7 +614,8 @@
(match_operand:DF 1 "register_operand" "f")))
(clobber (match_scratch:HI 2 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
;; These two insns will never be generated by combine due to the mode of
;; the COMPARE.
@@ -561,7 +637,7 @@
; "TARGET_80387"
; "* return output_float_compare (insn, operands);")
-(define_insn "cmpsf_cc_1"
+(define_insn "*cmpsf_cc_1"
[(set (cc0)
(match_operator 2 "VOIDmode_compare_op"
[(match_operand:SF 0 "nonimmediate_operand" "f,fm")
@@ -569,27 +645,8 @@
(clobber (match_scratch:HI 3 "=a,a"))]
"TARGET_80387
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "* return output_float_compare (insn, operands);")
-
-(define_insn ""
- [(set (cc0)
- (match_operator 2 "VOIDmode_compare_op"
- [(match_operand:SF 0 "register_operand" "f")
- (float:SF
- (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
- (clobber (match_scratch:HI 3 "=a"))]
- "TARGET_80387"
- "* return output_float_compare (insn, operands);")
-
-(define_insn ""
- [(set (cc0)
- (match_operator 2 "VOIDmode_compare_op"
- [(float:SF
- (match_operand:SI 0 "nonimmediate_operand" "rm"))
- (match_operand:SF 1 "register_operand" "f")]))
- (clobber (match_scratch:HI 3 "=a"))]
- "TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_insn ""
[(set (cc0)
@@ -597,7 +654,8 @@
(match_operand:SF 1 "register_operand" "f")))
(clobber (match_scratch:HI 2 "=a"))]
"TARGET_80387"
- "* return output_float_compare (insn, operands);")
+ "* return output_float_compare (insn, operands);"
+ [(set_attr "type" "fcompare")])
(define_expand "cmpxf"
[(set (cc0)
@@ -711,7 +769,10 @@
/* For small integers, we may actually use testb. */
if (GET_CODE (operands[1]) == CONST_INT
&& ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
- && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
+ && (! REG_P (operands[0]) || QI_REG_P (operands[0]))
+ /* A Pentium test is pairable only with eax. Not with ah or al. */
+ && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
+ || optimize_size))
{
/* We may set the sign bit spuriously. */
@@ -757,7 +818,8 @@
return AS2 (test%L0,%1,%0);
return AS2 (test%L1,%0,%1);
-}")
+}"
+ [(set_attr "type" "compare")])
(define_insn ""
[(set (cc0)
@@ -805,7 +867,8 @@
return AS2 (test%W0,%1,%0);
return AS2 (test%W1,%0,%1);
-}")
+}"
+ [(set_attr "type" "compare")])
(define_insn ""
[(set (cc0)
@@ -818,7 +881,8 @@
return AS2 (test%B0,%1,%0);
return AS2 (test%B1,%0,%1);
-}")
+}"
+ [(set_attr "type" "compare")])
;; move instructions.
;; There is one for each machine mode,
@@ -829,13 +893,15 @@
[(set (match_operand:SI 0 "push_operand" "=<")
(match_operand:SI 1 "nonmemory_operand" "rn"))]
"flag_pic"
- "* return AS1 (push%L0,%1);")
+ "* return AS1 (push%L0,%1);"
+ [(set_attr "memory" "store")])
(define_insn ""
[(set (match_operand:SI 0 "push_operand" "=<")
(match_operand:SI 1 "nonmemory_operand" "ri"))]
"!flag_pic"
- "* return AS1 (push%L0,%1);")
+ "* return AS1 (push%L0,%1);"
+ [(set_attr "memory" "store")])
;; On a 386, it is faster to push MEM directly.
@@ -843,7 +909,9 @@
[(set (match_operand:SI 0 "push_operand" "=<")
(match_operand:SI 1 "memory_operand" "m"))]
"TARGET_PUSH_MEMORY"
- "* return AS1 (push%L0,%1);")
+ "* return AS1 (push%L0,%1);"
+ [(set_attr "type" "memory")
+ (set_attr "memory" "load")])
;; General case of fullword move.
@@ -863,7 +931,7 @@
/* Don't generate memory->memory moves, go through a register */
else if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -874,18 +942,24 @@
;; On i486, incl reg is faster than movl $1,reg.
(define_insn ""
- [(set (match_operand:SI 0 "general_operand" "=g,r")
- (match_operand:SI 1 "general_operand" "rn,im"))]
+ [(set (match_operand:SI 0 "general_operand" "=g,r,r")
+ (match_operand:SI 1 "general_operand" "rn,i,m"))]
"((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
|| (GET_CODE (operands[1]) != MEM))
&& flag_pic"
"*
{
rtx link;
- if (operands[1] == const0_rtx && REG_P (operands[0]))
+
+ /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes
+ longer. */
+ if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
+ && operands[1] == const0_rtx && REG_P (operands[0]))
return AS2 (xor%L0,%0,%0);
if (operands[1] == const1_rtx
+ /* PPRO and K6 prefer mov to inc to reduce dependencies. */
+ && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
&& ! INSN_DELETED_P (XEXP (link, 0))
@@ -901,7 +975,9 @@
return AS2 (lea%L0,%a1,%0);
return AS2 (mov%L0,%1,%0);
-}")
+}"
+ [(set_attr "type" "integer,integer,memory")
+ (set_attr "memory" "*,*,load")])
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=g,r")
@@ -912,10 +988,18 @@
"*
{
rtx link;
+
+ /* Use of xor was disabled for AMD K6 as recommended by the Optimization
+ Manual. My test shows, that this generally hurts the performance, because
+ mov is longer and takes longer to decode and decoding is the main
+ bottleneck of K6 when executing GCC code. */
+
if (operands[1] == const0_rtx && REG_P (operands[0]))
return AS2 (xor%L0,%0,%0);
if (operands[1] == const1_rtx
+ /* PPRO and K6 prefer mov to inc to reduce dependencies. */
+ && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
&& ! INSN_DELETED_P (XEXP (link, 0))
@@ -928,19 +1012,25 @@
return AS1 (inc%L0,%0);
return AS2 (mov%L0,%1,%0);
-}")
+}"
+ [(set_attr "type" "integer,memory")
+ (set_attr "memory" "*,load")])
(define_insn ""
[(set (match_operand:HI 0 "push_operand" "=<")
(match_operand:HI 1 "nonmemory_operand" "ri"))]
""
- "* return AS1 (push%W0,%1);")
+ "* return AS1 (push%W0,%1);"
+ [(set_attr "type" "memory")
+ (set_attr "memory" "store")])
(define_insn ""
[(set (match_operand:HI 0 "push_operand" "=<")
(match_operand:HI 1 "memory_operand" "m"))]
"TARGET_PUSH_MEMORY"
- "* return AS1 (push%W0,%1);")
+ "* return AS1 (push%W0,%1);"
+ [(set_attr "type" "memory")
+ (set_attr "memory" "load")])
;; On i486, an incl and movl are both faster than incw and movw.
@@ -952,7 +1042,7 @@
{
/* Don't generate memory->memory moves, go through a register */
if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -971,6 +1061,8 @@
return AS2 (xor%L0,%k0,%k0);
if (REG_P (operands[0]) && operands[1] == const1_rtx
+ /* PPRO and K6 prefer mov to inc to reduce dependencies. */
+ && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
&& ! INSN_DELETED_P (XEXP (link, 0))
@@ -989,7 +1081,7 @@
operands[1] = i386_sext16_if_const (operands[1]);
return AS2 (mov%L0,%k1,%k0);
}
- if (TARGET_PENTIUMPRO)
+ if (! TARGET_ZERO_EXTEND_WITH_AND)
{
/* movzwl is faster than movw on the Pentium Pro,
* although not as fast as an aligned movl. */
@@ -1002,7 +1094,9 @@
}
return AS2 (mov%W0,%1,%0);
-}")
+}"
+ [(set_attr "type" "integer,memory")
+ (set_attr "memory" "*,load")])
(define_expand "movstricthi"
[(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
@@ -1012,7 +1106,7 @@
{
/* Don't generate memory->memory moves, go through a register */
if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -1027,10 +1121,18 @@
"*
{
rtx link;
+
+ /* Use of xor was disabled for AMD K6 as recommended by the Optimization
+ Manual. My test shows, that this generally hurts the performance, because
+ mov is longer and takes longer to decode and decoding is the main
+ bottleneck of K6 when executing GCC code. */
+
if (operands[1] == const0_rtx && REG_P (operands[0]))
return AS2 (xor%W0,%0,%0);
if (operands[1] == const1_rtx
+ /* PPRO and K6 prefer mov to inc to reduce dependencies. */
+ && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
&& ! INSN_DELETED_P (XEXP (link, 0))
@@ -1043,7 +1145,8 @@
return AS1 (inc%W0,%0);
return AS2 (mov%W0,%1,%0);
-}")
+}"
+ [(set_attr "type" "integer,memory")])
;; emit_push_insn when it calls move_by_pieces
;; requires an insn to "push a byte".
@@ -1078,7 +1181,7 @@
{
/* Don't generate memory->memory moves, go through a register */
if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -1093,10 +1196,12 @@
"*
{
rtx link;
- if (operands[1] == const0_rtx && REG_P (operands[0]))
- return AS2 (xor%L0,%k0,%k0);
+
+ /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.
+ It is at least as fast as xor on any processor except a Pentium. */
if (operands[1] == const1_rtx
+ && TARGET_PENTIUM
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
&& ! INSN_DELETED_P (XEXP (link, 0))
@@ -1138,7 +1243,7 @@
{
/* Don't generate memory->memory moves, go through a register */
if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -1153,10 +1258,11 @@
"*
{
rtx link;
- if (operands[1] == const0_rtx && REG_P (operands[0]))
- return AS2 (xor%B0,%0,%0);
+
+ /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */
if (operands[1] == const1_rtx
+ && TARGET_PENTIUM
&& ! NON_QI_REG_P (operands[0])
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
@@ -1182,7 +1288,8 @@
(define_insn "movsf_push"
[(set (match_operand:SF 0 "push_operand" "=<,<")
(match_operand:SF 1 "general_operand" "*rfF,m"))]
- "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
+ "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
+ || reload_in_progress || reload_completed"
"*
{
if (STACK_REG_P (operands[1]))
@@ -1209,11 +1316,15 @@
return AS1 (push%L0,%1);
}")
-(define_insn "movsf_push_memory"
- [(set (match_operand:SF 0 "push_operand" "=<")
- (match_operand:SF 1 "memory_operand" "m"))]
- "TARGET_PUSH_MEMORY"
- "* return AS1 (push%L0,%1);")
+(define_split
+ [(set (match_operand:SF 0 "push_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ "reload_completed && STACK_REG_P (operands[1])"
+ [(set (reg:SI 7)
+ (minus:SI (reg:SI 7) (const_int 4)))
+ (set (mem:SF (reg:SI 7))
+ (match_dup 1))]
+ "")
(define_expand "movsf"
[(set (match_operand:SF 0 "general_operand" "")
@@ -1223,7 +1334,7 @@
{
/* Don't generate memory->memory moves, go through a register */
if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -1231,34 +1342,21 @@
}
/* If we are loading a floating point constant that isn't 0 or 1
- into a register, indicate we need the pic register loaded. This could
- be optimized into stores of constants if the target eventually moves
- to memory, but better safe than sorry. */
+ into a register, force the value to memory now, since we'll
+ get better code out the back end. */
else if ((reload_in_progress | reload_completed) == 0
- && GET_CODE (operands[0]) != MEM
- && GET_CODE (operands[1]) == CONST_DOUBLE
- && !standard_80387_constant_p (operands[1]))
+ && GET_CODE (operands[0]) != MEM
+ && GET_CODE (operands[1]) == CONST_DOUBLE
+ && !standard_80387_constant_p (operands[1]))
{
- rtx insn, note, fp_const;
-
- fp_const = force_const_mem (SFmode, operands[1]);
- if (flag_pic)
- current_function_uses_pic_offset_table = 1;
-
- insn = emit_insn (gen_rtx_SET (SFmode, operands[0], fp_const));
- note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
-
- if (note)
- XEXP (note, 0) = operands[1];
- else
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
+ operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
}
}")
;; For the purposes of regclass, prefer FLOAT_REGS.
(define_insn ""
- [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm")
- (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m")
+ (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))]
"(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
"*
{
@@ -1274,20 +1372,6 @@
return AS1 (fld,%y0);
}
- /* Handle a transfer between the 387 and a 386 register */
-
- if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
- RET;
- }
-
- if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
- {
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
-
/* Handle other kinds of writes from the 387 */
if (STACK_TOP_P (operands[1]))
@@ -1327,10 +1411,12 @@
return AS1 (fxch,%0);
}")
+
(define_insn "movdf_push"
[(set (match_operand:DF 0 "push_operand" "=<,<")
(match_operand:DF 1 "general_operand" "*rfF,o"))]
- "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
+ "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
+ || reload_in_progress || reload_completed"
"*
{
if (STACK_REG_P (operands[1]))
@@ -1357,11 +1443,15 @@
return output_move_double (operands);
}")
-(define_insn "movdf_push_memory"
- [(set (match_operand:DF 0 "push_operand" "=<")
- (match_operand:DF 1 "memory_operand" "o"))]
- "TARGET_PUSH_MEMORY"
- "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),0,0);")
+(define_split
+ [(set (match_operand:DF 0 "push_operand" "")
+ (match_operand:DF 1 "register_operand" ""))]
+ "reload_completed && STACK_REG_P (operands[1])"
+ [(set (reg:SI 7)
+ (minus:SI (reg:SI 7) (const_int 8)))
+ (set (mem:DF (reg:SI 7))
+ (match_dup 1))]
+ "")
(define_expand "movdf"
[(set (match_operand:DF 0 "general_operand" "")
@@ -1371,7 +1461,7 @@
{
/* Don't generate memory->memory moves, go through a register */
if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -1383,30 +1473,18 @@
optimized into stores of constants if the target eventually moves to
memory, but better safe than sorry. */
else if ((reload_in_progress | reload_completed) == 0
- && GET_CODE (operands[0]) != MEM
- && GET_CODE (operands[1]) == CONST_DOUBLE
- && !standard_80387_constant_p (operands[1]))
+ && GET_CODE (operands[0]) != MEM
+ && GET_CODE (operands[1]) == CONST_DOUBLE
+ && !standard_80387_constant_p (operands[1]))
{
- rtx insn, note, fp_const;
-
- fp_const = force_const_mem (DFmode, operands[1]);
- if (flag_pic)
- current_function_uses_pic_offset_table = 1;
-
- insn = emit_insn (gen_rtx_SET (DFmode, operands[0], fp_const));
- note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
-
- if (note)
- XEXP (note, 0) = operands[1];
- else
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
+ operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
}
}")
;; For the purposes of regclass, prefer FLOAT_REGS.
(define_insn ""
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
- (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o")
+ (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))]
"(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
|| (GET_CODE (operands[1]) != MEM)"
"*
@@ -1423,20 +1501,6 @@
return AS1 (fld,%y0);
}
- /* Handle a transfer between the 387 and a 386 register */
-
- if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
- RET;
- }
-
- if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
- {
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
-
/* Handle other kinds of writes from the 387 */
if (STACK_TOP_P (operands[1]))
@@ -1480,7 +1544,8 @@
(define_insn "movxf_push"
[(set (match_operand:XF 0 "push_operand" "=<,<")
(match_operand:XF 1 "general_operand" "*rfF,o"))]
- "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
+ "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
+ || reload_in_progress || reload_completed"
"*
{
if (STACK_REG_P (operands[1]))
@@ -1506,11 +1571,15 @@
return output_move_double (operands);
}")
-(define_insn "movxf_push_memory"
- [(set (match_operand:XF 0 "push_operand" "=<")
- (match_operand:XF 1 "memory_operand" "o"))]
- "TARGET_PUSH_MEMORY"
- "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),0,0);")
+(define_split
+ [(set (match_operand:XF 0 "push_operand" "")
+ (match_operand:XF 1 "register_operand" ""))]
+ "reload_completed && STACK_REG_P (operands[1])"
+ [(set (reg:SI 7)
+ (minus:SI (reg:SI 7) (const_int 12)))
+ (set (mem:XF (reg:SI 7))
+ (match_dup 1))]
+ "")
(define_expand "movxf"
[(set (match_operand:XF 0 "general_operand" "")
@@ -1520,7 +1589,7 @@
{
/* Don't generate memory->memory moves, go through a register */
if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -1532,30 +1601,18 @@
be optimized into stores of constants if the target eventually moves
to memory, but better safe than sorry. */
else if ((reload_in_progress | reload_completed) == 0
- && GET_CODE (operands[0]) != MEM
- && GET_CODE (operands[1]) == CONST_DOUBLE
- && !standard_80387_constant_p (operands[1]))
+ && GET_CODE (operands[0]) != MEM
+ && GET_CODE (operands[1]) == CONST_DOUBLE
+ && !standard_80387_constant_p (operands[1]))
{
- rtx insn, note, fp_const;
-
- fp_const = force_const_mem (XFmode, operands[1]);
- if (flag_pic)
- current_function_uses_pic_offset_table = 1;
-
- insn = emit_insn (gen_rtx_SET (XFmode, operands[0], fp_const));
- note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
-
- if (note)
- XEXP (note, 0) = operands[1];
- else
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
+ operands[1] = validize_mem (force_const_mem (XFmode, operands[1]));
}
}")
(define_insn ""
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
- (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o")
+ (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))]
"(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
|| (GET_CODE (operands[1]) != MEM)"
"*
@@ -1572,20 +1629,6 @@
return AS1 (fld,%y0);
}
- /* Handle a transfer between the 387 and a 386 register */
-
- if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
- RET;
- }
-
- if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
- {
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
-
/* Handle other kinds of writes from the 387 */
if (STACK_TOP_P (operands[1]))
@@ -1644,7 +1687,7 @@
{
/* Don't generate memory->memory moves, go through a register */
if (TARGET_MOVE
- && (reload_in_progress | reload_completed) == 0
+ && no_new_pseudos == 0
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (operands[1]) == MEM)
{
@@ -1657,8 +1700,44 @@
(match_operand:DI 1 "general_operand" "riF,m"))]
"(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
|| (GET_CODE (operands[1]) != MEM)"
- "* return output_move_double (operands);")
+ "* return output_move_double (operands);"
+ [(set_attr "type" "integer,memory")
+ (set_attr "memory" "*,load")])
+
+(define_split
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ "reload_completed
+ && (offsettable_memref_p (operands[0])
+ || nonmemory_operand (operands[0], DImode))
+ && (offsettable_memref_p (operands[1])
+ || nonmemory_operand (operands[1], DImode))
+ && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]),
+ operands[1])
+ || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]),
+ operands[1]))"
+ [(set (match_dup 2)
+ (match_dup 4))
+ (set (match_dup 3)
+ (match_dup 5))]
+ "
+{
+ split_di (&operands[0], 1, &operands[2], &operands[3]);
+ split_di (&operands[1], 1, &operands[4], &operands[5]);
+
+ if (reg_overlap_mentioned_p (operands[2], operands[1]))
+ {
+ rtx tmp;
+
+ tmp = operands[2];
+ operands[2] = operands[3];
+ operands[3] = tmp;
+ tmp = operands[4];
+ operands[4] = operands[5];
+ operands[5] = tmp;
+ }
+}")
;;- conversion instructions
;;- NONE
@@ -1666,10 +1745,25 @@
;;- zero extension instructions
;; See comments by `andsi' for when andl is faster than movzx.
-(define_insn "zero_extendhisi2"
+(define_expand "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
+ ""
+ "")
+
+;; When optimizing for the PPro/PII or code size, always use movzwl.
+;; We want to use a different pattern so we can use different constraints
+;; than the generic pattern.
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
+ "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
+ "* return AS2 (movz%W0%L0,%1,%0);")
+
+(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
- ""
+ "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
"*
{
rtx xops[2];
@@ -1730,10 +1824,23 @@
(const_int 65535)))]
"operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
-(define_insn "zero_extendqihi2"
+(define_expand "zero_extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ ""
+ "")
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+ "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
+
+ "* return AS2 (movz%B0%W0,%1,%0);")
+
+(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
- ""
+ "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
"*
{
rtx xops[2];
@@ -1811,10 +1918,22 @@
FAIL;
operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
-(define_insn "zero_extendqisi2"
+(define_expand "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ ""
+ "")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+ "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
+ "* return AS2 (movz%B0%L0,%1,%0);")
+
+(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
- ""
+ "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
"*
{
rtx xops[2];
@@ -1899,58 +2018,105 @@
"operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
(define_insn "zero_extendsidi2"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
- (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
+ (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
""
- "*
- {
- rtx high[2], low[2], xops[4];
-
- if (REG_P (operands[0]) && REG_P (operands[1])
- && REGNO (operands[0]) == REGNO (operands[1]))
- {
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- return AS2 (xor%L0,%0,%0);
- }
-
- split_di (operands, 1, low, high);
- xops[0] = low[0];
- xops[1] = operands[1];
- xops[2] = high[0];
- xops[3] = const0_rtx;
-
- output_asm_insn (AS2 (mov%L0,%1,%0), xops);
- if (GET_CODE (low[0]) == MEM)
- output_asm_insn (AS2 (mov%L2,%3,%2), xops);
- else
- output_asm_insn (AS2 (xor%L2,%2,%2), xops);
+ "#")
- RET;
-}")
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
+ "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
+ [(set (match_dup 4) (const_int 0))]
+ "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+(define_split
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
+ "reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 4) (const_int 0))]
+ "split_di (&operands[0], 1, &operands[3], &operands[4]);")
;;- sign extension instructions
(define_insn "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r")))
+ (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
""
- "*
+ "#")
+
+;; Extend to memory case when source register does die.
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
+ "(flow2_completed
+ && dead_or_set_p (insn, operands[1])
+ && !reg_mentioned_p (operands[1], operands[0]))"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
+ (set (match_dup 4) (match_dup 1))]
+ "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+;; Extend to memory case when source register does not die.
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
+ "flow2_completed"
+ [(const_int 0)]
+ "
+{
+ split_di (&operands[0], 1, &operands[3], &operands[4]);
+
+ emit_move_insn (operands[3], operands[1]);
+
+ /* Generate a cltd if possible and doing so it profitable. */
+ if (true_regnum (operands[1]) == 0
+ && true_regnum (operands[2]) == 1
+ && (optimize_size || !TARGET_PENTIUM))
+ {
+ emit_insn (gen_ashrsi3_31 (operands[2], operands[1]));
+ }
+ else
+ {
+ emit_move_insn (operands[2], operands[1]);
+ emit_insn (gen_ashrsi3_31 (operands[2], operands[2]));
+ }
+ emit_move_insn (operands[4], operands[2]);
+ DONE;
+}")
+
+;; Extend to register case. Optimize case where source and destination
+;; registers match and cases where we can use cltd.
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_scratch:SI 2 ""))]
+ "reload_completed"
+ [(const_int 0)]
+ "
{
- if (REGNO (operands[0]) == 0)
+ split_di (&operands[0], 1, &operands[3], &operands[4]);
+
+ if (true_regnum (operands[3]) != true_regnum (operands[1]))
+ emit_move_insn (operands[3], operands[1]);
+
+ /* Generate a cltd if possible and doing so it profitable. */
+ if (true_regnum (operands[3]) == 0
+ && (optimize_size || !TARGET_PENTIUM))
{
- /* This used to be cwtl, but that extends HI to SI somehow. */
-#ifdef INTEL_SYNTAX
- return \"cdq\";
-#else
- return \"cltd\";
-#endif
+ emit_insn (gen_ashrsi3_31 (operands[4], operands[3]));
+ DONE;
}
- operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- output_asm_insn (AS2 (mov%L0,%0,%1), operands);
+ if (true_regnum (operands[4]) != true_regnum (operands[1]))
+ emit_move_insn (operands[4], operands[1]);
- operands[0] = GEN_INT (31);
- return AS2 (sar%L1,%0,%1);
+ emit_insn (gen_ashrsi3_31 (operands[4], operands[4]));
+ DONE;
}")
;; Note that the i386 programmers' manual says that the opcodes
@@ -1964,7 +2130,8 @@
"*
{
if (REGNO (operands[0]) == 0
- && REG_P (operands[1]) && REGNO (operands[1]) == 0)
+ && REG_P (operands[1]) && REGNO (operands[1]) == 0
+ && (optimize_size || ix86_cpu != PROCESSOR_K6))
#ifdef INTEL_SYNTAX
return \"cwde\";
#else
@@ -1985,7 +2152,8 @@
"*
{
if (REGNO (operands[0]) == 0
- && REG_P (operands[1]) && REGNO (operands[1]) == 0)
+ && REG_P (operands[1]) && REGNO (operands[1]) == 0
+ && (optimize_size || ix86_cpu != PROCESSOR_K6))
return \"cbtw\";
#ifdef INTEL_SYNTAX
@@ -2069,110 +2237,237 @@
;; Conversions between float and double.
-(define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f")
- (float_extend:DF
- (match_operand:SF 1 "nonimmediate_operand" "f,fm")))]
+(define_expand "extendsfdf2"
+ [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (float_extend:DF
+ (match_operand:SF 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))])]
"TARGET_80387"
+ "
+{
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+ operands[1] = force_reg (SFmode, operands[1]);
+
+ operands[2] = assign_386_stack_local (SFmode, 0);
+ operands[3] = assign_386_stack_local (DFmode, 0);
+}")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r")
+ (float_extend:DF
+ (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
+ (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
+ "TARGET_80387 && (GET_CODE (operands[0]) != MEM
+ || GET_CODE (operands[1]) != MEM)"
"*
{
- int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+ output_float_extend (insn, operands);
+ return \"\";
+}"
+ [(set_attr "type" "fld,fpop,fld,fpop")])
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
- RET;
- }
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float_extend:DF (match_operand:SF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))
+ (clobber (match_operand:DF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float_extend:DF (match_dup 2)))]
+ "")
- if (NON_STACK_REG_P (operands[0]))
- {
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float_extend:DF (match_operand:SF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))
+ (clobber (match_operand:DF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
+ [(set (match_dup 3)
+ (float_extend:DF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 3))]
+ "")
- if (STACK_TOP_P (operands[0]))
- return AS1 (fld%z1,%y1);
+(define_split
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))
+ (clobber (match_operand:DF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_extend:DF (match_dup 1)))]
+ "")
- if (GET_CODE (operands[0]) == MEM)
- {
- if (stack_top_dies)
- return AS1 (fstp%z0,%y0);
- else
- return AS1 (fst%z0,%y0);
- }
+(define_insn ""
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
+ "TARGET_80387 && (GET_CODE (operands[0]) != MEM
+ || GET_CODE (operands[1]) != MEM)"
+ "*
+{
+ output_float_extend (insn, operands);
+ return \"\";
+}"
+ [(set_attr "type" "fld,fpop")])
+
+(define_expand "extenddfxf2"
+ [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
+ (float_extend:XF
+ (match_operand:DF 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))])]
+ "TARGET_80387"
+ "
+{
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+ operands[1] = force_reg (DFmode, operands[1]);
- abort ();
+ operands[2] = assign_386_stack_local (DFmode, 0);
+ operands[3] = assign_386_stack_local (XFmode, 0);
}")
-(define_insn "extenddfxf2"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
+(define_insn ""
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
(float_extend:XF
- (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
- "TARGET_80387"
+ (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f")))
+ (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m"))
+ (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
+ "TARGET_80387 && (GET_CODE (operands[0]) != MEM
+ || GET_CODE (operands[1]) != MEM)"
"*
{
- int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+ output_float_extend (insn, operands);
+ return \"\";
+}"
+ [(set_attr "type" "fld,fpop,fld,fpop")])
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
- RET;
- }
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))
+ (clobber (match_operand:XF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float_extend:XF (match_dup 2)))]
+ "")
- if (NON_STACK_REG_P (operands[0]))
- {
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))
+ (clobber (match_operand:XF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
+ [(set (match_dup 3)
+ (float_extend:XF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 3))]
+ "")
- if (STACK_TOP_P (operands[0]))
- return AS1 (fld%z1,%y1);
+(define_split
+ [(set (match_operand:XF 0 "nonimmediate_operand" "")
+ (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))
+ (clobber (match_operand:XF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_extend:XF (match_dup 1)))]
+ "")
- if (GET_CODE (operands[0]) == MEM)
- {
- output_asm_insn (AS1 (fstp%z0,%y0), operands);
- if (! stack_top_dies)
- return AS1 (fld%z0,%y0);
- RET;
- }
+(define_insn ""
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
+ (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
+ "TARGET_80387 && (GET_CODE (operands[0]) != MEM
+ || GET_CODE (operands[1]) != MEM)"
+ "*
+{
+ output_float_extend (insn, operands);
+ return \"\";
+}"
+ [(set_attr "type" "fld,fpop")])
+
+(define_expand "extendsfxf2"
+ [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
+ (float_extend:XF
+ (match_operand:SF 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))])]
+ "TARGET_80387"
+ "
+{
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+ operands[1] = force_reg (SFmode, operands[1]);
- abort ();
+ operands[2] = assign_386_stack_local (SFmode, 0);
+ operands[3] = assign_386_stack_local (XFmode, 0);
}")
-(define_insn "extendsfxf2"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
+(define_insn ""
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
(float_extend:XF
- (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
- "TARGET_80387"
+ (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
+ (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
+ "TARGET_80387 && (GET_CODE (operands[0]) != MEM
+ || GET_CODE (operands[1]) != MEM)"
"*
{
- int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
-
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
- RET;
- }
+ output_float_extend (insn, operands);
+ return \"\";
+}"
+ [(set_attr "type" "fld,fpop,fld,fpop")])
- if (NON_STACK_REG_P (operands[0]))
- {
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))
+ (clobber (match_operand:XF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float_extend:XF (match_dup 2)))]
+ "")
- if (STACK_TOP_P (operands[0]))
- return AS1 (fld%z1,%y1);
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))
+ (clobber (match_operand:XF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
+ [(set (match_dup 3)
+ (float_extend:XF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 3))]
+ "")
- if (GET_CODE (operands[0]) == MEM)
- {
- output_asm_insn (AS1 (fstp%z0,%y0), operands);
- if (! stack_top_dies)
- return AS1 (fld%z0,%y0);
- RET;
- }
+(define_split
+ [(set (match_operand:XF 0 "nonimmediate_operand" "")
+ (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))
+ (clobber (match_operand:XF 3 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_extend:XF (match_dup 1)))]
+ "")
- abort ();
-}")
+(define_insn ""
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
+ (float_extend:XF
+ (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
+ "TARGET_80387 && (GET_CODE (operands[0]) != MEM
+ || GET_CODE (operands[1]) != MEM)"
+ "*
+{
+ output_float_extend (insn, operands);
+ return \"\";
+}"
+ [(set_attr "type" "fld,fpop")])
(define_expand "truncdfsf2"
[(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
@@ -2185,480 +2480,764 @@
operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
}")
-;; This cannot output into an f-reg because there is no way to be sure
-;; of truncating in that case. Otherwise this is just like a simple move
-;; insn. So we pretend we can output to a reg in order to get better
-;; register preferencing, but we really use a stack slot.
-
(define_insn ""
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
(float_truncate:SF
- (match_operand:DF 1 "register_operand" "0,f")))
- (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
+ (match_operand:DF 1 "register_operand" "0,f,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
"TARGET_80387"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+ rtx xops[1];
- if (GET_CODE (operands[0]) == MEM)
- {
- if (stack_top_dies)
- return AS1 (fstp%z0,%0);
- else
- return AS1 (fst%z0,%0);
- }
- else if (STACK_TOP_P (operands[0]))
- {
- output_asm_insn (AS1 (fstp%z2,%y2), operands);
- return AS1 (fld%z2,%y2);
- }
+ xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
+
+ if (stack_top_dies || STACK_REG_P (operands[0]))
+ output_asm_insn (AS1 (fstp%z0,%0), xops);
else
- abort ();
-}")
+ output_asm_insn (AS1 (fst%z0,%0), xops);
-(define_insn "truncxfsf2"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
- (float_truncate:SF
- (match_operand:XF 1 "register_operand" "f,f")))]
+ if (STACK_REG_P (operands[0]))
+ return AS1 (fld%z2,%2);
+ else if (NON_STACK_REG_P (operands[0]))
+ return AS2 (mov%L0,%2,%0);
+
+ return \"\";
+}"
+ [(set_attr "type" "fpop")])
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (float_truncate:SF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 2))]
+ "")
+
+(define_split
+ [(set (match_operand:SF 0 "memory_operand" "")
+ (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_truncate:SF (match_dup 1)))]
+ "")
+
+;; This cannot output into an f-reg because there is no way to be sure
+;; of truncating in that case.
+
+(define_insn ""
+ [(set (match_operand:SF 0 "memory_operand" "=m")
+ (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
"TARGET_80387"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
- if (NON_STACK_REG_P (operands[0]))
- {
- if (stack_top_dies == 0)
- {
- output_asm_insn (AS1 (fld,%y1), operands);
- stack_top_dies = 1;
- }
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
- else if (GET_CODE (operands[0]) == MEM)
- {
- if (stack_top_dies)
- return AS1 (fstp%z0,%0);
- else
- {
- output_asm_insn (AS1 (fld,%y1), operands);
- return AS1 (fstp%z0,%0);
- }
- }
+ if (stack_top_dies)
+ return AS1 (fstp%z0,%0);
else
- abort ();
+ return AS1 (fst%z0,%0);
+}"
+ [(set_attr "type" "fpop")])
+
+(define_expand "truncxfsf2"
+ [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ (float_truncate:SF
+ (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_dup 2))])]
+ "TARGET_80387"
+ "
+{
+ operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
}")
-(define_insn "truncxfdf2"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
- (float_truncate:DF
- (match_operand:XF 1 "register_operand" "f,f")))]
+(define_insn ""
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
+ (float_truncate:SF
+ (match_operand:XF 1 "register_operand" "0,f,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
"TARGET_80387"
"*
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+ rtx xops[1];
- if (NON_STACK_REG_P (operands[0]))
- {
- if (stack_top_dies == 0)
- {
- output_asm_insn (AS1 (fld,%y1), operands);
- stack_top_dies = 1;
- }
- output_to_reg (operands[0], stack_top_dies, 0);
- RET;
- }
- else if (GET_CODE (operands[0]) == MEM)
- {
- if (stack_top_dies)
- return AS1 (fstp%z0,%0);
- else
- {
- output_asm_insn (AS1 (fld,%y1), operands);
- return AS1 (fstp%z0,%0);
- }
- }
+ xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
+
+ if (stack_top_dies || STACK_REG_P (operands[0]))
+ output_asm_insn (AS1 (fstp%z0,%0), xops);
else
- abort ();
-}")
+ output_asm_insn (AS1 (fst%z0,%0), xops);
-
-;; The 387 requires that the stack top dies after converting to DImode.
+ if (STACK_REG_P (operands[0]))
+ return AS1 (fld%z2,%2);
+ else if (NON_STACK_REG_P (operands[0]))
+ return AS2 (mov%L0,%2,%0);
-;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
-;; doing a signed conversion to DImode, and then taking just the low
-;; part.
+ return \"\";
+}"
+ [(set_attr "type" "fpop")])
-(define_expand "fixuns_truncxfsi2"
- [(set (match_dup 4)
- (match_operand:XF 1 "register_operand" ""))
- (parallel [(set (match_dup 2)
- (fix:DI (fix:XF (match_dup 4))))
- (clobber (match_dup 4))
- (clobber (match_dup 5))
- (clobber (match_dup 6))
- (clobber (match_scratch:SI 7 ""))])
- (set (match_operand:SI 0 "general_operand" "")
- (match_dup 3))]
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (float_truncate:SF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 2))]
+ "")
+
+(define_split
+ [(set (match_operand:SF 0 "memory_operand" "")
+ (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_truncate:SF (match_dup 1)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "memory_operand" "=m")
+ (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
"TARGET_80387"
- "
+ "*
{
- operands[2] = gen_reg_rtx (DImode);
- operands[3] = gen_lowpart (SImode, operands[2]);
- operands[4] = gen_reg_rtx (XFmode);
- operands[5] = (rtx) assign_386_stack_local (SImode, 0);
- operands[6] = (rtx) assign_386_stack_local (DImode, 1);
-}")
+ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
-(define_expand "fixuns_truncdfsi2"
- [(set (match_dup 4)
- (match_operand:DF 1 "register_operand" ""))
- (parallel [(set (match_dup 2)
- (fix:DI (fix:DF (match_dup 4))))
- (clobber (match_dup 4))
- (clobber (match_dup 5))
- (clobber (match_dup 6))
- (clobber (match_scratch:SI 7 ""))])
- (set (match_operand:SI 0 "general_operand" "")
- (match_dup 3))]
+ if (stack_top_dies)
+ return AS1 (fstp%z0,%0);
+ else
+ return AS1 (fst%z0,%0);
+}"
+ [(set_attr "type" "fpop")])
+
+(define_expand "truncxfdf2"
+ [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (float_truncate:DF
+ (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_dup 2))])]
"TARGET_80387"
"
{
- operands[2] = gen_reg_rtx (DImode);
- operands[3] = gen_lowpart (SImode, operands[2]);
- operands[4] = gen_reg_rtx (DFmode);
- operands[5] = (rtx) assign_386_stack_local (SImode, 0);
- operands[6] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[2] = (rtx) assign_386_stack_local (DFmode, 0);
}")
-(define_expand "fixuns_truncsfsi2"
- [(set (match_dup 4)
- (match_operand:SF 1 "register_operand" ""))
- (parallel [(set (match_dup 2)
- (fix:DI (fix:SF (match_dup 4))))
- (clobber (match_dup 4))
- (clobber (match_dup 5))
- (clobber (match_dup 6))
- (clobber (match_scratch:SI 7 ""))])
- (set (match_operand:SI 0 "general_operand" "")
- (match_dup 3))]
+(define_insn ""
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r")
+ (float_truncate:DF
+ (match_operand:XF 1 "register_operand" "0,f,f")))
+ (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))]
"TARGET_80387"
- "
+ "*
{
- operands[2] = gen_reg_rtx (DImode);
- operands[3] = gen_lowpart (SImode, operands[2]);
- operands[4] = gen_reg_rtx (SFmode);
- operands[5] = (rtx) assign_386_stack_local (SImode, 0);
- operands[6] = (rtx) assign_386_stack_local (DImode, 1);
-}")
+ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
+ rtx xops[2];
-;; Signed conversion to DImode.
+ xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
-(define_expand "fix_truncxfdi2"
+ if (stack_top_dies || STACK_REG_P (operands[0]))
+ output_asm_insn (AS1 (fstp%z0,%0), xops);
+ else
+ output_asm_insn (AS1 (fst%z0,%0), xops);
+
+ if (STACK_REG_P (operands[0]))
+ return AS1 (fld%z2,%2);
+ else if (NON_STACK_REG_P (operands[0]))
+ {
+ xops[0] = operands[0];
+ xops[1] = operands[2];
+ output_asm_insn (output_move_double (xops), xops);
+ }
+
+ return \"\";
+}"
+ [(set_attr "type" "fpop")])
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
[(set (match_dup 2)
- (match_operand:XF 1 "register_operand" ""))
- (parallel [(set (match_operand:DI 0 "general_operand" "")
- (fix:DI (fix:XF (match_dup 2))))
- (clobber (match_dup 2))
- (clobber (match_dup 3))
- (clobber (match_dup 4))
- (clobber (match_scratch:SI 5 ""))])]
+ (float_truncate:DF (match_dup 1)))
+ (set (match_dup 0)
+ (match_dup 2))]
+ "")
+
+(define_split
+ [(set (match_operand:DF 0 "memory_operand" "")
+ (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float_truncate:DF (match_dup 1)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "memory_operand" "=m")
+ (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
"TARGET_80387"
- "
+ "*
{
- operands[1] = copy_to_mode_reg (XFmode, operands[1]);
- operands[2] = gen_reg_rtx (XFmode);
- operands[3] = (rtx) assign_386_stack_local (SImode, 0);
- operands[4] = (rtx) assign_386_stack_local (DImode, 1);
-}")
+ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
-(define_expand "fix_truncdfdi2"
- [(set (match_dup 2)
- (match_operand:DF 1 "register_operand" ""))
- (parallel [(set (match_operand:DI 0 "general_operand" "")
- (fix:DI (fix:DF (match_dup 2))))
+ if (stack_top_dies)
+ return AS1 (fstp%z0,%0);
+ else
+ return AS1 (fst%z0,%0);
+}"
+ [(set_attr "type" "fpop")])
+
+;; Conversions between floating point and fix point.
+
+(define_expand "fix_truncsfsi2"
+ [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_dup 4))
- (clobber (match_scratch:SI 5 ""))])]
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
- operands[1] = copy_to_mode_reg (DFmode, operands[1]);
- operands[2] = gen_reg_rtx (DFmode);
- operands[3] = (rtx) assign_386_stack_local (SImode, 0);
- operands[4] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (SImode, 0);
}")
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
+ (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:SI 4 "memory_operand" "m,m"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
+ "TARGET_80387"
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
+
(define_expand "fix_truncsfdi2"
- [(set (match_dup 2)
- (match_operand:SF 1 "register_operand" ""))
- (parallel [(set (match_operand:DI 0 "general_operand" "")
- (fix:DI (fix:SF (match_dup 2))))
+ [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
+ (clobber (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_dup 4))
- (clobber (match_scratch:SI 5 ""))])]
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
operands[1] = copy_to_mode_reg (SFmode, operands[1]);
- operands[2] = gen_reg_rtx (SFmode);
- operands[3] = (rtx) assign_386_stack_local (SImode, 0);
- operands[4] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (DImode, 0);
}")
-;; These match a signed conversion of either DFmode or SFmode to DImode.
-
(define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
- (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f"))))
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
+ (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
(clobber (match_dup 1))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:DI 4 "memory_operand" "m,o"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
-(define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
- (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f"))))
- (clobber (match_dup 1))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+(define_expand "fix_truncdfsi2"
+ [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (fix:SI (fix:DF (match_operand:DF 1 "register_operand" ""))))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
+ "
+{
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (SImode, 0);
+}")
(define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
- (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f"))))
- (clobber (match_dup 1))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
+ (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:SI 4 "memory_operand" "m,m"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
-
-;; Signed MODE_FLOAT conversion to SImode.
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
-(define_expand "fix_truncxfsi2"
- [(parallel [(set (match_operand:SI 0 "general_operand" "")
- (fix:SI
- (fix:XF (match_operand:XF 1 "register_operand" ""))))
+(define_expand "fix_truncdfdi2"
+ [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
+ (clobber (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
- (clobber (match_scratch:SI 4 ""))])]
+ (clobber (match_dup 4))
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
- operands[2] = (rtx) assign_386_stack_local (SImode, 0);
- operands[3] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[1] = copy_to_mode_reg (DFmode, operands[1]);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (DImode, 0);
}")
-(define_expand "fix_truncdfsi2"
- [(parallel [(set (match_operand:SI 0 "general_operand" "")
- (fix:SI
- (fix:DF (match_operand:DF 1 "register_operand" ""))))
+(define_insn ""
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
+ (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
+ (clobber (match_dup 1))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:DI 4 "memory_operand" "m,o"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
+ "TARGET_80387"
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "fix_truncxfsi2"
+ [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (fix:SI (fix:XF (match_operand:XF 1 "register_operand" ""))))
(clobber (match_dup 2))
(clobber (match_dup 3))
- (clobber (match_scratch:SI 4 ""))])]
+ (clobber (match_dup 4))
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
- operands[2] = (rtx) assign_386_stack_local (SImode, 0);
- operands[3] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (SImode, 0);
}")
-(define_expand "fix_truncsfsi2"
- [(parallel [(set (match_operand:SI 0 "general_operand" "")
- (fix:SI
- (fix:SF (match_operand:SF 1 "register_operand" ""))))
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
+ (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:SI 4 "memory_operand" "m,m"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
+ "TARGET_80387"
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "fix_truncxfdi2"
+ [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (fix:DI (fix:XF (match_operand:XF 1 "register_operand" ""))))
+ (clobber (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
- (clobber (match_scratch:SI 4 ""))])]
+ (clobber (match_dup 4))
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
- operands[2] = (rtx) assign_386_stack_local (SImode, 0);
- operands[3] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[1] = copy_to_mode_reg (XFmode, operands[1]);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (DImode, 0);
}")
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
- (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
+ (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
+ (clobber (match_dup 1))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:DI 4 "memory_operand" "m,o"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
+
+;; Conversion between fixed point and floating point.
-(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
- (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+;; ??? Possibly represent floatunssidf2 here in gcc2.
+
+(define_expand "floatsisf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
+ "operands[2] = assign_386_stack_local (SImode, 0);")
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
- (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
-
-;; Conversion between fixed point and floating point.
-;; The actual pattern that matches these is at the end of this file.
+ "#")
-;; ??? Possibly represent floatunssidf2 here in gcc2.
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:SI 1 "memory_operand" "")))
+ (clobber (match_operand:SI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:SF (match_dup 1)))]
+ "")
-(define_expand "floatsisf2"
+(define_split
[(set (match_operand:SF 0 "register_operand" "")
- (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
+ (float:SF (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:SF (match_dup 2)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:SI 1 "memory_operand" "m")))]
+ "TARGET_80387"
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "floathisf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
"TARGET_80387"
+ "operands[2] = assign_386_stack_local (HImode, 0);")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
+ "TARGET_80387"
+ "#")
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:HI 1 "memory_operand" "")))
+ (clobber (match_operand:HI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:SF (match_dup 1)))]
"")
-(define_expand "floatdisf2"
+(define_split
[(set (match_operand:SF 0 "register_operand" "")
- (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
+ (float:SF (match_operand:HI 1 "register_operand" "")))
+ (clobber (match_operand:HI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:SF (match_dup 2)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_80387"
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "floatdisf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
"TARGET_80387"
+ "operands[2] = assign_386_stack_local (DImode, 0);")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
+ "TARGET_80387"
+ "#")
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:DI 1 "memory_operand" "")))
+ (clobber (match_operand:DI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:SF (match_dup 1)))]
+ "")
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:DI 1 "register_operand" "")))
+ (clobber (match_operand:DI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:SF (match_dup 2)))]
"")
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:DI 1 "memory_operand" "m")))]
+ "TARGET_80387"
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
+
(define_expand "floatsidf2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
+ "TARGET_80387"
+ "operands[2] = assign_386_stack_local (SImode, 0);")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
+ "TARGET_80387"
+ "#")
+
+(define_split
[(set (match_operand:DF 0 "register_operand" "")
- (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
+ (float:DF (match_operand:SI 1 "memory_operand" "")))
+ (clobber (match_operand:SI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:DF (match_dup 1)))]
+ "")
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:DF (match_dup 2)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:SI 1 "memory_operand" "m")))]
+ "TARGET_80387"
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "floathidf2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
"TARGET_80387"
+ "operands[2] = assign_386_stack_local (HImode, 0);")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
+ "TARGET_80387"
+ "#")
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:HI 1 "memory_operand" "")))
+ (clobber (match_operand:HI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:DF (match_dup 1)))]
"")
-(define_expand "floatdidf2"
+(define_split
[(set (match_operand:DF 0 "register_operand" "")
- (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
+ (float:DF (match_operand:HI 1 "register_operand" "")))
+ (clobber (match_operand:HI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:DF (match_dup 2)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_80387"
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "floatdidf2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
+ "TARGET_80387"
+ "operands[2] = assign_386_stack_local (DImode, 0);")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
"TARGET_80387"
+ "#")
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:DI 1 "memory_operand" "")))
+ (clobber (match_operand:DI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:DF (match_dup 1)))]
"")
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:DI 1 "register_operand" "")))
+ (clobber (match_operand:DI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:DF (match_dup 2)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:DI 1 "memory_operand" "m")))]
+ "TARGET_80387"
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
+
(define_expand "floatsixf2"
- [(set (match_operand:XF 0 "register_operand" "")
- (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
"TARGET_80387"
- "")
+ "operands[2] = assign_386_stack_local (SImode, 0);")
-(define_expand "floatdixf2"
+(define_insn ""
+ [(set (match_operand:XF 0 "register_operand" "=f,f")
+ (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
+ "TARGET_80387"
+ "#")
+
+(define_split
[(set (match_operand:XF 0 "register_operand" "")
- (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
- "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96"
+ (float:XF (match_operand:SI 1 "memory_operand" "")))
+ (clobber (match_operand:SI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:XF (match_dup 1)))]
"")
-;; This will convert from SImode or DImode to MODE_FLOAT.
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float:XF (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:XF (match_dup 2)))]
+ "")
(define_insn ""
[(set (match_operand:XF 0 "register_operand" "=f")
- (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
+ (float:XF (match_operand:SI 1 "memory_operand" "m")))]
"TARGET_80387"
- "*
-{
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fild%z0,%1));
- RET;
- }
- else if (GET_CODE (operands[1]) == MEM)
- return AS1 (fild%z1,%1);
- else
- abort ();
-}")
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
+(define_expand "floathixf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (float:XF (match_operand:HI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
"TARGET_80387"
- "*
-{
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fild%z0,%1));
- RET;
- }
- else if (GET_CODE (operands[1]) == MEM)
- return AS1 (fild%z1,%1);
- else
- abort ();
-}")
+ "operands[2] = assign_386_stack_local (HImode, 0);")
(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
+ [(set (match_operand:XF 0 "register_operand" "=f,f")
+ (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
"TARGET_80387"
- "*
-{
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fild%z0,%1));
- RET;
- }
- else if (GET_CODE (operands[1]) == MEM)
- return AS1 (fild%z1,%1);
- else
- abort ();
-}")
+ "#")
+
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float:XF (match_operand:HI 1 "memory_operand" "")))
+ (clobber (match_operand:HI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:XF (match_dup 1)))]
+ "")
+
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float:XF (match_operand:HI 1 "register_operand" "")))
+ (clobber (match_operand:HI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:XF (match_dup 2)))]
+ "")
(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (float:XF (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_80387"
- "*
-{
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fild%z0,%1));
- RET;
- }
- else if (GET_CODE (operands[1]) == MEM)
- return AS1 (fild%z1,%1);
- else
- abort ();
-}")
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "floatdixf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))
+ (clobber (match_dup 2))])]
+ "TARGET_80387"
+ "operands[2] = assign_386_stack_local (DImode, 0);")
(define_insn ""
[(set (match_operand:XF 0 "register_operand" "=f,f")
- (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))]
+ (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
+ (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
"TARGET_80387"
- "*
-{
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fild%z0,%1));
- RET;
- }
- else if (GET_CODE (operands[1]) == MEM)
- return AS1 (fild%z1,%1);
- else
- abort ();
-}")
+ "#")
+
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float:XF (match_operand:DI 1 "memory_operand" "")))
+ (clobber (match_operand:DI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 0)
+ (float:XF (match_dup 1)))]
+ "")
+
+(define_split
+ [(set (match_operand:XF 0 "register_operand" "")
+ (float:XF (match_operand:DI 1 "register_operand" "")))
+ (clobber (match_operand:DI 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (float:XF (match_dup 2)))]
+ "")
(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (float:XF (match_operand:DI 1 "memory_operand" "m")))]
"TARGET_80387"
- "*
-{
- if (NON_STACK_REG_P (operands[1]))
- {
- output_op_from_reg (operands[1], AS1 (fild%z0,%1));
- RET;
- }
- else if (GET_CODE (operands[1]) == MEM)
- return AS1 (fild%z1,%1);
- else
- abort ();
-}")
+ "* return AS1 (fild%z1,%1);"
+ [(set_attr "type" "fpop")])
;;- add instructions
-(define_insn "addsidi3_1"
+(define_insn "*addsidi3_1"
[(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
(plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
(zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
@@ -2666,7 +3245,7 @@
""
"*
{
- rtx low[3], high[3], xops[7], temp;
+ rtx low[3], high[3], xops[7];
CC_STATUS_INIT;
@@ -2703,8 +3282,11 @@
output_asm_insn (AS2 (add%L0,%2,%0), low);
output_asm_insn (AS2 (adc%L0,%2,%0), high);
+ cc_status.value1 = high[0];
+ cc_status.flags = CC_NO_OVERFLOW;
RET;
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "addsidi3_2"
[(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
@@ -2714,7 +3296,7 @@
""
"*
{
- rtx low[3], high[3], xops[7], temp;
+ rtx low[3], high[3], xops[7];
CC_STATUS_INIT;
@@ -2781,8 +3363,11 @@
output_asm_insn (AS2 (add%L0,%2,%0), low);
output_asm_insn (AS2 (adc%L0,%2,%0), high);
+ cc_status.value1 = high[0];
+ cc_status.flags = CC_NO_OVERFLOW;
RET;
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "adddi3"
[(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
@@ -2831,6 +3416,9 @@
}
}
+ cc_status.value1 = high[0];
+ cc_status.flags = CC_NO_OVERFLOW;
+
if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
{
xops[0] = high[0];
@@ -2855,7 +3443,8 @@
output_asm_insn (AS2 (add%L0,%2,%0), high);
RET;
-}")
+}"
+ [(set_attr "type" "binary")])
;; On a 486, it is faster to do movl/addl than to do a single leal if
;; operands[1] and operands[2] are both registers.
@@ -2875,7 +3464,7 @@
"*
{
if (REG_P (operands[0]) && REG_P (operands[1])
- && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT)
+ && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
&& REGNO (operands[0]) != REGNO (operands[1]))
{
if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
@@ -2920,7 +3509,8 @@
}
return AS2 (add%L0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
;; addsi3 is faster, so put this after.
@@ -2949,7 +3539,8 @@
CC_STATUS_INIT;
return AS2 (lea%L0,%a1,%0);
-}")
+}"
+ [(set_attr "type" "lea")])
;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
@@ -2963,12 +3554,30 @@
"IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
(define_insn ""
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
- (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "ri,rm")))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r")
+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
+ (match_operand:HI 2 "general_operand" "ri,rm,ri")))]
"ix86_binary_operator_ok (PLUS, HImode, operands)"
"*
{
+ if (REG_P (operands[0]) && REG_P (operands[1])
+ && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
+ && REGNO (operands[0]) != REGNO (operands[1]))
+ {
+ if (operands[2] == stack_pointer_rtx)
+ abort ();
+
+ CC_STATUS_INIT;
+ operands[1]
+ = gen_rtx_PLUS (SImode,
+ gen_rtx_REG (SImode, REGNO (operands[1])),
+ (! REG_P (operands[2])
+ ? operands[2]
+ : gen_rtx_REG (SImode, REGNO (operands[2]))));
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ return AS2 (lea%L0,%a1,%0);
+ }
+
/* ??? what about offsettable memory references? */
if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
&& QI_REG_P (operands[0])
@@ -3019,7 +3628,8 @@
return AS1 (dec%W0,%0);
return AS2 (add%W0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
(define_expand "addqi3"
[(set (match_operand:QI 0 "general_operand" "")
@@ -3029,12 +3639,31 @@
"IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
(define_insn ""
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
- (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "qn,qmn")))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q")
+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q")
+ (match_operand:QI 2 "general_operand" "qn,qmn,qn")))]
"ix86_binary_operator_ok (PLUS, QImode, operands)"
"*
{
+ if (REG_P (operands[0]) && REG_P (operands[1])
+ && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
+ && (REGNO (operands[0]) != REGNO (operands[1])
+ || NON_QI_REG_P (operands[1])
+ || (REG_P (operands[2]) && NON_QI_REG_P (operands[2]))))
+ {
+ if (operands[2] == stack_pointer_rtx)
+ abort ();
+
+ CC_STATUS_INIT;
+ operands[1]
+ = gen_rtx_PLUS (SImode,
+ gen_rtx_REG (SImode, REGNO (operands[1])),
+ (! REG_P (operands[2])
+ ? operands[2]
+ : gen_rtx_REG (SImode, REGNO (operands[2]))));
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ return AS2 (lea%L0,%a1,%0);
+ }
if (operands[2] == const1_rtx)
return AS1 (inc%B0,%0);
@@ -3044,7 +3673,8 @@
return AS1 (dec%B0,%0);
return AS2 (add%B0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
;Lennart Augustsson <augustss@cs.chalmers.se>
;says this pattern just makes slower code:
@@ -3141,8 +3771,12 @@
output_asm_insn (AS2 (sub%L0,%2,%0), low);
output_asm_insn (AS2 (sbb%L0,%2,%0), high);
+ cc_status.value1 = high[0];
+ cc_status.flags = CC_NO_OVERFLOW;
+
RET;
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "subdi3"
[(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
@@ -3185,6 +3819,9 @@
}
}
+ cc_status.value1 = high[0];
+ cc_status.flags = CC_NO_OVERFLOW;
+
if (GET_CODE (operands[3]) == REG)
{
xops[0] = high[0];
@@ -3206,10 +3843,12 @@
}
else
- output_asm_insn (AS2 (sub%L0,%2,%0), high);
+ output_asm_insn (AS2 (sub%L0,%2,%0), high);
+
RET;
-}")
+}"
+ [(set_attr "type" "binary")])
(define_expand "subsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
@@ -3223,7 +3862,8 @@
(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
(match_operand:SI 2 "general_operand" "ri,rm")))]
"ix86_binary_operator_ok (MINUS, SImode, operands)"
- "* return AS2 (sub%L0,%2,%0);")
+ "* return AS2 (sub%L0,%2,%0);"
+ [(set_attr "type" "binary")])
(define_expand "subhi3"
[(set (match_operand:HI 0 "general_operand" "")
@@ -3248,7 +3888,8 @@
return AS2 (sub%L0,%k2,%k0);
}
return AS2 (sub%W0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
(define_expand "subqi3"
[(set (match_operand:QI 0 "general_operand" "")
@@ -3262,7 +3903,8 @@
(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
(match_operand:QI 2 "general_operand" "qn,qmn")))]
"ix86_binary_operator_ok (MINUS, QImode, operands)"
- "* return AS2 (sub%B0,%2,%0);")
+ "* return AS2 (sub%B0,%2,%0);"
+ [(set_attr "type" "binary")])
;; The patterns that match these are at the end of this file.
@@ -3688,7 +4330,8 @@ word_zero_and_operation:
}
return AS2 (and%L0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "andhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
@@ -3766,14 +4409,16 @@ word_zero_and_operation:
}
return AS2 (and%W0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "andqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
(match_operand:QI 2 "general_operand" "qn,qmn")))]
""
- "* return AS2 (and%B0,%2,%0);")
+ "* return AS2 (and%B0,%2,%0);"
+ [(set_attr "type" "binary")])
/* I am nervous about these two.. add them later..
;I presume this means that we have something in say op0= eax which is small
@@ -3889,7 +4534,8 @@ byte_or_operation:
}
return AS2 (or%L0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "iorhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
@@ -3973,14 +4619,16 @@ byte_or_operation:
}
return AS2 (or%W0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "iorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
(match_operand:QI 2 "general_operand" "qn,qmn")))]
""
- "* return AS2 (or%B0,%2,%0);")
+ "* return AS2 (or%B0,%2,%0);"
+ [(set_attr "type" "binary")])
;;- xor instructions
@@ -4016,7 +4664,10 @@ byte_or_operation:
byte_xor_operation:
CC_STATUS_INIT;
- if (intval == 0xff)
+ if (intval == 0xff
+ && (!TARGET_PENTIUM || optimize_size
+ || (GET_CODE (operands[0]) == MEM
+ && memory_address_info (XEXP (operands[0], 0), 1))))
return AS1 (not%B0,%b0);
if (intval != INTVAL (operands[2]))
@@ -4032,7 +4683,10 @@ byte_xor_operation:
if (REG_P (operands[0]))
{
CC_STATUS_INIT;
- if (intval == 0xff)
+ if (intval == 0xff
+ && (!TARGET_PENTIUM || optimize_size
+ || (GET_CODE (operands[0]) == MEM
+ && memory_address_info (XEXP (operands[0], 0), 1))))
return AS1 (not%B0,%h0);
operands[2] = GEN_INT (intval);
@@ -4068,7 +4722,8 @@ byte_xor_operation:
}
return AS2 (xor%L0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "xorhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
@@ -4088,7 +4743,10 @@ byte_xor_operation:
if (INTVAL (operands[2]) & 0xffff0000)
operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
- if (INTVAL (operands[2]) == 0xff)
+ if (INTVAL (operands[2]) == 0xff
+ && (!TARGET_PENTIUM || optimize_size
+ || (GET_CODE (operands[0]) == MEM
+ && memory_address_info (XEXP (operands[0], 0), 1))))
return AS1 (not%B0,%b0);
return AS2 (xor%B0,%2,%b0);
@@ -4102,7 +4760,10 @@ byte_xor_operation:
CC_STATUS_INIT;
operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
- if (INTVAL (operands[2]) == 0xff)
+ if (INTVAL (operands[2]) == 0xff
+ && (!TARGET_PENTIUM || optimize_size
+ || (GET_CODE (operands[0]) == MEM
+ && memory_address_info (XEXP (operands[0], 0), 1))))
return AS1 (not%B0,%h0);
return AS2 (xor%B0,%2,%h0);
@@ -4129,115 +4790,55 @@ byte_xor_operation:
}
return AS2 (xor%W0,%2,%0);
-}")
+}"
+ [(set_attr "type" "binary")])
(define_insn "xorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
(match_operand:QI 2 "general_operand" "qn,qm")))]
""
- "* return AS2 (xor%B0,%2,%0);")
+ "* return AS2 (xor%B0,%2,%0);"
+ [(set_attr "type" "binary")])
;; logical operations for DImode
-
(define_insn "anddi3"
- [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
- (and:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
- (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
- (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
+ [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
+ (and:DI (match_operand:DI 1 "general_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "oriF,riF")))]
""
- "#")
+ "#"
+ [(set_attr "type" "binary")])
+
(define_insn "iordi3"
- [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
- (ior:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
- (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
- (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
+ [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
+ (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "oriF,riF")))]
""
- "#")
-
+ "#"
+ [(set_attr "type" "binary")])
+
(define_insn "xordi3"
- [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
- (xor:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
- (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
- (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
+ [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
+ (xor:DI (match_operand:DI 1 "general_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "oriF,riF")))]
""
- "#")
+ "#"
+ [(set_attr "type" "binary")])
(define_split
- [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
- (match_operator:DI 4 "ix86_logical_operator"
- [(match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
- (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")]))
- (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
- "reload_completed"
- [(const_int 0)]
- "
-{
- rtx low[3], high[3], xops[7], temp;
- rtx (*genfunc)() = (GET_CODE (operands[4]) == AND ? gen_andsi3
- : GET_CODE (operands[4]) == IOR ? gen_iorsi3
- : GET_CODE (operands[4]) == XOR ? gen_xorsi3
- : 0);
-
- if (rtx_equal_p (operands[0], operands[2]))
- {
- temp = operands[1];
- operands[1] = operands[2];
- operands[2] = temp;
- }
-
- split_di (operands, 3, low, high);
- if (!rtx_equal_p (operands[0], operands[1]))
- {
- xops[0] = high[0];
- xops[1] = low[0];
- xops[2] = high[1];
- xops[3] = low[1];
-
- if (GET_CODE (operands[0]) != MEM)
- {
- emit_insn (gen_movsi (xops[1], xops[3]));
- emit_insn (gen_movsi (xops[0], xops[2]));
- }
- else
- {
- xops[4] = high[2];
- xops[5] = low[2];
- xops[6] = operands[3];
- emit_insn (gen_movsi (xops[6], xops[3]));
- emit_insn ((*genfunc) (xops[6], xops[6], xops[5]));
- emit_insn (gen_movsi (xops[1], xops[6]));
- emit_insn (gen_movsi (xops[6], xops[2]));
- emit_insn ((*genfunc) (xops[6], xops[6], xops[4]));
- emit_insn (gen_movsi (xops[0], xops[6]));
- DONE;
- }
- }
-
- if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
- {
- xops[0] = high[0];
- xops[1] = low[0];
- xops[2] = high[2];
- xops[3] = low[2];
- xops[4] = operands[3];
-
- emit_insn (gen_movsi (xops[4], xops[3]));
- emit_insn ((*genfunc) (xops[1], xops[1], xops[4]));
- emit_insn (gen_movsi (xops[4], xops[2]));
- emit_insn ((*genfunc) (xops[0], xops[0], xops[4]));
- }
-
- else
- {
- emit_insn ((*genfunc) (low[0], low[0], low[2]));
- emit_insn ((*genfunc) (high[0], high[0], high[2]));
- }
-
- DONE;
-}")
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operator:DI 3 "ix86_logical_operator"
+ [(match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")]))]
+ ""
+ [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)]))
+ (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))]
+ "split_di (&operands[0], 1, &operands[4], &operands[5]);
+ split_di (&operands[1], 1, &operands[6], &operands[7]);
+ split_di (&operands[2], 1, &operands[8], &operands[9]);")
;;- negation instructions
@@ -4271,7 +4872,13 @@ byte_xor_operation:
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
""
- "neg%W0 %0")
+ "*
+ if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
+ {
+ CC_STATUS_INIT;
+ return AS1(neg%L0,%k0);
+ }
+ return AS1(neg%W0,%0);")
(define_insn "negqi2"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
@@ -4283,31 +4890,36 @@ byte_xor_operation:
[(set (match_operand:SF 0 "register_operand" "=f")
(neg:SF (match_operand:SF 1 "register_operand" "0")))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
(define_insn "negdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(neg:DF (match_operand:DF 1 "register_operand" "0")))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
(define_insn ""
[(set (match_operand:DF 0 "register_operand" "=f")
(neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
(define_insn "negxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(neg:XF (match_operand:XF 1 "register_operand" "0")))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
(define_insn ""
[(set (match_operand:XF 0 "register_operand" "=f")
(neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
;; Absolute value instructions
@@ -4443,19 +5055,88 @@ byte_xor_operation:
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
""
- "not%L0 %0")
+ "*
+{
+ /* A Pentium NOT is not pariable. Output it only in case of complex
+ memory address, because XOR will be inpariable anyway because
+ of immediate/displacement rule. */
+
+ if (TARGET_PENTIUM && !optimize_size
+ && (GET_CODE (operands[0]) != MEM
+ || memory_address_info (XEXP (operands[0], 0), 1) == 0))
+ {
+ rtx xops[2];
+ xops[0] = operands[0];
+ xops[1] = GEN_INT (0xffffffff);
+ output_asm_insn (AS2 (xor%L0,%1,%0), xops);
+ RET;
+ }
+ else
+ return AS1 (not%L0,%0);
+}")
(define_insn "one_cmplhi2"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
""
- "not%W0 %0")
+ "*
+{
+ /* A Pentium NOT is not pariable. Output it only in case of complex
+ memory address, because XOR will be inpariable anyway because
+ of immediate/displacement rule. */
+
+ if (TARGET_PENTIUM && !optimize_size
+ && (GET_CODE (operands[0]) != MEM
+ || memory_address_info (XEXP (operands[0], 0), 1) == 0))
+ {
+ rtx xops[2];
+ xops[0] = operands[0];
+ xops[1] = GEN_INT (0xffff);
+ if (REG_P (operands[0])
+ && i386_cc_probably_useless_p (insn))
+ {
+ CC_STATUS_INIT;
+ output_asm_insn (AS2 (xor%L0,%1,%k0), xops);
+ }
+ else
+ output_asm_insn (AS2 (xor%W0,%1,%0), xops);
+ RET;
+ }
+ else
+ {
+ if (REG_P (operands[0])
+ && i386_cc_probably_useless_p (insn))
+ {
+ CC_STATUS_INIT;
+ return AS1 (not%L0,%k0);
+ }
+ return AS1 (not%W0,%0);
+ }
+}")
(define_insn "one_cmplqi2"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
""
- "not%B0 %0")
+ "*
+{
+ /* A Pentium NOT is not pariable. Output it only in case of complex
+ memory address, because XOR will be inpariable anyway because
+ of immediate/displacement rule. */
+
+ if (TARGET_PENTIUM && !optimize_size
+ && (GET_CODE (operands[0]) != MEM
+ || memory_address_info (XEXP (operands[0], 0), 1) == 0))
+ {
+ rtx xops[2];
+ xops[0] = operands[0];
+ xops[1] = GEN_INT (0xff);
+ output_asm_insn (AS2 (xor%B0,%1,%0), xops);
+ RET;
+ }
+ else
+ return AS1 (not%B0,%0);
+}")
;;- arithmetic shift instructions
@@ -4566,79 +5247,79 @@ byte_xor_operation:
RET;
}")
-;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
-;; On i486, movl/sall appears slightly faster than leal, but the leal
-;; is smaller - use leal for now unless the shift count is 1.
+(define_expand "ashlsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
+ ""
+ "")
-(define_insn "ashlsi3"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
- (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0")
- (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
+(define_expand "ashlhi3"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
+ (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
+ (match_operand:HI 2 "nonmemory_operand" "")))]
""
- "*
-{
- if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
- {
- if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1)
- {
- output_asm_insn (AS2 (mov%L0,%1,%0), operands);
- return AS2 (add%L0,%1,%0);
- }
- else
- {
- CC_STATUS_INIT;
+ "")
- if (operands[1] == stack_pointer_rtx)
- {
- output_asm_insn (AS2 (mov%L0,%1,%0), operands);
- operands[1] = operands[0];
- }
- operands[1] = gen_rtx_MULT (SImode, operands[1],
- GEN_INT (1 << INTVAL (operands[2])));
- return AS2 (lea%L0,%a1,%0);
- }
- }
+(define_expand "ashlqi3"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
+ (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
+ (match_operand:QI 2 "nonmemory_operand" "")))]
+ ""
+ "")
- if (REG_P (operands[2]))
- return AS2 (sal%L0,%b2,%0);
+;; Pattern for shifts which can be encoded into an lea instruction.
+;; This is kept as a separate pattern so that regmove can optimize cases
+;; where we know the source and destination must match.
+;;
+;; Do not expose this pattern when optimizing for size since we never want
+;; to use lea when optimizing for size since mov+sal is smaller than lea.
- if (REG_P (operands[0]) && operands[2] == const1_rtx)
- return AS2 (add%L0,%0,%0);
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
+ (match_operand:SI 2 "small_shift_operand" "M,M")))]
+ "! optimize_size"
+ "* return output_ashl (insn, operands);")
- return AS2 (sal%L0,%2,%0);
-}")
+;; Generic left shift pattern to catch all cases not handled by the
+;; shift pattern above.
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+ (match_operand:SI 2 "nonmemory_operand" "cI")))]
+ ""
+ "* return output_ashl (insn, operands);")
-(define_insn "ashlhi3"
+(define_insn ""
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r")
+ (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
+ (match_operand:HI 2 "small_shift_operand" "M,M")))]
+ "! optimize_size"
+ "* return output_ashl (insn, operands);")
+
+(define_insn ""
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:HI 2 "nonmemory_operand" "cI")))]
""
- "*
-{
- if (REG_P (operands[2]))
- return AS2 (sal%W0,%b2,%0);
+ "* return output_ashl (insn, operands);")
- if (REG_P (operands[0]) && operands[2] == const1_rtx)
- return AS2 (add%W0,%0,%0);
-
- return AS2 (sal%W0,%2,%0);
-}")
+(define_insn ""
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q")
+ (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q")
+ (match_operand:QI 2 "small_shift_operand" "M,M")))]
+ "! optimize_size"
+ "* return output_ashl (insn, operands);")
-(define_insn "ashlqi3"
+;; Generic left shift pattern to catch all cases not handled by the
+;; shift pattern above.
+(define_insn ""
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "cI")))]
""
- "*
-{
- if (REG_P (operands[2]))
- return AS2 (sal%B0,%b2,%0);
-
- if (REG_P (operands[0]) && operands[2] == const1_rtx)
- return AS2 (add%B0,%0,%0);
-
- return AS2 (sal%B0,%2,%0);
-}")
+ "* return output_ashl (insn, operands);")
;; See comment above `ashldi3' about how this works.
@@ -4755,6 +5436,15 @@ byte_xor_operation:
RET;
}")
+(define_insn "ashrsi3_31"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
+ (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
+ (const_int 31)))]
+ "!TARGET_PENTIUM || optimize_size"
+ "@
+ sar%L0 $31,%0
+ cltd")
+
(define_insn "ashrsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
@@ -5177,7 +5867,10 @@ byte_xor_operation:
mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
operands[1] = GEN_INT (mask);
- if (QI_REG_P (operands[0]))
+ if (QI_REG_P (operands[0])
+ /* A Pentium test is pairable only with eax. Not with ah or al. */
+ && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
+ || optimize_size))
{
if ((mask & ~0xff) == 0)
{
@@ -5211,7 +5904,10 @@ byte_xor_operation:
mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
operands[1] = GEN_INT (mask);
- if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
+ if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
+ /* A Pentium test is pairable only with eax. Not with ah or al. */
+ && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
+ || optimize_size))
{
if ((mask & ~0xff) == 0)
{
@@ -5261,10 +5957,6 @@ byte_xor_operation:
;; For all sCOND expanders, also expand the compare or test insn that
;; generates cc0. Generate an equality comparison if `seq' or `sne'.
-;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
-;; not have any input reloads. A MEM write might need an input reload
-;; for the address of the MEM. So don't allow MEM as the SET_DEST.
-
(define_expand "seq"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5279,18 +5971,6 @@ byte_xor_operation:
operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
}")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (eq:QI (cc0) (const_int 0)))]
- ""
- "*
-{
- if (cc_prev_status.flags & CC_Z_IN_NOT_C)
- return AS1 (setnb,%0);
- else
- return AS1 (sete,%0);
-}")
-
(define_expand "sne"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5305,19 +5985,6 @@ byte_xor_operation:
operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
}")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (ne:QI (cc0) (const_int 0)))]
- ""
- "*
-{
- if (cc_prev_status.flags & CC_Z_IN_NOT_C)
- return AS1 (setb,%0);
- else
- return AS1 (setne,%0);
-}
-")
-
(define_expand "sgt"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5325,19 +5992,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (gt:QI (cc0) (const_int 0)))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (sete,%0);
-
- OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
-}")
-
(define_expand "sgtu"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5345,12 +5999,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (gtu:QI (cc0) (const_int 0)))]
- ""
- "* return \"seta %0\"; ")
-
(define_expand "slt"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5358,19 +6006,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (lt:QI (cc0) (const_int 0)))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (sete,%0);
-
- OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
-}")
-
(define_expand "sltu"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5378,12 +6013,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (ltu:QI (cc0) (const_int 0)))]
- ""
- "* return \"setb %0\"; ")
-
(define_expand "sge"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5391,19 +6020,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (ge:QI (cc0) (const_int 0)))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (sete,%0);
-
- OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
-}")
-
(define_expand "sgeu"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5411,12 +6027,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (geu:QI (cc0) (const_int 0)))]
- ""
- "* return \"setae %0\"; ")
-
(define_expand "sle"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5424,19 +6034,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (le:QI (cc0) (const_int 0)))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (setb,%0);
-
- OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
-}")
-
(define_expand "sleu"
[(match_dup 1)
(set (match_operand:QI 0 "register_operand" "")
@@ -5444,11 +6041,69 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=q")
- (leu:QI (cc0) (const_int 0)))]
- ""
- "* return \"setbe %0\"; ")
+;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
+;; not have any input reloads. A MEM write might need an input reload
+;; for the address of the MEM. So don't allow MEM as the SET_DEST.
+
+(define_insn "*setcc"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
+ (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))]
+ "reload_completed || register_operand (operands[0], QImode)"
+ "*
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+ if (cc_prev_status.flags & CC_TEST_AX)
+ {
+ int eq;
+ HOST_WIDE_INT c;
+ operands[2] = gen_rtx_REG (SImode, 0);
+ switch (code)
+ {
+ case EQ:
+ c = 0x4000;
+ eq = 0;
+ break;
+ case NE:
+ c = 0x4000;
+ eq = 1;
+ break;
+ case GT:
+ c = 0x4100;
+ eq = 1;
+ break;
+ case LT:
+ c = 0x100;
+ eq = 0;
+ break;
+ case GE:
+ c = 0x100;
+ eq = 1;
+ break;
+ case LE:
+ c = 0x4100;
+ eq = 0;
+ break;
+ default:
+ abort ();
+ }
+ if (!TARGET_PENTIUM || optimize_size)
+ {
+ operands[3] = GEN_INT (c >> 8);
+ output_asm_insn (AS2 (test%B0,%3,%h2), operands);
+ }
+ else
+ {
+ operands[3] = GEN_INT (c);
+ output_asm_insn (AS2 (test%L0,%3,%2), operands);
+ }
+ return eq ? AS1 (sete,%0) : AS1 (setne, %0);
+ }
+
+ if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
+ return (char *)0;
+ return AS1(set%D1,%0);
+}")
+
;; Basic conditional jump instructions.
;; We ignore the overflow flag for signed branch instructions.
@@ -5473,29 +6128,6 @@ byte_xor_operation:
operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
}")
-(define_insn ""
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
-{
- if (cc_prev_status.flags & CC_Z_IN_NOT_C)
- return \"jnc %l0\";
- else
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x4000);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (jne,%l0);
- }
-
- return \"je %l0\";
-}")
-
(define_expand "bne"
[(match_dup 1)
(set (pc)
@@ -5513,28 +6145,6 @@ byte_xor_operation:
operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
}")
-(define_insn ""
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
-{
- if (cc_prev_status.flags & CC_Z_IN_NOT_C)
- return \"jc %l0\";
- else
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x4000);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (je,%l0);
- }
-
- return \"jne %l0\";
-}")
(define_expand "bgt"
[(match_dup 1)
@@ -5546,29 +6156,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (je,%l0);
-
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x4100);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (je,%l0);
- }
- OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
-}")
-
(define_expand "bgtu"
[(match_dup 1)
(set (pc)
@@ -5579,15 +6166,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "ja %l0")
-
(define_expand "blt"
[(match_dup 1)
(set (pc)
@@ -5598,28 +6176,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (je,%l0);
-
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x100);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (jne,%l0);
- }
- OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
-}")
(define_expand "bltu"
[(match_dup 1)
@@ -5631,15 +6187,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "jb %l0")
-
(define_expand "bge"
[(match_dup 1)
(set (pc)
@@ -5650,28 +6197,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (je,%l0);
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x100);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (je,%l0);
- }
- OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
-}")
-
(define_expand "bgeu"
[(match_dup 1)
(set (pc)
@@ -5682,15 +6207,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "jae %l0")
-
(define_expand "ble"
[(match_dup 1)
(set (pc)
@@ -5701,29 +6217,6 @@ byte_xor_operation:
""
"operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
-(define_insn ""
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (jb,%l0);
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x4100);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (jne,%l0);
- }
-
- OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
-}")
-
(define_expand "bleu"
[(match_dup 1)
(set (pc)
@@ -5736,184 +6229,127 @@ byte_xor_operation:
(define_insn ""
[(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 1 "" ""))
(pc)))]
""
- "jbe %l0")
-
-;; Negated conditional jump instructions.
-
-(define_insn ""
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
-{
- if (cc_prev_status.flags & CC_Z_IN_NOT_C)
- return \"jc %l0\";
- else
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x4000);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (je,%l0);
- }
- return \"jne %l0\";
-}")
-
-(define_insn ""
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
"*
{
- if (cc_prev_status.flags & CC_Z_IN_NOT_C)
- return \"jnc %l0\";
- else
+ enum rtx_code code = GET_CODE (operands[0]);
if (cc_prev_status.flags & CC_TEST_AX)
{
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x4000);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (jne,%l0);
+ int eq;
+ HOST_WIDE_INT c;
+ operands[2] = gen_rtx_REG (SImode, 0);
+ switch (code)
+ {
+ case EQ:
+ c = 0x4000;
+ eq = 0;
+ break;
+ case NE:
+ c = 0x4000;
+ eq = 1;
+ break;
+ case GT:
+ c = 0x4100;
+ eq = 1;
+ break;
+ case LT:
+ c = 0x100;
+ eq = 0;
+ break;
+ case GE:
+ c = 0x100;
+ eq = 1;
+ break;
+ case LE:
+ c = 0x4100;
+ eq = 0;
+ break;
+ default:
+ abort ();
+ }
+ if (!TARGET_PENTIUM || optimize_size)
+ {
+ operands[3] = GEN_INT (c >> 8);
+ output_asm_insn (AS2 (test%B0,%3,%h2), operands);
+ }
+ else
+ {
+ operands[3] = GEN_INT (c);
+ output_asm_insn (AS2 (test%L0,%3,%2), operands);
+ }
+ return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
}
- return \"je %l0\";
-}")
+ if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
+ return (char *)0;
-(define_insn ""
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (jne,%l0);
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x4100);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (jne,%l0);
- }
- OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
+ return AS1(j%D0,%l1);
}")
(define_insn ""
[(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "jbe %l0")
-
-(define_insn ""
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(cc0) (const_int 0)])
(pc)
- (label_ref (match_operand 0 "" ""))))]
+ (label_ref (match_operand 1 "" ""))))]
""
"*
{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (jne,%l0);
+ enum rtx_code code = GET_CODE (operands[0]);
if (cc_prev_status.flags & CC_TEST_AX)
{
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x100);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (je,%l0);
+ int eq;
+ HOST_WIDE_INT c;
+ operands[2] = gen_rtx_REG (SImode, 0);
+ switch (code)
+ {
+ case EQ:
+ c = 0x4000;
+ eq = 1;
+ break;
+ case NE:
+ c = 0x4000;
+ eq = 0;
+ break;
+ case GT:
+ c = 0x4100;
+ eq = 0;
+ break;
+ case LT:
+ c = 0x100;
+ eq = 1;
+ break;
+ case GE:
+ c = 0x100;
+ eq = 0;
+ break;
+ case LE:
+ c = 0x4100;
+ eq = 1;
+ break;
+ default:
+ abort ();
+ }
+ if (!TARGET_PENTIUM || optimize_size)
+ {
+ operands[3] = GEN_INT (c >> 8);
+ output_asm_insn (AS2 (test%B0,%3,%h2), operands);
+ }
+ else
+ {
+ operands[3] = GEN_INT (c);
+ output_asm_insn (AS2 (test%L0,%3,%2), operands);
+ }
+ return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
}
+ if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
+ return (char *)0;
- OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
-}")
-
-(define_insn ""
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "jae %l0")
-
-(define_insn ""
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (jne,%l0);
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x100);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (jne,%l0);
- }
- OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
+ return AS1(j%d0,%l1);
}")
-
-(define_insn ""
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "jb %l0")
-
-(define_insn ""
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
-{
- if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
- && ! (cc_prev_status.flags & CC_FCOMI))
- return AS1 (jae,%l0);
-
- if (cc_prev_status.flags & CC_TEST_AX)
- {
- operands[1] = gen_rtx_REG (SImode, 0);
- operands[2] = GEN_INT (0x4100);
- output_asm_insn (AS2 (testl,%2,%1), operands);
- return AS1 (je,%l0);
- }
- OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
-}")
-
-(define_insn ""
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "ja %l0")
;; Unconditional and other jump instructions
@@ -5921,7 +6357,8 @@ byte_xor_operation:
[(set (pc)
(label_ref (match_operand 0 "" "")))]
""
- "jmp %l0")
+ "jmp %l0"
+ [(set_attr "memory" "none")])
(define_insn "indirect_jump"
[(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
@@ -5931,7 +6368,8 @@ byte_xor_operation:
CC_STATUS_INIT;
return AS1 (jmp,%*%0);
-}")
+}"
+ [(set_attr "memory" "none")])
;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
;; if S does not change i
@@ -5952,7 +6390,7 @@ byte_xor_operation:
(define_insn ""
[(set (pc)
(if_then_else (match_operator 0 "arithmetic_comparison_operator"
- [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
+ [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m")
(match_operand:SI 2 "general_operand" "rmi,ri"))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
@@ -5964,6 +6402,11 @@ byte_xor_operation:
"*
{
CC_STATUS_INIT;
+
+ if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 &&
+ operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6)
+ return \"loop %l3\";
+
if (operands[2] == constm1_rtx)
output_asm_insn (AS1 (dec%L1,%1), operands);
@@ -6228,6 +6671,12 @@ byte_xor_operation:
{
rtx addr;
+ if (operands[3] == const0_rtx)
+ {
+ emit_insn (gen_call (operands[0], operands[1]));
+ DONE;
+ }
+
if (flag_pic)
current_function_uses_pic_offset_table = 1;
@@ -6330,6 +6779,12 @@ byte_xor_operation:
{
rtx addr;
+ if (operands[4] == const0_rtx)
+ {
+ emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+
if (flag_pic)
current_function_uses_pic_offset_table = 1;
@@ -6469,7 +6924,8 @@ byte_xor_operation:
(define_insn "blockage"
[(unspec_volatile [(const_int 0)] 0)]
""
- "")
+ ""
+ [(set_attr "memory" "none")])
;; Insn emitted into the body of a function to return from a function.
;; This is only done if the function's epilogue is known to be simple.
@@ -6483,18 +6939,21 @@ byte_xor_operation:
(define_insn "return_internal"
[(return)]
"reload_completed"
- "ret")
+ "ret"
+ [(set_attr "memory" "none")])
(define_insn "return_pop_internal"
[(return)
(use (match_operand:SI 0 "const_int_operand" ""))]
"reload_completed"
- "ret %0")
+ "ret %0"
+ [(set_attr "memory" "none")])
(define_insn "nop"
[(const_int 0)]
""
- "nop")
+ "nop"
+ [(set_attr "memory" "none")])
(define_expand "prologue"
[(const_int 1)]
@@ -6521,7 +6980,8 @@ byte_xor_operation:
xops[1] = stack_pointer_rtx;
output_asm_insn (AS2 (sub%L1,%0,%1), xops);
RET;
-}")
+}"
+ [(set_attr "memory" "none")])
(define_insn "prologue_set_got"
[(set (match_operand:SI 0 "" "")
@@ -6553,15 +7013,14 @@ byte_xor_operation:
""
"*
{
- char buffer[64];
-
output_asm_insn (AS1 (call,%X1), operands);
if (! TARGET_DEEP_BRANCH_PREDICTION)
{
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
}
RET;
-}")
+}"
+ [(set_attr "memory" "none")])
(define_insn "prologue_get_pc_and_set_got"
[(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
@@ -6573,9 +7032,10 @@ byte_xor_operation:
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[1]));
output_asm_insn (AS1 (pop%L0,%0), operands);
- output_asm_insn (\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
+ output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
RET;
-}")
+}"
+ [(set_attr "memory" "none")])
(define_expand "epilogue"
[(const_int 1)]
@@ -6598,14 +7058,16 @@ byte_xor_operation:
xops[1] = stack_pointer_rtx;
output_asm_insn (AS2 (mov%L0,%0,%1), xops);
RET;
-}")
+}"
+ [(set_attr "memory" "none")])
(define_insn "leave"
[(const_int 2)
(clobber (reg:SI 6))
(clobber (reg:SI 7))]
""
- "leave")
+ "leave"
+ [(set_attr "memory" "none")])
(define_insn "pop"
[(set (match_operand:SI 0 "register_operand" "r")
@@ -6616,7 +7078,8 @@ byte_xor_operation:
{
output_asm_insn (AS1 (pop%L0,%P0), operands);
RET;
-}")
+}"
+ [(set_attr "memory" "load")])
(define_expand "movstrsi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
@@ -6698,7 +7161,7 @@ byte_xor_operation:
""
"
{
- rtx addr0, addr1;
+ rtx addr0;
if (GET_CODE (operands[1]) != CONST_INT)
FAIL;
@@ -6715,7 +7178,7 @@ byte_xor_operation:
;; But strength reduction might offset the MEM expression. So we let
;; reload put the address into %edi.
-(define_insn ""
+(define_insn "*bzero"
[(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
(const_int 0))
(use (match_operand:SI 1 "const_int_operand" "n"))
@@ -6731,17 +7194,35 @@ byte_xor_operation:
output_asm_insn (\"cld\", operands);
if (GET_CODE (operands[1]) == CONST_INT)
{
- if (INTVAL (operands[1]) & ~0x03)
+ unsigned int count = INTVAL (operands[1]) & 0xffffffff;
+ if (count & ~0x03)
{
- xops[0] = GEN_INT ((INTVAL (operands[1]) >> 2) & 0x3fffffff);
+ xops[0] = GEN_INT (count / 4);
xops[1] = operands[4];
- output_asm_insn (AS2 (mov%L1,%0,%1), xops);
+ /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles.
+ 80386: 4/5+5n (+2 for set of ecx)
+ 80486: 5/7+5n (+1 for set of ecx)
+ */
+ if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6))
+ {
+ do
+#ifdef INTEL_SYNTAX
+ output_asm_insn (\"stosd\", xops);
+#else
+ output_asm_insn (\"stosl\", xops);
+#endif
+ while ((count -= 4) > 3);
+ }
+ else
+ {
+ output_asm_insn (AS2 (mov%L1,%0,%1), xops);
#ifdef INTEL_SYNTAX
- output_asm_insn (\"rep stosd\", xops);
+ output_asm_insn (\"rep stosd\", xops);
#else
- output_asm_insn (\"rep\;stosl\", xops);
+ output_asm_insn (\"rep\;stosl\", xops);
#endif
+ }
}
if (INTVAL (operands[1]) & 0x02)
output_asm_insn (\"stosw\", operands);
@@ -6910,9 +7391,7 @@ byte_xor_operation:
;; mulM3 and divM3. There are three patterns for each of DFmode and
;; SFmode. The first is the normal insn, the second the same insn but
;; with one operand a conversion, and the third the same insn but with
-;; the other operand a conversion. The conversion may be SFmode or
-;; SImode if the target mode DFmode, but only SImode if the target mode
-;; is SFmode.
+;; the other operand a conversion.
(define_insn ""
[(set (match_operand:DF 0 "register_operand" "=f,f")
@@ -6932,23 +7411,6 @@ byte_xor_operation:
)])
(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (match_operator:DF 3 "binary_387_op"
- [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm"))
- (match_operand:DF 2 "register_operand" "0")]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "is_mul" "")
- (const_string "fpmul")
- (match_operand:DF 3 "is_div" "")
- (const_string "fpdiv")
- ]
- (const_string "fpop")
- )
- )])
-
-(define_insn ""
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_387_op"
[(match_operand:XF 1 "register_operand" "0,f")
@@ -6966,23 +7428,6 @@ byte_xor_operation:
)])
(define_insn ""
- [(set (match_operand:XF 0 "register_operand" "=f")
- (match_operator:XF 3 "binary_387_op"
- [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm"))
- (match_operand:XF 2 "register_operand" "0")]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "is_mul" "")
- (const_string "fpmul")
- (match_operand:DF 3 "is_div" "")
- (const_string "fpdiv")
- ]
- (const_string "fpop")
- )
- )])
-
-(define_insn ""
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_387_op"
[(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
@@ -7000,23 +7445,6 @@ byte_xor_operation:
)])
(define_insn ""
- [(set (match_operand:XF 0 "register_operand" "=f")
- (match_operator:XF 3 "binary_387_op"
- [(match_operand:XF 1 "register_operand" "0")
- (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "is_mul" "")
- (const_string "fpmul")
- (match_operand:DF 3 "is_div" "")
- (const_string "fpdiv")
- ]
- (const_string "fpop")
- )
- )])
-
-(define_insn ""
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_387_op"
[(match_operand:XF 1 "register_operand" "0,f")
@@ -7052,23 +7480,6 @@ byte_xor_operation:
)])
(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (match_operator:DF 3 "binary_387_op"
- [(match_operand:DF 1 "register_operand" "0")
- (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "is_mul" "")
- (const_string "fpmul")
- (match_operand:DF 3 "is_div" "")
- (const_string "fpdiv")
- ]
- (const_string "fpop")
- )
- )])
-
-(define_insn ""
[(set (match_operand:DF 0 "register_operand" "=f,f")
(match_operator:DF 3 "binary_387_op"
[(match_operand:DF 1 "register_operand" "0,f")
@@ -7102,40 +7513,6 @@ byte_xor_operation:
(const_string "fpop")
)
)])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (match_operator:SF 3 "binary_387_op"
- [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm"))
- (match_operand:SF 2 "register_operand" "0")]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "is_mul" "")
- (const_string "fpmul")
- (match_operand:DF 3 "is_div" "")
- (const_string "fpdiv")
- ]
- (const_string "fpop")
- )
- )])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (match_operator:SF 3 "binary_387_op"
- [(match_operand:SF 1 "register_operand" "0")
- (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "is_mul" "")
- (const_string "fpmul")
- (match_operand:DF 3 "is_div" "")
- (const_string "fpdiv")
- ]
- (const_string "fpop")
- )
- )])
(define_expand "strlensi"
[(parallel [(set (match_dup 4)
@@ -7258,12 +7635,12 @@ byte_xor_operation:
"#")
(define_split
- [(set (match_operand:SI 0 "register_operand" "=r,r")
+ [(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:SI 3 "nonimmediate_operand" "rm,0")
- (match_operand:SI 4 "nonimmediate_operand" "0,rm")))]
+ (match_operand:SI 3 "nonimmediate_operand" "")
+ (match_operand:SI 4 "nonimmediate_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7273,12 +7650,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:SI 0 "register_operand" "=r,r")
+ [(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:SI 4 "nonimmediate_operand" "rm,0")
- (match_operand:SI 5 "nonimmediate_operand" "0,rm")))]
+ (match_operand:SI 4 "nonimmediate_operand" "")
+ (match_operand:SI 5 "nonimmediate_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7332,12 +7709,12 @@ byte_xor_operation:
"#")
(define_split
- [(set (match_operand:HI 0 "register_operand" "=r,r")
+ [(set (match_operand:HI 0 "register_operand" "")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:HI 3 "nonimmediate_operand" "rm,0")
- (match_operand:HI 4 "nonimmediate_operand" "0,rm")))]
+ (match_operand:HI 3 "nonimmediate_operand" "")
+ (match_operand:HI 4 "nonimmediate_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7347,12 +7724,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:HI 0 "register_operand" "=r,r")
+ [(set (match_operand:HI 0 "register_operand" "")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:HI 4 "nonimmediate_operand" "rm,0")
- (match_operand:HI 5 "nonimmediate_operand" "0,rm")))]
+ (match_operand:HI 4 "nonimmediate_operand" "")
+ (match_operand:HI 5 "nonimmediate_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(compare (match_dup 2) (match_dup 3)))
@@ -7435,12 +7812,12 @@ byte_xor_operation:
"#")
(define_split
- [(set (match_operand:SF 0 "register_operand" "=f,f")
+ [(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:SF 3 "register_operand" "f,0")
- (match_operand:SF 4 "register_operand" "0,f")))]
+ (match_operand:SF 3 "register_operand" "")
+ (match_operand:SF 4 "register_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7450,12 +7827,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:SF 0 "register_operand" "=f,f")
+ [(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:SF 4 "register_operand" "f,0")
- (match_operand:SF 5 "register_operand" "0,f")))]
+ (match_operand:SF 4 "register_operand" "")
+ (match_operand:SF 5 "register_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7537,12 +7914,12 @@ byte_xor_operation:
"#")
(define_split
- [(set (match_operand:DF 0 "register_operand" "=f,f")
+ [(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:DF 3 "register_operand" "f,0")
- (match_operand:DF 4 "register_operand" "0,f")))]
+ (match_operand:DF 3 "register_operand" "")
+ (match_operand:DF 4 "register_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7552,12 +7929,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:DF 0 "register_operand" "=f,f")
+ [(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:DF 4 "register_operand" "f,0")
- (match_operand:DF 5 "register_operand" "0,f")))]
+ (match_operand:DF 4 "register_operand" "")
+ (match_operand:DF 5 "register_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7639,12 +8016,12 @@ byte_xor_operation:
"#")
(define_split
- [(set (match_operand:XF 0 "register_operand" "=f,f")
+ [(set (match_operand:XF 0 "register_operand" "")
(if_then_else:XF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:XF 3 "register_operand" "f,0")
- (match_operand:XF 4 "register_operand" "0,f")))]
+ (match_operand:XF 3 "register_operand" "")
+ (match_operand:XF 4 "register_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7654,12 +8031,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:XF 0 "register_operand" "=f,f")
+ [(set (match_operand:XF 0 "register_operand" "")
(if_then_else:XF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:XF 4 "register_operand" "f,0")
- (match_operand:XF 5 "register_operand" "0,f")))]
+ (match_operand:XF 4 "register_operand" "")
+ (match_operand:XF 5 "register_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7713,42 +8090,43 @@ byte_xor_operation:
"#")
(define_split
- [(set (match_operand:DI 0 "register_operand" "=&r,&r")
+ [(set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:DI 3 "nonimmediate_operand" "ro,0")
- (match_operand:DI 4 "nonimmediate_operand" "0,ro")))]
+ (match_operand:DI 3 "nonimmediate_operand" "")
+ (match_operand:DI 4 "nonimmediate_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
- (set (match_dup 0)
- (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)])
- (match_dup 3) (match_dup 4)))]
- "")
+ (set (match_dup 5)
+ (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
+ (match_dup 7) (match_dup 9)))
+ (set (match_dup 6)
+ (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
+ (match_dup 8) (match_dup 10)))]
+ "split_di (&operands[0], 1, &operands[5], &operands[6]);
+ split_di (&operands[3], 1, &operands[7], &operands[8]);
+ split_di (&operands[4], 1, &operands[9], &operands[10]);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "=&r,&r")
+ [(set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:DI 4 "nonimmediate_operand" "ro,0")
- (match_operand:DI 5 "nonimmediate_operand" "0,ro")))]
+ (match_operand:DI 4 "nonimmediate_operand" "")
+ (match_operand:DI 5 "nonimmediate_operand" "")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
- (set (match_dup 0)
- (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)])
- (match_dup 4) (match_dup 5)))]
- "")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=&r,&r")
- (if_then_else:DI (match_operator 1 "comparison_operator"
- [(cc0) (const_int 0)])
- (match_operand:DI 2 "nonimmediate_operand" "ro,0")
- (match_operand:DI 3 "nonimmediate_operand" "0,ro")))]
- "TARGET_CMOVE && reload_completed"
- "* return output_int_conditional_move (which_alternative, operands);")
+ (set (match_dup 6)
+ (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
+ (match_dup 8) (match_dup 10)))
+ (set (match_dup 7)
+ (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
+ (match_dup 9) (match_dup 11)))]
+ "split_di (&operands[0], 1, &operands[6], &operands[7]);
+ split_di (&operands[4], 1, &operands[8], &operands[9]);
+ split_di (&operands[5], 1, &operands[10], &operands[11]);")
(define_insn "strlensi_unroll"
[(set (match_operand:SI 0 "register_operand" "=&r,&r")
@@ -7785,7 +8163,8 @@ byte_xor_operation:
(set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
(clobber (match_dup 0))]
"TARGET_STACK_PROBE"
- "* return AS1(call,__alloca);")
+ "* return AS1(call,__alloca);"
+ [(set_attr "memory" "none")])
(define_expand "allocate_stack"
[(set (match_operand:SI 0 "register_operand" "=r")
OpenPOWER on IntegriCloud