| @@ -93,6 +93,7 @@ ST_FUNC void vpush(CType *type); · 92 unmodified lines |
| 93 | ST_FUNC int gvtst(int inv, int t); | 93 | ST_FUNC int gvtst(int inv, int t); |
| 94 | static void gen_inline_functions(TCCState *s); | 94 | static void gen_inline_functions(TCCState *s); |
| 95 | static void skip_or_save_block(TokenString **str); | 95 | static void skip_or_save_block(TokenString **str); |
| | 96 | static void gv_dup(void); |
| 96 | | 97 | |
| 97 | ST_INLN int is_float(int t) | 98 | ST_INLN int is_float(int t) |
| 98 | { | 99 | { |
| @@ -1065,38 +1066,142 @@ static void gbound(void) · 966 unmodified lines |
| 1065 | } | 1066 | } |
| 1066 | #endif | 1067 | #endif |
| 1067 | | 1068 | |
| | 1069 | static void incr_bf_adr(int o) |
| | 1070 | { |
| | 1071 | vtop->type = char_pointer_type; |
| | 1072 | gaddrof(); |
| | 1073 | vpushi(o); |
| | 1074 | gen_op('+'); |
| | 1075 | vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN)) |
| | 1076 | | (VT_BYTE|VT_UNSIGNED); |
| | 1077 | vtop->r = (vtop->r & ~VT_LVAL_TYPE) |
| | 1078 | | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL); |
| | 1079 | } |
| | 1080 | |
| | 1081 | /* single-byte load mode for packed or otherwise unaligned bitfields */ |
| | 1082 | static void load_packed_bf(CType *type, int bit_pos, int bit_size) |
| | 1083 | { |
| | 1084 | int n, o, bits; |
| | 1085 | save_reg_upstack(vtop->r, 1); |
| | 1086 | vpushi(0); // B X |
| | 1087 | vtop->type.t |= type->t; |
| | 1088 | bits = 0, o = bit_pos >> 3, bit_pos &= 7; |
| | 1089 | do { |
| | 1090 | vswap(); // X B |
| | 1091 | incr_bf_adr(o); |
| | 1092 | vdup(); // X B B |
| | 1093 | n = 8 - bit_pos; |
| | 1094 | if (n > bit_size) |
| | 1095 | n = bit_size; |
| | 1096 | if (bit_pos) |
| | 1097 | vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y |
| | 1098 | if (n < 8) |
| | 1099 | vpushi((1 << n) - 1), gen_op('&'); |
| | 1100 | gen_cast(type); |
| | 1101 | if (bits) |
| | 1102 | vpushi(bits), gen_op(TOK_SHL); |
| | 1103 | vrotb(3); // B Y X |
| | 1104 | gen_op('|'); // B X |
| | 1105 | bits += n, bit_size -= n, o = 1; |
| | 1106 | } while (bit_size); |
| | 1107 | vswap(), vpop(); |
| | 1108 | if (!(type->t & VT_UNSIGNED)) { |
| | 1109 | n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits; |
| | 1110 | vpushi(n), gen_op(TOK_SHL); |
| | 1111 | vpushi(n), gen_op(TOK_SAR); |
| | 1112 | } |
| | 1113 | } |
| | 1114 | |
| | 1115 | /* single-byte store mode for packed or otherwise unaligned bitfields */ |
| | 1116 | void store_packed_bf(int bit_pos, int bit_size) |
| | 1117 | { |
| | 1118 | int bits, n, o, m, c; |
| | 1119 | |
| | 1120 | c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| | 1121 | vswap(); // X B |
| | 1122 | save_reg_upstack(vtop->r, 1); |
| | 1123 | bits = 0, o = bit_pos >> 3, bit_pos &= 7; |
| | 1124 | do { |
| | 1125 | incr_bf_adr(o); // X B |
| | 1126 | vswap(); //B X |
| | 1127 | c ? vdup() : gv_dup(); // B V X |
| | 1128 | vrott(3); // X B V |
| | 1129 | if (bits) |
| | 1130 | vpushi(bits), gen_op(TOK_SHR); |
| | 1131 | if (bit_pos) |
| | 1132 | vpushi(bit_pos), gen_op(TOK_SHL); |
| | 1133 | n = 8 - bit_pos; |
| | 1134 | if (n > bit_size) |
| | 1135 | n = bit_size; |
| | 1136 | if (n < 8) { |
| | 1137 | m = ((1 << n) - 1) << bit_pos; |
| | 1138 | vpushi(m), gen_op('&'); // X B V1 |
| | 1139 | vpushv(vtop-1); // X B V1 B |
| | 1140 | vpushi(m & 0x80 ? ~m & 0x7f : ~m); |
| | 1141 | gen_op('&'); // X B V1 B1 |
| | 1142 | gen_op('|'); // X B V2 |
| | 1143 | } |
| | 1144 | vdup(), vtop[-1] = vtop[-2]; // X B B V2 |
| | 1145 | vstore(), vpop(); // X B |
| | 1146 | bits += n, bit_size -= n, bit_pos = 0, o = 1; |
| | 1147 | } while (bit_size); |
| | 1148 | vpop(), vpop(); |
| | 1149 | } |
| | 1150 | |
| | 1151 | int adjust_bf(SValue *sv, int bit_pos, int bit_size) |
| | 1152 | { |
| | 1153 | int t; |
| | 1154 | if (0 == sv->type.ref) |
| | 1155 | return 0; |
| | 1156 | t = sv->type.ref->auxtype; |
| | 1157 | if (t != -1 && t != VT_STRUCT) { |
| | 1158 | sv->type.t = (sv->type.t & ~VT_BTYPE) | t; |
| | 1159 | sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t); |
| | 1160 | } |
| | 1161 | return t; |
| | 1162 | } |
| | 1163 | |
| 1068 | /* store vtop a register belonging to class 'rc'. lvalues are | 1164 | /* store vtop a register belonging to class 'rc'. lvalues are |
| 1069 | converted to values. Cannot be used if cannot be converted to | 1165 | converted to values. Cannot be used if cannot be converted to |
| 1070 | register value (such as structures). */ | 1166 | register value (such as structures). */ |
| 1071 | ST_FUNC int gv(int rc) | 1167 | ST_FUNC int gv(int rc) |
| 1072 | { | 1168 | { |
| 1073 | int r, bit_pos, bit_size, size, align; | 1169 | int r, bit_pos, bit_size, size, align, rc2; |
| 1074 | int rc2; | | |
| 1075 | | 1170 | |
| 1076 | /* NOTE: get_reg can modify vstack[] */ | 1171 | /* NOTE: get_reg can modify vstack[] */ |
| 1077 | if (vtop->type.t & VT_BITFIELD) { | 1172 | if (vtop->type.t & VT_BITFIELD) { |
| 1078 | CType type; | 1173 | CType type; |
| 1079 | int bits = 32; | 1174 | |
| 1080 | bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; | 1175 | bit_pos = BIT_POS(vtop->type.t); |
| 1081 | bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; | 1176 | bit_size = BIT_SIZE(vtop->type.t); |
| 1082 | /* remove bit field info to avoid loops */ | 1177 | /* remove bit field info to avoid loops */ |
| 1083 | vtop->type.t &= ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1); | 1178 | vtop->type.t &= ~VT_STRUCT_MASK; |
| 1084 | /* cast to int to propagate signedness in following ops */ | 1179 | |
| 1085 | if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { | 1180 | type.ref = NULL; |
| 1086 | type.t = VT_LLONG; | 1181 | type.t = vtop->type.t & VT_UNSIGNED; |
| 1087 | bits = 64; | 1182 | if ((vtop->type.t & VT_BTYPE) == VT_BOOL) |
| 1088 | } else | | |
| 1089 | type.t = VT_INT; | | |
| 1090 | if((vtop->type.t & VT_UNSIGNED) | | |
| 1091 | || (vtop->type.t & VT_BTYPE) == VT_BOOL) | | |
| 1092 | type.t |= VT_UNSIGNED; | 1183 | type.t |= VT_UNSIGNED; |
| 1093 | gen_cast(&type); | 1184 | |
| 1094 | /* generate shifts */ | 1185 | r = adjust_bf(vtop, bit_pos, bit_size); |
| 1095 | vpushi(bits - (bit_pos + bit_size)); | 1186 | |
| 1096 | gen_op(TOK_SHL); | 1187 | if ((vtop->type.t & VT_BTYPE) == VT_LLONG) |
| 1097 | vpushi(bits - bit_size); | 1188 | type.t |= VT_LLONG; |
| 1098 | /* NOTE: transformed to SHR if unsigned */ | 1189 | else |
| 1099 | gen_op(TOK_SAR); | 1190 | type.t |= VT_INT; |
| | 1191 | |
| | 1192 | if (r == VT_STRUCT) { |
| | 1193 | load_packed_bf(&type, bit_pos, bit_size); |
| | 1194 | } else { |
| | 1195 | int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32; |
| | 1196 | /* cast to int to propagate signedness in following ops */ |
| | 1197 | gen_cast(&type); |
| | 1198 | /* generate shifts */ |
| | 1199 | vpushi(bits - (bit_pos + bit_size)); |
| | 1200 | gen_op(TOK_SHL); |
| | 1201 | vpushi(bits - bit_size); |
| | 1202 | /* NOTE: transformed to SHR if unsigned */ |
| | 1203 | gen_op(TOK_SAR); |
| | 1204 | } |
| 1100 | r = gv(rc); | 1205 | r = gv(rc); |
| 1101 | } else { | 1206 | } else { |
| 1102 | if (is_float(vtop->type.t) && | 1207 | if (is_float(vtop->type.t) && |
| @@ -1362,6 +1467,10 @@ static void gv_dup(void) · 259 unmodified lines |
| 1362 | t = vtop->type.t; | 1467 | t = vtop->type.t; |
| 1363 | #if PTR_SIZE == 4 | 1468 | #if PTR_SIZE == 4 |
| 1364 | if ((t & VT_BTYPE) == VT_LLONG) { | 1469 | if ((t & VT_BTYPE) == VT_LLONG) { |
| | 1470 | if (t & VT_BITFIELD) { |
| | 1471 | gv(RC_INT); |
| | 1472 | t = vtop->type.t; |
| | 1473 | } |
| 1365 | lexpand(); | 1474 | lexpand(); |
| 1366 | gv_dup(); | 1475 | gv_dup(); |
| 1367 | vswap(); | 1476 | vswap(); |
| @@ -2920,45 +3029,49 @@ ST_FUNC void vstore(void) · 1552 unmodified lines |
| 2920 | /* save lvalue as expression result (example: s.b = s.a = n;) */ | 3029 | /* save lvalue as expression result (example: s.b = s.a = n;) */ |
| 2921 | vdup(), vtop[-1] = vtop[-2]; | 3030 | vdup(), vtop[-1] = vtop[-2]; |
| 2922 | | 3031 | |
| 2923 | bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f; | 3032 | bit_pos = BIT_POS(ft); |
| 2924 | bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f; | 3033 | bit_size = BIT_SIZE(ft); |
| 2925 | /* remove bit field info to avoid loops */ | 3034 | /* remove bit field info to avoid loops */ |
| 2926 | vtop[-1].type.t = ft & ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1); | 3035 | vtop[-1].type.t = ft & ~VT_STRUCT_MASK; |
| 2927 | | 3036 | |
| 2928 | if((ft & VT_BTYPE) == VT_BOOL) { | 3037 | if ((ft & VT_BTYPE) == VT_BOOL) { |
| 2929 | gen_cast(&vtop[-1].type); | 3038 | gen_cast(&vtop[-1].type); |
| 2930 | vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED); | 3039 | vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED); |
| 2931 | } | 3040 | } |
| 2932 | | 3041 | |
| 2933 | /* duplicate destination */ | 3042 | r = adjust_bf(vtop - 1, bit_pos, bit_size); |
| 2934 | vdup(); | 3043 | if (r == VT_STRUCT) { |
| 2935 | vtop[-1] = vtop[-2]; | 3044 | gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT); |
| 2936 | | 3045 | store_packed_bf(bit_pos, bit_size); |
| 2937 | /* mask and shift source */ | 3046 | } else { |
| 2938 | if((ft & VT_BTYPE) != VT_BOOL) { | 3047 | unsigned long long mask = (1ULL << bit_size) - 1; |
| 2939 | if((ft & VT_BTYPE) == VT_LLONG) { | 3048 | if ((ft & VT_BTYPE) != VT_BOOL) { |
| 2940 | vpushll((1ULL << bit_size) - 1ULL); | 3049 | /* mask source */ |
| 2941 | } else { | 3050 | if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG) |
| 2942 | vpushi((1 << bit_size) - 1); | 3051 | vpushll(mask); |
| | 3052 | else |
| | 3053 | vpushi((unsigned)mask); |
| | 3054 | gen_op('&'); |
| 2943 | } | 3055 | } |
| | 3056 | /* shift source */ |
| | 3057 | vpushi(bit_pos); |
| | 3058 | gen_op(TOK_SHL); |
| | 3059 | vswap(); |
| | 3060 | /* duplicate destination */ |
| | 3061 | vdup(); |
| | 3062 | vrott(3); |
| | 3063 | /* load destination, mask and or with source */ |
| | 3064 | if ((vtop->type.t & VT_BTYPE) == VT_LLONG) |
| | 3065 | vpushll(~(mask << bit_pos)); |
| | 3066 | else |
| | 3067 | vpushi(~((unsigned)mask << bit_pos)); |
| 2944 | gen_op('&'); | 3068 | gen_op('&'); |
| | 3069 | gen_op('|'); |
| | 3070 | /* store result */ |
| | 3071 | vstore(); |
| | 3072 | /* ... and discard */ |
| | 3073 | vpop(); |
| 2945 | } | 3074 | } |
| 2946 | vpushi(bit_pos); | | |
| 2947 | gen_op(TOK_SHL); | | |
| 2948 | /* load destination, mask and or with source */ | | |
| 2949 | vswap(); | | |
| 2950 | if((ft & VT_BTYPE) == VT_LLONG) { | | |
| 2951 | vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos)); | | |
| 2952 | } else { | | |
| 2953 | vpushi(~(((1 << bit_size) - 1) << bit_pos)); | | |
| 2954 | } | | |
| 2955 | gen_op('&'); | | |
| 2956 | gen_op('|'); | | |
| 2957 | /* store result */ | | |
| 2958 | vstore(); | | |
| 2959 | /* ... and discard */ | | |
| 2960 | vpop(); | | |
| 2961 | | | |
| 2962 | } else { | 3075 | } else { |
| 2963 | #ifdef CONFIG_TCC_BCHECK | 3076 | #ifdef CONFIG_TCC_BCHECK |
| 2964 | /* bound check case */ | 3077 | /* bound check case */ |
| @@ -3276,112 +3389,114 @@ static void struct_add_offset (Sym *s, int offset) · 311 unmodified lines |
| 3276 | | 3389 | |
| 3277 | static void struct_layout(CType *type, AttributeDef *ad) | 3390 | static void struct_layout(CType *type, AttributeDef *ad) |
| 3278 | { | 3391 | { |
| 3279 | int align, maxalign, offset, c, bit_pos, bt, prevbt, prev_bit_size; | 3392 | int size, align, maxalign, offset, c, bit_pos, bit_size; |
| | 3393 | int packed, a, bt, prevbt, prev_bit_size; |
| 3280 | int pcc = !tcc_state->ms_bitfields; | 3394 | int pcc = !tcc_state->ms_bitfields; |
| 3281 | int packwarn = tcc_state->warn_gcc_compat; | 3395 | int pragma_pack = *tcc_state->pack_stack_ptr; |
| 3282 | int typealign, bit_size, size; | | |
| 3283 | | | |
| 3284 | Sym *f; | 3396 | Sym *f; |
| 3285 | if (ad->a.aligned) | 3397 | |
| 3286 | maxalign = 1 << (ad->a.aligned - 1); | 3398 | maxalign = 1; |
| 3287 | else | | |
| 3288 | maxalign = 1; | | |
| 3289 | offset = 0; | 3399 | offset = 0; |
| 3290 | c = 0; | 3400 | c = 0; |
| 3291 | bit_pos = 0; | 3401 | bit_pos = 0; |
| 3292 | prevbt = VT_STRUCT; /* make it never match */ | 3402 | prevbt = VT_STRUCT; /* make it never match */ |
| 3293 | prev_bit_size = 0; | 3403 | prev_bit_size = 0; |
| 3294 | size = 0; | 3404 | |
| | 3405 | //#define BF_DEBUG |
| 3295 | | 3406 | |
| 3296 | for (f = type->ref->next; f; f = f->next) { | 3407 | for (f = type->ref->next; f; f = f->next) { |
| 3297 | size = type_size(&f->type, &typealign); | 3408 | if (f->type.t & VT_BITFIELD) |
| 3298 | if (f->type.t & VT_BITFIELD) | 3409 | bit_size = BIT_SIZE(f->type.t); |
| 3299 | bit_size = (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; | 3410 | else |
| 3300 | else | 3411 | bit_size = -1; |
| 3301 | bit_size = -1; | 3412 | size = type_size(&f->type, &align); |
| 3302 | if (bit_size == 0 && pcc) { | 3413 | a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0; |
| 3303 | /* Zero-width bit-fields in PCC mode aren't affected | 3414 | packed = 0; |
| 3304 | by any packing (attribute or pragma). */ | 3415 | |
| 3305 | align = typealign; | 3416 | if (pcc && bit_size == 0) { |
| 3306 | } else if (f->r > 1) { | 3417 | /* in pcc mode, packing does not affect zero-width bitfields */ |
| 3307 | align = f->r; | 3418 | |
| 3308 | } else if (ad->a.packed || f->r == 1) { | 3419 | } else { |
| 3309 | align = 1; | 3420 | /* in pcc mode, attribute packed overrides if set. */ |
| 3310 | /* Packed fields or packed records don't let the base type | 3421 | if (pcc && (f->a.packed || ad->a.packed)) |
| 3311 | influence the records type alignment. */ | 3422 | align = packed = 1; |
| 3312 | typealign = 1; | 3423 | |
| 3313 | } else { | 3424 | /* pragma pack overrides align if lesser and packs bitfields always */ |
| 3314 | align = typealign; | 3425 | if (pragma_pack) { |
| 3315 | } | 3426 | packed = 1; |
| 3316 | if (type->ref->type.t == VT_UNION) { | 3427 | if (pragma_pack < align) |
| | 3428 | align = pragma_pack; |
| | 3429 | /* in pcc mode pragma pack also overrides individual align */ |
| | 3430 | if (pcc && pragma_pack < a) |
| | 3431 | a = 0; |
| | 3432 | } |
| | 3433 | } |
| | 3434 | /* some individual align was specified */ |
| | 3435 | if (a) |
| | 3436 | align = a; |
| | 3437 | |
| | 3438 | if (type->ref->type.t == VT_UNION) { |
| 3317 | if (pcc && bit_size >= 0) | 3439 | if (pcc && bit_size >= 0) |
| 3318 | size = (bit_size + 7) >> 3; | 3440 | size = (bit_size + 7) >> 3; |
| 3319 | /* Bit position is already zero from our caller. */ | | |
| 3320 | offset = 0; | 3441 | offset = 0; |
| 3321 | if (size > c) | 3442 | if (size > c) |
| 3322 | c = size; | 3443 | c = size; |
| | 3444 | |
| 3323 | } else if (bit_size < 0) { | 3445 | } else if (bit_size < 0) { |
| 3324 | int addbytes = pcc ? (bit_pos + 7) >> 3 : 0; | 3446 | if (pcc) |
| 3325 | prevbt = VT_STRUCT; | 3447 | c += (bit_pos + 7) >> 3; |
| 3326 | prev_bit_size = 0; | 3448 | c = (c + align - 1) & -align; |
| 3327 | c = (c + addbytes + align - 1) & -align; | | |
| 3328 | offset = c; | 3449 | offset = c; |
| 3329 | if (size > 0) | 3450 | if (size > 0) |
| 3330 | c += size; | 3451 | c += size; |
| 3331 | bit_pos = 0; | 3452 | bit_pos = 0; |
| | 3453 | prevbt = VT_STRUCT; |
| | 3454 | prev_bit_size = 0; |
| | 3455 | |
| 3332 | } else { | 3456 | } else { |
| 3333 | /* A bit-field. Layout is more complicated. There are two | 3457 | /* A bit-field. Layout is more complicated. There are two |
| 3334 | options TCC implements: PCC compatible and MS compatible | 3458 | options: PCC (GCC) compatible and MS compatible */ |
| 3335 | (PCC compatible is what GCC uses for almost all targets). | 3459 | if (pcc) { |
| 3336 | In PCC layout the overall size of the struct (in c) is | 3460 | /* In PCC layout a bit-field is placed adjacent to the |
| 3337 | _excluding_ the current run of bit-fields (that is, | 3461 | preceding bit-fields, except if: |
| 3338 | there's at least additional bit_pos bits after c). In | 3462 | - it has zero-width |
| 3339 | MS layout c does include the current run of bit-fields. | 3463 | - an individual alignment was given |
| 3340 | | 3464 | - it would overflow its base type container and |
| 3341 | This matters for calculating the natural alignment buckets | 3465 | there is no packing */ |
| 3342 | in PCC mode. */ | 3466 | if (bit_size == 0) { |
| 3343 | | 3467 | new_field: |
| 3344 | /* 'align' will be used to influence records alignment, | 3468 | c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align; |
| 3345 | so it's the max of specified and type alignment, except | | |
| 3346 | in certain cases that depend on the mode. */ | | |
| 3347 | if (align < typealign) | | |
| 3348 | align = typealign; | | |
| 3349 | if (pcc) { | | |
| 3350 | /* In PCC layout a non-packed bit-field is placed adjacent | | |
| 3351 | to the preceding bit-fields, except if it would overflow | | |
| 3352 | its container (depending on base type) or it's a zero-width | | |
| 3353 | bit-field. Packed non-zero-width bit-fields always are | | |
| 3354 | placed adjacent. */ | | |
| 3355 | int ofs = (c * 8 + bit_pos) % (typealign * 8); | | |
| 3356 | int ofs2 = ofs + bit_size + (typealign * 8) - 1; | | |
| 3357 | if (bit_size == 0 || | | |
| 3358 | (typealign != 1 && | | |
| 3359 | (ofs2 / (typealign * 8)) > (size/typealign))) { | | |
| 3360 | c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign; | | |
| 3361 | bit_pos = 0; | 3469 | bit_pos = 0; |
| 3362 | } else if (bit_pos + bit_size > size * 8) { | 3470 | } else if (f->a.aligned) { |
| 3363 | c += bit_pos >> 3; | 3471 | goto new_field; |
| 3364 | bit_pos &= 7; | 3472 | } else if (!packed) { |
| 3365 | if (bit_pos + bit_size > size * 8) { | 3473 | int a8 = align * 8; |
| 3366 | c += 1, bit_pos = 0; | 3474 | int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8; |
| 3367 | if ((ad->a.packed || f->r) && packwarn) { | 3475 | if (ofs > size / align) |
| 3368 | tcc_warning("struct layout not compatible with GCC (internal limitation)"); | 3476 | goto new_field; |
| 3369 | packwarn = 0; | 3477 | } |
| 3370 | } | 3478 | |
| 3371 | } | 3479 | /* in pcc mode, long long bitfields have type int if they fit */ |
| 3372 | } | 3480 | if (size == 8 && bit_size <= 32) { |
| 3373 | offset = c; | 3481 | f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT; |
| | 3482 | size = 4; |
| | 3483 | } |
| | 3484 | if (bit_pos >= size * 8) { |
| | 3485 | c += size; |
| | 3486 | bit_pos -= size * 8; |
| | 3487 | } |
| | 3488 | offset = c; |
| 3374 | /* In PCC layout named bit-fields influence the alignment | 3489 | /* In PCC layout named bit-fields influence the alignment |
| 3375 | of the containing struct using the base types alignment, | 3490 | of the containing struct using the base types alignment, |
| 3376 | except for packed fields (which here have correct | 3491 | except for packed fields (which here have correct align). */ |
| 3377 | align/typealign). */ | 3492 | if (f->v & SYM_FIRST_ANOM) |
| 3378 | if ((f->v & SYM_FIRST_ANOM)) | 3493 | align = 1; |
| 3379 | align = 1; | | |
| 3380 | } else { | 3494 | } else { |
| 3381 | bt = f->type.t & VT_BTYPE; | 3495 | bt = f->type.t & VT_BTYPE; |
| 3382 | if ((bit_pos + bit_size > size * 8) || | 3496 | if ((bit_pos + bit_size > size * 8) |
| 3383 | (bit_size > 0) == (bt != prevbt)) { | 3497 | || (bit_size > 0) == (bt != prevbt) |
| 3384 | c = (c + typealign - 1) & -typealign; | 3498 | ) { |
| | 3499 | c = (c + align - 1) & -align; |
| 3385 | offset = c; | 3500 | offset = c; |
| 3386 | bit_pos = 0; | 3501 | bit_pos = 0; |
| 3387 | /* In MS bitfield mode a bit-field run always uses | 3502 | /* In MS bitfield mode a bit-field run always uses |
| @@ -3389,34 +3504,33 @@ static void struct_layout(CType *type, AttributeDef *ad) · 1 unmodified line |
| 3389 | To start a new run it's also required that this | 3504 | To start a new run it's also required that this |
| 3390 | or the last bit-field had non-zero width. */ | 3505 | or the last bit-field had non-zero width. */ |
| 3391 | if (bit_size || prev_bit_size) | 3506 | if (bit_size || prev_bit_size) |
| 3392 | c += size; | 3507 | c += size; |
| 3393 | } | 3508 | } |
| 3394 | /* In MS layout the records alignment is normally | 3509 | /* In MS layout the records alignment is normally |
| 3395 | influenced by the field, except for a zero-width | 3510 | influenced by the field, except for a zero-width |
| 3396 | field at the start of a run (but by further zero-width | 3511 | field at the start of a run (but by further zero-width |
| 3397 | fields it is again). */ | 3512 | fields it is again). */ |
| 3398 | if (bit_size == 0 && prevbt != bt) | 3513 | if (bit_size == 0 && prevbt != bt) |
| 3399 | align = 1; | 3514 | align = 1; |
| 3400 | prevbt = bt; | 3515 | prevbt = bt; |
| 3401 | prev_bit_size = bit_size; | 3516 | prev_bit_size = bit_size; |
| 3402 | } | 3517 | } |
| | 3518 | |
| 3403 | f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT)) | 3519 | f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT)) |
| 3404 | | (bit_pos << VT_STRUCT_SHIFT); | 3520 | | (bit_pos << VT_STRUCT_SHIFT); |
| 3405 | bit_pos += bit_size; | 3521 | bit_pos += bit_size; |
| 3406 | if (pcc && bit_pos >= size * 8) { | | |
| 3407 | c += size; | | |
| 3408 | bit_pos -= size * 8; | | |
| 3409 | } | | |
| 3410 | } | 3522 | } |
| 3411 | if (align > maxalign) | 3523 | if (align > maxalign) |
| 3412 | maxalign = align; | 3524 | maxalign = align; |
| 3413 | #if 0 | 3525 | |
| 3414 | printf("set field %s offset=%d", | 3526 | #ifdef BF_DEBUG |
| 3415 | get_tok_str(f->v & ~SYM_FIELD, NULL), offset); | 3527 | printf("set field %s offset %-2d size %-2d align %-2d", |
| | 3528 | get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align); |
| 3416 | if (f->type.t & VT_BITFIELD) { | 3529 | if (f->type.t & VT_BITFIELD) { |
| 3417 | printf(" pos=%d size=%d", | 3530 | printf(" pos %-2d bits %-2d", |
| 3418 | (f->type.t >> VT_STRUCT_SHIFT) & 0x3f, | 3531 | BIT_POS(f->type.t), |
| 3419 | (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f); | 3532 | BIT_SIZE(f->type.t) |
| | 3533 | ); |
| 3420 | } | 3534 | } |
| 3421 | printf("\n"); | 3535 | printf("\n"); |
| 3422 | #endif | 3536 | #endif |
| @@ -3458,18 +3572,91 @@ static void struct_layout(CType *type, AttributeDef *ad) · 35 unmodified lines |
| 3458 | | 3572 | |
| 3459 | f->r = 0; | 3573 | f->r = 0; |
| 3460 | } | 3574 | } |
| | 3575 | |
| | 3576 | if (pcc) |
| | 3577 | c += (bit_pos + 7) >> 3; |
| | 3578 | |
| | 3579 | a = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 0; |
| | 3580 | if (a < maxalign) |
| | 3581 | a = maxalign; |
| | 3582 | c = (c + a - 1) & -a; |
| | 3583 | |
| 3461 | /* store size and alignment */ | 3584 | /* store size and alignment */ |
| 3462 | type->ref->c = (c + (pcc ? (bit_pos + 7) >> 3 : 0) | 3585 | type->ref->c = c; |
| 3463 | + maxalign - 1) & -maxalign; | 3586 | type->ref->r = a; |
| 3464 | type->ref->r = maxalign; | 3587 | |
| 3465 | if (offset + size > type->ref->c && type->ref->c) | 3588 | #ifdef BF_DEBUG |
| 3466 | tcc_warning("will touch memory past end of the struct (internal limitation)"); | 3589 | printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout); |
| | 3590 | #endif |
| | 3591 | |
| | 3592 | /* check whether we can access bitfields by their type */ |
| | 3593 | for (f = type->ref->next; f; f = f->next) { |
| | 3594 | int s, px, cx, c0; |
| | 3595 | CType t; |
| | 3596 | |
| | 3597 | if (0 == (f->type.t & VT_BITFIELD)) |
| | 3598 | continue; |
| | 3599 | f->type.ref = f; |
| | 3600 | f->auxtype = -1; |
| | 3601 | bit_size = BIT_SIZE(f->type.t); |
| | 3602 | if (bit_size == 0) |
| | 3603 | continue; |
| | 3604 | bit_pos = BIT_POS(f->type.t); |
| | 3605 | size = type_size(&f->type, &align); |
| | 3606 | |
| | 3607 | if (bit_pos + bit_size <= size * 8 && f->c + size <= c) |
| | 3608 | continue; |
| | 3609 | |
| | 3610 | /* try to access the field using a differnt type */ |
| | 3611 | c0 = -1, s = align = 1; |
| | 3612 | for (;;) { |
| | 3613 | px = f->c * 8 + bit_pos; |
| | 3614 | cx = (px >> 3) & -align; |
| | 3615 | px = px - (cx << 3); |
| | 3616 | if (c0 == cx) |
| | 3617 | break; |
| | 3618 | s = (px + bit_size + 7) >> 3; |
| | 3619 | if (s > 4) { |
| | 3620 | t.t = VT_LLONG; |
| | 3621 | } else if (s > 2) { |
| | 3622 | t.t = VT_INT; |
| | 3623 | } else if (s > 1) { |
| | 3624 | t.t = VT_SHORT; |
| | 3625 | } else { |
| | 3626 | t.t = VT_BYTE; |
| | 3627 | } |
| | 3628 | s = type_size(&t, &align); |
| | 3629 | c0 = cx; |
| | 3630 | } |
| | 3631 | |
| | 3632 | if (px + bit_size <= s * 8 && cx + s <= c) { |
| | 3633 | /* update offset and bit position */ |
| | 3634 | f->c = cx; |
| | 3635 | bit_pos = px; |
| | 3636 | f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT)) |
| | 3637 | | (bit_pos << VT_STRUCT_SHIFT); |
| | 3638 | if (s != size) |
| | 3639 | f->auxtype = t.t; |
| | 3640 | } else { |
| | 3641 | /* fall back to load/store single-byte wise */ |
| | 3642 | f->auxtype = VT_STRUCT; |
| | 3643 | } |
| | 3644 | |
| | 3645 | #ifdef BF_DEBUG |
| | 3646 | printf("FIX field %s offset %-2d size %-2d align %-2d " |
| | 3647 | "pos %-2d bits %-2d %s\n", |
| | 3648 | get_tok_str(f->v & ~SYM_FIELD, NULL), |
| | 3649 | cx, s, align, px, bit_size, |
| | 3650 | f->auxtype == VT_PTR ? " byte-wise" : "" |
| | 3651 | ); |
| | 3652 | #endif |
| | 3653 | } |
| 3467 | } | 3654 | } |
| 3468 | | 3655 | |
| 3469 | /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */ | 3656 | /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */ |
| 3470 | static void struct_decl(CType *type, int u) | 3657 | static void struct_decl(CType *type, int u) |
| 3471 | { | 3658 | { |
| 3472 | int v, c, size, align, flexible, alignoverride; | 3659 | int v, c, size, align, flexible; |
| 3473 | int bit_size, bsize, bt; | 3660 | int bit_size, bsize, bt; |
| 3474 | Sym *s, *ss, **ps; | 3661 | Sym *s, *ss, **ps; |
| 3475 | AttributeDef ad, ad1; | 3662 | AttributeDef ad, ad1; |
| @@ -3623,17 +3810,6 @@ do_decl: · 147 unmodified lines |
| 3623 | parse_attribute(&ad1); | 3810 | parse_attribute(&ad1); |
| 3624 | } | 3811 | } |
| 3625 | size = type_size(&type1, &align); | 3812 | size = type_size(&type1, &align); |
| 3626 | /* Only remember non-default alignment. */ | | |
| 3627 | alignoverride = 0; | | |
| 3628 | if (ad1.a.aligned) { | | |
| 3629 | int speca = 1 << (ad1.a.aligned - 1); | | |
| 3630 | alignoverride = speca; | | |
| 3631 | } else if (ad1.a.packed || ad.a.packed) { | | |
| 3632 | alignoverride = 1; | | |
| 3633 | } else if (*tcc_state->pack_stack_ptr) { | | |
| 3634 | if (align >= *tcc_state->pack_stack_ptr) | | |
| 3635 | alignoverride = *tcc_state->pack_stack_ptr; | | |
| 3636 | } | | |
| 3637 | if (bit_size >= 0) { | 3813 | if (bit_size >= 0) { |
| 3638 | bt = type1.t & VT_BTYPE; | 3814 | bt = type1.t & VT_BTYPE; |
| 3639 | if (bt != VT_INT && | 3815 | if (bt != VT_INT && |
| @@ -3646,9 +3822,12 @@ do_decl: · 6 unmodified lines |
| 3646 | if (bit_size > bsize) { | 3822 | if (bit_size > bsize) { |
| 3647 | tcc_error("width of '%s' exceeds its type", | 3823 | tcc_error("width of '%s' exceeds its type", |
| 3648 | get_tok_str(v, NULL)); | 3824 | get_tok_str(v, NULL)); |
| 3649 | } else if (bit_size == bsize) { | 3825 | } else if (bit_size == bsize |
| | 3826 | && !ad.a.packed && !ad1.a.packed) { |
| 3650 | /* no need for bit fields */ | 3827 | /* no need for bit fields */ |
| 3651 | ; | 3828 | ; |
| | 3829 | } else if (bit_size == 64) { |
| | 3830 | tcc_error("field width 64 not implemented"); |
| 3652 | } else { | 3831 | } else { |
| 3653 | type1.t = (type1.t & ~VT_STRUCT_MASK) | 3832 | type1.t = (type1.t & ~VT_STRUCT_MASK) |
| 3654 | | VT_BITFIELD | 3833 | | VT_BITFIELD |
| @@ -3668,7 +3847,8 @@ do_decl: · 13 unmodified lines |
| 3668 | v = anon_sym++; | 3847 | v = anon_sym++; |
| 3669 | } | 3848 | } |
| 3670 | if (v) { | 3849 | if (v) { |
| 3671 | ss = sym_push(v | SYM_FIELD, &type1, alignoverride, 0); | 3850 | ss = sym_push(v | SYM_FIELD, &type1, 0, 0); |
| | 3851 | ss->a = ad1.a; |
| 3672 | *ps = ss; | 3852 | *ps = ss; |
| 3673 | ps = &ss->next; | 3853 | ps = &ss->next; |
| 3674 | } | 3854 | } |
| @@ -4495,7 +4675,10 @@ ST_FUNC void unary(void) · 820 unmodified lines |
| 4495 | next(); | 4675 | next(); |
| 4496 | in_sizeof++; | 4676 | in_sizeof++; |
| 4497 | expr_type(&type, 1); // Perform a in_sizeof = 0; | 4677 | expr_type(&type, 1); // Perform a in_sizeof = 0; |
| | 4678 | s = vtop[1].sym; /* hack: accessing previous vtop */ |
| 4498 | size = type_size(&type, &align); | 4679 | size = type_size(&type, &align); |
| | 4680 | if (s && s->a.aligned) |
| | 4681 | align = 1 << (s->a.aligned - 1); |
| 4499 | if (t == TOK_SIZEOF) { | 4682 | if (t == TOK_SIZEOF) { |
| 4500 | if (!(type.t & VT_VLA)) { | 4683 | if (!(type.t & VT_VLA)) { |
| 4501 | if (size < 0) | 4684 | if (size < 0) |
| @@ -6140,9 +6323,8 @@ static int decl_designator(CType *type, Section *sec, unsigned long c, · 1638 unmodified lines |
| 6140 | /* store a value or an expression directly in global data or in local array */ | 6323 | /* store a value or an expression directly in global data or in local array */ |
| 6141 | static void init_putv(CType *type, Section *sec, unsigned long c) | 6324 | static void init_putv(CType *type, Section *sec, unsigned long c) |
| 6142 | { | 6325 | { |
| 6143 | int bt, bit_pos, bit_size; | 6326 | int bt; |
| 6144 | void *ptr; | 6327 | void *ptr; |
| 6145 | unsigned long long bit_mask; | | |
| 6146 | CType dtype; | 6328 | CType dtype; |
| 6147 | | 6329 | |
| 6148 | dtype = *type; | 6330 | dtype = *type; |
| @@ -6158,15 +6340,6 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 9 unmodified lines |
| 6158 | section_reserve(sec, c + size); | 6340 | section_reserve(sec, c + size); |
| 6159 | ptr = sec->data + c; | 6341 | ptr = sec->data + c; |
| 6160 | /* XXX: make code faster ? */ | 6342 | /* XXX: make code faster ? */ |
| 6161 | if (!(type->t & VT_BITFIELD)) { | | |
| 6162 | bit_pos = 0; | | |
| 6163 | bit_size = PTR_SIZE * 8; | | |
| 6164 | bit_mask = -1LL; | | |
| 6165 | } else { | | |
| 6166 | bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; | | |
| 6167 | bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; | | |
| 6168 | bit_mask = (1LL << bit_size) - 1; | | |
| 6169 | } | | |
| 6170 | if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) && | 6343 | if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) && |
| 6171 | vtop->sym->v >= SYM_FIRST_ANOM && | 6344 | vtop->sym->v >= SYM_FIRST_ANOM && |
| 6172 | /* XXX This rejects compound literals like | 6345 | /* XXX This rejects compound literals like |
| @@ -6219,31 +6392,48 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 46 unmodified lines |
| 6219 | } | 6392 | } |
| 6220 | } | 6393 | } |
| 6221 | } else { | 6394 | } else { |
| 6222 | if ((vtop->r & VT_SYM) && | 6395 | if ((vtop->r & VT_SYM) && |
| 6223 | (bt == VT_BYTE || | 6396 | (bt == VT_BYTE || |
| 6224 | bt == VT_SHORT || | 6397 | bt == VT_SHORT || |
| 6225 | bt == VT_DOUBLE || | 6398 | bt == VT_DOUBLE || |
| 6226 | bt == VT_LDOUBLE || | 6399 | bt == VT_LDOUBLE || |
| 6227 | #if PTR_SIZE == 8 | 6400 | #if PTR_SIZE == 8 |
| 6228 | (bt == VT_LLONG && bit_size != 64) || | 6401 | bt == VT_INT || |
| 6229 | bt == VT_INT | | |
| 6230 | #else | 6402 | #else |
| 6231 | bt == VT_LLONG || | 6403 | bt == VT_LLONG || |
| 6232 | (bt == VT_INT && bit_size != 32) | | |
| 6233 | #endif | 6404 | #endif |
| | 6405 | (type->t & VT_BITFIELD) |
| 6234 | )) | 6406 | )) |
| 6235 | tcc_error("initializer element is not computable at load time"); | 6407 | tcc_error("initializer element is not computable at load time"); |
| 6236 | switch(bt) { | 6408 | |
| | 6409 | if (type->t & VT_BITFIELD) { |
| | 6410 | int bit_pos, bit_size, bits, n; |
| | 6411 | unsigned char *p, v, m; |
| | 6412 | bit_pos = BIT_POS(vtop->type.t); |
| | 6413 | bit_size = BIT_SIZE(vtop->type.t); |
| | 6414 | p = (unsigned char*)ptr + (bit_pos >> 3); |
| | 6415 | bit_pos &= 7, bits = 0; |
| | 6416 | while (bit_size) { |
| | 6417 | n = 8 - bit_pos; |
| | 6418 | if (n > bit_size) |
| | 6419 | n = bit_size; |
| | 6420 | v = vtop->c.i >> bits << bit_pos; |
| | 6421 | m = ((1 << n) - 1) << bit_pos; |
| | 6422 | *p = (*p & ~m) | (v & m); |
| | 6423 | bits += n, bit_size -= n, bit_pos = 0, ++p; |
| | 6424 | } |
| | 6425 | } else |
| | 6426 | switch(bt) { |
| 6237 | /* XXX: when cross-compiling we assume that each type has the | 6427 | /* XXX: when cross-compiling we assume that each type has the |
| 6238 | same representation on host and target, which is likely to | 6428 | same representation on host and target, which is likely to |
| 6239 | be wrong in the case of long double */ | 6429 | be wrong in the case of long double */ |
| 6240 | case VT_BOOL: | 6430 | case VT_BOOL: |
| 6241 | vtop->c.i = (vtop->c.i != 0); | 6431 | vtop->c.i = vtop->c.i != 0; |
| 6242 | case VT_BYTE: | 6432 | case VT_BYTE: |
| 6243 | *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; | 6433 | *(char *)ptr |= vtop->c.i; |
| 6244 | break; | 6434 | break; |
| 6245 | case VT_SHORT: | 6435 | case VT_SHORT: |
| 6246 | *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; | 6436 | *(short *)ptr |= vtop->c.i; |
| 6247 | break; | 6437 | break; |
| 6248 | case VT_FLOAT: | 6438 | case VT_FLOAT: |
| 6249 | *(float*)ptr = vtop->c.f; | 6439 | *(float*)ptr = vtop->c.f; |
| @@ -6270,14 +6460,14 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 20 unmodified lines |
| 6270 | break; | 6460 | break; |
| 6271 | #if PTR_SIZE != 8 | 6461 | #if PTR_SIZE != 8 |
| 6272 | case VT_LLONG: | 6462 | case VT_LLONG: |
| 6273 | *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos; | 6463 | *(long long *)ptr |= vtop->c.i; |
| 6274 | break; | 6464 | break; |
| 6275 | #else | 6465 | #else |
| 6276 | case VT_LLONG: | 6466 | case VT_LLONG: |
| 6277 | #endif | 6467 | #endif |
| 6278 | case VT_PTR: | 6468 | case VT_PTR: |
| 6279 | { | 6469 | { |
| 6280 | addr_t val = (vtop->c.i & bit_mask) << bit_pos; | 6470 | addr_t val = vtop->c.i; |
| 6281 | #if PTR_SIZE == 8 | 6471 | #if PTR_SIZE == 8 |
| 6282 | if (vtop->r & VT_SYM) | 6472 | if (vtop->r & VT_SYM) |
| 6283 | greloca(sec, vtop->sym, c, R_DATA_PTR, val); | 6473 | greloca(sec, vtop->sym, c, R_DATA_PTR, val); |
| @@ -6292,7 +6482,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 8 unmodified lines |
| 6292 | } | 6482 | } |
| 6293 | default: | 6483 | default: |
| 6294 | { | 6484 | { |
| 6295 | int val = (vtop->c.i & bit_mask) << bit_pos; | 6485 | int val = vtop->c.i; |
| 6296 | #if PTR_SIZE == 8 | 6486 | #if PTR_SIZE == 8 |
| 6297 | if (vtop->r & VT_SYM) | 6487 | if (vtop->r & VT_SYM) |
| 6298 | greloca(sec, vtop->sym, c, R_DATA_PTR, val); | 6488 | greloca(sec, vtop->sym, c, R_DATA_PTR, val); |