aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'tccgen.c')
-rw-r--r--tccgen.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/tccgen.c b/tccgen.c
index 6ea62e2..75959ad 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3062,6 +3062,24 @@ ST_FUNC void parse_mult_str (CString *astr, const char *msg)
cstr_ccat(astr, '\0');
}
+/* If I is >= 1 and a power of two, returns log2(i)+1.
+ If I is 0 returns 0. */
+static int exact_log2p1(int i)
+{
+ int ret;
+ if (!i)
+ return 0;
+ for (ret = 1; i >= 1 << 8; ret += 8)
+ i >>= 8;
+ if (i >= 1 << 4)
+ ret += 4, i >>= 4;
+ if (i >= 1 << 2)
+ ret += 2, i >>= 2;
+ if (i >= 1 << 1)
+ ret++;
+ return ret;
+}
+
/* Parse GNUC __attribute__ extension. Currently, the following
extensions are recognized:
- aligned(n) : set data/function alignment.
@@ -3131,7 +3149,9 @@ static void parse_attribute(AttributeDef *ad)
} else {
n = MAX_ALIGN;
}
- ad->a.aligned = n;
+ ad->a.aligned = exact_log2p1(n);
+ if (n != 1 << (ad->a.aligned - 1))
+ tcc_error("alignment of %d is larger than implemented", n);
break;
case TOK_PACKED1:
case TOK_PACKED2:
@@ -3270,7 +3290,7 @@ static void struct_layout(CType *type, AttributeDef *ad)
int pcc = !tcc_state->ms_bitfields;
Sym *f;
if (ad->a.aligned)
- maxalign = ad->a.aligned;
+ maxalign = 1 << (ad->a.aligned - 1);
else
maxalign = 1;
offset = 0;
@@ -3293,6 +3313,8 @@ static void struct_layout(CType *type, AttributeDef *ad)
align = f->r;
} else if (ad->a.packed || f->r == 1) {
align = 1;
+ /* Packed fields or packed records don't let the base type
+ influence the records type alignment. */
typealign = 1;
} else {
align = typealign;
@@ -3587,8 +3609,9 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
/* Only remember non-default alignment. */
alignoverride = 0;
if (ad1.a.aligned) {
- if (align < ad1.a.aligned)
- alignoverride = ad1.a.aligned;
+ int speca = 1 << (ad1.a.aligned - 1);
+ if (align < speca)
+ alignoverride = speca;
} else if (ad1.a.packed || ad->a.packed) {
alignoverride = 1;
} else if (*tcc_state->pack_stack_ptr) {
@@ -6594,8 +6617,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
* pointed_size(&flexible_array->type);
/* take into account specified alignment if bigger */
if (ad->a.aligned) {
- if (ad->a.aligned > align)
- align = ad->a.aligned;
+ int speca = 1 << (ad->a.aligned - 1);
+ if (speca > align)
+ align = speca;
} else if (ad->a.packed) {
align = 1;
}