00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #include "system.h"
00029 #include "coretypes.h"
00030 #include "tm.h"
00031 #include "tree.h"
00032 #include "rtl.h"
00033 #include "tm_p.h"
00034 #include "flags.h"
00035 #include "function.h"
00036 #include "expr.h"
00037 #include "toplev.h"
00038 #include "ggc.h"
00039 #include "target.h"
00040 #include "langhooks.h"
00041 #include "regs.h"
00042 #include "params.h"
00043
00044
00045
00046 tree sizetype_tab[(int) TYPE_KIND_LAST];
00047
00048
00049
00050 unsigned int maximum_field_alignment = TARGET_DEFAULT_PACK_STRUCT * BITS_PER_UNIT;
00051
00052 unsigned int initial_max_fld_align = TARGET_DEFAULT_PACK_STRUCT;
00053
00054
00055
00056 unsigned int set_alignment = 0;
00057
00058
00059
00060
00061 static int reference_types_internal = 0;
00062
00063 static void finalize_record_size (record_layout_info);
00064 static void finalize_type_size (tree);
00065 static void place_union_field (record_layout_info, tree);
00066 #if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
00067 static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
00068 HOST_WIDE_INT, tree);
00069 #endif
00070 extern void debug_rli (record_layout_info);
00071
00072
00073
00074 static GTY(()) tree pending_sizes;
00075
00076
00077
00078
00079 void
00080 internal_reference_types (void)
00081 {
00082 reference_types_internal = 1;
00083 }
00084
00085
00086
00087 tree
00088 get_pending_sizes (void)
00089 {
00090 tree chain = pending_sizes;
00091
00092 pending_sizes = 0;
00093 return chain;
00094 }
00095
00096
00097
00098 void
00099 put_pending_size (tree expr)
00100 {
00101
00102
00103 expr = skip_simple_arithmetic (expr);
00104
00105 if (TREE_CODE (expr) == SAVE_EXPR)
00106 pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes);
00107 }
00108
00109
00110
00111
00112 void
00113 put_pending_sizes (tree chain)
00114 {
00115 gcc_assert (!pending_sizes);
00116 pending_sizes = chain;
00117 }
00118
00119
00120
00121
00122 tree
00123 variable_size (tree size)
00124 {
00125 tree save;
00126
00127
00128
00129
00130
00131 if (TREE_CONSTANT (size)
00132 || lang_hooks.decls.global_bindings_p () < 0
00133 || CONTAINS_PLACEHOLDER_P (size))
00134 return size;
00135
00136 size = save_expr (size);
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 save = skip_simple_arithmetic (size);
00147
00148 if (cfun && cfun->x_dont_save_pending_sizes_p)
00149
00150
00151 return size;
00152
00153 if (lang_hooks.decls.global_bindings_p ())
00154 {
00155 if (TREE_CONSTANT (size))
00156 error ("type size can%'t be explicitly evaluated");
00157 else
00158 error ("variable-size type declared outside of any function");
00159
00160 return size_one_node;
00161 }
00162
00163 put_pending_size (save);
00164
00165 return size;
00166 }
00167
00168 #ifndef MAX_FIXED_MODE_SIZE
00169 #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
00170 #endif
00171
00172
00173
00174
00175
00176
00177 enum machine_mode
00178 mode_for_size (unsigned int size, enum mode_class class, int limit)
00179 {
00180 enum machine_mode mode;
00181
00182 if (limit && size > MAX_FIXED_MODE_SIZE)
00183 return BLKmode;
00184
00185
00186 for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
00187 mode = GET_MODE_WIDER_MODE (mode))
00188 if (GET_MODE_PRECISION (mode) == size)
00189 return mode;
00190
00191 return BLKmode;
00192 }
00193
00194
00195
00196 enum machine_mode
00197 mode_for_size_tree (tree size, enum mode_class class, int limit)
00198 {
00199 if (TREE_CODE (size) != INTEGER_CST
00200 || TREE_OVERFLOW (size)
00201
00202
00203
00204 || compare_tree_int (size, 1000) > 0)
00205 return BLKmode;
00206 else
00207 return mode_for_size (tree_low_cst (size, 1), class, limit);
00208 }
00209
00210
00211
00212
00213 enum machine_mode
00214 smallest_mode_for_size (unsigned int size, enum mode_class class)
00215 {
00216 enum machine_mode mode;
00217
00218
00219
00220 for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
00221 mode = GET_MODE_WIDER_MODE (mode))
00222 if (GET_MODE_PRECISION (mode) >= size)
00223 return mode;
00224
00225 gcc_unreachable ();
00226 }
00227
00228
00229
00230 enum machine_mode
00231 int_mode_for_mode (enum machine_mode mode)
00232 {
00233 switch (GET_MODE_CLASS (mode))
00234 {
00235 case MODE_INT:
00236 case MODE_PARTIAL_INT:
00237 break;
00238
00239 case MODE_COMPLEX_INT:
00240 case MODE_COMPLEX_FLOAT:
00241 case MODE_FLOAT:
00242 case MODE_VECTOR_INT:
00243 case MODE_VECTOR_FLOAT:
00244 mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
00245 break;
00246
00247 case MODE_RANDOM:
00248 if (mode == BLKmode)
00249 break;
00250
00251
00252
00253 case MODE_CC:
00254 default:
00255 gcc_unreachable ();
00256 }
00257
00258 return mode;
00259 }
00260
00261
00262
00263
00264 unsigned int
00265 get_mode_alignment (enum machine_mode mode)
00266 {
00267 return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
00268 }
00269
00270
00271
00272
00273
00274 static inline void
00275 do_type_align (tree type, tree decl)
00276 {
00277 if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
00278 {
00279 DECL_ALIGN (decl) = TYPE_ALIGN (type);
00280 if (TREE_CODE (decl) == FIELD_DECL)
00281 DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 void
00299 layout_decl (tree decl, unsigned int known_align)
00300 {
00301 tree type = TREE_TYPE (decl);
00302 enum tree_code code = TREE_CODE (decl);
00303 rtx rtl = NULL_RTX;
00304
00305 if (code == CONST_DECL)
00306 return;
00307
00308 gcc_assert (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL
00309 || code == TYPE_DECL ||code == FIELD_DECL);
00310
00311 rtl = DECL_RTL_IF_SET (decl);
00312
00313 if (type == error_mark_node)
00314 type = void_type_node;
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 DECL_UNSIGNED (decl) = TYPE_UNSIGNED (type);
00327 if (DECL_MODE (decl) == VOIDmode)
00328 DECL_MODE (decl) = TYPE_MODE (type);
00329
00330 if (DECL_SIZE (decl) == 0)
00331 {
00332 DECL_SIZE (decl) = TYPE_SIZE (type);
00333 DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
00334 }
00335 else if (DECL_SIZE_UNIT (decl) == 0)
00336 DECL_SIZE_UNIT (decl)
00337 = fold_convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
00338 bitsize_unit_node));
00339
00340 if (code != FIELD_DECL)
00341
00342 do_type_align (type, decl);
00343 else
00344
00345 {
00346 bool old_user_align = DECL_USER_ALIGN (decl);
00347
00348 if (DECL_BIT_FIELD (decl))
00349 {
00350 DECL_BIT_FIELD_TYPE (decl) = type;
00351
00352
00353
00354 if (integer_zerop (DECL_SIZE (decl))
00355 && ! DECL_PACKED (decl)
00356 && ! targetm.ms_bitfield_layout_p (DECL_FIELD_CONTEXT (decl)))
00357 {
00358 #ifdef PCC_BITFIELD_TYPE_MATTERS
00359 if (PCC_BITFIELD_TYPE_MATTERS)
00360 do_type_align (type, decl);
00361 else
00362 #endif
00363 {
00364 #ifdef EMPTY_FIELD_BOUNDARY
00365 if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
00366 {
00367 DECL_ALIGN (decl) = EMPTY_FIELD_BOUNDARY;
00368 DECL_USER_ALIGN (decl) = 0;
00369 }
00370 #endif
00371 }
00372 }
00373
00374
00375
00376
00377 if (TYPE_SIZE (type) != 0
00378 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
00379 && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
00380 {
00381 enum machine_mode xmode
00382 = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
00383
00384 if (xmode != BLKmode
00385 && (known_align == 0
00386 || known_align >= GET_MODE_ALIGNMENT (xmode)))
00387 {
00388 DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
00389 DECL_ALIGN (decl));
00390 DECL_MODE (decl) = xmode;
00391 DECL_BIT_FIELD (decl) = 0;
00392 }
00393 }
00394
00395
00396 if (TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
00397 && known_align >= TYPE_ALIGN (type)
00398 && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
00399 DECL_BIT_FIELD (decl) = 0;
00400 }
00401 else if (DECL_PACKED (decl) && DECL_USER_ALIGN (decl))
00402
00403
00404
00405 ;
00406 else
00407 do_type_align (type, decl);
00408
00409
00410
00411
00412
00413
00414
00415
00416 if (DECL_PACKED (decl)
00417 && !old_user_align
00418 && (DECL_NONADDRESSABLE_P (decl)
00419 || DECL_SIZE_UNIT (decl) == 0
00420 || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
00421 DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
00422
00423 if (! DECL_USER_ALIGN (decl) && ! DECL_PACKED (decl))
00424 {
00425
00426
00427
00428 #ifdef BIGGEST_FIELD_ALIGNMENT
00429 DECL_ALIGN (decl)
00430 = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT);
00431 #endif
00432 #ifdef ADJUST_FIELD_ALIGN
00433 DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
00434 #endif
00435 }
00436
00437
00438 if (maximum_field_alignment != 0)
00439 DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
00440 }
00441
00442
00443 if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
00444 DECL_SIZE (decl) = variable_size (DECL_SIZE (decl));
00445 if (DECL_SIZE_UNIT (decl) != 0
00446 && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST)
00447 DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl));
00448
00449
00450 if (warn_larger_than
00451 && (code == VAR_DECL || code == PARM_DECL)
00452 && ! DECL_EXTERNAL (decl))
00453 {
00454 tree size = DECL_SIZE_UNIT (decl);
00455
00456 if (size != 0 && TREE_CODE (size) == INTEGER_CST
00457 && compare_tree_int (size, larger_than_size) > 0)
00458 {
00459 int size_as_int = TREE_INT_CST_LOW (size);
00460
00461 if (compare_tree_int (size, size_as_int) == 0)
00462 warning ("%Jsize of %qD is %d bytes", decl, decl, size_as_int);
00463 else
00464 warning ("%Jsize of %qD is larger than %d bytes",
00465 decl, decl, larger_than_size);
00466 }
00467 }
00468
00469
00470 if (rtl)
00471 {
00472 PUT_MODE (rtl, DECL_MODE (decl));
00473 SET_DECL_RTL (decl, 0);
00474 set_mem_attributes (rtl, decl, 1);
00475 SET_DECL_RTL (decl, rtl);
00476 }
00477 }
00478
00479
00480
00481
00482 void
00483 relayout_decl (tree decl)
00484 {
00485 DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = 0;
00486 DECL_MODE (decl) = VOIDmode;
00487 DECL_ALIGN (decl) = 0;
00488 SET_DECL_RTL (decl, 0);
00489
00490 layout_decl (decl, 0);
00491 }
00492
00493
00494
00495
00496 void (*lang_adjust_rli) (record_layout_info) = 0;
00497
00498 void
00499 set_lang_adjust_rli (void (*f) (record_layout_info))
00500 {
00501 lang_adjust_rli = f;
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511 record_layout_info
00512 start_record_layout (tree t)
00513 {
00514 record_layout_info rli = xmalloc (sizeof (struct record_layout_info_s));
00515
00516 rli->t = t;
00517
00518
00519
00520
00521 rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));
00522 rli->unpacked_align = rli->record_align;
00523 rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);
00524
00525 #ifdef STRUCTURE_SIZE_BOUNDARY
00526
00527 if (! TYPE_PACKED (t))
00528 rli->record_align = MAX (rli->record_align, (unsigned) STRUCTURE_SIZE_BOUNDARY);
00529 #endif
00530
00531 rli->offset = size_zero_node;
00532 rli->bitpos = bitsize_zero_node;
00533 rli->prev_field = 0;
00534 rli->pending_statics = 0;
00535 rli->packed_maybe_necessary = 0;
00536
00537 return rli;
00538 }
00539
00540
00541
00542
00543 tree
00544 bit_from_pos (tree offset, tree bitpos)
00545 {
00546 return size_binop (PLUS_EXPR, bitpos,
00547 size_binop (MULT_EXPR,
00548 fold_convert (bitsizetype, offset),
00549 bitsize_unit_node));
00550 }
00551
00552 tree
00553 byte_from_pos (tree offset, tree bitpos)
00554 {
00555 return size_binop (PLUS_EXPR, offset,
00556 fold_convert (sizetype,
00557 size_binop (TRUNC_DIV_EXPR, bitpos,
00558 bitsize_unit_node)));
00559 }
00560
00561 void
00562 pos_from_bit (tree *poffset, tree *pbitpos, unsigned int off_align,
00563 tree pos)
00564 {
00565 *poffset = size_binop (MULT_EXPR,
00566 fold_convert (sizetype,
00567 size_binop (FLOOR_DIV_EXPR, pos,
00568 bitsize_int (off_align))),
00569 size_int (off_align / BITS_PER_UNIT));
00570 *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, bitsize_int (off_align));
00571 }
00572
00573
00574
00575
00576 void
00577 normalize_offset (tree *poffset, tree *pbitpos, unsigned int off_align)
00578 {
00579
00580
00581 if (compare_tree_int (*pbitpos, off_align) >= 0)
00582 {
00583 tree extra_aligns = size_binop (FLOOR_DIV_EXPR, *pbitpos,
00584 bitsize_int (off_align));
00585
00586 *poffset
00587 = size_binop (PLUS_EXPR, *poffset,
00588 size_binop (MULT_EXPR,
00589 fold_convert (sizetype, extra_aligns),
00590 size_int (off_align / BITS_PER_UNIT)));
00591
00592 *pbitpos
00593 = size_binop (FLOOR_MOD_EXPR, *pbitpos, bitsize_int (off_align));
00594 }
00595 }
00596
00597
00598
00599 void
00600 debug_rli (record_layout_info rli)
00601 {
00602 print_node_brief (stderr, "type", rli->t, 0);
00603 print_node_brief (stderr, "\noffset", rli->offset, 0);
00604 print_node_brief (stderr, " bitpos", rli->bitpos, 0);
00605
00606 fprintf (stderr, "\naligns: rec = %u, unpack = %u, off = %u\n",
00607 rli->record_align, rli->unpacked_align,
00608 rli->offset_align);
00609 if (rli->packed_maybe_necessary)
00610 fprintf (stderr, "packed may be necessary\n");
00611
00612 if (rli->pending_statics)
00613 {
00614 fprintf (stderr, "pending statics:\n");
00615 debug_tree (rli->pending_statics);
00616 }
00617 }
00618
00619
00620
00621
00622 void
00623 normalize_rli (record_layout_info rli)
00624 {
00625 normalize_offset (&rli->offset, &rli->bitpos, rli->offset_align);
00626 }
00627
00628
00629
00630 tree
00631 rli_size_unit_so_far (record_layout_info rli)
00632 {
00633 return byte_from_pos (rli->offset, rli->bitpos);
00634 }
00635
00636
00637
00638 tree
00639 rli_size_so_far (record_layout_info rli)
00640 {
00641 return bit_from_pos (rli->offset, rli->bitpos);
00642 }
00643
00644
00645
00646
00647
00648
00649 unsigned int
00650 update_alignment_for_field (record_layout_info rli, tree field,
00651 unsigned int known_align)
00652 {
00653
00654 unsigned int desired_align;
00655
00656 tree type = TREE_TYPE (field);
00657
00658 bool user_align;
00659 bool is_bitfield;
00660
00661
00662 layout_decl (field, known_align);
00663 desired_align = DECL_ALIGN (field);
00664 user_align = DECL_USER_ALIGN (field);
00665
00666 is_bitfield = (type != error_mark_node
00667 && DECL_BIT_FIELD_TYPE (field)
00668 && ! integer_zerop (TYPE_SIZE (type)));
00669
00670
00671
00672
00673 if (is_bitfield && targetm.ms_bitfield_layout_p (rli->t))
00674 {
00675
00676
00677
00678
00679
00680
00681 if (! integer_zerop (DECL_SIZE (field))
00682 ? ! DECL_PACKED (field)
00683 : (rli->prev_field
00684 && DECL_BIT_FIELD_TYPE (rli->prev_field)
00685 && ! integer_zerop (DECL_SIZE (rli->prev_field))))
00686 {
00687 unsigned int type_align = TYPE_ALIGN (type);
00688 type_align = MAX (type_align, desired_align);
00689 if (maximum_field_alignment != 0)
00690 type_align = MIN (type_align, maximum_field_alignment);
00691 rli->record_align = MAX (rli->record_align, type_align);
00692 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
00693 }
00694 }
00695 #ifdef PCC_BITFIELD_TYPE_MATTERS
00696 else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
00697 {
00698
00699
00700
00701 if (DECL_NAME (field) != 0
00702 || targetm.align_anon_bitfield ())
00703 {
00704 unsigned int type_align = TYPE_ALIGN (type);
00705
00706 #ifdef ADJUST_FIELD_ALIGN
00707 if (! TYPE_USER_ALIGN (type))
00708 type_align = ADJUST_FIELD_ALIGN (field, type_align);
00709 #endif
00710
00711 if (maximum_field_alignment != 0)
00712 type_align = MIN (type_align, maximum_field_alignment);
00713 else if (DECL_PACKED (field))
00714 type_align = MIN (type_align, BITS_PER_UNIT);
00715
00716
00717
00718
00719
00720
00721 rli->record_align = MAX (rli->record_align, desired_align);
00722 rli->record_align = MAX (rli->record_align, type_align);
00723
00724 if (warn_packed)
00725 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
00726 user_align |= TYPE_USER_ALIGN (type);
00727 }
00728 }
00729 #endif
00730 else
00731 {
00732 rli->record_align = MAX (rli->record_align, desired_align);
00733 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
00734 }
00735
00736 TYPE_USER_ALIGN (rli->t) |= user_align;
00737
00738 return desired_align;
00739 }
00740
00741
00742
00743 static void
00744 place_union_field (record_layout_info rli, tree field)
00745 {
00746 update_alignment_for_field (rli, field, 0);
00747
00748 DECL_FIELD_OFFSET (field) = size_zero_node;
00749 DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
00750 SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
00751
00752
00753
00754 if (TREE_CODE (rli->t) == UNION_TYPE)
00755 rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
00756 else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
00757 rli->offset = fold (build3 (COND_EXPR, sizetype,
00758 DECL_QUALIFIER (field),
00759 DECL_SIZE_UNIT (field), rli->offset));
00760 }
00761
00762 #if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
00763
00764
00765
00766 static int
00767 excess_unit_span (HOST_WIDE_INT byte_offset, HOST_WIDE_INT bit_offset,
00768 HOST_WIDE_INT size, HOST_WIDE_INT align, tree type)
00769 {
00770
00771
00772 unsigned HOST_WIDE_INT offset = byte_offset * BITS_PER_UNIT + bit_offset;
00773
00774 offset = offset % align;
00775 return ((offset + size + align - 1) / align
00776 > ((unsigned HOST_WIDE_INT) tree_low_cst (TYPE_SIZE (type), 1)
00777 / align));
00778 }
00779 #endif
00780
00781
00782
00783
00784
00785
00786 void
00787 place_field (record_layout_info rli, tree field)
00788 {
00789
00790 unsigned int desired_align;
00791
00792
00793 unsigned int known_align;
00794 unsigned int actual_align;
00795
00796 tree type = TREE_TYPE (field);
00797
00798 if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
00799 return;
00800
00801
00802
00803
00804
00805 if (TREE_CODE (field) == VAR_DECL)
00806 {
00807 rli->pending_statics = tree_cons (NULL_TREE, field,
00808 rli->pending_statics);
00809 return;
00810 }
00811
00812
00813
00814 else if (TREE_CODE (field) != FIELD_DECL)
00815 return;
00816
00817
00818
00819 else if (TREE_CODE (rli->t) != RECORD_TYPE)
00820 {
00821 place_union_field (rli, field);
00822 return;
00823 }
00824
00825
00826
00827 if (! integer_zerop (rli->bitpos))
00828 known_align = (tree_low_cst (rli->bitpos, 1)
00829 & - tree_low_cst (rli->bitpos, 1));
00830 else if (integer_zerop (rli->offset))
00831 known_align = BIGGEST_ALIGNMENT;
00832 else if (host_integerp (rli->offset, 1))
00833 known_align = (BITS_PER_UNIT
00834 * (tree_low_cst (rli->offset, 1)
00835 & - tree_low_cst (rli->offset, 1)));
00836 else
00837 known_align = rli->offset_align;
00838
00839 desired_align = update_alignment_for_field (rli, field, known_align);
00840
00841 if (warn_packed && DECL_PACKED (field))
00842 {
00843 if (known_align >= TYPE_ALIGN (type))
00844 {
00845 if (TYPE_ALIGN (type) > desired_align)
00846 {
00847 if (STRICT_ALIGNMENT)
00848 warning ("%Jpacked attribute causes inefficient alignment "
00849 "for %qD", field, field);
00850 else
00851 warning ("%Jpacked attribute is unnecessary for %qD",
00852 field, field);
00853 }
00854 }
00855 else
00856 rli->packed_maybe_necessary = 1;
00857 }
00858
00859
00860
00861 if (known_align < desired_align)
00862 {
00863
00864
00865
00866 if (warn_padded)
00867 warning ("%Jpadding struct to align %qD", field, field);
00868
00869
00870
00871 if (desired_align < rli->offset_align)
00872 rli->bitpos = round_up (rli->bitpos, desired_align);
00873 else
00874 {
00875
00876 rli->offset
00877 = size_binop (PLUS_EXPR, rli->offset,
00878 fold_convert (sizetype,
00879 size_binop (CEIL_DIV_EXPR, rli->bitpos,
00880 bitsize_unit_node)));
00881 rli->bitpos = bitsize_zero_node;
00882
00883 rli->offset = round_up (rli->offset, desired_align / BITS_PER_UNIT);
00884 }
00885
00886 if (! TREE_CONSTANT (rli->offset))
00887 rli->offset_align = desired_align;
00888
00889 }
00890
00891
00892
00893 #ifdef PCC_BITFIELD_TYPE_MATTERS
00894 if (PCC_BITFIELD_TYPE_MATTERS
00895 && ! targetm.ms_bitfield_layout_p (rli->t)
00896 && TREE_CODE (field) == FIELD_DECL
00897 && type != error_mark_node
00898 && DECL_BIT_FIELD (field)
00899 && ! DECL_PACKED (field)
00900 && maximum_field_alignment == 0
00901 && ! integer_zerop (DECL_SIZE (field))
00902 && host_integerp (DECL_SIZE (field), 1)
00903 && host_integerp (rli->offset, 1)
00904 && host_integerp (TYPE_SIZE (type), 1))
00905 {
00906 unsigned int type_align = TYPE_ALIGN (type);
00907 tree dsize = DECL_SIZE (field);
00908 HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
00909 HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
00910 HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
00911
00912 #ifdef ADJUST_FIELD_ALIGN
00913 if (! TYPE_USER_ALIGN (type))
00914 type_align = ADJUST_FIELD_ALIGN (field, type_align);
00915 #endif
00916
00917
00918
00919 if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
00920 rli->bitpos = round_up (rli->bitpos, type_align);
00921
00922 TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
00923 }
00924 #endif
00925
00926 #ifdef BITFIELD_NBYTES_LIMITED
00927 if (BITFIELD_NBYTES_LIMITED
00928 && ! targetm.ms_bitfield_layout_p (rli->t)
00929 && TREE_CODE (field) == FIELD_DECL
00930 && type != error_mark_node
00931 && DECL_BIT_FIELD_TYPE (field)
00932 && ! DECL_PACKED (field)
00933 && ! integer_zerop (DECL_SIZE (field))
00934 && host_integerp (DECL_SIZE (field), 1)
00935 && host_integerp (rli->offset, 1)
00936 && host_integerp (TYPE_SIZE (type), 1))
00937 {
00938 unsigned int type_align = TYPE_ALIGN (type);
00939 tree dsize = DECL_SIZE (field);
00940 HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
00941 HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
00942 HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
00943
00944 #ifdef ADJUST_FIELD_ALIGN
00945 if (! TYPE_USER_ALIGN (type))
00946 type_align = ADJUST_FIELD_ALIGN (field, type_align);
00947 #endif
00948
00949 if (maximum_field_alignment != 0)
00950 type_align = MIN (type_align, maximum_field_alignment);
00951
00952
00953 else if (DECL_PACKED (field))
00954 type_align = MIN (type_align, BITS_PER_UNIT);
00955
00956
00957
00958 if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
00959 rli->bitpos = round_up (rli->bitpos, type_align);
00960
00961 TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
00962 }
00963 #endif
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 if (targetm.ms_bitfield_layout_p (rli->t)
00980 && ((DECL_BIT_FIELD_TYPE (field) && ! DECL_PACKED (field))
00981 || (rli->prev_field && ! DECL_PACKED (rli->prev_field))))
00982 {
00983
00984
00985 tree prev_saved = rli->prev_field;
00986
00987
00988
00989 if (rli->prev_field )
00990 {
00991
00992
00993
00994
00995
00996
00997 if (DECL_BIT_FIELD_TYPE (field)
00998 && !integer_zerop (DECL_SIZE (field))
00999 && !integer_zerop (DECL_SIZE (rli->prev_field))
01000 && host_integerp (DECL_SIZE (rli->prev_field), 0)
01001 && host_integerp (TYPE_SIZE (type), 0)
01002 && simple_cst_equal (TYPE_SIZE (type),
01003 TYPE_SIZE (TREE_TYPE (rli->prev_field))))
01004 {
01005
01006
01007
01008 HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 0);
01009
01010 if (rli->remaining_in_alignment < bitsize)
01011 {
01012
01013 rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
01014 rli->bitpos
01015 = size_binop (PLUS_EXPR, TYPE_SIZE (type),
01016 DECL_FIELD_BIT_OFFSET (rli->prev_field));
01017 rli->prev_field = field;
01018 rli->remaining_in_alignment
01019 = tree_low_cst (TYPE_SIZE (type), 0);
01020 }
01021
01022 rli->remaining_in_alignment -= bitsize;
01023 }
01024 else
01025 {
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 if (!integer_zerop (DECL_SIZE (rli->prev_field)))
01036 {
01037 tree type_size = TYPE_SIZE (TREE_TYPE (rli->prev_field));
01038
01039 rli->bitpos
01040 = size_binop (PLUS_EXPR, type_size,
01041 DECL_FIELD_BIT_OFFSET (rli->prev_field));
01042 }
01043 else
01044
01045
01046 prev_saved = NULL;
01047
01048
01049
01050 if (!DECL_BIT_FIELD_TYPE(field)
01051 || integer_zerop (DECL_SIZE (field)))
01052 rli->prev_field = NULL;
01053 }
01054
01055 normalize_rli (rli);
01056 }
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070 if (!DECL_BIT_FIELD_TYPE (field)
01071 || ( prev_saved != NULL
01072 ? !simple_cst_equal (TYPE_SIZE (type),
01073 TYPE_SIZE (TREE_TYPE (prev_saved)))
01074 : !integer_zerop (DECL_SIZE (field)) ))
01075 {
01076
01077 unsigned int type_align = BITS_PER_UNIT;
01078
01079
01080
01081
01082
01083 if (DECL_SIZE (field) != NULL
01084 && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 0)
01085 && host_integerp (DECL_SIZE (field), 0))
01086 rli->remaining_in_alignment
01087 = tree_low_cst (TYPE_SIZE (TREE_TYPE(field)), 0)
01088 - tree_low_cst (DECL_SIZE (field), 0);
01089
01090
01091 if (!DECL_PACKED(field))
01092 type_align = MAX(TYPE_ALIGN (type), type_align);
01093
01094 if (prev_saved
01095 && DECL_BIT_FIELD_TYPE (prev_saved)
01096
01097
01098
01099 && ! integer_zerop (DECL_SIZE (prev_saved)))
01100 type_align = MAX (type_align,
01101 TYPE_ALIGN (TREE_TYPE (prev_saved)));
01102
01103 if (maximum_field_alignment != 0)
01104 type_align = MIN (type_align, maximum_field_alignment);
01105
01106 rli->bitpos = round_up (rli->bitpos, type_align);
01107
01108
01109
01110 rli->prev_field = NULL;
01111 }
01112 }
01113
01114
01115 normalize_rli (rli);
01116 DECL_FIELD_OFFSET (field) = rli->offset;
01117 DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
01118 SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
01119
01120
01121
01122
01123 if (! integer_zerop (DECL_FIELD_BIT_OFFSET (field)))
01124 actual_align = (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
01125 & - tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1));
01126 else if (integer_zerop (DECL_FIELD_OFFSET (field)))
01127 actual_align = BIGGEST_ALIGNMENT;
01128 else if (host_integerp (DECL_FIELD_OFFSET (field), 1))
01129 actual_align = (BITS_PER_UNIT
01130 * (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
01131 & - tree_low_cst (DECL_FIELD_OFFSET (field), 1)));
01132 else
01133 actual_align = DECL_OFFSET_ALIGN (field);
01134
01135 if (known_align != actual_align)
01136 layout_decl (field, actual_align);
01137
01138
01139 if (rli->prev_field == NULL && DECL_BIT_FIELD_TYPE(field))
01140 rli->prev_field = field;
01141
01142
01143
01144
01145
01146
01147
01148
01149 if (DECL_SIZE (field) == 0)
01150 ;
01151 else if (TREE_CODE (DECL_SIZE_UNIT (field)) != INTEGER_CST
01152 || TREE_CONSTANT_OVERFLOW (DECL_SIZE_UNIT (field)))
01153 {
01154 rli->offset
01155 = size_binop (PLUS_EXPR, rli->offset,
01156 fold_convert (sizetype,
01157 size_binop (CEIL_DIV_EXPR, rli->bitpos,
01158 bitsize_unit_node)));
01159 rli->offset
01160 = size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
01161 rli->bitpos = bitsize_zero_node;
01162 rli->offset_align = MIN (rli->offset_align, desired_align);
01163 }
01164 else
01165 {
01166 rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
01167 normalize_rli (rli);
01168 }
01169 }
01170
01171
01172
01173
01174
01175 static void
01176 finalize_record_size (record_layout_info rli)
01177 {
01178 tree unpadded_size, unpadded_size_unit;
01179
01180
01181
01182 rli->offset_align = BITS_PER_UNIT;
01183 normalize_rli (rli);
01184
01185
01186 #ifdef ROUND_TYPE_ALIGN
01187 TYPE_ALIGN (rli->t) = ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t),
01188 rli->record_align);
01189 #else
01190 TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align);
01191 #endif
01192
01193
01194
01195
01196 unpadded_size = rli_size_so_far (rli);
01197 unpadded_size_unit = rli_size_unit_so_far (rli);
01198 if (! integer_zerop (rli->bitpos))
01199 unpadded_size_unit
01200 = size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);
01201
01202
01203 TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
01204 TYPE_SIZE_UNIT (rli->t)
01205 = round_up (unpadded_size_unit, TYPE_ALIGN_UNIT (rli->t));
01206
01207 if (warn_padded && TREE_CONSTANT (unpadded_size)
01208 && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
01209 warning ("padding struct size to alignment boundary");
01210
01211 if (warn_packed && TREE_CODE (rli->t) == RECORD_TYPE
01212 && TYPE_PACKED (rli->t) && ! rli->packed_maybe_necessary
01213 && TREE_CONSTANT (unpadded_size))
01214 {
01215 tree unpacked_size;
01216
01217 #ifdef ROUND_TYPE_ALIGN
01218 rli->unpacked_align
01219 = ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t), rli->unpacked_align);
01220 #else
01221 rli->unpacked_align = MAX (TYPE_ALIGN (rli->t), rli->unpacked_align);
01222 #endif
01223
01224 unpacked_size = round_up (TYPE_SIZE (rli->t), rli->unpacked_align);
01225 if (simple_cst_equal (unpacked_size, TYPE_SIZE (rli->t)))
01226 {
01227 TYPE_PACKED (rli->t) = 0;
01228
01229 if (TYPE_NAME (rli->t))
01230 {
01231 const char *name;
01232
01233 if (TREE_CODE (TYPE_NAME (rli->t)) == IDENTIFIER_NODE)
01234 name = IDENTIFIER_POINTER (TYPE_NAME (rli->t));
01235 else
01236 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (rli->t)));
01237
01238 if (STRICT_ALIGNMENT)
01239 warning ("packed attribute causes inefficient "
01240 "alignment for %qs", name);
01241 else
01242 warning ("packed attribute is unnecessary for %qs", name);
01243 }
01244 else
01245 {
01246 if (STRICT_ALIGNMENT)
01247 warning ("packed attribute causes inefficient alignment");
01248 else
01249 warning ("packed attribute is unnecessary");
01250 }
01251 }
01252 }
01253 }
01254
01255
01256
01257 void
01258 compute_record_mode (tree type)
01259 {
01260 tree field;
01261 enum machine_mode mode = VOIDmode;
01262
01263
01264
01265
01266
01267 TYPE_MODE (type) = BLKmode;
01268
01269 if (! host_integerp (TYPE_SIZE (type), 1))
01270 return;
01271
01272
01273
01274
01275 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
01276 {
01277 if (TREE_CODE (field) != FIELD_DECL)
01278 continue;
01279
01280 if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK
01281 || (TYPE_MODE (TREE_TYPE (field)) == BLKmode
01282 && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field))
01283 && !(TYPE_SIZE (TREE_TYPE (field)) != 0
01284 && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))))
01285 || ! host_integerp (bit_position (field), 1)
01286 || DECL_SIZE (field) == 0
01287 || ! host_integerp (DECL_SIZE (field), 1))
01288 return;
01289
01290
01291
01292
01293 if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
01294 mode = DECL_MODE (field);
01295
01296 #ifdef MEMBER_TYPE_FORCES_BLK
01297
01298
01299
01300 if (MEMBER_TYPE_FORCES_BLK (field, mode))
01301 return;
01302 #endif
01303 }
01304
01305 TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
01306
01307
01308
01309
01310 if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
01311 && GET_MODE_SIZE (mode) == GET_MODE_SIZE (TYPE_MODE (type)))
01312 TYPE_MODE (type) = mode;
01313
01314
01315
01316 if (TYPE_MODE (type) != BLKmode
01317 && STRICT_ALIGNMENT
01318 && ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
01319 || TYPE_ALIGN (type) >= GET_MODE_ALIGNMENT (TYPE_MODE (type))))
01320 {
01321
01322
01323 TYPE_NO_FORCE_BLK (type) = 1;
01324 TYPE_MODE (type) = BLKmode;
01325 }
01326 }
01327
01328
01329
01330
01331 static void
01332 finalize_type_size (tree type)
01333 {
01334
01335
01336
01337
01338
01339 if (TYPE_MODE (type) != BLKmode && TYPE_MODE (type) != VOIDmode
01340 && (STRICT_ALIGNMENT
01341 || (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
01342 && TREE_CODE (type) != QUAL_UNION_TYPE
01343 && TREE_CODE (type) != ARRAY_TYPE)))
01344 {
01345 TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
01346 TYPE_USER_ALIGN (type) = 0;
01347 }
01348
01349
01350 #ifdef ROUND_TYPE_ALIGN
01351 TYPE_ALIGN (type)
01352 = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT);
01353 #endif
01354
01355
01356
01357 if (TYPE_SIZE_UNIT (type) == 0 && TYPE_SIZE (type) != 0)
01358
01359
01360
01361 TYPE_SIZE_UNIT (type)
01362 = fold_convert (sizetype,
01363 size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type),
01364 bitsize_unit_node));
01365
01366 if (TYPE_SIZE (type) != 0)
01367 {
01368 TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type));
01369 TYPE_SIZE_UNIT (type) = round_up (TYPE_SIZE_UNIT (type),
01370 TYPE_ALIGN_UNIT (type));
01371 }
01372
01373
01374 if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
01375 TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
01376 if (TYPE_SIZE_UNIT (type) != 0
01377 && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
01378 TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type));
01379
01380
01381 if (TYPE_NEXT_VARIANT (type)
01382 || type != TYPE_MAIN_VARIANT (type))
01383 {
01384 tree variant;
01385
01386 tree size = TYPE_SIZE (type);
01387 tree size_unit = TYPE_SIZE_UNIT (type);
01388 unsigned int align = TYPE_ALIGN (type);
01389 unsigned int user_align = TYPE_USER_ALIGN (type);
01390 enum machine_mode mode = TYPE_MODE (type);
01391
01392
01393 for (variant = TYPE_MAIN_VARIANT (type);
01394 variant != 0;
01395 variant = TYPE_NEXT_VARIANT (variant))
01396 {
01397 TYPE_SIZE (variant) = size;
01398 TYPE_SIZE_UNIT (variant) = size_unit;
01399 TYPE_ALIGN (variant) = align;
01400 TYPE_USER_ALIGN (variant) = user_align;
01401 TYPE_MODE (variant) = mode;
01402 }
01403 }
01404 }
01405
01406
01407
01408
01409
01410
01411
01412 void
01413 finish_record_layout (record_layout_info rli, int free_p)
01414 {
01415
01416 finalize_record_size (rli);
01417
01418
01419 compute_record_mode (rli->t);
01420
01421
01422 finalize_type_size (rli->t);
01423
01424
01425
01426 while (rli->pending_statics)
01427 {
01428 layout_decl (TREE_VALUE (rli->pending_statics), 0);
01429 rli->pending_statics = TREE_CHAIN (rli->pending_statics);
01430 }
01431
01432
01433 if (free_p)
01434 free (rli);
01435 }
01436
01437
01438
01439
01440
01441
01442
01443
01444 void
01445 finish_builtin_struct (tree type, const char *name, tree fields,
01446 tree align_type)
01447 {
01448 tree tail, next;
01449
01450 for (tail = NULL_TREE; fields; tail = fields, fields = next)
01451 {
01452 DECL_FIELD_CONTEXT (fields) = type;
01453 next = TREE_CHAIN (fields);
01454 TREE_CHAIN (fields) = tail;
01455 }
01456 TYPE_FIELDS (type) = tail;
01457
01458 if (align_type)
01459 {
01460 TYPE_ALIGN (type) = TYPE_ALIGN (align_type);
01461 TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);
01462 }
01463
01464 layout_type (type);
01465 #if 0
01466 TYPE_NAME (type) = make_type_decl (get_identifier (name), type);
01467 #else
01468 TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type);
01469 #endif
01470 TYPE_STUB_DECL (type) = TYPE_NAME (type);
01471 layout_decl (TYPE_NAME (type), 0);
01472 }
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484 void
01485 layout_type (tree type)
01486 {
01487 gcc_assert (type);
01488
01489 if (type == error_mark_node)
01490 return;
01491
01492
01493 if (TYPE_SIZE (type))
01494 return;
01495
01496 switch (TREE_CODE (type))
01497 {
01498 case LANG_TYPE:
01499
01500
01501 gcc_unreachable ();
01502
01503 case BOOLEAN_TYPE:
01504 if (TYPE_PRECISION (type) == 0)
01505 TYPE_PRECISION (type) = 1;
01506
01507
01508
01509 case INTEGER_TYPE:
01510 case ENUMERAL_TYPE:
01511 case CHAR_TYPE:
01512 if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
01513 && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
01514 TYPE_UNSIGNED (type) = 1;
01515
01516 TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
01517 MODE_INT);
01518 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
01519 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
01520 break;
01521
01522 case REAL_TYPE:
01523 TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
01524 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
01525 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
01526 break;
01527
01528 case COMPLEX_TYPE:
01529 TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
01530 TYPE_MODE (type)
01531 = mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
01532 (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
01533 ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT),
01534 0);
01535 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
01536 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
01537 break;
01538
01539 case VECTOR_TYPE:
01540 {
01541 int nunits = TYPE_VECTOR_SUBPARTS (type);
01542 tree nunits_tree = build_int_cst (NULL_TREE, nunits);
01543 tree innertype = TREE_TYPE (type);
01544
01545 gcc_assert (!(nunits & (nunits - 1)));
01546
01547
01548 if (TYPE_MODE (type) == VOIDmode)
01549 {
01550 enum machine_mode innermode = TYPE_MODE (innertype);
01551 enum machine_mode mode;
01552
01553
01554 if (GET_MODE_CLASS (innermode) == MODE_FLOAT)
01555 mode = MIN_MODE_VECTOR_FLOAT;
01556 else
01557 mode = MIN_MODE_VECTOR_INT;
01558
01559 for (; mode != VOIDmode ; mode = GET_MODE_WIDER_MODE (mode))
01560 if (GET_MODE_NUNITS (mode) == nunits
01561 && GET_MODE_INNER (mode) == innermode
01562 && targetm.vector_mode_supported_p (mode))
01563 break;
01564
01565
01566 if (mode == VOIDmode
01567 && GET_MODE_CLASS (innermode) == MODE_INT)
01568 mode = mode_for_size (nunits * GET_MODE_BITSIZE (innermode),
01569 MODE_INT, 0);
01570
01571 if (mode == VOIDmode || !have_regs_of_mode[mode])
01572 TYPE_MODE (type) = BLKmode;
01573 else
01574 TYPE_MODE (type) = mode;
01575 }
01576
01577 TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
01578 TYPE_SIZE_UNIT (type) = int_const_binop (MULT_EXPR,
01579 TYPE_SIZE_UNIT (innertype),
01580 nunits_tree, 0);
01581 TYPE_SIZE (type) = int_const_binop (MULT_EXPR, TYPE_SIZE (innertype),
01582 nunits_tree, 0);
01583
01584
01585
01586 TYPE_ALIGN (type) = tree_low_cst (TYPE_SIZE (type), 0);
01587 break;
01588 }
01589
01590 case VOID_TYPE:
01591
01592 TYPE_ALIGN (type) = 1;
01593 TYPE_USER_ALIGN (type) = 0;
01594 TYPE_MODE (type) = VOIDmode;
01595 break;
01596
01597 case OFFSET_TYPE:
01598 TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
01599 TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
01600
01601
01602 TYPE_MODE (type) = mode_for_size (POINTER_SIZE, MODE_INT, 0);
01603 break;
01604
01605 case FUNCTION_TYPE:
01606 case METHOD_TYPE:
01607
01608
01609
01610 TYPE_MODE (type) = mode_for_size (FUNCTION_BOUNDARY, MODE_INT, 0);
01611 TYPE_SIZE (type) = bitsize_int (FUNCTION_BOUNDARY);
01612 TYPE_SIZE_UNIT (type) = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
01613 break;
01614
01615 case POINTER_TYPE:
01616 case REFERENCE_TYPE:
01617 {
01618
01619 enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
01620 && reference_types_internal)
01621 ? Pmode : TYPE_MODE (type));
01622
01623 int nbits = GET_MODE_BITSIZE (mode);
01624
01625 TYPE_SIZE (type) = bitsize_int (nbits);
01626 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
01627 TYPE_UNSIGNED (type) = 1;
01628 TYPE_PRECISION (type) = nbits;
01629 }
01630 break;
01631
01632 case ARRAY_TYPE:
01633 {
01634 tree index = TYPE_DOMAIN (type);
01635 tree element = TREE_TYPE (type);
01636
01637 build_pointer_type (element);
01638
01639
01640 if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
01641 && TYPE_SIZE (element))
01642 {
01643 tree ub = TYPE_MAX_VALUE (index);
01644 tree lb = TYPE_MIN_VALUE (index);
01645 tree length;
01646 tree element_size;
01647
01648
01649
01650 length = size_binop (PLUS_EXPR, size_one_node,
01651 fold_convert (sizetype,
01652 fold (build2 (MINUS_EXPR,
01653 TREE_TYPE (lb),
01654 ub, lb))));
01655
01656
01657 element_size = TYPE_SIZE (element);
01658 if (TYPE_PACKED (type) && INTEGRAL_TYPE_P (element)
01659 && (integer_zerop (TYPE_MAX_VALUE (element))
01660 || integer_onep (TYPE_MAX_VALUE (element)))
01661 && host_integerp (TYPE_MIN_VALUE (element), 1))
01662 {
01663 HOST_WIDE_INT maxvalue
01664 = tree_low_cst (TYPE_MAX_VALUE (element), 1);
01665 HOST_WIDE_INT minvalue
01666 = tree_low_cst (TYPE_MIN_VALUE (element), 1);
01667
01668 if (maxvalue - minvalue == 1
01669 && (maxvalue == 1 || maxvalue == 0))
01670 element_size = integer_one_node;
01671 }
01672
01673
01674
01675
01676
01677 if (!TYPE_UNSIGNED (sizetype)
01678 && TREE_CODE (TYPE_MIN_VALUE (index)) != INTEGER_CST
01679 && TREE_CODE (TYPE_MAX_VALUE (index)) != INTEGER_CST)
01680 length = size_binop (MAX_EXPR, length, size_zero_node);
01681
01682 TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
01683 fold_convert (bitsizetype,
01684 length));
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694 if (TYPE_SIZE_UNIT (element) != 0 && ! integer_onep (element_size))
01695 TYPE_SIZE_UNIT (type)
01696 = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length);
01697 }
01698
01699
01700
01701
01702 #ifdef ROUND_TYPE_ALIGN
01703 TYPE_ALIGN (type)
01704 = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (element), BITS_PER_UNIT);
01705 #else
01706 TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
01707 #endif
01708 TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
01709 TYPE_MODE (type) = BLKmode;
01710 if (TYPE_SIZE (type) != 0
01711 #ifdef MEMBER_TYPE_FORCES_BLK
01712 && ! MEMBER_TYPE_FORCES_BLK (type, VOIDmode)
01713 #endif
01714
01715
01716 && (TYPE_MODE (TREE_TYPE (type)) != BLKmode
01717 || TYPE_NO_FORCE_BLK (TREE_TYPE (type))))
01718 {
01719
01720 if (simple_cst_equal (TYPE_SIZE (type),
01721 TYPE_SIZE (TREE_TYPE (type))))
01722 TYPE_MODE (type) = TYPE_MODE (TREE_TYPE (type));
01723 else
01724 TYPE_MODE (type)
01725 = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
01726
01727 if (TYPE_MODE (type) != BLKmode
01728 && STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
01729 && TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type))
01730 && TYPE_MODE (type) != BLKmode)
01731 {
01732 TYPE_NO_FORCE_BLK (type) = 1;
01733 TYPE_MODE (type) = BLKmode;
01734 }
01735 }
01736 break;
01737 }
01738
01739 case RECORD_TYPE:
01740 case UNION_TYPE:
01741 case QUAL_UNION_TYPE:
01742 {
01743 tree field;
01744 record_layout_info rli;
01745
01746
01747 rli = start_record_layout (type);
01748
01749
01750
01751
01752 if (TREE_CODE (type) == QUAL_UNION_TYPE)
01753 TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));
01754
01755
01756 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
01757 place_field (rli, field);
01758
01759 if (TREE_CODE (type) == QUAL_UNION_TYPE)
01760 TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));
01761
01762 if (lang_adjust_rli)
01763 (*lang_adjust_rli) (rli);
01764
01765
01766 finish_record_layout (rli, true);
01767
01768 #ifdef KEY
01769 if (flag_spin_file && gspin_invoked(type))
01770 gs_x (type);
01771 #endif
01772 }
01773 break;
01774
01775 case FILE_TYPE:
01776
01777
01778 TYPE_ALIGN (type) = BIGGEST_ALIGNMENT;
01779 TYPE_USER_ALIGN (type) = 0;
01780 TYPE_MODE (type) = BLKmode;
01781 break;
01782
01783 default:
01784 gcc_unreachable ();
01785 }
01786
01787
01788
01789
01790 if (TREE_CODE (type) != RECORD_TYPE
01791 && TREE_CODE (type) != UNION_TYPE
01792 && TREE_CODE (type) != QUAL_UNION_TYPE)
01793 finalize_type_size (type);
01794
01795
01796
01797
01798
01799
01800 if (AGGREGATE_TYPE_P (type) && TYPE_ALIAS_SET_KNOWN_P (type))
01801 TYPE_ALIAS_SET (type) = 0;
01802 }
01803
01804
01805
01806 tree
01807 make_signed_type (int precision)
01808 {
01809 tree type = make_node (INTEGER_TYPE);
01810
01811 TYPE_PRECISION (type) = precision;
01812
01813 fixup_signed_type (type);
01814 return type;
01815 }
01816
01817
01818
01819 tree
01820 make_unsigned_type (int precision)
01821 {
01822 tree type = make_node (INTEGER_TYPE);
01823
01824 TYPE_PRECISION (type) = precision;
01825
01826 fixup_unsigned_type (type);
01827 return type;
01828 }
01829
01830
01831
01832
01833 void
01834 initialize_sizetypes (bool signed_p)
01835 {
01836 tree t = make_node (INTEGER_TYPE);
01837
01838 TYPE_MODE (t) = SImode;
01839 TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode);
01840 TYPE_USER_ALIGN (t) = 0;
01841 TYPE_IS_SIZETYPE (t) = 1;
01842 TYPE_UNSIGNED (t) = !signed_p;
01843 TYPE_SIZE (t) = build_int_cst (t, GET_MODE_BITSIZE (SImode));
01844 TYPE_SIZE_UNIT (t) = build_int_cst (t, GET_MODE_SIZE (SImode));
01845 TYPE_PRECISION (t) = GET_MODE_BITSIZE (SImode);
01846 TYPE_MIN_VALUE (t) = build_int_cst (t, 0);
01847
01848
01849
01850 TYPE_MAX_VALUE (t) = build_int_cst (t, 1000);
01851
01852 sizetype = t;
01853 bitsizetype = build_distinct_type_copy (t);
01854 }
01855
01856
01857
01858
01859
01860
01861
01862 void
01863 set_sizetype (tree type)
01864 {
01865 int oprecision = TYPE_PRECISION (type);
01866
01867
01868
01869
01870 int precision = MIN (oprecision + BITS_PER_UNIT_LOG + 1,
01871 2 * HOST_BITS_PER_WIDE_INT);
01872 tree t;
01873
01874 gcc_assert (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (sizetype));
01875
01876 t = build_distinct_type_copy (type);
01877
01878
01879 TYPE_CACHED_VALUES (t) = TYPE_CACHED_VALUES (sizetype);
01880 TYPE_CACHED_VALUES_P (t) = TYPE_CACHED_VALUES_P (sizetype);
01881 TREE_TYPE (TYPE_CACHED_VALUES (t)) = type;
01882 TYPE_UID (t) = TYPE_UID (sizetype);
01883 TYPE_IS_SIZETYPE (t) = 1;
01884
01885
01886 memcpy (sizetype, t, tree_size (sizetype));
01887 TYPE_MAIN_VARIANT (sizetype) = sizetype;
01888
01889 t = make_node (INTEGER_TYPE);
01890 TYPE_NAME (t) = get_identifier ("bit_size_type");
01891
01892
01893 TYPE_CACHED_VALUES (t) = TYPE_CACHED_VALUES (bitsizetype);
01894 TYPE_CACHED_VALUES_P (t) = TYPE_CACHED_VALUES_P (bitsizetype);
01895 TYPE_PRECISION (t) = precision;
01896 TYPE_UID (t) = TYPE_UID (bitsizetype);
01897 TYPE_IS_SIZETYPE (t) = 1;
01898
01899 memcpy (bitsizetype, t, tree_size (bitsizetype));
01900
01901 if (TYPE_UNSIGNED (type))
01902 {
01903 fixup_unsigned_type (bitsizetype);
01904 ssizetype = build_distinct_type_copy (make_signed_type (oprecision));
01905 TYPE_IS_SIZETYPE (ssizetype) = 1;
01906 sbitsizetype = build_distinct_type_copy (make_signed_type (precision));
01907 TYPE_IS_SIZETYPE (sbitsizetype) = 1;
01908 }
01909 else
01910 {
01911 fixup_signed_type (bitsizetype);
01912 ssizetype = sizetype;
01913 sbitsizetype = bitsizetype;
01914 }
01915 }
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925 void
01926 set_min_and_max_values_for_integral_type (tree type,
01927 int precision,
01928 bool is_unsigned)
01929 {
01930 tree min_value;
01931 tree max_value;
01932
01933 if (is_unsigned)
01934 {
01935 min_value = build_int_cst (type, 0);
01936 max_value
01937 = build_int_cst_wide (type, precision - HOST_BITS_PER_WIDE_INT >= 0
01938 ? -1
01939 : ((HOST_WIDE_INT) 1 << precision) - 1,
01940 precision - HOST_BITS_PER_WIDE_INT > 0
01941 ? ((unsigned HOST_WIDE_INT) ~0
01942 >> (HOST_BITS_PER_WIDE_INT
01943 - (precision - HOST_BITS_PER_WIDE_INT)))
01944 : 0);
01945 }
01946 else
01947 {
01948 min_value
01949 = build_int_cst_wide (type,
01950 (precision - HOST_BITS_PER_WIDE_INT > 0
01951 ? 0
01952 : (HOST_WIDE_INT) (-1) << (precision - 1)),
01953 (((HOST_WIDE_INT) (-1)
01954 << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
01955 ? precision - HOST_BITS_PER_WIDE_INT - 1
01956 : 0))));
01957 max_value
01958 = build_int_cst_wide (type,
01959 (precision - HOST_BITS_PER_WIDE_INT > 0
01960 ? -1
01961 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
01962 (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
01963 ? (((HOST_WIDE_INT) 1
01964 << (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
01965 : 0));
01966 }
01967
01968 TYPE_MIN_VALUE (type) = min_value;
01969 TYPE_MAX_VALUE (type) = max_value;
01970 }
01971
01972
01973
01974
01975
01976
01977 void
01978 fixup_signed_type (tree type)
01979 {
01980 int precision = TYPE_PRECISION (type);
01981
01982
01983
01984
01985 if (precision > HOST_BITS_PER_WIDE_INT * 2)
01986 precision = HOST_BITS_PER_WIDE_INT * 2;
01987
01988 set_min_and_max_values_for_integral_type (type, precision,
01989 false);
01990
01991
01992 layout_type (type);
01993 }
01994
01995
01996
01997
01998
01999 void
02000 fixup_unsigned_type (tree type)
02001 {
02002 int precision = TYPE_PRECISION (type);
02003
02004
02005
02006
02007 if (precision > HOST_BITS_PER_WIDE_INT * 2)
02008 precision = HOST_BITS_PER_WIDE_INT * 2;
02009
02010 TYPE_UNSIGNED (type) = 1;
02011
02012 set_min_and_max_values_for_integral_type (type, precision,
02013 true);
02014
02015
02016 layout_type (type);
02017 }
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034 enum machine_mode
02035 get_best_mode (int bitsize, int bitpos, unsigned int align,
02036 enum machine_mode largest_mode, int volatilep)
02037 {
02038 enum machine_mode mode;
02039 unsigned int unit = 0;
02040
02041
02042 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
02043 mode = GET_MODE_WIDER_MODE (mode))
02044 {
02045 unit = GET_MODE_BITSIZE (mode);
02046 if ((bitpos % unit) + bitsize <= unit)
02047 break;
02048 }
02049
02050 if (mode == VOIDmode
02051
02052
02053
02054
02055
02056
02057
02058 || MIN (unit, BIGGEST_ALIGNMENT) > align
02059 || (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode)))
02060 return VOIDmode;
02061
02062 if (SLOW_BYTE_ACCESS && ! volatilep)
02063 {
02064 enum machine_mode wide_mode = VOIDmode, tmode;
02065
02066 for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); tmode != VOIDmode;
02067 tmode = GET_MODE_WIDER_MODE (tmode))
02068 {
02069 unit = GET_MODE_BITSIZE (tmode);
02070 if (bitpos / unit == (bitpos + bitsize - 1) / unit
02071 && unit <= BITS_PER_WORD
02072 && unit <= MIN (align, BIGGEST_ALIGNMENT)
02073 && (largest_mode == VOIDmode
02074 || unit <= GET_MODE_BITSIZE (largest_mode)))
02075 wide_mode = tmode;
02076 }
02077
02078 if (wide_mode != VOIDmode)
02079 return wide_mode;
02080 }
02081
02082 return mode;
02083 }
02084
02085
02086
02087
02088 void
02089 get_mode_bounds (enum machine_mode mode, int sign,
02090 enum machine_mode target_mode,
02091 rtx *mmin, rtx *mmax)
02092 {
02093 unsigned size = GET_MODE_BITSIZE (mode);
02094 unsigned HOST_WIDE_INT min_val, max_val;
02095
02096 gcc_assert (size <= HOST_BITS_PER_WIDE_INT);
02097
02098 if (sign)
02099 {
02100 min_val = -((unsigned HOST_WIDE_INT) 1 << (size - 1));
02101 max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1;
02102 }
02103 else
02104 {
02105 min_val = 0;
02106 max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1) << 1) - 1;
02107 }
02108
02109 *mmin = GEN_INT (trunc_int_for_mode (min_val, target_mode));
02110 *mmax = GEN_INT (trunc_int_for_mode (max_val, target_mode));
02111 }
02112
02113 #include "gt-stor-layout.h"