From abf909e1acd60eb19480fd68c570df2b8451a502 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 24 Nov 2002 16:00:08 +0000 Subject: [PATCH] added static bit fields init - version change - #error and #warning fix - support aligned attribute without parameter --- tcc.c | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/tcc.c b/tcc.c index 4f982ae..07fa7c3 100644 --- a/tcc.c +++ b/tcc.c @@ -2541,6 +2541,7 @@ static void preprocess(int is_bof) case TOK_ERROR: case TOK_WARNING: c = tok; + ch = file->buf_ptr[0]; skip_spaces(); q = buf; while (ch != '\n' && ch != CH_EOF) { @@ -5567,12 +5568,16 @@ void parse_attribute(AttributeDef *ad) break; case TOK_ALIGNED: case TOK___ALIGNED__: - skip('('); - n = expr_const(); - if (n <= 0 || (n & (n - 1)) != 0) - error("alignment must be a positive power of two"); + if (tok == '(') { + next(); + n = expr_const(); + if (n <= 0 || (n & (n - 1)) != 0) + error("alignment must be a positive power of two"); + skip(')'); + } else { + n = MAX_ALIGN; + } ad->aligned = n; - skip(')'); break; case TOK_UNUSED: case TOK___UNUSED__: @@ -7263,8 +7268,9 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, static void init_putv(CType *type, Section *sec, unsigned long c, int v, int expr_type) { - int saved_global_expr, bt; + int saved_global_expr, bt, bit_pos, bit_size; void *ptr; + unsigned long long bit_mask; switch(expr_type) { case EXPR_VAL: @@ -7291,19 +7297,30 @@ static void init_putv(CType *type, Section *sec, unsigned long c, gen_assign_cast(type); bt = type->t & VT_BTYPE; ptr = sec->data + c; + /* XXX: make code faster ? */ + if (!(type->t & VT_BITFIELD)) { + bit_pos = 0; + bit_size = 32; + bit_mask = -1LL; + } else { + bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; + bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; + bit_mask = (1LL << bit_size) - 1; + } if ((vtop->r & VT_SYM) && (bt == VT_BYTE || bt == VT_SHORT || bt == VT_DOUBLE || bt == VT_LDOUBLE || - bt == VT_LLONG)) + bt == VT_LLONG || + (bt == VT_INT && bit_size != 32))) error("initializer element is not computable at load time"); switch(bt) { case VT_BYTE: - *(char *)ptr = vtop->c.i; + *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; break; case VT_SHORT: - *(short *)ptr = vtop->c.i; + *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; break; case VT_DOUBLE: *(double *)ptr = vtop->c.d; @@ -7312,13 +7329,13 @@ static void init_putv(CType *type, Section *sec, unsigned long c, *(long double *)ptr = vtop->c.ld; break; case VT_LLONG: - *(long long *)ptr = vtop->c.ll; + *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos; break; default: if (vtop->r & VT_SYM) { greloc(sec, vtop->sym, c, R_DATA_32); } - *(int *)ptr = vtop->c.i; + *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos; break; } vtop--; @@ -7467,7 +7484,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, /* NOTE: the previous test is a specific case for automatic struct/union init */ /* XXX: union needs only one init */ - /* XXX: handle bit fields */ no_oblock = 1; if (first || tok == '{') { skip('{'); @@ -7480,8 +7496,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, n = s->c; while (tok != '}') { decl_designator(type, sec, c, NULL, &f, size_only); - /* XXX: bitfields ? */ - /* fill with zero between fields */ index = f->c; if (!size_only && array_length < index) { init_putz(type, sec, c + array_length, @@ -7490,12 +7504,12 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, index = index + type_size(&f->type, &align1); if (index > array_length) array_length = index; - if (no_oblock && f->next == NULL) + f = f->next; + if (no_oblock && f == NULL) break; if (tok == '}') break; skip(','); - f = f->next; } /* put zeros at the end */ if (!size_only && array_length < n) { @@ -8843,7 +8857,7 @@ static int64_t getclock_us(void) void help(void) { - printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" + printf("tcc version 0.9.14 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n" " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n" " [--] infile1 [infile2... --] [infile_args...]\n"