Message ID | 20161209230311.36024-3-luc.vanoostenryck@gmail.com (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
On Sat, Dec 10, 2016 at 7:03 AM, Luc Van Oostenryck <luc.vanoostenryck@gmail.com> wrote: > There is already support for __int128_t & __uint128_t but not yet > for GCC's __int128. > > This patch add support for it and a couple of test cases. > > Note: it's slightly more tricky that it look because contrary to > '__int128_t', '__int128' is not an exact type (it can still receive > the 'unsigned' or 'signed' specifier). > > @@ -1496,6 +1504,8 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta > } > seen |= s->op->set; > class += s->op->class; > + if (s->op->set & Set_Int128) > + size = 2; > if (s->op->type & KW_SHORT) { > size = -1; > } else if (s->op->type & KW_LONG && size++) { This patch is already applied in sparse-next. But I have a question regarding the "size = 2;" Is the number 2 a magic number? Chris -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Feb 7, 2017 at 10:49 AM, Luc Van Oostenryck <luc.vanoostenryck@gmail.com> wrote: >>> @@ -1496,6 +1504,8 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta >>> } >>> seen |= s->op->set; >>> class += s->op->class; >>> + if (s->op->set & Set_Int128) >>> + size = 2; >>> if (s->op->type & KW_SHORT) { >>> size = -1; >>> } else if (s->op->type & KW_LONG && size++) { >> >> This patch is already applied in sparse-next. >> But I have a question regarding the "size = 2;" Is the number 2 a magic >> number? > > Not really magic but certainly not obvious: > * 'size' acts here as a sort of modifiers for interger > * plain integer, 'int' thus, are set to 'size = 0' > * then if 'short' is encountered, it's set to 'size = -1' > * each 'long' increment size by 1 > * so int = 0, long = 1, long long = 2 & long long long = 3 > * here __int128 is in fact 'long long long' so should ends to 3 > but the code contained a 'size++' which explain the 'size = 2' > I had to had to support this type. > > To be honest I don't like much what is done with this 'size' but > it works and I always try to make the smallest change in the > pre-existing code. > Adding the sparse mailing list. Thanks for the explain regarding the size. So the size is actually the how many extra int in terms of size. In that case, maybe we can add define/enum SIZE_128_BIT as 2, SIZE_SHORT as -1 etc together with your comment. Chris -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Feb 07, 2017 at 11:05:19AM +0800, Christopher Li wrote: > On Tue, Feb 7, 2017 at 10:49 AM, Luc Van Oostenryck > <luc.vanoostenryck@gmail.com> wrote: > >>> @@ -1496,6 +1504,8 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta > >>> } > >>> seen |= s->op->set; > >>> class += s->op->class; > >>> + if (s->op->set & Set_Int128) > >>> + size = 2; > >>> if (s->op->type & KW_SHORT) { > >>> size = -1; > >>> } else if (s->op->type & KW_LONG && size++) { > >> > >> This patch is already applied in sparse-next. > >> But I have a question regarding the "size = 2;" Is the number 2 a magic > >> number? > > > > Not really magic but certainly not obvious: > > * 'size' acts here as a sort of modifiers for interger > > * plain integer, 'int' thus, are set to 'size = 0' > > * then if 'short' is encountered, it's set to 'size = -1' > > * each 'long' increment size by 1 > > * so int = 0, long = 1, long long = 2 & long long long = 3 > > * here __int128 is in fact 'long long long' so should ends to 3 > > but the code contained a 'size++' which explain the 'size = 2' > > I had to had to support this type. > > > > To be honest I don't like much what is done with this 'size' but > > it works and I always try to make the smallest change in the > > pre-existing code. > > > > Adding the sparse mailing list. > > Thanks for the explain regarding the size. So the size is actually the > how many extra int in terms of size. > > In that case, maybe we can add define/enum SIZE_128_BIT as 2, > SIZE_SHORT as -1 etc together with your comment. I think it would be misleading because: * here 'size' is not directly related to the size of the integer (in the sizeof() sense) but is very close to the notion of 'rank' as used in the C standard * __int128 is essentially 'long long long int' and as such we should set SIZE_128_BIT as 3 and not as 2 but here we have to *initialize* it to the preceding rank, 2, as the next run of the loop will increment it to the right value, 3. I tried to do it in a more clear/direct way but as I had then to duplicate some code I choose to do it with the existing code & logic. If you wish, I'll look if I can make things a bit clearer or maybe just adding an appropriate comment. Luc -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/parse.c b/parse.c index 808a078a..fa46758a 100644 --- a/parse.c +++ b/parse.c @@ -101,6 +101,7 @@ enum { Set_Short = 256, Set_Long = 512, Set_Vlong = 1024, + Set_Int128 = 2048, Set_Any = Set_T | Set_Short | Set_Long | Set_Signed | Set_Unsigned }; @@ -253,6 +254,12 @@ static struct symbol_op long_op = { .set = Set_Long, }; +static struct symbol_op int128_op = { + .type = KW_SPECIFIER | KW_LONG, + .test = Set_S|Set_T|Set_Char|Set_Short|Set_Int|Set_Float|Set_Double|Set_Long|Set_Vlong|Set_Int128, + .set = Set_T|Set_Int128, +}; + static struct symbol_op if_op = { .statement = parse_if_statement, }; @@ -408,6 +415,7 @@ static struct init_keyword { { "__signed", NS_TYPEDEF, .op = &signed_op }, { "__signed__", NS_TYPEDEF, .op = &signed_op }, { "unsigned", NS_TYPEDEF, .op = &unsigned_op }, + { "__int128", NS_TYPEDEF, .op = &int128_op }, { "_Bool", NS_TYPEDEF, .type = &bool_ctype, .op = &spec_op }, /* Predeclared types */ @@ -1496,6 +1504,8 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta } seen |= s->op->set; class += s->op->class; + if (s->op->set & Set_Int128) + size = 2; if (s->op->type & KW_SHORT) { size = -1; } else if (s->op->type & KW_LONG && size++) { diff --git a/validation/int128.c b/validation/int128.c new file mode 100644 index 00000000..53d678e2 --- /dev/null +++ b/validation/int128.c @@ -0,0 +1,58 @@ +typedef __int128 int128_t; +typedef signed __int128 sint128_t; +typedef unsigned __int128 uint128_t; + +typedef __int128 int badxi; +typedef int __int128 badix; +typedef unsigned unsigned __int128 baduu; +typedef double __int128 baddx; +typedef __int128 double badxd; + +int sizeof_int128(void) +{ + return sizeof(__int128); +} + +typedef unsigned long long u64; +typedef unsigned long u32; + +u64 foo(u64 a, u64 b, u64 c, u32 s) +{ + unsigned __int128 tmp; + + tmp = (((uint128_t)a) * b) + c; + return (u64) (tmp >> s); +} + +/* + * check-name: int128 + * check-command: test-linearize $file + * check-output-ignore + * + * check-output-contains: ret\\..*\\$16 + * check-output-contains: mulu\\.128 + * check-output-contains: add\\.128 + * + * check-error-start +int128.c:5:18: error: two or more data types in declaration specifiers +int128.c:5:18: error: Trying to use reserved word 'int' as identifier +int128.c:5:25: error: Expected ; at end of declaration +int128.c:5:25: error: got badxi +int128.c:6:13: error: two or more data types in declaration specifiers +int128.c:6:13: error: Trying to use reserved word '__int128' as identifier +int128.c:6:25: error: Expected ; at end of declaration +int128.c:6:25: error: got badix +int128.c:7:18: error: impossible combination of type specifiers: unsigned unsigned +int128.c:7:18: error: Trying to use reserved word 'unsigned' as identifier +int128.c:7:27: error: Expected ; at end of declaration +int128.c:7:27: error: got __int128 +int128.c:8:16: error: two or more data types in declaration specifiers +int128.c:8:16: error: Trying to use reserved word '__int128' as identifier +int128.c:8:25: error: Expected ; at end of declaration +int128.c:8:25: error: got baddx +int128.c:9:18: error: two or more data types in declaration specifiers +int128.c:9:18: error: Trying to use reserved word 'double' as identifier +int128.c:9:25: error: Expected ; at end of declaration +int128.c:9:25: error: got badxd + * check-error-end + */
There is already support for __int128_t & __uint128_t but not yet for GCC's __int128. This patch add support for it and a couple of test cases. Note: it's slightly more tricky that it look because contrary to '__int128_t', '__int128' is not an exact type (it can still receive the 'unsigned' or 'signed' specifier). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- parse.c | 10 +++++++++ validation/int128.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 validation/int128.c