diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e621bbf7e3a..b95214dfacf6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +Thu Sep 30 14:39:17 1999 Bernd Schmidt + + * tree.h (enum built_in_function): Rename BUILT_IN_DWARF_REG_SIZE + to BUILT_IN_INIT_DWARF_REG_SIZES. + * builtins.c (expand_builtins, case BUILT_IN_INIT_DWARF_REG_SIZES): + Renamed from BUILT_IN_DWARF_REG_SIZE; call + expand_builtin_init_dwarf_reg_sizes. + * c-decl.c (init_decl_processing): Replace __builtin_dwarf_reg_size + with __builtin_init_dwarf_reg_size_table. + * dwarf2out.c (struct reg_size_range): Delete. + (expand_builtin_init_dwarf_reg_sizes): New function. + (expand_builtin_dwarf_reg_size): Delete. + * except.h (expand_builtin_init_dwarf_reg_sizes): Declare. + (expand_builtin_dwarf_reg_size): Don't declare. + * libgcc2.c (dwarf_reg_size_table_initialized): New. + (dwarf_reg_size_table): New. + (init_reg_size_table): New function. + (copy_reg): Use dwarf_reg_size_table. + (eh_context_initialize): Make sure dwarf_reg_size_table is initialized + before use. + Thu Sep 30 05:40:34 1999 Richard Earnshaw * c-lang.c (finish_file case ndef ASM_OUTPUT_{CON,DE}STRUCTOR): diff --git a/gcc/builtins.c b/gcc/builtins.c index 36a6493d6452..1fb7b7413664 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2484,8 +2484,9 @@ expand_builtin (exp, target, subtarget, mode, ignore) #ifdef DWARF2_UNWIND_INFO case BUILT_IN_DWARF_FP_REGNUM: return expand_builtin_dwarf_fp_regnum (); - case BUILT_IN_DWARF_REG_SIZE: - return expand_builtin_dwarf_reg_size (TREE_VALUE (arglist), target); + case BUILT_IN_INIT_DWARF_REG_SIZES: + expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist)); + return const0_rtx; #endif case BUILT_IN_FROB_RETURN_ADDR: return expand_builtin_frob_return_addr (TREE_VALUE (arglist)); diff --git a/gcc/c-decl.c b/gcc/c-decl.c index ca8f26b88c08..75ad2bac0b79 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -3068,8 +3068,8 @@ init_decl_processing () builtin_function ("__builtin_dwarf_fp_regnum", build_function_type (unsigned_type_node, endlink), BUILT_IN_DWARF_FP_REGNUM, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ("__builtin_dwarf_reg_size", int_ftype_int, - BUILT_IN_DWARF_REG_SIZE, BUILT_IN_NORMAL, NULL_PTR); + builtin_function ("__builtin_init_dwarf_reg_size_table", void_ftype_ptr, + BUILT_IN_INIT_DWARF_REG_SIZES, BUILT_IN_NORMAL, NULL_PTR); builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr, BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_NORMAL, NULL_PTR); builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr, diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 74f9d6dc611b..6732e5811dec 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -560,110 +560,26 @@ reg_number (rtl) return regno; } -struct reg_size_range +/* Generate code to initialize the register size table. */ + +void +expand_builtin_init_dwarf_reg_sizes (address) + tree address; { - int beg; - int end; - int size; -}; + int i; + enum machine_mode mode = TYPE_MODE (char_type_node); + rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0); + rtx mem = gen_rtx_MEM (mode, addr); -/* Given a register number in REG_TREE, return an rtx for its size in bytes. - We do this in kind of a roundabout way, by building up a list of - register size ranges and seeing where our register falls in one of those - ranges. We need to do it this way because REG_TREE is not a constant, - and the target macros were not designed to make this task easy. */ - -rtx -expand_builtin_dwarf_reg_size (reg_tree, target) - tree reg_tree; - rtx target; -{ - enum machine_mode mode; - int size; - struct reg_size_range ranges[5]; - tree t, t2; - - int i = 0; - int n_ranges = 0; - int last_size = -1; - - for (; i < FIRST_PSEUDO_REGISTER; ++i) + for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) { - /* The return address is out of order on the MIPS, and we don't use - copy_reg for it anyway, so we don't care here how large it is. */ - if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN) - continue; + int offset = i * GET_MODE_SIZE (mode); + int size = GET_MODE_SIZE (reg_raw_mode[i]); - mode = reg_raw_mode[i]; - - /* CCmode is arbitrarily given a size of 4 bytes. It is more useful - to use the same size as word_mode, since that reduces the number - of ranges we need. It should not matter, since the result should - never be used for a condition code register anyways. */ - if (GET_MODE_CLASS (mode) == MODE_CC) - mode = word_mode; - - size = GET_MODE_SIZE (mode); - - /* If this register is not valid in the specified mode and - we have a previous size, use that for the size of this - register to avoid making junk tiny ranges. */ - if (! HARD_REGNO_MODE_OK (i, mode) && last_size != -1) - size = last_size; - - if (size != last_size) - { - ranges[n_ranges].beg = i; - ranges[n_ranges].size = last_size = size; - ++n_ranges; - if (n_ranges >= 5) - abort (); - } - ranges[n_ranges-1].end = i; + emit_move_insn (change_address (mem, mode, + plus_constant (addr, offset)), + GEN_INT (size)); } - - /* The usual case: fp regs surrounded by general regs. */ - if (n_ranges == 3 && ranges[0].size == ranges[2].size) - { - if ((DWARF_FRAME_REGNUM (ranges[1].end) - - DWARF_FRAME_REGNUM (ranges[1].beg)) - != ranges[1].end - ranges[1].beg) - abort (); - t = fold (build (GE_EXPR, integer_type_node, reg_tree, - build_int_2 (DWARF_FRAME_REGNUM (ranges[1].beg), 0))); - t2 = fold (build (LE_EXPR, integer_type_node, reg_tree, - build_int_2 (DWARF_FRAME_REGNUM (ranges[1].end), 0))); - t = fold (build (TRUTH_ANDIF_EXPR, integer_type_node, t, t2)); - t = fold (build (COND_EXPR, integer_type_node, t, - build_int_2 (ranges[1].size, 0), - build_int_2 (ranges[0].size, 0))); - } - else - { - /* Initialize last_end to be larger than any possible - DWARF_FRAME_REGNUM. */ - int last_end = 0x7fffffff; - --n_ranges; - t = build_int_2 (ranges[n_ranges].size, 0); - do - { - int beg = DWARF_FRAME_REGNUM (ranges[n_ranges].beg); - int end = DWARF_FRAME_REGNUM (ranges[n_ranges].end); - if (beg < 0) - continue; - if (end >= last_end) - abort (); - last_end = end; - if (end - beg != ranges[n_ranges].end - ranges[n_ranges].beg) - abort (); - t2 = fold (build (LE_EXPR, integer_type_node, reg_tree, - build_int_2 (end, 0))); - t = fold (build (COND_EXPR, integer_type_node, t2, - build_int_2 (ranges[n_ranges].size, 0), t)); - } - while (--n_ranges >= 0); - } - return expand_expr (t, target, Pmode, 0); } /* Convert a DWARF call frame info. operation to its string name */ diff --git a/gcc/except.h b/gcc/except.h index 73bbe4dc8d73..07d4359a239f 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -473,7 +473,7 @@ rtx expand_builtin_dwarf_fp_regnum PROTO((void)); #ifdef TREE_CODE rtx expand_builtin_frob_return_addr PROTO((tree)); rtx expand_builtin_extract_return_addr PROTO((tree)); -rtx expand_builtin_dwarf_reg_size PROTO((tree, rtx)); +void expand_builtin_init_dwarf_reg_sizes PROTO((tree)); void expand_builtin_eh_return PROTO((tree, tree, tree)); #endif void expand_eh_return PROTO((void)); diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index aa8839be00da..777112ce4e4a 100644 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -3120,6 +3120,18 @@ __get_eh_info () return &eh->info; } +#ifdef DWARF2_UNWIND_INFO +static int dwarf_reg_size_table_initialized = 0; +static char dwarf_reg_size_table[FIRST_PSEUDO_REGISTER]; + +static void +init_reg_size_table () +{ + __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table); + dwarf_reg_size_table_initialized = 1; +} +#endif + #if __GTHREADS static void eh_threads_initialize () @@ -3152,12 +3164,24 @@ eh_context_initialize () /* Use static version of EH context. */ get_eh_context = &eh_context_static; } +#ifdef DWARF2_UNWIND_INFO + { + static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT; + if (__gthread_once (&once_regsizes, init_reg_size_table) != 0 + || ! dwarf_reg_size_table_initialized) + init_reg_size_table (); + } +#endif #else /* no __GTHREADS */ /* Use static version of EH context. */ get_eh_context = &eh_context_static; +#ifdef DWARF2_UNWIND_INFO + init_reg_size_table (); +#endif + #endif /* no __GTHREADS */ return (*get_eh_context) (); @@ -3395,7 +3419,6 @@ EH_TABLE_LOOKUP #ifdef DWARF2_UNWIND_INFO - /* Return the table version of an exception descriptor */ short @@ -3620,7 +3643,7 @@ copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata) word_type *preg = get_reg_addr (reg, udata, NULL); word_type *ptreg = get_reg_addr (reg, target_udata, NULL); - memcpy (ptreg, preg, __builtin_dwarf_reg_size (reg)); + memcpy (ptreg, preg, dwarf_reg_size_table [reg]); } /* Retrieve the return address for frame UDATA. */ diff --git a/gcc/tree.h b/gcc/tree.h index f2b6c729a10c..cacdb28f2031 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -120,7 +120,7 @@ enum built_in_function BUILT_IN_UNWIND_INIT, BUILT_IN_DWARF_CFA, BUILT_IN_DWARF_FP_REGNUM, - BUILT_IN_DWARF_REG_SIZE, + BUILT_IN_INIT_DWARF_REG_SIZES, BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_EXTRACT_RETURN_ADDR, BUILT_IN_EH_RETURN,