Commit 5c0caeb3 by Richard Sandiford Committed by Richard Sandiford

Add support for MODE_VECTOR_BOOL

This patch adds a new mode class to represent vectors of booleans.
GET_MODE_BITSIZE (m) / GET_MODE_NUNITS (m) determines the number
of bits that are used to represent each boolean; this can be 1
for a fully-packed representation or greater than 1 for an unpacked
representation.  In the latter case, the value of bits other than
the lowest is not significant.

These are used by the SVE port to represent predicates.

2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* mode-classes.def (MODE_VECTOR_BOOL): New mode class.
	* machmode.h (INTEGRAL_MODE_P, VECTOR_MODE_P): Return true
	for MODE_VECTOR_BOOL.
	* machmode.def (VECTOR_BOOL_MODE): Document.
	* genmodes.c (VECTOR_BOOL_MODE): New macro.
	(make_vector_bool_mode): New function.
	(complete_mode, emit_mode_wider, emit_mode_adjustments): Handle
	MODE_VECTOR_BOOL.
	* lto-streamer-in.c (lto_input_mode_table): Likewise.
	* rtx-vector-builder.c (rtx_vector_builder::find_cached_value):
	Likewise.
	* stor-layout.c (int_mode_for_mode): Likewise.
	* tree.c (build_vector_type_for_mode): Likewise.
	* varasm.c (output_constant_pool_2): Likewise.
	* emit-rtl.c (init_emit_once): Make sure that CONST1_RTX (BImode) and
	CONSTM1_RTX (BImode) are the same thing.  Initialize const_tiny_rtx
	for MODE_VECTOR_BOOL.
	* expr.c (expand_expr_real_1): Use VECTOR_MODE_P instead of a list
	of mode class checks.
	* tree-vect-generic.c (expand_vector_operation): Use VECTOR_MODE_P
	instead of a list of mode class checks.
	(expand_vector_scalar_condition): Likewise.
	(type_for_widest_vector_mode): Handle BImode as an inner mode.

gcc/c-family/
	* c-common.c (c_common_type_for_mode): Handle MODE_VECTOR_BOOL.

gcc/fortran/
	* trans-types.c (gfc_type_for_mode): Handle MODE_VECTOR_BOOL.

gcc/go/
	* go-lang.c (go_langhook_type_for_mode): Handle MODE_VECTOR_BOOL.

gcc/lto/
	* lto-lang.c (lto_type_for_mode): Handle MODE_VECTOR_BOOL.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r256202
