changeset 206:fd3dbd365c06

[project @ 2002-11-24 16:00:08 by bellard] added static bit fields init - version change - #error and #warning fix - support aligned attribute without parameter
author bellard
date Sun, 24 Nov 2002 16:00:08 +0000
parents 0e2c76559eaa
children f80d7b61c819
files tcc.c
diffstat 1 files changed, 31 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/tcc.c	Sun Nov 24 15:59:16 2002 +0000
+++ b/tcc.c	Sun Nov 24 16:00:08 2002 +0000
@@ -2541,6 +2541,7 @@
     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 @@
             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 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 @@
         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 @@
             *(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 @@
         /* 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 @@
         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 @@
             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 @@
 
 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"