aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2002-09-09 13:00:55 +0200
committerAndreas Jaeger <aj@gcc.gnu.org>2002-09-09 13:00:55 +0200
commit7ec70495eaf949ca89abf196cc59a881e6f1b03a (patch)
tree37a9bcb38958706b29c3b3e9532a2dc6861d7730
parentb2fc915b74f7f44d01c0c5ff0fbdc5dad005e2ef (diff)
downloadgcc-7ec70495eaf949ca89abf196cc59a881e6f1b03a.zip
gcc-7ec70495eaf949ca89abf196cc59a881e6f1b03a.tar.gz
gcc-7ec70495eaf949ca89abf196cc59a881e6f1b03a.tar.bz2
i386.c (index_register_operand): New.
2002-09-09 Jan Hubicka <jh@suse.cz> * i386.c (index_register_operand): New. * i386.h (predicate_codes): Add new predicate. * i386.md (lea_general_*): Use index_regsiter_operand (ashift to lea splitter): Do not produce invalid leas (ashift to mov+ashift split): New. From-SVN: r56970
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/i386/i386.c24
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/config/i386/i386.md34
4 files changed, 60 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0503d56..be66367 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2002-09-09 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (index_register_operand): New.
+ * i386.h (predicate_codes): Add new predicate.
+ * i386.md (lea_general_*): Use index_regsiter_operand
+ (ashift to lea splitter): Do not produce invalid leas
+ (ashift to mov+ashift split): New.
+
2002-09-09 Nick Clifton <nickc@redhat.com>
* config/fr30/fr30.c (output.h): Move after inclusion of tree.h.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1d0d160..81a9b97 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3217,6 +3217,30 @@ nonmemory_no_elim_operand (op, mode)
return GET_CODE (op) == CONST_INT || register_operand (op, mode);
}
+/* Return false if this is any eliminable register or stack register,
+ otherwise work like register_operand. */
+
+int
+index_register_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+{
+ rtx t = op;
+ if (GET_CODE (t) == SUBREG)
+ t = SUBREG_REG (t);
+ if (!REG_P (t))
+ return 0;
+ if (t == arg_pointer_rtx
+ || t == frame_pointer_rtx
+ || t == virtual_incoming_args_rtx
+ || t == virtual_stack_vars_rtx
+ || t == virtual_stack_dynamic_rtx
+ || REGNO (t) == STACK_POINTER_REGNUM)
+ return 0;
+
+ return general_operand (op, mode);
+}
+
/* Return true if op is a Q_REGS class register. */
int
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index d04c605..ddef1f9 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -3173,6 +3173,7 @@ do { \
{"general_no_elim_operand", {CONST_INT, CONST_DOUBLE, CONST, \
SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}}, \
{"nonmemory_no_elim_operand", {CONST_INT, REG, SUBREG}}, \
+ {"index_register_operand", {SUBREG, REG}}, \
{"q_regs_operand", {SUBREG, REG}}, \
{"non_q_regs_operand", {SUBREG, REG}}, \
{"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU, UNORDERED, \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 240880d..a306509 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -4845,7 +4845,7 @@
(define_insn_and_split "*lea_general_1"
[(set (match_operand 0 "register_operand" "=r")
- (plus (plus (match_operand 1 "register_operand" "r")
+ (plus (plus (match_operand 1 "index_register_operand" "r")
(match_operand 2 "register_operand" "r"))
(match_operand 3 "immediate_operand" "i")))]
"(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
@@ -4877,7 +4877,7 @@
(define_insn_and_split "*lea_general_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
- (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
(match_operand:SI 2 "register_operand" "r"))
(match_operand:SI 3 "immediate_operand" "i"))))]
"TARGET_64BIT"
@@ -4897,7 +4897,7 @@
(define_insn_and_split "*lea_general_2"
[(set (match_operand 0 "register_operand" "=r")
- (plus (mult (match_operand 1 "register_operand" "r")
+ (plus (mult (match_operand 1 "index_register_operand" "r")
(match_operand 2 "const248_operand" "i"))
(match_operand 3 "nonmemory_operand" "ri")))]
"(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
@@ -4927,7 +4927,7 @@
(define_insn_and_split "*lea_general_2_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+ (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
(match_operand:SI 2 "const248_operand" "n"))
(match_operand:SI 3 "nonmemory_operand" "ri"))))]
"TARGET_64BIT"
@@ -4946,7 +4946,7 @@
(define_insn_and_split "*lea_general_3"
[(set (match_operand 0 "register_operand" "=r")
- (plus (plus (mult (match_operand 1 "register_operand" "r")
+ (plus (plus (mult (match_operand 1 "index_register_operand" "r")
(match_operand 2 "const248_operand" "i"))
(match_operand 3 "register_operand" "r"))
(match_operand 4 "immediate_operand" "i")))]
@@ -4980,7 +4980,7 @@
(define_insn_and_split "*lea_general_3_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
- (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+ (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
(match_operand:SI 2 "const248_operand" "n"))
(match_operand:SI 3 "register_operand" "r"))
(match_operand:SI 4 "immediate_operand" "i"))))]
@@ -10615,7 +10615,7 @@
;; Convert lea to the lea pattern to avoid flags dependency.
(define_split
[(set (match_operand 0 "register_operand" "")
- (ashift (match_operand 1 "register_operand" "")
+ (ashift (match_operand 1 "index_register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))
(clobber (reg:CC 17))]
"reload_completed
@@ -10633,6 +10633,26 @@
DONE;
})
+;; Rare case of shifting RSP is handled by generating move and shift
+(define_split
+ [(set (match_operand 0 "register_operand" "")
+ (ashift (match_operand 1 "register_operand" "")
+ (match_operand:QI 2 "const_int_operand" "")))
+ (clobber (reg:CC 17))]
+ "reload_completed
+ && true_regnum (operands[0]) != true_regnum (operands[1])"
+ [(const_int 0)]
+{
+ rtx pat, clob;
+ emit_move_insn (operands[1], operands[0]);
+ pat = gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_ASHIFT (GET_MODE (operands[0]),
+ operands[0], operands[2]));
+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
+ DONE;
+})
+
(define_insn "*ashlsi3_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")