* doc/tm.texi (TARGET_MD_ASM_CLOBBERS): Adjust wording to not
authorhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 23 Mar 2005 03:55:36 +0000 (03:55 +0000)
committerhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 23 Mar 2005 03:55:36 +0000 (03:55 +0000)
imply that this is called once, independent of asms in code.
Adjust to now being pased output and input lists.  Mention helper
function decl_overlaps_hard_reg_set_p.
* hooks.c (hook_tree_tree_tree_tree_3rd_identity): Rename from
hook_tree_tree_identity and to take three trees, returning third.
* hooks.h (hook_tree_tree_tree_tree_3rd_identity): Adjust the
prototype.
* stmt.c: include hard-reg-set.h before tree.h.
(decl_overlaps_hard_reg_set_p): New function, broken out from...
(decl_conflicts_with_clobbers_p): Call
decl_overlaps_hard_reg_set_p.
(expand_asm_operands): Pass output and input lists in call to
targetm.md_asm_clobbers.
* target-def.h (TARGET_MD_ASM_CLOBBERS): Define as
hook_tree_tree_tree_tree_3rd_identity.
* target.h (struct gcc_target.md_asm_clobbers): Take three tree
parameters.
* tree.h [HARD_CONST] (decl_overlaps_hard_reg_set_p): Prototype.
* config/i386/i386.c (ix86_md_asm_clobbers): Adjust to three
parameters, first two unused.
* config/cris/cris.c (cris_md_asm_clobbers): Adjust to added
parameters.  Only add MOF to clobbers if there's no 'h' mentioned
in constraint letters and MOF is not mentioned as a asm-declared
register in neither of the input and output lists.

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

gcc/ChangeLog
gcc/config/cris/cris.c
gcc/config/i386/i386.c
gcc/doc/tm.texi
gcc/hooks.c
gcc/hooks.h
gcc/stmt.c
gcc/target-def.h
gcc/target.h
gcc/tree.h

index 61dc2dd..d52a4a7 100644 (file)
@@ -1,3 +1,31 @@
+2005-03-23  Hans-Peter Nilsson  <hp@axis.com>
+
+       * doc/tm.texi (TARGET_MD_ASM_CLOBBERS): Adjust wording to not
+       imply that this is called once, independent of asms in code.
+       Adjust to now being pased output and input lists.  Mention helper
+       function decl_overlaps_hard_reg_set_p.
+       * hooks.c (hook_tree_tree_tree_tree_3rd_identity): Rename from
+       hook_tree_tree_identity and to take three trees, returning third.
+       * hooks.h (hook_tree_tree_tree_tree_3rd_identity): Adjust the
+       prototype.
+       * stmt.c: include hard-reg-set.h before tree.h.
+       (decl_overlaps_hard_reg_set_p): New function, broken out from...
+       (decl_conflicts_with_clobbers_p): Call
+       decl_overlaps_hard_reg_set_p.
+       (expand_asm_operands): Pass output and input lists in call to
+       targetm.md_asm_clobbers.
+       * target-def.h (TARGET_MD_ASM_CLOBBERS): Define as
+       hook_tree_tree_tree_tree_3rd_identity.
+       * target.h (struct gcc_target.md_asm_clobbers): Take three tree
+       parameters.
+       * tree.h [HARD_CONST] (decl_overlaps_hard_reg_set_p): Prototype.
+       * config/i386/i386.c (ix86_md_asm_clobbers): Adjust to three
+       parameters, first two unused.
+       * config/cris/cris.c (cris_md_asm_clobbers): Adjust to added
+       parameters.  Only add MOF to clobbers if there's no 'h' mentioned
+       in constraint letters and MOF is not mentioned as a asm-declared
+       register in neither of the input and output lists.
+
 2005-03-23  DJ Delorie  <dj@redhat.com>
 
        * optabs.c (expand_binop): Make sure the first subword's result
index a4c61b4..314ae0f 100644 (file)
@@ -125,7 +125,7 @@ static bool cris_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
                                    tree, bool);
 static int cris_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
                                   tree, bool);
-static tree cris_md_asm_clobbers (tree);
+static tree cris_md_asm_clobbers (tree, tree, tree);
 
 /* This is the argument from the "-max-stack-stackframe=" option.  */
 const char *cris_max_stackframe_str;
