mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-17 05:20:26 +08:00
target-def.h (TARGET_SCALAR_MODE_SUPPORTED_P): New.
* target-def.h (TARGET_SCALAR_MODE_SUPPORTED_P): New. * target.h (struct gcc_target): Add scalar_mode_supported_p. * targhooks.c (default_scalar_mode_supported_p): New. * targhooks.h (default_scalar_mode_supported_p): Declare. * doc/tm.texi (TARGET_SCALAR_MODE_SUPPORTED_P): Document. * c-common.c (handle_mode_attribute): Query scalar_mode_supported_p before attempting to create types. Tidy. * expr.c (vector_mode_valid_p): Use scalar_mode_supported_p. * config/alpha/alpha.c (alpha_scalar_mode_supported_p): New. (TARGET_SCALAR_MODE_SUPPORTED_P): New. From-SVN: r86593
This commit is contained in:
parent
9950712b1d
commit
6dd53648e9
@ -1,3 +1,18 @@
|
||||
2004-08-25 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* target-def.h (TARGET_SCALAR_MODE_SUPPORTED_P): New.
|
||||
* target.h (struct gcc_target): Add scalar_mode_supported_p.
|
||||
* targhooks.c (default_scalar_mode_supported_p): New.
|
||||
* targhooks.h (default_scalar_mode_supported_p): Declare.
|
||||
* doc/tm.texi (TARGET_SCALAR_MODE_SUPPORTED_P): Document.
|
||||
|
||||
* c-common.c (handle_mode_attribute): Query scalar_mode_supported_p
|
||||
before attempting to create types. Tidy.
|
||||
* expr.c (vector_mode_valid_p): Use scalar_mode_supported_p.
|
||||
|
||||
* config/alpha/alpha.c (alpha_scalar_mode_supported_p): New.
|
||||
(TARGET_SCALAR_MODE_SUPPORTED_P): New.
|
||||
|
||||
2004-08-25 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/i386/freebsd.h (SUBTARGET_OVERRIDE_OPTIONS): Don't
|
||||
|
@ -4267,7 +4267,7 @@ handle_mode_attribute (tree *node, tree name, tree args,
|
||||
int len = strlen (p);
|
||||
enum machine_mode mode = VOIDmode;
|
||||
tree typefm;
|
||||
tree ptr_type;
|
||||
bool valid_mode;
|
||||
|
||||
if (len > 4 && p[0] == '_' && p[1] == '_'
|
||||
&& p[len - 1] == '_' && p[len - 2] == '_')
|
||||
@ -4294,51 +4294,67 @@ handle_mode_attribute (tree *node, tree name, tree args,
|
||||
|
||||
if (mode == VOIDmode)
|
||||
{
|
||||
error ("unknown machine mode `%s'", p);
|
||||
error ("unknown machine mode %<%s%>", p);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (VECTOR_MODE_P (mode))
|
||||
valid_mode = false;
|
||||
switch (GET_MODE_CLASS (mode))
|
||||
{
|
||||
case MODE_INT:
|
||||
case MODE_PARTIAL_INT:
|
||||
case MODE_FLOAT:
|
||||
valid_mode = targetm.scalar_mode_supported_p (mode);
|
||||
break;
|
||||
|
||||
case MODE_COMPLEX_INT:
|
||||
case MODE_COMPLEX_FLOAT:
|
||||
valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
|
||||
break;
|
||||
|
||||
case MODE_VECTOR_INT:
|
||||
case MODE_VECTOR_FLOAT:
|
||||
warning ("specifying vector types with __attribute__ ((mode)) "
|
||||
"is deprecated");
|
||||
warning ("use __attribute__ ((vector_size)) instead");
|
||||
valid_mode = vector_mode_valid_p (mode);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!valid_mode)
|
||||
{
|
||||
error ("unable to emulate %<%s%>", p);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
|
||||
if (typefm == NULL_TREE)
|
||||
error ("no data type for mode `%s'", p);
|
||||
|
||||
else if ((TREE_CODE (type) == POINTER_TYPE
|
||||
|| TREE_CODE (type) == REFERENCE_TYPE)
|
||||
&& !targetm.valid_pointer_mode (mode))
|
||||
error ("invalid pointer mode `%s'", p);
|
||||
else
|
||||
if (POINTER_TYPE_P (type))
|
||||
{
|
||||
/* If this is a vector, make sure we either have hardware
|
||||
support, or we can emulate it. */
|
||||
if (VECTOR_MODE_P (mode) && !vector_mode_valid_p (mode))
|
||||
tree (*fn)(tree, enum machine_mode, bool);
|
||||
|
||||
if (!targetm.valid_pointer_mode (mode))
|
||||
{
|
||||
error ("unable to emulate '%s'", GET_MODE_NAME (mode));
|
||||
error ("invalid pointer mode %<%s%>", p);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == POINTER_TYPE)
|
||||
{
|
||||
ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
|
||||
mode, false);
|
||||
*node = ptr_type;
|
||||
}
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
ptr_type = build_reference_type_for_mode (TREE_TYPE (type),
|
||||
mode, false);
|
||||
*node = ptr_type;
|
||||
}
|
||||
if (TREE_CODE (type) == POINTER_TYPE)
|
||||
fn = build_pointer_type_for_mode;
|
||||
else
|
||||
*node = typefm;
|
||||
/* No need to layout the type here. The caller should do this. */
|
||||
fn = build_reference_type_for_mode;
|
||||
typefm = fn (TREE_TYPE (type), mode, false);
|
||||
}
|
||||
else
|
||||
typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
|
||||
if (typefm == NULL_TREE)
|
||||
{
|
||||
error ("no data type for mode %<%s%>", p);
|
||||
return NULL_TREE;
|
||||
}
|
||||
*node = typefm;
|
||||
|
||||
/* No need to layout the type here. The caller should do this. */
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
|
@ -670,14 +670,45 @@ alpha_extra_constraint (rtx value, int c)
|
||||
}
|
||||
}
|
||||
|
||||
/* Implements target hook vector_mode_supported_p. */
|
||||
/* The scalar modes supported differs from the default check-what-c-supports
|
||||
version in that sometimes TFmode is available even when long double
|
||||
indicates only DFmode. On unicosmk, we have the situation that HImode
|
||||
doesn't map to any C type, but of course we still support that. */
|
||||
|
||||
static bool
|
||||
alpha_scalar_mode_supported_p (enum machine_mode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case QImode:
|
||||
case HImode:
|
||||
case SImode:
|
||||
case DImode:
|
||||
case TImode: /* via optabs.c */
|
||||
return true;
|
||||
|
||||
case SFmode:
|
||||
case DFmode:
|
||||
return true;
|
||||
|
||||
case TFmode:
|
||||
return TARGET_HAS_XFLOATING_LIBS;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Alpha implements a couple of integer vector mode operations when
|
||||
TARGET_MAX is enabled. */
|
||||
|
||||
static bool
|
||||
alpha_vector_mode_supported_p (enum machine_mode mode)
|
||||
{
|
||||
if (TARGET_MAX
|
||||
&& ((mode == V8QImode)
|
||||
|| (mode == V4HImode)
|
||||
|| (mode == V2SImode)))
|
||||
&& (mode == V8QImode
|
||||
|| mode == V4HImode
|
||||
|| mode == V2SImode))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -9362,6 +9393,9 @@ alpha_init_libfuncs (void)
|
||||
#define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
|
||||
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
|
||||
#define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
|
||||
|
||||
#undef TARGET_SCALAR_MODE_SUPPORTED_P
|
||||
#define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
|
||||
#undef TARGET_VECTOR_MODE_SUPPORTED_P
|
||||
#define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
|
||||
|
||||
|
@ -3878,6 +3878,18 @@ arguments to @code{va_arg}; the latter two are as in
|
||||
@code{gimplify.c:gimplify_expr}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} bool TARGET_SCALAR_MODE_SUPPORTED_P (enum machine_mode @var{mode})
|
||||
Define this to return nonzero if the port is prepared to handle
|
||||
insns involving scalar mode @var{mode}. For a scalar mode to be
|
||||
considered supported, all the basic arithmetic and comparisons
|
||||
must work.
|
||||
|
||||
The default version of this hook returns true for any mode
|
||||
required to handle the basic C types (as defined by the port).
|
||||
Included here are the double-word arithmetic supported by the
|
||||
code in @file{optabs.c}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} bool TARGET_VECTOR_MODE_SUPPORTED_P (enum machine_mode @var{mode})
|
||||
Define this to return nonzero if the port is prepared to handle
|
||||
insns involving vector mode @var{mode}. At the very least, it
|
||||
|
@ -8799,7 +8799,7 @@ vector_mode_valid_p (enum machine_mode mode)
|
||||
|
||||
/* If we have support for the inner mode, we can safely emulate it.
|
||||
We may not have V2DI, but me can emulate with a pair of DIs. */
|
||||
return mov_optab->handlers[innermode].insn_code != CODE_FOR_nothing;
|
||||
return targetm.scalar_mode_supported_p (innermode);
|
||||
}
|
||||
|
||||
/* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */
|
||||
|
@ -305,6 +305,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#define TARGET_VALID_POINTER_MODE default_valid_pointer_mode
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_SCALAR_MODE_SUPPORTED_P
|
||||
#define TARGET_SCALAR_MODE_SUPPORTED_P default_scalar_mode_supported_p
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_VECTOR_MODE_SUPPORTED_P
|
||||
#define TARGET_VECTOR_MODE_SUPPORTED_P hook_bool_mode_false
|
||||
#endif
|
||||
@ -475,6 +479,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
TARGET_ENCODE_SECTION_INFO, \
|
||||
TARGET_STRIP_NAME_ENCODING, \
|
||||
TARGET_VALID_POINTER_MODE, \
|
||||
TARGET_SCALAR_MODE_SUPPORTED_P, \
|
||||
TARGET_VECTOR_MODE_SUPPORTED_P, \
|
||||
TARGET_VECTOR_OPAQUE_P, \
|
||||
TARGET_RTX_COSTS, \
|
||||
|
@ -381,7 +381,14 @@ struct gcc_target
|
||||
/* True if MODE is valid for a pointer in __attribute__((mode("MODE"))). */
|
||||
bool (* valid_pointer_mode) (enum machine_mode mode);
|
||||
|
||||
/* True if MODE is valid for a vector. */
|
||||
/* True if MODE is valid for the target. By "valid", we mean able to
|
||||
be manipulated in non-trivial ways. In particular, this means all
|
||||
the arithmetic is supported. */
|
||||
bool (* scalar_mode_supported_p) (enum machine_mode mode);
|
||||
|
||||
/* Similarly for vector modes. "Supported" here is less strict. At
|
||||
least some operations are supported; need to check optabs or builtins
|
||||
for further details. */
|
||||
bool (* vector_mode_supported_p) (enum machine_mode mode);
|
||||
|
||||
/* True if a vector is opaque. */
|
||||
|
@ -62,6 +62,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "tm_p.h"
|
||||
#include "target-def.h"
|
||||
|
||||
|
||||
void
|
||||
default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
|
||||
{
|
||||
@ -207,3 +208,49 @@ default_unwind_emit (FILE * stream ATTRIBUTE_UNUSED,
|
||||
/* Should never happen. */
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* True if MODE is valid for the target. By "valid", we mean able to
|
||||
be manipulated in non-trivial ways. In particular, this means all
|
||||
the arithmetic is supported.
|
||||
|
||||
By default we guess this means that any C type is supported. If
|
||||
we can't map the mode back to a type that would be available in C,
|
||||
then reject it. Special case, here, is the double-word arithmetic
|
||||
supported by optabs.c. */
|
||||
|
||||
bool
|
||||
default_scalar_mode_supported_p (enum machine_mode mode)
|
||||
{
|
||||
int precision = GET_MODE_PRECISION (mode);
|
||||
|
||||
switch (GET_MODE_CLASS (mode))
|
||||
{
|
||||
case MODE_PARTIAL_INT:
|
||||
case MODE_INT:
|
||||
if (precision == CHAR_TYPE_SIZE)
|
||||
return true;
|
||||
if (precision == SHORT_TYPE_SIZE)
|
||||
return true;
|
||||
if (precision == INT_TYPE_SIZE)
|
||||
return true;
|
||||
if (precision == LONG_TYPE_SIZE)
|
||||
return true;
|
||||
if (precision == LONG_LONG_TYPE_SIZE)
|
||||
return true;
|
||||
if (precision == 2 * BITS_PER_WORD)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
case MODE_FLOAT:
|
||||
if (precision == FLOAT_TYPE_SIZE)
|
||||
return true;
|
||||
if (precision == DOUBLE_TYPE_SIZE)
|
||||
return true;
|
||||
if (precision == LONG_DOUBLE_TYPE_SIZE)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
@ -43,3 +43,5 @@ extern bool hook_pass_by_reference_must_pass_in_stack
|
||||
(CUMULATIVE_ARGS *, enum machine_mode mode, tree, bool);
|
||||
|
||||
extern void default_unwind_emit (FILE *, rtx);
|
||||
|
||||
extern bool default_scalar_mode_supported_p (enum machine_mode);
|
||||
|
Loading…
x
Reference in New Issue
Block a user