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>
|
||||
|
||||
* 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);
|
||||
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]),
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
53
gcc/stmt.c
53
gcc/stmt.c
@ -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. */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user