@@ -3060,8 +3060,38 @@ cris_arg_partial_bytes (CUMULATIVE_ARGS *ca, enum machine_mode mode,
 /* Worker function for TARGET_MD_ASM_CLOBBERS.  */
 
 static tree
-cris_md_asm_clobbers (tree clobbers)
+cris_md_asm_clobbers (tree outputs, tree inputs, tree clobbers)
 {
+  HARD_REG_SET mof_set;
+  tree t;
+
+  CLEAR_HARD_REG_SET (mof_set);
+  SET_HARD_REG_BIT (mof_set, CRIS_MOF_REGNUM);
+
+  for (t = outputs; t != NULL; t = TREE_CHAIN (t))
+    {
+      tree val = TREE_VALUE (t);
+
+      /* The constraint letter for the singleton register class of MOF
+        is 'h'.  If it's mentioned in the constraints, the asm is
+        MOF-aware and adding it to the clobbers would cause it to have
+        impossible constraints.  */
+      if (strchr (TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))),
+                 'h') != NULL
+         || decl_overlaps_hard_reg_set_p (val, mof_set))
+       return clobbers;
+    }
+
+  for (t = inputs; t != NULL; t = TREE_CHAIN (t))
+    {
+      tree val = TREE_VALUE (t);
+
+      if (strchr (TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))),
+                 'h') != NULL
+         || decl_overlaps_hard_reg_set_p (val, mof_set))
+       return clobbers;
+    }
+
   return tree_cons (NULL_TREE,
                    build_string (strlen (reg_names[CRIS_MOF_REGNUM]),
                                  reg_names[CRIS_MOF_REGNUM]),
index f76812f..e254017 100644 (file)
@@ -923,7 +923,7 @@ static tree ix86_handle_struct_attribute (tree *, tree, tree, int, bool *);
 static int extended_reg_mentioned_1 (rtx *, void *);
 static bool ix86_rtx_costs (rtx, int, int, int *);
 static int min_insn_size (rtx);
-static tree ix86_md_asm_clobbers (tree clobbers);
+static tree ix86_md_asm_clobbers (tree outputs, tree inputs, tree clobbers);
 static bool ix86_must_pass_in_stack (enum machine_mode mode, tree type);
 static bool ix86_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
                                    tree, bool);
@@ -16880,7 +16880,9 @@ ix86_vector_mode_supported_p (enum machine_mode mode)
    with the old cc0-based compiler.  */
 
 static tree
-ix86_md_asm_clobbers (tree clobbers)
+ix86_md_asm_clobbers (tree outputs ATTRIBUTE_UNUSED,
+                     tree inputs ATTRIBUTE_UNUSED,
+                     tree clobbers)
 {
   clobbers = tree_cons (NULL_TREE, build_string (5, "flags"),
                        clobbers);
index 799a0f8..af269f2 100644 (file)
@@ -9314,11 +9314,15 @@ from shared libraries (DLLs).
 You need not define this macro if it would always evaluate to zero.
 @end defmac
 
-@deftypefn {Target Hook} tree TARGET_MD_ASM_CLOBBERS (tree @var{clobbers})
+@deftypefn {Target Hook} tree TARGET_MD_ASM_CLOBBERS (tree @var{outputs}, tree @var{inputs}, tree @var{clobbers})
 This target hook should add to @var{clobbers} @code{STRING_CST} trees for
-any hard regs the port wishes to automatically clobber for all asms.
+any hard regs the port wishes to automatically clobber for an asm.
 It should return the result of the last @code{tree_cons} used to add a
-clobber.
+clobber.  The @var{outputs}, @var{inputs} and @var{clobber} lists are the
+corresponding parameters to the asm and may be inspected to avoid
+clobbering a register that is an input or output of the asm.  You can use
+@code{decl_overlaps_hard_reg_set_p}, declared in @file{tree.h}, to test
+for overlap with regards to asm-declared registers.
 @end deftypefn
 
 @defmac MATH_LIBRARY
index 274d427..6e6e7c7 100644 (file)
@@ -228,11 +228,12 @@ hook_rtx_tree_int_null (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED)
   return NULL;
 }
 
-/* Generic hook that takes a tree and returns it as is.  */
+/* Generic hook that takes three trees and returns the last one as is.  */
 tree
-hook_tree_tree_identity (tree a)
+hook_tree_tree_tree_tree_3rd_identity (tree a ATTRIBUTE_UNUSED,
+                                      tree b ATTRIBUTE_UNUSED, tree c)
 {
-  return a;
+  return c;
 }
 
 /* Generic hook that takes a tree and returns a NULL string.  */
index 133ea2a..b799a8c 100644 (file)
@@ -62,7 +62,7 @@ extern bool hook_bool_tree_tree_false (tree, tree);
 extern rtx hook_rtx_rtx_identity (rtx);
 extern rtx hook_rtx_rtx_null (rtx);
 extern rtx hook_rtx_tree_int_null (tree, int);
-extern tree hook_tree_tree_identity (tree a);
+extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
 extern const char *hook_constcharptr_tree_null (tree);
 extern tree hook_tree_tree_tree_bool_null (tree, tree, bool);
 #endif
