]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
mips.c (mips_symbol_insns_1): Allow LEAs of SYMBOL_FORCE_TO_MEM constants.
authorRichard Sandiford <richard@codesourcery.com>
Tue, 11 Sep 2007 09:51:17 +0000 (09:51 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 11 Sep 2007 09:51:17 +0000 (09:51 +0000)
gcc/
* config/mips/mips.c (mips_symbol_insns_1): Allow LEAs of
SYMBOL_FORCE_TO_MEM constants.
(mips_rtx_costs): Give a cost of 1 to force_to_mem_operands.
(mips16_rewrite_pool_refs_info): New structure.
(mips16_rewrite_pool_constant): New function, split out from...
(mips16_rewrite_pool_refs): ...here.  Take a pointer to a
mips16_rewrite_pool_refs_info structure rather than a pointer
to a constant pool.  Force force_to_mem_operands into memory.
(mips16_lay_out_constants): Update call to mips16_rewrite_pool_refs.
* config/mips/predicates.md (force_to_mem_operand): New predicate.
* config/mips/constraints.md (kf): New constraint.
* config/mips/mips.md (*movdi_64bit_mips16): Add a d <- kf alternative.
(*movsi_mips16): Likewise.

From-SVN: r128365

gcc/ChangeLog
gcc/config/mips/constraints.md
gcc/config/mips/mips.c
gcc/config/mips/mips.md
gcc/config/mips/predicates.md

index e5523d03bead81c999dbf8f7050a20174c0cc59c..470e25478dba65e4d3ef9d187af3b60b79bf6a10 100644 (file)
@@ -1,3 +1,19 @@
+2007-09-11  Richard Sandiford  <richard@codesourcery.com>
+
+       * config/mips/mips.c (mips_symbol_insns_1): Allow LEAs of
+       SYMBOL_FORCE_TO_MEM constants.
+       (mips_rtx_costs): Give a cost of 1 to force_to_mem_operands.
+       (mips16_rewrite_pool_refs_info): New structure.
+       (mips16_rewrite_pool_constant): New function, split out from...
+       (mips16_rewrite_pool_refs): ...here.  Take a pointer to a
+       mips16_rewrite_pool_refs_info structure rather than a pointer
+       to a constant pool.  Force force_to_mem_operands into memory.
+       (mips16_lay_out_constants): Update call to mips16_rewrite_pool_refs.
+       * config/mips/predicates.md (force_to_mem_operand): New predicate.
+       * config/mips/constraints.md (kf): New constraint.
+       * config/mips/mips.md (*movdi_64bit_mips16): Add a d <- kf alternative.
+       (*movsi_mips16): Likewise.
+
 2007-09-11  Richard Sandiford  <richard@codesourcery.com>
            Nigel Stephens  <nigel@mips.com>
            David Ung  <davidu@mips.com>
index 47b396689544202bef0e63f108e5c2beaf373268..98e8d6f2faae9d0fa9a74b1fbae4027c58a0faf3 100644 (file)
 ;; but the DSPr2 version allows any accumulator target.
 (define_register_constraint "ka" "TARGET_DSPR2 ? ACC_REGS : MD_REGS")
 
+(define_constraint "kf"
+  "@internal"
+  (match_operand 0 "force_to_mem_operand"))
+
 ;; This is a normal rather than a register constraint because we can
 ;; never use the stack pointer as a reload register.
 (define_constraint "ks"
index 34c4420016838e70204cb9e092f57ca9f39b553a..0e69827296d08cb8c315d5ea4f37445974aeae7a 100644 (file)
@@ -1908,6 +1908,11 @@ mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode)
       return 0;
 
     case SYMBOL_FORCE_TO_MEM:
+      /* LEAs will be converted into constant-pool references by
+        mips_reorg.  */
+      if (mode == MAX_MACHINE_MODE)
+       return 1;
+
       /* The constant must be loaded from the constant pool.  */
       return 0;
 
@@ -3140,6 +3145,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
     case SYMBOL_REF:
     case LABEL_REF:
     case CONST_DOUBLE:
+      if (force_to_mem_operand (x, VOIDmode))
+       {
+         *total = COSTS_N_INSNS (1);
+         return true;
+       }
       cost = mips_const_insns (x);
       if (cost > 0)
        {
@@ -10099,20 +10109,14 @@ mips16_insn_length (rtx insn)
   return get_attr_length (insn);
 }
 
-/* Rewrite *X so that constant pool references refer to the constant's
-   label instead.  DATA points to the constant pool structure.  */
+/* If *X is a symbolic constant that refers to the constant pool, add
+   the constant to POOL and rewrite *X to use the constant's label.  */
 
-static int
-mips16_rewrite_pool_refs (rtx *x, void *data)
+static void
+mips16_rewrite_pool_constant (struct mips16_constant_pool *pool, rtx *x)
 {
-  struct mips16_constant_pool *pool = data;
   rtx base, offset, label;
 
-  if (MEM_P (*x))
-    x = &XEXP (*x, 0);
-  else if (!TARGET_MIPS16_TEXT_LOADS)
-    return 0;
-
   split_const (*x, &base, &offset);
   if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
     {
@@ -10120,8 +10124,41 @@ mips16_rewrite_pool_refs (rtx *x, void *data)
                            get_pool_mode (base));
       base = gen_rtx_LABEL_REF (Pmode, label);
       *x = mips_unspec_address_offset (base, offset, SYMBOL_PC_RELATIVE);
+    }
+}
+
+/* This structure is used to communicate with mips16_rewrite_pool_refs.
+   INSN is the instruction we're rewriting and POOL points to the current
+   constant pool.  */
+struct mips16_rewrite_pool_refs_info {
+  rtx insn;
+  struct mips16_constant_pool *pool;
+};
+
+/* Rewrite *X so that constant pool references refer to the constant's
+   label instead.  DATA points to a mips16_rewrite_pool_refs_info
+   structure.  */
+
+static int
+mips16_rewrite_pool_refs (rtx *x, void *data)
+{
+  struct mips16_rewrite_pool_refs_info *info = data;
+
+  if (force_to_mem_operand (*x, Pmode))
+    {
+      rtx mem = force_const_mem (GET_MODE (*x), *x);
+      validate_change (info->insn, x, mem, false);
+    }
+
+  if (MEM_P (*x))
+    {
+      mips16_rewrite_pool_constant (info->pool, &XEXP (*x, 0));
       return -1;
     }
+
+  if (TARGET_MIPS16_TEXT_LOADS)
+    mips16_rewrite_pool_constant (info->pool, x);
+
   return GET_CODE (*x) == CONST ? -1 : 0;
 }
 
