added static bit fields init - version change - #error and #warning fix - support aligned attribute without parameter
This commit is contained in:
42
tcc.c
42
tcc.c
@ -2541,6 +2541,7 @@ static void preprocess(int is_bof)
|
|||||||
case TOK_ERROR:
|
case TOK_ERROR:
|
||||||
case TOK_WARNING:
|
case TOK_WARNING:
|
||||||
c = tok;
|
c = tok;
|
||||||
|
ch = file->buf_ptr[0];
|
||||||
skip_spaces();
|
skip_spaces();
|
||||||
q = buf;
|
q = buf;
|
||||||
while (ch != '\n' && ch != CH_EOF) {
|
while (ch != '\n' && ch != CH_EOF) {
|
||||||
@ -5567,12 +5568,16 @@ void parse_attribute(AttributeDef *ad)
|
|||||||
break;
|
break;
|
||||||
case TOK_ALIGNED:
|
case TOK_ALIGNED:
|
||||||
case TOK___ALIGNED__:
|
case TOK___ALIGNED__:
|
||||||
skip('(');
|
if (tok == '(') {
|
||||||
|
next();
|
||||||
n = expr_const();
|
n = expr_const();
|
||||||
if (n <= 0 || (n & (n - 1)) != 0)
|
if (n <= 0 || (n & (n - 1)) != 0)
|
||||||
error("alignment must be a positive power of two");
|
error("alignment must be a positive power of two");
|
||||||
ad->aligned = n;
|
|
||||||
skip(')');
|
skip(')');
|
||||||
|
} else {
|
||||||
|
n = MAX_ALIGN;
|
||||||
|
}
|
||||||
|
ad->aligned = n;
|
||||||
break;
|
break;
|
||||||
case TOK_UNUSED:
|
case TOK_UNUSED:
|
||||||
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,
|
static void init_putv(CType *type, Section *sec, unsigned long c,
|
||||||
int v, int expr_type)
|
int v, int expr_type)
|
||||||
{
|
{
|
||||||
int saved_global_expr, bt;
|
int saved_global_expr, bt, bit_pos, bit_size;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
unsigned long long bit_mask;
|
||||||
|
|
||||||
switch(expr_type) {
|
switch(expr_type) {
|
||||||
case EXPR_VAL:
|
case EXPR_VAL:
|
||||||
@ -7291,19 +7297,30 @@ static void init_putv(CType *type, Section *sec, unsigned long c,
|
|||||||
gen_assign_cast(type);
|
gen_assign_cast(type);
|
||||||
bt = type->t & VT_BTYPE;
|
bt = type->t & VT_BTYPE;
|
||||||
ptr = sec->data + c;
|
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) &&
|
if ((vtop->r & VT_SYM) &&
|
||||||
(bt == VT_BYTE ||
|
(bt == VT_BYTE ||
|
||||||
bt == VT_SHORT ||
|
bt == VT_SHORT ||
|
||||||
bt == VT_DOUBLE ||
|
bt == VT_DOUBLE ||
|
||||||
bt == VT_LDOUBLE ||
|
bt == VT_LDOUBLE ||
|
||||||
bt == VT_LLONG))
|
bt == VT_LLONG ||
|
||||||
|
(bt == VT_INT && bit_size != 32)))
|
||||||
error("initializer element is not computable at load time");
|
error("initializer element is not computable at load time");
|
||||||
switch(bt) {
|
switch(bt) {
|
||||||
case VT_BYTE:
|
case VT_BYTE:
|
||||||
*(char *)ptr = vtop->c.i;
|
*(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
|
||||||
break;
|
break;
|
||||||
case VT_SHORT:
|
case VT_SHORT:
|
||||||
*(short *)ptr = vtop->c.i;
|
*(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
|
||||||
break;
|
break;
|
||||||
case VT_DOUBLE:
|
case VT_DOUBLE:
|
||||||
*(double *)ptr = vtop->c.d;
|
*(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;
|
*(long double *)ptr = vtop->c.ld;
|
||||||
break;
|
break;
|
||||||
case VT_LLONG:
|
case VT_LLONG:
|
||||||
*(long long *)ptr = vtop->c.ll;
|
*(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (vtop->r & VT_SYM) {
|
if (vtop->r & VT_SYM) {
|
||||||
greloc(sec, vtop->sym, c, R_DATA_32);
|
greloc(sec, vtop->sym, c, R_DATA_32);
|
||||||
}
|
}
|
||||||
*(int *)ptr = vtop->c.i;
|
*(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vtop--;
|
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
|
/* NOTE: the previous test is a specific case for automatic
|
||||||
struct/union init */
|
struct/union init */
|
||||||
/* XXX: union needs only one init */
|
/* XXX: union needs only one init */
|
||||||
/* XXX: handle bit fields */
|
|
||||||
no_oblock = 1;
|
no_oblock = 1;
|
||||||
if (first || tok == '{') {
|
if (first || tok == '{') {
|
||||||
skip('{');
|
skip('{');
|
||||||
@ -7480,8 +7496,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
|||||||
n = s->c;
|
n = s->c;
|
||||||
while (tok != '}') {
|
while (tok != '}') {
|
||||||
decl_designator(type, sec, c, NULL, &f, size_only);
|
decl_designator(type, sec, c, NULL, &f, size_only);
|
||||||
/* XXX: bitfields ? */
|
|
||||||
/* fill with zero between fields */
|
|
||||||
index = f->c;
|
index = f->c;
|
||||||
if (!size_only && array_length < index) {
|
if (!size_only && array_length < index) {
|
||||||
init_putz(type, sec, c + array_length,
|
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);
|
index = index + type_size(&f->type, &align1);
|
||||||
if (index > array_length)
|
if (index > array_length)
|
||||||
array_length = index;
|
array_length = index;
|
||||||
if (no_oblock && f->next == NULL)
|
f = f->next;
|
||||||
|
if (no_oblock && f == NULL)
|
||||||
break;
|
break;
|
||||||
if (tok == '}')
|
if (tok == '}')
|
||||||
break;
|
break;
|
||||||
skip(',');
|
skip(',');
|
||||||
f = f->next;
|
|
||||||
}
|
}
|
||||||
/* put zeros at the end */
|
/* put zeros at the end */
|
||||||
if (!size_only && array_length < n) {
|
if (!size_only && array_length < n) {
|
||||||
@ -8843,7 +8857,7 @@ static int64_t getclock_us(void)
|
|||||||
|
|
||||||
void help(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"
|
"usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
|
||||||
" [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
|
" [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
|
||||||
" [--] infile1 [infile2... --] [infile_args...]\n"
|
" [--] infile1 [infile2... --] [infile_args...]\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user