index 9a1df90..2e29202 100644 (file)
@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm.h"
 
 #include "rtl.h"
+#include "hard-reg-set.h"
 #include "tree.h"
 #include "tm_p.h"
 #include "flags.h"
@@ -39,7 +40,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "insn-config.h"
 #include "expr.h"
 #include "libfuncs.h"
-#include "hard-reg-set.h"
 #include "recog.h"
 #include "machmode.h"
 #include "toplev.h"
@@ -558,15 +558,12 @@ parse_input_constraint (const char **constraint_p, int input_num,
   return true;
 }
 
-/* Check for overlap between registers marked in CLOBBERED_REGS and
-   anything inappropriate in DECL.  Emit error and return TRUE for error,
-   FALSE for ok.  */
+/* Return true iff there's an overlap between REGS and DECL, where DECL
+   can be an asm-declared register.  */
 
-static bool
-decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs)
+bool
+decl_overlaps_hard_reg_set_p (tree decl, const HARD_REG_SET regs)
 {
-  /* Conflicts between asm-declared register variables and the clobber
-     list are not allowed.  */
   if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
       && DECL_REGISTER (decl)
       && REG_P (DECL_RTL (decl))
@@ -579,18 +576,34 @@ decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs)
           regno < (REGNO (reg)
                    + hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]);
           regno++)
-       if (TEST_HARD_REG_BIT (clobbered_regs, regno))
-         {
-           error ("asm-specifier for variable %qs conflicts with "
-                  "asm clobber list",
-                  IDENTIFIER_POINTER (DECL_NAME (decl)));
-
-           /* Reset registerness to stop multiple errors emitted for a
-              single variable.  */
-           DECL_REGISTER (decl) = 0;
-           return true;
-         }
+       if (TEST_HARD_REG_BIT (regs, regno))
+         return true;
+    }
+
+  return false;
+}
+
+
+/* Check for overlap between registers marked in CLOBBERED_REGS and
+   anything inappropriate in DECL.  Emit error and return TRUE for error,
+   FALSE for ok.  */
+
+static bool
+decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs)
+{
+  /* Conflicts between asm-declared register variables and the clobber
+     list are not allowed.  */
+  if (decl_overlaps_hard_reg_set_p (decl, clobbered_regs))
+    {
+      error ("asm-specifier for variable %qs conflicts with asm clobber list",
+            IDENTIFIER_POINTER (DECL_NAME (decl)));
+
+      /* Reset registerness to stop multiple errors emitted for a single
+        variable.  */
+      DECL_REGISTER (decl) = 0;
+      return true;
     }
+
   return false;
 }
 
@@ -656,7 +669,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
      Case in point is when the i386 backend moved from cc0 to a hard reg --
      maintaining source-level compatibility means automatically clobbering
      the flags register.  */
-  clobbers = targetm.md_asm_clobbers (clobbers);
+  clobbers = targetm.md_asm_clobbers (outputs, inputs, clobbers);
 
   /* Count the number of meaningful clobbered registers, ignoring what
      we would ignore later.  */
index bb989f9..6c9b475 100644 (file)
@@ -379,7 +379,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE default_builtin_setjmp_frame_value
 
-#define TARGET_MD_ASM_CLOBBERS hook_tree_tree_identity
+#define TARGET_MD_ASM_CLOBBERS hook_tree_tree_tree_tree_3rd_identity
 
 #define TARGET_DWARF_CALLING_CONVENTION hook_int_tree_0
 
index 152cb7d..bb914da 100644 (file)
@@ -487,8 +487,8 @@ struct gcc_target
   rtx (* builtin_setjmp_frame_value) (void);
 
   /* This target hook should add STRING_CST trees for any hard regs
-     the port wishes to automatically clobber for all asms.  */
-  tree (* md_asm_clobbers) (tree);
+     the port wishes to automatically clobber for an asm.  */
+  tree (* md_asm_clobbers) (tree, tree, tree);
 
   /* This target hook allows the backend to specify a calling convention
      in the debug information.  This function actually returns an
index 41881bf..6a96e09 100644 (file)
@@ -3756,6 +3756,10 @@ extern tree resolve_asm_operand_names (tree, tree, tree);
 extern void expand_case (tree);
 extern void expand_decl (tree);
 extern void expand_anon_union_decl (tree, tree, tree);
+#ifdef HARD_CONST
+/* Silly ifdef to avoid having all includers depend on hard-reg-set.h.  */
+extern bool decl_overlaps_hard_reg_set_p (tree, const HARD_REG_SET);
+#endif
 
 /* In gimplify.c.  */
 extern tree create_artificial_label (void);