public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: DJ Delorie <dj@redhat.com>
To: "Joseph S. Myers" <joseph@codesourcery.com>
Cc: richard.guenther@gmail.com, gcc@gcc.gnu.org
Subject: Re: proposal to make SIZE_TYPE more flexible
Date: Tue, 10 Dec 2013 03:35:00 -0000	[thread overview]
Message-ID: <201312100334.rBA3YwMq017441@greed.delorie.com> (raw)
In-Reply-To: <Pine.LNX.4.64.1311230039030.12354@digraph.polyomino.org.uk>	(joseph@codesourcery.com)


First pass at actual code.  I took the path of using a new macro in
TARGET-modes.def and having genmodes build the relevent tables.  Part
of the table is created by genmodes, the rest is created at runtime.

genmodes: bitsize, mode.

runtime: signed/unsigned type trees
  (eventually, flag for "target supports this, for this run")

I ended up making a range of RID_* codes as it seemed too difficult to
have one code map to more than one token.  I only added four, though,
and they're mapped to the table entries so each target can (at the
moment) define up to four __intN types.  insn-modes.h has a define
that says how many codes are actually used.

I also have not yet removed the int128 code, although my patch shows a
128-bit __intN definition being added the new way.  This patch is
mostly just to get an OK on my methods.



Index: machmode.h
===================================================================
--- machmode.h	(revision 205719)
+++ machmode.h	(working copy)
@@ -322,7 +322,16 @@ extern void init_adjust_machine_modes (v
 			 GET_MODE_PRECISION (MODE2))
 
 #define HWI_COMPUTABLE_MODE_P(MODE) \
   (SCALAR_INT_MODE_P (MODE) \
    && GET_MODE_PRECISION (MODE) <= HOST_BITS_PER_WIDE_INT)
 
+typedef struct {
+  /* These parts are initailized by genmodes output */
+  int bitsize;
+  enum machine_mode m;
+  /* RID_* is RID_INTN_BASE + index into this array */
+} int_n_data_t;
+
+extern const int_n_data_t int_n_data[NUM_INT_N_ENTS];
+
 #endif /* not HAVE_MACHINE_MODES */
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c	(revision 205719)
+++ c-family/c-common.c	(working copy)
@@ -5285,12 +5285,13 @@ c_common_nodes_and_builtins (void)
   int char16_type_size;
   int char32_type_size;
   int wchar_type_size;
   tree array_domain_type;
   tree va_list_ref_type_node;
   tree va_list_arg_type_node;
+  int i;
 
   build_common_tree_nodes (flag_signed_char, flag_short_double);
 
   /* Define `int' and `char' first so that dbx will output them first.  */
   record_builtin_type (RID_INT, NULL, integer_type_node);
   record_builtin_type (RID_CHAR, "char", char_type_node);
@@ -5308,12 +5309,24 @@ c_common_nodes_and_builtins (void)
     {
       record_builtin_type (RID_INT128, "__int128",
 			   int128_integer_type_node);
       record_builtin_type (RID_MAX, "__int128 unsigned",
 			   int128_unsigned_type_node);
     }
+
+  for (i = 0; i < NUM_INT_N_ENTS; i ++)
+    {
+      char name[25];
+      sprintf (name, "__int%d", int_n_data[i].bitsize);
+      record_builtin_type ((enum rid)(RID_FIRST_INT_N + i), name,
+			   int_n_trees[i].signed_type);
+      sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
+      record_builtin_type (RID_MAX, name,
+			   int_n_trees[i].unsigned_type);
+    }
+
   if (c_dialect_cxx ())
     record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node);
   record_builtin_type (RID_MAX, "long long int",
 		       long_long_integer_type_node);
   record_builtin_type (RID_MAX, "long long unsigned int",
 		       long_long_unsigned_type_node);
@@ -11576,12 +11589,15 @@ keyword_begins_type_specifier (enum rid 
     case RID_STRUCT:
     case RID_CLASS:
     case RID_UNION:
     case RID_ENUM:
       return true;
     default:
+      if (keyword >= RID_FIRST_INT_N
+	  && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS)
+	return true;
       return false;
     }
 }
 
 /* Return true if KEYWORD names a type qualifier.  */
 