parent cf098191
...@@ -2,6 +2,34 @@ ...@@ -2,6 +2,34 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* mode-classes.def (MODE_VECTOR_BOOL): New mode class.
* machmode.h (INTEGRAL_MODE_P, VECTOR_MODE_P): Return true
for MODE_VECTOR_BOOL.
* machmode.def (VECTOR_BOOL_MODE): Document.
* genmodes.c (VECTOR_BOOL_MODE): New macro.
(make_vector_bool_mode): New function.
(complete_mode, emit_mode_wider, emit_mode_adjustments): Handle
MODE_VECTOR_BOOL.
* lto-streamer-in.c (lto_input_mode_table): Likewise.
* rtx-vector-builder.c (rtx_vector_builder::find_cached_value):
Likewise.
* stor-layout.c (int_mode_for_mode): Likewise.
* tree.c (build_vector_type_for_mode): Likewise.
* varasm.c (output_constant_pool_2): Likewise.
* emit-rtl.c (init_emit_once): Make sure that CONST1_RTX (BImode) and
CONSTM1_RTX (BImode) are the same thing. Initialize const_tiny_rtx
for MODE_VECTOR_BOOL.
* expr.c (expand_expr_real_1): Use VECTOR_MODE_P instead of a list
of mode class checks.
* tree-vect-generic.c (expand_vector_operation): Use VECTOR_MODE_P
instead of a list of mode class checks.
(expand_vector_scalar_condition): Likewise.
(type_for_widest_vector_mode): Handle BImode as an inner mode.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* machmode.h (mode_size): Change from unsigned short to * machmode.h (mode_size): Change from unsigned short to
poly_uint16_pod. poly_uint16_pod.
(mode_to_bytes): Return a poly_uint16 rather than an unsigned short. (mode_to_bytes): Return a poly_uint16 rather than an unsigned short.
......
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* c-common.c (c_common_type_for_mode): Handle MODE_VECTOR_BOOL.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* c-ubsan.c (ubsan_instrument_shift): Treat GET_MODE_BITSIZE * c-ubsan.c (ubsan_instrument_shift): Treat GET_MODE_BITSIZE
as polynomial. as polynomial.
......
...@@ -2279,6 +2279,14 @@ c_common_type_for_mode (machine_mode mode, int unsignedp) ...@@ -2279,6 +2279,14 @@ c_common_type_for_mode (machine_mode mode, int unsignedp)
if (inner_type != NULL_TREE) if (inner_type != NULL_TREE)
return build_complex_type (inner_type); return build_complex_type (inner_type);
} }
else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
&& valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
{
unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode),
GET_MODE_NUNITS (mode));
tree bool_type = build_nonstandard_boolean_type (elem_bits);
return build_vector_type_for_mode (bool_type, mode);
}
else if (VECTOR_MODE_P (mode) else if (VECTOR_MODE_P (mode)
&& valid_vector_subparts_p (GET_MODE_NUNITS (mode))) && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
{ {
......
...@@ -6268,6 +6268,12 @@ init_emit_once (void) ...@@ -6268,6 +6268,12 @@ init_emit_once (void)
FOR_EACH_MODE_IN_CLASS (mode, MODE_INT) FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
const_tiny_rtx[3][(int) mode] = constm1_rtx; const_tiny_rtx[3][(int) mode] = constm1_rtx;
/* For BImode, 1 and -1 are unsigned and signed interpretations
of the same value. */
const_tiny_rtx[0][(int) BImode] = const0_rtx;
const_tiny_rtx[1][(int) BImode] = const_true_rtx;
const_tiny_rtx[3][(int) BImode] = const_true_rtx;
for (mode = MIN_MODE_PARTIAL_INT; for (mode = MIN_MODE_PARTIAL_INT;
mode <= MAX_MODE_PARTIAL_INT; mode <= MAX_MODE_PARTIAL_INT;
mode = (machine_mode)((int)(mode) + 1)) mode = (machine_mode)((int)(mode) + 1))
...@@ -6285,6 +6291,15 @@ init_emit_once (void) ...@@ -6285,6 +6291,15 @@ init_emit_once (void)
const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner); const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
} }
/* As for BImode, "all 1" and "all -1" are unsigned and signed
interpretations of the same value. */
FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_BOOL)
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
const_tiny_rtx[3][(int) mode] = gen_const_vector (mode, 3);
const_tiny_rtx[1][(int) mode] = const_tiny_rtx[3][(int) mode];
}
FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT) FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
{ {
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0); const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
...@@ -6386,10 +6401,6 @@ init_emit_once (void) ...@@ -6386,10 +6401,6 @@ init_emit_once (void)
if (GET_MODE_CLASS ((machine_mode) i) == MODE_CC) if (GET_MODE_CLASS ((machine_mode) i) == MODE_CC)
const_tiny_rtx[0][i] = const0_rtx; const_tiny_rtx[0][i] = const0_rtx;
const_tiny_rtx[0][(int) BImode] = const0_rtx;
if (STORE_FLAG_VALUE == 1)
const_tiny_rtx[1][(int) BImode] = const1_rtx;
FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_POINTER_BOUNDS) FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_POINTER_BOUNDS)
{ {
scalar_mode smode = smode_iter.require (); scalar_mode smode = smode_iter.require ();
......
...@@ -10082,12 +10082,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, ...@@ -10082,12 +10082,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
case VECTOR_CST: case VECTOR_CST:
{ {
tree tmp = NULL_TREE; tree tmp = NULL_TREE;
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT if (VECTOR_MODE_P (mode))
|| GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
|| GET_MODE_CLASS (mode) == MODE_VECTOR_FRACT
|| GET_MODE_CLASS (mode) == MODE_VECTOR_UFRACT
|| GET_MODE_CLASS (mode) == MODE_VECTOR_ACCUM
|| GET_MODE_CLASS (mode) == MODE_VECTOR_UACCUM)
return const_vector_from_tree (exp); return const_vector_from_tree (exp);
scalar_int_mode int_mode; scalar_int_mode int_mode;
if (is_int_mode (mode, &int_mode)) if (is_int_mode (mode, &int_mode))
......
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* trans-types.c (gfc_type_for_mode): Handle MODE_VECTOR_BOOL.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* trans-types.c (gfc_type_for_mode): Check valid_vector_subparts_p. * trans-types.c (gfc_type_for_mode): Check valid_vector_subparts_p.
2018-01-03 Thomas Koenig <tkoenig@gcc.gnu.org> 2018-01-03 Thomas Koenig <tkoenig@gcc.gnu.org>
......
...@@ -3185,6 +3185,14 @@ gfc_type_for_mode (machine_mode mode, int unsignedp) ...@@ -3185,6 +3185,14 @@ gfc_type_for_mode (machine_mode mode, int unsignedp)
tree type = gfc_type_for_size (GET_MODE_PRECISION (int_mode), unsignedp); tree type = gfc_type_for_size (GET_MODE_PRECISION (int_mode), unsignedp);
return type != NULL_TREE && mode == TYPE_MODE (type) ? type : NULL_TREE; return type != NULL_TREE && mode == TYPE_MODE (type) ? type : NULL_TREE;
} }
else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
&& valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
{
unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode),
GET_MODE_NUNITS (mode));
tree bool_type = build_nonstandard_boolean_type (elem_bits);
return build_vector_type_for_mode (bool_type, mode);
}
else if (VECTOR_MODE_P (mode) else if (VECTOR_MODE_P (mode)
&& valid_vector_subparts_p (GET_MODE_NUNITS (mode))) && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
{ {
......
...@@ -375,6 +375,10 @@ complete_mode (struct mode_data *m) ...@@ -375,6 +375,10 @@ complete_mode (struct mode_data *m)
m->bytesize = 2 * m->component->bytesize; m->bytesize = 2 * m->component->bytesize;
break; break;
case MODE_VECTOR_BOOL:
validate_mode (m, UNSET, SET, SET, SET, UNSET);
break;
case MODE_VECTOR_INT: case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT: case MODE_VECTOR_FLOAT:
case MODE_VECTOR_FRACT: case MODE_VECTOR_FRACT:
...@@ -526,6 +530,28 @@ make_vector_modes (enum mode_class cl, unsigned int width, ...@@ -526,6 +530,28 @@ make_vector_modes (enum mode_class cl, unsigned int width,
} }
} }
/* Create a vector of booleans called NAME with COUNT elements and
BYTESIZE bytes in total. */
#define VECTOR_BOOL_MODE(NAME, COUNT, BYTESIZE) \
make_vector_bool_mode (#NAME, COUNT, BYTESIZE, __FILE__, __LINE__)
static void ATTRIBUTE_UNUSED
make_vector_bool_mode (const char *name, unsigned int count,
unsigned int bytesize, const char *file,
unsigned int line)
{
struct mode_data *m = find_mode ("BI");
if (!m)
{
error ("%s:%d: no mode \"BI\"", file, line);
return;
}
struct mode_data *v = new_mode (MODE_VECTOR_BOOL, name, file, line);
v->component = m;
v->ncomponents = count;
v->bytesize = bytesize;
}
/* Input. */ /* Input. */
#define _SPECIAL_MODE(C, N) \ #define _SPECIAL_MODE(C, N) \
...@@ -1438,7 +1464,8 @@ emit_mode_wider (void) ...@@ -1438,7 +1464,8 @@ emit_mode_wider (void)
/* For vectors we want twice the number of components, /* For vectors we want twice the number of components,
with the same element type. */ with the same element type. */
if (m->cl == MODE_VECTOR_INT if (m->cl == MODE_VECTOR_BOOL
|| m->cl == MODE_VECTOR_INT
|| m->cl == MODE_VECTOR_FLOAT || m->cl == MODE_VECTOR_FLOAT
|| m->cl == MODE_VECTOR_FRACT || m->cl == MODE_VECTOR_FRACT
|| m->cl == MODE_VECTOR_UFRACT || m->cl == MODE_VECTOR_UFRACT
...@@ -1657,6 +1684,7 @@ emit_mode_adjustments (void) ...@@ -1657,6 +1684,7 @@ emit_mode_adjustments (void)
printf ("\n /* %s:%d */\n", a->file, a->line); printf ("\n /* %s:%d */\n", a->file, a->line);
switch (a->mode->cl) switch (a->mode->cl)
{ {
case MODE_VECTOR_BOOL:
case MODE_VECTOR_INT: case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT: case MODE_VECTOR_FLOAT:
case MODE_VECTOR_FRACT: case MODE_VECTOR_FRACT:
...@@ -1688,6 +1716,10 @@ emit_mode_adjustments (void) ...@@ -1688,6 +1716,10 @@ emit_mode_adjustments (void)
m->name); m->name);
break; break;
case MODE_VECTOR_BOOL:
/* Changes to BImode should not affect vector booleans. */
break;
case MODE_VECTOR_INT: case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT: case MODE_VECTOR_FLOAT:
case MODE_VECTOR_FRACT: case MODE_VECTOR_FRACT:
...@@ -1728,6 +1760,10 @@ emit_mode_adjustments (void) ...@@ -1728,6 +1760,10 @@ emit_mode_adjustments (void)
printf (" mode_base_align[E_%smode] = s;\n", m->name); printf (" mode_base_align[E_%smode] = s;\n", m->name);
break; break;
case MODE_VECTOR_BOOL:
/* Changes to BImode should not affect vector booleans. */
break;
case MODE_VECTOR_INT: case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT: case MODE_VECTOR_FLOAT:
case MODE_VECTOR_FRACT: case MODE_VECTOR_FRACT:
......
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* go-lang.c (go_langhook_type_for_mode): Handle MODE_VECTOR_BOOL.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* go-lang.c (go_langhook_type_for_mode): Check valid_vector_subparts_p. * go-lang.c (go_langhook_type_for_mode): Check valid_vector_subparts_p.
2018-01-03 Jakub Jelinek <jakub@redhat.com> 2018-01-03 Jakub Jelinek <jakub@redhat.com>
......
...@@ -377,9 +377,17 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp) ...@@ -377,9 +377,17 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp)
make sense for the middle-end to ask the frontend for a type make sense for the middle-end to ask the frontend for a type
which the frontend does not support. However, at least for now which the frontend does not support. However, at least for now
it is required. See PR 46805. */ it is required. See PR 46805. */
if (VECTOR_MODE_P (mode) if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
&& valid_vector_subparts_p (GET_MODE_NUNITS (mode))) && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
{ {
unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode),
GET_MODE_NUNITS (mode));
tree bool_type = build_nonstandard_boolean_type (elem_bits);
return build_vector_type_for_mode (bool_type, mode);
}
else if (VECTOR_MODE_P (mode)
&& valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
{
tree inner; tree inner;
inner = go_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp); inner = go_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
......
...@@ -1675,6 +1675,7 @@ lto_input_mode_table (struct lto_file_decl_data *file_data) ...@@ -1675,6 +1675,7 @@ lto_input_mode_table (struct lto_file_decl_data *file_data)
{ {
switch (mclass) switch (mclass)
{ {
case MODE_VECTOR_BOOL:
case MODE_VECTOR_INT: case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT: case MODE_VECTOR_FLOAT:
case MODE_VECTOR_FRACT: case MODE_VECTOR_FRACT:
......
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* lto-lang.c (lto_type_for_mode): Handle MODE_VECTOR_BOOL.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* lto-lang.c (lto_type_for_mode): Check valid_vector_subparts_p. * lto-lang.c (lto_type_for_mode): Check valid_vector_subparts_p.
* lto.c (hash_canonical_type): Handle polynomial TYPE_VECTOR_SUBPARTS. * lto.c (hash_canonical_type): Handle polynomial TYPE_VECTOR_SUBPARTS.
......
...@@ -1012,6 +1012,14 @@ lto_type_for_mode (machine_mode mode, int unsigned_p) ...@@ -1012,6 +1012,14 @@ lto_type_for_mode (machine_mode mode, int unsigned_p)
if (inner_type != NULL_TREE) if (inner_type != NULL_TREE)
return build_complex_type (inner_type); return build_complex_type (inner_type);
} }
else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
&& valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
{
unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode),
GET_MODE_NUNITS (mode));
tree bool_type = build_nonstandard_boolean_type (elem_bits);
return build_vector_type_for_mode (bool_type, mode);
}
else if (VECTOR_MODE_P (mode) else if (VECTOR_MODE_P (mode)
&& valid_vector_subparts_p (GET_MODE_NUNITS (mode))) && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
{ {
......
...@@ -142,6 +142,13 @@ along with GCC; see the file COPYING3. If not see ...@@ -142,6 +142,13 @@ along with GCC; see the file COPYING3. If not see
than two bytes (if CLASS is FLOAT). CLASS must be INT or than two bytes (if CLASS is FLOAT). CLASS must be INT or
FLOAT. The names follow the same rule as VECTOR_MODE uses. FLOAT. The names follow the same rule as VECTOR_MODE uses.
VECTOR_BOOL_MODE (NAME, COUNT, BYTESIZE)
Create a vector mode called NAME that contains COUNT boolean
elements and occupies BYTESIZE bytes in total. Each boolean
element occupies (COUNT * BITS_PER_UNIT) / BYTESIZE bits, with
the element at index 0 occupying the lsb of the first byte in
memory. Only the lowest bit of each element is significant.
COMPLEX_MODES (CLASS); COMPLEX_MODES (CLASS);
For all modes presently declared in class CLASS, construct For all modes presently declared in class CLASS, construct
corresponding complex modes. Modes smaller than one byte corresponding complex modes. Modes smaller than one byte
......
...@@ -108,6 +108,7 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES]; ...@@ -108,6 +108,7 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
(GET_MODE_CLASS (MODE) == MODE_INT \ (GET_MODE_CLASS (MODE) == MODE_INT \
|| GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \ || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_INT) || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT)
/* Nonzero if MODE is a floating-point mode. */ /* Nonzero if MODE is a floating-point mode. */
...@@ -123,8 +124,9 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES]; ...@@ -123,8 +124,9 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)
/* Nonzero if MODE is a vector mode. */ /* Nonzero if MODE is a vector mode. */
#define VECTOR_MODE_P(MODE) \ #define VECTOR_MODE_P(MODE) \
(GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \ (GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT \ || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT \ || GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT \ || GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT \
......
...@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
DEF_MODE_CLASS (MODE_DECIMAL_FLOAT), /* decimal floating point */ \ DEF_MODE_CLASS (MODE_DECIMAL_FLOAT), /* decimal floating point */ \
DEF_MODE_CLASS (MODE_COMPLEX_INT), /* complex numbers */ \ DEF_MODE_CLASS (MODE_COMPLEX_INT), /* complex numbers */ \
DEF_MODE_CLASS (MODE_COMPLEX_FLOAT), \ DEF_MODE_CLASS (MODE_COMPLEX_FLOAT), \
DEF_MODE_CLASS (MODE_VECTOR_BOOL), /* vectors of single bits */ \
DEF_MODE_CLASS (MODE_VECTOR_INT), /* SIMD vectors */ \ DEF_MODE_CLASS (MODE_VECTOR_INT), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_FRACT), /* SIMD vectors */ \ DEF_MODE_CLASS (MODE_VECTOR_FRACT), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_UFRACT), /* SIMD vectors */ \ DEF_MODE_CLASS (MODE_VECTOR_UFRACT), /* SIMD vectors */ \
......
...@@ -88,6 +88,16 @@ rtx_vector_builder::find_cached_value () ...@@ -88,6 +88,16 @@ rtx_vector_builder::find_cached_value ()
rtx elt = (*this)[0]; rtx elt = (*this)[0];
if (GET_MODE_CLASS (m_mode) == MODE_VECTOR_BOOL)
{
if (elt == const1_rtx || elt == constm1_rtx)
return CONST1_RTX (m_mode);
else if (elt == const0_rtx)
return CONST0_RTX (m_mode);
else
gcc_unreachable ();
}
/* We can be called before the global vector constants are set up, /* We can be called before the global vector constants are set up,
but in that case we'll just return null. */ but in that case we'll just return null. */
scalar_mode inner_mode = GET_MODE_INNER (m_mode); scalar_mode inner_mode = GET_MODE_INNER (m_mode);
......
...@@ -379,12 +379,13 @@ int_mode_for_mode (machine_mode mode) ...@@ -379,12 +379,13 @@ int_mode_for_mode (machine_mode mode)
case MODE_COMPLEX_FLOAT: case MODE_COMPLEX_FLOAT:
case MODE_FLOAT: case MODE_FLOAT:
case MODE_DECIMAL_FLOAT: case MODE_DECIMAL_FLOAT:
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
case MODE_FRACT: case MODE_FRACT:
case MODE_ACCUM: case MODE_ACCUM:
case MODE_UFRACT: case MODE_UFRACT:
case MODE_UACCUM: case MODE_UACCUM:
case MODE_VECTOR_BOOL:
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
case MODE_VECTOR_FRACT: case MODE_VECTOR_FRACT:
case MODE_VECTOR_ACCUM: case MODE_VECTOR_ACCUM:
case MODE_VECTOR_UFRACT: case MODE_VECTOR_UFRACT:
......
...@@ -981,12 +981,7 @@ expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type ...@@ -981,12 +981,7 @@ expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type
/* If the compute mode is not a vector mode (hence we are not decomposing /* If the compute mode is not a vector mode (hence we are not decomposing
a BLKmode vector to smaller, hardware-supported vectors), we may want a BLKmode vector to smaller, hardware-supported vectors), we may want
to expand the operations in parallel. */ to expand the operations in parallel. */
if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT if (!VECTOR_MODE_P (compute_mode))
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FRACT
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UFRACT
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_ACCUM
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UACCUM)
switch (code) switch (code)
{ {
case PLUS_EXPR: case PLUS_EXPR:
...@@ -1175,6 +1170,8 @@ type_for_widest_vector_mode (tree type, optab op) ...@@ -1175,6 +1170,8 @@ type_for_widest_vector_mode (tree type, optab op)
mode = MIN_MODE_VECTOR_ACCUM; mode = MIN_MODE_VECTOR_ACCUM;
else if (SCALAR_UACCUM_MODE_P (inner_mode)) else if (SCALAR_UACCUM_MODE_P (inner_mode))
mode = MIN_MODE_VECTOR_UACCUM; mode = MIN_MODE_VECTOR_UACCUM;
else if (inner_mode == BImode)
mode = MIN_MODE_VECTOR_BOOL;
else else
mode = MIN_MODE_VECTOR_INT; mode = MIN_MODE_VECTOR_INT;
...@@ -1537,12 +1534,7 @@ expand_vector_scalar_condition (gimple_stmt_iterator *gsi) ...@@ -1537,12 +1534,7 @@ expand_vector_scalar_condition (gimple_stmt_iterator *gsi)
/* If the compute mode is not a vector mode (hence we are not decomposing /* If the compute mode is not a vector mode (hence we are not decomposing
a BLKmode vector to smaller, hardware-supported vectors), we may want a BLKmode vector to smaller, hardware-supported vectors), we may want
to expand the operations in parallel. */ to expand the operations in parallel. */
if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT if (!VECTOR_MODE_P (compute_mode))
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FRACT
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UFRACT
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_ACCUM
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UACCUM)
new_rhs = expand_vector_parallel (gsi, do_cond, type, rhs2, rhs3, new_rhs = expand_vector_parallel (gsi, do_cond, type, rhs2, rhs3,
COND_EXPR); COND_EXPR);
else else
......
...@@ -10509,6 +10509,7 @@ build_vector_type_for_mode (tree innertype, machine_mode mode) ...@@ -10509,6 +10509,7 @@ build_vector_type_for_mode (tree innertype, machine_mode mode)
switch (GET_MODE_CLASS (mode)) switch (GET_MODE_CLASS (mode))
{ {
case MODE_VECTOR_BOOL:
case MODE_VECTOR_INT: case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT: case MODE_VECTOR_FLOAT:
case MODE_VECTOR_FRACT: case MODE_VECTOR_FRACT:
......
...@@ -3918,6 +3918,32 @@ output_constant_pool_2 (fixed_size_mode mode, rtx x, unsigned int align) ...@@ -3918,6 +3918,32 @@ output_constant_pool_2 (fixed_size_mode mode, rtx x, unsigned int align)
assemble_integer (x, GET_MODE_SIZE (mode), align, 1); assemble_integer (x, GET_MODE_SIZE (mode), align, 1);
break; break;
case MODE_VECTOR_BOOL:
{
gcc_assert (GET_CODE (x) == CONST_VECTOR);
/* Pick the smallest integer mode that contains at least one
whole element. Often this is byte_mode and contains more
than one element. */
unsigned int nelts = GET_MODE_NUNITS (mode);
unsigned int elt_bits = GET_MODE_BITSIZE (mode) / nelts;
unsigned int int_bits = MAX (elt_bits, BITS_PER_UNIT);
scalar_int_mode int_mode = int_mode_for_size (int_bits, 0).require ();
/* Build the constant up one integer at a time. */
unsigned int elts_per_int = int_bits / elt_bits;
for (unsigned int i = 0; i < nelts; i += elts_per_int)
{
unsigned HOST_WIDE_INT value = 0;
unsigned int limit = MIN (nelts - i, elts_per_int);
for (unsigned int j = 0; j < limit; ++j)
if (INTVAL (CONST_VECTOR_ELT (x, i + j)) != 0)
value |= 1 << (j * elt_bits);
output_constant_pool_2 (int_mode, gen_int_mode (value, int_mode),
i != 0 ? MIN (align, int_bits) : align);
}
break;
}
case MODE_VECTOR_FLOAT: case MODE_VECTOR_FLOAT:
case MODE_VECTOR_INT: case MODE_VECTOR_INT:
case MODE_VECTOR_FRACT: case MODE_VECTOR_FRACT:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment