aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2009-08-06 20:19:15 +0000
committerChristopher Li <sparse@chrisli.org>2009-08-01 20:30:19 -0700
commit94a27dcf4ac83ca900be9e3f78bb545290a46f79 (patch)
tree27c4da9a030f2020c52e5c43663b7ea623e3081f
parentlinearize.h: sanitize header (diff)
downloadsparse-94a27dcf4ac83ca900be9e3f78bb545290a46f79.tar.gz
sparse-94a27dcf4ac83ca900be9e3f78bb545290a46f79.tar.bz2
sparse-94a27dcf4ac83ca900be9e3f78bb545290a46f79.zip
Add support for TImode type (__int128_t)
GCC provides a 128 bit type called internally as TImode (__int128_t)on 64 bit platforms (at least x86_64 and Sparc64). These types are used by OpenBIOS. Add support for types "long long long", __mode__(TI) and __(u)int128_t. Signed-off-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
-rwxr-xr-xcgcc7
-rw-r--r--evaluate.c6
-rw-r--r--expand.c3
-rw-r--r--gdbhelpers3
-rw-r--r--parse.c25
-rw-r--r--show-parse.c3
-rw-r--r--symbol.c6
-rw-r--r--symbol.h9
-rw-r--r--target.c1
-rw-r--r--target.h1
10 files changed, 51 insertions, 13 deletions
diff --git a/cgcc b/cgcc
index fdda6d1..8295fcd 100755
--- a/cgcc
+++ b/cgcc
@@ -128,8 +128,9 @@ sub integer_types {
16 => '32767',
32 => '2147483647',
64 => '9223372036854775807',
+ 128 => '170141183460469231731687303715884105727',
);
- my @types = (['SCHAR',''], ['SHRT',''], ['INT',''], ['LONG','L'], ['LONG_LONG','LL']);
+ my @types = (['SCHAR',''], ['SHRT',''], ['INT',''], ['LONG','L'], ['LONG_LONG','LL'], ['LONG_LONG_LONG','LLL']);
my $result = " -D__CHAR_BIT__=$char";
while (@types) {
@@ -260,12 +261,12 @@ sub add_specs {
&define_size_t ($m64 ? "long unsigned int" : "unsigned int"));
} elsif ($spec eq 'sparc64') {
return (' -Dsparc=1 -D__sparc=1 -D__sparc__=1 -D__sparcv9__=1 -D__sparc64__=1 -D__arch64__=1 -D__LP64__=1' .
- &integer_types (8, 16, 32, 64, 64) .
+ &integer_types (8, 16, 32, 64, 64, 128) .
&float_types (1, 1, 33, [24,8], [53,11], [113,15]) .
&define_size_t ("long unsigned int"));
} elsif ($spec eq 'x86_64') {
return (' -Dx86_64=1 -D__x86_64=1 -D__x86_64__=1' .
- &integer_types (8, 16, 32, $m32 ? 32 : 64, 64) .
+ &integer_types (8, 16, 32, $m32 ? 32 : 64, 64, 128) .
&float_types (1, 1, 33, [24,8], [53,11], [113,15]) .
&define_size_t ($m32 ? "unsigned int" : "long unsigned int"));
} elsif ($spec eq 'ppc') {
diff --git a/evaluate.c b/evaluate.c
index 1ab5ae8..805ae90 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -165,7 +165,7 @@ static struct symbol *bigger_int_type(struct symbol *left, struct symbol *right)
if ((lmod ^ rmod) & MOD_UNSIGNED) {
if (lmod & MOD_UNSIGNED)
goto left;
- } else if ((lmod & ~rmod) & (MOD_LONG | MOD_LONGLONG))
+ } else if ((lmod & ~rmod) & (MOD_LONG_ALL))
goto left;
right:
left = right;
@@ -512,7 +512,7 @@ Normal:
} else if (rclass & TYPE_FLOAT) {
unsigned long lmod = ltype->ctype.modifiers;
unsigned long rmod = rtype->ctype.modifiers;
- if (rmod & ~lmod & (MOD_LONG | MOD_LONGLONG))
+ if (rmod & ~lmod & (MOD_LONG_ALL))
return rtype;
else
return ltype;
@@ -2114,7 +2114,7 @@ static int evaluate_arguments(struct symbol *f, struct symbol *fn, struct expres
*p = cast_to(expr, integer_promotion(type));
} else if (class & TYPE_FLOAT) {
unsigned long mod = type->ctype.modifiers;
- if (!(mod & (MOD_LONG|MOD_LONGLONG)))
+ if (!(mod & (MOD_LONG_ALL)))
*p = cast_to(expr, &double_ctype);
} else if (class & TYPE_PTR) {
if (expr->ctype == &null_ctype)
diff --git a/expand.c b/expand.c
index 82fd62a..b965dc3 100644
--- a/expand.c
+++ b/expand.c
@@ -128,7 +128,8 @@ Float:
else
expr->fvalue = old->fvalue;
- if (!(newtype->ctype.modifiers & MOD_LONGLONG)) {
+ if (!(newtype->ctype.modifiers & MOD_LONGLONG) && \
+ !(newtype->ctype.modifiers & MOD_LONGLONGLONG)) {
if ((newtype->ctype.modifiers & MOD_LONG))
expr->fvalue = (double)expr->fvalue;
else
diff --git a/gdbhelpers b/gdbhelpers
index db78d6c..8634786 100644
--- a/gdbhelpers
+++ b/gdbhelpers
@@ -125,6 +125,9 @@ define gdb_show_ctype
if ($arg0->modifiers & MOD_LONGLONG)
printf "MOD_LONGLONG "
end
+ if ($arg0->modifiers & MOD_LONGLONGLONG)
+ printf "MOD_LONGLONGLONG "
+ end
if ($arg0->modifiers & MOD_TYPEDEF)
printf "MOD_TYPEDEF "
end
diff --git a/parse.c b/parse.c
index 613f439..5e75242 100644
--- a/parse.c
+++ b/parse.c
@@ -70,7 +70,7 @@ static attr_t
typedef struct symbol *to_mode_t(struct symbol *);
static to_mode_t
- to_QI_mode, to_HI_mode, to_SI_mode, to_DI_mode, to_word_mode;
+ to_QI_mode, to_HI_mode, to_SI_mode, to_DI_mode, to_TI_mode, to_word_mode;
enum {
Set_T = 1,
@@ -347,6 +347,11 @@ static struct symbol_op mode_DI_op = {
.to_mode = to_DI_mode
};
+static struct symbol_op mode_TI_op = {
+ .type = KW_MODE,
+ .to_mode = to_TI_mode
+};
+
static struct symbol_op mode_word_op = {
.type = KW_MODE,
.to_mode = to_word_mode
@@ -386,6 +391,8 @@ static struct init_keyword {
/* Predeclared types */
{ "__builtin_va_list", NS_TYPEDEF, .type = &ptr_ctype, .op = &spec_op },
+ { "__int128_t", NS_TYPEDEF, .type = &lllong_ctype, .op = &spec_op },
+ { "__uint128_t",NS_TYPEDEF, .type = &ulllong_ctype, .op = &spec_op },
/* Extended types */
{ "typeof", NS_TYPEDEF, .op = &typeof_op },
@@ -457,6 +464,8 @@ static struct init_keyword {
{ "__SI__", NS_KEYWORD, .op = &mode_SI_op },
{ "DI", NS_KEYWORD, MOD_LONGLONG, .op = &mode_DI_op },
{ "__DI__", NS_KEYWORD, MOD_LONGLONG, .op = &mode_DI_op },
+ { "TI", NS_KEYWORD, MOD_LONGLONGLONG, .op = &mode_TI_op },
+ { "__TI__", NS_KEYWORD, MOD_LONGLONGLONG, .op = &mode_TI_op },
{ "word", NS_KEYWORD, MOD_LONG, .op = &mode_word_op },
{ "__word__", NS_KEYWORD, MOD_LONG, .op = &mode_word_op },
@@ -1042,6 +1051,14 @@ static struct symbol *to_DI_mode(struct symbol *ctype)
: &sllong_ctype;
}
+static struct symbol *to_TI_mode(struct symbol *ctype)
+{
+ if (ctype->ctype.base_type != &int_type)
+ return NULL;
+ return ctype->ctype.modifiers & MOD_UNSIGNED ? &ulllong_ctype
+ : &slllong_ctype;
+}
+
static struct symbol *to_word_mode(struct symbol *ctype)
{
if (ctype->ctype.base_type != &int_type)
@@ -1322,9 +1339,11 @@ Catch_all:
static struct symbol * const int_types[] =
{&short_ctype, &int_ctype, &long_ctype, &llong_ctype};
static struct symbol * const signed_types[] =
- {&sshort_ctype, &sint_ctype, &slong_ctype, &sllong_ctype};
+ {&sshort_ctype, &sint_ctype, &slong_ctype, &sllong_ctype,
+ &slllong_ctype};
static struct symbol * const unsigned_types[] =
- {&ushort_ctype, &uint_ctype, &ulong_ctype, &ullong_ctype};
+ {&ushort_ctype, &uint_ctype, &ulong_ctype, &ullong_ctype,
+ &ulllong_ctype};
static struct symbol * const real_types[] =
{&float_ctype, &double_ctype, &ldouble_ctype};
static struct symbol * const char_types[] =
diff --git a/show-parse.c b/show-parse.c
index 99795e8..f249f4b 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -191,6 +191,9 @@ static struct ctype_name {
{ & llong_ctype, "long long" },
{ &sllong_ctype, "signed long long" },
{ &ullong_ctype, "unsigned long long" },
+ { & lllong_ctype, "long long long" },
+ { &slllong_ctype, "signed long long long" },
+ { &ulllong_ctype, "unsigned long long long" },
{ &void_ctype, "void" },
{ &bool_ctype, "bool" },
diff --git a/symbol.c b/symbol.c
index cda6bd0..96dfbfa 100644
--- a/symbol.c
+++ b/symbol.c
@@ -751,6 +751,7 @@ struct symbol bool_ctype, void_ctype, type_ctype,
int_ctype, sint_ctype, uint_ctype,
long_ctype, slong_ctype, ulong_ctype,
llong_ctype, sllong_ctype, ullong_ctype,
+ lllong_ctype, slllong_ctype, ulllong_ctype,
float_ctype, double_ctype, ldouble_ctype,
string_ctype, ptr_ctype, lazy_ptr_ctype,
incomplete_ctype, label_ctype, bad_ctype,
@@ -787,6 +788,7 @@ void init_symbols(void)
#define MOD_ESIGNED (MOD_SIGNED | MOD_EXPLICITLY_SIGNED)
#define MOD_LL (MOD_LONG | MOD_LONGLONG)
+#define MOD_LLL MOD_LONGLONGLONG
static const struct ctype_declare {
struct symbol *ptr;
enum type type;
@@ -816,6 +818,9 @@ static const struct ctype_declare {
{ &llong_ctype, SYM_BASETYPE, MOD_SIGNED | MOD_LL, &bits_in_longlong, &max_int_alignment, &int_type },
{ &sllong_ctype, SYM_BASETYPE, MOD_ESIGNED | MOD_LL, &bits_in_longlong, &max_int_alignment, &int_type },
{ &ullong_ctype, SYM_BASETYPE, MOD_UNSIGNED | MOD_LL, &bits_in_longlong, &max_int_alignment, &int_type },
+ { &lllong_ctype, SYM_BASETYPE, MOD_SIGNED | MOD_LLL, &bits_in_longlonglong, &max_int_alignment, &int_type },
+ { &slllong_ctype, SYM_BASETYPE, MOD_ESIGNED | MOD_LLL, &bits_in_longlonglong, &max_int_alignment, &int_type },
+ { &ulllong_ctype, SYM_BASETYPE, MOD_UNSIGNED | MOD_LLL, &bits_in_longlonglong, &max_int_alignment, &int_type },
{ &float_ctype, SYM_BASETYPE, 0, &bits_in_float, &max_fp_alignment, &fp_type },
{ &double_ctype, SYM_BASETYPE, MOD_LONG, &bits_in_double, &max_fp_alignment, &fp_type },
@@ -828,6 +833,7 @@ static const struct ctype_declare {
{ &lazy_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype },
{ NULL, }
};
+#undef MOD_LLL
#undef MOD_LL
#undef MOD_ESIGNED
diff --git a/symbol.h b/symbol.h
index 42d69d6..60fdad0 100644
--- a/symbol.h
+++ b/symbol.h
@@ -196,8 +196,9 @@ struct symbol {
#define MOD_SHORT 0x0200
#define MOD_LONG 0x0400
#define MOD_LONGLONG 0x0800
+#define MOD_LONGLONGLONG 0x1000
-#define MOD_TYPEDEF 0x1000
+#define MOD_TYPEDEF 0x10000
#define MOD_TLS 0x20000
#define MOD_INLINE 0x40000
@@ -219,8 +220,9 @@ struct symbol {
#define MOD_NONLOCAL (MOD_EXTERN | MOD_TOPLEVEL)
#define MOD_STORAGE (MOD_AUTO | MOD_REGISTER | MOD_STATIC | MOD_EXTERN | MOD_INLINE | MOD_TOPLEVEL)
#define MOD_SIGNEDNESS (MOD_SIGNED | MOD_UNSIGNED | MOD_EXPLICITLY_SIGNED)
-#define MOD_SPECIFIER (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG | MOD_SIGNEDNESS)
-#define MOD_SIZE (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG)
+#define MOD_LONG_ALL (MOD_LONG | MOD_LONGLONG | MOD_LONGLONGLONG)
+#define MOD_SPECIFIER (MOD_CHAR | MOD_SHORT | MOD_LONG_ALL | MOD_SIGNEDNESS)
+#define MOD_SIZE (MOD_CHAR | MOD_SHORT | MOD_LONG_ALL)
#define MOD_IGNORE (MOD_TOPLEVEL | MOD_STORAGE | MOD_ADDRESSABLE | \
MOD_ASSIGNED | MOD_USERTYPE | MOD_ACCESSED | MOD_EXPLICITLY_SIGNED)
#define MOD_PTRINHERIT (MOD_VOLATILE | MOD_CONST | MOD_NODEREF | MOD_STORAGE)
@@ -240,6 +242,7 @@ extern struct symbol bool_ctype, void_ctype, type_ctype,
int_ctype, sint_ctype, uint_ctype,
long_ctype, slong_ctype, ulong_ctype,
llong_ctype, sllong_ctype, ullong_ctype,
+ lllong_ctype, slllong_ctype, ulllong_ctype,
float_ctype, double_ctype, ldouble_ctype,
string_ctype, ptr_ctype, lazy_ptr_ctype,
incomplete_ctype, label_ctype, bad_ctype,
diff --git a/target.c b/target.c
index bf1bb8f..17b228a 100644
--- a/target.c
+++ b/target.c
@@ -20,6 +20,7 @@ int bits_in_short = 16;
int bits_in_int = 32;
int bits_in_long = 32;
int bits_in_longlong = 64;
+int bits_in_longlonglong = 128;
int max_int_alignment = 4;
diff --git a/target.h b/target.h
index 7f0fd27..1030c7c 100644
--- a/target.h
+++ b/target.h
@@ -18,6 +18,7 @@ extern int bits_in_short;
extern int bits_in_int;
extern int bits_in_long;
extern int bits_in_longlong;
+extern int bits_in_longlonglong;
extern int max_int_alignment;