Add COMPLEX_VECTOR_INT modes for amdgcn This enables only minimal support for complex types containing integer vectors with the intention of allowing vectorized divmod libfunc operations (these return a pair of integers modelled as a complex number). There's no way to declare variables of this mode in the front-end, and no attempt to support it everywhere that complex modes can exist; the only use-case, at present, is the implicit use by divmod calls generated by the middle-end. In order to prevent unexpected problems with other architectures these modes are only enabled for amdgcn. gcc/ChangeLog: * config/gcn/gcn-modes.def: Initialize COMPLEX_VECTOR_INT modes. * genmodes.cc (complex_class): Support MODE_COMPLEX_VECTOR_INT. (complete_mode): Likewise. (emit_mode_unit_size): Upgrade mode_unit_size type to short. (emit_mode_adjustments): Support MODE_COMPLEX_VECTOR_INT. * machmode.def: Mention MODE_COMPLEX_VECTOR_INT. * machmode.h (mode_to_unit_size): Upgrade type to short. * mode-classes.def: Add MODE_COMPLEX_VECTOR_INT. * stor-layout.cc (int_mode_for_mode): Support MODE_COMPLEX_VECTOR_INT. * tree.cc (build_complex_type): Allow VECTOR_INTEGER_TYPE_P. diff --git a/gcc/config/gcn/gcn-modes.def b/gcc/config/gcn/gcn-modes.def index 1357bec825d..486168fbeb3 100644 --- a/gcc/config/gcn/gcn-modes.def +++ b/gcc/config/gcn/gcn-modes.def @@ -121,3 +121,6 @@ ADJUST_ALIGNMENT (V2TI, 16); ADJUST_ALIGNMENT (V2HF, 2); ADJUST_ALIGNMENT (V2SF, 4); ADJUST_ALIGNMENT (V2DF, 8); + +/* These are used for vectorized divmod. */ +COMPLEX_MODES (VECTOR_INT); diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc index 715787b8f48..d472ee5a9a3 100644 --- a/gcc/genmodes.cc +++ b/gcc/genmodes.cc @@ -125,6 +125,7 @@ complex_class (enum mode_class c) case MODE_INT: return MODE_COMPLEX_INT; case MODE_PARTIAL_INT: return MODE_COMPLEX_INT; case MODE_FLOAT: return MODE_COMPLEX_FLOAT; + case MODE_VECTOR_INT: return MODE_COMPLEX_VECTOR_INT; default: error ("no complex class for class %s", mode_class_names[c]); return MODE_RANDOM; @@ -382,6 +383,7 @@ complete_mode (struct mode_data *m) case MODE_COMPLEX_INT: case MODE_COMPLEX_FLOAT: + case MODE_COMPLEX_VECTOR_INT: /* Complex modes should have a component indicated, but no more. */ validate_mode (m, UNSET, UNSET, SET, UNSET, UNSET); m->ncomponents = 2; @@ -1173,10 +1175,10 @@ inline __attribute__((__always_inline__))\n\ #else\n\ extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\ #endif\n\ -unsigned char\n\ +unsigned short\n\ mode_unit_size_inline (machine_mode mode)\n\ {\n\ - extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];\ + extern CONST_MODE_UNIT_SIZE unsigned short mode_unit_size[NUM_MACHINE_MODES];\ \n\ gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\ switch (mode)\n\ @@ -1683,7 +1685,7 @@ emit_mode_unit_size (void) int c; struct mode_data *m; - print_maybe_const_decl ("%sunsigned char", "mode_unit_size", + print_maybe_const_decl ("%sunsigned short", "mode_unit_size", "NUM_MACHINE_MODES", adj_bytesize); for_all_modes (c, m) @@ -1873,6 +1875,7 @@ emit_mode_adjustments (void) { case MODE_COMPLEX_INT: case MODE_COMPLEX_FLOAT: + case MODE_COMPLEX_VECTOR_INT: printf (" mode_size[E_%smode] = 2*s;\n", m->name); printf (" mode_unit_size[E_%smode] = s;\n", m->name); printf (" mode_base_align[E_%smode] = s & (~s + 1);\n", @@ -1920,6 +1923,7 @@ emit_mode_adjustments (void) { case MODE_COMPLEX_INT: case MODE_COMPLEX_FLOAT: + case MODE_COMPLEX_VECTOR_INT: printf (" mode_base_align[E_%smode] = s;\n", m->name); break; diff --git a/gcc/machmode.def b/gcc/machmode.def index 62e2ba10d45..5bb5ae14fc3 100644 --- a/gcc/machmode.def +++ b/gcc/machmode.def @@ -267,6 +267,7 @@ UACCUM_MODE (UTA, 16, 64, 64); /* 64.64 */ COMPLEX_MODES (INT); COMPLEX_MODES (PARTIAL_INT); COMPLEX_MODES (FLOAT); +/* COMPLEX_MODES (VECTOR_INT); Let's enable these per architecture. */ /* Decimal floating point modes. */ DECIMAL_FLOAT_MODE (SD, 4, decimal_single_format); diff --git a/gcc/machmode.h b/gcc/machmode.h index f1865c1ef42..5f4e13f0643 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -26,7 +26,7 @@ extern CONST_MODE_SIZE poly_uint16_pod mode_size[NUM_MACHINE_MODES]; extern CONST_MODE_PRECISION poly_uint16_pod mode_precision[NUM_MACHINE_MODES]; extern const unsigned char mode_inner[NUM_MACHINE_MODES]; extern CONST_MODE_NUNITS poly_uint16_pod mode_nunits[NUM_MACHINE_MODES]; -extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES]; +extern CONST_MODE_UNIT_SIZE unsigned short mode_unit_size[NUM_MACHINE_MODES]; extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES]; extern const unsigned char mode_next[NUM_MACHINE_MODES]; extern const unsigned char mode_wider[NUM_MACHINE_MODES]; @@ -586,7 +586,7 @@ mode_to_inner (machine_mode mode) /* Return the base GET_MODE_UNIT_SIZE value for MODE. */ -ALWAYS_INLINE unsigned char +ALWAYS_INLINE unsigned short mode_to_unit_size (machine_mode mode) { #if GCC_VERSION >= 4001 diff --git a/gcc/mode-classes.def b/gcc/mode-classes.def index de42d7ee6fb..dc6097081b3 100644 --- a/gcc/mode-classes.def +++ b/gcc/mode-classes.def @@ -37,4 +37,5 @@ along with GCC; see the file COPYING3. If not see DEF_MODE_CLASS (MODE_VECTOR_ACCUM), /* SIMD vectors */ \ DEF_MODE_CLASS (MODE_VECTOR_UACCUM), /* SIMD vectors */ \ DEF_MODE_CLASS (MODE_VECTOR_FLOAT), \ + DEF_MODE_CLASS (MODE_COMPLEX_VECTOR_INT), \ DEF_MODE_CLASS (MODE_OPAQUE) /* opaque modes */ diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc index 023de8c37db..0699d44e516 100644 --- a/gcc/stor-layout.cc +++ b/gcc/stor-layout.cc @@ -391,6 +391,7 @@ int_mode_for_mode (machine_mode mode) case MODE_VECTOR_ACCUM: case MODE_VECTOR_UFRACT: case MODE_VECTOR_UACCUM: + case MODE_COMPLEX_VECTOR_INT: return int_mode_for_size (GET_MODE_BITSIZE (mode), 0); case MODE_OPAQUE: diff --git a/gcc/tree.cc b/gcc/tree.cc index ead4248b8e5..e1c87bbb0bb 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -7665,7 +7665,8 @@ build_complex_type (tree component_type, bool named) { gcc_assert (INTEGRAL_TYPE_P (component_type) || SCALAR_FLOAT_TYPE_P (component_type) - || FIXED_POINT_TYPE_P (component_type)); + || FIXED_POINT_TYPE_P (component_type) + || VECTOR_INTEGER_TYPE_P (component_type)); /* Make a node of the sort we want. */ tree probe = make_node (COMPLEX_TYPE);