This commit was generated by cvs2svn to compensate for changes in r70635,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
4e21a652d8
@ -1,3 +1,357 @@
|
||||
2001-01-01 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
* version.c: Bump.
|
||||
|
||||
* loop.c (instrument_loop_bct): Set JUMP_LABEL on new jump.
|
||||
|
||||
2000-12-27 Geoffrey Keating <geoffk@redhat.com>
|
||||
* config/rs6000/rs6000.md (define_attr "length"): Correct
|
||||
calculation.
|
||||
|
||||
2001-01-01 Philipp Thomas <pthomas@suse.de>
|
||||
|
||||
* configure.in: Make the help for --enable-nls make it
|
||||
clear that this is an experimental feature.
|
||||
* configure: Regenerate.
|
||||
* ABOUT-GCC-NLS: Explain why NLS support is buggy.
|
||||
|
||||
2000-12-29 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
* version.c: Bump.
|
||||
|
||||
* combine.c (cant_combine_insn_p): Only restrict hard register
|
||||
combinations for SMALL_REGISTER_CLASSES machines.
|
||||
|
||||
* config/sparc/sparc.c (pic_address_needs_scratch): LABEL_REFs are
|
||||
not valid pic operands.
|
||||
|
||||
2000-12-26 Kazu Hirata <kazu@hxi.com>
|
||||
* config/h8300/h8300.c (get_shift_alg): Fix a typo in the
|
||||
assembly code for 12-bit ASHIFTRT in HImode.
|
||||
|
||||
2000-07-17 Kazu Hirata <kazu@hxi.com>
|
||||
* h8300.md: Fix the format of mac.
|
||||
(movsi_h8300hs): Output a tab after stmac instead of a space.
|
||||
|
||||
2000-10-07 Will Cohen <wcohen@redhat.com>, Kazu Hirata <kazu@hxi.com>
|
||||
* config/h8300/h8300.md: Remove the memory alternative and correct
|
||||
the insn lengths in the templates for sign extention and zero
|
||||
extention.
|
||||
|
||||
2000-12-23 Philip Blundell <philb@gnu.org>
|
||||
* config/arm/linux-elf.h (CPP_PREDEFINES): Don't define `arm' or
|
||||
`arm_elf'; do define `__arm__'.
|
||||
|
||||
2000-08-22 Richard Henderson <rth@cygnus.com>
|
||||
* alias.c (init_alias_analysis): Do not register
|
||||
struct_value_incoming_rtx or static_chain_rtx as pointing
|
||||
to stack memory.
|
||||
|
||||
Tue Dec 5 20:09:14 2000 Jeffrey A Law (law@cygnus.com)
|
||||
* builtins.c (expand_builtin_setjmp_setup): Set
|
||||
current_function_has_nonlocal_label.
|
||||
|
||||
2000-12-03 Richard Henderson <rth@redhat.com>
|
||||
* builtins.c (expand_builtin_setjmp_setup): New.
|
||||
(expand_builtin_setjmp_receiver): New.
|
||||
(expand_builtin_setjmp): Split out _setup and _receiver functions.
|
||||
Move argument parsing in from ...
|
||||
(expand_builtin): ... here.
|
||||
* except.c (receive_exception_label): Branch around receiver
|
||||
unless new-style exceptions. Call expand_builtin_setjmp_receiver.
|
||||
(start_dynamic_handler): Call expand_builtin_setjmp_setup.
|
||||
* expr.h: Update builtin setjmp decls.
|
||||
|
||||
2000-12-22 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
* calls.c (emit_call_1): Fall back to call_pop/call_value_pop if no
|
||||
non-popping calls are available.
|
||||
|
||||
* flow.c (propagate_block): Use flow_delete_insn instead of
|
||||
NOTEifying a dead ADDR_VEC.
|
||||
|
||||
Fri Sep 10 11:43:07 1999 Philip Blundell <pb@futuretv.com>
|
||||
* configure.in, config/arm/linux-oldld.h,
|
||||
config/arm/linux-elf26.h, config/arm/linux-elf.h: Backport latest
|
||||
ARM GNU/Linux config from mainline.
|
||||
* configure: Regenerate.
|
||||
|
||||
2000-02-08 Geoff Keating <geoffk@cygnus.com>
|
||||
* dwarf2.h (DW_CFA_GNU_negative_offset_extended): New constant.
|
||||
* dwarf2out.c (dwarf_cfi_name): Print name of new constant.
|
||||
(reg_save): Use DW_CFA_GNU_negative_offset_extended when needed.
|
||||
(output_cfi): Handle output of DW_CFA_GNU_negative_offset_extended.
|
||||
* frame.c (execute_cfa_insn): Handle
|
||||
DW_CFA_GNU_negative_offset_extended.
|
||||
|
||||
2000-03-06 Mark Mitchell <mark@codesourcery.com>
|
||||
* function.c (free_temps_for_rtl_expr): Don't free slots
|
||||
that have been pushed into a higher level.
|
||||
|
||||
1999-12-16 David S. Miller <davem@redhat.com>
|
||||
* expr.c (emit_move_insn_1): Only emit clobbers if one of
|
||||
the outputs is a SUBREG.
|
||||
|
||||
Wed Sep 22 17:35:55 1999 Michael Meissner <meissner@cygnus.com>
|
||||
* expr.c (emit_move_insn_1): If we are copying a complex that fits
|
||||
in one word or less (complex char, complex short, or on 64 bit
|
||||
systems complex float) to/from a hard register, copy it through
|
||||
memory instead of dying in gen_{real,imag}part. If we have a
|
||||
short complex type, prevent inlining since it allocates stack
|
||||
memory.
|
||||
|
||||
Fri Dec 15 15:32:16 MET 2000 Jan Hubicka <jh@suse.cz>
|
||||
* combine.c (cant_combine_insn_p): Get around SUBREGs when determining
|
||||
hardreg<->reg moves.
|
||||
|
||||
2000-12-01 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* combine.c (cant_combine_insn_p): Only disallow insns involving
|
||||
hard regs if they are reg-reg moves.
|
||||
|
||||
2000-11-24 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* combine.c (cant_combine_insn_p): New function.
|
||||
(try_combine): Use it.
|
||||
|
||||
2000-12-20 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
* version.c: Bump.
|
||||
|
||||
* reload1.c (free_for_value_p): Fix error in last change.
|
||||
|
||||
2000-03-22 Richard Henderson <rth@cygnus.com>
|
||||
* stmt.c (expand_asm_operands): Don't promote the temporary.
|
||||
|
||||
Sun Sep 19 09:03:40 1999 Mark Mitchell <mark@codesourcery.com>
|
||||
* rtl.h (insns_safe_to_move_p): New function.
|
||||
* loop.c (find_and_verify_loops): Use it.
|
||||
* rtlanal.c (insns_safe_to_move_p): Define it.
|
||||
|
||||
Thu Nov 2 19:20:12 2000 J"orn Rennecke <amylaar@redhat.com>
|
||||
* reload.c (find_equiv_reg): Test all hard registers for membership
|
||||
in the requested class.
|
||||
|
||||
Sun Apr 23 16:24:35 2000 Denis Chertykov <denisc@overta.ru>
|
||||
* reload.c (find_equiv_reg): Checks all valueno regs
|
||||
as a reload_reg_p regs.
|
||||
|
||||
Fri Apr 21 14:58:29 2000 Denis Chertykov <denisc@overta.ru>
|
||||
* reload.c (find_equiv_reg): Checks all valueno and regno regs
|
||||
as a call-clobbered regs.
|
||||
|
||||
2000-12-18 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
2000-09-15 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* optabs.c (emit_libcall_block): If target is a user variable,
|
||||
copy to a temporary first.
|
||||
|
||||
2000-04-28 Kazu Hirata <kazu@hxi.com>
|
||||
* h8300.c (function_epilogue): Clean up flags when the last insn
|
||||
in a function is a barrier.
|
||||
|
||||
Mon Aug 30 01:02:09 1999 Jeffrey A Law (law@cygnus.com)
|
||||
* emit-rtl.c (copy_rtx_if_shared): A MEM which references
|
||||
virtual_stack_vars_rtx or virtual_incoming_args_rtx can not
|
||||
be shared.
|
||||
|
||||
2000-03-24 Geoff Keating <geoffk@cygnus.com>
|
||||
* flow.c (propagate_block): When we delete an ADDR_VEC,
|
||||
also delete the BARRIER following it if there is one.
|
||||
|
||||
Wed Oct 27 14:10:27 1999 Geoffrey Keating <geoffk@cygnus.com>
|
||||
* flow.c (propagate_block): When the last reference to a label
|
||||
before an ADDR_VEC is deleted because the reference is a dead
|
||||
store, delete the ADDR_VEC.
|
||||
|
||||
2000-03-19 Richard Henderson <rth@cygnus.com>
|
||||
* flow.c (delete_block): Delete the addr_vec along with the block.
|
||||
(flow_delete_insn): Decrement LABEL_NUSES when deleting insns that
|
||||
reference labels.
|
||||
|
||||
2000-12-02 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* reload1.c (free_for_value_p): New function, frontend to
|
||||
reload_reg_free_for_value_p. All callers of the latter now call
|
||||
this function with an additional mode argument.
|
||||
|
||||
2000-11-10 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
(regno_clobbered_p): New arg SETS. Examine SETs if it's nonzero. All
|
||||
callers changed.
|
||||
* reload1.c (choose_reload_regs): Registers set in the insn can't be
|
||||
used for RELOAD_OTHER reloads.
|
||||
|
||||
2000-10-28 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* reload1.c (choose_reload_regs): Never set reload_override_in for an
|
||||
optional reload.
|
||||
|
||||
2000-09-07 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* reload.c (regno_clobbered_p): Accept new arg, MODE, and use it
|
||||
to handle multiword modes correctly. All callers and the declaration
|
||||
changed.
|
||||
|
||||
2000-12-18 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* rs6000.c (and64_operand): Use logical_u_operand.
|
||||
(first_reg_to_save): Don't save fixed or call-used registers
|
||||
except PIC_OFFSET_TABLE_REGNUM when -fpic even though it is fixed.
|
||||
* rs6000.md (anddi3): Prefer rldic? over andis instruction.
|
||||
|
||||
2000-12-18 Zack Weinberg <zackw@Stanford.EDU>:
|
||||
|
||||
* Makefile.in: Rename cpp to cpp0, tradcpp to tradcpp0, and
|
||||
xcpp to cpp throughout.
|
||||
(native): Remove unnecessary dependency on cpp.
|
||||
* gcc.c (C specs): Call cpp0 to do preprocessing, not cpp.
|
||||
* ch/lang-specs.h, cp/lang-specs.h, f/lang-specs.h,
|
||||
objc/lang-specs.h: Call cpp0 to do preprocessing, not cpp.
|
||||
|
||||
2000-12-18 Christian Groessler <cpg@aladdin.de>
|
||||
|
||||
* toplev.c (check_lang_option): Use NUM_ELEM only on arrays, not on
|
||||
pointers.
|
||||
|
||||
2000-12-18 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* linux.h (DEFAULT_VTABLE_THUNKS): Switch back to version 1.
|
||||
* alpha/linux-elf.h (DEFAULT_VTABLE_THUNKS): Likewise.
|
||||
* arm/linux-elf (DEFAULT_VTABLE_THUNKS): Likewise.
|
||||
* i386/freebsd-elf.h (DEFAULT_VTABLE_THUNKS): Likewise.
|
||||
* rs6000/linux.h (DEFAULT_VTABLE_THUNKS): Likewise.
|
||||
* sparc/linux.h (DEFAULT_VTABLE_THUNKS): Likewise.
|
||||
|
||||
2000-12-05 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
* version.c: Bump.
|
||||
|
||||
2000-07-03 Nick Clifton <nickc@cygnus.com>
|
||||
* config/arm/arm.md: Fix post increment and pre increment
|
||||
peepholes so that they do not generate UNPREDICATBLE opcodes.
|
||||
(ie ones where the increment clobbers the source/destination).
|
||||
|
||||
Mon Oct 25 00:42:35 1999 Jeffrey A Law (law@cygnus.com)
|
||||
* arm.c (arm_override_options): Correct initialization of
|
||||
arm_fast_multiply, arm_arch4, arm_arch5, arm_ld_sched,
|
||||
arm_is_strong, and arm_is_6_or_7.
|
||||
|
||||
Thu Jul 29 19:01:58 1999 Bernd Schmidt <bernds@cygnus.co.uk>
|
||||
* arm.h (Hint): Delete macro.
|
||||
Substitute HOST_WIDE_INT for Hint in some prototypes.
|
||||
* arm.c: Substitute HOST_WIDE_INT for Hint in one prototype.
|
||||
|
||||
2000-11-30 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
* version.c: Bump.
|
||||
|
||||
Based on a patch from Geoff Keating <geoffk@redhat.com>:
|
||||
* loop.c (basic_induction_var): If a REG is set from something
|
||||
that is not a biv, then the REG is not a biv. Even if it is
|
||||
earlier set from something that is a biv.
|
||||
|
||||
2000-09-01 Jim Wilson <wilson@cygnus.com>
|
||||
* loop.c (check_final_value): Check for biv use before checking for
|
||||
giv use. Check for both biv and giv uses. Always set last_giv_use
|
||||
if there is a giv use.
|
||||
|
||||
2000-09-29 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
* loop.c (check_final_value): A GIV is not replaceable if used
|
||||
before set.
|
||||
|
||||
Sun Oct 10 13:28:48 1999 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* loop.c (find_and_verify_loops): When looking for a BARRIER, don't
|
||||
use one before a jump table.
|
||||
|
||||
Fri Jul 9 10:48:28 1999 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* loop.c (check_dbra_loop): When reversing a loop, delete all
|
||||
REG_EQUAL notes referencing the reversed biv except those which are
|
||||
for a giv based on it.
|
||||
|
||||
2000-11-24 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* reload1.c (conflicts_with_override): New function.
|
||||
(emit_input_reload_insns): Use it to tighten test for validity
|
||||
of substituting into output of previous insn.
|
||||
|
||||
Wed Oct 27 03:09:23 1999 J"orn Rennecke <amylaar@redhat.co.uk>
|
||||
* reload.h (earlyclobber_operand_p): Declare.
|
||||
* reload.c (earlyclobber_operand_p): Don't declare. No longer static.
|
||||
* reload1.c (reload_reg_free_for_value_p): RELOAD_OTHER reloads with
|
||||
an earlyclobbered output conflict with RELOAD_INPUT reloads - handle
|
||||
case where the RELOAD_OTHER reload is new. Use
|
||||
earlyclobber_operand_p.
|
||||
|
||||
2000-01-12 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* reload1.c (reload_reg_unavailable): New static variable.
|
||||
(reload_reg_free_p): Test it.
|
||||
(reload_reg_free_for_value_p): Test it instead of reload_reg_used.
|
||||
(choose_reload_regs_init): Compute it.
|
||||
|
||||
Thu Jul 6 18:30:36 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
* reload.c (push_reload): When seeing if can reuse a register,
|
||||
check extra registers against widest of INMODE and OUTMODE.
|
||||
|
||||
1999-11-29 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* reload.c (push_reload): When looking for a register to put into
|
||||
reg_rtx, make sure all hard regs in a multi-reg register are in the
|
||||
right class and nonfixed.
|
||||
|
||||
1999-11-29 Joern Rennecke <amylaar@redhat.co.uk>
|
||||
* reload1.c (reloads_conflict): Reverse test comparing operand
|
||||
numbers when testing for conflict between output/outaddr reloads.
|
||||
|
||||
2000-07-12 Richard Henderson <rth@redhat.com>
|
||||
* reload.c (push_secondary_reload): Make sure to add the new
|
||||
reload at the end, after acquiring secondary memory.
|
||||
|
||||
2000-09-14 Alexandre Oliva <aoliva@redhat.com>, Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* reload.c (find_reloads_address_1): Generate reloads for auto_inc
|
||||
pseudos that refer to the original pseudos, not only to their
|
||||
equivalent memory locations.
|
||||
|
||||
2000-09-18 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
* reload1.c (forget_old_reloads_1): If a hard reg is stored, clear
|
||||
its entry in spill_reg_store.
|
||||
|
||||
Tue Oct 26 00:41:54 1999 Bernd Schmidt <bernds@cygnus.co.uk>
|
||||
* reload1.c (reload_reg_free_for_value_p): Show
|
||||
RELOAD_FOR_OTHER_ADDRESS reloads can conflict with RELOAD_OTHER
|
||||
reloads.
|
||||
|
||||
2000-02-26 Geoff Keating <geoffk@cygnus.com>
|
||||
* reload1.c (do_output_reload): Check reg_reloaded_valid before
|
||||
looking at reg_reloaded_contents.
|
||||
|
||||
Thu Apr 13 19:39:56 2000 Clinton Popetz <cpopetz@cygnus.com>
|
||||
* emit-rtl.c (try_split): Avoid infinite loop if the split
|
||||
results in a sequence that contains the original insn.
|
||||
|
||||
1999-12-14 Bernd Schmidt <bernds@cygnus.co.uk>
|
||||
* combine.c (combine_simplify_rtx): Don't make shared rtl.
|
||||
(simplify_logical): Likewise.
|
||||
|
||||
Sat May 20 07:27:35 2000 Alexandre Oliva <aoliva@cygnus.com>
|
||||
* fold-const.c (make_range): Handle degenerated intervals.
|
||||
Fixes c-torture/execute/991221-1.c
|
||||
|
||||
2000-07-15 Michael Meissner <meissner@redhat.com>
|
||||
* fold-const.c (fold): When optimizing FOO++ == CONST into ++FOO
|
||||
== CONST + INCREMENT, don't overwrite the tree node for FOO++,
|
||||
create a new node instead.
|
||||
|
||||
2000-01-01 Bernd Schmidt <bernds@cygnus.co.uk>
|
||||
* expmed.c (emit_store_flag): Prevent losing a pending stack
|
||||
adjust the same way we prevent losing queued increments.
|
||||
|
||||
2000-10-27 Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
* expr.c (expand_expr, case INDIRECT_REF): If the address is a
|
||||
PLUS, that does not prove the object is in a structure.
|
||||
|
||||
2000-08-25 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* collect2.c (use_import_list): Always return 0 (disable).
|
||||
|
||||
2000-07-07 Manfred Hollstein <manfredh@redhat.com>
|
||||
|
||||
* i386.md (exception_receiver): Add missing parameter in
|
||||
call to load_pic_register.
|
||||
|
||||
Fri May 26 10:30:02 2000 Richard Earnshaw (rearnsha@arm.com)
|
||||
|
||||
* arm.md (negdi2): Add clobber of condition code register.
|
||||
|
@ -1455,15 +1455,6 @@ init_alias_analysis ()
|
||||
new_reg_base_value[HARD_FRAME_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
|
||||
#endif
|
||||
if (struct_value_incoming_rtx
|
||||
&& GET_CODE (struct_value_incoming_rtx) == REG)
|
||||
new_reg_base_value[REGNO (struct_value_incoming_rtx)]
|
||||
= gen_rtx_ADDRESS (Pmode, struct_value_incoming_rtx);
|
||||
|
||||
if (static_chain_rtx
|
||||
&& GET_CODE (static_chain_rtx) == REG)
|
||||
new_reg_base_value[REGNO (static_chain_rtx)]
|
||||
= gen_rtx_ADDRESS (Pmode, static_chain_rtx);
|
||||
|
||||
/* Walk the insns adding values to the new_reg_base_value array. */
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||
|
@ -405,7 +405,15 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
|
||||
|
||||
#ifndef ACCUMULATE_OUTGOING_ARGS
|
||||
#if defined (HAVE_call_pop) && defined (HAVE_call_value_pop)
|
||||
if (HAVE_call_pop && HAVE_call_value_pop && n_popped > 0)
|
||||
/* If the target has "call" or "call_value" insns, then prefer them
|
||||
if no arguments are actually popped. If the target does not have
|
||||
"call" or "call_value" insns, then we must use the popping versions
|
||||
even if the call has no arguments to pop. */
|
||||
if (HAVE_call_pop && HAVE_call_value_pop
|
||||
#if defined (HAVE_call) && defined (HAVE_call_value)
|
||||
&& (n_popped > 0 || ! HAVE_call || ! HAVE_call_value)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
rtx n_pop = GEN_INT (n_popped);
|
||||
rtx pat;
|
||||
|
@ -3045,21 +3045,11 @@ scan_prog_file (prog_name, which_pass)
|
||||
|
||||
#ifdef COLLECT_EXPORT_LIST
|
||||
|
||||
/* This new function is used to decide whether we should
|
||||
generate import list for an object or to use it directly. */
|
||||
/* Never generate import list (gcc-2.95 branch). */
|
||||
static int
|
||||
use_import_list (prog_name)
|
||||
char *prog_name;
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* If we do not build a shared object then import list should not be used. */
|
||||
if (! shared_obj) return 0;
|
||||
|
||||
/* Currently we check only for libgcc, but this can be changed in future. */
|
||||
p = strstr (prog_name, "libgcc.a");
|
||||
if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -392,6 +392,7 @@ static int n_occurrences;
|
||||
static void init_reg_last_arrays PROTO((void));
|
||||
static void setup_incoming_promotions PROTO((void));
|
||||
static void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx));
|
||||
static int cant_combine_insn_p PROTO((rtx));
|
||||
static int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *));
|
||||
static int sets_function_arg_p PROTO((rtx));
|
||||
static int combinable_i3pat PROTO((rtx, rtx *, rtx, rtx, int, rtx *));
|
||||
@ -1312,6 +1313,54 @@ combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Determine whether INSN can be used in a combination. Return nonzero if
|
||||
not. This is used in try_combine to detect early some cases where we
|
||||
can't perform combinations. */
|
||||
|
||||
static int
|
||||
cant_combine_insn_p (insn)
|
||||
rtx insn;
|
||||
{
|
||||
rtx set;
|
||||
rtx src, dest;
|
||||
|
||||
/* If this isn't really an insn, we can't do anything.
|
||||
This can occur when flow deletes an insn that it has merged into an
|
||||
auto-increment address. */
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
|
||||
return 1;
|
||||
|
||||
/* For the 2.95.3 release, restrict this code to only handle the machines
|
||||
where it's strictly needed. */
|
||||
if (! SMALL_REGISTER_CLASSES)
|
||||
return 0;
|
||||
|
||||
/* Never combine loads and stores involving hard regs. The register
|
||||
allocator can usually handle such reg-reg moves by tying. If we allow
|
||||
the combiner to make substitutions of hard regs, we risk aborting in
|
||||
reload on machines that have SMALL_REGISTER_CLASSES.
|
||||
As an exception, we allow combinations involving fixed regs; these are
|
||||
not available to the register allocator so there's no risk involved. */
|
||||
|
||||
set = single_set (insn);
|
||||
if (! set)
|
||||
return 0;
|
||||
src = SET_SRC (set);
|
||||
dest = SET_DEST (set);
|
||||
if (GET_CODE (src) == SUBREG)
|
||||
src = SUBREG_REG (src);
|
||||
if (GET_CODE (dest) == SUBREG)
|
||||
dest = SUBREG_REG (dest);
|
||||
if (REG_P (src) && REG_P (dest)
|
||||
&& ((REGNO (src) < FIRST_PSEUDO_REGISTER
|
||||
&& ! fixed_regs[REGNO (src)])
|
||||
|| (REGNO (dest) < FIRST_PSEUDO_REGISTER
|
||||
&& ! fixed_regs[REGNO (dest)])))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to combine the insns I1 and I2 into I3.
|
||||
Here I1 and I2 appear earlier than I3.
|
||||
I1 can be zero; then we combine just I2 into I3.
|
||||
@ -1362,21 +1411,20 @@ try_combine (i3, i2, i1)
|
||||
register rtx link;
|
||||
int i;
|
||||
|
||||
/* If any of I1, I2, and I3 isn't really an insn, we can't do anything.
|
||||
This can occur when flow deletes an insn that it has merged into an
|
||||
auto-increment address. We also can't do anything if I3 has a
|
||||
REG_LIBCALL note since we don't want to disrupt the contiguity of a
|
||||
libcall. */
|
||||
|
||||
if (GET_RTX_CLASS (GET_CODE (i3)) != 'i'
|
||||
|| GET_RTX_CLASS (GET_CODE (i2)) != 'i'
|
||||
|| (i1 && GET_RTX_CLASS (GET_CODE (i1)) != 'i')
|
||||
/* Exit early if one of the insns involved can't be used for
|
||||
combinations. */
|
||||
if (cant_combine_insn_p (i3)
|
||||
|| cant_combine_insn_p (i2)
|
||||
|| (i1 && cant_combine_insn_p (i1))
|
||||
/* We also can't do anything if I3 has a
|
||||
REG_LIBCALL note since we don't want to disrupt the contiguity of a
|
||||
libcall. */
|
||||
#if 0
|
||||
/* ??? This gives worse code, and appears to be unnecessary, since no
|
||||
pass after flow uses REG_LIBCALL/REG_RETVAL notes. */
|
||||
|| find_reg_note (i3, REG_LIBCALL, NULL_RTX)
|
||||
#endif
|
||||
)
|
||||
)
|
||||
return 0;
|
||||
|
||||
combine_attempts++;
|
||||
@ -4015,7 +4063,8 @@ simplify_rtx (x, op0_mode, last, in_dest)
|
||||
gen_binary (MULT, mode,
|
||||
XEXP (XEXP (x, 0), 0), XEXP (x, 1)),
|
||||
gen_binary (MULT, mode,
|
||||
XEXP (XEXP (x, 0), 1), XEXP (x, 1))));
|
||||
XEXP (XEXP (x, 0), 1),
|
||||
copy_rtx (XEXP (x, 1)))));
|
||||
|
||||
if (GET_CODE (x) != MULT)
|
||||
return x;
|
||||
@ -4954,7 +5003,8 @@ simplify_logical (x, last)
|
||||
x = apply_distributive_law
|
||||
(gen_binary (GET_CODE (op0), mode,
|
||||
gen_binary (AND, mode, XEXP (op0, 0), op1),
|
||||
gen_binary (AND, mode, XEXP (op0, 1), op1)));
|
||||
gen_binary (AND, mode, XEXP (op0, 1),
|
||||
copy_rtx (op1))));
|
||||
if (GET_CODE (x) != AND)
|
||||
return x;
|
||||
}
|
||||
@ -4963,7 +5013,8 @@ simplify_logical (x, last)
|
||||
return apply_distributive_law
|
||||
(gen_binary (GET_CODE (op1), mode,
|
||||
gen_binary (AND, mode, XEXP (op1, 0), op0),
|
||||
gen_binary (AND, mode, XEXP (op1, 1), op0)));
|
||||
gen_binary (AND, mode, XEXP (op1, 1),
|
||||
copy_rtx (op0))));
|
||||
|
||||
/* Similarly, taking advantage of the fact that
|
||||
(and (not A) (xor B C)) == (xor (ior A B) (ior A C)) */
|
||||
@ -4972,13 +5023,14 @@ simplify_logical (x, last)
|
||||
return apply_distributive_law
|
||||
(gen_binary (XOR, mode,
|
||||
gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)),
|
||||
gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 1))));
|
||||
gen_binary (IOR, mode, copy_rtx (XEXP (op0, 0)),
|
||||
XEXP (op1, 1))));
|
||||
|
||||
else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR)
|
||||
return apply_distributive_law
|
||||
(gen_binary (XOR, mode,
|
||||
gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)),
|
||||
gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 1))));
|
||||
gen_binary (IOR, mode, copy_rtx (XEXP (op1, 0)), XEXP (op0, 1))));
|
||||
break;
|
||||
|
||||
case IOR:
|
||||
@ -5004,7 +5056,8 @@ simplify_logical (x, last)
|
||||
x = apply_distributive_law
|
||||
(gen_binary (AND, mode,
|
||||
gen_binary (IOR, mode, XEXP (op0, 0), op1),
|
||||
gen_binary (IOR, mode, XEXP (op0, 1), op1)));
|
||||
gen_binary (IOR, mode, XEXP (op0, 1),
|
||||
copy_rtx (op1))));
|
||||
|
||||
if (GET_CODE (x) != IOR)
|
||||
return x;
|
||||
@ -5015,7 +5068,8 @@ simplify_logical (x, last)
|
||||
x = apply_distributive_law
|
||||
(gen_binary (AND, mode,
|
||||
gen_binary (IOR, mode, XEXP (op1, 0), op0),
|
||||
gen_binary (IOR, mode, XEXP (op1, 1), op0)));
|
||||
gen_binary (IOR, mode, XEXP (op1, 1),
|
||||
copy_rtx (op0))));
|
||||
|
||||
if (GET_CODE (x) != IOR)
|
||||
return x;
|
||||
|
@ -38,7 +38,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef USE_GNULIBC_1
|
||||
#undef DEFAULT_VTABLE_THUNKS
|
||||
#define DEFAULT_VTABLE_THUNKS 2
|
||||
#define DEFAULT_VTABLE_THUNKS 1
|
||||
#endif
|
||||
|
||||
#ifndef USE_GNULIBC_1
|
||||
|
@ -89,7 +89,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef USE_GNULIBC_1
|
||||
#undef DEFAULT_VTABLE_THUNKS
|
||||
#define DEFAULT_VTABLE_THUNKS 2
|
||||
#define DEFAULT_VTABLE_THUNKS 1
|
||||
#endif
|
||||
|
||||
#undef LIB_SPEC
|
||||
|
@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef USE_GNULIBC_1
|
||||
#undef DEFAULT_VTABLE_THUNKS
|
||||
#define DEFAULT_VTABLE_THUNKS 2
|
||||
#define DEFAULT_VTABLE_THUNKS 1
|
||||
#endif
|
||||
|
||||
/* Use stabs instead of DWARF debug format. */
|
||||
|
@ -2429,6 +2429,9 @@ int
|
||||
pic_address_needs_scratch (x)
|
||||
rtx x;
|
||||
{
|
||||
if (GET_CODE (x) == LABEL_REF)
|
||||
return 1;
|
||||
|
||||
/* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
|
||||
if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
|
||||
|
@ -756,15 +756,31 @@ changequote([,])dnl
|
||||
tmake_file=arm/t-linux
|
||||
gnu_ld=yes
|
||||
;;
|
||||
arm*-*-linux-gnuoldld*) # ARM GNU/Linux with old ELF linker
|
||||
xm_file=arm/xm-linux.h
|
||||
xmake_file=x-linux
|
||||
tm_file="arm/linux-oldld.h arm/linux-elf.h"
|
||||
case $machine in
|
||||
armv2*-*-*)
|
||||
tm_file="arm/linux-elf26.h $tm_file"
|
||||
;;
|
||||
esac
|
||||
tmake_file="t-linux arm/t-linux"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
case x${enable_threads} in
|
||||
x | xyes | xpthreads | xposix)
|
||||
thread_file='posix'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
arm*-*-linux-gnu*) # ARM GNU/Linux with ELF
|
||||
xm_file=arm/xm-linux.h
|
||||
xmake_file=x-linux
|
||||
tm_file="arm/linux-elf.h"
|
||||
case $machine in
|
||||
armv2*-*-*)
|
||||
tm_file=arm/linux-elf26.h
|
||||
;;
|
||||
*)
|
||||
tm_file=arm/linux-elf.h
|
||||
tm_file="arm/linux-elf26.h $tm_file"
|
||||
;;
|
||||
esac
|
||||
tmake_file="t-linux arm/t-linux"
|
||||
@ -3731,7 +3747,8 @@ ALL_LINGUAS="en_UK"
|
||||
|
||||
# NLS support is still experimental, so disable it by default for now.
|
||||
AC_ARG_ENABLE(nls,
|
||||
[ --enable-nls use Native Language Support (disabled by default)],
|
||||
[ --enable-nls use Native Language Support (disabled by default).
|
||||
EXPERIMENTAL, see ABOUT-GCC-NLS.],
|
||||
, enable_nls=no)
|
||||
|
||||
AM_GNU_GETTEXT
|
||||
|
@ -1,3 +1,19 @@
|
||||
Fri Jun 9 17:55:08 2000 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
2000-02-07 <loewis@informatik.hu-berlin.de>
|
||||
* decl2.c (import_export_decl): vlist ctor wrappers follow virtual
|
||||
methods in their interface.
|
||||
(vlist_ctor_wrapper_p): new function.
|
||||
(finish_vlist_ctor_wrapper): likewise.
|
||||
|
||||
2000-02-06 <loewis@informatik.hu-berlin.de>
|
||||
* decl2.c (maybe_retrofit_in_chrg): Move call to
|
||||
make_vlist_ctor_wrapper from here ...
|
||||
* decl.c (grok_ctor_properties): ... to here.
|
||||
* decl.c (grokfndecl): ... and here.
|
||||
* init.c (no_vlist_base_init): Declare unseen Vlist ctor weak.
|
||||
* decl2.c (maybe_retrofit_in_chrg): Be sorry about varargs ctors.
|
||||
|
||||
2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* exception.cc (__cp_pop_exception): Cleanup the original object.
|
||||
|
@ -980,7 +980,11 @@ maybe_retrofit_in_chrg (fn)
|
||||
if (DECL_CONSTRUCTOR_P (fn))
|
||||
{
|
||||
if (TYPE_USES_PVBASES (DECL_CLASS_CONTEXT (fn)))
|
||||
DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_PVBASE;
|
||||
{
|
||||
DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_PVBASE;
|
||||
if (flag_vtable_thunks_compat && varargs_function_p (fn))
|
||||
sorry ("-fvtable-thunks=2 for vararg constructor", fn);
|
||||
}
|
||||
else
|
||||
DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_VBASE;
|
||||
}
|
||||
@ -1028,10 +1032,6 @@ maybe_retrofit_in_chrg (fn)
|
||||
fntype = build_exception_variant (fntype,
|
||||
TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
|
||||
TREE_TYPE (fn) = fntype;
|
||||
|
||||
if (flag_vtable_thunks_compat
|
||||
&& DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))
|
||||
make_vlist_ctor_wrapper (fn);
|
||||
}
|
||||
|
||||
/* Classes overload their constituent function names automatically.
|
||||
@ -2854,6 +2854,30 @@ import_export_decl (decl)
|
||||
else
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 0;
|
||||
}
|
||||
else if (DECL_VLIST_CTOR_WRAPPER_P (decl))
|
||||
{
|
||||
int implement;
|
||||
tree ctype = DECL_CLASS_CONTEXT (decl);
|
||||
import_export_class (ctype);
|
||||
if (!DECL_THIS_INLINE (DECL_VLIST_CTOR_WRAPPED (decl)))
|
||||
{
|
||||
/* No change. */
|
||||
}
|
||||
else if (CLASSTYPE_INTERFACE_KNOWN (ctype))
|
||||
{
|
||||
implement = !CLASSTYPE_INTERFACE_ONLY (ctype)
|
||||
&& flag_implement_inlines;
|
||||
DECL_NOT_REALLY_EXTERN (decl) = implement;
|
||||
DECL_EXTERNAL (decl) = !implement;
|
||||
}
|
||||
else
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
}
|
||||
if (flag_weak)
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else if (DECL_FUNCTION_MEMBER_P (decl))
|
||||
{
|
||||
tree ctype = DECL_CLASS_CONTEXT (decl);
|
||||
@ -3606,6 +3630,33 @@ generate_ctor_and_dtor_functions_for_priority (n, data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns non-zero if T is a vlist ctor wrapper. */
|
||||
|
||||
static int
|
||||
vlist_ctor_wrapper_p (t, data)
|
||||
tree t;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return (TREE_CODE (t) == FUNCTION_DECL) && DECL_VLIST_CTOR_WRAPPER_P (t);
|
||||
}
|
||||
|
||||
/* Emits a vlist ctor wrapper if necessary. */
|
||||
|
||||
static int
|
||||
finish_vlist_ctor_wrapper (t, data)
|
||||
tree *t;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
import_export_decl (*t);
|
||||
if (!DECL_EXTERNAL (*t) && !TREE_USED (*t))
|
||||
{
|
||||
mark_used (*t);
|
||||
synthesize_method (*t);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This routine is called from the last rule in yyparse ().
|
||||
Its job is to create all the code needed to initialize and
|
||||
destroy the global aggregates. We do the destruction
|
||||
@ -3682,6 +3733,12 @@ finish_file ()
|
||||
/*data=*/0))
|
||||
reconsider = 1;
|
||||
|
||||
if (walk_globals (vlist_ctor_wrapper_p,
|
||||
finish_vlist_ctor_wrapper,
|
||||
/*data=*/0))
|
||||
reconsider = 1;
|
||||
|
||||
|
||||
/* The list of objects with static storage duration is built up
|
||||
in reverse order, so we reverse it here. We also clear
|
||||
STATIC_AGGREGATES so that any new aggregates added during the
|
||||
|
@ -1262,6 +1262,14 @@ no_vlist_base_init (rval, exp, init, binfo, flags)
|
||||
my_friendly_assert (TREE_CODE (func) == CALL_EXPR, 20000131);
|
||||
func = TREE_OPERAND (func, 0);
|
||||
my_friendly_assert (TREE_CODE (func) == ADDR_EXPR, 20000132);
|
||||
func = TREE_OPERAND (func, 0);
|
||||
my_friendly_assert (TREE_CODE (func) == FUNCTION_DECL, 20000133);
|
||||
|
||||
/* If we have already seen a definition for the wrapped function,
|
||||
we don't need to declare it weak. Also, declare_weak will complain
|
||||
if we do. */
|
||||
if (!TREE_ASM_WRITTEN (func))
|
||||
declare_weak (func);
|
||||
|
||||
if (init == NULL_TREE
|
||||
|| (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))
|
||||
|
@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA. */
|
||||
{"@c++",
|
||||
#if USE_CPPLIB
|
||||
{
|
||||
"%{E|M|MM:cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
"%{E|M|MM:cpp0 -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
%{C:%{!E:%eGNU C++ does not support -C without using -E}}\
|
||||
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
|
||||
%{!no-gcc:-D__GNUC__=%v1 -D__GNUG__=%v1 -D__GNUC_MINOR__=%v2}\
|
||||
@ -62,7 +62,7 @@ Boston, MA 02111-1307, USA. */
|
||||
%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
|
||||
%{!pipe:%g.s} %A\n }}}}"}},
|
||||
#else /* ! USE_CPPLIB */
|
||||
{"cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
{"cpp0 -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
%{C:%{!E:%eGNU C++ does not support -C without using -E}}\
|
||||
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
|
||||
%{!no-gcc:-D__GNUC__=%v1 -D__GNUG__=%v1 -D__GNUC_MINOR__=%v2}\
|
||||
|
@ -2241,13 +2241,18 @@ emit_thunk (thunk_fndecl)
|
||||
}
|
||||
|
||||
void
|
||||
make_vlist_ctor_wrapper (fn)
|
||||
maybe_vlist_ctor_wrapper (fn, definep)
|
||||
tree fn;
|
||||
int definep;
|
||||
{
|
||||
tree fntype, decl;
|
||||
tree arg_types, parms, parm, basetype, pbasetype;
|
||||
tree t, ctors;
|
||||
|
||||
if (!flag_vtable_thunks_compat
|
||||
|| !DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))
|
||||
return;
|
||||
|
||||
arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
pbasetype = TREE_VALUE (arg_types);
|
||||
basetype = TREE_TYPE (pbasetype);
|
||||
@ -2324,15 +2329,23 @@ make_vlist_ctor_wrapper (fn)
|
||||
/* Remember the original function. */
|
||||
DECL_VLIST_CTOR_WRAPPED (decl) = fn;
|
||||
|
||||
/* When fn is declared, DECL_INITIAL is null. When it is defined,
|
||||
DECL_INITIAL will be error_mark_node. */
|
||||
if (DECL_INITIAL (fn) == error_mark_node)
|
||||
/* If this is called from start_method, definep is -1. Then we
|
||||
are inside the class, and fn is inline by default. */
|
||||
if (definep)
|
||||
{
|
||||
/* Record that the ctor is being defined, so we also emit the
|
||||
wrapper later. */
|
||||
TREE_USED (decl) = 1;
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 1;
|
||||
DECL_INITIAL (decl) = NULL_TREE;
|
||||
wrapper later. */
|
||||
if (DECL_THIS_INLINE (fn) || (definep == -1))
|
||||
{
|
||||
DECL_THIS_INLINE (decl) = 1;
|
||||
DECL_INLINE (decl) = 1;
|
||||
pushdecl_top_level (decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
TREE_USED (decl) = 1;
|
||||
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = 1;
|
||||
}
|
||||
mark_inline_for_output (decl);
|
||||
}
|
||||
}
|
||||
@ -2651,6 +2664,3 @@ synthesize_method (fndecl)
|
||||
else if (nested)
|
||||
pop_cp_function_context (context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Declarations and definitions of codes relating to the DWARF2 symbolic
|
||||
debugging information format.
|
||||
Copyright (C) 1992, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1995, 1996, 1997, 2000
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Gary Funck (gary@intrepid.com). Derived from the
|
||||
DWARF 1 implementation written by Ron Guilmette (rfg@monkeys.com).
|
||||
|
||||
@ -501,7 +502,8 @@ enum dwarf_call_frame_info
|
||||
|
||||
/* GNU extensions */
|
||||
DW_CFA_GNU_window_save = 0x2d,
|
||||
DW_CFA_GNU_args_size = 0x2e
|
||||
DW_CFA_GNU_args_size = 0x2e,
|
||||
DW_CFA_GNU_negative_offset_extended = 0x2f
|
||||
};
|
||||
|
||||
#define DW_CIE_ID 0xffffffff
|
||||
|
@ -719,6 +719,8 @@ dwarf_cfi_name (cfi_opc)
|
||||
return "DW_CFA_GNU_window_save";
|
||||
case DW_CFA_GNU_args_size:
|
||||
return "DW_CFA_GNU_args_size";
|
||||
case DW_CFA_GNU_negative_offset_extended:
|
||||
return "DW_CFA_GNU_negative_offset_extended";
|
||||
|
||||
default:
|
||||
return "DW_CFA_<unknown>";
|
||||
@ -948,7 +950,10 @@ reg_save (label, reg, sreg, offset)
|
||||
|
||||
offset /= DWARF_CIE_DATA_ALIGNMENT;
|
||||
if (offset < 0)
|
||||
abort ();
|
||||
{
|
||||
cfi->dw_cfi_opc = DW_CFA_GNU_negative_offset_extended;
|
||||
offset = -offset;
|
||||
}
|
||||
cfi->dw_cfi_oprnd2.dw_cfi_offset = offset;
|
||||
}
|
||||
else
|
||||
@ -1635,6 +1640,7 @@ output_cfi (cfi, fde)
|
||||
break;
|
||||
#endif
|
||||
case DW_CFA_offset_extended:
|
||||
case DW_CFA_GNU_negative_offset_extended:
|
||||
case DW_CFA_def_cfa:
|
||||
output_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
|
||||
fputc ('\n', asm_out_file);
|
||||
|
@ -1847,25 +1847,17 @@ copy_rtx_if_shared (orig)
|
||||
return x;
|
||||
|
||||
case MEM:
|
||||
/* A MEM is allowed to be shared if its address is constant
|
||||
or is a constant plus one of the special registers. */
|
||||
if (CONSTANT_ADDRESS_P (XEXP (x, 0))
|
||||
|| XEXP (x, 0) == virtual_stack_vars_rtx
|
||||
|| XEXP (x, 0) == virtual_incoming_args_rtx)
|
||||
/* A MEM is allowed to be shared if its address is constant.
|
||||
|
||||
We used to allow sharing of MEMs which referenced
|
||||
virtual_stack_vars_rtx or virtual_incoming_args_rtx, but
|
||||
that can lose. instantiate_virtual_regs will not unshare
|
||||
the MEMs, and combine may change the structure of the address
|
||||
because it looks safe and profitable in one context, but
|
||||
in some other context it creates unrecognizable RTL. */
|
||||
if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
|
||||
return x;
|
||||
|
||||
if (GET_CODE (XEXP (x, 0)) == PLUS
|
||||
&& (XEXP (XEXP (x, 0), 0) == virtual_stack_vars_rtx
|
||||
|| XEXP (XEXP (x, 0), 0) == virtual_incoming_args_rtx)
|
||||
&& CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
|
||||
{
|
||||
/* This MEM can appear in more than one place,
|
||||
but its address better not be shared with anything else. */
|
||||
if (! x->used)
|
||||
XEXP (x, 0) = copy_rtx_if_shared (XEXP (x, 0));
|
||||
x->used = 1;
|
||||
return x;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2359,10 +2351,18 @@ try_split (pat, trial, last)
|
||||
it, in turn, will be split (SFmode on the 29k is an example). */
|
||||
if (GET_CODE (seq) == SEQUENCE)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Avoid infinite loop if any insn of the result matches
|
||||
the original pattern. */
|
||||
for (i = 0; i < XVECLEN (seq, 0); i++)
|
||||
if (GET_CODE (XVECEXP (seq, 0, i)) == INSN
|
||||
&& rtx_equal_p (PATTERN (XVECEXP (seq, 0, i)), pat))
|
||||
return trial;
|
||||
|
||||
/* If we are splitting a JUMP_INSN, look for the JUMP_INSN in
|
||||
SEQ and copy our JUMP_LABEL to it. If JUMP_LABEL is non-zero,
|
||||
increment the usage count so we don't delete the label. */
|
||||
int i;
|
||||
|
||||
if (GET_CODE (trial) == JUMP_INSN)
|
||||
for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
|
||||
|
@ -723,21 +723,41 @@ static void
|
||||
receive_exception_label (handler_label)
|
||||
rtx handler_label;
|
||||
{
|
||||
rtx around_label = NULL_RTX;
|
||||
|
||||
if (! flag_new_exceptions || exceptions_via_longjmp)
|
||||
{
|
||||
around_label = gen_label_rtx ();
|
||||
emit_jump (around_label);
|
||||
emit_barrier ();
|
||||
}
|
||||
|
||||
emit_label (handler_label);
|
||||
|
||||
if (! exceptions_via_longjmp)
|
||||
{
|
||||
#ifdef HAVE_exception_receiver
|
||||
if (! exceptions_via_longjmp)
|
||||
if (HAVE_exception_receiver)
|
||||
emit_insn (gen_exception_receiver ());
|
||||
if (HAVE_exception_receiver)
|
||||
emit_insn (gen_exception_receiver ());
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_nonlocal_goto_receiver
|
||||
if (! exceptions_via_longjmp)
|
||||
if (HAVE_nonlocal_goto_receiver)
|
||||
emit_insn (gen_nonlocal_goto_receiver ());
|
||||
if (HAVE_nonlocal_goto_receiver)
|
||||
emit_insn (gen_nonlocal_goto_receiver ());
|
||||
else
|
||||
#endif
|
||||
}
|
||||
{ /* Nothing */ }
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef DONT_USE_BUILTIN_SETJMP
|
||||
expand_builtin_setjmp_receiver (handler_label);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (around_label)
|
||||
emit_label (around_label);
|
||||
}
|
||||
|
||||
struct func_eh_entry
|
||||
{
|
||||
@ -1320,7 +1340,7 @@ static void
|
||||
start_dynamic_handler ()
|
||||
{
|
||||
rtx dhc, dcc;
|
||||
rtx x, arg, buf;
|
||||
rtx arg, buf;
|
||||
int size;
|
||||
|
||||
#ifndef DONT_USE_BUILTIN_SETJMP
|
||||
@ -1362,18 +1382,17 @@ start_dynamic_handler ()
|
||||
buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
|
||||
|
||||
#ifdef DONT_USE_BUILTIN_SETJMP
|
||||
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1,
|
||||
buf, Pmode);
|
||||
/* If we come back here for a catch, transfer control to the handler. */
|
||||
jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
|
||||
#else
|
||||
{
|
||||
/* A label to continue execution for the no exception case. */
|
||||
rtx noex = gen_label_rtx();
|
||||
x = expand_builtin_setjmp (buf, NULL_RTX, noex,
|
||||
ehstack.top->entry->exception_handler_label);
|
||||
emit_label (noex);
|
||||
rtx x;
|
||||
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST,
|
||||
TYPE_MODE (integer_type_node), 1,
|
||||
buf, Pmode);
|
||||
/* If we come back here for a catch, transfer control to the handler. */
|
||||
jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
|
||||
}
|
||||
#else
|
||||
expand_builtin_setjmp_setup (buf,
|
||||
ehstack.top->entry->exception_handler_label);
|
||||
#endif
|
||||
|
||||
/* We are committed to this, so update the handler chain. */
|
||||
|
@ -4194,9 +4194,11 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
|
||||
comparison and then the scc insn.
|
||||
|
||||
compare_from_rtx may call emit_queue, which would be deleted below
|
||||
if the scc insn fails. So call it ourselves before setting LAST. */
|
||||
if the scc insn fails. So call it ourselves before setting LAST.
|
||||
Likewise for do_pending_stack_adjust. */
|
||||
|
||||
emit_queue ();
|
||||
do_pending_stack_adjust ();
|
||||
last = get_last_insn ();
|
||||
|
||||
comparison
|
||||
|
@ -191,6 +191,7 @@ static rtx expand_builtin PROTO((tree, rtx, rtx,
|
||||
static int apply_args_size PROTO((void));
|
||||
static int apply_result_size PROTO((void));
|
||||
static rtx result_vector PROTO((int, rtx));
|
||||
static rtx expand_builtin_setjmp PROTO((tree, rtx));
|
||||
static rtx expand_builtin_apply_args PROTO((void));
|
||||
static rtx expand_builtin_apply PROTO((rtx, rtx, rtx));
|
||||
static void expand_builtin_return PROTO((rtx));
|
||||
@ -2679,19 +2680,79 @@ emit_move_insn_1 (x, y)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Show the output dies here. This is necessary for pseudos;
|
||||
rtx realpart_x, realpart_y;
|
||||
rtx imagpart_x, imagpart_y;
|
||||
|
||||
/* If this is a complex value with each part being smaller than a
|
||||
word, the usual calling sequence will likely pack the pieces into
|
||||
a single register. Unfortunately, SUBREG of hard registers only
|
||||
deals in terms of words, so we have a problem converting input
|
||||
arguments to the CONCAT of two registers that is used elsewhere
|
||||
for complex values. If this is before reload, we can copy it into
|
||||
memory and reload. FIXME, we should see about using extract and
|
||||
insert on integer registers, but complex short and complex char
|
||||
variables should be rarely used. */
|
||||
if (GET_MODE_BITSIZE (mode) < 2*BITS_PER_WORD
|
||||
&& (reload_in_progress | reload_completed) == 0)
|
||||
{
|
||||
int packed_dest_p = (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER);
|
||||
int packed_src_p = (REG_P (y) && REGNO (y) < FIRST_PSEUDO_REGISTER);
|
||||
|
||||
if (packed_dest_p || packed_src_p)
|
||||
{
|
||||
enum mode_class reg_class = ((class == MODE_COMPLEX_FLOAT)
|
||||
? MODE_FLOAT : MODE_INT);
|
||||
|
||||
enum machine_mode reg_mode =
|
||||
mode_for_size (GET_MODE_BITSIZE (mode), reg_class, 1);
|
||||
|
||||
if (reg_mode != BLKmode)
|
||||
{
|
||||
rtx mem = assign_stack_temp (reg_mode,
|
||||
GET_MODE_SIZE (mode), 0);
|
||||
|
||||
rtx cmem = change_address (mem, mode, NULL_RTX);
|
||||
|
||||
current_function_cannot_inline
|
||||
= "function using short complex types cannot be inline";
|
||||
|
||||
if (packed_dest_p)
|
||||
{
|
||||
rtx sreg = gen_rtx_SUBREG (reg_mode, x, 0);
|
||||
emit_move_insn_1 (cmem, y);
|
||||
return emit_move_insn_1 (sreg, mem);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx sreg = gen_rtx_SUBREG (reg_mode, y, 0);
|
||||
emit_move_insn_1 (mem, sreg);
|
||||
return emit_move_insn_1 (x, cmem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
realpart_x = gen_realpart (submode, x);
|
||||
realpart_y = gen_realpart (submode, y);
|
||||
imagpart_x = gen_imagpart (submode, x);
|
||||
imagpart_y = gen_imagpart (submode, y);
|
||||
|
||||
/* Show the output dies here. This is necessary for SUBREGs
|
||||
of pseudos since we cannot track their lifetimes correctly;
|
||||
hard regs shouldn't appear here except as return values.
|
||||
We never want to emit such a clobber after reload. */
|
||||
if (x != y
|
||||
&& ! (reload_in_progress || reload_completed))
|
||||
&& ! (reload_in_progress || reload_completed)
|
||||
&& (GET_CODE (realpart_x) == SUBREG
|
||||
|| GET_CODE (imagpart_x) == SUBREG))
|
||||
{
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
|
||||
}
|
||||
|
||||
emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
|
||||
(gen_realpart (submode, x), gen_realpart (submode, y)));
|
||||
(realpart_x, realpart_y));
|
||||
emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
|
||||
(gen_imagpart (submode, x), gen_imagpart (submode, y)));
|
||||
(imagpart_x, imagpart_y));
|
||||
}
|
||||
|
||||
return get_last_insn ();
|
||||
@ -2703,6 +2764,8 @@ emit_move_insn_1 (x, y)
|
||||
else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
|
||||
{
|
||||
rtx last_insn = 0;
|
||||
rtx seq;
|
||||
int need_clobber;
|
||||
|
||||
#ifdef PUSH_ROUNDING
|
||||
|
||||
@ -2715,15 +2778,9 @@ emit_move_insn_1 (x, y)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Show the output dies here. This is necessary for pseudos;
|
||||
hard regs shouldn't appear here except as return values.
|
||||
We never want to emit such a clobber after reload. */
|
||||
if (x != y
|
||||
&& ! (reload_in_progress || reload_completed))
|
||||
{
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
|
||||
}
|
||||
start_sequence ();
|
||||
|
||||
need_clobber = 0;
|
||||
for (i = 0;
|
||||
i < (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
|
||||
i++)
|
||||
@ -2745,9 +2802,27 @@ emit_move_insn_1 (x, y)
|
||||
if (xpart == 0 || ypart == 0)
|
||||
abort ();
|
||||
|
||||
need_clobber |= (GET_CODE (xpart) == SUBREG);
|
||||
|
||||
last_insn = emit_move_insn (xpart, ypart);
|
||||
}
|
||||
|
||||
seq = gen_sequence ();
|
||||
end_sequence ();
|
||||
|
||||
/* Show the output dies here. This is necessary for SUBREGs
|
||||
of pseudos since we cannot track their lifetimes correctly;
|
||||
hard regs shouldn't appear here except as return values.
|
||||
We never want to emit such a clobber after reload. */
|
||||
if (x != y
|
||||
&& ! (reload_in_progress || reload_completed)
|
||||
&& need_clobber != 0)
|
||||
{
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
|
||||
}
|
||||
|
||||
emit_insn (seq);
|
||||
|
||||
return last_insn;
|
||||
}
|
||||
else
|
||||
@ -6262,12 +6337,8 @@ expand_expr (exp, target, tmode, modifier)
|
||||
}
|
||||
|
||||
temp = gen_rtx_MEM (mode, op0);
|
||||
/* If address was computed by addition,
|
||||
mark this as an element of an aggregate. */
|
||||
if (TREE_CODE (exp1) == PLUS_EXPR
|
||||
|| (TREE_CODE (exp1) == SAVE_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (exp1, 0)) == PLUS_EXPR)
|
||||
|| AGGREGATE_TYPE_P (TREE_TYPE (exp))
|
||||
|
||||
if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
|
||||
|| (TREE_CODE (exp1) == ADDR_EXPR
|
||||
&& (exp2 = TREE_OPERAND (exp1, 0))
|
||||
&& AGGREGATE_TYPE_P (TREE_TYPE (exp2))))
|
||||
@ -8473,44 +8544,29 @@ expand_builtin_return_addr (fndecl_code, count, tem)
|
||||
return tem;
|
||||
}
|
||||
|
||||
/* __builtin_setjmp is passed a pointer to an array of five words (not
|
||||
all will be used on all machines). It operates similarly to the C
|
||||
library function of the same name, but is more efficient. Much of
|
||||
the code below (and for longjmp) is copied from the handling of
|
||||
non-local gotos.
|
||||
/* Construct the leading half of a __builtin_setjmp call. Control will
|
||||
return to RECEIVER_LABEL. This is used directly by sjlj exception
|
||||
handling code. */
|
||||
|
||||
NOTE: This is intended for use by GNAT and the exception handling
|
||||
scheme in the compiler and will only work in the method used by
|
||||
them. */
|
||||
|
||||
rtx
|
||||
expand_builtin_setjmp (buf_addr, target, first_label, next_label)
|
||||
void
|
||||
expand_builtin_setjmp_setup (buf_addr, receiver_label)
|
||||
rtx buf_addr;
|
||||
rtx target;
|
||||
rtx first_label, next_label;
|
||||
rtx receiver_label;
|
||||
{
|
||||
rtx lab1 = gen_label_rtx ();
|
||||
enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
|
||||
enum machine_mode value_mode;
|
||||
rtx stack_save;
|
||||
|
||||
value_mode = TYPE_MODE (integer_type_node);
|
||||
|
||||
#ifdef POINTERS_EXTEND_UNSIGNED
|
||||
buf_addr = convert_memory_address (Pmode, buf_addr);
|
||||
#endif
|
||||
|
||||
buf_addr = force_reg (Pmode, buf_addr);
|
||||
|
||||
if (target == 0 || GET_CODE (target) != REG
|
||||
|| REGNO (target) < FIRST_PSEUDO_REGISTER)
|
||||
target = gen_reg_rtx (value_mode);
|
||||
|
||||
emit_queue ();
|
||||
|
||||
/* We store the frame pointer and the address of lab1 in the buffer
|
||||
and use the rest of it for the stack save area, which is
|
||||
machine-dependent. */
|
||||
/* We store the frame pointer and the address of receiver_label in
|
||||
the buffer and use the rest of it for the stack save area, which
|
||||
is machine-dependent. */
|
||||
|
||||
#ifndef BUILTIN_SETJMP_FRAME_VALUE
|
||||
#define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
|
||||
@ -8522,7 +8578,7 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
|
||||
(gen_rtx_MEM (Pmode,
|
||||
plus_constant (buf_addr,
|
||||
GET_MODE_SIZE (Pmode)))),
|
||||
force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
|
||||
force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
|
||||
|
||||
stack_save = gen_rtx_MEM (sa_mode,
|
||||
plus_constant (buf_addr,
|
||||
@ -8535,20 +8591,22 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
|
||||
emit_insn (gen_builtin_setjmp_setup (buf_addr));
|
||||
#endif
|
||||
|
||||
/* Set TARGET to zero and branch to the first-time-through label. */
|
||||
emit_move_insn (target, const0_rtx);
|
||||
emit_jump_insn (gen_jump (first_label));
|
||||
emit_barrier ();
|
||||
emit_label (lab1);
|
||||
|
||||
/* Tell flow about the strange goings on. Putting `lab1' on
|
||||
`nonlocal_goto_handler_labels' to indicates that function
|
||||
calls may traverse the arc back to this label. */
|
||||
/* Tell optimize_save_area_alloca that extra work is going to
|
||||
need to go on during alloca. */
|
||||
current_function_calls_setjmp = 1;
|
||||
|
||||
/* Set this so all the registers get saved in our frame; we need to be
|
||||
able to copy the saved values for any registers from frames we unwind. */
|
||||
current_function_has_nonlocal_label = 1;
|
||||
nonlocal_goto_handler_labels =
|
||||
gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
|
||||
}
|
||||
|
||||
/* Construct the trailing part of a __builtin_setjmp call.
|
||||
This is used directly by sjlj exception handling code. */
|
||||
|
||||
void
|
||||
expand_builtin_setjmp_receiver (receiver_label)
|
||||
rtx receiver_label ATTRIBUTE_UNUSED;
|
||||
{
|
||||
/* Clobber the FP when we get here, so we have to make sure it's
|
||||
marked as used by this function. */
|
||||
emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
|
||||
@ -8595,7 +8653,7 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
|
||||
|
||||
#ifdef HAVE_builtin_setjmp_receiver
|
||||
if (HAVE_builtin_setjmp_receiver)
|
||||
emit_insn (gen_builtin_setjmp_receiver (lab1));
|
||||
emit_insn (gen_builtin_setjmp_receiver (receiver_label));
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_nonlocal_goto_receiver
|
||||
@ -8606,11 +8664,60 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
|
||||
{
|
||||
; /* Nothing */
|
||||
}
|
||||
}
|
||||
|
||||
/* Set TARGET, and branch to the next-time-through label. */
|
||||
emit_move_insn (target, const1_rtx);
|
||||
emit_jump_insn (gen_jump (next_label));
|
||||
|
||||
/* __builtin_setjmp is passed a pointer to an array of five words (not
|
||||
all will be used on all machines). It operates similarly to the C
|
||||
library function of the same name, but is more efficient. Much of
|
||||
the code below (and for longjmp) is copied from the handling of
|
||||
non-local gotos.
|
||||
|
||||
NOTE: This is intended for use by GNAT and the exception handling
|
||||
scheme in the compiler and will only work in the method used by
|
||||
them. */
|
||||
|
||||
static rtx
|
||||
expand_builtin_setjmp (arglist, target)
|
||||
tree arglist;
|
||||
rtx target;
|
||||
{
|
||||
rtx buf_addr, next_lab, cont_lab;
|
||||
|
||||
if (arglist == 0
|
||||
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
|
||||
return NULL_RTX;
|
||||
|
||||
if (target == 0 || GET_CODE (target) != REG
|
||||
|| REGNO (target) < FIRST_PSEUDO_REGISTER)
|
||||
target = gen_reg_rtx (TYPE_MODE (integer_type_node));
|
||||
|
||||
buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
|
||||
|
||||
next_lab = gen_label_rtx ();
|
||||
cont_lab = gen_label_rtx ();
|
||||
|
||||
expand_builtin_setjmp_setup (buf_addr, next_lab);
|
||||
|
||||
/* Set TARGET to zero and branch to the continue label. */
|
||||
emit_move_insn (target, const0_rtx);
|
||||
emit_jump_insn (gen_jump (cont_lab));
|
||||
emit_barrier ();
|
||||
emit_label (next_lab);
|
||||
|
||||
expand_builtin_setjmp_receiver (next_lab);
|
||||
|
||||
/* Set TARGET to one. */
|
||||
emit_move_insn (target, const1_rtx);
|
||||
emit_label (cont_lab);
|
||||
|
||||
/* Tell flow about the strange goings on. Putting `next_lab' on
|
||||
`nonlocal_goto_handler_labels' to indicates that function
|
||||
calls may traverse the arc back to this label. */
|
||||
|
||||
current_function_has_nonlocal_label = 1;
|
||||
nonlocal_goto_handler_labels
|
||||
= gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
|
||||
|
||||
return target;
|
||||
}
|
||||
@ -9632,18 +9739,10 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
||||
#endif
|
||||
|
||||
case BUILT_IN_SETJMP:
|
||||
if (arglist == 0
|
||||
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
|
||||
break;
|
||||
else
|
||||
{
|
||||
rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
|
||||
VOIDmode, 0);
|
||||
rtx lab = gen_label_rtx ();
|
||||
rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
|
||||
emit_label (lab);
|
||||
return ret;
|
||||
}
|
||||
target = expand_builtin_setjmp (arglist, target);
|
||||
if (target)
|
||||
return target;
|
||||
break;
|
||||
|
||||
/* __builtin_longjmp is passed a pointer to an array of five words.
|
||||
It's similar to the C library longjmp function but works with
|
||||
|
@ -831,7 +831,8 @@ extern rtx store_expr PROTO((tree, rtx, int));
|
||||
Useful after calling expand_expr with 1 as sum_ok. */
|
||||
extern rtx force_operand PROTO((rtx, rtx));
|
||||
|
||||
extern rtx expand_builtin_setjmp PROTO((rtx, rtx, rtx, rtx));
|
||||
extern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx));
|
||||
extern void expand_builtin_setjmp_receiver PARAMS ((rtx));
|
||||
|
||||
#ifdef TREE_CODE
|
||||
/* Generate code for computing expression EXP.
|
||||
|
@ -35,7 +35,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
Sun f77, at least) so you test `__unix' rather than `unix'.
|
||||
-D_LANGUAGE_FORTRAN is used by some compilers like SGI and
|
||||
might as well be in there. */
|
||||
{"cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
{"cpp0 -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
%{C:%{!E:%eGNU C does not support -C without using -E}}\
|
||||
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
|
||||
%{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\
|
||||
@ -85,7 +85,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
|
||||
%{!pipe:%g.s} %A\n }}}}"}},
|
||||
{"@f77-version",
|
||||
{"cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I \
|
||||
{"cpp0 -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I \
|
||||
%{C:%{!E:%eGNU C does not support -C without using -E}} \
|
||||
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG} \
|
||||
%{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2} \
|
||||
|
@ -1 +1 @@
|
||||
const char *ffe_version_string = "0.5.25 19991024 (release)";
|
||||
const char *ffe_version_string = "0.5.25 19991030 (prerelease)";
|
||||
|
@ -1681,7 +1681,7 @@ delete_block (b)
|
||||
basic_block b;
|
||||
{
|
||||
int deleted_handler = 0;
|
||||
rtx insn, end;
|
||||
rtx insn, end, tmp;
|
||||
|
||||
/* If the head of this block is a CODE_LABEL, then it might be the
|
||||
label for an exception handler which can't be reached.
|
||||
@ -1728,11 +1728,21 @@ delete_block (b)
|
||||
}
|
||||
}
|
||||
|
||||
/* Selectively unlink the insn chain. Include any BARRIER that may
|
||||
follow the basic block. */
|
||||
end = next_nonnote_insn (b->end);
|
||||
if (!end || GET_CODE (end) != BARRIER)
|
||||
end = b->end;
|
||||
/* Include any jump table following the basic block. */
|
||||
end = b->end;
|
||||
if (GET_CODE (end) == JUMP_INSN
|
||||
&& (tmp = JUMP_LABEL (end)) != NULL_RTX
|
||||
&& (tmp = NEXT_INSN (tmp)) != NULL_RTX
|
||||
&& GET_CODE (tmp) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (tmp)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
|
||||
end = tmp;
|
||||
|
||||
/* Include any barrier that may follow the basic block. */
|
||||
tmp = next_nonnote_insn (b->end);
|
||||
if (tmp && GET_CODE (tmp) == BARRIER)
|
||||
end = tmp;
|
||||
|
||||
delete_insn_chain (insn, end);
|
||||
|
||||
no_delete_insns:
|
||||
@ -1796,6 +1806,7 @@ flow_delete_insn (insn)
|
||||
{
|
||||
rtx prev = PREV_INSN (insn);
|
||||
rtx next = NEXT_INSN (insn);
|
||||
rtx note;
|
||||
|
||||
PREV_INSN (insn) = NULL_RTX;
|
||||
NEXT_INSN (insn) = NULL_RTX;
|
||||
@ -1815,6 +1826,10 @@ flow_delete_insn (insn)
|
||||
if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
|
||||
LABEL_NUSES (JUMP_LABEL (insn))--;
|
||||
|
||||
/* Also if deleting an insn that references a label. */
|
||||
else if ((note = find_reg_note (insn, REG_LABEL, NULL_RTX)) != NULL_RTX)
|
||||
LABEL_NUSES (XEXP (note, 0))--;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
@ -2721,6 +2736,39 @@ propagate_block (old, first, last, final, significant, bnum, remove_dead_code)
|
||||
can cause trouble for first or last insn in a basic block. */
|
||||
if (final && insn_is_dead)
|
||||
{
|
||||
rtx inote;
|
||||
/* If the insn referred to a label, note that the label is
|
||||
now less used. */
|
||||
for (inote = REG_NOTES (insn); inote; inote = XEXP (inote, 1))
|
||||
{
|
||||
if (REG_NOTE_KIND (inote) == REG_LABEL)
|
||||
{
|
||||
rtx label = XEXP (inote, 0);
|
||||
rtx next;
|
||||
LABEL_NUSES (label)--;
|
||||
|
||||
/* If this label was attached to an ADDR_VEC, it's
|
||||
safe to delete the ADDR_VEC. In fact, it's pretty much
|
||||
mandatory to delete it, because the ADDR_VEC may
|
||||
be referencing labels that no longer exist. */
|
||||
if (LABEL_NUSES (label) == 0
|
||||
&& (next = next_nonnote_insn (label)) != NULL
|
||||
&& GET_CODE (next) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
|
||||
{
|
||||
rtx pat = PATTERN (next);
|
||||
int diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
|
||||
int len = XVECLEN (pat, diff_vec_p);
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
|
||||
|
||||
flow_delete_insn (next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PUT_CODE (insn, NOTE);
|
||||
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
||||
NOTE_SOURCE_FILE (insn) = 0;
|
||||
|
@ -3259,8 +3259,17 @@ make_range (exp, pin_p, plow, phigh)
|
||||
low = range_binop (PLUS_EXPR, type, n_high, 0,
|
||||
integer_one_node, 0);
|
||||
high = range_binop (MINUS_EXPR, type, n_low, 0,
|
||||
integer_one_node, 0);
|
||||
in_p = ! in_p;
|
||||
integer_one_node, 0);
|
||||
|
||||
/* If the range is of the form +/- [ x+1, x ], we won't
|
||||
be able to normalize it. But then, it represents the
|
||||
whole range or the empty set, so make it +/- [ -, - ].
|
||||
*/
|
||||
if (tree_int_cst_equal (n_low, low)
|
||||
&& tree_int_cst_equal (n_high, high))
|
||||
low = high = 0;
|
||||
else
|
||||
in_p = ! in_p;
|
||||
}
|
||||
else
|
||||
low = n_low, high = n_high;
|
||||
@ -5625,7 +5634,15 @@ fold (expr)
|
||||
tree newconst
|
||||
= fold (build (PLUS_EXPR, TREE_TYPE (varop),
|
||||
constop, TREE_OPERAND (varop, 1)));
|
||||
TREE_SET_CODE (varop, PREINCREMENT_EXPR);
|
||||
|
||||
/* Do not overwrite the current varop to be a preincrement,
|
||||
create a new node so that we won't confuse our caller who
|
||||
might create trees and throw them away, reusing the
|
||||
arguments that they passed to build. This shows up in
|
||||
the THEN or ELSE parts of ?: being postincrements. */
|
||||
varop = build (PREINCREMENT_EXPR, TREE_TYPE (varop),
|
||||
TREE_OPERAND (varop, 0),
|
||||
TREE_OPERAND (varop, 1));
|
||||
|
||||
/* If VAROP is a reference to a bitfield, we must mask
|
||||
the constant by the width of the field. */
|
||||
@ -5669,9 +5686,9 @@ fold (expr)
|
||||
}
|
||||
|
||||
|
||||
t = build (code, type, TREE_OPERAND (t, 0),
|
||||
TREE_OPERAND (t, 1));
|
||||
TREE_OPERAND (t, constopnum) = newconst;
|
||||
t = build (code, type,
|
||||
(constopnum == 0) ? newconst : varop,
|
||||
(constopnum == 1) ? newconst : varop);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@ -5684,7 +5701,15 @@ fold (expr)
|
||||
tree newconst
|
||||
= fold (build (MINUS_EXPR, TREE_TYPE (varop),
|
||||
constop, TREE_OPERAND (varop, 1)));
|
||||
TREE_SET_CODE (varop, PREDECREMENT_EXPR);
|
||||
|
||||
/* Do not overwrite the current varop to be a predecrement,
|
||||
create a new node so that we won't confuse our caller who
|
||||
might create trees and throw them away, reusing the
|
||||
arguments that they passed to build. This shows up in
|
||||
the THEN or ELSE parts of ?: being postdecrements. */
|
||||
varop = build (PREDECREMENT_EXPR, TREE_TYPE (varop),
|
||||
TREE_OPERAND (varop, 0),
|
||||
TREE_OPERAND (varop, 1));
|
||||
|
||||
if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
|
||||
&& DECL_BIT_FIELD(TREE_OPERAND
|
||||
@ -5723,9 +5748,9 @@ fold (expr)
|
||||
}
|
||||
|
||||
|
||||
t = build (code, type, TREE_OPERAND (t, 0),
|
||||
TREE_OPERAND (t, 1));
|
||||
TREE_OPERAND (t, constopnum) = newconst;
|
||||
t = build (code, type,
|
||||
(constopnum == 0) ? newconst : varop,
|
||||
(constopnum == 1) ? newconst : varop);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
@ -714,6 +714,14 @@ execute_cfa_insn (void *p, struct frame_state_internal *state,
|
||||
state->s.args_size = offset;
|
||||
break;
|
||||
|
||||
case DW_CFA_GNU_negative_offset_extended:
|
||||
p = decode_uleb128 (p, ®);
|
||||
p = decode_uleb128 (p, &offset);
|
||||
offset *= info->data_align;
|
||||
state->s.saved[reg] = REG_SAVED_OFFSET;
|
||||
state->s.reg_or_offset[reg] = -offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
@ -2773,6 +2773,7 @@ find_and_verify_loops (f)
|
||||
{
|
||||
rtx p;
|
||||
rtx our_next = next_real_insn (insn);
|
||||
rtx last_insn_to_move = NEXT_INSN (insn);
|
||||
int dest_loop;
|
||||
int outer_loop = -1;
|
||||
|
||||
@ -2824,21 +2825,39 @@ find_and_verify_loops (f)
|
||||
&& INSN_UID (JUMP_LABEL (p)) != 0
|
||||
&& condjump_p (p)
|
||||
&& ! simplejump_p (p)
|
||||
&& next_real_insn (JUMP_LABEL (p)) == our_next)
|
||||
&& next_real_insn (JUMP_LABEL (p)) == our_next
|
||||
/* If it's not safe to move the sequence, then we
|
||||
mustn't try. */
|
||||
&& insns_safe_to_move_p (p, NEXT_INSN (insn),
|
||||
&last_insn_to_move))
|
||||
{
|
||||
rtx target
|
||||
= JUMP_LABEL (insn) ? JUMP_LABEL (insn) : get_last_insn ();
|
||||
int target_loop_num = uid_loop_num[INSN_UID (target)];
|
||||
rtx loc;
|
||||
rtx loc, loc2;
|
||||
|
||||
for (loc = target; loc; loc = PREV_INSN (loc))
|
||||
if (GET_CODE (loc) == BARRIER
|
||||
/* Don't move things inside a tablejump. */
|
||||
&& ((loc2 = next_nonnote_insn (loc)) == 0
|
||||
|| GET_CODE (loc2) != CODE_LABEL
|
||||
|| (loc2 = next_nonnote_insn (loc2)) == 0
|
||||
|| GET_CODE (loc2) != JUMP_INSN
|
||||
|| (GET_CODE (PATTERN (loc2)) != ADDR_VEC
|
||||
&& GET_CODE (PATTERN (loc2)) != ADDR_DIFF_VEC))
|
||||
&& uid_loop_num[INSN_UID (loc)] == target_loop_num)
|
||||
break;
|
||||
|
||||
if (loc == 0)
|
||||
for (loc = target; loc; loc = NEXT_INSN (loc))
|
||||
if (GET_CODE (loc) == BARRIER
|
||||
/* Don't move things inside a tablejump. */
|
||||
&& ((loc2 = next_nonnote_insn (loc)) == 0
|
||||
|| GET_CODE (loc2) != CODE_LABEL
|
||||
|| (loc2 = next_nonnote_insn (loc2)) == 0
|
||||
|| GET_CODE (loc2) != JUMP_INSN
|
||||
|| (GET_CODE (PATTERN (loc2)) != ADDR_VEC
|
||||
&& GET_CODE (PATTERN (loc2)) != ADDR_DIFF_VEC))
|
||||
&& uid_loop_num[INSN_UID (loc)] == target_loop_num)
|
||||
break;
|
||||
|
||||
@ -2879,11 +2898,13 @@ find_and_verify_loops (f)
|
||||
|
||||
/* Include the BARRIER after INSN and copy the
|
||||
block after LOC. */
|
||||
new_label = squeeze_notes (new_label, NEXT_INSN (insn));
|
||||
reorder_insns (new_label, NEXT_INSN (insn), loc);
|
||||
new_label = squeeze_notes (new_label,
|
||||
last_insn_to_move);
|
||||
reorder_insns (new_label, last_insn_to_move, loc);
|
||||
|
||||
/* All those insns are now in TARGET_LOOP_NUM. */
|
||||
for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
|
||||
for (q = new_label;
|
||||
q != NEXT_INSN (last_insn_to_move);
|
||||
q = NEXT_INSN (q))
|
||||
uid_loop_num[INSN_UID (q)] = target_loop_num;
|
||||
|
||||
@ -5678,6 +5699,7 @@ check_final_value (v, loop_start, loop_end, n_iterations)
|
||||
or all uses follow that insn in the same basic block),
|
||||
- its final value can be calculated (this condition is different
|
||||
than the one above in record_giv)
|
||||
- it's not used before it's set
|
||||
- no assignments to the biv occur during the giv's lifetime. */
|
||||
|
||||
#if 0
|
||||
@ -5689,7 +5711,7 @@ check_final_value (v, loop_start, loop_end, n_iterations)
|
||||
if ((final_value = final_giv_value (v, loop_start, loop_end, n_iterations))
|
||||
&& (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn)))
|
||||
{
|
||||
int biv_increment_seen = 0;
|
||||
int biv_increment_seen = 0, before_giv_insn = 0;
|
||||
rtx p = v->insn;
|
||||
rtx last_giv_use;
|
||||
|
||||
@ -5719,26 +5741,35 @@ check_final_value (v, loop_start, loop_end, n_iterations)
|
||||
{
|
||||
p = NEXT_INSN (p);
|
||||
if (p == loop_end)
|
||||
p = NEXT_INSN (loop_start);
|
||||
{
|
||||
before_giv_insn = 1;
|
||||
p = NEXT_INSN (loop_start);
|
||||
}
|
||||
if (p == v->insn)
|
||||
break;
|
||||
|
||||
if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
|
||||
|| GET_CODE (p) == CALL_INSN)
|
||||
{
|
||||
if (biv_increment_seen)
|
||||
/* It is possible for the BIV increment to use the GIV if we
|
||||
have a cycle. Thus we must be sure to check each insn for
|
||||
both BIV and GIV uses, and we must check for BIV uses
|
||||
first. */
|
||||
|
||||
if (! biv_increment_seen
|
||||
&& reg_set_p (v->src_reg, PATTERN (p)))
|
||||
biv_increment_seen = 1;
|
||||
|
||||
if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
|
||||
{
|
||||
if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
|
||||
if (biv_increment_seen || before_giv_insn)
|
||||
{
|
||||
v->replaceable = 0;
|
||||
v->not_replaceable = 1;
|
||||
break;
|
||||
}
|
||||
last_giv_use = p;
|
||||
}
|
||||
else if (reg_set_p (v->src_reg, PATTERN (p)))
|
||||
biv_increment_seen = 1;
|
||||
else if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
|
||||
last_giv_use = p;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5983,6 +6014,7 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
|
||||
insn = p;
|
||||
while (1)
|
||||
{
|
||||
rtx dest;
|
||||
do {
|
||||
insn = PREV_INSN (insn);
|
||||
} while (insn && GET_CODE (insn) == NOTE
|
||||
@ -5994,20 +6026,26 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
|
||||
if (set == 0)
|
||||
break;
|
||||
|
||||
if ((SET_DEST (set) == x
|
||||
|| (GET_CODE (SET_DEST (set)) == SUBREG
|
||||
&& (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
|
||||
<= UNITS_PER_WORD)
|
||||
&& (GET_MODE_CLASS (GET_MODE (SET_DEST (set)))
|
||||
== MODE_INT)
|
||||
&& SUBREG_REG (SET_DEST (set)) == x))
|
||||
&& basic_induction_var (SET_SRC (set),
|
||||
(GET_MODE (SET_SRC (set)) == VOIDmode
|
||||
? GET_MODE (x)
|
||||
: GET_MODE (SET_SRC (set))),
|
||||
dest_reg, insn,
|
||||
inc_val, mult_val, location))
|
||||
return 1;
|
||||
dest = SET_DEST (set);
|
||||
if (dest == x
|
||||
|| (GET_CODE (dest) == SUBREG
|
||||
&& (GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD)
|
||||
&& (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
|
||||
&& SUBREG_REG (dest) == x))
|
||||
return basic_induction_var (SET_SRC (set),
|
||||
(GET_MODE (SET_SRC (set)) == VOIDmode
|
||||
? GET_MODE (x)
|
||||
: GET_MODE (SET_SRC (set))),
|
||||
dest_reg, insn,
|
||||
inc_val, mult_val, location);
|
||||
|
||||
while (GET_CODE (dest) == SIGN_EXTRACT
|
||||
|| GET_CODE (dest) == ZERO_EXTRACT
|
||||
|| GET_CODE (dest) == SUBREG
|
||||
|| GET_CODE (dest) == STRICT_LOW_PART)
|
||||
dest = XEXP (dest, 0);
|
||||
if (dest == x)
|
||||
break;
|
||||
}
|
||||
/* ... fall through ... */
|
||||
|
||||
@ -8155,6 +8193,40 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
|
||||
bl->nonneg = 1;
|
||||
}
|
||||
|
||||
/* No insn may reference both the reversed and another biv or it
|
||||
will fail (see comment near the top of the loop reversal
|
||||
code).
|
||||
Earlier on, we have verified that the biv has no use except
|
||||
counting, or it is the only biv in this function.
|
||||
However, the code that computes no_use_except_counting does
|
||||
not verify reg notes. It's possible to have an insn that
|
||||
references another biv, and has a REG_EQUAL note with an
|
||||
expression based on the reversed biv. To avoid this case,
|
||||
remove all REG_EQUAL notes based on the reversed biv
|
||||
here. */
|
||||
for (p = loop_start; p != loop_end; p = NEXT_INSN (p))
|
||||
if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
|
||||
{
|
||||
rtx *pnote;
|
||||
rtx set = single_set (p);
|
||||
/* If this is a set of a GIV based on the reversed biv, any
|
||||
REG_EQUAL notes should still be correct. */
|
||||
if (! set
|
||||
|| GET_CODE (SET_DEST (set)) != REG
|
||||
|| (size_t) REGNO (SET_DEST (set)) >= reg_iv_type->num_elements
|
||||
|| REG_IV_TYPE (REGNO (SET_DEST (set))) != GENERAL_INDUCT
|
||||
|| REG_IV_INFO (REGNO (SET_DEST (set)))->src_reg != bl->biv->src_reg)
|
||||
for (pnote = ®_NOTES (p); *pnote;)
|
||||
{
|
||||
if (REG_NOTE_KIND (*pnote) == REG_EQUAL
|
||||
&& reg_mentioned_p (regno_reg_rtx[bl->regno],
|
||||
XEXP (*pnote, 0)))
|
||||
*pnote = XEXP (*pnote, 1);
|
||||
else
|
||||
pnote = &XEXP (*pnote, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark that this biv has been reversed. Each giv which depends
|
||||
on this biv, and which is also live past the end of the loop
|
||||
will have to be fixed up. */
|
||||
@ -9314,6 +9386,7 @@ instrument_loop_bct (loop_start, loop_end, loop_num_iterations)
|
||||
emit_jump_insn_before (gen_decrement_and_branch_on_count (counter_reg,
|
||||
start_label),
|
||||
loop_end);
|
||||
JUMP_LABEL (prev_nonnote_insn (loop_end)) = start_label;
|
||||
LABEL_NUSES (start_label)++;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
|
||||
{".m", {"@objective-c"}},
|
||||
{"@objective-c",
|
||||
#if USE_CPPLIB
|
||||
{"%{E|M|MM:cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
{"%{E|M|MM:cpp0 -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
%{C:%{!E:%eGNU C does not support -C without using -E}}\
|
||||
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
|
||||
-D__OBJC__ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\
|
||||
@ -55,7 +55,7 @@ Boston, MA 02111-1307, USA. */
|
||||
%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
|
||||
%{!pipe:%g.s} %A\n }}}}"}
|
||||
#else /* ! USE_CPPLIB */
|
||||
{"cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
{"cpp0 -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
|
||||
%{C:%{!E:%eGNU C does not support -C without using -E}}\
|
||||
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
|
||||
-D__OBJC__ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\
|
||||
|
@ -2887,8 +2887,14 @@ emit_libcall_block (insns, target, result, equiv)
|
||||
rtx result;
|
||||
rtx equiv;
|
||||
{
|
||||
rtx final_dest = target;
|
||||
rtx prev, next, first, last, insn;
|
||||
|
||||
/* If this is a reg with REG_USERVAR_P set, then it could possibly turn
|
||||
into a MEM later. Protect the libcall block from this change. */
|
||||
if (! REG_P (target) || REG_USERVAR_P (target))
|
||||
target = gen_reg_rtx (GET_MODE (target));
|
||||
|
||||
/* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
|
||||
reg note to indicate that this call cannot throw. (Unless there is
|
||||
already a REG_EH_REGION note.) */
|
||||
@ -2952,6 +2958,9 @@ emit_libcall_block (insns, target, result, equiv)
|
||||
!= CODE_FOR_nothing)
|
||||
set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
|
||||
|
||||
if (final_dest != target)
|
||||
emit_move_insn (final_dest, target);
|
||||
|
||||
if (prev == 0)
|
||||
first = get_insns ();
|
||||
else
|
||||
|
@ -296,7 +296,7 @@ extern rtx find_equiv_reg PROTO((rtx, rtx, enum reg_class, int, short *,
|
||||
int, enum machine_mode));
|
||||
|
||||
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
|
||||
extern int regno_clobbered_p PROTO((int, rtx));
|
||||
extern int regno_clobbered_p PROTO((int, rtx, enum machine_mode, int));
|
||||
|
||||
/* Functions in reload1.c: */
|
||||
|
||||
@ -342,3 +342,5 @@ extern void save_call_clobbered_regs PROTO((void));
|
||||
|
||||
/* Replace (subreg (reg)) with the appropriate (reg) for any operands. */
|
||||
extern void cleanup_subreg_operands PROTO ((rtx));
|
||||
|
||||
extern int earlyclobber_operand_p PROTO((rtx));
|
||||
|
@ -420,9 +420,13 @@ static void clear_reload_reg_in_use PROTO((int, int, enum reload_type,
|
||||
enum machine_mode));
|
||||
static int reload_reg_free_p PROTO((int, int, enum reload_type));
|
||||
static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type, rtx, rtx, int, int));
|
||||
static int free_for_value_p PROTO((int, enum machine_mode, int,
|
||||
enum reload_type, rtx, rtx,
|
||||
int, int));
|
||||
static int reload_reg_reaches_end_p PROTO((int, int, enum reload_type));
|
||||
static int allocate_reload_reg PROTO((struct insn_chain *, int, int,
|
||||
int));
|
||||
static int conflicts_with_override PROTO((rtx));
|
||||
static void choose_reload_regs PROTO((struct insn_chain *));
|
||||
static void merge_assigned_reloads PROTO((rtx));
|
||||
static void emit_reload_insns PROTO((struct insn_chain *));
|
||||
@ -4518,7 +4522,10 @@ forget_old_reloads_1 (x, ignored)
|
||||
reload reg in the current instruction. */
|
||||
if (n_reloads == 0
|
||||
|| ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
|
||||
CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
|
||||
{
|
||||
CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
|
||||
spill_reg_store[regno + i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Since value of X has changed,
|
||||
@ -4577,6 +4584,8 @@ reload_reg_class_lower (r1p, r2p)
|
||||
/* The following HARD_REG_SETs indicate when each hard register is
|
||||
used for a reload of various parts of the current insn. */
|
||||
|
||||
/* If reg is unavailable for all reloads. */
|
||||
static HARD_REG_SET reload_reg_unavailable;
|
||||
/* If reg is in use as a reload reg for a RELOAD_OTHER reload. */
|
||||
static HARD_REG_SET reload_reg_used;
|
||||
/* If reg is in use for a RELOAD_FOR_INPUT_ADDRESS reload for operand I. */
|
||||
@ -4799,8 +4808,8 @@ reload_reg_free_p (regno, opnum, type)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* In use for a RELOAD_OTHER means it's not available for anything. */
|
||||
if (TEST_HARD_REG_BIT (reload_reg_used, regno))
|
||||
if (TEST_HARD_REG_BIT (reload_reg_used, regno)
|
||||
|| TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
|
||||
return 0;
|
||||
|
||||
switch (type)
|
||||
@ -5133,7 +5142,7 @@ reloads_conflict (r1, r2)
|
||||
return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT
|
||||
|| ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS
|
||||
|| r2_type == RELOAD_FOR_OUTADDR_ADDRESS)
|
||||
&& r2_opnum >= r1_opnum));
|
||||
&& r2_opnum <= r1_opnum));
|
||||
|
||||
case RELOAD_FOR_INSN:
|
||||
return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_OUTPUT
|
||||
@ -5171,25 +5180,8 @@ rtx reload_override_in[MAX_RELOADS];
|
||||
or -1 if we did not need a register for this reload. */
|
||||
int reload_spill_index[MAX_RELOADS];
|
||||
|
||||
/* Return 1 if the value in reload reg REGNO, as used by a reload
|
||||
needed for the part of the insn specified by OPNUM and TYPE,
|
||||
may be used to load VALUE into it.
|
||||
/* Subroutine of free_for_value_p, used to check a single register. */
|
||||
|
||||
Other read-only reloads with the same value do not conflict
|
||||
unless OUT is non-zero and these other reloads have to live while
|
||||
output reloads live.
|
||||
If OUT is CONST0_RTX, this is a special case: it means that the
|
||||
test should not be for using register REGNO as reload register, but
|
||||
for copying from register REGNO into the reload register.
|
||||
|
||||
RELOADNUM is the number of the reload we want to load this value for;
|
||||
a reload does not conflict with itself.
|
||||
|
||||
When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
|
||||
reloads that load an address for the very reload we are considering.
|
||||
|
||||
The caller has to make sure that there is no conflict with the return
|
||||
register. */
|
||||
static int
|
||||
reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
|
||||
ignore_address_reloads)
|
||||
@ -5201,6 +5193,10 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
|
||||
int ignore_address_reloads;
|
||||
{
|
||||
int time1;
|
||||
/* Set if we see an input reload that must not share its reload register
|
||||
with any new earlyclobber, but might otherwise share the reload
|
||||
register with an output or input-output reload. */
|
||||
int check_earlyclobber = 0;
|
||||
int i;
|
||||
int copy = 0;
|
||||
|
||||
@ -5208,7 +5204,7 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
|
||||
available as spill registers, including hard registers that are
|
||||
earlyclobbered in asms. As a temporary measure, reject anything
|
||||
in reload_reg_used. */
|
||||
if (TEST_HARD_REG_BIT (reload_reg_used, regno))
|
||||
if (TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
|
||||
return 0;
|
||||
|
||||
if (out == const0_rtx)
|
||||
@ -5235,7 +5231,8 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
|
||||
switch (type)
|
||||
{
|
||||
case RELOAD_FOR_OTHER_ADDRESS:
|
||||
time1 = 0;
|
||||
/* RELOAD_FOR_OTHER_ADDRESS conflicts with RELOAD_OTHER reloads. */
|
||||
time1 = copy ? 0 : 1;
|
||||
break;
|
||||
case RELOAD_OTHER:
|
||||
time1 = copy ? 1 : MAX_RECOG_OPERANDS * 5 + 5;
|
||||
@ -5327,6 +5324,7 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
|
||||
break;
|
||||
case RELOAD_FOR_INPUT:
|
||||
time2 = reload_opnum[i] * 4 + 4;
|
||||
check_earlyclobber = 1;
|
||||
break;
|
||||
/* reload_opnum[i] * 4 + 4 <= (MAX_RECOG_OPERAND - 1) * 4 + 4
|
||||
== MAX_RECOG_OPERAND * 4 */
|
||||
@ -5339,6 +5337,7 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
|
||||
break;
|
||||
case RELOAD_FOR_OPERAND_ADDRESS:
|
||||
time2 = MAX_RECOG_OPERANDS * 4 + 2;
|
||||
check_earlyclobber = 1;
|
||||
break;
|
||||
case RELOAD_FOR_INSN:
|
||||
time2 = MAX_RECOG_OPERANDS * 4 + 3;
|
||||
@ -5367,6 +5366,9 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
|
||||
if (! reload_in[i] || rtx_equal_p (reload_in[i], value))
|
||||
{
|
||||
time2 = MAX_RECOG_OPERANDS * 4 + 4;
|
||||
/* Earlyclobbered outputs must conflict with inputs. */
|
||||
if (earlyclobber_operand_p (reload_out[i]))
|
||||
time2 = MAX_RECOG_OPERANDS * 4 + 3;
|
||||
break;
|
||||
}
|
||||
time2 = 1;
|
||||
@ -5389,9 +5391,71 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Earlyclobbered outputs must conflict with inputs. */
|
||||
if (check_earlyclobber && out && earlyclobber_operand_p (out))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return 1 if the value in reload reg REGNO, as used by a reload
|
||||
needed for the part of the insn specified by OPNUM and TYPE,
|
||||
may be used to load VALUE into it.
|
||||
|
||||
MODE is the mode in which the register is used, this is needed to
|
||||
determine how many hard regs to test.
|
||||
|
||||
Other read-only reloads with the same value do not conflict
|
||||
unless OUT is non-zero and these other reloads have to live while
|
||||
output reloads live.
|
||||
If OUT is CONST0_RTX, this is a special case: it means that the
|
||||
test should not be for using register REGNO as reload register, but
|
||||
for copying from register REGNO into the reload register.
|
||||
|
||||
RELOADNUM is the number of the reload we want to load this value for;
|
||||
a reload does not conflict with itself.
|
||||
|
||||
When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
|
||||
reloads that load an address for the very reload we are considering.
|
||||
|
||||
The caller has to make sure that there is no conflict with the return
|
||||
register. */
|
||||
|
||||
static int
|
||||
free_for_value_p (regno, mode, opnum, type, value, out, reloadnum,
|
||||
ignore_address_reloads)
|
||||
int regno;
|
||||
enum machine_mode mode;
|
||||
int opnum;
|
||||
enum reload_type type;
|
||||
rtx value, out;
|
||||
int reloadnum;
|
||||
int ignore_address_reloads;
|
||||
{
|
||||
int nregs = HARD_REGNO_NREGS (regno, mode);
|
||||
while (nregs-- > 0)
|
||||
if (! reload_reg_free_for_value_p (regno + nregs, opnum, type, value, out,
|
||||
reloadnum, ignore_address_reloads))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Determine whether the reload reg X overlaps any rtx'es used for
|
||||
overriding inheritance. Return nonzero if so. */
|
||||
|
||||
static int
|
||||
conflicts_with_override (x)
|
||||
rtx x;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_reloads; i++)
|
||||
if (reload_override_in[i]
|
||||
&& reg_overlap_mentioned_p (x, reload_override_in[i]))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find a spill register to use as a reload register for reload R.
|
||||
LAST_RELOAD is non-zero if this is the last reload for the insn being
|
||||
processed.
|
||||
@ -5472,11 +5536,10 @@ allocate_reload_reg (chain, r, last_reload, noerror)
|
||||
/* We check reload_reg_used to make sure we
|
||||
don't clobber the return register. */
|
||||
&& ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
|
||||
&& reload_reg_free_for_value_p (regnum,
|
||||
reload_opnum[r],
|
||||
reload_when_needed[r],
|
||||
reload_in[r],
|
||||
reload_out[r], r, 1)))
|
||||
&& free_for_value_p (regnum, reload_mode[r],
|
||||
reload_opnum[r],
|
||||
reload_when_needed[r],
|
||||
reload_in[r], reload_out[r], r, 1)))
|
||||
&& TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
|
||||
&& HARD_REGNO_MODE_OK (regnum, reload_mode[r])
|
||||
/* Look first for regs to share, then for unshared. But
|
||||
@ -5669,7 +5732,7 @@ choose_reload_regs (chain)
|
||||
CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
|
||||
}
|
||||
|
||||
IOR_COMPL_HARD_REG_SET (reload_reg_used, chain->used_spill_regs);
|
||||
COMPL_HARD_REG_SET (reload_reg_unavailable, chain->used_spill_regs);
|
||||
|
||||
#if 0 /* Not needed, now that we can always retry without inheritance. */
|
||||
/* See if we have more mandatory reloads than spill regs.
|
||||
@ -5931,10 +5994,9 @@ choose_reload_regs (chain)
|
||||
&& (reload_nregs[r] == max_group_size
|
||||
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
|
||||
i))
|
||||
&& reload_reg_free_for_value_p (i, reload_opnum[r],
|
||||
reload_when_needed[r],
|
||||
reload_in[r],
|
||||
const0_rtx, r, 1))
|
||||
&& free_for_value_p (i, reload_mode[r], reload_opnum[r],
|
||||
reload_when_needed[r], reload_in[r],
|
||||
const0_rtx, r, 1))
|
||||
{
|
||||
/* If a group is needed, verify that all the subsequent
|
||||
registers still have their values intact. */
|
||||
@ -5968,9 +6030,11 @@ choose_reload_regs (chain)
|
||||
break;
|
||||
|
||||
if (i1 != n_earlyclobbers
|
||||
|| ! (reload_reg_free_for_value_p
|
||||
(i, reload_opnum[r], reload_when_needed[r],
|
||||
reload_in[r], reload_out[r], r, 1))
|
||||
|| ! (free_for_value_p (i, reload_mode[r],
|
||||
reload_opnum[r],
|
||||
reload_when_needed[r],
|
||||
reload_in[r],
|
||||
reload_out[r], r, 1))
|
||||
/* Don't use it if we'd clobber a pseudo reg. */
|
||||
|| (TEST_HARD_REG_BIT (reg_used_in_insn, i)
|
||||
&& reload_out[r]
|
||||
@ -5992,9 +6056,12 @@ choose_reload_regs (chain)
|
||||
&& rtx_equal_p (reload_out[r],
|
||||
reload_reg_rtx[r])))
|
||||
{
|
||||
reload_override_in[r] = last_reg;
|
||||
reload_inheritance_insn[r]
|
||||
= reg_reloaded_insn[i];
|
||||
if (! reload_optional[r])
|
||||
{
|
||||
reload_override_in[r] = last_reg;
|
||||
reload_inheritance_insn[r]
|
||||
= reg_reloaded_insn[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -6072,10 +6139,11 @@ choose_reload_regs (chain)
|
||||
and of the desired class. */
|
||||
if (equiv != 0
|
||||
&& ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
|
||||
&& ! reload_reg_free_for_value_p (regno, reload_opnum[r],
|
||||
reload_when_needed[r],
|
||||
reload_in[r],
|
||||
reload_out[r], r, 1))
|
||||
&& ! free_for_value_p (regno, reload_mode[r],
|
||||
reload_opnum[r],
|
||||
reload_when_needed[r],
|
||||
reload_in[r], reload_out[r], r,
|
||||
1))
|
||||
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
|
||||
regno)))
|
||||
equiv = 0;
|
||||
@ -6093,7 +6161,8 @@ choose_reload_regs (chain)
|
||||
if (reg_overlap_mentioned_for_reload_p (equiv,
|
||||
reload_earlyclobbers[i]))
|
||||
{
|
||||
reload_override_in[r] = equiv;
|
||||
if (! reload_optional[r])
|
||||
reload_override_in[r] = equiv;
|
||||
equiv = 0;
|
||||
break;
|
||||
}
|
||||
@ -6104,7 +6173,8 @@ choose_reload_regs (chain)
|
||||
In particular, we then can't use EQUIV for a
|
||||
RELOAD_FOR_OUTPUT_ADDRESS reload. */
|
||||
|
||||
if (equiv != 0 && regno_clobbered_p (regno, insn))
|
||||
if (equiv != 0 && regno_clobbered_p (regno, insn,
|
||||
reload_mode[r], 0))
|
||||
{
|
||||
switch (reload_when_needed[r])
|
||||
{
|
||||
@ -6116,13 +6186,32 @@ choose_reload_regs (chain)
|
||||
case RELOAD_OTHER:
|
||||
case RELOAD_FOR_INPUT:
|
||||
case RELOAD_FOR_OPERAND_ADDRESS:
|
||||
reload_override_in[r] = equiv;
|
||||
if (! reload_optional[r])
|
||||
reload_override_in[r] = equiv;
|
||||
/* Fall through. */
|
||||
default:
|
||||
equiv = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (regno_clobbered_p (regno, insn, reload_mode[r], 1))
|
||||
switch (reload_when_needed[r])
|
||||
{
|
||||
case RELOAD_FOR_OTHER_ADDRESS:
|
||||
case RELOAD_FOR_INPADDR_ADDRESS:
|
||||
case RELOAD_FOR_INPUT_ADDRESS:
|
||||
case RELOAD_FOR_OPADDR_ADDR:
|
||||
case RELOAD_FOR_OPERAND_ADDRESS:
|
||||
case RELOAD_FOR_INPUT:
|
||||
break;
|
||||
case RELOAD_OTHER:
|
||||
if (! reload_optional[r])
|
||||
reload_override_in[r] = equiv;
|
||||
/* Fall through. */
|
||||
default:
|
||||
equiv = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we found an equivalent reg, say no code need be generated
|
||||
to load it, and use it as our reload reg. */
|
||||
@ -6283,13 +6372,12 @@ choose_reload_regs (chain)
|
||||
check_reg = reload_override_in[r];
|
||||
else
|
||||
continue;
|
||||
if (! reload_reg_free_for_value_p (true_regnum (check_reg),
|
||||
reload_opnum[r],
|
||||
reload_when_needed[r],
|
||||
reload_in[r],
|
||||
(reload_inherited[r]
|
||||
? reload_out[r] : const0_rtx),
|
||||
r, 1))
|
||||
if (! free_for_value_p (true_regnum (check_reg), reload_mode[r],
|
||||
reload_opnum[r], reload_when_needed[r],
|
||||
reload_in[r],
|
||||
(reload_inherited[r]
|
||||
? reload_out[r] : const0_rtx),
|
||||
r, 1))
|
||||
{
|
||||
if (pass)
|
||||
continue;
|
||||
@ -6646,10 +6734,10 @@ emit_reload_insns (chain)
|
||||
|
||||
/* Don't use OLDEQUIV if any other reload changes it at an
|
||||
earlier stage of this insn or at this stage. */
|
||||
if (! reload_reg_free_for_value_p (regno, reload_opnum[j],
|
||||
reload_when_needed[j],
|
||||
reload_in[j], const0_rtx, j,
|
||||
0))
|
||||
if (! free_for_value_p (regno, reload_mode[j],
|
||||
reload_opnum[j],
|
||||
reload_when_needed[j],
|
||||
reload_in[j], const0_rtx, j, 0))
|
||||
oldequiv = 0;
|
||||
|
||||
/* If it is no cheaper to copy from OLDEQUIV into the
|
||||
@ -6799,11 +6887,10 @@ emit_reload_insns (chain)
|
||||
&& dead_or_set_p (insn, old)
|
||||
/* This is unsafe if some other reload
|
||||
uses the same reg first. */
|
||||
&& reload_reg_free_for_value_p (REGNO (reloadreg),
|
||||
reload_opnum[j],
|
||||
reload_when_needed[j],
|
||||
old, reload_out[j],
|
||||
j, 0))
|
||||
&& ! conflicts_with_override (reloadreg)
|
||||
&& free_for_value_p (REGNO (reloadreg), reload_mode[j],
|
||||
reload_opnum[j], reload_when_needed[j],
|
||||
old, reload_out[j], j, 0))
|
||||
{
|
||||
rtx temp = PREV_INSN (insn);
|
||||
while (temp && GET_CODE (temp) == NOTE)
|
||||
@ -7112,7 +7199,8 @@ emit_reload_insns (chain)
|
||||
/* We don't need to test full validity of last_regno for
|
||||
inherit here; we only want to know if the store actually
|
||||
matches the pseudo. */
|
||||
if (reg_reloaded_contents[last_regno] == pseudo_no
|
||||
if (TEST_HARD_REG_BIT (reg_reloaded_valid, last_regno)
|
||||
&& reg_reloaded_contents[last_regno] == pseudo_no
|
||||
&& spill_reg_store[last_regno]
|
||||
&& rtx_equal_p (pseudo, spill_reg_stored_to[last_regno]))
|
||||
delete_output_reload (insn, j, last_regno);
|
||||
@ -7288,7 +7376,7 @@ emit_reload_insns (chain)
|
||||
|| !(set = single_set (insn))
|
||||
|| rtx_equal_p (old, SET_DEST (set))
|
||||
|| !reg_mentioned_p (old, SET_SRC (set))
|
||||
|| !regno_clobbered_p (REGNO (old), insn))
|
||||
|| !regno_clobbered_p (REGNO (old), insn, reload_mode[j], 0))
|
||||
gen_reload (old, reloadreg, reload_opnum[j],
|
||||
reload_when_needed[j]);
|
||||
}
|
||||
|
@ -1084,6 +1084,7 @@ extern int for_each_rtx PROTO((rtx *, rtx_function, void *));
|
||||
extern rtx regno_use_in PROTO((int, rtx));
|
||||
extern int auto_inc_p PROTO((rtx));
|
||||
extern void remove_node_from_expr_list PROTO((rtx, rtx *));
|
||||
extern int insns_safe_to_move_p PROTO((rtx, rtx, rtx *));
|
||||
|
||||
/* flow.c */
|
||||
|
||||
|
@ -2289,3 +2289,82 @@ auto_inc_p (x)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return 1 if the sequence of instructions beginning with FROM and up
|
||||
to and including TO is safe to move. If NEW_TO is non-NULL, and
|
||||
the sequence is not already safe to move, but can be easily
|
||||
extended to a sequence which is safe, then NEW_TO will point to the
|
||||
end of the extended sequence.
|
||||
|
||||
For now, this function only checks that the region contains whole
|
||||
exception regiongs, but it could be extended to check additional
|
||||
conditions as well. */
|
||||
|
||||
int
|
||||
insns_safe_to_move_p (from, to, new_to)
|
||||
rtx from;
|
||||
rtx to;
|
||||
rtx *new_to;
|
||||
{
|
||||
int eh_region_count = 0;
|
||||
int past_to_p = 0;
|
||||
rtx r = from;
|
||||
|
||||
/* By default, assume the end of the region will be what was
|
||||
suggested. */
|
||||
if (new_to)
|
||||
*new_to = to;
|
||||
|
||||
while (r)
|
||||
{
|
||||
if (GET_CODE (r) == NOTE)
|
||||
{
|
||||
switch (NOTE_LINE_NUMBER (r))
|
||||
{
|
||||
case NOTE_INSN_EH_REGION_BEG:
|
||||
++eh_region_count;
|
||||
break;
|
||||
|
||||
case NOTE_INSN_EH_REGION_END:
|
||||
if (eh_region_count == 0)
|
||||
/* This sequence of instructions contains the end of
|
||||
an exception region, but not he beginning. Moving
|
||||
it will cause chaos. */
|
||||
return 0;
|
||||
|
||||
--eh_region_count;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (past_to_p)
|
||||
/* If we've passed TO, and we see a non-note instruction, we
|
||||
can't extend the sequence to a movable sequence. */
|
||||
return 0;
|
||||
|
||||
if (r == to)
|
||||
{
|
||||
if (!new_to)
|
||||
/* It's OK to move the sequence if there were matched sets of
|
||||
exception region notes. */
|
||||
return eh_region_count == 0;
|
||||
|
||||
past_to_p = 1;
|
||||
}
|
||||
|
||||
/* It's OK to move the sequence if there were matched sets of
|
||||
exception region notes. */
|
||||
if (past_to_p && eh_region_count == 0)
|
||||
{
|
||||
*new_to = r;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Go to the next instruction. */
|
||||
r = NEXT_INSN (r);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1351,7 +1351,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||
}
|
||||
else
|
||||
{
|
||||
output_rtx[i] = assign_temp (type, 0, 0, 0);
|
||||
output_rtx[i] = assign_temp (type, 0, 0, 1);
|
||||
TREE_VALUE (tail) = make_tree (type, output_rtx[i]);
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
char *version_string = "2.95.2 19991024 (release)";
|
||||
char *version_string = "2.95.3 20010101 (prerelease)";
|
||||
|
Loading…
Reference in New Issue
Block a user