mirror of git://gcc.gnu.org/git/gcc.git
tm.texi (TARGET_MD_ASM_CLOBBERS): Adjust wording to not imply that this is called once, independent of asms in code.
* 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. From-SVN: r96923
This commit is contained in:
parent
06cd9d7220
commit
6115892313
|
@ -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>
|
2005-03-23 DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
* optabs.c (expand_binop): Make sure the first subword's result
|
* optabs.c (expand_binop): Make sure the first subword's result
|
||||||
|
|
|
@ -125,7 +125,7 @@ static bool cris_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||||
tree, bool);
|
tree, bool);
|
||||||
static int cris_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
static int cris_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||||
tree, bool);
|
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. */
|
/* This is the argument from the "-max-stack-stackframe=" option. */
|
||||||
const char *cris_max_stackframe_str;
|
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. */
|
/* Worker function for TARGET_MD_ASM_CLOBBERS. */
|
||||||
|
|
||||||
static tree
|
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,
|
return tree_cons (NULL_TREE,
|
||||||
build_string (strlen (reg_names[CRIS_MOF_REGNUM]),
|
build_string (strlen (reg_names[CRIS_MOF_REGNUM]),
|
||||||
reg_names[CRIS_MOF_REGNUM]),
|
reg_names[CRIS_MOF_REGNUM]),
|
||||||
|
|
|
@ -923,7 +923,7 @@ static tree ix86_handle_struct_attribute (tree *, tree, tree, int, bool *);
|
||||||
static int extended_reg_mentioned_1 (rtx *, void *);
|
static int extended_reg_mentioned_1 (rtx *, void *);
|
||||||
static bool ix86_rtx_costs (rtx, int, int, int *);
|
static bool ix86_rtx_costs (rtx, int, int, int *);
|
||||||
static int min_insn_size (rtx);
|
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_must_pass_in_stack (enum machine_mode mode, tree type);
|
||||||
static bool ix86_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
static bool ix86_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||||
tree, bool);
|
tree, bool);
|
||||||
|
@ -16880,7 +16880,9 @@ ix86_vector_mode_supported_p (enum machine_mode mode)
|
||||||
with the old cc0-based compiler. */
|
with the old cc0-based compiler. */
|
||||||
|
|
||||||
static tree
|
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 = tree_cons (NULL_TREE, build_string (5, "flags"),
|
||||||
clobbers);
|
clobbers);
|
||||||
|
|
|
@ -9314,11 +9314,15 @@ from shared libraries (DLLs).
|
||||||
You need not define this macro if it would always evaluate to zero.
|
You need not define this macro if it would always evaluate to zero.
|
||||||
@end defmac
|
@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
|
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
|
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
|
@end deftypefn
|
||||||
|
|
||||||
@defmac MATH_LIBRARY
|
@defmac MATH_LIBRARY
|
||||||
|
|
|
@ -228,11 +228,12 @@ hook_rtx_tree_int_null (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED)
|
||||||
return NULL;
|
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
|
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. */
|
/* Generic hook that takes a tree and returns a NULL string. */
|
||||||
|
|
|
@ -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_identity (rtx);
|
||||||
extern rtx hook_rtx_rtx_null (rtx);
|
extern rtx hook_rtx_rtx_null (rtx);
|
||||||
extern rtx hook_rtx_tree_int_null (tree, int);
|
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 const char *hook_constcharptr_tree_null (tree);
|
||||||
extern tree hook_tree_tree_tree_bool_null (tree, tree, bool);
|
extern tree hook_tree_tree_tree_bool_null (tree, tree, bool);
|
||||||
#endif
|
#endif
|
||||||
|
|
43
gcc/stmt.c
43
gcc/stmt.c
|
@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||||
#include "tm.h"
|
#include "tm.h"
|
||||||
|
|
||||||
#include "rtl.h"
|
#include "rtl.h"
|
||||||
|
#include "hard-reg-set.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "tm_p.h"
|
#include "tm_p.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
@ -39,7 +40,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||||
#include "insn-config.h"
|
#include "insn-config.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "libfuncs.h"
|
#include "libfuncs.h"
|
||||||
#include "hard-reg-set.h"
|
|
||||||
#include "recog.h"
|
#include "recog.h"
|
||||||
#include "machmode.h"
|
#include "machmode.h"
|
||||||
#include "toplev.h"
|
#include "toplev.h"
|
||||||
|
@ -558,15 +558,12 @@ parse_input_constraint (const char **constraint_p, int input_num,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for overlap between registers marked in CLOBBERED_REGS and
|
/* Return true iff there's an overlap between REGS and DECL, where DECL
|
||||||
anything inappropriate in DECL. Emit error and return TRUE for error,
|
can be an asm-declared register. */
|
||||||
FALSE for ok. */
|
|
||||||
|
|
||||||
static bool
|
bool
|
||||||
decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs)
|
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)
|
if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
|
||||||
&& DECL_REGISTER (decl)
|
&& DECL_REGISTER (decl)
|
||||||
&& REG_P (DECL_RTL (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)
|
regno < (REGNO (reg)
|
||||||
+ hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]);
|
+ hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]);
|
||||||
regno++)
|
regno++)
|
||||||
if (TEST_HARD_REG_BIT (clobbered_regs, regno))
|
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)
|
||||||
{
|
{
|
||||||
error ("asm-specifier for variable %qs conflicts with "
|
/* Conflicts between asm-declared register variables and the clobber
|
||||||
"asm clobber list",
|
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)));
|
IDENTIFIER_POINTER (DECL_NAME (decl)));
|
||||||
|
|
||||||
/* Reset registerness to stop multiple errors emitted for a
|
/* Reset registerness to stop multiple errors emitted for a single
|
||||||
single variable. */
|
variable. */
|
||||||
DECL_REGISTER (decl) = 0;
|
DECL_REGISTER (decl) = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
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 --
|
Case in point is when the i386 backend moved from cc0 to a hard reg --
|
||||||
maintaining source-level compatibility means automatically clobbering
|
maintaining source-level compatibility means automatically clobbering
|
||||||
the flags register. */
|
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
|
/* Count the number of meaningful clobbered registers, ignoring what
|
||||||
we would ignore later. */
|
we would ignore later. */
|
||||||
|
|
|
@ -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_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
|
#define TARGET_DWARF_CALLING_CONVENTION hook_int_tree_0
|
||||||
|
|
||||||
|
|
|
@ -487,8 +487,8 @@ struct gcc_target
|
||||||
rtx (* builtin_setjmp_frame_value) (void);
|
rtx (* builtin_setjmp_frame_value) (void);
|
||||||
|
|
||||||
/* This target hook should add STRING_CST trees for any hard regs
|
/* This target hook should add STRING_CST trees for any hard regs
|
||||||
the port wishes to automatically clobber for all asms. */
|
the port wishes to automatically clobber for an asm. */
|
||||||
tree (* md_asm_clobbers) (tree);
|
tree (* md_asm_clobbers) (tree, tree, tree);
|
||||||
|
|
||||||
/* This target hook allows the backend to specify a calling convention
|
/* This target hook allows the backend to specify a calling convention
|
||||||
in the debug information. This function actually returns an
|
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_case (tree);
|
||||||
extern void expand_decl (tree);
|
extern void expand_decl (tree);
|
||||||
extern void expand_anon_union_decl (tree, tree, 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. */
|
/* In gimplify.c. */
|
||||||
extern tree create_artificial_label (void);
|
extern tree create_artificial_label (void);
|
||||||
|
|
Loading…
Reference in New Issue