Index: c-family/c-common.h
===================================================================
--- c-family/c-common.h	(revision 205719)
+++ c-family/c-common.h	(working copy)
@@ -185,12 +185,29 @@ enum rid
   RID_ADDR_SPACE_14,
   RID_ADDR_SPACE_15,
 
   RID_FIRST_ADDR_SPACE = RID_ADDR_SPACE_0,
   RID_LAST_ADDR_SPACE = RID_ADDR_SPACE_15,
 
+  /* __intN_t keywords.  The _N_M here doesn't correspond to the intN
+     in the keyword; use the bitsize in int_n_t_data_t[M] for that.
+     For example, if int_n_t_data_t[0].bitsize is 13, then RID_INT_N_0
+     is for __int13_t.  */
+
+  /* Note that the range to use is RID_FIRST_INT_N through
+     RID_FIRST_INT_N + NUM_INT_N_ENTS - 1 and c-parser.c has a list of
+     all RID_INT_N_* in a case statement.  */
+
+  RID_INT_N_0,
+  RID_INT_N_1,
+  RID_INT_N_2,
+  RID_INT_N_3,
+
+  RID_FIRST_INT_N = RID_INT_N_0,
+  RID_LAST_INT_N = RID_INT_N_3,
+
   RID_MAX,
 
   RID_FIRST_MODIFIER = RID_STATIC,
   RID_LAST_MODIFIER = RID_ONEWAY,
 
   RID_FIRST_CXX0X = RID_CONSTEXPR,
Index: c/c-parser.c
===================================================================
--- c/c-parser.c	(revision 205719)
+++ c/c-parser.c	(working copy)
@@ -109,12 +109,21 @@ c_parse_init (void)
 
       id = get_identifier (c_common_reswords[i].word);
       C_SET_RID_CODE (id, c_common_reswords[i].rid);
       C_IS_RESERVED_WORD (id) = 1;
       ridpointers [(int) c_common_reswords[i].rid] = id;
     }
+
+  for (i = 0; i < NUM_INT_N_ENTS; i++)
+    {
+      char name[50];
+      sprintf (name, "__int%d", int_n_data[i].bitsize);
+      id = get_identifier (name);
+      C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
+      C_IS_RESERVED_WORD (id) = 1;
+    }
 }
 \f
 /* The C lexer intermediates between the lexer in cpplib and c-lex.c
    and the C parser.  Unlike the C++ lexer, the parser structure
    stores the lexer information instead of using a separate structure.
    Identifiers are separated into ordinary identifiers, type names,
@@ -506,12 +515,15 @@ c_token_starts_typename (c_token *token)
 	case RID_FRACT:
 	case RID_ACCUM:
 	case RID_SAT:
 	case RID_AUTO_TYPE:
 	  return true;
 	default:
+	  if (token->keyword >= RID_FIRST_INT_N
+	      && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS)
+	    return true;
 	  return false;
 	}
     case CPP_LESS:
       if (c_dialect_objc ())
 	return true;
       return false;
@@ -665,12 +677,15 @@ c_token_starts_declspecs (c_token *token
 	case RID_SAT:
 	case RID_ALIGNAS:
 	case RID_ATOMIC:
 	case RID_AUTO_TYPE:
 	  return true;
 	default:
+	  if (token->keyword >= RID_FIRST_INT_N
+	      && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS)
+	    return true;
 	  return false;
 	}
     case CPP_LESS:
       if (c_dialect_objc ())
 	return true;
       return false;
@@ -2294,12 +2309,16 @@ c_parser_declspecs (c_parser *parser, st
 	case RID_DFLOAT64:
 	case RID_DFLOAT128:
 	case RID_BOOL:
 	case RID_FRACT:
 	case RID_ACCUM:
 	case RID_SAT:
+	case RID_INT_N_0:
+	case RID_INT_N_1:
+	case RID_INT_N_2:
+	case RID_INT_N_3:
 	  if (!typespec_ok)
 	    goto out;
 	  attrs_ok = true;
 	  seen_type = true;
 	  if (c_dialect_objc ())
 	    parser->objc_need_raw_identifier = true;
@@ -3744,12 +3763,16 @@ c_parser_attribute_any_word (c_parser *p
 	case RID_ACCUM:
 	case RID_SAT:
 	case RID_TRANSACTION_ATOMIC:
 	case RID_TRANSACTION_CANCEL:
 	case RID_ATOMIC:
 	case RID_AUTO_TYPE:
+	case RID_INT_N_0:
+	case RID_INT_N_1:
+	case RID_INT_N_2:
+	case RID_INT_N_3:
 	  ok = true;
 	  break;
 	default:
 	  ok = false;
 	  break;
 	}
@@ -8807,12 +8830,16 @@ c_parser_objc_selector (c_parser *parser
     case RID_FLOAT:
     case RID_DOUBLE:
     case RID_VOID:
     case RID_BOOL:
     case RID_ATOMIC:
     case RID_AUTO_TYPE:
+    case RID_INT_N_0:
+    case RID_INT_N_1:
+    case RID_INT_N_2:
+    case RID_INT_N_3:
       c_parser_consume_token (parser);
       return value;
     default:
       return NULL_TREE;
     }
 }
Index: c/c-tree.h
===================================================================
--- c/c-tree.h	(revision 205719)
+++ c/c-tree.h	(working copy)
@@ -206,12 +206,13 @@ enum c_typespec_keyword {
   cts_void,
   cts_bool,
   cts_char,
   cts_int,
   cts_float,
   cts_int128,
+  cts_int_n,
   cts_double,
   cts_dfloat32,
   cts_dfloat64,
   cts_dfloat128,
   cts_fract,
   cts_accum,
@@ -272,12 +273,14 @@ struct c_declspecs {
      separately.  */
   tree attrs;
   /* The base-2 log of the greatest alignment required by an _Alignas
      specifier, in bytes, or -1 if no such specifiers with nonzero
      alignment.  */
   int align_log;
