diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e293ad04a95..e919420a8af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2013-10-24 Ilya Enkovich + + * mode-classes.def (MODE_POINTER_BOUNDS): New. + * tree.def (POINTER_BOUNDS_TYPE): New. + * genmodes.c (complete_mode): Support MODE_POINTER_BOUNDS. + (POINTER_BOUNDS_MODE): New. + (make_pointer_bounds_mode): New. + * machmode.h (POINTER_BOUNDS_MODE_P): New. + * stor-layout.c (int_mode_for_mode): Support MODE_POINTER_BOUNDS. + (layout_type): Support POINTER_BOUNDS_TYPE. + * tree-pretty-print.c (dump_generic_node): Support POINTER_BOUNDS_TYPE. + * tree.c (build_int_cst_wide): Support POINTER_BOUNDS_TYPE. + (type_contains_placeholder_1): Likewise. + * tree.h (POINTER_BOUNDS_TYPE_P): New. + * varasm.c (output_constant): Support POINTER_BOUNDS_TYPE. + * doc/rtl.texi (MODE_POINTER_BOUNDS): New. + 2013-10-24 Igor Shevlyakov * expr.c (expand_expr_real_1): Use mode of memory reference rather diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 84c0444ad9c..77a9c703216 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -1382,6 +1382,12 @@ any @code{CC_MODE} modes listed in the @file{@var{machine}-modes.def}. @xref{Jump Patterns}, also see @ref{Condition Code}. +@findex MODE_POINTER_BOUNDS +@item MODE_POINTER_BOUNDS +Pointer bounds modes. Used to represent values of pointer bounds type. +Operations in these modes may be executed as NOPs depending on hardware +features and environment setup. + @findex MODE_RANDOM @item MODE_RANDOM This is a catchall mode class for modes which don't fit into the above diff --git a/gcc/genmodes.c b/gcc/genmodes.c index a0b2f21f11b..0aa5de618b0 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -333,6 +333,7 @@ complete_mode (struct mode_data *m) break; case MODE_INT: + case MODE_POINTER_BOUNDS: case MODE_FLOAT: case MODE_DECIMAL_FLOAT: case MODE_FRACT: @@ -534,6 +535,19 @@ make_special_mode (enum mode_class cl, const char *name, new_mode (cl, name, file, line); } +#define POINTER_BOUNDS_MODE(N, Y) \ + make_pointer_bounds_mode (#N, Y, __FILE__, __LINE__) + +static void ATTRIBUTE_UNUSED +make_pointer_bounds_mode (const char *name, + unsigned int bytesize, + const char *file, unsigned int line) +{ + struct mode_data *m = new_mode (MODE_POINTER_BOUNDS, name, file, line); + m->bytesize = bytesize; +} + + #define INT_MODE(N, Y) FRACTIONAL_INT_MODE (N, -1U, Y) #define FRACTIONAL_INT_MODE(N, B, Y) \ make_int_mode (#N, B, Y, __FILE__, __LINE__) diff --git a/gcc/machmode.h b/gcc/machmode.h index da0923a81a2..71c72525b4a 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -174,6 +174,9 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES]; || CLASS == MODE_ACCUM \ || CLASS == MODE_UACCUM) +#define POINTER_BOUNDS_MODE_P(MODE) \ + (GET_MODE_CLASS (MODE) == MODE_POINTER_BOUNDS) + /* Get the size in bytes and bits of an object of mode MODE. */ extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES]; diff --git a/gcc/mode-classes.def b/gcc/mode-classes.def index 7207ef7712b..a94fd614603 100644 --- a/gcc/mode-classes.def +++ b/gcc/mode-classes.def @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see DEF_MODE_CLASS (MODE_CC), /* condition code in a register */ \ DEF_MODE_CLASS (MODE_INT), /* integer */ \ DEF_MODE_CLASS (MODE_PARTIAL_INT), /* integer with padding bits */ \ + DEF_MODE_CLASS (MODE_POINTER_BOUNDS), /* bounds */ \ DEF_MODE_CLASS (MODE_FRACT), /* signed fractional number */ \ DEF_MODE_CLASS (MODE_UFRACT), /* unsigned fractional number */ \ DEF_MODE_CLASS (MODE_ACCUM), /* signed accumulator */ \ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 4619d6e427b..f390eea7910 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -383,6 +383,7 @@ int_mode_for_mode (enum machine_mode mode) case MODE_VECTOR_ACCUM: case MODE_VECTOR_UFRACT: case MODE_VECTOR_UACCUM: + case MODE_POINTER_BOUNDS: mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0); break; @@ -2122,6 +2123,14 @@ layout_type (tree type) SET_TYPE_MODE (type, VOIDmode); break; + case POINTER_BOUNDS_TYPE: + SET_TYPE_MODE (type, + mode_for_size (TYPE_PRECISION (type), + MODE_POINTER_BOUNDS, 0)); + TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type))); + TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); + break; + case OFFSET_TYPE: TYPE_SIZE (type) = bitsize_int (POINTER_SIZE); TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT); diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 150333b208f..b2c5411f68c 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -866,6 +866,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, break; case VOID_TYPE: + case POINTER_BOUNDS_TYPE: case INTEGER_TYPE: case REAL_TYPE: case FIXED_POINT_TYPE: diff --git a/gcc/tree.c b/gcc/tree.c index 4560b724ad1..0a42109065c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1221,7 +1221,8 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi) case POINTER_TYPE: case REFERENCE_TYPE: - /* Cache NULL pointer. */ + case POINTER_BOUNDS_TYPE: + /* Cache NULL pointer and zero bounds. */ if (!hi && !low) { limit = 1; @@ -3273,6 +3274,7 @@ type_contains_placeholder_1 (const_tree type) switch (TREE_CODE (type)) { case VOID_TYPE: + case POINTER_BOUNDS_TYPE: case COMPLEX_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: diff --git a/gcc/tree.def b/gcc/tree.def index 9bd1b3d21c2..1a2c2663502 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -232,6 +232,11 @@ DEFTREECODE (QUAL_UNION_TYPE, "qual_union_type", tcc_type, 0) /* The void type in C */ DEFTREECODE (VOID_TYPE, "void_type", tcc_type, 0) +/* Type to hold bounds for a pointer. + Has TYPE_PRECISION component to specify number of bits used + by this type. */ +DEFTREECODE (POINTER_BOUNDS_TYPE, "pointer_bounds_type", tcc_type, 0) + /* Type of functions. Special fields: TREE_TYPE type of value returned. TYPE_ARG_TYPES list of types of arguments expected. diff --git a/gcc/tree.h b/gcc/tree.h index 7732d6926d0..bba117da819 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -542,6 +542,10 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, /* Nonzero if this type is a complete type. */ #define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE) +/* Nonzero if this type is a pointer bounds type. */ +#define POINTER_BOUNDS_TYPE_P(NODE) \ + (TREE_CODE (NODE) == POINTER_BOUNDS_TYPE) + /* Nonzero if this type is the (possibly qualified) void type. */ #define VOID_TYPE_P(NODE) (TREE_CODE (NODE) == VOID_TYPE) diff --git a/gcc/varasm.c b/gcc/varasm.c index acf8af083d4..52ba182b00d 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -4704,6 +4704,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align) case REFERENCE_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE: + case POINTER_BOUNDS_TYPE: if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER), MIN (size, thissize), align, 0))