From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14469 invoked by alias); 10 Dec 2013 03:35:17 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 14453 invoked by uid 89); 10 Dec 2013 03:35:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.8 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 10 Dec 2013 03:35:12 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rBA3Z0hW028893 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 9 Dec 2013 22:35:01 -0500 Received: from greed.delorie.com (ovpn-113-44.phx2.redhat.com [10.3.113.44]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id rBA3Yxje027029 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 9 Dec 2013 22:35:00 -0500 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1]) by greed.delorie.com (8.14.4/8.14.4) with ESMTP id rBA3Ywkf017442; Mon, 9 Dec 2013 22:34:58 -0500 Received: (from dj@localhost) by greed.delorie.com (8.14.4/8.14.4/Submit) id rBA3YwMq017441; Mon, 9 Dec 2013 22:34:58 -0500 Date: Tue, 10 Dec 2013 03:35:00 -0000 Message-Id: <201312100334.rBA3YwMq017441@greed.delorie.com> From: DJ Delorie To: "Joseph S. Myers" CC: richard.guenther@gmail.com, gcc@gcc.gnu.org In-reply-to: (joseph@codesourcery.com) Subject: Re: proposal to make SIZE_TYPE more flexible References: <201310300422.r9U4M6Mx002568@greed.delorie.com> <201310301917.r9UJHxg7028662@greed.delorie.com> <201310302219.r9UMJg9e001309@greed.delorie.com> <201311140158.rAE1wCkg006136@greed.delorie.com> <201311152338.rAFNc9CJ007961@greed.delorie.com> <201311212241.rALMf15B028014@greed.delorie.com> <201311220828.rAM8Ss0q011135@greed.delorie.com> <201311221933.rAMJXDUt031382@greed.delorie.com> <201311222118.rAMLIxag003002@greed.delorie.com> X-IsSubscribed: yes X-SW-Source: 2013-12/txt/msg00116.txt.bz2 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; + } } /* 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 % 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 % 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 % and % 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 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, "", MAX_MODE_CLASS, -1U, -1U, -1U, -1U, 0, 0, 0, 0, 0, - "", 0, 0, 0, 0 + "", 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);