aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-03-26 15:56:34 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-03-26 13:56:34 +0000
commitcc2e591b48e51df008d4e09d1f67f1195f8cbeb5 (patch)
treefc22ba8e7d086f9d7db904862931e20340cefe1d /gcc
parent8362f4207eaa70dbee88b09a893cd5aa0515ee7f (diff)
downloadgcc-cc2e591b48e51df008d4e09d1f67f1195f8cbeb5.zip
gcc-cc2e591b48e51df008d4e09d1f67f1195f8cbeb5.tar.gz
gcc-cc2e591b48e51df008d4e09d1f67f1195f8cbeb5.tar.bz2
i386.md (push mem DI peep2): New.
* i386.md (push mem DI peep2): New. (mov 0, mov -1 peep2): Handle 64bit. (lea to arithmetics peep2): Handle 64bit leas. (rsp arithmetics to push/pop peep2s): New. * i386.md (truncdfsf2_3, trunctfsf2_2): Change predicate to memory_operand. From-SVN: r40847
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/i386/i386.md181
2 files changed, 183 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index db3c86d..477517c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+Mon Mar 26 15:55:08 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (push mem DI peep2): New.
+ (mov 0, mov -1 peep2): Handle 64bit.
+ (lea to arithmetics peep2): Handle 64bit leas.
+ (rsp arithmetics to push/pop peep2s): New.
+
+ * i386.md (truncdfsf2_3, trunctfsf2_2): Change predicate to memory_operand.
+
Mon Mar 26 14:35:18 CEST 2001 Jan Hubicka <jh@suse.cz>
* i386.c (struct machine_function): Add save_varrargs_registers.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6a23023..8f6c36b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -4341,7 +4341,7 @@
(set_attr "mode" "DF,SF")])
(define_insn "truncdfsf2_3"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
+ [(set (match_operand:SF 0 "memory_operand" "=m")
(float_truncate:SF
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_80387"
@@ -4490,7 +4490,7 @@
(set_attr "mode" "SF")])
(define_insn "*trunctfsf2_2"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
+ [(set (match_operand:SF 0 "memory_operand" "=m")
(float_truncate:SF
(match_operand:TF 1 "register_operand" "f")))]
"TARGET_80387"
@@ -15890,6 +15890,15 @@
(set (match_dup 0) (match_dup 2))]
"")
+(define_peephole2
+ [(set (match_operand:DI 0 "push_operand" "")
+ (match_operand:DI 1 "memory_operand" ""))
+ (match_scratch:DI 2 "r")]
+ "! optimize_size && ! TARGET_PUSH_MEMORY"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (match_dup 2))]
+ "")
+
;; We need to handle SFmode only, because DFmode and XFmode is split to
;; SImode pushes.
(define_peephole2
@@ -16209,12 +16218,14 @@
(const_int 0))]
"(GET_MODE (operands[0]) == QImode
|| GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == SImode)
+ || GET_MODE (operands[0]) == SImode
+ || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
&& (! TARGET_USE_MOV0 || optimize_size)
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (const_int 0))
(clobber (reg:CC 17))])]
- "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
+ "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
+ true_regnum (operands[0]));")
(define_peephole2
[(set (strict_low_part (match_operand 0 "register_operand" ""))
@@ -16231,12 +16242,14 @@
[(set (match_operand 0 "register_operand" "")
(const_int -1))]
"(GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == SImode)
+ || GET_MODE (operands[0]) == SImode
+ || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
&& (optimize_size || TARGET_PENTIUM)
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (const_int -1))
(clobber (reg:CC 17))])]
- "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
+ "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
+ true_regnum (operands[0]));")
;; Attempt to convert simple leas to adds. These can be created by
;; move expanders.
@@ -16251,14 +16264,53 @@
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
+ (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "nonmemory_operand" "")) 0))]
+ "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
+ [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
+ (clobber (reg:CC 17))])]
+ "operands[2] = gen_lowpart (SImode, operands[2]);")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_dup 0)
+ (match_operand:DI 1 "x86_64_general_operand" "")))]
+ "peep2_regno_dead_p (0, FLAGS_REG)"
+ [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 17))])]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
(mult:SI (match_dup 0)
- (match_operand:SI 1 "immediate_operand" "")))]
+ (match_operand:SI 1 "const_int_operand" "")))]
"exact_log2 (INTVAL (operands[1])) >= 0
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
(clobber (reg:CC 17))])]
"operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (mult:DI (match_dup 0)
+ (match_operand:DI 1 "const_int_operand" "")))]
+ "exact_log2 (INTVAL (operands[1])) >= 0
+ && peep2_regno_dead_p (0, FLAGS_REG)"
+ [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
+ (clobber (reg:CC 17))])]
+ "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "const_int_operand" "")) 0))]
+ "exact_log2 (INTVAL (operands[1])) >= 0
+ && REGNO (operands[0]) == REGNO (operands[1])
+ && peep2_regno_dead_p (0, FLAGS_REG)"
+ [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
+ (clobber (reg:CC 17))])]
+ "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
+
;; The ESP adjustments can be done by the push and pop instructions. Resulting
;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
;; many CPUs it is also faster, since special hardware to avoid esp
@@ -16456,6 +16508,121 @@
(clobber (match_dup 0))])]
"")
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
+ (set (reg:DI 6) (reg:DI 6))
+ (clobber (reg:CC 17))])]
+ "optimize_size || !TARGET_SUB_ESP_4"
+ [(clobber (match_dup 0))
+ (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
+ (set (reg:DI 6) (reg:DI 6))])])
+
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
+ (set (reg:DI 6) (reg:DI 6))
+ (clobber (reg:CC 17))])]
+ "optimize_size || !TARGET_SUB_ESP_8"
+ [(clobber (match_dup 0))
+ (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
+ (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
+ (set (reg:DI 6) (reg:DI 6))])])
+
+;; Convert esp substractions to push.
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
+ (clobber (reg:CC 17))])]
+ "optimize_size || !TARGET_SUB_ESP_4"
+ [(clobber (match_dup 0))
+ (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
+
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
+ (clobber (reg:CC 17))])]
+ "optimize_size || !TARGET_SUB_ESP_8"
+ [(clobber (match_dup 0))
+ (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
+ (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
+
+;; Convert epilogue deallocator to pop.
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
+ (set (reg:DI 6) (reg:DI 6))
+ (clobber (reg:CC 17))])]
+ "optimize_size || !TARGET_ADD_ESP_4"
+ [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
+ (set (reg:DI 6) (reg:DI 6))])]
+ "")
+
+;; Two pops case is tricky, since pop causes dependency on destination register.
+;; We use two registers if available.
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (match_scratch:DI 1 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
+ (set (reg:DI 6) (reg:DI 6))
+ (clobber (reg:CC 17))])]
+ "optimize_size || !TARGET_ADD_ESP_8"
+ [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
+ (set (reg:DI 6) (reg:DI 6))])
+ (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
+ "")
+
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
+ (set (reg:DI 6) (reg:DI 6))
+ (clobber (reg:CC 17))])]
+ "optimize_size"
+ [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
+ (set (reg:DI 6) (reg:DI 6))])
+ (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
+ "")
+
+;; Convert esp additions to pop.
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
+ (clobber (reg:CC 17))])]
+ ""
+ [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
+ "")
+
+;; Two pops case is tricky, since pop causes dependency on destination register.
+;; We use two registers if available.
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (match_scratch:DI 1 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
+ (clobber (reg:CC 17))])]
+ ""
+ [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
+ (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
+ "")
+
+(define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
+ (clobber (reg:CC 17))])]
+ "optimize_size"
+ [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
+ (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
+ (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
+ "")
+
;; Call-value patterns last so that the wildcard operand does not
;; disrupt insn-recog's switch tables.