@@ -4226,11 +4226,11 @@ optimized for speed.
@end table
All these attributes should use @code{(const_int 1)} to allow an alternative
-or @code{(const_int 0)} to disallow it. The attributes must be a static
-property of the subtarget; they cannot for example depend on the
-current operands, on the current optimization level, on the location
-of the insn within the body of a loop, on whether register allocation
-has finished, or on the current compiler pass.
+or @code{(const_int 0)} to disallow it. The attributes must have
+type @code{code,alternative} and be a static property of the
+subtarget; they cannot for example depend on the current operands, on
+the current optimization level, on whether register allocation has
+finished, or on the current compiler pass.
The @code{enabled} attribute is a correctness property. It tells GCC to act
as though the disabled alternatives were never defined in the first place.
@@ -4295,14 +4295,16 @@ with the @code{enabled} attribute defined like this:
@smallexample
-(define_attr "cpu_facility" "standard,new" (const_string "standard"))
+(define_attr "cpu_facility" "standard,new" (const_string "standard")
+ "code,alternative")
(define_attr "enabled" ""
(cond [(eq_attr "cpu_facility" "standard") (const_int 1)
(and (eq_attr "cpu_facility" "new")
(ne (symbol_ref "TARGET_NEW") (const_int 0)))
(const_int 1)]
- (const_int 0)))
+ (const_int 0))
+ "code,alternative")
@end smallexample
@@ -8173,7 +8175,8 @@ distances. @xref{Insn Lengths}.
@item enabled
The @code{enabled} attribute can be defined to prevent certain
alternatives of an insn definition from being used during code
-generation. @xref{Disable Insn Alternatives}.
+generation. @xref{Disable Insn Alternatives}. This attribute must
+have type @code{code,alternative}.
@item mnemonic
The @code{mnemonic} attribute can be defined to implement instruction
@@ -355,15 +355,15 @@ main (int argc, char **argv)
"#define insn_current_length hook_int_rtx_insn_unreachable\n"
"#include \"insn-addr.h\"\n"
"#endif\n"
- "extern int hook_int_rtx_1 (rtx);\n"
+ "extern int hook_int_int_int_1 (int, int);\n"
"#if !HAVE_ATTR_enabled\n"
- "#define get_attr_enabled hook_int_rtx_1\n"
+ "#define get_attr_enabled hook_int_int_int_1\n"
"#endif\n"
"#if !HAVE_ATTR_preferred_for_size\n"
- "#define get_attr_preferred_for_size hook_int_rtx_1\n"
+ "#define get_attr_preferred_for_size hook_int_int_int_1\n"
"#endif\n"
"#if !HAVE_ATTR_preferred_for_speed\n"
- "#define get_attr_preferred_for_speed hook_int_rtx_1\n"
+ "#define get_attr_preferred_for_speed hook_int_int_int_1\n"
"#endif\n");
/* Output flag masks for use by reorg.
@@ -191,6 +191,12 @@ default_can_output_mi_thunk_no_vcall (const_tree a ATTRIBUTE_UNUSED,
}
int
+hook_int_int_int_1 (int, int)
+{
+ return 1;
+}
+
+int
hook_int_uint_mode_1 (unsigned int a ATTRIBUTE_UNUSED,
machine_mode b ATTRIBUTE_UNUSED)
{
@@ -77,6 +77,7 @@ extern void hook_void_tree_treeptr (tree, tree *);
extern void hook_void_int_int (int, int);
extern void hook_void_gcc_optionsp (struct gcc_options *);
+extern int hook_int_int_int_1 (int, int);
extern int hook_int_uint_mode_1 (unsigned int, machine_mode);
extern int hook_int_const_tree_0 (const_tree);
extern int hook_int_const_tree_const_tree_1 (const_tree, const_tree);
@@ -2042,19 +2042,22 @@ have_bool_attr (bool_attr attr)
gcc_unreachable ();
}
-/* Return the value of ATTR for instruction INSN. */
+/* Return the value of ATTR for alternative ALTERNATIVE of the instruction
+ with code ICODE. */
static bool
-get_bool_attr (rtx_insn *insn, bool_attr attr)
+get_bool_attr (int icode, int alternative, bool_attr attr)
{
switch (attr)
{
case BA_ENABLED:
- return get_attr_enabled (insn);
+ return get_attr_enabled (icode, alternative);
case BA_PREFERRED_FOR_SIZE:
- return get_attr_enabled (insn) && get_attr_preferred_for_size (insn);
+ return (get_attr_enabled (icode, alternative)
+ && get_attr_preferred_for_size (icode, alternative));
case BA_PREFERRED_FOR_SPEED:
- return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn);
+ return (get_attr_enabled (icode, alternative)
+ && get_attr_preferred_for_speed (icode, alternative));
}
gcc_unreachable ();
}
@@ -2062,49 +2065,35 @@ get_bool_attr (rtx_insn *insn, bool_attr attr)
/* Like get_bool_attr_mask, but don't use the cache. */
static alternative_mask
-get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr)
+get_bool_attr_mask_uncached (int icode, bool_attr attr)
{
- /* Temporarily install enough information for get_attr_<foo> to assume
- that the insn operands are already cached. As above, the attribute
- mustn't depend on the values of operands, so we don't provide their
- real values here. */
- rtx_insn *old_insn = recog_data.insn;
- int old_alternative = cached_which_alternative;
-
- recog_data.insn = insn;
alternative_mask mask = ALL_ALTERNATIVES;
- int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives;
+ int n_alternatives = MAX (insn_data[icode].n_alternatives, 1);
for (int i = 0; i < n_alternatives; i++)
{
- cached_which_alternative = i;
- if (!get_bool_attr (insn, attr))
+ if (!get_bool_attr (icode, i, attr))
mask &= ~ALTERNATIVE_BIT (i);
}
- recog_data.insn = old_insn;
- cached_which_alternative = old_alternative;
return mask;
}
-/* Return the mask of operand alternatives that are allowed for INSN
- by boolean attribute ATTR. This mask depends only on INSN and on
- the current target; it does not depend on things like the values of
- operands. */
+/* Return the mask of operand alternatives that are allowed for instruction
+ code ICODE by boolean attribute ATTR. */
-static alternative_mask
-get_bool_attr_mask (rtx_insn *insn, bool_attr attr)
+alternative_mask
+get_bool_attr_mask (int icode, bool_attr attr)
{
/* Quick exit for asms and for targets that don't use these attributes. */
- int code = INSN_CODE (insn);
- if (code < 0 || !have_bool_attr (attr))
+ if (icode < 0 || !have_bool_attr (attr))
return ALL_ALTERNATIVES;
/* Calling get_attr_<foo> can be expensive, so cache the mask
for speed. */
- if (!this_target_recog->x_bool_attr_masks[code][attr])
- this_target_recog->x_bool_attr_masks[code][attr]
- = get_bool_attr_mask_uncached (insn, attr);
- return this_target_recog->x_bool_attr_masks[code][attr];
+ if (!this_target_recog->x_bool_attr_masks[icode][attr])
+ this_target_recog->x_bool_attr_masks[icode][attr]
+ = get_bool_attr_mask_uncached (icode, attr);
+ return this_target_recog->x_bool_attr_masks[icode][attr];
}
/* Return the set of alternatives of INSN that are allowed by the current
@@ -2113,7 +2102,7 @@ get_bool_attr_mask (rtx_insn *insn, bool_attr attr)
alternative_mask
get_enabled_alternatives (rtx_insn *insn)
{
- return get_bool_attr_mask (insn, BA_ENABLED);
+ return get_bool_attr_mask (INSN_CODE (insn), BA_ENABLED);
}
/* Return the set of alternatives of INSN that are allowed by the current
@@ -2124,9 +2113,9 @@ alternative_mask
get_preferred_alternatives (rtx_insn *insn)
{
if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))
- return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
+ return get_bool_attr_mask (INSN_CODE (insn), BA_PREFERRED_FOR_SPEED);
else
- return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
+ return get_bool_attr_mask (INSN_CODE (insn), BA_PREFERRED_FOR_SIZE);
}
/* Return the set of alternatives of INSN that are allowed by the current
@@ -2139,9 +2128,9 @@ alternative_mask
get_preferred_alternatives (rtx_insn *insn, basic_block bb)
{
if (optimize_bb_for_speed_p (bb))
- return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
+ return get_bool_attr_mask (INSN_CODE (insn), BA_PREFERRED_FOR_SPEED);
else
- return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
+ return get_bool_attr_mask (INSN_CODE (insn), BA_PREFERRED_FOR_SIZE);
}
/* Assert that the cached boolean attributes for INSN are still accurate.
@@ -2159,7 +2148,7 @@ check_bool_attrs (rtx_insn *insn)
enum bool_attr attr = (enum bool_attr) i;
if (this_target_recog->x_bool_attr_masks[code][attr])
gcc_assert (this_target_recog->x_bool_attr_masks[code][attr]
- == get_bool_attr_mask_uncached (insn, attr));
+ == get_bool_attr_mask_uncached (code, attr));
}
return true;
}
@@ -399,6 +399,7 @@ extern struct target_recog *this_target_recog;
#define this_target_recog (&default_target_recog)
#endif
+alternative_mask get_bool_attr_mask (int, bool_attr);
alternative_mask get_enabled_alternatives (rtx_insn *);
alternative_mask get_preferred_alternatives (rtx_insn *);
alternative_mask get_preferred_alternatives (rtx_insn *, basic_block);