diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/config/cris/cris.c | 34 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 6 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 10 | ||||
-rw-r--r-- | gcc/hooks.c | 7 | ||||
-rw-r--r-- | gcc/hooks.h | 2 | ||||
-rw-r--r-- | gcc/stmt.c | 53 | ||||
-rw-r--r-- | gcc/target-def.h | 2 | ||||
-rw-r--r-- | gcc/target.h | 4 | ||||
-rw-r--r-- | gcc/tree.h | 4 |
10 files changed, 116 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 61dc2dd..d52a4a7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index a4c61b4..314ae0f 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -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]), diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f76812f..e254017 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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); diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 799a0f8..af269f2 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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 diff --git a/gcc/hooks.c b/gcc/hooks.c index 274d427a..6e6e7c7 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -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. */ diff --git a/gcc/hooks.h b/gcc/hooks.h index 133ea2a..b799a8c 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -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 @@ -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. */ diff --git a/gcc/target-def.h b/gcc/target-def.h index bb989f9..6c9b475 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -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 diff --git a/gcc/target.h b/gcc/target.h index 152cb7d..bb914da 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -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 @@ -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); |