@@ -10131,6 +10168,7 @@ static void
 mips16_lay_out_constants (void)
 {
   struct mips16_constant_pool pool;
+  struct mips16_rewrite_pool_refs_info info;
   rtx insn, barrier;
 
   if (!TARGET_MIPS16_PCREL_LOADS)
@@ -10142,7 +10180,11 @@ mips16_lay_out_constants (void)
     {
       /* Rewrite constant pool references in INSN.  */
       if (INSN_P (insn))
-       for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &pool);
+       {
+         info.insn = insn;
+         info.pool = &pool;
+         for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &info);
+       }
 
       pool.insn_address += mips16_insn_length (insn);
 
index a6a5ea4a20f04ac89b413d34ff9b0e9f34da7561..c1cffb1bc04c361bef32f6dd0478afcc9b800ae8 100644 (file)
    (set_attr "length"  "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
 
 (define_insn "*movdi_64bit_mips16"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
-       (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m")
+       (match_operand:DI 1 "move_operand" "d,d,y,K,N,kf,U,m,d"))]
   "TARGET_64BIT && TARGET_MIPS16
    && (register_operand (operands[0], DImode)
        || register_operand (operands[1], DImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "type"    "move,move,move,arith,arith,const,load,store")
+  [(set_attr "type"    "move,move,move,arith,arith,load,const,load,store")
    (set_attr "mode"    "DI")
    (set_attr_alternative "length"
                [(const_int 4)
                 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
                               (const_int 8)
                               (const_int 12))
+                (const_int 8)
                 (const_string "*")
                 (const_string "*")
                 (const_string "*")])])
    (set_attr "length"  "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
 
 (define_insn "*movsi_mips16"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
-       (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m")
+       (match_operand:SI 1 "move_operand" "d,d,y,K,N,kf,U,m,d"))]
   "TARGET_MIPS16
    && (register_operand (operands[0], SImode)
        || register_operand (operands[1], SImode))"
   { return mips_output_move (operands[0], operands[1]); }
-  [(set_attr "type"    "move,move,move,arith,arith,const,load,store")
+  [(set_attr "type"    "move,move,move,arith,arith,load,const,load,store")
    (set_attr "mode"    "SI")
    (set_attr_alternative "length"
                [(const_int 4)
                 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
                               (const_int 8)
                               (const_int 12))
+                (const_int 8)
                 (const_string "*")
                 (const_string "*")
                 (const_string "*")])])
index e275283082ce8976b7033237427b27582c0cd6fe..6c533e5e80fff1cabf0f79a739ed3d819fa79c74 100644 (file)
          && type == SYMBOL_ABSOLUTE);
 })
 
+(define_predicate "force_to_mem_operand"
+  (match_code "const,symbol_ref,label_ref")
+{
+  enum mips_symbol_type symbol_type;
+  return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
+         && symbol_type == SYMBOL_FORCE_TO_MEM);
+})
+
 (define_predicate "got_disp_operand"
   (match_code "const,symbol_ref,label_ref")
 {