OSDN Git Service

2002-09-09 Jan Hubicka <jh@suse.cz>
authoraj <aj@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 9 Sep 2002 11:00:55 +0000 (11:00 +0000)
committeraj <aj@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 9 Sep 2002 11:00:55 +0000 (11:00 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56970 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md

index 0503d56..be66367 100644 (file)
@@ -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.
index 1d0d160..81a9b97 100644 (file)
@@ -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
index d04c605..ddef1f9 100644 (file)
@@ -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, \
index 240880d..a306509 100644 (file)
 
 (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
 (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"
 
 (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
 (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"
 
 (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")))]
 (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"))))]
 ;; 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
   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")