+  /* For the __intN declspec, this stores the index into the int_n_* arrays.  */
+  int int_n_idx;
   /* The storage class specifier, or csc_none if none.  */
   enum c_storage_class storage_class;
   /* Any type specifier keyword used such as "int", not reflecting
      modifiers such as "short", or cts_none if none.  */
   ENUM_BITFIELD (c_typespec_keyword) typespec_word : 8;
   /* The kind of type specifier if one has been seen, ctsk_none
Index: c/c-decl.c
===================================================================
--- c/c-decl.c	(revision 205719)
+++ c/c-decl.c	(working copy)
@@ -9508,12 +9508,39 @@ declspecs_add_type (location_t loc, stru
 	      else
 		{
 		  specs->typespec_word = cts_int128;
 		  specs->locations[cdw_typespec] = loc;
 		}
 	      return specs;
+	    case RID_INT_N_0:
+	    case RID_INT_N_1:
+	    case RID_INT_N_2:
+	    case RID_INT_N_3:
+	      if (!in_system_header_at (input_location))
+		pedwarn (loc, OPT_Wpedantic,
+			 "ISO C does not support %<__intN%> types");
+
+	      if (specs->long_p)
+		error_at (loc,
+			  ("both %<__intN%> and %<long%> in "
+			   "declaration specifiers"));
+	      else if (specs->saturating_p)
+		error_at (loc,
+			  ("both %<_Sat%> and %<__intN%> in "
+			   "declaration specifiers"));
+	      else if (specs->short_p)
+		error_at (loc,
+			  ("both %<__intN%> and %<short%> in "
+			   "declaration specifiers"));
+	      else
+		{
+		  specs->typespec_word = cts_int_n;
+		  specs->int_n_idx = i - RID_INT_N_0;
+		  specs->locations[cdw_typespec] = loc;
+		}
+	      return specs;
 	    case RID_VOID:
 	      if (specs->long_p)
 		error_at (loc,
 			  ("both %<long%> and %<void%> in "
 			   "declaration specifiers"));
 	      else if (specs->short_p)
@@ -10082,12 +10109,25 @@ finish_declspecs (struct c_declspecs *sp
 	{
 	  pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
 		   "ISO C does not support complex integer types");
 	  specs->type = build_complex_type (specs->type);
 	}
       break;
+    case cts_int_n:
+      gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
+      gcc_assert (!(specs->signed_p && specs->unsigned_p));
+      specs->type = (specs->unsigned_p
+		     ? int_n_trees[specs->int_n_idx].unsigned_type
+		     : int_n_trees[specs->int_n_idx].signed_type);
+      if (specs->complex_p)
+	{
+	  pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
+		   "ISO C does not support complex integer types");
+	  specs->type = build_complex_type (specs->type);
+	}
+      break;
     case cts_int:
       gcc_assert (!(specs->long_p && specs->short_p));
       gcc_assert (!(specs->signed_p && specs->unsigned_p));
       if (specs->long_long_p)
 	specs->type = (specs->unsigned_p
 		       ? long_long_unsigned_type_node
Index: tree.c
===================================================================
--- tree.c	(revision 205719)
+++ tree.c	(working copy)
@@ -236,12 +236,14 @@ static unsigned int type_hash_list (cons
 static unsigned int attribute_hash_list (const_tree, hashval_t);
 static bool decls_same_for_odr (tree decl1, tree decl2);
 
 tree global_trees[TI_MAX];
 tree integer_types[itk_none];
 
+int_n_trees_t int_n_trees[NUM_INT_N_ENTS];
+
 unsigned char tree_contains_struct[MAX_TREE_CODES][64];
 
 /* Number of operands for each OpenMP clause.  */
 unsigned const char omp_clause_num_ops[] =
 {
   0, /* OMP_CLAUSE_ERROR  */
@@ -9447,12 +9449,14 @@ make_vector_type (tree innertype, int nu
   return t;
 }
 
 static tree
 make_or_reuse_type (unsigned size, int unsignedp)
 {
+  int i;
+
   if (size == INT_TYPE_SIZE)
     return unsignedp ? unsigned_type_node : integer_type_node;
   if (size == CHAR_TYPE_SIZE)
     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
   if (size == SHORT_TYPE_SIZE)
     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
@@ -9462,12 +9466,17 @@ make_or_reuse_type (unsigned size, int u
     return (unsignedp ? long_long_unsigned_type_node
             : long_long_integer_type_node);
   if (size == 128 && int128_integer_type_node)
     return (unsignedp ? int128_unsigned_type_node
             : int128_integer_type_node);
 
+  for (i = 0; i < NUM_INT_N_ENTS; i ++)
+    if (size == int_n_data[i].bitsize)
+      return (unsignedp ? int_n_trees[i].unsigned_type
+	      : int_n_trees[i].signed_type);
+
   if (unsignedp)
     return make_unsigned_type (size);
   else
     return make_signed_type (size);
 }
 
@@ -9576,12 +9585,14 @@ build_atomic_base (tree type, unsigned i
    SHORT_DOUBLE specifies whether double should be of the same precision
    as float.  */
 
 void
 build_common_tree_nodes (bool signed_char, bool short_double)
 {
+  int i;
+
   error_mark_node = make_node (ERROR_MARK);
   TREE_TYPE (error_mark_node) = error_mark_node;
 
   initialize_sizetypes ();
 
   /* Define both `signed char' and `unsigned char'.  */
@@ -9615,12 +9626,20 @@ build_common_tree_nodes (bool signed_cha
       {
         int128_integer_type_node = make_signed_type (128);
         int128_unsigned_type_node = make_unsigned_type (128);
       }
 #endif
 
+    for (i = 0; i < NUM_INT_N_ENTS; i ++)
+      {
+	int_n_trees[i].signed_type = make_signed_type (int_n_data[i].bitsize);
+	int_n_trees[i].unsigned_type = make_unsigned_type (int_n_data[i].bitsize);
+	TYPE_SIZE (int_n_trees[i].signed_type) = bitsize_int (int_n_data[i].bitsize);
+	TYPE_SIZE (int_n_trees[i].unsigned_type) = bitsize_int (int_n_data[i].bitsize);
+      }
+
   /* Define a boolean type.  This type only represents boolean values but
      may be larger than char depending on the value of BOOL_TYPE_SIZE.
      Front ends which want to override this size (i.e. Java) can redefine
      boolean_type_node before calling build_common_tree_nodes_2.  */
   boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
   TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
Index: tree.h
===================================================================
--- tree.h	(revision 205719)
+++ tree.h	(working copy)
@@ -4552,7 +4552,16 @@ extern unsigned int get_pointer_alignmen
 extern tree fold_call_stmt (gimple, bool);
 extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
 extern void set_builtin_user_assembler_name (tree decl, const char *asmspec);
 extern bool is_simple_builtin (tree);
 extern bool is_inexpensive_builtin (tree);
 
+
+typedef struct {
+  /* These parts are initialized at runtime */
+  tree signed_type;
+  tree unsigned_type;
+} int_n_trees_t;
+
+extern int_n_trees_t int_n_trees[NUM_INT_N_ENTS];
+
 #endif  /* GCC_TREE_H  */
Index: stor-layout.c
===================================================================
--- stor-layout.c	(revision 205719)
+++ stor-layout.c	(working copy)
@@ -310,22 +310,28 @@ finalize_size_functions (void)
    than MAX_FIXED_MODE_SIZE will not be used.  */
 
 enum machine_mode
 mode_for_size (unsigned int size, enum mode_class mclass, int limit)
 {
   enum machine_mode mode;
+  int i;
 
   if (limit && size > MAX_FIXED_MODE_SIZE)
     return BLKmode;
 
   /* Get the first mode which has this size, in the specified class.  */
   for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
     if (GET_MODE_PRECISION (mode) == size)
       return mode;
 
+  if (mclass == MODE_INT && mode == BLKmode)
+    for (i = 0; i < NUM_INT_N_ENTS; i ++)
+      if (int_n_data[i].bitsize == size)
+	return int_n_data[i].m;
+
   return BLKmode;
 }
 
 /* Similar, except passed a tree node.  */
 
 enum machine_mode
@@ -346,22 +352,32 @@ mode_for_size_tree (const_tree size, enu
 /* Similar, but never return BLKmode; return the narrowest mode that
    contains at least the requested number of value bits.  */
 
 enum machine_mode
 smallest_mode_for_size (unsigned int size, enum mode_class mclass)
 {
-  enum machine_mode mode;
+  enum machine_mode mode = VOIDmode;
+  int i;
 
   /* Get the first mode which has at least this size, in the
      specified class.  */
   for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
     if (GET_MODE_PRECISION (mode) >= size)
-      return mode;
+      break;
 
-  gcc_unreachable ();
+  if (mclass == MODE_INT)
+    for (i = 0; i < NUM_INT_N_ENTS; i ++)
+      if (int_n_data[i].bitsize >= size
+	  && int_n_data[i].bitsize < GET_MODE_PRECISION (mode))
+	mode = int_n_data[i].m;
+
+  if (mode == VOIDmode)
+    gcc_unreachable ();
+
+  return mode;
 }
 
 /* Find an integer mode of the exact same size, or BLKmode on failure.  */
 
 enum machine_mode
 int_mode_for_mode (enum machine_mode mode)
Index: genmodes.c
===================================================================
--- genmodes.c	(revision 205719)
+++ genmodes.c	(working copy)
@@ -69,23 +69,25 @@ struct mode_data
 
   const char *file;		/* file and line of definition, */
   unsigned int line;		/* for error reporting */
   unsigned int counter;		/* Rank ordering of modes */
   unsigned int ibit;		/* the number of integral bits */
   unsigned int fbit;		/* the number of fractional bits */
+
+  unsigned int int_n;		/* If nonzero, then __int<INT_N> will be defined */
 };
 
 static struct mode_data *modes[MAX_MODE_CLASS];
 static unsigned int n_modes[MAX_MODE_CLASS];
 static struct mode_data *void_mode;
 
 static const struct mode_data blank_mode = {
   0, "<unknown>", MAX_MODE_CLASS,
   -1U, -1U, -1U, -1U,
   0, 0, 0, 0, 0,
-  "<unknown>", 0, 0, 0, 0
+  "<unknown>", 0, 0, 0, 0, 0
 };
 
 static htab_t modes_by_name;
 
 /* Data structure for recording target-specified runtime adjustments
    to a particular mode.  We support varying the byte size, the
@@ -627,12 +629,40 @@ reset_float_format (const char *name, co
       error ("%s:%d: mode \"%s\" is not a FLOAT class", file, line, name);
       return;
     }
   m->format = format;
 }
 
+/* __intN support.  */
+#define INT_N(PREC,M) \
+  make_int_n (PREC, #M, __FILE__, __LINE__)
+static void ATTRIBUTE_UNUSED
+make_int_n (int bitsize, const char *m,
+            const char *file, unsigned int line)
+{
+  struct mode_data *component = find_mode (m);
+  if (!component)
+    {
+      error ("%s:%d: no mode \"%s\"", file, line, m);
+      return;
+    }
+  if (component->cl != MODE_INT
+      && component->cl != MODE_PARTIAL_INT)
+    {
+      error ("%s:%d: mode \"%s\" is not class INT or PARTIAL_INT", file, line, m);
+      return;
+    }
+  if (component->int_n != 0)
+    {
+      error ("%s:%d: mode \"%s\" already has an intN", file, line, m);
+      return;
+    }
+
+  component->int_n = bitsize;
+}
+
 /* Partial integer modes are specified by relation to a full integer
    mode.  */
 #define PARTIAL_INT_MODE(M,PREC,NAME)				\
   make_partial_integer_mode (#M, #NAME, PREC, __FILE__, __LINE__)
 static void ATTRIBUTE_UNUSED
 make_partial_integer_mode (const char *base, const char *name,
@@ -881,12 +911,13 @@ emit_max_int (void)
 
 static void
 emit_insn_modes_h (void)
 {
   int c;
   struct mode_data *m, *first, *last;
+  int n_int_n_ents = 0;
 
   printf ("/* Generated automatically from machmode.def%s%s\n",
 	   HAVE_EXTRA_MODES ? " and " : "",
 	   EXTRA_MODES_FILE);
 
   puts ("\
@@ -941,12 +972,19 @@ enum machine_mode\n{");
 #if 0 /* disabled for backward compatibility, temporary */
   printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
 #endif
   printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const");
   printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const");
   emit_max_int ();
+
+  for_all_modes (c, m)
+    if (m->int_n)
+      n_int_n_ents ++;
+
+  printf ("#define NUM_INT_N_ENTS %d\n", n_int_n_ents);
+
   puts ("\
 \n\
 #endif /* insn-modes.h */");
 }
 
 static void
@@ -1384,12 +1422,34 @@ emit_mode_fbit (void)
   for_all_modes (c, m)
     tagged_printf ("%u", m->fbit, m->name);
 
   print_closer ();
 }
 
+/* Emit __intN for all modes.  */
+
+static void
+emit_mode_int_n (void)
+{
+  int c;
+  struct mode_data *m;
+
+  print_decl ("int_n_data_t", "int_n_data", "");
+
+  for_all_modes (c, m)
+    if (m->int_n)
+      {
+	printf(" {\n");
+	tagged_printf ("%u", m->int_n, m->name);
+	printf ("%smode,", m->name);
+	printf(" },\n");
+      }
+
+  print_closer ();
+}
+
 
 static void
 emit_insn_modes_c (void)
 {
   emit_insn_modes_c_header ();
   emit_mode_name ();
@@ -1403,12 +1463,13 @@ emit_insn_modes_c (void)
   emit_mode_base_align ();
   emit_class_narrowest_mode ();
   emit_real_format_for_mode ();
   emit_mode_adjustments ();
   emit_mode_ibit ();
   emit_mode_fbit ();
+  emit_mode_int_n ();
 }
 
 static void
 emit_min_insn_modes_c (void)
 {
   emit_min_insn_modes_c_header ();
Index: gimple.c
===================================================================
--- gimple.c	(revision 205719)
+++ gimple.c	(working copy)
@@ -2091,12 +2091,13 @@ gimple_compare_field_offset (tree f1, tr
    signed according to UNSIGNEDP.  */
 
 static tree
 gimple_signed_or_unsigned_type (bool unsignedp, tree type)
 {
   tree type1;
+  int i;
 
   type1 = TYPE_MAIN_VARIANT (type);
   if (type1 == signed_char_type_node
       || type1 == char_type_node
       || type1 == unsigned_char_type_node)
     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
@@ -2112,12 +2113,20 @@ gimple_signed_or_unsigned_type (bool uns
            ? long_long_unsigned_type_node
 	   : long_long_integer_type_node;
   if (int128_integer_type_node && (type1 == int128_integer_type_node || type1 == int128_unsigned_type_node))
     return unsignedp
            ? int128_unsigned_type_node
 	   : int128_integer_type_node;
+
+  for (i = 0; i < NUM_INT_N_ENTS; i ++)
+      if (type1 == int_n_trees[i].unsigned_type
+	  || type1 == int_n_trees[i].signed_type)
+	return unsignedp
+	  ? int_n_trees[i].unsigned_type
+	  : int_n_trees[i].signed_type;
+
 #if HOST_BITS_PER_WIDE_INT >= 64
   if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node)
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
 #endif
   if (type1 == intDI_type_node || type1 == unsigned_intDI_type_node)
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
@@ -2229,12 +2238,18 @@ gimple_signed_or_unsigned_type (bool uns
 	    : long_long_integer_type_node);
   if (int128_integer_type_node && TYPE_OK (int128_integer_type_node))
     return (unsignedp
 	    ? int128_unsigned_type_node
 	    : int128_integer_type_node);
 
+  for (i = 0; i < NUM_INT_N_ENTS; i ++)
+    if (TYPE_MODE (type) == int_n_data[i].m && TYPE_PRECISION (type) == int_n_data[i].bitsize)
+	return unsignedp
+	  ? int_n_trees[i].unsigned_type
+	  : int_n_trees[i].signed_type;
+
 #if HOST_BITS_PER_WIDE_INT >= 64
   if (TYPE_OK (intTI_type_node))
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
 #endif
   if (TYPE_OK (intDI_type_node))
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
Index: config/msp430/msp430-modes.def
===================================================================
--- config/msp430/msp430-modes.def	(revision 205719)
+++ config/msp430/msp430-modes.def	(working copy)
@@ -1,3 +1,5 @@
 /* 20-bit address */
 PARTIAL_INT_MODE (SI, 20, PSI);
 
+INT_N (20, PSI);
+INT_N (64, TI);

  reply	other threads:[~2013-12-10  3:35 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-30  4:28 DJ Delorie
2013-10-30 15:53 ` Joseph S. Myers
2013-10-30 19:18   ` DJ Delorie
2013-10-30 20:49     ` Joseph S. Myers
2013-10-30 22:19       ` DJ Delorie
2013-10-30 22:51         ` Joseph S. Myers
2013-11-14  1:58           ` DJ Delorie
2013-11-14 13:26             ` Joseph S. Myers
2013-11-14 18:12               ` DJ Delorie
2013-11-14 18:37                 ` Joseph S. Myers
2013-11-14 18:48                   ` DJ Delorie
2013-11-14 21:40                     ` Joseph S. Myers
2013-11-15  1:47                       ` DJ Delorie
2013-11-15  1:56                         ` Joseph S. Myers
2013-11-15 23:38               ` DJ Delorie
2013-11-16 11:23                 ` Richard Biener
2013-11-16 12:26                   ` Joseph S. Myers
2013-11-21 22:41                     ` DJ Delorie
2013-11-21 22:59                       ` Joseph S. Myers
2013-11-22  8:29                         ` DJ Delorie
2013-11-22 12:43                           ` Joseph S. Myers
2013-11-22 19:33                             ` DJ Delorie
2013-11-22 21:00                               ` Joseph S. Myers
2013-11-22 21:19                                 ` DJ Delorie
2013-11-23  0:41                                   ` Joseph S. Myers
2013-12-10  3:35                                     ` DJ Delorie [this message]
2013-12-10 17:17                                       ` Joseph S. Myers
2013-12-10 18:10                                         ` DJ Delorie
2013-12-10 18:38                                           ` Joseph S. Myers
2013-12-10 18:42                                             ` DJ Delorie
2013-12-11  9:27                                               ` Richard Biener
2013-12-20  4:58                                         ` DJ Delorie
2013-12-20 12:42                                           ` Joseph S. Myers
2013-12-20 19:47                                         ` DJ Delorie
2013-12-20 21:53                                           ` Joseph S. Myers
2013-12-20 21:59                                             ` DJ Delorie
2013-12-20 22:15                                               ` Joseph S. Myers
2013-12-20 22:40                                                 ` DJ Delorie
2013-12-21  1:01                                                   ` Joseph S. Myers
2014-01-09  2:31                                                     ` DJ Delorie
2014-01-09  3:23                                                       ` Joseph S. Myers
2014-01-09  7:02                                                         ` DJ Delorie
2014-01-09 16:22                                                           ` Joseph S. Myers
2014-01-15 12:48                                                             ` DJ Delorie
2014-01-28 21:52                                                               ` DJ Delorie
2014-01-28 21:58                                                                 ` Joseph S. Myers
2014-01-28 22:24                                                                   ` DJ Delorie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201312100334.rBA3YwMq017441@greed.delorie.com \
    --to=dj@redhat.com \
    --cc=gcc@gcc.gnu.org \
    --cc=joseph@codesourcery.com \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).