This commit was generated by cvs2svn to compensate for changes in r117395,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
46c315278f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=117396
26805
contrib/gcc/ChangeLog
26805
contrib/gcc/ChangeLog
File diff suppressed because it is too large
Load Diff
@ -2670,7 +2670,7 @@ Thu Jun 4 01:26:57 1998 Craig Burley <burley@gnu.org>
|
||||
|
||||
Thu Jun 4 00:54:21 1998 Graham <grahams@rcp.co.uk>
|
||||
|
||||
* loop.c (check_dbra_loop): Initialise final_value before
|
||||
* loop.c (check_dbra_loop): Initialize final_value before
|
||||
normalizing the loop.
|
||||
|
||||
Wed Jun 3 20:00:04 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
@ -4435,7 +4435,7 @@ Sun May 3 23:57:25 1998 Robert Lipe <robertl@dgii.com>
|
||||
|
||||
Sun May 3 13:51:34 1998 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
Support for official Sparc V9 ABI:
|
||||
Support for official SPARC V9 ABI:
|
||||
* sparc.c (sparc_override_options): Force stack bias off for !arch64.
|
||||
Care for flag_pcc_struct_return default.
|
||||
(output_move_quad): Rewrite to move by halves on v9 and in the
|
||||
@ -6574,8 +6574,8 @@ Wed Mar 11 12:05:20 1998 Teemu Torma <tot@trema.com>
|
||||
* gthr.h: Changed the comment about return values.
|
||||
* gthr-solaris.h (__gthread_once): Do not use errno; return the
|
||||
error number instead of -1.
|
||||
(__gthread_key_create): Any non-zero return value is an error.
|
||||
* libgcc2.c (eh_context_initialize): Check for non-zero return
|
||||
(__gthread_key_create): Any nonzero return value is an error.
|
||||
* libgcc2.c (eh_context_initialize): Check for nonzero return
|
||||
value from __gthread_once.
|
||||
Check that the value of get_eh_context was really changed.
|
||||
|
||||
@ -10440,7 +10440,7 @@ Tue Nov 4 20:36:50 1997 Richard Henderson (rth@cygnus.com)
|
||||
|
||||
* alpha.c (alpha_handle_trap_shadows): Init sum.defd to zero.
|
||||
|
||||
* alpha.md (attr trap): Make TRAP_YES non-zero for sanity's sake.
|
||||
* alpha.md (attr trap): Make TRAP_YES nonzero for sanity's sake.
|
||||
|
||||
Tue Nov 4 18:49:42 1997 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
@ -12000,7 +12000,7 @@ Wed Sep 10 11:49:20 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
EXCEPTION_SECTION, mark the start of the frame info with a
|
||||
collectible tag.
|
||||
* collect2.c (frame_tables): New list.
|
||||
(is_ctor_dtor): Recognise frame entries.
|
||||
(is_ctor_dtor): Recognize frame entries.
|
||||
(scan_prog_file): Likewise.
|
||||
(main): Pass -fno-exceptions to sub-compile. Also do collection
|
||||
if there are any frame entries.
|
||||
|
@ -469,7 +469,7 @@ Sun May 2 15:16:42 1999 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
(ASSEMBLER_DIALECT): Define.
|
||||
(CONDITIONAL_REGISTER_USAGE): Rename floating point registers if
|
||||
required for the UNIX assembler.
|
||||
(ASM_OUTPUT_INT): Remove. The compiler will synthesise it.
|
||||
(ASM_OUTPUT_INT): Remove. The compiler will synthesize it.
|
||||
(ASM_OUTPUT_ADDR_VEC_PROLOGUE): Remove.
|
||||
(ASM_OPEN_PAREN, ASM_CLOSE_PAREN): Change to "[" and "]".
|
||||
(TRAMPOLINE_TEMPLATE): Use ASM_OUTPUT_SHORT.
|
||||
@ -1732,7 +1732,7 @@ Fri Apr 9 10:40:10 1999 Kaveh R. Ghazi <ghazi@snafu.rutgers.edu>
|
||||
Thu Apr 8 19:20:18 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* expr.c (expand_expr, case ARRAY_REF, COMPONENT_REF, BIT_FIELD_REF):
|
||||
Do not try to optimize a aggregate address which has VOIDmode.
|
||||
Do not try to optimize an aggregate address which has VOIDmode.
|
||||
Mirrors March 23 change to expand_assignment.
|
||||
|
||||
* flow.c (delete_unreachable_blocks): Do not require EDGE_FALLTHRU
|
||||
@ -2152,7 +2152,7 @@ Fri Apr 2 12:58:26 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
Fri Apr 2 12:19:17 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
|
||||
* config/c4x/c4x.md (*db): Enable pattern if TARGET_LOOP_UNSIGNED
|
||||
is non-zero.
|
||||
is nonzero.
|
||||
(movstrqi_small, movstrqi_large, *cmpstrqi): Add + modifier to address
|
||||
register constraints.
|
||||
(*movhi_clobber+1): Modify splitter pattern to handle destination
|
||||
@ -2625,7 +2625,7 @@ Tue Mar 23 23:32:14 1999 Jeffrey A Law (law@cygnus.com)
|
||||
left using a variable rotate right. Provide anonymous pattern for
|
||||
rotate left by a constant value.
|
||||
|
||||
* expr.c (expand_assignment): Do not try to optimize a aggregate
|
||||
* expr.c (expand_assignment): Do not try to optimize an aggregate
|
||||
address which has VOIDmode.
|
||||
|
||||
Tue Mar 23 22:51:48 1999 Mumit Khan <khan@xraylith.wisc.edu>
|
||||
@ -4287,7 +4287,7 @@ Thu Feb 25 21:52:54 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
in registers.
|
||||
|
||||
* expr.h (PRETEND_OUTGOING_VARARGS_NAMED): Provide default definition.
|
||||
* function.c (assign_parms): Honour PRETEND_OUTGOING_VARARGS_NAMED.
|
||||
* function.c (assign_parms): Honor PRETEND_OUTGOING_VARARGS_NAMED.
|
||||
* calls.c (expand_call): Likewise.
|
||||
|
||||
* sh.c (sh_expand_prologue): For TARGET_HITACHI, don't push varargs /
|
||||
@ -4454,7 +4454,7 @@ Mon Feb 22 19:36:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
StrongARM.
|
||||
(arm_is_6_or_7): New variable: true iff the target processor is an
|
||||
ARM6 or and ARM7.
|
||||
(arm_select): Fields reorganised.
|
||||
(arm_select): Fields reorganized.
|
||||
(struct processors): processor_type field removed.
|
||||
(all_procs): Remove.
|
||||
(all_cores): New array: Definitions of all known ARM cpu cores.
|
||||
@ -5184,10 +5184,10 @@ Mon Feb 8 21:31:06 1999 Richard Henderson <rth@cygnus.com>
|
||||
(scan_loop): ... moved out of here. Always initialize.
|
||||
Test loop_has_call instead of reg_single_usage not zero.
|
||||
Free reg_single_usage after strength reduction.
|
||||
(count_loop_regs_set): Assume single_usage non-zero.
|
||||
(count_loop_regs_set): Assume single_usage nonzero.
|
||||
(combine_givs_used_by_other): Test reg_single_usage.
|
||||
(load_mems_and_recount_loop_regs_set): Remove reg_single_usage
|
||||
as a parameter. Assume non-zero.
|
||||
as a parameter. Assume nonzero.
|
||||
|
||||
1999-02-08 Zack Weinberg <zack@midnite.ec.rhno.columbia.edu>
|
||||
|
||||
@ -7018,7 +7018,7 @@ Thu Jan 7 03:08:17 1999 Richard Henderson <rth@cygnus.com>
|
||||
Thu Jan 7 03:03:42 1999 Stan Cox <scox@cygnus.com>
|
||||
Richard Henderson <rth@cygnus.com>
|
||||
|
||||
Support for Hypersparc and Sparclite86x:
|
||||
Support for HyperSPARC and SPARClite86x:
|
||||
* sparc.h (TARGET_CPU_hypersparc, TARGET_CPU_sparclite86x): New.
|
||||
(CPP_CPU32_DEFAULT_SPEC): Fix up for the new targets.
|
||||
(ASM_CPU32_DEFAULT_SPEC): Likewise.
|
||||
@ -10282,7 +10282,7 @@ Wed Oct 28 16:46:07 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
|
||||
Wed Oct 28 14:06:49 1998 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* dwarfout.c (dwarfout_file_scope_decl): If DECL_CONTEXT, don't abort
|
||||
if pending_types is non-zero.
|
||||
if pending_types is nonzero.
|
||||
(dwarfout_finish): Verify pending_types is zero before finishing.
|
||||
|
||||
Wed Oct 28 10:29:09 1998 Nick Clifton <nickc@cygnus.com>
|
||||
@ -11967,7 +11967,7 @@ Fri Oct 9 14:26:44 1998 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
Fri Oct 9 11:44:47 1998 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* loop.c (insert_bct): Ensure loop_iteration_var non-zero before use.
|
||||
* loop.c (insert_bct): Ensure loop_iteration_var nonzero before use.
|
||||
|
||||
Thu Oct 8 21:59:47 1998 Dave Brolley <brolley@cygnus.com>
|
||||
|
||||
@ -13059,7 +13059,7 @@ Sat Sep 19 12:05:09 1998 Richard Henderson <rth@cygnus.com>
|
||||
Sat Sep 19 07:33:36 1998 Richard Earnshaw (rearnsha@arm.com)
|
||||
|
||||
* arm.c (add_constant): New parameter address_only, change caller.
|
||||
Set it non-zero if taking the address of an item in the pool.
|
||||
Set it nonzero if taking the address of an item in the pool.
|
||||
(arm_reorg): Handle cases where we need the address of an item in
|
||||
the pool.
|
||||
|
||||
@ -13371,7 +13371,7 @@ Sun Sep 13 08:13:39 1998 Ben Elliston <bje@cygnus.com>
|
||||
runtime library will do this.
|
||||
|
||||
* objc/Make-lang.in: Do not build the runtime library or install
|
||||
the Objective C header files. The Makefile for the runtime
|
||||
the Objective-C header files. The Makefile for the runtime
|
||||
library will do this.
|
||||
|
||||
* objc/Makefile.in (all.indirect): Only build the front-end.
|
||||
@ -15068,7 +15068,7 @@ Mon Aug 10 19:02:55 1998 John Carr <jfc@mit.edu>
|
||||
Mon Aug 10 04:28:13 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
|
||||
Richard Henderson <rth@cygnus.com>
|
||||
|
||||
Rewrite Sparc backend for better code generation and
|
||||
Rewrite SPARC backend for better code generation and
|
||||
improved sparc64 support.
|
||||
* config/sparc/sp64-elf.h: Set JUMP_TABLES_IN_TEXT_SECTION to
|
||||
zero.
|
||||
@ -15155,7 +15155,7 @@ Mon Aug 10 04:28:13 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
|
||||
(define_function_unit ieu1): New, executes compare, call, and
|
||||
uncond_branch type insns.
|
||||
(define_function_units for type fdivs, fdivd, fsqrt): These
|
||||
execute in the fpu multiply unit not the adder on UltraSparc.
|
||||
execute in the fpu multiply unit not the adder on UltraSPARC.
|
||||
(define_expand cmpdi): Disallow TARGET_V8PLUS.
|
||||
(define_insn cmpsi_insn): Rename to cmpsi_insn_sp32.
|
||||
(define_insn cmpsi_insn_sp64): New, same as sp32 variant except it
|
||||
@ -15570,7 +15570,7 @@ Mon Jul 27 14:22:36 1998 Dave Brolley <brolley@cygnus.com>
|
||||
|
||||
Mon Jul 27 11:43:54 1998 Stan Cox <scox@cygnus.com>
|
||||
|
||||
* longlong.h (count_leading_zeros): Sparclite scan instruction was
|
||||
* longlong.h (count_leading_zeros): SPARClite scan instruction was
|
||||
being invoked incorrectly.
|
||||
|
||||
* i386.c (ix86_prologue): Added SUBTARGET_PROLOGUE invocation.
|
||||
|
@ -262,7 +262,7 @@ Fri Dec 24 12:34:26 1999 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
Thu Dec 23 23:15:22 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
|
||||
* reload1.c (emit_input_reload_insns): Restore old behaviour
|
||||
* reload1.c (emit_input_reload_insns): Restore old behavior
|
||||
wrt. 'special' reloads.
|
||||
|
||||
1999-12-23 Zack Weinberg <zack@wolery.cumb.org>
|
||||
@ -1531,7 +1531,7 @@ Thu Dec 2 18:59:48 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
|
||||
1999-12-02 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* config/fp-bit.c: Initialise all fields of the NAN
|
||||
* config/fp-bit.c: Initialize all fields of the NAN
|
||||
constants.
|
||||
|
||||
* c-lex.c (check_newline): Pass pragma_getc and pragma_ungetc
|
||||
@ -2434,10 +2434,10 @@ Thu Nov 18 11:10:03 1999 Jan Hubicka <hubicka@freesoft.cz>
|
||||
|
||||
1999-11-18 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* toplev.c (main): Correctly detect an unrecognised option.
|
||||
* toplev.c (main): Correctly detect an unrecognized option.
|
||||
|
||||
* cppinit.c (cpp_handle_option): Do not claim to have consumed
|
||||
a -f option if it has not been recognised.
|
||||
a -f option if it has not been recognized.
|
||||
|
||||
Thu Nov 18 00:59:11 1999 Michael Gschwind <mikeg@alagoas.watson.ibm.com>
|
||||
|
||||
@ -3184,13 +3184,13 @@ Wed Nov 3 15:11:27 1999 David S. Miller <davem@redhat.com>
|
||||
|
||||
* config/sparc/sparc.md: Remove insn type fpsqrt, add fpsqrts
|
||||
and fpsqrtd. Use them and create fdiv function unit to more
|
||||
accurately represent fpu sqrt pipeline semantics on UltraSparc.
|
||||
accurately represent fpu sqrt pipeline semantics on UltraSPARC.
|
||||
* config/sparc/sparc.c: Account for fpsqrt{s,d} changes.
|
||||
|
||||
Wed Nov 3 15:11:27 1999 Matteo Frigo <athena@fftw.org>
|
||||
|
||||
* config/sparc/sparc.md: Adjust FADD/FMUL result latencies to
|
||||
3 on UltraSparc.
|
||||
3 on UltraSPARC.
|
||||
* config/sparc/sparc.c (ultra_schedule_insn): Insert launched
|
||||
insn into ready list, do not use just a raw swap.
|
||||
|
||||
@ -3567,7 +3567,7 @@ Sat Oct 30 14:31:48 1999 Richard Henderson <rth@cygnus.com>
|
||||
(ggc_alloc_obj): Likewise. Use a different pattern than poison_pages.
|
||||
(ggc_collect): Poison before sweeping.
|
||||
* ggc-simple.c: Update pre-function commentary.
|
||||
(ggc_alloc_obj): Poison non-zeroed memory.
|
||||
(ggc_alloc_obj): Poison nonzeroed memory.
|
||||
|
||||
Sat Oct 30 14:28:52 1999 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
@ -4002,7 +4002,7 @@ Mon Oct 18 21:16:06 1999 Fred Fish <fnf@be.com>
|
||||
|
||||
Thu Oct 28 10:00:48 1999 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* config/arm/arm.c: Initialise arm_structure_size_boundary to
|
||||
* config/arm/arm.c: Initialize arm_structure_size_boundary to
|
||||
DEFAULT_STRUCTURE_SIZE_BOUNDARY.
|
||||
* config/arm/arm.h (DEFAULT_STRUCTURE_SIZE_BOUNDARY): Define
|
||||
to the value 32 if it has not already been defined.
|
||||
@ -4782,7 +4782,7 @@ Tue Oct 19 15:26:11 1999 Richard Earnshaw (rearnsha@arm.com)
|
||||
Tue Oct 19 14:01:34 1999 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* toplev.c (main): Do not generate an error message if an
|
||||
unrecognised command line switch is recognisable by another
|
||||
unrecognized command line switch is recognisable by another
|
||||
language. If extra_warnings are enabled, then generate a
|
||||
warning message instead.
|
||||
|
||||
@ -4960,7 +4960,7 @@ Sat Oct 16 13:42:29 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
|
||||
Sat Oct 16 13:37:46 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
|
||||
* config/c4x/c4x.md (movstrqi_small): Utilise parallel move
|
||||
* config/c4x/c4x.md (movstrqi_small): Utilize parallel move
|
||||
instructions.
|
||||
|
||||
Sat Oct 16 13:26:47 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
@ -6509,15 +6509,15 @@ Sat Sep 25 09:03:17 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
Sat Sep 25 13:42:15 1999 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* varasm.c (asm_emit_uninitialised): New function: Generate
|
||||
the assembler statements necessary to declare an uninitialised
|
||||
the assembler statements necessary to declare an uninitialized
|
||||
variable.
|
||||
(ASM_EMIT_LOCAL): New macro: Emit a local, uninitialised
|
||||
(ASM_EMIT_LOCAL): New macro: Emit a local, uninitialized
|
||||
variable.
|
||||
(ASM_EMIT_BSS): New macro: Emit an entry in the bss section.
|
||||
(ASM_EMIT_COMMON): New macro: Emit an entry in the common
|
||||
section.
|
||||
(assemble_variable): Use asm_emit_uninitialised to emit an
|
||||
uninitialised variable.
|
||||
uninitialized variable.
|
||||
|
||||
Fri Sep 24 17:10:56 1999 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
@ -8316,7 +8316,7 @@ Thu Sep 9 13:46:06 1999 Geoffrey Keating <geoffk@cygnus.com>
|
||||
* cppexp.c (cpp_lex): Handle `defined (xxx)' for poisoned xxx.
|
||||
Include cpphash.h.
|
||||
* cpphash.c (special_symbol): Handle plain `xxx' for poisoned xxx.
|
||||
* cpplib.c (do_define): Generalise to handle poisoned definitions,
|
||||
* cpplib.c (do_define): Generalize to handle poisoned definitions,
|
||||
redefining poisoned identifiers, etc.
|
||||
(do_undef): Don't allow poisoned identifiers to be undefined.
|
||||
(do_pragma): Add #pragma poison.
|
||||
@ -8325,7 +8325,7 @@ Thu Sep 9 13:46:06 1999 Geoffrey Keating <geoffk@cygnus.com>
|
||||
* cccp.c: Add T_POISON node type.
|
||||
(special_symbol): Handle `defined(xxx)' and plain `xxx' for
|
||||
poisoned xxx.
|
||||
(do_define): Generalise to handle poisoned definitions,
|
||||
(do_define): Generalize to handle poisoned definitions,
|
||||
redefining poisoned identifiers, etc.
|
||||
(do_undef): Don't allow poisoned identifiers to be undefined.
|
||||
(do_pragma): Add #pragma poison.
|
||||
@ -9759,7 +9759,7 @@ Sun Aug 29 04:30:52 1999 John Wehle (john@feith.com)
|
||||
All uses updated.
|
||||
(prescan_loop, strength_reduce): New argument loop_info. All callers
|
||||
updated.
|
||||
(scan_loop): New variable loop_info, initialise to address of
|
||||
(scan_loop): New variable loop_info, initialize to address of
|
||||
this_loop_info.
|
||||
(prescan_loop): Set loop_info->vtop if find NOTE_INSN_LOOP_VTOP.
|
||||
Delete variable loop_has_multiple_exit targets and replace with
|
||||
@ -14093,7 +14093,7 @@ Wed Jun 2 12:25:55 1999 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
Wed Jun 2 08:42:55 1999 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* config/arm/tcoff.h (USER_LABEL_PREFIX): Synchronise with
|
||||
* config/arm/tcoff.h (USER_LABEL_PREFIX): Synchronize with
|
||||
definition in config/arm/coff.h
|
||||
* config/arm/coff.h: Add comment about USER_LABEL_PREFIX.
|
||||
|
||||
|
@ -1353,7 +1353,7 @@ Wed Jun 7 20:34:33 2000 Denis Chertykov <denisc@overta.ru>
|
||||
* c-common.h (c_language_kind): New type.
|
||||
(c_language): New variab.e
|
||||
* c-common.c (lang_get_alias_set): Don't put structures in
|
||||
non-zero alias sets in C++.
|
||||
nonzero alias sets in C++.
|
||||
* c-decl.c (c_language): Define it.
|
||||
* c-lex.c (doing_objc_thang): Remove.
|
||||
* c-tree.h (doing_objc_thang): Make it a macro.
|
||||
@ -1538,7 +1538,7 @@ Mon Jun 5 06:46:28 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
2000-06-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* Makefile.in (intl.*): Honor non-zero exit codes in the intl
|
||||
* Makefile.in (intl.*): Honor nonzero exit codes in the intl
|
||||
subdir.
|
||||
|
||||
2000-06-03 Geoff Keating <geoffk@cygnus.com>
|
||||
@ -2036,7 +2036,7 @@ Sun May 28 18:37:07 2000 Clinton Popetz <cpopetz@cygnus.com>
|
||||
|
||||
Sun May 28 23:26:59 2000 Philippe De Muyter <phdm@macqel.be>
|
||||
|
||||
* mklibgcc.in (all): Variable initialised to `libgcc'.
|
||||
* mklibgcc.in (all): Variable initialized to `libgcc'.
|
||||
|
||||
2000-05-28 Gabriel Dos Reis <gdr@codesourcery.com>
|
||||
|
||||
@ -2088,10 +2088,10 @@ Sun May 28 23:26:59 2000 Philippe De Muyter <phdm@macqel.be>
|
||||
* regclass.c [CLASS_CANNOT_CHANGE_SIZE]
|
||||
(class_can_change_size): New variable.
|
||||
(reg_changes_size): New variable.
|
||||
(init_reg_sets_1): Initialise class_can_change_size.
|
||||
(init_reg_sets_1): Initialize class_can_change_size.
|
||||
(record_operand_costs): Remove subreg_changes_size.
|
||||
Don't pass it around. Instead update reg_changes_size.
|
||||
(regclass): Initialise and free reg_changes_size. If a register
|
||||
(regclass): Initialize and free reg_changes_size. If a register
|
||||
changes size, don't preference it to a class that contains
|
||||
registers that can't change size.
|
||||
(record_reg_classes): Don't look at subreg_changes_size.
|
||||
@ -2161,7 +2161,7 @@ Sun May 28 23:26:59 2000 Philippe De Muyter <phdm@macqel.be>
|
||||
|
||||
* reload.c (get_secondary_mem): Don't widen floating-point modes.
|
||||
|
||||
* combine.c (subst): Honour CLASS_CANNOT_CHANGE_SIZE when
|
||||
* combine.c (subst): Honor CLASS_CANNOT_CHANGE_SIZE when
|
||||
substituting the REG in a (subreg:X (reg:Y ...)).
|
||||
|
||||
2000-05-28 Neil Booth <NeilB@earthling.net>
|
||||
@ -2174,7 +2174,7 @@ Sun May 28 23:26:59 2000 Philippe De Muyter <phdm@macqel.be>
|
||||
|
||||
2000-05-28 Neil Booth <NeilB@earthling.net>
|
||||
|
||||
* cpplex.c (_cpp_init_toklist): No comment space to initialise.
|
||||
* cpplex.c (_cpp_init_toklist): No comment space to initialize.
|
||||
(_cpp_free_toklist): No comment space to free.
|
||||
(expand_comment_space): Remove.
|
||||
(save_comment_space): Place the comment in the current token and
|
||||
@ -2340,7 +2340,7 @@ Sat May 27 11:01:27 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
boolean_operator for the boolean patterns without NOTs.
|
||||
|
||||
* config/rs6000/rs6000.c (reg_or_logical_cint_operand): Rename
|
||||
from reg_or_u_cint_operand. Change comment and behaviour.
|
||||
from reg_or_u_cint_operand. Change comment and behavior.
|
||||
(logical_operand): Clean up, add assertion.
|
||||
(non_logical_cint_operand): Also check for
|
||||
reg_or_logical_cint_operand.
|
||||
@ -3133,7 +3133,7 @@ Fri May 19 06:49:35 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
2000-05-18 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* config/arm/unknown-elf.h (UNIQUE_SECTION): Place constant,
|
||||
uninitialised data in .rodata not .bss, and do not interpret an
|
||||
uninitialized data in .rodata not .bss, and do not interpret an
|
||||
error in the initialisation value as meaning that the variable
|
||||
should be placed in the .bss section.
|
||||
|
||||
@ -3225,7 +3225,7 @@ Thu May 18 12:10:18 2000 Philippe De Muyter <phdm@macqel.be>
|
||||
|
||||
2000-05-18 Neil Booth <NeilB@earthling.net>
|
||||
|
||||
* cppinit.c (cpp_reader_init): Initialise col_adjust and
|
||||
* cppinit.c (cpp_reader_init): Initialize col_adjust and
|
||||
default tab stop size.
|
||||
(no_num, OPT_ftabstop): New.
|
||||
(handle_option): Handle "ftabstop=" command-line option.
|
||||
@ -7957,7 +7957,7 @@ Wed Apr 5 18:03:31 2000 Toshiyasu Morita (toshi.morita@sega.com)
|
||||
2000-04-05 Chris Demetriou <cgd@netbsd.org>
|
||||
|
||||
* mips.h (MASK_DEBUG_A, MASK_DEBUG_B, MASK_DEBUG_C): Zero the
|
||||
remaining non-zero debugging masks.
|
||||
remaining nonzero debugging masks.
|
||||
|
||||
Wed Apr 5 09:44:07 2000 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
@ -10256,7 +10256,7 @@ Thu Mar 16 02:14:16 2000 Hans-Peter Nilsson <hp@bitrange.com>
|
||||
2000-02-03 Geoff Keating <geoffk@cygnus.com>
|
||||
|
||||
* rs6000.c (rs6000_sr_alias_set): New variable.
|
||||
(rs6000_override_options): Initialise rs6000_sr_alias_set.
|
||||
(rs6000_override_options): Initialize rs6000_sr_alias_set.
|
||||
(rs6000_emit_stack_tie): New function.
|
||||
(rs6000_emit_allocate_stack): Specify RTX_FRAME_RELATED_P
|
||||
in a way that dwarf2out can understand.
|
||||
@ -10804,8 +10804,8 @@ Wed Feb 23 13:00:06 CET 2000 Jan Hubicka <jh@suse.cz>
|
||||
2000-03-14 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* gcc.c (do_spec_1): Catch the case where %* is used in a
|
||||
substitution pattern, but it has not been initialised.
|
||||
Issue a meaningful error message if an unrecognised operator
|
||||
substitution pattern, but it has not been initialized.
|
||||
Issue a meaningful error message if an unrecognized operator
|
||||
is encountered in a spec string.
|
||||
|
||||
2000-03-14 Richard Earnshaw <rearnsha@arm.com>
|
||||
@ -15005,7 +15005,7 @@ Mon Jan 24 16:50:08 MET 2000 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* basic-block.h (struct loops): New field `levels'.
|
||||
* flow.c (flow_loops_level_compute): Traverse all outer loops.
|
||||
(flow_loop_level_compute): Initialise level to 1.
|
||||
(flow_loop_level_compute): Initialize level to 1.
|
||||
(flow_loops_find): Set loops->levels.
|
||||
(flow_loops_dump): Print loops->levels.
|
||||
|
||||
@ -15047,7 +15047,7 @@ Mon Jan 24 16:50:08 MET 2000 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
2000-01-22 Alan Modra <alan@SPRI.Levels.UniSA.Edu.Au>
|
||||
|
||||
* config/elfos.h (UNIQUE_SECTION): Restore uninitialised data
|
||||
* config/elfos.h (UNIQUE_SECTION): Restore uninitialized data
|
||||
section naming to that prior to 2000-01-07 patch.
|
||||
* config/mips/elf.h (UNIQUE_SECTION): Ditto.
|
||||
* config/mips/elf64.h (UNIQUE_SECTION): Ditto.
|
||||
@ -15242,7 +15242,7 @@ Wed Jan 19 19:12:36 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
* loop.c (current_loop_info): Renamed from loop_info_data
|
||||
and changed to a pointer.
|
||||
(loop_optimize): Allocate loop_info structure for each loop
|
||||
and initialise to zero.
|
||||
and initialize to zero.
|
||||
(scan_loop): Set current_loop_info.
|
||||
|
||||
* unroll.c (loop_iterations): Don't abort if REG_USERVAR_P set
|
||||
@ -15281,7 +15281,7 @@ Wed Jan 19 19:12:36 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
(expand_end_bindings): Likewise.
|
||||
(expand_decl): Likewise. Consult optimize not obey_regdecls.
|
||||
* toplev.c (obey_regdecls): Remove.
|
||||
(rest_of_compilation): Don't set it. Kill stupid in favour of
|
||||
(rest_of_compilation): Don't set it. Kill stupid in favor of
|
||||
flow1, local-alloc, and reload.
|
||||
(main): Don't set obey_regdecls.
|
||||
|
||||
@ -16500,25 +16500,25 @@ Thu Jan 6 13:44:59 CET 2000 Jan Hubicka <jh@suse.cz>
|
||||
uninitialized data decls.
|
||||
|
||||
* config/i386/winnt.c (i386_pe_unique_section): Cope with
|
||||
being called for uninitialised data.
|
||||
being called for uninitialized data.
|
||||
|
||||
* config/i386/interix.c (i386_pe_unique_section): Cope with
|
||||
being called for uninitialised data.
|
||||
being called for uninitialized data.
|
||||
|
||||
* config/mips/elf.h (UNIQUE_SECTION): Cope with being called
|
||||
for uninitialised data.
|
||||
for uninitialized data.
|
||||
|
||||
* config/mips/elf64.h (UNIQUE_SECTION): Cope with being called
|
||||
for uninitialised data.
|
||||
for uninitialized data.
|
||||
|
||||
* config/mips/iri6gld.h (UNIQUE_SECTION): Cope with being called
|
||||
for uninitialised data.
|
||||
for uninitialized data.
|
||||
|
||||
* config/arm/unknown-elf.h (IN_NAMED_SECTION): Define.
|
||||
(UNIQUE_SECTION_P): Always generate a unique section if
|
||||
flag_data_sections is true.
|
||||
(UNIQUE_SECTION): Also generate unique sections for
|
||||
uninitialised data.
|
||||
uninitialized data.
|
||||
(ASM_OUTPUT_ALIGNED_BSS): Redefine to use named_section().
|
||||
(ASM_OUTPUT_ALIGNED_DECL_LOCAL): Redefine to use
|
||||
named_section().
|
||||
@ -16611,7 +16611,7 @@ Tue Jan 4 22:30:16 2000 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
2000-01-05 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
|
||||
* config/c4x/c4x.h (IS_XXX_REG, IS_XXX_REGNO): Swap behaviour of
|
||||
* config/c4x/c4x.h (IS_XXX_REG, IS_XXX_REGNO): Swap behavior of
|
||||
macros so that they're consistent with their names.
|
||||
* config/c4x/c4x.c (IS_XXX_REG, IS_XXX_REGNO): Likewise.
|
||||
* config/c4x/c4x.md (IS_XXX_REG, IS_XXX_REGNO): Likewise.
|
||||
|
@ -142,7 +142,7 @@
|
||||
|
||||
* c-parse.in (select_or_iter_stmt): Use truthvalue_conversion
|
||||
on the condition of a FOR statement, so that it gets typechecked
|
||||
and optimised.
|
||||
and optimized.
|
||||
|
||||
2000-12-29 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
@ -300,7 +300,7 @@
|
||||
scavenging it.
|
||||
|
||||
* dwarf2out_frame_debug_expr: Allow the (scratch) frame
|
||||
pointer to be initialised from the stack pointer plus a
|
||||
pointer to be initialized from the stack pointer plus a
|
||||
constant.
|
||||
|
||||
2000-12-22 Bernd Schmidt <bernds@redhat.com>
|
||||
@ -355,7 +355,7 @@
|
||||
|
||||
* reload.c (update_auto_inc_notes): New, broken out from ...
|
||||
(find_reloads_address_1): ... use here, also correct possible
|
||||
use of uninitialised reloadnum.
|
||||
use of uninitialized reloadnum.
|
||||
|
||||
2000-12-21 David O'Brien <obrien@FreeBSD.org>
|
||||
|
||||
@ -1235,7 +1235,7 @@ Mon Dec 11 13:51:09 2000 Jeffrey A Law (law@cygnus.com)
|
||||
arm_compute_save_reg_mask.
|
||||
(arm_expand_prologue): Use arm_current_func_type and
|
||||
arm_compute_save_reg_mask.
|
||||
(arm_init_machine_status): Initialise func_type field, if
|
||||
(arm_init_machine_status): Initialize func_type field, if
|
||||
necessary.
|
||||
(thumb_expand_prologue): Use arm_current_func_type.
|
||||
(output_thumb_prologue): Use arm_current_func_type.
|
||||
@ -2120,7 +2120,7 @@ Tue Dec 5 20:09:14 2000 Jeffrey A Law (law@cygnus.com)
|
||||
(expand_builtin_strrchr): Use it.
|
||||
(builtin_memset_read_str): New function.
|
||||
(expand_builtin_memset): Use target_char_cast.
|
||||
Try to optimize memset with second argument non-zero using
|
||||
Try to optimize memset with second argument nonzero using
|
||||
store_by_pieces.
|
||||
|
||||
2000-11-30 Marek Michalkiewicz <marekm@linux.org.pl>
|
||||
@ -2923,9 +2923,9 @@ Sun Nov 26 10:02:37 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
(cxx_target_objs): Substitute in the makefile.
|
||||
* configure: Regenerate.
|
||||
|
||||
* Makefile.in (C_TARGET_OBJS): Define and initialise from
|
||||
* Makefile.in (C_TARGET_OBJS): Define and initialize from
|
||||
c_target_objs.
|
||||
(CXX_TARGET_OBJS): Define and initialise from
|
||||
(CXX_TARGET_OBJS): Define and initialize from
|
||||
cxx_target_objs.
|
||||
(C_AND_OBJC_OBJS): Include C_TARGET_OBJS.
|
||||
|
||||
@ -3046,7 +3046,7 @@ Fri Nov 24 19:48:09 2000 J"orn Rennecke <amylaar@redhat.com>
|
||||
|
||||
2000-11-23 Graham Stott <grahams@redhat.com>
|
||||
|
||||
* cse.c (cse_insn): Initialise all regcost variables.
|
||||
* cse.c (cse_insn): Initialize all regcost variables.
|
||||
Fix a typo add missing '='.
|
||||
Only compare costs if there is a replacement insn.
|
||||
|
||||
@ -3247,7 +3247,7 @@ Wed Nov 22 00:52:55 2000 J"orn Rennecke <amylaar@redhat.com>
|
||||
|
||||
2000-11-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* configure.in (HAVE_AS_DWARF2_DEBUG_LINE): Sparc has .file/.loc
|
||||
* configure.in (HAVE_AS_DWARF2_DEBUG_LINE): SPARC has .file/.loc
|
||||
support in as as well.
|
||||
* configure: Regenerate.
|
||||
|
||||
@ -3811,7 +3811,7 @@ Tue Nov 14 12:34:56 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
2000-11-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* reload1.c (emit_input_reload_insns): Honour forcing of constants
|
||||
* reload1.c (emit_input_reload_insns): Honor forcing of constants
|
||||
into memory by PREFERRED_RELOAD_CLASS NO_REGS.
|
||||
|
||||
2000-11-14 Michael Matz <matzmich@cs.tu-berlin.de>
|
||||
@ -5216,13 +5216,13 @@ Tue Oct 31 15:33:27 2000 J"orn Rennecke <amylaar@redhat.com>
|
||||
hash table.
|
||||
|
||||
* cppinit.c (cpp_reader_init): Move cpp_init_completed test to top.
|
||||
Initialise various members of cpp_reader, memory pools, and the
|
||||
Initialize various members of cpp_reader, memory pools, and the
|
||||
special nodes.
|
||||
(cpp_printer_init): Delete.
|
||||
(cpp_cleanup): Update.
|
||||
(struct builtin, builtin_array, initialize_builtins): Update for new
|
||||
hashnode definition and builtin handling.
|
||||
(cpp_start_read, cpp_finish): Don't take or initialise a
|
||||
(cpp_start_read, cpp_finish): Don't take or initialize a
|
||||
printer. Update.
|
||||
|
||||
* cpplib.h (cpp_printer, cpp_toklist, CPP_DEFINED, BOL,
|
||||
@ -7147,7 +7147,7 @@ Fri Sep 29 13:20:42 MET DST 2000 Jan Hubicka <jh@suse.cz>
|
||||
error" tests.
|
||||
* cppinit.c (cpp_handle_option): Remove surplus \n.
|
||||
* cpplex.c (ON_REST_ARG): Delete.
|
||||
(skip_block_comment): Initialise prevc.
|
||||
(skip_block_comment): Initialize prevc.
|
||||
(parse_args): Improve error messages.
|
||||
(maybe_paste_with_next): Use CONTEXT_VARARGS rather
|
||||
than ON_REST_ARG.
|
||||
@ -8018,14 +8018,14 @@ Mon 18-Sep-2000 19:21:35 BST Neil Booth <NeilB@earthling.net>
|
||||
* cpplib.c (_cpp_check_directive, _cpp_check_linemarker):
|
||||
New implementations.
|
||||
(do_assert): Don't bother setting the answer's list's line.
|
||||
(cpp_push_buffer): Initialise new pfile and read_ahead members
|
||||
(cpp_push_buffer): Initialize new pfile and read_ahead members
|
||||
of struct cpp_buffer.
|
||||
|
||||
* cpplib.h (cppchar_t): New typedef.
|
||||
(struct cpp_buffer): read_ahead, pfile and col_adjust are
|
||||
new members.
|
||||
(struct lexer_state): New structure that determines the state
|
||||
and behaviour of the lexer.
|
||||
and behavior of the lexer.
|
||||
(IN_DIRECTIVE, KNOWN_DIRECTIVE): New macros.
|
||||
(struct cpp_reader): New member "state". Rename
|
||||
multiline_string_line and multiline_string_column. Delete
|
||||
@ -8101,7 +8101,7 @@ Mon 18-Sep-2000 19:21:35 BST Neil Booth <NeilB@earthling.net>
|
||||
|
||||
2000-09-18 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* c-common.c (check_format_types): Reorganise and clean up,
|
||||
* c-common.c (check_format_types): Reorganize and clean up,
|
||||
checking earlier for ERROR_MARKs and making cur_type into its
|
||||
TYPE_MAIN_VARIANT where convenient.
|
||||
|
||||
@ -8547,9 +8547,9 @@ Fri 15-Sep-2000 06:49:07 BST Neil Booth <NeilB@earthling.net>
|
||||
* config/h8300.h (TARGET_MAC): New.
|
||||
(TARGET_SWITCHES): Add -ms2600 and -mno-s2600.
|
||||
(CONDITIONA_REGISTER_USAGE): Disable the mac register on any
|
||||
machine other than H8/S2600.
|
||||
* config/h8300.md: Accept mac instructions on the H8/S2600 instead
|
||||
of the H8/S2000.
|
||||
machine other than H8S/2600.
|
||||
* config/h8300.md: Accept mac instructions on the H8S/2600 instead
|
||||
of the H8S/2000.
|
||||
|
||||
2000-09-14 Alexandre Oliva <aoliva@redhat.com>, Bernd Schmidt <bernds@redhat.co.uk>
|
||||
|
||||
@ -9445,7 +9445,7 @@ Thu 07-Sep-2000 21:29:00 BST Neil Booth <NeilB@earthling.net>
|
||||
yy_lim, or yy_get_token. Don't define get_directive_line if
|
||||
USE_CPPLIB.
|
||||
* c-common.h: Add multiple include guard. Define RID values
|
||||
for every keyword in C, C++, and Objective C. Put all the
|
||||
for every keyword in C, C++, and Objective-C. Put all the
|
||||
modifiers first.
|
||||
(struct c_fileinfo, get_fileinfo, dump_time_statistics): New.
|
||||
* c-decl.c (c_decode_option): Handle -lang-objc here.
|
||||
@ -11108,7 +11108,7 @@ Sun 20-Aug-2000 09:25:45 BST Neil Booth <NeilB@earthling.net>
|
||||
instructions in it before checking for indirect jumps.
|
||||
|
||||
* ifcvt.c (find_if_block): Do not consider a THEN block that ends
|
||||
in a indirect jump as a potential for conditional execution.
|
||||
in an indirect jump as a potential for conditional execution.
|
||||
|
||||
* d30v.h (d30v_init_expanders): Don't declare here.
|
||||
* d30v-protos.h (d30v_init_expanders): Declare here with a valid
|
||||
@ -11556,7 +11556,7 @@ Mon Aug 14 18:51:44 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
rather than DECL_OFFSET_ALIGN.
|
||||
(place_field): Likewise.
|
||||
* expmed.c (store_bit_field): Abort on align==0 to avoid
|
||||
antisocial machine behaviour.
|
||||
antisocial machine behavior.
|
||||
|
||||
2000-08-12 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
@ -12487,7 +12487,7 @@ Thu Aug 3 15:53:03 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
2000-08-03 Kazu Hirata <kazu@hxi.com>
|
||||
|
||||
* h8300.c: Fix a comment typo.
|
||||
* h8300.h (OK_FOR_U): Accept a 32-bit constant address on H8/S.
|
||||
* h8300.h (OK_FOR_U): Accept a 32-bit constant address on H8S.
|
||||
|
||||
* jump.c: Fix formatting.
|
||||
|
||||
@ -12911,7 +12911,7 @@ Mon Jul 31 20:35:50 2000 Denis Chertykov <denisc@overta.ru>
|
||||
|
||||
* h8300.h (MODES_TIEABLE_P): Accept a combination of QImode and
|
||||
HImode on all architectures and a combination of HImode and SImode
|
||||
on H8/300H and H8/S.
|
||||
on H8/300H and H8S.
|
||||
|
||||
* h8300.c (split_adds_subs): Rearrange code for conciseness.
|
||||
|
||||
@ -13799,7 +13799,7 @@ Wed Jul 19 01:22:15 CEST 2000 Marc Espie <espie@cvs.openbsd.org>
|
||||
|
||||
2000-07-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* calls.c (store_arg): Return non-zero if sibcall_failure is desired.
|
||||
* calls.c (store_arg): Return nonzero if sibcall_failure is desired.
|
||||
(expand_call): Adjust caller.
|
||||
|
||||
2000-07-17 Gabriel Dos Reis <gdr@codesourcery.com>
|
||||
@ -14169,7 +14169,7 @@ Fri Jul 14 10:25:53 2000 Clinton Popetz <cpopetz@cygnus.com>
|
||||
* c-common.h (flag_digraphs): New.
|
||||
* c-decl.c (c_decode_option): Set flag_digraphs as appropriate.
|
||||
* c-lex.c (yylex): Use flag_digraphs to decide whether to
|
||||
honour digraphs.
|
||||
honor digraphs.
|
||||
|
||||
2000-07-13 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
@ -14482,7 +14482,7 @@ Tue Jul 11 16:26:17 2000 Clinton Popetz <cpopetz@cygnus.com>
|
||||
(handle_option): Set digraphs according to standard.
|
||||
Merge OPT_lang_c89 handler with OPT_std_c89.
|
||||
|
||||
* cpplex.c: (lex_line, can_paste): Honour digraphs in
|
||||
* cpplex.c: (lex_line, can_paste): Honor digraphs in
|
||||
accordance with the digraphs flag.
|
||||
|
||||
* cpplib.h: (struct cpp_options): New option digraphs.
|
||||
|
@ -24,7 +24,7 @@
|
||||
* gcc.c (process_command): Append a DIR_SEPARATOR to a path
|
||||
specified by the -B switch, if doing so would create a valid
|
||||
directory name.
|
||||
* doc/invoke.texi: Document changed behaviour of -B.
|
||||
* doc/invoke.texi: Document changed behavior of -B.
|
||||
|
||||
2001-06-29 DJ Delorie <dj@redhat.com>
|
||||
|
||||
@ -77,7 +77,7 @@ Fri Jun 29 12:27:24 2001 Jeffrey A Law (law@cygnus.com)
|
||||
* config/arc/arc-protos.h, config/arc/arc.c, config/arc/arc.h
|
||||
(arc_comp_type_attributes, arc_set_default_type_attributes,
|
||||
COMP_TYPE_ATTRIBUTES, SET_DEFAULT_TYPE_ATTRIBUTES): Remove
|
||||
functions and macros with default behaviour.
|
||||
functions and macros with default behavior.
|
||||
* config/m32r/m32r-protos.h, config/m32r/m32r.c,
|
||||
config/m32r/m32r.h (m32r_comp_type_attributes,
|
||||
m32r_set_default_type_attributes, COMP_TYPE_ATTRIBUTES,
|
||||
@ -1070,7 +1070,7 @@ Mon Jun 18 15:43:10 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
2001-06-18 Ben Elliston <bje@redhat.com>
|
||||
|
||||
* except.c (resolve_fixup_regions): Initialise "cleanup".
|
||||
* except.c (resolve_fixup_regions): Initialize "cleanup".
|
||||
|
||||
2001-06-17 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
@ -1131,7 +1131,7 @@ Fri Jun 15 18:05:22 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
Fri Jun 15 19:35:38 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* optabs.c (expand_twoval_binop): Avoid undefined behaviour.
|
||||
* optabs.c (expand_twoval_binop): Avoid undefined behavior.
|
||||
|
||||
2001-06-15 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
|
||||
|
||||
@ -2885,7 +2885,7 @@ Thu May 24 15:56:48 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
2001-05-22 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* unwind-dw2-fde.c (__deregister_frame_info): Stubbify in favour of...
|
||||
* unwind-dw2-fde.c (__deregister_frame_info): Stubbify in favor of...
|
||||
(__deregister_frame_info_bases): New.
|
||||
* unwind-dw2-fde.h: Declare it.
|
||||
* libgcc-std.ver: Export it.
|
||||
@ -2903,7 +2903,7 @@ Thu May 24 15:56:48 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
* config/ia64/ia64.md (nonlocal_goto): Reverse label and frame pointer
|
||||
parameters to __ia64_nonlocal_goto. Flag as NO_RETURN.
|
||||
* config/ia64/ia64.c (ia64_expand_epilogue): Make sure we are issuing
|
||||
"r2" to the assembly file. Only issue allocs with non-zero parameters.
|
||||
"r2" to the assembly file. Only issue allocs with nonzero parameters.
|
||||
|
||||
2001-05-22 Loren J. Rittle <ljrittle@acm.org>
|
||||
David O'Brien <obrien@freebsd.org>
|
||||
@ -4498,7 +4498,7 @@ Fri May 4 13:10:03 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
(ix86_align_loops): Delete.
|
||||
(ix86_align_jumps): Delete.
|
||||
(override_options): Mark -malign-* as obsolete. Emulate their
|
||||
behaviour with the -falign-* options. Default -falign-* from
|
||||
behavior with the -falign-* options. Default -falign-* from
|
||||
the processor table.
|
||||
* i386.h (FUNCTION_BOUNDARY): Define to 16; revert Richard Kenner's
|
||||
patch of Wed May 2 13:09:36 2001.
|
||||
@ -5194,7 +5194,7 @@ Wed Apr 25 17:09:50 2001 J"orn Rennecke <amylaar@redhat.com>
|
||||
2001-04-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* emit-rtl.c (subreg_hard_regno): Only do HARD_REGNO_MODE_OK check
|
||||
if check_mode is non-zero.
|
||||
if check_mode is nonzero.
|
||||
|
||||
2001-04-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
@ -10795,7 +10795,7 @@ Fri Feb 9 15:05:27 2001 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
* config/i386/i386.c (ix86_frame_pointer_required): New.
|
||||
(ix86_setup_frame_addresses): New.
|
||||
(struct machine_funciton): Add accesses_prev_frame.
|
||||
(struct machine_function): Add accesses_prev_frame.
|
||||
* config/i386/i386.h (FRAME_POINTER_REQUIRED): Call
|
||||
ix86_frame_pointer_required.
|
||||
(SUBTARGET_FRAME_POINTER_REQUIRED): New.
|
||||
@ -11536,7 +11536,7 @@ Mon Jan 29 20:38:19 2001 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
2001-01-27 Michael Sokolov <msokolov@ivan.Harhan.ORG>
|
||||
|
||||
* fixproto: Correctly install synthesised unistd.h and stdlib.h when
|
||||
* fixproto: Correctly install synthesized unistd.h and stdlib.h when
|
||||
they didn't need fixing.
|
||||
|
||||
2001-01-27 Janis Johnson <janis@us.ibm.com>
|
||||
@ -11558,7 +11558,7 @@ Mon Jan 29 20:38:19 2001 Christopher Faylor <cgf@cygnus.com>
|
||||
(really_start_incremental_init): Clear it.
|
||||
(push_init_level): Save constructor_range_stack and clear it if
|
||||
pushing explicit braces.
|
||||
(pop_init_level): abort if constructor_range_stack is non-zero at
|
||||
(pop_init_level): abort if constructor_range_stack is nonzero at
|
||||
explicit closing brace. Restore saved constructor_range_stack if
|
||||
not implicit.
|
||||
|
||||
@ -11587,10 +11587,10 @@ Mon Jan 29 20:38:19 2001 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
* loop.c (loop_giv_reduce_benefit): Copy mode size into
|
||||
int variable.
|
||||
(check_ext_dependant_givs): Initialise u_start_val and
|
||||
(check_ext_dependant_givs): Initialize u_start_val and
|
||||
u_end_val.
|
||||
(load_mems): Make last_max_reg unsigned.
|
||||
(try_swap_copy_prop): Use INSN_P and initialise set.
|
||||
(try_swap_copy_prop): Use INSN_P and initialize set.
|
||||
|
||||
Fri Jan 26 23:22:58 2001 Denis Chertykov <denisc@overta.ru>
|
||||
|
||||
@ -11700,7 +11700,7 @@ Wed Jan 24 23:51:55 2001 J"orn Rennecke <amylaar@redhat.com>
|
||||
* cppinit.c (cpp_start_read): Remove deps_add_dep call.
|
||||
* tradcpp.c (main): Add -imacros or -include'd dependencies
|
||||
for -M*.
|
||||
* cpp.texi (-M, -MM): Document -M -include behaviour.
|
||||
* cpp.texi (-M, -MM): Document -M -include behavior.
|
||||
|
||||
2001-01-24 Roger Collins <roger@ProProject.com>
|
||||
|
||||
@ -11922,7 +11922,7 @@ Sun Jan 21 09:44:17 2001 Denis Chertykov <denisc@overta.ru>
|
||||
|
||||
* config/avr/avr.c (ret_cond_branch): New argument (reverse) added.
|
||||
If REVERSE nonzero then condition code in X must be reversed.
|
||||
(encode_section_info): Optimise if/else.
|
||||
(encode_section_info): Optimize if/else.
|
||||
(avr_function_value): Fix formatting.
|
||||
|
||||
* config/avr/avr.md (branch): Call to ret_cond_branch changed.
|
||||
@ -12652,7 +12652,7 @@ Sat Jan 13 09:53:32 MET 2001 Jan Hubicka <jh@suse.cz>
|
||||
(pending_init_member): Rename to...
|
||||
(find_init_member): ...this function. Call set_nonincremental_init
|
||||
if necessary. Compare values of purpose index trees, not the trees
|
||||
themselves. Return the actual value, not just non-zero if something
|
||||
themselves. Return the actual value, not just nonzero if something
|
||||
is found.
|
||||
(output_init_element): Remove checks for duplicates.
|
||||
If field has zero size, only check the initializer for correctness.
|
||||
@ -12892,7 +12892,7 @@ Fri Jan 12 00:04:00 MET 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
2001-01-10 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* config/d30v/d30v.c (d30v_init_machine_status): Initialise
|
||||
* config/d30v/d30v.c (d30v_init_machine_status): Initialize
|
||||
machine_function structure to zero.
|
||||
Add prototypes for machine_status functions.
|
||||
|
||||
@ -13097,7 +13097,7 @@ Wed Jan 10 16:38:31 MET 2001 Jan Hubicka <jh@suse.cz>
|
||||
* config/d30v/d30v.h (struct_machine): Move here.
|
||||
Add eh_epilogue_sp_ofs field.
|
||||
|
||||
*config/d30v/d30v.md (epilogue): Initialise eh_epilogue_sp_ofs
|
||||
*config/d30v/d30v.md (epilogue): Initialize eh_epilogue_sp_ofs
|
||||
field in cfun->machine structure.
|
||||
|
||||
Tue Jan 9 21:34:57 2001 John David Anglin <dave@hiauly1.hia.nrc.ca>
|
||||
@ -13179,7 +13179,7 @@ Tue Jan 9 21:25:19 2001 Jeffrey A Law (law@cygnus.com)
|
||||
(emit_a_shift): Adopt to the new calling prototype of
|
||||
get_shift_alg.
|
||||
(function_prologue): Fix code for a monitor
|
||||
function. Support H8/S.
|
||||
function. Support H8S.
|
||||
(function_epilogue): Do not output pop for a monitor function.
|
||||
|
||||
2001-01-09 Nick Clifton <nickc@redhat.com>
|
||||
@ -13264,7 +13264,7 @@ Tue Jan 9 21:25:19 2001 Jeffrey A Law (law@cygnus.com)
|
||||
20001-01-09 Graham Stott <grahams@redhat.com>
|
||||
|
||||
* cppfiles.c (_cpp_execute_include): Move `len` initialisation
|
||||
after `ptr` is initialised.
|
||||
after `ptr` is initialized.
|
||||
|
||||
2001-01-09 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
@ -13876,7 +13876,7 @@ Fri Jan 5 16:29:49 MET 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
2001-01-05 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* cpp.texi: Update for -MP. Clarify behaviour of -MT.
|
||||
* cpp.texi: Update for -MP. Clarify behavior of -MT.
|
||||
* cppinit.c (initialize_dependency_output): Update.
|
||||
(cpp_finish): Output dummy targets for -MP.
|
||||
(OPT_MP): New.
|
||||
|
@ -995,7 +995,7 @@ Mon Dec 17 18:27:52 CET 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
Mon Dec 17 17:57:05 CET 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* Makefile.in (cfgcleanup.o): Add cselib.h dependancy.
|
||||
* Makefile.in (cfgcleanup.o): Add cselib.h dependency.
|
||||
* basic-block.h (CLEANUP_THREADING): New constant.
|
||||
* cfgcleanup.c: Include cselib.h
|
||||
(thread_jump, mark_effect): New functions.
|
||||
@ -1020,10 +1020,10 @@ Mon Dec 17 17:57:05 CET 2001 Jan Hubicka <jh@suse.cz>
|
||||
* target.h (asm_out.byte_op, asm_out.aligned_op, asm_out.unaligned_op,
|
||||
asm_out.integer): New fields.
|
||||
* target-def.h (TARGET_ASM_BYTE_OP, TARGET_ASM_ALIGNED_[HSDT]I_OP,
|
||||
TARGET_ASM_UNALIGNED_[HSDT]I_OP, TARGET_ASM_INTEGER): New initialisers.
|
||||
TARGET_ASM_UNALIGNED_[HSDT]I_OP, TARGET_ASM_INTEGER): New initializers.
|
||||
(TARGET_ASM_ALIGNED_INT_OP, TARGET_ASM_UNALIGNED_INT_OP): Collect
|
||||
the individual initialisers together.
|
||||
(TARGET_ASM_OUT): Add the new initialisers.
|
||||
the individual initializers together.
|
||||
(TARGET_ASM_OUT): Add the new initializers.
|
||||
* output.h (assemble_integer): Return bool.
|
||||
(integer_asm_op): Declare.
|
||||
(default_assemble_integer): Declare.
|
||||
@ -5339,9 +5339,9 @@ Wed Nov 14 06:37:54 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
2001-11-13 Kazu Hirata <kazu@hxi.com>
|
||||
|
||||
* config/h8300/h8300.c (shift_alg_si): Use special code for
|
||||
25-bit shifts on H8/S.
|
||||
25-bit shifts on H8S.
|
||||
(get_shift_alg): Generate special code for 25-bit shifts on
|
||||
H8/S.
|
||||
H8S.
|
||||
|
||||
2001-11-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
@ -5449,10 +5449,10 @@ Tue Nov 13 05:45:40 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
2001-11-12 Kazu Hirata <kazu@hxi.com>
|
||||
|
||||
* config/h8300/h8300.c (shift_alg_qi): Use rotations when
|
||||
doing 6-bit logical shifts on H8/S.
|
||||
(shift_alg_qi): Use special code for 21-bit shifts on H8/S.
|
||||
doing 6-bit logical shifts on H8S.
|
||||
(shift_alg_qi): Use special code for 21-bit shifts on H8S.
|
||||
(get_shift_alg): Generate special code for 21-bit shifts on
|
||||
H8/S.
|
||||
H8S.
|
||||
|
||||
2001-11-12 Kazu Hirata <kazu@hxi.com>
|
||||
|
||||
@ -6891,7 +6891,7 @@ Sat Nov 3 10:37:56 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
2001-11-01 David S. Miller <davem@redhat.com>
|
||||
|
||||
* doc/install.texi (Specific, sparc-sun-solaris2*): Bring
|
||||
64-bit Sparc description more in line with reality.
|
||||
64-bit SPARC description more in line with reality.
|
||||
|
||||
2001-11-01 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
@ -9881,7 +9881,7 @@ Fri Sep 28 14:59:34 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
2001-09-27 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* dwarf2out.c (dwarf2out_frame_finish): Never elide .debug_frame
|
||||
in favour of .eh_frame.
|
||||
in favor of .eh_frame.
|
||||
|
||||
2001-09-27 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
@ -10036,7 +10036,7 @@ Tue Sep 25 17:13:56 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
(builtin_decsription): Add new field mask which is used to determine
|
||||
when to define the builtin via the macro def_builtin.
|
||||
|
||||
(bdesc_comi): Initialise new mask fields.
|
||||
(bdesc_comi): Initialize new mask fields.
|
||||
(bdesc_2srg): Likewise.
|
||||
(bdesc_1arg): Likewise.
|
||||
|
||||
@ -12374,7 +12374,7 @@ Thu Aug 30 10:21:43 2001 J"orn Rennecke <amylaar@redhat.com>
|
||||
(INIT_SECTION_ASM_OP): Define.
|
||||
(FINI_SECTION_ASM_OP): Define.
|
||||
(SUBTARGET_EXTRA_SECTIONS): Remove trailing comma.
|
||||
(RDATA_SECTION_FUNCITON): Provide prototype.
|
||||
(RDATA_SECTION_FUNCTION): Provide prototype.
|
||||
|
||||
2001-08-29 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
@ -16219,7 +16219,7 @@ Thu Jul 26 14:04:03 EDT 2001 John Wehle (john@feith.com)
|
||||
* flow.c (update_life_info): Simplify the CFG and
|
||||
recalculate the global regs which are alive when
|
||||
removing dead code during a global update.
|
||||
(propagate_block): Return non-zero if an INSN is
|
||||
(propagate_block): Return nonzero if an INSN is
|
||||
deleted.
|
||||
|
||||
2001-07-26 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
|
||||
@ -16689,7 +16689,7 @@ Sun Jul 22 21:31:04 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
(xcoff_debug_hooks, dbx_debug_hooks): Use it.
|
||||
* sdbout.c (sdbout_finish): New.
|
||||
(sdbout_debug_hooks): Use it, add comments.
|
||||
(sdbout_global_decl): Defer initialised public vars to
|
||||
(sdbout_global_decl): Defer initialized public vars to
|
||||
sdbout_finish.
|
||||
* varasm.c (assemble_variable): Don't output debug information
|
||||
for file-scope variables.
|
||||
@ -16721,7 +16721,7 @@ Sun Jul 22 21:31:04 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
(xcoff_debug_hooks, dbx_debug_hooks): Use it.
|
||||
* sdbout.c (sdbout_finish): New.
|
||||
(sdbout_debug_hooks): Use it, add comments.
|
||||
(sdbout_global_decl): Defer initialised public vars to
|
||||
(sdbout_global_decl): Defer initialized public vars to
|
||||
sdbout_finish.
|
||||
* varasm.c (assemble_variable): Don't output debug information
|
||||
for file-scope variables.
|
||||
@ -16990,7 +16990,7 @@ Fri Jul 20 13:24:16 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* Makefile.in (toplev.o, dwarfout.o, final.o): Don't depend on
|
||||
dwarfout.h.
|
||||
* dbxout.c (dbxout_function): Rename dbxout_funciton_decl, move
|
||||
* dbxout.c (dbxout_function): Rename dbxout_function_decl, move
|
||||
to conditionally compiled block.
|
||||
(dbx_debug_hooks, xcoff_debug_hooks): Update.
|
||||
* dbxout.h (dbxout_function): Remove.
|
||||
@ -18418,7 +18418,7 @@ Mon Jul 9 06:41:07 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
* config/ia64/ia64.c (ia64_output_end_prologue): Rename to
|
||||
ia64_output_function_end_prologue. Use in target struct
|
||||
and make static.
|
||||
(ia64_function_prologue, ia64_funciton_epilogue): Rename
|
||||
(ia64_function_prologue, ia64_function_epilogue): Rename
|
||||
mistyped prototypes.
|
||||
* config/ia64/ia64.h (FUNCTION_END_PROLOGUE): Delete.
|
||||
* config/m88k/m88k-protos.h (m88k_end_prologue, m88k_begin_epilogue):
|
||||
@ -19186,13 +19186,13 @@ Sun Jul 1 11:53:52 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* c-parse.in (OBJC_STRING): Kill.
|
||||
(objc_string): Decompose to [objc_string] '@' STRING.
|
||||
(reswords): Take the leading '@' off all the Objective C keywords.
|
||||
(reswords): Take the leading '@' off all the Objective-C keywords.
|
||||
(objc_rid_sans_at): Kill.
|
||||
(init_reswords): Don't initialize it.
|
||||
(yylexname): Use OBJC_IS_AT_KEYWORD and OBJC_IS_PQ_KEYWORD.
|
||||
(_yylex): Kill reconsider label. Look ahead one token after
|
||||
an '@'; if we get an identifier, check whether it's an
|
||||
Objective C @-keyword. If so, return the keyword. Otherwise,
|
||||
Objective-C @-keyword. If so, return the keyword. Otherwise,
|
||||
put back the token and return the '@' as a terminal.
|
||||
|
||||
* cpplib.c (lex_macro_node): Remove unnecessary check for
|
||||
|
21543
contrib/gcc/ChangeLog.7
Normal file
21543
contrib/gcc/ChangeLog.7
Normal file
File diff suppressed because it is too large
Load Diff
@ -5704,7 +5704,7 @@ Sun Aug 13 14:50:58 1995 Jim Wilson <wilson@chestnut.cygnus.com>
|
||||
* Makefile.in (gfloat.h): Add a - before the rm command.
|
||||
|
||||
* loop.c (find_and_verify_loops): Set dest_loop only if
|
||||
JUMP_LABEL (insn) is non-zero.
|
||||
JUMP_LABEL (insn) is nonzero.
|
||||
|
||||
Mon Jul 31 14:31:53 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
@ -6057,7 +6057,7 @@ Mon Jul 17 06:41:19 1995 Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
||||
|
||||
* xm-alpha.h (sbrk): Add declaration.
|
||||
|
||||
* convert.c (convert_to_integer): If TYPE is a enumeral type or
|
||||
* convert.c (convert_to_integer): If TYPE is an enumeral type or
|
||||
if its precision is not the same as the size of its mode,
|
||||
convert in two steps.
|
||||
|
||||
@ -8538,7 +8538,7 @@ Tue Apr 25 18:52:43 1995 Stephen R. van den Berg (berg@pool.informatik.rwth-aa
|
||||
(mark_regs_pat, straighten_stack): New functions.
|
||||
(reg_to_stack): Amend initialisation of FP_mode_reg.
|
||||
Mark FP registers mentioned in USE insns before NOTE_INSN_FUNCTION_BEG.
|
||||
(get_true_reg): Eliminate FP subreg accesses in favour of the
|
||||
(get_true_reg): Eliminate FP subreg accesses in favor of the
|
||||
actual FP register in use.
|
||||
(record_reg_life_pat): Make it work on SUBREGs as well. Make use of
|
||||
the new mark_regs_pat function. Handle USE insns if called unnested.
|
||||
@ -8552,7 +8552,7 @@ Tue Apr 25 18:52:43 1995 Stephen R. van den Berg (berg@pool.informatik.rwth-aa
|
||||
Delete the no_live_regs shortcut to save space.
|
||||
Use stackentry state to determine filled registers.
|
||||
(replace_reg): Accept COMPLEX_FLOAT as well.
|
||||
(move_for_stack_reg): Optimise away some pointer dereferencing.
|
||||
(move_for_stack_reg): Optimize away some pointer dereferencing.
|
||||
(subst_stack_regs): Make sure the stack is in the right order
|
||||
and of the right size for register passing.
|
||||
(goto_block_pat): Make sure the stack is in the right order
|
||||
@ -8841,7 +8841,7 @@ Sat Apr 15 13:26:34 1995 Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
||||
Sat Apr 15 12:11:46 1995 Brendan Kehoe <brendan@cygnus.com>
|
||||
|
||||
* alpha/alpha.c (output_epilog): Initialize fp_offset to 0, and
|
||||
make sure it's non-zero before we try to use it to restore the
|
||||
make sure it's nonzero before we try to use it to restore the
|
||||
frame pointer.
|
||||
|
||||
Fri Apr 14 19:45:05 1995 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||
|
@ -2636,7 +2636,7 @@ Wed Sep 10 11:49:20 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
EXCEPTION_SECTION, mark the start of the frame info with a
|
||||
collectable tag.
|
||||
* collect2.c (frame_tables): New list.
|
||||
(is_ctor_dtor): Recognise frame entries.
|
||||
(is_ctor_dtor): Recognize frame entries.
|
||||
(scan_prog_file): Likewise.
|
||||
(main): Pass -fno-exceptions to sub-compile. Also do collection
|
||||
if there are any frame entries.
|
||||
@ -3114,7 +3114,7 @@ Wed Aug 27 20:15:53 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
(braf_branch_p, align_length, fixup_addr_diff_vecs): Likewise.
|
||||
(addr_diff_vec_adjust, get_dest_uid, gen_far_branch): Likewise.
|
||||
(split_branches, regs_used, gen_block_redirect): Likewise.
|
||||
(from_compare): Can't compare non-zero DImode constant directly.
|
||||
(from_compare): Can't compare nonzero DImode constant directly.
|
||||
Emit special code for TARGET_SH3E floating point with code == GE.
|
||||
Force 0.0 into a register for SH3E.
|
||||
(print_operand): Add ','.
|
||||
@ -3935,7 +3935,7 @@ Mon Aug 4 08:06:48 1997 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
|
||||
integer argument of push_reload.
|
||||
|
||||
* rtlanal.c (may_trap_p): Fix unintended fall-through so divisions by
|
||||
non-zero constants are handled properly. Return 1 for FP divisions.
|
||||
nonzero constants are handled properly. Return 1 for FP divisions.
|
||||
|
||||
Mon Aug 4 06:52:20 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
@ -3948,7 +3948,7 @@ Sun Aug 3 21:57:31 1997 Jim Meyering <meyering@eng.ascend.com>
|
||||
|
||||
Sun Aug 3 21:54:51 1997 Nick Burrett <n.a.burrett@btinternet.com>
|
||||
|
||||
* cpplib.c (cpp_start_read): Recognise suffixes 'cp' and 'c++'.
|
||||
* cpplib.c (cpp_start_read): Recognize suffixes 'cp' and 'c++'.
|
||||
|
||||
Sun Aug 3 19:18:27 1997 Ralf Baechle <ralf@uni-koblenz.de>
|
||||
|
||||
@ -5105,7 +5105,7 @@ Thu Jun 19 21:18:20 1997 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
Thu Jun 19 14:55:49 1997 Brendan Kehoe <brendan@cygnus.com>
|
||||
|
||||
* toplev.c (xmalloc): Only give the fatal msg if SIZE is non-zero.
|
||||
* toplev.c (xmalloc): Only give the fatal msg if SIZE is nonzero.
|
||||
|
||||
Sun Apr 27 23:19:13 1997 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
@ -9711,7 +9711,7 @@ Sun Oct 20 20:01:09 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
||||
Fri Oct 18 13:32:13 1996 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
* rs6000.md (float conversion insns): Generate correct code
|
||||
if the bit 15 of rs6000_fpmem_offset is non-zero.
|
||||
if the bit 15 of rs6000_fpmem_offset is nonzero.
|
||||
|
||||
Thu Oct 17 23:22:03 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
@ -9814,7 +9814,7 @@ Tue Oct 15 16:52:33 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
Tue Oct 15 11:19:17 1996 Lee Iverson <leei@Canada.AI.SRI.COM>
|
||||
|
||||
* mips.h (CPP_SPEC): Restore -D_LANGUAGE_C for Objective C.
|
||||
* mips.h (CPP_SPEC): Restore -D_LANGUAGE_C for Objective-C.
|
||||
|
||||
Mon Oct 14 18:03:35 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
@ -9864,7 +9864,7 @@ Fri Oct 11 12:19:21 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
(ASM_SPEC): Rewrite to use above specs.
|
||||
(SUBTARGET_CPP{,_SIZE}_SPEC): Define.
|
||||
(CPP_SPEC): Use above specs. Don't define _LANGUAGE_C if C++ or
|
||||
Objective C.
|
||||
Objective-C.
|
||||
({,SUBTARGET_}EXTRA_SPECS): Define.
|
||||
* mips/dec-bsd.h ({CPP,ASM}_SPEC): Don't define.
|
||||
* mips/dec-osf1.h (CPP_SPEC): Don't define.
|
||||
@ -11676,7 +11676,7 @@ Thu Jul 11 17:29:33 1996 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
Thu Jul 11 10:12:50 1996 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* h8300.h (OK_FOR_U): If generating H8/S code, accept
|
||||
* h8300.h (OK_FOR_U): If generating H8S code, accept
|
||||
SYMBOL_REF and SYMBOL_REF + CONST_INT.
|
||||
|
||||
* h8300.c ({shift,rotate}_one): Emit tabs between opcode and
|
||||
@ -11684,7 +11684,7 @@ Thu Jul 11 10:12:50 1996 Jeffrey A Law (law@cygnus.com)
|
||||
(shift_two, rotate_two): Define.
|
||||
(get_shift_alg): Accept new argument "assembler2_p" for
|
||||
rotate/shift by two insns. All callers changed. Rework
|
||||
to generate more efficient code on the H8/300, H8/300H, and H8/S.
|
||||
to generate more efficient code on the H8/300, H8/300H, and H8S.
|
||||
Try to simplify somewhat.
|
||||
(emit_a_shift): Use shift-by-two insns when they're available.
|
||||
Emit tabs between opcode and operands to be consistent with
|
||||
@ -11755,31 +11755,31 @@ Mon Jul 8 18:00:33 1996 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
Mon Jul 8 16:27:33 1996 Jeffrey A. Law <law@cygnus.com>
|
||||
|
||||
* First cut at support for the H8/S.
|
||||
* h8300.c (h8300_init_once): Handle the H8/S (treat it
|
||||
* First cut at support for the H8S.
|
||||
* h8300.c (h8300_init_once): Handle the H8S (treat it
|
||||
like the H8/300H).
|
||||
(dosize, adds_subs_operand, one_insn_adds_subs_operand): Likewise.
|
||||
(output_adds_subs, const_costs, print_operand): Likewise.
|
||||
(output_simode_bld, h8300_adjust_insn_length): Likewise.
|
||||
(push_order, pop_order): Reverse.
|
||||
(function_prologue): Try to use ldm.l and stm.l insns
|
||||
on the H8/S. Minor cleanups.
|
||||
on the H8S. Minor cleanups.
|
||||
(function_epilogue): Likewise.
|
||||
(asm_file_start): Emit ".h8300s" when compiling for the H8/S.
|
||||
* h8300/h8300.h (CPP_SPEC): Handle the H8/S.
|
||||
(asm_file_start): Emit ".h8300s" when compiling for the H8S.
|
||||
* h8300/h8300.h (CPP_SPEC): Handle the H8S.
|
||||
(TARGET_H8300S): New target.
|
||||
(TARGET_SWITCHES): Add "-ms" and "-mno-s".
|
||||
(BITS_PER_WORD): Handle the H8/S (treat it like the H8/300H).
|
||||
(BITS_PER_WORD): Handle the H8S (treat it like the H8/300H).
|
||||
(UNITS_PER_WORD, POINTER_SIZE, PARM_BOUNDARY): Likewise.
|
||||
(BIGGEST_ALIGNMENT, BIGGEST_FIELD_ALIGNMENT): Likewise.
|
||||
(INITIALIZE_TRAMPOLINE, MOVE_MAX, Pmode): Likewise.
|
||||
* h8300.md: Handle H8/S just like H8/300H
|
||||
* h8300.md: Handle H8S just like H8/300H
|
||||
throughout the entire file.
|
||||
* t-h8300 (MULTILIB_OPTIONS): Build "-ms" libraries too.
|
||||
(MULTILIB_DIRNAMES): Put H8/S libraries in "h8300s" directory.
|
||||
(MULTILIB_DIRNAMES): Put H8S libraries in "h8300s" directory.
|
||||
* h8300/lib1funcs.asm: Emit ".h8300s" pseudo-op when generating
|
||||
h8300s object files. Otherwise treat the H8/S just like the H8/300H.
|
||||
* ginclude/stdarg.h: Handle the H8/S.
|
||||
h8300s object files. Otherwise treat the H8S just like the H8/300H.
|
||||
* ginclude/stdarg.h: Handle the H8S.
|
||||
* ginclude/varargs.h: Likewise.
|
||||
|
||||
Mon Jul 8 14:50:58 1996 Doug Evans <dje@cygnus.com>
|
||||
@ -14430,7 +14430,7 @@ Thu Apr 4 11:40:55 1996 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
Wed Apr 3 14:10:16 1996 Jim Wilson <wilson@chestnut.cygnus.com>
|
||||
|
||||
* expr.c (emit_push_insn): Clobber register only if it is non-zero.
|
||||
* expr.c (emit_push_insn): Clobber register only if it is nonzero.
|
||||
|
||||
Wed Apr 3 11:31:55 1996 Jeffrey A. Law <law@cygnus.com>
|
||||
|
||||
|
@ -18,7 +18,7 @@ Aug 31, 1998:
|
||||
from the input stream, and to push them back into the input stream respectively.
|
||||
The third argument is a pointer to a null terminate string which is the first
|
||||
word after #pragma. The expression supplied by HANDLE_PRAGMA should return
|
||||
non-zero if it parsed and implemented the pragma. Otherwise it should return
|
||||
nonzero if it parsed and implemented the pragma. Otherwise it should return
|
||||
zero, and leave the input stream as it was before the expression was evaluated.
|
||||
|
||||
A new back-end definable macro has been added: INSERT_ATTRIBUTES. This macro
|
||||
|
@ -1,112 +1,28 @@
|
||||
This file contains information about GCC releases up to GCC 2.8.1, and
|
||||
some information about EGCS releases. For more details of changes in
|
||||
EGCS releases, and details of changes in GCC 2.95 and more recent
|
||||
releases, see the release notes on the GCC web site and the file NEWS
|
||||
which contains the most relevant parts of those release notes in text
|
||||
form.
|
||||
a tiny bit of information on EGCS.
|
||||
|
||||
Noteworthy changes in GCC for EGCS 1.1.
|
||||
---------------------------------------
|
||||
For details of changes in EGCS releases and GCC 2.95 and later releases,
|
||||
see the release notes on the GCC web site or the file NEWS which contains
|
||||
the most relevant parts of those release notes in text form.
|
||||
|
||||
The compiler now implements global common subexpression elimination (gcse) as
|
||||
well as global constant/copy propagation. (link to gcse page).
|
||||
|
||||
More major improvements have been made to the alias analysis code. A new
|
||||
option to allow front-ends to provide alias information to the optimizers
|
||||
has also been added (-fstrict-aliasing). -fstrict-aliasing is off by default
|
||||
now, but will be enabled by default in the future. (link to alias page)
|
||||
|
||||
Major changes continue in the exception handling support. This release
|
||||
includes some changes to reduce static overhead for exception handling. It
|
||||
also includes some major changes to the setjmp/longjmp based EH mechanism to
|
||||
make it less pessimistic. And finally, major infrastructure improvements
|
||||
to the dwarf2 EH mechanism have been made to make our EH support extensible.
|
||||
|
||||
We have fixed the infamous security problems with temporary files.
|
||||
|
||||
The "regmove" optimization pass has been nearly completely rewritten. It now
|
||||
uses much more information about the target to determine profitability of
|
||||
transformations.
|
||||
|
||||
The compiler now recomputes register usage information immediately before
|
||||
register allocation. Previously such information was only not kept up to
|
||||
date after instruction combination which led to poor register allocation
|
||||
choices by our priority based register allocator.
|
||||
|
||||
The register reloading phase of the compiler has been improved to better
|
||||
optimize spill code. This primarily helps targets which generate lots of
|
||||
spills (like the x86 ports and many register poor embedded ports).
|
||||
|
||||
A few changes in the heuristics used by the register allocator and scheduler
|
||||
have been made which can significantly improve performance for certain
|
||||
applications.
|
||||
|
||||
The compiler's branch shortening algorithms have been significantly improved
|
||||
to work better on targets which align jump targets.
|
||||
Changes in GCC for EGCS (that are not listed in the web release notes)
|
||||
---------------------------------------------------------------------
|
||||
|
||||
The compiler now supports the "ADDRESSOF" optimization which can significantly
|
||||
reduce the overhead for certain inline calls (and inline calls in general).
|
||||
|
||||
The compiler now supports a code size optimization switch (-Os). When enabled
|
||||
the compiler will prefer optimizations which improve code size over those
|
||||
which improve code speed.
|
||||
|
||||
The compiler has been improved to completely eliminate library calls which
|
||||
compute constant values. This is particularly useful on machines which
|
||||
do not have integer mul/div or floating point support on-chip.
|
||||
|
||||
GCC now supports a "--help" option to print detailed help information.
|
||||
|
||||
cpplib has been greatly improved. It is probably usable for some sites now
|
||||
(major missing feature is trigraphs).
|
||||
|
||||
Memory footprint for the compiler has been significantly reduced for certain
|
||||
pathalogical cases.
|
||||
|
||||
Build time improvements for targets which support lots of sched parameters
|
||||
(alpha and mips primarily).
|
||||
|
||||
Compile time for certain programs using large constant initializers has been
|
||||
improved (affects glibc significantly).
|
||||
|
||||
Plus an incredible number of infrastructure changes, warning fixes, bugfixes
|
||||
and local optimizations.
|
||||
|
||||
Various improvements have been made to better support cross compilations. They
|
||||
are still not easy, but they are improving.
|
||||
|
||||
Target specific NEWS
|
||||
|
||||
Sparc: Now includes V8 plus and V9 support, lots of tuning for Ultrasparcs
|
||||
and uses the Haifa scheduler by default.
|
||||
|
||||
Alpha: EV6 tuned, optimized expansion of memcpy/bzero.
|
||||
|
||||
x86: Data in the static store is aligned per Intel recommendations. Jump
|
||||
targets are aligned per Intel recommendations. Improved epilogue
|
||||
sequences for Pentium chips. Backend improvements which should help
|
||||
register allocation on all x86 variants. Support for PPro conditional
|
||||
move instructions has been fixed and enabled. Random changes
|
||||
throughout the port to make generated code more Pentium friendly.
|
||||
Improved support for 64bit integer operations.
|
||||
Unixware 7, a System V Release 5 target is now supported.
|
||||
SCO OpenServer targets can support GAS. See gcc/INSTALL for details.
|
||||
|
||||
RS6000/PowerPC: Includes AIX4.3 support as well as PowerPC64 support.
|
||||
Haifa instruction scheduling is enabled by default now.
|
||||
|
||||
MIPS: Multiply/Multiply-Add support has been largely rewritten to generate
|
||||
more efficient code. Includes mips16 support.
|
||||
|
||||
M68K: Various micro-optimizations and Coldfire fixes.
|
||||
Target-specific changes:
|
||||
|
||||
M32r: Major improvements to this port.
|
||||
|
||||
Arm: Includes Thumb and super interworking support.
|
||||
|
||||
EGCS includes all gcc2 changes up to and including the June 9, 1998 snapshot.
|
||||
|
||||
|
||||
Noteworthy changes in GCC version 2.8.1
|
||||
---------------------------------------
|
||||
|
||||
|
@ -123,8 +123,19 @@ int myfunc PARAMS ((double, int *));
|
||||
|
||||
int
|
||||
myfunc (var1, var2)
|
||||
double var1;
|
||||
int *var2;
|
||||
double var1;
|
||||
int *var2;
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
This implies that if the function takes no arguments, it should be
|
||||
declared and defined as follows:
|
||||
|
||||
int myfunc PARAMS ((void));
|
||||
|
||||
int
|
||||
myfunc ()
|
||||
{
|
||||
...
|
||||
}
|
||||
@ -139,32 +150,16 @@ void cpp_ice PARAMS ((cpp_reader *, const char *msgid, ...));
|
||||
|
||||
void
|
||||
cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
|
||||
{
|
||||
#ifndef ANSI_PROTOTYPES
|
||||
cpp_reader *pfile;
|
||||
const char *msgid;
|
||||
#endif
|
||||
va_list ap;
|
||||
|
||||
VA_START (ap, msgid);
|
||||
|
||||
#ifndef ANSI_PROTOTYPES
|
||||
pfile = va_arg (ap, cpp_reader *);
|
||||
msgid = va_arg (ap, const char *);
|
||||
#endif
|
||||
{
|
||||
VA_OPEN (ap, msgid);
|
||||
VA_FIXEDARG (ap, cpp_reader *, pfile);
|
||||
VA_FIXEDARG (ap, const char *, msgid);
|
||||
|
||||
...
|
||||
va_end (ap);
|
||||
VA_CLOSE (ap);
|
||||
}
|
||||
|
||||
For the curious, here are the definitions of the above macros. See
|
||||
ansidecl.h for the definitions of the above macros and more.
|
||||
|
||||
#define PARAMS(paramlist) paramlist /* ISO C. */
|
||||
#define VPARAMS(args) args
|
||||
|
||||
#define PARAMS(paramlist) () /* K+R C. */
|
||||
#define VPARAMS(args) (va_alist) va_dcl
|
||||
See ansidecl.h for the definitions of the above macros and more.
|
||||
|
||||
One aspect of using K+R style function declarations, is you cannot
|
||||
have arguments whose types are char, short, or float, since without
|
||||
@ -305,8 +300,8 @@ long and int are not the same size.
|
||||
Second, if you write a function definition with no return type at
|
||||
all:
|
||||
|
||||
operate(a, b)
|
||||
int a, b;
|
||||
operate (a, b)
|
||||
int a, b;
|
||||
{
|
||||
...
|
||||
}
|
||||
@ -319,8 +314,8 @@ Implicit function declarations always have return type int. So if you
|
||||
correct the above definition to
|
||||
|
||||
void
|
||||
operate(a, b)
|
||||
int a, b;
|
||||
operate (a, b)
|
||||
int a, b;
|
||||
...
|
||||
|
||||
but operate() is called above its definition, you will get an error
|
||||
|
446
contrib/gcc/aclocal.m4
vendored
446
contrib/gcc/aclocal.m4
vendored
@ -306,10 +306,7 @@ procedure conftest is begin null; end conftest;
|
||||
EOF
|
||||
gcc_cv_prog_adac=no
|
||||
# Have to do ac_tool_prefix and user overrides by hand.
|
||||
user_adac=$ADAC
|
||||
user_cc=$CC
|
||||
for cand in ${ac_tool_prefix}$user_adac $user_adac \
|
||||
${ac_tool_prefix}$user_cc $user_cc \
|
||||
for cand in ${ADAC+"$ADAC"} ${CC+"$CC"} \
|
||||
${ac_tool_prefix}gcc gcc \
|
||||
${ac_tool_prefix}cc cc \
|
||||
${ac_tool_prefix}gnatgcc gnatgcc \
|
||||
@ -399,352 +396,93 @@ fi
|
||||
AC_SUBST($1)dnl
|
||||
])
|
||||
|
||||
# Check whether mmap can map an arbitrary page from /dev/zero or with
|
||||
# MAP_ANONYMOUS, without MAP_FIXED.
|
||||
AC_DEFUN([AC_FUNC_MMAP_ANYWHERE],
|
||||
[AC_CHECK_FUNCS(getpagesize)
|
||||
# The test program for the next two tests is the same except for one
|
||||
# set of ifdefs.
|
||||
changequote({{{,}}})dnl
|
||||
{{{cat >ct-mmap.inc <<'EOF'
|
||||
#include <sys/types.h>
|
||||
# mmap(2) blacklisting. Some platforms provide the mmap library routine
|
||||
# but don't support all of the features we need from it.
|
||||
AC_DEFUN([gcc_AC_FUNC_MMAP_BLACKLIST],
|
||||
[if test $ac_cv_header_sys_mman_h != yes \
|
||||
|| test $ac_cv_func_mmap != yes; then
|
||||
gcc_cv_func_mmap_file=no
|
||||
gcc_cv_func_mmap_dev_zero=no
|
||||
gcc_cv_func_mmap_anon=no
|
||||
else
|
||||
AC_CACHE_CHECK([whether read-only mmap of a plain file works],
|
||||
gcc_cv_func_mmap_file,
|
||||
[# Add a system to this blacklist if
|
||||
# mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
|
||||
# memory area containing the same data that you'd get if you applied
|
||||
# read() to the same fd. The only system known to have a problem here
|
||||
# is VMS, where text files have record structure.
|
||||
case "$host_os" in
|
||||
vms*)
|
||||
gcc_cv_func_mmap_file=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_file=yes;;
|
||||
esac])
|
||||
AC_CACHE_CHECK([whether mmap from /dev/zero works],
|
||||
gcc_cv_func_mmap_dev_zero,
|
||||
[# Add a system to this blacklist if it has mmap() but /dev/zero
|
||||
# does not exist, or if mmapping /dev/zero does not give anonymous
|
||||
# zeroed pages with both the following properties:
|
||||
# 1. If you map N consecutive pages in with one call, and then
|
||||
# unmap any subset of those pages, the pages that were not
|
||||
# explicitly unmapped remain accessible.
|
||||
# 2. If you map two adjacent blocks of memory and then unmap them
|
||||
# both at once, they must both go away.
|
||||
# Systems known to be in this category are Windows (all variants),
|
||||
# VMS, and Darwin.
|
||||
case "$host_os" in
|
||||
vms* | cygwin* | pe | mingw* | darwin*)
|
||||
gcc_cv_func_mmap_dev_zero=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_dev_zero=yes;;
|
||||
esac])
|
||||
|
||||
# Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
|
||||
AC_CACHE_CHECK([for MAP_ANON(YMOUS)], gcc_cv_decl_map_anon,
|
||||
[AC_TRY_COMPILE(
|
||||
[#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
],
|
||||
[int n = MAP_ANONYMOUS;],
|
||||
gcc_cv_decl_map_anon=yes,
|
||||
gcc_cv_decl_map_anon=no)])
|
||||
|
||||
/* This mess was copied from the GNU getpagesize.h. */
|
||||
#ifndef HAVE_GETPAGESIZE
|
||||
# ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
|
||||
/* Assume that all systems that can run configure have sys/param.h. */
|
||||
# ifndef HAVE_SYS_PARAM_H
|
||||
# define HAVE_SYS_PARAM_H 1
|
||||
# endif
|
||||
|
||||
# ifdef _SC_PAGESIZE
|
||||
# define getpagesize() sysconf(_SC_PAGESIZE)
|
||||
# else /* no _SC_PAGESIZE */
|
||||
# ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# ifdef EXEC_PAGESIZE
|
||||
# define getpagesize() EXEC_PAGESIZE
|
||||
# else /* no EXEC_PAGESIZE */
|
||||
# ifdef NBPG
|
||||
# define getpagesize() NBPG * CLSIZE
|
||||
# ifndef CLSIZE
|
||||
# define CLSIZE 1
|
||||
# endif /* no CLSIZE */
|
||||
# else /* no NBPG */
|
||||
# ifdef NBPC
|
||||
# define getpagesize() NBPC
|
||||
# else /* no NBPC */
|
||||
# ifdef PAGESIZE
|
||||
# define getpagesize() PAGESIZE
|
||||
# endif /* PAGESIZE */
|
||||
# endif /* no NBPC */
|
||||
# endif /* no NBPG */
|
||||
# endif /* no EXEC_PAGESIZE */
|
||||
# else /* no HAVE_SYS_PARAM_H */
|
||||
# define getpagesize() 8192 /* punt totally */
|
||||
# endif /* no HAVE_SYS_PARAM_H */
|
||||
# endif /* no _SC_PAGESIZE */
|
||||
|
||||
#endif /* no HAVE_GETPAGESIZE */
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
# define MAP_FAILED -1
|
||||
#endif
|
||||
|
||||
#undef perror_exit
|
||||
#define perror_exit(str, val) \
|
||||
do { perror(str); exit(val); } while (0)
|
||||
|
||||
/* Some versions of cygwin mmap require that munmap is called with the
|
||||
same parameters as mmap. GCC expects that this is not the case.
|
||||
Test for various forms of this problem. Warning - icky signal games. */
|
||||
|
||||
static sigset_t unblock_sigsegv;
|
||||
static jmp_buf r;
|
||||
static size_t pg;
|
||||
static int devzero;
|
||||
|
||||
static char *
|
||||
anonmap (size)
|
||||
size_t size;
|
||||
{
|
||||
#ifdef USE_MAP_ANON
|
||||
return (char *) mmap (0, size, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
#else
|
||||
return (char *) mmap (0, size, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE, devzero, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
sigsegv (unused)
|
||||
int unused;
|
||||
{
|
||||
sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0);
|
||||
longjmp (r, 1);
|
||||
}
|
||||
|
||||
/* Basic functionality test. */
|
||||
void
|
||||
test_0 ()
|
||||
{
|
||||
char *x = anonmap (pg);
|
||||
if (x == (char *) MAP_FAILED)
|
||||
perror_exit("test 0 mmap", 2);
|
||||
|
||||
*(int *)x += 1;
|
||||
|
||||
if (munmap(x, pg) < 0)
|
||||
perror_exit("test 0 munmap", 3);
|
||||
}
|
||||
|
||||
/* 1. If we map a 2-page region and unmap its second page, the first page
|
||||
must remain. */
|
||||
static void
|
||||
test_1 ()
|
||||
{
|
||||
char *x = anonmap (pg * 2);
|
||||
if (x == (char *)MAP_FAILED)
|
||||
perror_exit ("test 1 mmap", 4);
|
||||
|
||||
signal (SIGSEGV, sigsegv);
|
||||
if (setjmp (r))
|
||||
perror_exit ("test 1 fault", 5);
|
||||
|
||||
x[0] = 1;
|
||||
x[pg] = 1;
|
||||
|
||||
if (munmap (x + pg, pg) < 0)
|
||||
perror_exit ("test 1 munmap 1", 6);
|
||||
x[0] = 2;
|
||||
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
x[pg] = 1;
|
||||
perror_exit ("test 1 no fault", 7);
|
||||
}
|
||||
if (munmap (x, pg) < 0)
|
||||
perror_exit ("test 1 munmap 2", 8);
|
||||
}
|
||||
|
||||
/* 2. If we map a 2-page region and unmap its first page, the second
|
||||
page must remain. */
|
||||
static void
|
||||
test_2 ()
|
||||
{
|
||||
char *x = anonmap (pg * 2);
|
||||
if (x == (char *)MAP_FAILED)
|
||||
perror_exit ("test 2 mmap", 9);
|
||||
|
||||
signal (SIGSEGV, sigsegv);
|
||||
if (setjmp (r))
|
||||
perror_exit ("test 2 fault", 10);
|
||||
|
||||
x[0] = 1;
|
||||
x[pg] = 1;
|
||||
|
||||
if (munmap (x, pg) < 0)
|
||||
perror_exit ("test 2 munmap 1", 11);
|
||||
|
||||
x[pg] = 2;
|
||||
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
x[0] = 1;
|
||||
perror_exit ("test 2 no fault", 12);
|
||||
}
|
||||
|
||||
if (munmap (x+pg, pg) < 0)
|
||||
perror_exit ("test 2 munmap 2", 13);
|
||||
}
|
||||
|
||||
/* 3. If we map two adjacent 1-page regions and unmap them both with
|
||||
one munmap, both must go away.
|
||||
|
||||
Getting two adjacent 1-page regions with two mmap calls is slightly
|
||||
tricky. All OS's tested skip over already-allocated blocks; therefore
|
||||
we have been careful to unmap all allocated regions in previous tests.
|
||||
HP/UX allocates pages backward in memory. No OS has yet been observed
|
||||
to be so perverse as to leave unmapped space between consecutive calls
|
||||
to mmap. */
|
||||
|
||||
static void
|
||||
test_3 ()
|
||||
{
|
||||
char *x, *y, *z;
|
||||
|
||||
x = anonmap (pg);
|
||||
if (x == (char *)MAP_FAILED)
|
||||
perror_exit ("test 3 mmap 1", 14);
|
||||
y = anonmap (pg);
|
||||
if (y == (char *)MAP_FAILED)
|
||||
perror_exit ("test 3 mmap 2", 15);
|
||||
|
||||
if (y != x + pg)
|
||||
{
|
||||
if (y == x - pg)
|
||||
z = y, y = x, x = z;
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "test 3 nonconsecutive pages - %lx, %lx\n",
|
||||
(unsigned long)x, (unsigned long)y);
|
||||
exit (16);
|
||||
}
|
||||
}
|
||||
|
||||
signal (SIGSEGV, sigsegv);
|
||||
if (setjmp (r))
|
||||
perror_exit ("test 3 fault", 17);
|
||||
|
||||
x[0] = 1;
|
||||
y[0] = 1;
|
||||
|
||||
if (munmap (x, pg*2) < 0)
|
||||
perror_exit ("test 3 munmap", 18);
|
||||
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
x[0] = 1;
|
||||
perror_exit ("test 3 no fault 1", 19);
|
||||
}
|
||||
|
||||
signal (SIGSEGV, sigsegv);
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
y[0] = 1;
|
||||
perror_exit ("test 3 no fault 2", 20);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
sigemptyset (&unblock_sigsegv);
|
||||
sigaddset (&unblock_sigsegv, SIGSEGV);
|
||||
pg = getpagesize ();
|
||||
#ifndef USE_MAP_ANON
|
||||
devzero = open ("/dev/zero", O_RDWR);
|
||||
if (devzero < 0)
|
||||
perror_exit ("open /dev/zero", 1);
|
||||
#endif
|
||||
|
||||
test_0();
|
||||
test_1();
|
||||
test_2();
|
||||
test_3();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
EOF}}}
|
||||
changequote([,])dnl
|
||||
|
||||
AC_CACHE_CHECK(for working mmap from /dev/zero,
|
||||
ac_cv_func_mmap_dev_zero,
|
||||
[AC_TRY_RUN(
|
||||
[#include "ct-mmap.inc"],
|
||||
ac_cv_func_mmap_dev_zero=yes,
|
||||
[if test $? -lt 4
|
||||
then ac_cv_func_mmap_dev_zero=no
|
||||
else ac_cv_func_mmap_dev_zero=buggy
|
||||
fi],
|
||||
# If this is not cygwin, and /dev/zero is a character device, it's probably
|
||||
# safe to assume it works.
|
||||
[case "$host_os" in
|
||||
cygwin* | win32 | pe | mingw* ) ac_cv_func_mmap_dev_zero=buggy ;;
|
||||
* ) if test -c /dev/zero
|
||||
then ac_cv_func_mmap_dev_zero=yes
|
||||
else ac_cv_func_mmap_dev_zero=no
|
||||
fi ;;
|
||||
esac])
|
||||
])
|
||||
if test $ac_cv_func_mmap_dev_zero = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
|
||||
[Define if mmap can get us zeroed pages from /dev/zero.])
|
||||
if test $gcc_cv_decl_map_anon = no; then
|
||||
gcc_cv_func_mmap_anon=no
|
||||
else
|
||||
AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
|
||||
gcc_cv_func_mmap_anon,
|
||||
[# Add a system to this blacklist if it has mmap() and MAP_ANON or
|
||||
# MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
||||
# doesn't give anonymous zeroed pages with the same properties listed
|
||||
# above for use of /dev/zero.
|
||||
# Systems known to be in this category are Windows, VMS, and SCO Unix.
|
||||
case "$host_os" in
|
||||
vms* | cygwin* | pe | mingw* | sco* | udk* )
|
||||
gcc_cv_func_mmap_anon=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_anon=yes;;
|
||||
esac])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for working mmap with MAP_ANON(YMOUS)],
|
||||
ac_cv_func_mmap_anon,
|
||||
[AC_TRY_RUN(
|
||||
[#define USE_MAP_ANON
|
||||
#include "ct-mmap.inc"],
|
||||
ac_cv_func_mmap_anon=yes,
|
||||
[if test $? -lt 4
|
||||
then ac_cv_func_mmap_anon=no
|
||||
else ac_cv_func_mmap_anon=buggy
|
||||
fi],
|
||||
# Unlike /dev/zero, it is not safe to assume MAP_ANON(YMOUS) works
|
||||
# just because it's there. Some SCO Un*xen define it but don't implement it.
|
||||
ac_cv_func_mmap_anon=no)
|
||||
])
|
||||
if test $ac_cv_func_mmap_anon = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_ANON, 1,
|
||||
[Define if mmap can get us zeroed pages using MAP_ANON(YMOUS).])
|
||||
fi
|
||||
rm -f ct-mmap.inc
|
||||
])
|
||||
|
||||
# Check whether mmap can map a plain file, without MAP_FIXED.
|
||||
AC_DEFUN([AC_FUNC_MMAP_FILE],
|
||||
[AC_CACHE_CHECK(for working mmap of a file, ac_cv_func_mmap_file,
|
||||
[# Create a file one thousand bytes long.
|
||||
for i in 1 2 3 4 5 6 7 8 9 0
|
||||
do for j in 1 2 3 4 5 6 7 8 9 0
|
||||
do echo $i $j xxxxx
|
||||
done
|
||||
done > conftestdata$$
|
||||
|
||||
AC_TRY_RUN([
|
||||
/* Test by Zack Weinberg. Modified from MMAP_ANYWHERE test by
|
||||
Richard Henderson and Alexandre Oliva.
|
||||
Check whether read-only mmap of a plain file works. */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char *x;
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
fd = open("conftestdata$$", O_RDONLY);
|
||||
if (fd < 0)
|
||||
exit(1);
|
||||
|
||||
if (fstat (fd, &st))
|
||||
exit(2);
|
||||
|
||||
x = (char*)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (x == (char *) -1)
|
||||
exit(3);
|
||||
|
||||
if (x[0] != '1' || x[1] != ' ' || x[2] != '1' || x[3] != ' ')
|
||||
exit(4);
|
||||
|
||||
if (munmap(x, st.st_size) < 0)
|
||||
exit(5);
|
||||
|
||||
exit(0);
|
||||
}], ac_cv_func_mmap_file=yes, ac_cv_func_mmap_file=no,
|
||||
ac_cv_func_mmap_file=no)])
|
||||
if test $ac_cv_func_mmap_file = yes; then
|
||||
if test $gcc_cv_func_mmap_file = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_FILE, 1,
|
||||
[Define if read-only mmap of a plain file works.])
|
||||
fi
|
||||
if test $gcc_cv_func_mmap_dev_zero = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
|
||||
[Define if mmap of /dev/zero works.])
|
||||
fi
|
||||
if test $gcc_cv_func_mmap_anon = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_ANON, 1,
|
||||
[Define if mmap with MAP_ANON(YMOUS) works.])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Locate a program and check that its version is acceptable.
|
||||
@ -1690,3 +1428,29 @@ strdup strtoul tsearch __argz_count __argz_stringify __argz_next])
|
||||
INTL_LIBTOOL_SUFFIX_PREFIX=ifelse([$1], use-libtool, [l], [])
|
||||
AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX)
|
||||
])
|
||||
|
||||
AC_DEFUN(gcc_AC_INITFINI_ARRAY,
|
||||
[AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
|
||||
gcc_cv_initfinit_array, [dnl
|
||||
cat > conftest.c <<EOF
|
||||
static int x = -1;
|
||||
int main (void) { return x; }
|
||||
int foo (void) { x = 0; }
|
||||
int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
|
||||
EOF
|
||||
if AC_TRY_COMMAND([${CC-cc} -o conftest conftest.c 1>&AS_MESSAGE_LOG_FD])
|
||||
then
|
||||
if ./conftest; then
|
||||
gcc_cv_initfinit_array=yes
|
||||
else
|
||||
gcc_cv_initfinit_array=no
|
||||
fi
|
||||
else
|
||||
gcc_cv_initfinit_array=no
|
||||
fi
|
||||
rm -f conftest*])
|
||||
AC_SUBST(gcc_cv_initfinit_array)
|
||||
if test $gcc_cv_initfinit_array = yes; then
|
||||
AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
|
||||
[Define .init_array/.fini_array sections are available and working.])
|
||||
fi])
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Alias analysis for GNU C
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by John Carr (jfc@mit.edu).
|
||||
|
||||
This file is part of GCC.
|
||||
@ -36,6 +37,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "splay-tree.h"
|
||||
#include "ggc.h"
|
||||
#include "langhooks.h"
|
||||
#include "target.h"
|
||||
|
||||
/* The alias sets assigned to MEMs assist the back-end in determining
|
||||
which MEMs can alias which other MEMs. In general, two MEMs in
|
||||
@ -75,7 +77,7 @@ typedef struct alias_set_entry
|
||||
/* The children of the alias set. These are not just the immediate
|
||||
children, but, in fact, all descendents. So, if we have:
|
||||
|
||||
struct T { struct S s; float f; }
|
||||
struct T { struct S s; float f; }
|
||||
|
||||
continuing our example above, the children here will be all of
|
||||
`int', `double', `float', and `struct S'. */
|
||||
@ -108,7 +110,13 @@ static tree decl_for_component_ref PARAMS ((tree));
|
||||
static rtx adjust_offset_for_component_ref PARAMS ((tree, rtx));
|
||||
static int nonoverlapping_memrefs_p PARAMS ((rtx, rtx));
|
||||
static int write_dependence_p PARAMS ((rtx, rtx, int));
|
||||
|
||||
static int nonlocal_mentioned_p_1 PARAMS ((rtx *, void *));
|
||||
static int nonlocal_mentioned_p PARAMS ((rtx));
|
||||
static int nonlocal_referenced_p_1 PARAMS ((rtx *, void *));
|
||||
static int nonlocal_referenced_p PARAMS ((rtx));
|
||||
static int nonlocal_set_p_1 PARAMS ((rtx *, void *));
|
||||
static int nonlocal_set_p PARAMS ((rtx));
|
||||
|
||||
/* Set up all info needed to perform alias analysis on memory references. */
|
||||
|
||||
@ -125,7 +133,7 @@ static int nonlocal_mentioned_p PARAMS ((rtx));
|
||||
/* Cap the number of passes we make over the insns propagating alias
|
||||
information through set chains. 10 is a completely arbitrary choice. */
|
||||
#define MAX_ALIAS_LOOP_PASSES 10
|
||||
|
||||
|
||||
/* reg_base_value[N] gives an address to which register N is related.
|
||||
If all sets after the first add or subtract to the current value
|
||||
or otherwise modify it so it does not point to a different top level
|
||||
@ -134,7 +142,7 @@ static int nonlocal_mentioned_p PARAMS ((rtx));
|
||||
|
||||
A base address can be an ADDRESS, SYMBOL_REF, or LABEL_REF. ADDRESS
|
||||
expressions represent certain special values: function arguments and
|
||||
the stack, frame, and argument pointers.
|
||||
the stack, frame, and argument pointers.
|
||||
|
||||
The contents of an ADDRESS is not normally used, the mode of the
|
||||
ADDRESS determines whether the ADDRESS is a function argument or some
|
||||
@ -145,10 +153,14 @@ static int nonlocal_mentioned_p PARAMS ((rtx));
|
||||
current function performs nonlocal memory memory references for the
|
||||
purposes of marking the function as a constant function. */
|
||||
|
||||
static rtx *reg_base_value;
|
||||
static GTY((length ("reg_base_value_size"))) rtx *reg_base_value;
|
||||
static rtx *new_reg_base_value;
|
||||
static unsigned int reg_base_value_size; /* size of reg_base_value array */
|
||||
|
||||
/* Static hunks of RTL used by the aliasing code; these are initialized
|
||||
once per function to avoid unnecessary RTL allocations. */
|
||||
static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
#define REG_BASE_VALUE(X) \
|
||||
(REGNO (X) < reg_base_value_size \
|
||||
? reg_base_value[REGNO (X)] : 0)
|
||||
@ -188,7 +200,7 @@ char *reg_known_equiv_p;
|
||||
|
||||
/* True when scanning insns from the start of the rtl to the
|
||||
NOTE_INSN_FUNCTION_BEG note. */
|
||||
static int copying_arguments;
|
||||
static bool copying_arguments;
|
||||
|
||||
/* The splay-tree used to store the various alias set entries. */
|
||||
static splay_tree alias_sets;
|
||||
@ -209,12 +221,12 @@ get_alias_set_entry (alias_set)
|
||||
/* Returns nonzero if the alias sets for MEM1 and MEM2 are such that
|
||||
the two MEMs cannot alias each other. */
|
||||
|
||||
static int
|
||||
static int
|
||||
mems_in_disjoint_alias_sets_p (mem1, mem2)
|
||||
rtx mem1;
|
||||
rtx mem2;
|
||||
{
|
||||
#ifdef ENABLE_CHECKING
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* Perform a basic sanity check. Namely, that there are no alias sets
|
||||
if we're not using strict aliasing. This helps to catch bugs
|
||||
whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or
|
||||
@ -311,6 +323,8 @@ int
|
||||
objects_must_conflict_p (t1, t2)
|
||||
tree t1, t2;
|
||||
{
|
||||
HOST_WIDE_INT set1, set2;
|
||||
|
||||
/* If neither has a type specified, we don't know if they'll conflict
|
||||
because we may be using them to store objects of various types, for
|
||||
example the argument and local variables areas of inlined functions. */
|
||||
@ -331,15 +345,15 @@ objects_must_conflict_p (t1, t2)
|
||||
|| (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)))
|
||||
return 1;
|
||||
|
||||
/* If one is aggregate and the other is scalar then they may not
|
||||
conflict. */
|
||||
if ((t1 != 0 && AGGREGATE_TYPE_P (t1))
|
||||
!= (t2 != 0 && AGGREGATE_TYPE_P (t2)))
|
||||
return 0;
|
||||
set1 = t1 ? get_alias_set (t1) : 0;
|
||||
set2 = t2 ? get_alias_set (t2) : 0;
|
||||
|
||||
/* Otherwise they conflict only if the alias sets conflict. */
|
||||
return alias_sets_conflict_p (t1 ? get_alias_set (t1) : 0,
|
||||
t2 ? get_alias_set (t2) : 0);
|
||||
/* Otherwise they conflict if they have no alias set or the same. We
|
||||
can't simply use alias_sets_conflict_p here, because we must make
|
||||
sure that every subtype of t1 will conflict with every subtype of
|
||||
t2 for which a pair of subobjects of these respective subtypes
|
||||
overlaps on the stack. */
|
||||
return set1 == 0 || set2 == 0 || set1 == set2;
|
||||
}
|
||||
|
||||
/* T is an expression with pointer type. Find the DECL on which this
|
||||
@ -508,8 +522,8 @@ get_alias_set (t)
|
||||
else
|
||||
{
|
||||
DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
|
||||
record_alias_subset (pointed_to_alias_set,
|
||||
DECL_POINTER_ALIAS_SET (decl));
|
||||
record_alias_subset (pointed_to_alias_set,
|
||||
DECL_POINTER_ALIAS_SET (decl));
|
||||
}
|
||||
}
|
||||
|
||||
@ -603,7 +617,7 @@ new_alias_set ()
|
||||
not vice versa. For example, in C, a store to an `int' can alias a
|
||||
structure containing an `int', but not vice versa. Here, the
|
||||
structure would be the SUPERSET and `int' the SUBSET. This
|
||||
function should be called only once per SUPERSET/SUBSET pair.
|
||||
function should be called only once per SUPERSET/SUBSET pair.
|
||||
|
||||
It is illegal for SUPERSET to be zero; everything is implicitly a
|
||||
subset of alias set zero. */
|
||||
@ -625,14 +639,14 @@ record_alias_subset (superset, subset)
|
||||
abort ();
|
||||
|
||||
superset_entry = get_alias_set_entry (superset);
|
||||
if (superset_entry == 0)
|
||||
if (superset_entry == 0)
|
||||
{
|
||||
/* Create an entry for the SUPERSET, so that we have a place to
|
||||
attach the SUBSET. */
|
||||
superset_entry
|
||||
= (alias_set_entry) xmalloc (sizeof (struct alias_set_entry));
|
||||
superset_entry->alias_set = superset;
|
||||
superset_entry->children
|
||||
superset_entry->children
|
||||
= splay_tree_new (splay_tree_compare_ints, 0, 0);
|
||||
superset_entry->has_zero_child = 0;
|
||||
splay_tree_insert (alias_sets, (splay_tree_key) superset,
|
||||
@ -646,7 +660,7 @@ record_alias_subset (superset, subset)
|
||||
subset_entry = get_alias_set_entry (subset);
|
||||
/* If there is an entry for the subset, enter all of its children
|
||||
(if they are not already present) as children of the SUPERSET. */
|
||||
if (subset_entry)
|
||||
if (subset_entry)
|
||||
{
|
||||
if (subset_entry->has_zero_child)
|
||||
superset_entry->has_zero_child = 1;
|
||||
@ -656,7 +670,7 @@ record_alias_subset (superset, subset)
|
||||
}
|
||||
|
||||
/* Enter the SUBSET itself as a child of the SUPERSET. */
|
||||
splay_tree_insert (superset_entry->children,
|
||||
splay_tree_insert (superset_entry->children,
|
||||
(splay_tree_key) subset, 0);
|
||||
}
|
||||
}
|
||||
@ -687,6 +701,17 @@ record_component_aliases (type)
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
case QUAL_UNION_TYPE:
|
||||
/* Recursively record aliases for the base classes, if there are any */
|
||||
if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); i++)
|
||||
{
|
||||
tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
|
||||
record_alias_subset (superset,
|
||||
get_alias_set (BINFO_TYPE (binfo)));
|
||||
}
|
||||
}
|
||||
for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
|
||||
if (TREE_CODE (field) == FIELD_DECL && ! DECL_NONADDRESSABLE_P (field))
|
||||
record_alias_subset (superset, get_alias_set (TREE_TYPE (field)));
|
||||
@ -759,9 +784,17 @@ find_base_value (src)
|
||||
The test above is not sufficient because the scheduler may move
|
||||
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
|
||||
if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
|
||||
&& regno < reg_base_value_size
|
||||
&& reg_base_value[regno])
|
||||
return reg_base_value[regno];
|
||||
&& regno < reg_base_value_size)
|
||||
{
|
||||
/* If we're inside init_alias_analysis, use new_reg_base_value
|
||||
to reduce the number of relaxation iterations. */
|
||||
if (new_reg_base_value && new_reg_base_value[regno]
|
||||
&& REG_N_SETS (regno) == 1)
|
||||
return new_reg_base_value[regno];
|
||||
|
||||
if (reg_base_value[regno])
|
||||
return reg_base_value[regno];
|
||||
}
|
||||
|
||||
return src;
|
||||
|
||||
@ -1111,7 +1144,7 @@ rtx_equal_for_memref_p (x, y)
|
||||
|
||||
case LABEL_REF:
|
||||
return XEXP (x, 0) == XEXP (y, 0);
|
||||
|
||||
|
||||
case SYMBOL_REF:
|
||||
return XSTR (x, 0) == XSTR (y, 0);
|
||||
|
||||
@ -1248,7 +1281,7 @@ find_base_term (x)
|
||||
|
||||
case TRUNCATE:
|
||||
if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
|
||||
return 0;
|
||||
return 0;
|
||||
/* Fall through. */
|
||||
case HIGH:
|
||||
case PRE_INC:
|
||||
@ -1302,7 +1335,7 @@ find_base_term (x)
|
||||
tests can certainly be added. For example, if one of the operands
|
||||
is a shift or multiply, then it must be the index register and the
|
||||
other operand is the base register. */
|
||||
|
||||
|
||||
if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2))
|
||||
return find_base_term (tmp2);
|
||||
|
||||
@ -1400,7 +1433,7 @@ base_alias_check (x, y, x_mode, y_mode)
|
||||
if (rtx_equal_p (x_base, y_base))
|
||||
return 1;
|
||||
|
||||
/* The base addresses of the read and write are different expressions.
|
||||
/* The base addresses of the read and write are different expressions.
|
||||
If they are both symbols and they are not accessed via AND, there is
|
||||
no conflict. We can bring knowledge of object alignment into play
|
||||
here. For example, on alpha, "char a, b;" can alias one another,
|
||||
@ -1475,7 +1508,7 @@ addr_side_effect_eval (addr, size, n_refs)
|
||||
int n_refs;
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
|
||||
switch (GET_CODE (addr))
|
||||
{
|
||||
case PRE_INC:
|
||||
@ -1494,7 +1527,7 @@ addr_side_effect_eval (addr, size, n_refs)
|
||||
default:
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
if (offset)
|
||||
addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0), GEN_INT (offset));
|
||||
else
|
||||
@ -1657,7 +1690,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
|
||||
}
|
||||
|
||||
/* Treat an access through an AND (e.g. a subword access on an Alpha)
|
||||
as an access with indeterminate size. Assume that references
|
||||
as an access with indeterminate size. Assume that references
|
||||
besides AND are aligned, so if the size of the other reference is
|
||||
at least as large as the alignment, assume no other overlap. */
|
||||
if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
@ -1669,7 +1702,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
|
||||
if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
|
||||
{
|
||||
/* ??? If we are indexing far enough into the array/structure, we
|
||||
may yet be able to determine that we can not overlap. But we
|
||||
may yet be able to determine that we can not overlap. But we
|
||||
also need to that we are far enough from the end not to overlap
|
||||
a following reference, so we do nothing with that for now. */
|
||||
if (GET_CODE (x) == AND || xsize < -INTVAL (XEXP (y, 1)))
|
||||
@ -1731,7 +1764,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
|
||||
If both memory references are volatile, then there must always be a
|
||||
dependence between the two references, since their order can not be
|
||||
changed. A volatile and non-volatile reference can be interchanged
|
||||
though.
|
||||
though.
|
||||
|
||||
A MEM_IN_STRUCT reference at a non-AND varying address can never
|
||||
conflict with a non-MEM_IN_STRUCT reference at a fixed address. We
|
||||
@ -1758,23 +1791,23 @@ read_dependence (mem, x)
|
||||
to decide whether or not an address may vary; it should return
|
||||
nonzero whenever variation is possible.
|
||||
MEM1_ADDR and MEM2_ADDR are the addresses of MEM1 and MEM2. */
|
||||
|
||||
|
||||
static rtx
|
||||
fixed_scalar_and_varying_struct_p (mem1, mem2, mem1_addr, mem2_addr, varies_p)
|
||||
rtx mem1, mem2;
|
||||
rtx mem1_addr, mem2_addr;
|
||||
int (*varies_p) PARAMS ((rtx, int));
|
||||
{
|
||||
{
|
||||
if (! flag_strict_aliasing)
|
||||
return NULL_RTX;
|
||||
|
||||
if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
|
||||
if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
|
||||
&& !varies_p (mem1_addr, 1) && varies_p (mem2_addr, 1))
|
||||
/* MEM1 is a scalar at a fixed address; MEM2 is a struct at a
|
||||
varying address. */
|
||||
return mem1;
|
||||
|
||||
if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2)
|
||||
if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2)
|
||||
&& varies_p (mem1_addr, 1) && !varies_p (mem2_addr, 1))
|
||||
/* MEM2 is a scalar at a fixed address; MEM1 is a struct at a
|
||||
varying address. */
|
||||
@ -1794,7 +1827,7 @@ aliases_everything_p (mem)
|
||||
/* If the address is an AND, its very hard to know at what it is
|
||||
actually pointing. */
|
||||
return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1852,7 +1885,7 @@ nonoverlapping_component_refs_p (x, y)
|
||||
while (x && y
|
||||
&& TREE_CODE (x) == COMPONENT_REF
|
||||
&& TREE_CODE (y) == COMPONENT_REF);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1885,7 +1918,7 @@ adjust_offset_for_component_ref (x, offset)
|
||||
return NULL_RTX;
|
||||
|
||||
ioffset = INTVAL (offset);
|
||||
do
|
||||
do
|
||||
{
|
||||
tree field = TREE_OPERAND (x, 1);
|
||||
|
||||
@ -1986,15 +2019,15 @@ nonoverlapping_memrefs_p (x, y)
|
||||
offsety = INTVAL (XEXP (basey, 1)), basey = XEXP (basey, 0);
|
||||
|
||||
/* If the bases are different, we know they do not overlap if both
|
||||
are constants or if one is a constant and the other a pointer into the
|
||||
are constants or if one is a constant and the other a pointer into the
|
||||
stack frame. Otherwise a different base means we can't tell if they
|
||||
overlap or not. */
|
||||
if (! rtx_equal_p (basex, basey))
|
||||
return ((CONSTANT_P (basex) && CONSTANT_P (basey))
|
||||
|| (CONSTANT_P (basex) && REG_P (basey)
|
||||
&& REGNO_PTR_FRAME_P (REGNO (basey)))
|
||||
|| (CONSTANT_P (basey) && REG_P (basex)
|
||||
&& REGNO_PTR_FRAME_P (REGNO (basex))));
|
||||
return ((CONSTANT_P (basex) && CONSTANT_P (basey))
|
||||
|| (CONSTANT_P (basex) && REG_P (basey)
|
||||
&& REGNO_PTR_FRAME_P (REGNO (basey)))
|
||||
|| (CONSTANT_P (basey) && REG_P (basex)
|
||||
&& REGNO_PTR_FRAME_P (REGNO (basex))));
|
||||
|
||||
sizex = (GET_CODE (rtlx) != MEM ? (int) GET_MODE_SIZE (GET_MODE (rtlx))
|
||||
: MEM_SIZE (rtlx) ? INTVAL (MEM_SIZE (rtlx))
|
||||
@ -2111,9 +2144,9 @@ true_dependence (mem, mem_mode, x, varies)
|
||||
}
|
||||
|
||||
/* Canonical true dependence: X is read after store in MEM takes place.
|
||||
Variant of true_dependence which assumes MEM has already been
|
||||
canonicalized (hence we no longer do that here).
|
||||
The mem_addr argument has been added, since true_dependence computed
|
||||
Variant of true_dependence which assumes MEM has already been
|
||||
canonicalized (hence we no longer do that here).
|
||||
The mem_addr argument has been added, since true_dependence computed
|
||||
this value prior to canonicalizing. */
|
||||
|
||||
int
|
||||
@ -2177,8 +2210,8 @@ canon_true_dependence (mem, mem_mode, mem_addr, x, varies)
|
||||
varies);
|
||||
}
|
||||
|
||||
/* Returns non-zero if a write to X might alias a previous read from
|
||||
(or, if WRITEP is non-zero, a write to) MEM. */
|
||||
/* Returns nonzero if a write to X might alias a previous read from
|
||||
(or, if WRITEP is nonzero, a write to) MEM. */
|
||||
|
||||
static int
|
||||
write_dependence_p (mem, x, writep)
|
||||
@ -2239,7 +2272,7 @@ write_dependence_p (mem, x, writep)
|
||||
SIZE_FOR_MODE (x), x_addr, 0))
|
||||
return 0;
|
||||
|
||||
fixed_scalar
|
||||
fixed_scalar
|
||||
= fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
|
||||
rtx_addr_varies_p);
|
||||
|
||||
@ -2266,36 +2299,23 @@ output_dependence (mem, x)
|
||||
{
|
||||
return write_dependence_p (mem, x, /*writep=*/1);
|
||||
}
|
||||
|
||||
/* Returns non-zero if X mentions something which is not
|
||||
local to the function and is not constant. */
|
||||
|
||||
/* A subroutine of nonlocal_mentioned_p, returns 1 if *LOC mentions
|
||||
something which is not local to the function and is not constant. */
|
||||
|
||||
static int
|
||||
nonlocal_mentioned_p (x)
|
||||
rtx x;
|
||||
nonlocal_mentioned_p_1 (loc, data)
|
||||
rtx *loc;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
rtx x = *loc;
|
||||
rtx base;
|
||||
RTX_CODE code;
|
||||
int regno;
|
||||
|
||||
code = GET_CODE (x);
|
||||
if (! x)
|
||||
return 0;
|
||||
|
||||
if (GET_RTX_CLASS (code) == 'i')
|
||||
{
|
||||
/* Constant functions can be constant if they don't use
|
||||
scratch memory used to mark function w/o side effects. */
|
||||
if (code == CALL_INSN && CONST_OR_PURE_CALL_P (x))
|
||||
{
|
||||
x = CALL_INSN_FUNCTION_USAGE (x);
|
||||
if (x == 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
x = PATTERN (x);
|
||||
code = GET_CODE (x);
|
||||
}
|
||||
|
||||
switch (code)
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case SUBREG:
|
||||
if (GET_CODE (SUBREG_REG (x)) == REG)
|
||||
@ -2377,74 +2397,263 @@ nonlocal_mentioned_p (x)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Recursively scan the operands of this expression. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
const char *fmt = GET_RTX_FORMAT (code);
|
||||
int i;
|
||||
|
||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
{
|
||||
if (fmt[i] == 'e' && XEXP (x, i))
|
||||
{
|
||||
if (nonlocal_mentioned_p (XEXP (x, i)))
|
||||
return 1;
|
||||
}
|
||||
else if (fmt[i] == 'E')
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < XVECLEN (x, i); j++)
|
||||
if (nonlocal_mentioned_p (XVECEXP (x, i, j)))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Returns nonzero if X might mention something which is not
|
||||
local to the function and is not constant. */
|
||||
|
||||
static int
|
||||
nonlocal_mentioned_p (x)
|
||||
rtx x;
|
||||
{
|
||||
|
||||
if (INSN_P (x))
|
||||
{
|
||||
if (GET_CODE (x) == CALL_INSN)
|
||||
{
|
||||
if (! CONST_OR_PURE_CALL_P (x))
|
||||
return 1;
|
||||
x = CALL_INSN_FUNCTION_USAGE (x);
|
||||
if (x == 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
x = PATTERN (x);
|
||||
}
|
||||
|
||||
return for_each_rtx (&x, nonlocal_mentioned_p_1, NULL);
|
||||
}
|
||||
|
||||
/* A subroutine of nonlocal_referenced_p, returns 1 if *LOC references
|
||||
something which is not local to the function and is not constant. */
|
||||
|
||||
static int
|
||||
nonlocal_referenced_p_1 (loc, data)
|
||||
rtx *loc;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
rtx x = *loc;
|
||||
|
||||
if (! x)
|
||||
return 0;
|
||||
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case MEM:
|
||||
case REG:
|
||||
case SYMBOL_REF:
|
||||
case SUBREG:
|
||||
return nonlocal_mentioned_p (x);
|
||||
|
||||
case CALL:
|
||||
/* Non-constant calls and recursion are not local. */
|
||||
return 1;
|
||||
|
||||
case SET:
|
||||
if (nonlocal_mentioned_p (SET_SRC (x)))
|
||||
return 1;
|
||||
|
||||
if (GET_CODE (SET_DEST (x)) == MEM)
|
||||
return nonlocal_mentioned_p (XEXP (SET_DEST (x), 0));
|
||||
|
||||
/* If the destination is anything other than a CC0, PC,
|
||||
MEM, REG, or a SUBREG of a REG that occupies all of
|
||||
the REG, then X references nonlocal memory if it is
|
||||
mentioned in the destination. */
|
||||
if (GET_CODE (SET_DEST (x)) != CC0
|
||||
&& GET_CODE (SET_DEST (x)) != PC
|
||||
&& GET_CODE (SET_DEST (x)) != REG
|
||||
&& ! (GET_CODE (SET_DEST (x)) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
|
||||
&& (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
|
||||
+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
|
||||
== ((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
|
||||
+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
|
||||
return nonlocal_mentioned_p (SET_DEST (x));
|
||||
return 0;
|
||||
|
||||
case CLOBBER:
|
||||
if (GET_CODE (XEXP (x, 0)) == MEM)
|
||||
return nonlocal_mentioned_p (XEXP (XEXP (x, 0), 0));
|
||||
return 0;
|
||||
|
||||
case USE:
|
||||
return nonlocal_mentioned_p (XEXP (x, 0));
|
||||
|
||||
case ASM_INPUT:
|
||||
case UNSPEC_VOLATILE:
|
||||
return 1;
|
||||
|
||||
case ASM_OPERANDS:
|
||||
if (MEM_VOLATILE_P (x))
|
||||
return 1;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns nonzero if X might reference something which is not
|
||||
local to the function and is not constant. */
|
||||
|
||||
static int
|
||||
nonlocal_referenced_p (x)
|
||||
rtx x;
|
||||
{
|
||||
|
||||
if (INSN_P (x))
|
||||
{
|
||||
if (GET_CODE (x) == CALL_INSN)
|
||||
{
|
||||
if (! CONST_OR_PURE_CALL_P (x))
|
||||
return 1;
|
||||
x = CALL_INSN_FUNCTION_USAGE (x);
|
||||
if (x == 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
x = PATTERN (x);
|
||||
}
|
||||
|
||||
return for_each_rtx (&x, nonlocal_referenced_p_1, NULL);
|
||||
}
|
||||
|
||||
/* A subroutine of nonlocal_set_p, returns 1 if *LOC sets
|
||||
something which is not local to the function and is not constant. */
|
||||
|
||||
static int
|
||||
nonlocal_set_p_1 (loc, data)
|
||||
rtx *loc;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
rtx x = *loc;
|
||||
|
||||
if (! x)
|
||||
return 0;
|
||||
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case CALL:
|
||||
/* Non-constant calls and recursion are not local. */
|
||||
return 1;
|
||||
|
||||
case PRE_INC:
|
||||
case PRE_DEC:
|
||||
case POST_INC:
|
||||
case POST_DEC:
|
||||
case PRE_MODIFY:
|
||||
case POST_MODIFY:
|
||||
return nonlocal_mentioned_p (XEXP (x, 0));
|
||||
|
||||
case SET:
|
||||
if (nonlocal_mentioned_p (SET_DEST (x)))
|
||||
return 1;
|
||||
return nonlocal_set_p (SET_SRC (x));
|
||||
|
||||
case CLOBBER:
|
||||
return nonlocal_mentioned_p (XEXP (x, 0));
|
||||
|
||||
case USE:
|
||||
return 0;
|
||||
|
||||
case ASM_INPUT:
|
||||
case UNSPEC_VOLATILE:
|
||||
return 1;
|
||||
|
||||
case ASM_OPERANDS:
|
||||
if (MEM_VOLATILE_P (x))
|
||||
return 1;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns nonzero if X might set something which is not
|
||||
local to the function and is not constant. */
|
||||
|
||||
static int
|
||||
nonlocal_set_p (x)
|
||||
rtx x;
|
||||
{
|
||||
|
||||
if (INSN_P (x))
|
||||
{
|
||||
if (GET_CODE (x) == CALL_INSN)
|
||||
{
|
||||
if (! CONST_OR_PURE_CALL_P (x))
|
||||
return 1;
|
||||
x = CALL_INSN_FUNCTION_USAGE (x);
|
||||
if (x == 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
x = PATTERN (x);
|
||||
}
|
||||
|
||||
return for_each_rtx (&x, nonlocal_set_p_1, NULL);
|
||||
}
|
||||
|
||||
/* Mark the function if it is constant. */
|
||||
|
||||
void
|
||||
mark_constant_function ()
|
||||
{
|
||||
rtx insn;
|
||||
int nonlocal_mentioned;
|
||||
int nonlocal_memory_referenced;
|
||||
|
||||
if (TREE_PUBLIC (current_function_decl)
|
||||
|| TREE_READONLY (current_function_decl)
|
||||
if (TREE_READONLY (current_function_decl)
|
||||
|| DECL_IS_PURE (current_function_decl)
|
||||
|| TREE_THIS_VOLATILE (current_function_decl)
|
||||
|| TYPE_MODE (TREE_TYPE (current_function_decl)) == VOIDmode)
|
||||
|| TYPE_MODE (TREE_TYPE (current_function_decl)) == VOIDmode
|
||||
|| current_function_has_nonlocal_goto
|
||||
|| !(*targetm.binds_local_p) (current_function_decl))
|
||||
return;
|
||||
|
||||
/* A loop might not return which counts as a side effect. */
|
||||
if (mark_dfs_back_edges ())
|
||||
return;
|
||||
|
||||
nonlocal_mentioned = 0;
|
||||
nonlocal_memory_referenced = 0;
|
||||
|
||||
init_alias_analysis ();
|
||||
|
||||
/* Determine if this is a constant function. */
|
||||
/* Determine if this is a constant or pure function. */
|
||||
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||
if (INSN_P (insn) && nonlocal_mentioned_p (insn))
|
||||
{
|
||||
nonlocal_mentioned = 1;
|
||||
{
|
||||
if (! INSN_P (insn))
|
||||
continue;
|
||||
|
||||
if (nonlocal_set_p (insn) || global_reg_mentioned_p (insn)
|
||||
|| volatile_refs_p (PATTERN (insn)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (! nonlocal_memory_referenced)
|
||||
nonlocal_memory_referenced = nonlocal_referenced_p (insn);
|
||||
}
|
||||
|
||||
end_alias_analysis ();
|
||||
|
||||
/* Mark the function. */
|
||||
|
||||
if (! nonlocal_mentioned)
|
||||
if (insn)
|
||||
;
|
||||
else if (nonlocal_memory_referenced)
|
||||
DECL_IS_PURE (current_function_decl) = 1;
|
||||
else
|
||||
TREE_READONLY (current_function_decl) = 1;
|
||||
}
|
||||
|
||||
|
||||
static HARD_REG_SET argument_registers;
|
||||
|
||||
|
||||
void
|
||||
init_alias_once ()
|
||||
@ -2460,7 +2669,19 @@ init_alias_once ()
|
||||
numbers, so translate if necessary due to register windows. */
|
||||
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
|
||||
&& HARD_REGNO_MODE_OK (i, Pmode))
|
||||
SET_HARD_REG_BIT (argument_registers, i);
|
||||
static_reg_base_value[i]
|
||||
= gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));
|
||||
|
||||
static_reg_base_value[STACK_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
|
||||
static_reg_base_value[ARG_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
|
||||
static_reg_base_value[FRAME_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
|
||||
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
||||
static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
|
||||
#endif
|
||||
|
||||
alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0);
|
||||
}
|
||||
@ -2479,10 +2700,10 @@ init_alias_analysis ()
|
||||
|
||||
reg_known_value_size = maxreg;
|
||||
|
||||
reg_known_value
|
||||
reg_known_value
|
||||
= (rtx *) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (rtx))
|
||||
- FIRST_PSEUDO_REGISTER;
|
||||
reg_known_equiv_p
|
||||
reg_known_equiv_p
|
||||
= (char*) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (char))
|
||||
- FIRST_PSEUDO_REGISTER;
|
||||
|
||||
@ -2490,8 +2711,8 @@ init_alias_analysis ()
|
||||
optimization. Loop unrolling can create a large number of
|
||||
registers. */
|
||||
reg_base_value_size = maxreg * 2;
|
||||
reg_base_value = (rtx *) xcalloc (reg_base_value_size, sizeof (rtx));
|
||||
ggc_add_rtx_root (reg_base_value, reg_base_value_size);
|
||||
reg_base_value = (rtx *) ggc_alloc_cleared (reg_base_value_size
|
||||
* sizeof (rtx));
|
||||
|
||||
new_reg_base_value = (rtx *) xmalloc (reg_base_value_size * sizeof (rtx));
|
||||
reg_seen = (char *) xmalloc (reg_base_value_size);
|
||||
@ -2534,7 +2755,7 @@ init_alias_analysis ()
|
||||
|
||||
/* We're at the start of the function each iteration through the
|
||||
loop, so we're copying arguments. */
|
||||
copying_arguments = 1;
|
||||
copying_arguments = true;
|
||||
|
||||
/* Wipe the potential alias information clean for this pass. */
|
||||
memset ((char *) new_reg_base_value, 0, reg_base_value_size * sizeof (rtx));
|
||||
@ -2550,21 +2771,8 @@ init_alias_analysis ()
|
||||
The address expression is VOIDmode for an argument and
|
||||
Pmode for other registers. */
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
if (TEST_HARD_REG_BIT (argument_registers, i))
|
||||
new_reg_base_value[i] = gen_rtx_ADDRESS (VOIDmode,
|
||||
gen_rtx_REG (Pmode, i));
|
||||
|
||||
new_reg_base_value[STACK_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
|
||||
new_reg_base_value[ARG_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
|
||||
new_reg_base_value[FRAME_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
|
||||
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
||||
new_reg_base_value[HARD_FRAME_POINTER_REGNUM]
|
||||
= gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
|
||||
#endif
|
||||
memcpy (new_reg_base_value, static_reg_base_value,
|
||||
FIRST_PSEUDO_REGISTER * sizeof (rtx));
|
||||
|
||||
/* Walk the insns adding values to the new_reg_base_value array. */
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||
@ -2637,7 +2845,7 @@ init_alias_analysis ()
|
||||
}
|
||||
else if (GET_CODE (insn) == NOTE
|
||||
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
|
||||
copying_arguments = 0;
|
||||
copying_arguments = false;
|
||||
}
|
||||
|
||||
/* Now propagate values from new_reg_base_value to reg_base_value. */
|
||||
@ -2705,12 +2913,7 @@ end_alias_analysis ()
|
||||
reg_known_value_size = 0;
|
||||
free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
|
||||
reg_known_equiv_p = 0;
|
||||
if (reg_base_value)
|
||||
{
|
||||
ggc_del_root (reg_base_value);
|
||||
free (reg_base_value);
|
||||
reg_base_value = 0;
|
||||
}
|
||||
reg_base_value = 0;
|
||||
reg_base_value_size = 0;
|
||||
if (alias_invariant)
|
||||
{
|
||||
@ -2718,3 +2921,5 @@ end_alias_analysis ()
|
||||
alias_invariant = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#include "gt-alias.h"
|
||||
|
@ -136,10 +136,13 @@ So instead we use the macro below and test it against specific values. */
|
||||
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||
#endif /* GCC_VERSION */
|
||||
|
||||
#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
|
||||
#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus))
|
||||
/* All known AIX compilers implement these things (but don't always
|
||||
define __STDC__). The RISC/OS MIPS compiler defines these things
|
||||
in SVR4 mode, but does not define __STDC__. */
|
||||
/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
|
||||
C++ compilers, does not define __STDC__, though it acts as if this
|
||||
was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
|
||||
|
||||
#define ANSI_PROTOTYPES 1
|
||||
#define PTR void *
|
||||
@ -265,8 +268,21 @@ So instead we use the macro below and test it against specific values. */
|
||||
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||
#endif /* ATTRIBUTE_NORETURN */
|
||||
|
||||
/* Attribute `nonnull' was valid as of gcc 3.3. */
|
||||
#ifndef ATTRIBUTE_NONNULL
|
||||
# if (GCC_VERSION >= 3003)
|
||||
# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
|
||||
# else
|
||||
# define ATTRIBUTE_NONNULL(m)
|
||||
# endif /* GNUC >= 3.3 */
|
||||
#endif /* ATTRIBUTE_NONNULL */
|
||||
|
||||
/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
|
||||
This was the case for the `printf' format attribute by itself
|
||||
before GCC 3.3, but as of 3.3 we need to add the `nonnull'
|
||||
attribute to retain this behavior. */
|
||||
#ifndef ATTRIBUTE_PRINTF
|
||||
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
||||
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
|
||||
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
|
||||
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
|
||||
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
|
||||
@ -274,6 +290,21 @@ So instead we use the macro below and test it against specific values. */
|
||||
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
|
||||
#endif /* ATTRIBUTE_PRINTF */
|
||||
|
||||
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
|
||||
NULL format specifier was allowed as of gcc 3.3. */
|
||||
#ifndef ATTRIBUTE_NULL_PRINTF
|
||||
# if (GCC_VERSION >= 3003)
|
||||
# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
||||
# else
|
||||
# define ATTRIBUTE_NULL_PRINTF(m, n)
|
||||
# endif /* GNUC >= 3.3 */
|
||||
# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
|
||||
# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
|
||||
# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
|
||||
# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
|
||||
# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
|
||||
#endif /* ATTRIBUTE_NULL_PRINTF */
|
||||
|
||||
/* We use __extension__ in some places to suppress -pedantic warnings
|
||||
about GCC extensions. This feature didn't work properly before
|
||||
gcc 2.8. */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "sbitmap.h"
|
||||
#include "varray.h"
|
||||
#include "partition.h"
|
||||
#include "hard-reg-set.h"
|
||||
|
||||
/* Head of register set linked list. */
|
||||
typedef bitmap_head regset_head;
|
||||
@ -33,7 +34,7 @@ typedef bitmap_head regset_head;
|
||||
typedef bitmap regset;
|
||||
|
||||
/* Initialize a new regset. */
|
||||
#define INIT_REG_SET(HEAD) bitmap_initialize (HEAD)
|
||||
#define INIT_REG_SET(HEAD) bitmap_initialize (HEAD, 1)
|
||||
|
||||
/* Clear a register set by freeing up the linked list. */
|
||||
#define CLEAR_REG_SET(HEAD) bitmap_clear (HEAD)
|
||||
@ -99,7 +100,7 @@ do { \
|
||||
#define OBSTACK_ALLOC_REG_SET(OBSTACK) BITMAP_OBSTACK_ALLOC (OBSTACK)
|
||||
|
||||
/* Initialize a register set. Returns the new register set. */
|
||||
#define INITIALIZE_REG_SET(HEAD) bitmap_initialize (&HEAD)
|
||||
#define INITIALIZE_REG_SET(HEAD) bitmap_initialize (&HEAD, 1)
|
||||
|
||||
/* Do any cleanup needed on a regset when it is no longer used. */
|
||||
#define FREE_REG_SET(REGSET) BITMAP_FREE(REGSET)
|
||||
@ -135,12 +136,16 @@ typedef struct edge_def {
|
||||
in profile.c */
|
||||
} *edge;
|
||||
|
||||
#define EDGE_FALLTHRU 1
|
||||
#define EDGE_ABNORMAL 2
|
||||
#define EDGE_ABNORMAL_CALL 4
|
||||
#define EDGE_EH 8
|
||||
#define EDGE_FAKE 16
|
||||
#define EDGE_DFS_BACK 32
|
||||
#define EDGE_FALLTHRU 1 /* 'Straight line' flow */
|
||||
#define EDGE_ABNORMAL 2 /* Strange flow, like computed
|
||||
label, or eh */
|
||||
#define EDGE_ABNORMAL_CALL 4 /* Call with abnormal exit
|
||||
like an exception, or sibcall */
|
||||
#define EDGE_EH 8 /* Exception throw */
|
||||
#define EDGE_FAKE 16 /* Not a real edge (profile.c) */
|
||||
#define EDGE_DFS_BACK 32 /* A backwards edge */
|
||||
#define EDGE_CAN_FALLTHRU 64 /* Candidate for straight line
|
||||
flow. */
|
||||
|
||||
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
|
||||
|
||||
@ -205,9 +210,15 @@ typedef struct basic_block_def {
|
||||
/* The index of this block. */
|
||||
int index;
|
||||
|
||||
/* Previous and next blocks in the chain. */
|
||||
struct basic_block_def *prev_bb, *next_bb;
|
||||
|
||||
/* The loop depth of this block. */
|
||||
int loop_depth;
|
||||
|
||||
/* Outermost loop containing the block. */
|
||||
struct loop *loop_father;
|
||||
|
||||
/* Expected number of executions: calculated in profile.c. */
|
||||
gcov_type count;
|
||||
|
||||
@ -221,12 +232,19 @@ typedef struct basic_block_def {
|
||||
#define BB_FREQ_MAX 10000
|
||||
|
||||
/* Masks for basic_block.flags. */
|
||||
#define BB_REACHABLE 1
|
||||
#define BB_DIRTY 1
|
||||
#define BB_NEW 2
|
||||
#define BB_REACHABLE 4
|
||||
#define BB_VISITED 8
|
||||
|
||||
/* Number of basic blocks in the current function. */
|
||||
|
||||
extern int n_basic_blocks;
|
||||
|
||||
/* First free basic block number. */
|
||||
|
||||
extern int last_basic_block;
|
||||
|
||||
/* Number of edges in the current function. */
|
||||
|
||||
extern int n_edges;
|
||||
@ -237,13 +255,30 @@ extern varray_type basic_block_info;
|
||||
|
||||
#define BASIC_BLOCK(N) (VARRAY_BB (basic_block_info, (N)))
|
||||
|
||||
/* For iterating over basic blocks. */
|
||||
#define FOR_BB_BETWEEN(BB, FROM, TO, DIR) \
|
||||
for (BB = FROM; BB != TO; BB = BB->DIR)
|
||||
|
||||
#define FOR_EACH_BB(BB) \
|
||||
FOR_BB_BETWEEN (BB, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR, next_bb)
|
||||
|
||||
#define FOR_EACH_BB_REVERSE(BB) \
|
||||
FOR_BB_BETWEEN (BB, EXIT_BLOCK_PTR->prev_bb, ENTRY_BLOCK_PTR, prev_bb)
|
||||
|
||||
/* Cycles through _all_ basic blocks, even the fake ones (entry and
|
||||
exit block). */
|
||||
|
||||
#define FOR_ALL_BB(BB) \
|
||||
for (BB = ENTRY_BLOCK_PTR; BB; BB = BB->next_bb)
|
||||
|
||||
/* What registers are live at the setjmp call. */
|
||||
|
||||
extern regset regs_live_at_setjmp;
|
||||
|
||||
/* Special labels found during CFG build. */
|
||||
|
||||
extern rtx label_value_list, tail_recursion_label_list;
|
||||
extern GTY(()) rtx label_value_list;
|
||||
extern GTY(()) rtx tail_recursion_label_list;
|
||||
|
||||
extern struct obstack flow_obstack;
|
||||
|
||||
@ -279,27 +314,30 @@ extern struct basic_block_def entry_exit_blocks[2];
|
||||
#define ENTRY_BLOCK_PTR (&entry_exit_blocks[0])
|
||||
#define EXIT_BLOCK_PTR (&entry_exit_blocks[1])
|
||||
|
||||
extern varray_type basic_block_for_insn;
|
||||
#define BLOCK_FOR_INSN(INSN) VARRAY_BB (basic_block_for_insn, INSN_UID (INSN))
|
||||
#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
|
||||
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
|
||||
|
||||
extern void compute_bb_for_insn PARAMS ((int));
|
||||
extern void compute_bb_for_insn PARAMS ((void));
|
||||
extern void free_bb_for_insn PARAMS ((void));
|
||||
extern void update_bb_for_insn PARAMS ((basic_block));
|
||||
extern void set_block_for_insn PARAMS ((rtx, basic_block));
|
||||
|
||||
extern void free_basic_block_vars PARAMS ((int));
|
||||
|
||||
extern edge split_block PARAMS ((basic_block, rtx));
|
||||
extern basic_block split_edge PARAMS ((edge));
|
||||
extern void insert_insn_on_edge PARAMS ((rtx, edge));
|
||||
|
||||
extern void commit_edge_insertions PARAMS ((void));
|
||||
extern void commit_edge_insertions_watch_calls PARAMS ((void));
|
||||
|
||||
extern void remove_fake_edges PARAMS ((void));
|
||||
extern void add_noreturn_fake_exit_edges PARAMS ((void));
|
||||
extern void connect_infinite_loops_to_exit PARAMS ((void));
|
||||
extern int flow_call_edges_add PARAMS ((sbitmap));
|
||||
extern edge cached_make_edge PARAMS ((sbitmap *, basic_block,
|
||||
basic_block, int));
|
||||
extern edge unchecked_make_edge PARAMS ((basic_block,
|
||||
basic_block, int));
|
||||
extern edge make_edge PARAMS ((basic_block,
|
||||
basic_block, int));
|
||||
extern edge make_single_succ_edge PARAMS ((basic_block,
|
||||
@ -308,10 +346,11 @@ extern void remove_edge PARAMS ((edge));
|
||||
extern void redirect_edge_succ PARAMS ((edge, basic_block));
|
||||
extern edge redirect_edge_succ_nodup PARAMS ((edge, basic_block));
|
||||
extern void redirect_edge_pred PARAMS ((edge, basic_block));
|
||||
extern basic_block create_basic_block_structure PARAMS ((int, rtx, rtx, rtx));
|
||||
extern basic_block create_basic_block PARAMS ((int, rtx, rtx));
|
||||
extern basic_block create_basic_block_structure PARAMS ((rtx, rtx, rtx, basic_block));
|
||||
extern basic_block create_basic_block PARAMS ((rtx, rtx, basic_block));
|
||||
extern int flow_delete_block PARAMS ((basic_block));
|
||||
extern int flow_delete_block_noexpunge PARAMS ((basic_block));
|
||||
extern void clear_bb_flags PARAMS ((void));
|
||||
extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
|
||||
extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
|
||||
basic_block));
|
||||
@ -324,6 +363,10 @@ extern void clear_edges PARAMS ((void));
|
||||
extern void mark_critical_edges PARAMS ((void));
|
||||
extern rtx first_insn_after_basic_block_note PARAMS ((basic_block));
|
||||
|
||||
/* Dominator information for basic blocks. */
|
||||
|
||||
typedef struct dominance_info *dominance_info;
|
||||
|
||||
/* Structure to hold information for each natural loop. */
|
||||
struct loop
|
||||
{
|
||||
@ -379,6 +422,9 @@ struct loop
|
||||
/* The loop nesting depth. */
|
||||
int depth;
|
||||
|
||||
/* Superloops of the loop. */
|
||||
struct loop **pred;
|
||||
|
||||
/* The height of the loop (enclosed loop levels) within the loop
|
||||
hierarchy tree. */
|
||||
int level;
|
||||
@ -392,10 +438,7 @@ struct loop
|
||||
/* Link to the next (sibling) loop. */
|
||||
struct loop *next;
|
||||
|
||||
/* Non-zero if the loop shares a header with another loop. */
|
||||
int shared;
|
||||
|
||||
/* Non-zero if the loop is invalid (e.g., contains setjmp.). */
|
||||
/* Nonzero if the loop is invalid (e.g., contains setjmp.). */
|
||||
int invalid;
|
||||
|
||||
/* Auxiliary info specific to a pass. */
|
||||
@ -404,16 +447,13 @@ struct loop
|
||||
/* The following are currently used by loop.c but they are likely to
|
||||
disappear as loop.c is converted to use the CFG. */
|
||||
|
||||
/* Non-zero if the loop has a NOTE_INSN_LOOP_VTOP. */
|
||||
/* Nonzero if the loop has a NOTE_INSN_LOOP_VTOP. */
|
||||
rtx vtop;
|
||||
|
||||
/* Non-zero if the loop has a NOTE_INSN_LOOP_CONT.
|
||||
/* Nonzero if the loop has a NOTE_INSN_LOOP_CONT.
|
||||
A continue statement will generate a branch to NEXT_INSN (cont). */
|
||||
rtx cont;
|
||||
|
||||
/* The dominator of cont. */
|
||||
rtx cont_dominator;
|
||||
|
||||
/* The NOTE_INSN_LOOP_BEG. */
|
||||
rtx start;
|
||||
|
||||
@ -460,6 +500,11 @@ struct loops
|
||||
will find the inner loops before their enclosing outer loops). */
|
||||
struct loop *array;
|
||||
|
||||
/* The above array is unused in new loop infrastructure and is kept only for
|
||||
purposes of the old loop optimizer. Instead we store just pointers to
|
||||
loops here. */
|
||||
struct loop **parray;
|
||||
|
||||
/* Pointer to root of loop heirachy tree. */
|
||||
struct loop *tree_root;
|
||||
|
||||
@ -467,7 +512,7 @@ struct loops
|
||||
struct cfg
|
||||
{
|
||||
/* The bitmap vector of dominators or NULL if not computed. */
|
||||
sbitmap *dom;
|
||||
dominance_info dom;
|
||||
|
||||
/* The ordering of the basic blocks in a depth first search. */
|
||||
int *dfs_order;
|
||||
@ -481,6 +526,33 @@ struct loops
|
||||
sbitmap shared_headers;
|
||||
};
|
||||
|
||||
/* Structure to group all of the information to process IF-THEN and
|
||||
IF-THEN-ELSE blocks for the conditional execution support. This
|
||||
needs to be in a public file in case the IFCVT macros call
|
||||
functions passing the ce_if_block data structure. */
|
||||
|
||||
typedef struct ce_if_block
|
||||
{
|
||||
basic_block test_bb; /* First test block. */
|
||||
basic_block then_bb; /* THEN block. */
|
||||
basic_block else_bb; /* ELSE block or NULL. */
|
||||
basic_block join_bb; /* Join THEN/ELSE blocks. */
|
||||
basic_block last_test_bb; /* Last bb to hold && or || tests. */
|
||||
int num_multiple_test_blocks; /* # of && and || basic blocks. */
|
||||
int num_and_and_blocks; /* # of && blocks. */
|
||||
int num_or_or_blocks; /* # of || blocks. */
|
||||
int num_multiple_test_insns; /* # of insns in && and || blocks. */
|
||||
int and_and_p; /* Complex test is &&. */
|
||||
int num_then_insns; /* # of insns in THEN block. */
|
||||
int num_else_insns; /* # of insns in ELSE block. */
|
||||
int pass; /* Pass number. */
|
||||
|
||||
#ifdef IFCVT_EXTRA_FIELDS
|
||||
IFCVT_EXTRA_FIELDS /* Any machine dependent fields. */
|
||||
#endif
|
||||
|
||||
} ce_if_block_t;
|
||||
|
||||
extern int flow_loops_find PARAMS ((struct loops *, int flags));
|
||||
extern int flow_loops_update PARAMS ((struct loops *, int flags));
|
||||
extern void flow_loops_free PARAMS ((struct loops *));
|
||||
@ -491,6 +563,8 @@ extern void flow_loop_dump PARAMS ((const struct loop *, FILE *,
|
||||
void (*)(const struct loop *,
|
||||
FILE *, int), int));
|
||||
extern int flow_loop_scan PARAMS ((struct loops *, struct loop *, int));
|
||||
extern void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *));
|
||||
extern void flow_loop_tree_node_remove PARAMS ((struct loop *));
|
||||
|
||||
/* This structure maintains an edge list vector. */
|
||||
struct edge_list
|
||||
@ -562,7 +636,12 @@ enum update_life_extent
|
||||
by dead code removal. */
|
||||
#define PROP_AUTOINC 64 /* Create autoinc mem references. */
|
||||
#define PROP_EQUAL_NOTES 128 /* Take into account REG_EQUAL notes. */
|
||||
#define PROP_FINAL 127 /* All of the above. */
|
||||
#define PROP_SCAN_DEAD_STORES 256 /* Scan for dead code. */
|
||||
#define PROP_FINAL (PROP_DEATH_NOTES | PROP_LOG_LINKS \
|
||||
| PROP_REG_INFO | PROP_KILL_DEAD_CODE \
|
||||
| PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
|
||||
| PROP_ALLOW_CFG_CHANGES \
|
||||
| PROP_SCAN_DEAD_STORES)
|
||||
|
||||
#define CLEANUP_EXPENSIVE 1 /* Do relativly expensive optimizations
|
||||
except for edge forwarding */
|
||||
@ -575,6 +654,8 @@ enum update_life_extent
|
||||
notes. */
|
||||
#define CLEANUP_UPDATE_LIFE 32 /* Keep life information up to date. */
|
||||
#define CLEANUP_THREADING 64 /* Do jump threading. */
|
||||
#define CLEANUP_NO_INSN_DEL 128 /* Do not try to delete trivially dead
|
||||
insns. */
|
||||
/* Flags for loop discovery. */
|
||||
|
||||
#define LOOP_TREE 1 /* Build loop hierarchy tree. */
|
||||
@ -582,12 +663,13 @@ enum update_life_extent
|
||||
#define LOOP_ENTRY_EDGES 4 /* Find entry edges. */
|
||||
#define LOOP_EXIT_EDGES 8 /* Find exit edges. */
|
||||
#define LOOP_EDGES (LOOP_ENTRY_EDGES | LOOP_EXIT_EDGES)
|
||||
#define LOOP_EXITS_DOMS 16 /* Find nodes that dom. all exits. */
|
||||
#define LOOP_ALL 31 /* All of the above */
|
||||
#define LOOP_ALL 15 /* All of the above */
|
||||
|
||||
extern void life_analysis PARAMS ((rtx, FILE *, int));
|
||||
extern void update_life_info PARAMS ((sbitmap, enum update_life_extent,
|
||||
extern int update_life_info PARAMS ((sbitmap, enum update_life_extent,
|
||||
int));
|
||||
extern int update_life_info_in_dirty_blocks PARAMS ((enum update_life_extent,
|
||||
int));
|
||||
extern int count_or_remove_death_notes PARAMS ((sbitmap, int));
|
||||
extern int propagate_block PARAMS ((basic_block, regset, regset, regset,
|
||||
int));
|
||||
@ -617,7 +699,12 @@ extern rtx emit_block_insn_before PARAMS ((rtx, rtx, basic_block));
|
||||
|
||||
/* In predict.c */
|
||||
extern void estimate_probability PARAMS ((struct loops *));
|
||||
extern void note_prediction_to_br_prob PARAMS ((void));
|
||||
extern void expected_value_to_br_prob PARAMS ((void));
|
||||
extern void note_prediction_to_br_prob PARAMS ((void));
|
||||
extern bool maybe_hot_bb_p PARAMS ((basic_block));
|
||||
extern bool probably_cold_bb_p PARAMS ((basic_block));
|
||||
extern bool probably_never_executed_bb_p PARAMS ((basic_block));
|
||||
|
||||
/* In flow.c */
|
||||
extern void init_flow PARAMS ((void));
|
||||
@ -630,10 +717,12 @@ extern void debug_regset PARAMS ((regset));
|
||||
extern void allocate_reg_life_data PARAMS ((void));
|
||||
extern void allocate_bb_life_data PARAMS ((void));
|
||||
extern void expunge_block PARAMS ((basic_block));
|
||||
extern void expunge_block_nocompact PARAMS ((basic_block));
|
||||
extern void link_block PARAMS ((basic_block, basic_block));
|
||||
extern void unlink_block PARAMS ((basic_block));
|
||||
extern void compact_blocks PARAMS ((void));
|
||||
extern basic_block alloc_block PARAMS ((void));
|
||||
extern void find_unreachable_blocks PARAMS ((void));
|
||||
extern void delete_noop_moves PARAMS ((rtx));
|
||||
extern int delete_noop_moves PARAMS ((rtx));
|
||||
extern basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
|
||||
extern basic_block force_nonfallthru PARAMS ((edge));
|
||||
extern bool redirect_edge_and_branch PARAMS ((edge, basic_block));
|
||||
@ -661,13 +750,32 @@ extern void free_aux_for_edges PARAMS ((void));
|
||||
debugger, and it is declared extern so we don't get warnings about
|
||||
it being unused. */
|
||||
extern void verify_flow_info PARAMS ((void));
|
||||
extern int flow_loop_outside_edge_p PARAMS ((const struct loop *, edge));
|
||||
extern bool flow_loop_outside_edge_p PARAMS ((const struct loop *, edge));
|
||||
extern bool flow_loop_nested_p PARAMS ((const struct loop *,
|
||||
const struct loop *));
|
||||
extern bool flow_bb_inside_loop_p PARAMS ((const struct loop *,
|
||||
const basic_block));
|
||||
extern basic_block *get_loop_body PARAMS ((const struct loop *));
|
||||
extern int dfs_enumerate_from PARAMS ((basic_block, int,
|
||||
bool (*)(basic_block, void *),
|
||||
basic_block *, int, void *));
|
||||
|
||||
extern edge loop_preheader_edge PARAMS ((struct loop *));
|
||||
extern edge loop_latch_edge PARAMS ((struct loop *));
|
||||
|
||||
extern void add_bb_to_loop PARAMS ((basic_block, struct loop *));
|
||||
extern void remove_bb_from_loops PARAMS ((basic_block));
|
||||
extern struct loop * find_common_loop PARAMS ((struct loop *, struct loop *));
|
||||
|
||||
extern void verify_loop_structure PARAMS ((struct loops *, int));
|
||||
#define VLS_EXPECT_PREHEADERS 1
|
||||
#define VLS_EXPECT_SIMPLE_LATCHES 2
|
||||
|
||||
typedef struct conflict_graph_def *conflict_graph;
|
||||
|
||||
/* Callback function when enumerating conflicts. The arguments are
|
||||
the smaller and larger regno in the conflict. Returns zero if
|
||||
enumeration is to continue, non-zero to halt enumeration. */
|
||||
enumeration is to continue, nonzero to halt enumeration. */
|
||||
typedef int (*conflict_graph_enum_fn) PARAMS ((int, int, void *));
|
||||
|
||||
|
||||
@ -690,8 +798,12 @@ extern conflict_graph conflict_graph_compute
|
||||
PARAMS ((regset,
|
||||
partition));
|
||||
extern bool mark_dfs_back_edges PARAMS ((void));
|
||||
extern void set_edge_can_fallthru_flag PARAMS ((void));
|
||||
extern void update_br_prob_note PARAMS ((basic_block));
|
||||
extern void fixup_abnormal_edges PARAMS ((void));
|
||||
extern bool can_hoist_insn_p PARAMS ((rtx, rtx, regset));
|
||||
extern rtx hoist_insn_after PARAMS ((rtx, rtx, rtx, rtx));
|
||||
extern rtx hoist_insn_to_edge PARAMS ((rtx, edge, rtx, rtx));
|
||||
extern bool control_flow_insn_p PARAMS ((rtx));
|
||||
|
||||
/* In dominance.c */
|
||||
@ -702,7 +814,21 @@ enum cdi_direction
|
||||
CDI_POST_DOMINATORS
|
||||
};
|
||||
|
||||
extern void calculate_dominance_info PARAMS ((int *, sbitmap *,
|
||||
enum cdi_direction));
|
||||
|
||||
extern dominance_info calculate_dominance_info PARAMS ((enum cdi_direction));
|
||||
extern void free_dominance_info PARAMS ((dominance_info));
|
||||
extern basic_block nearest_common_dominator PARAMS ((dominance_info,
|
||||
basic_block, basic_block));
|
||||
extern void set_immediate_dominator PARAMS ((dominance_info,
|
||||
basic_block, basic_block));
|
||||
extern basic_block get_immediate_dominator PARAMS ((dominance_info,
|
||||
basic_block));
|
||||
extern bool dominated_by_p PARAMS ((dominance_info, basic_block, basic_block));
|
||||
extern int get_dominated_by PARAMS ((dominance_info, basic_block, basic_block **));
|
||||
extern void add_to_dominance_info PARAMS ((dominance_info, basic_block));
|
||||
extern void delete_from_dominance_info PARAMS ((dominance_info, basic_block));
|
||||
basic_block recount_dominator PARAMS ((dominance_info, basic_block));
|
||||
extern void redirect_immediate_dominators PARAMS ((dominance_info, basic_block,
|
||||
basic_block));
|
||||
void iterate_fix_dominators PARAMS ((dominance_info, basic_block *, int));
|
||||
extern void verify_dominators PARAMS ((dominance_info));
|
||||
#endif /* GCC_BASIC_BLOCK_H */
|
||||
|
@ -89,11 +89,13 @@
|
||||
#include "flags.h"
|
||||
#include "output.h"
|
||||
#include "cfglayout.h"
|
||||
#include "function.h"
|
||||
#include "target.h"
|
||||
|
||||
/* Local function prototypes. */
|
||||
static void make_reorder_chain PARAMS ((void));
|
||||
static basic_block make_reorder_chain_1 PARAMS ((basic_block, basic_block));
|
||||
static basic_block maybe_duplicate_computed_goto_succ PARAMS ((basic_block));
|
||||
|
||||
/* Compute an ordering for a subgraph beginning with block BB. Record the
|
||||
ordering in RBI()->index and chained through RBI()->next. */
|
||||
@ -102,14 +104,11 @@ static void
|
||||
make_reorder_chain ()
|
||||
{
|
||||
basic_block prev = NULL;
|
||||
int nbb_m1 = n_basic_blocks - 1;
|
||||
basic_block next;
|
||||
basic_block next, bb;
|
||||
|
||||
/* Loop until we've placed every block. */
|
||||
do
|
||||
{
|
||||
int i;
|
||||
|
||||
next = NULL;
|
||||
|
||||
/* Find the next unplaced block. */
|
||||
@ -119,19 +118,59 @@ make_reorder_chain ()
|
||||
remove from the list as we place. The head of that list is
|
||||
what we're looking for here. */
|
||||
|
||||
for (i = 0; i <= nbb_m1 && !next; ++i)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
if (! RBI (bb)->visited)
|
||||
FOR_EACH_BB (bb)
|
||||
if (! RBI (bb)->visited)
|
||||
{
|
||||
next = bb;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (next)
|
||||
prev = make_reorder_chain_1 (next, prev);
|
||||
prev = make_reorder_chain_1 (next, prev);
|
||||
}
|
||||
while (next);
|
||||
RBI (prev)->next = NULL;
|
||||
}
|
||||
|
||||
/* If the successor is our artificial computed_jump block, duplicate it. */
|
||||
|
||||
static inline basic_block
|
||||
maybe_duplicate_computed_goto_succ (bb)
|
||||
basic_block bb;
|
||||
{
|
||||
edge e;
|
||||
basic_block next;
|
||||
|
||||
/* Note that we can't rely on computed_goto_common_label still being in
|
||||
the instruction stream -- cfgloop.c likes to munge things about. But
|
||||
we can still use it's non-null-ness to avoid a fruitless search. */
|
||||
if (!cfun->computed_goto_common_label)
|
||||
return NULL;
|
||||
|
||||
/* Only want to duplicate when coming from a simple branch. */
|
||||
e = bb->succ;
|
||||
if (!e || e->succ_next)
|
||||
return NULL;
|
||||
|
||||
/* Only duplicate if we've already layed out this block once. */
|
||||
next = e->dest;
|
||||
if (!RBI (next)->visited)
|
||||
return NULL;
|
||||
|
||||
/* See if the block contains only a computed branch. */
|
||||
if ((next->head == next->end
|
||||
|| next_active_insn (next->head) == next->end)
|
||||
&& computed_jump_p (next->end))
|
||||
{
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Duplicating block %d after %d\n",
|
||||
next->index, bb->index);
|
||||
return cfg_layout_duplicate_bb (next, e);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* A helper function for make_reorder_chain.
|
||||
|
||||
We do not follow EH edges, or non-fallthru edges to noreturn blocks.
|
||||
@ -158,13 +197,13 @@ make_reorder_chain_1 (bb, prev)
|
||||
restart:
|
||||
RBI (prev)->next = bb;
|
||||
|
||||
if (rtl_dump_file && prev->index + 1 != bb->index)
|
||||
if (rtl_dump_file && prev->next_bb != bb)
|
||||
fprintf (rtl_dump_file, "Reordering block %d after %d\n",
|
||||
bb->index, prev->index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bb->index != 0)
|
||||
if (bb->prev_bb != ENTRY_BLOCK_PTR)
|
||||
abort ();
|
||||
}
|
||||
RBI (bb)->visited = 1;
|
||||
@ -205,9 +244,13 @@ make_reorder_chain_1 (bb, prev)
|
||||
e_taken = e;
|
||||
}
|
||||
|
||||
next = (taken ? e_taken : e_fall)->dest;
|
||||
next = ((taken && e_taken) ? e_taken : e_fall)->dest;
|
||||
}
|
||||
|
||||
/* If the successor is our artificial computed_jump block, duplicate it. */
|
||||
else
|
||||
next = maybe_duplicate_computed_goto_succ (bb);
|
||||
|
||||
/* In the absence of a prediction, disturb things as little as possible
|
||||
by selecting the old "next" block from the list of successors. If
|
||||
there had been a fallthru edge, that will be the one. */
|
||||
@ -221,7 +264,7 @@ make_reorder_chain_1 (bb, prev)
|
||||
next = e->dest;
|
||||
break;
|
||||
}
|
||||
else if (e->dest->index == bb->index + 1)
|
||||
else if (e->dest == bb->next_bb)
|
||||
{
|
||||
if (! (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)))
|
||||
next = e->dest;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Functions to support general ended bitmaps.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -23,6 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "rtl.h"
|
||||
#include "flags.h"
|
||||
#include "obstack.h"
|
||||
#include "ggc.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
/* Obstack to allocate bitmap elements from. */
|
||||
@ -40,13 +42,33 @@ static int bitmap_obstack_init = FALSE;
|
||||
/* Global data */
|
||||
bitmap_element bitmap_zero_bits; /* An element of all zero bits. */
|
||||
static bitmap_element *bitmap_free; /* Freelist of bitmap elements. */
|
||||
static GTY((deletable (""))) bitmap_element *bitmap_ggc_free;
|
||||
|
||||
static void bitmap_elem_to_freelist PARAMS ((bitmap, bitmap_element *));
|
||||
static void bitmap_element_free PARAMS ((bitmap, bitmap_element *));
|
||||
static bitmap_element *bitmap_element_allocate PARAMS ((void));
|
||||
static bitmap_element *bitmap_element_allocate PARAMS ((bitmap));
|
||||
static int bitmap_element_zerop PARAMS ((bitmap_element *));
|
||||
static void bitmap_element_link PARAMS ((bitmap, bitmap_element *));
|
||||
static bitmap_element *bitmap_find_bit PARAMS ((bitmap, unsigned int));
|
||||
|
||||
/* Add ELEM to the appropriate freelist. */
|
||||
static INLINE void
|
||||
bitmap_elem_to_freelist (head, elt)
|
||||
bitmap head;
|
||||
bitmap_element *elt;
|
||||
{
|
||||
if (head->using_obstack)
|
||||
{
|
||||
elt->next = bitmap_free;
|
||||
bitmap_free = elt;
|
||||
}
|
||||
else
|
||||
{
|
||||
elt->next = bitmap_ggc_free;
|
||||
bitmap_ggc_free = elt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free a bitmap element. Since these are allocated off the
|
||||
bitmap_obstack, "free" actually means "put onto the freelist". */
|
||||
|
||||
@ -75,56 +97,68 @@ bitmap_element_free (head, elt)
|
||||
if (head->current)
|
||||
head->indx = head->current->indx;
|
||||
}
|
||||
|
||||
elt->next = bitmap_free;
|
||||
bitmap_free = elt;
|
||||
bitmap_elem_to_freelist (head, elt);
|
||||
}
|
||||
|
||||
/* Allocate a bitmap element. The bits are cleared, but nothing else is. */
|
||||
|
||||
static INLINE bitmap_element *
|
||||
bitmap_element_allocate ()
|
||||
bitmap_element_allocate (head)
|
||||
bitmap head;
|
||||
{
|
||||
bitmap_element *element;
|
||||
|
||||
if (bitmap_free != 0)
|
||||
if (head->using_obstack)
|
||||
{
|
||||
element = bitmap_free;
|
||||
bitmap_free = element->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We can't use gcc_obstack_init to initialize the obstack since
|
||||
print-rtl.c now calls bitmap functions, and bitmap is linked
|
||||
into the gen* functions. */
|
||||
if (!bitmap_obstack_init)
|
||||
if (bitmap_free != 0)
|
||||
{
|
||||
bitmap_obstack_init = TRUE;
|
||||
|
||||
/* Let particular systems override the size of a chunk. */
|
||||
element = bitmap_free;
|
||||
bitmap_free = element->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We can't use gcc_obstack_init to initialize the obstack since
|
||||
print-rtl.c now calls bitmap functions, and bitmap is linked
|
||||
into the gen* functions. */
|
||||
if (!bitmap_obstack_init)
|
||||
{
|
||||
bitmap_obstack_init = TRUE;
|
||||
|
||||
/* Let particular systems override the size of a chunk. */
|
||||
#ifndef OBSTACK_CHUNK_SIZE
|
||||
#define OBSTACK_CHUNK_SIZE 0
|
||||
#endif
|
||||
/* Let them override the alloc and free routines too. */
|
||||
/* Let them override the alloc and free routines too. */
|
||||
#ifndef OBSTACK_CHUNK_ALLOC
|
||||
#define OBSTACK_CHUNK_ALLOC xmalloc
|
||||
#endif
|
||||
#ifndef OBSTACK_CHUNK_FREE
|
||||
#define OBSTACK_CHUNK_FREE free
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 2)
|
||||
#define __alignof__(type) 0
|
||||
#endif
|
||||
|
||||
obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
|
||||
__alignof__ (bitmap_element),
|
||||
(void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
|
||||
(void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
|
||||
|
||||
obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
|
||||
__alignof__ (bitmap_element),
|
||||
(void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
|
||||
(void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
|
||||
}
|
||||
|
||||
element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
|
||||
sizeof (bitmap_element));
|
||||
}
|
||||
|
||||
element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
|
||||
sizeof (bitmap_element));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bitmap_ggc_free != NULL)
|
||||
{
|
||||
element = bitmap_ggc_free;
|
||||
bitmap_ggc_free = element->next;
|
||||
}
|
||||
else
|
||||
element = ggc_alloc (sizeof (bitmap_element));
|
||||
}
|
||||
|
||||
memset (element->bits, 0, sizeof (element->bits));
|
||||
@ -232,11 +266,10 @@ bitmap_clear (head)
|
||||
for (element = head->first; element != 0; element = next)
|
||||
{
|
||||
next = element->next;
|
||||
element->next = bitmap_free;
|
||||
bitmap_free = element;
|
||||
bitmap_elem_to_freelist (head, element);
|
||||
}
|
||||
|
||||
head->first = head->current = 0;
|
||||
head->first = head->current = 0;
|
||||
}
|
||||
|
||||
/* Copy a bitmap to another bitmap. */
|
||||
@ -256,7 +289,7 @@ bitmap_copy (to, from)
|
||||
/* Copy elements in forward direction one at a time */
|
||||
for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
|
||||
{
|
||||
bitmap_element *to_elt = bitmap_element_allocate ();
|
||||
bitmap_element *to_elt = bitmap_element_allocate (to);
|
||||
|
||||
to_elt->indx = from_ptr->indx;
|
||||
|
||||
@ -298,7 +331,7 @@ bitmap_find_bit (head, bit)
|
||||
unsigned int bit;
|
||||
{
|
||||
bitmap_element *element;
|
||||
unsigned HOST_WIDE_INT indx = bit / BITMAP_ELEMENT_ALL_BITS;
|
||||
unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
if (head->current == 0
|
||||
|| head->indx == indx)
|
||||
@ -337,10 +370,9 @@ bitmap_clear_bit (head, bit)
|
||||
|
||||
if (ptr != 0)
|
||||
{
|
||||
unsigned bit_num = bit % (unsigned) HOST_BITS_PER_WIDE_INT;
|
||||
unsigned word_num = ((bit / (unsigned) HOST_BITS_PER_WIDE_INT)
|
||||
% BITMAP_ELEMENT_WORDS);
|
||||
ptr->bits[word_num] &= ~ (((unsigned HOST_WIDE_INT) 1) << bit_num);
|
||||
unsigned bit_num = bit % BITMAP_WORD_BITS;
|
||||
unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
ptr->bits[word_num] &= ~ (((BITMAP_WORD) 1) << bit_num);
|
||||
|
||||
/* If we cleared the entire word, free up the element */
|
||||
if (bitmap_element_zerop (ptr))
|
||||
@ -356,14 +388,13 @@ bitmap_set_bit (head, bit)
|
||||
int bit;
|
||||
{
|
||||
bitmap_element *ptr = bitmap_find_bit (head, bit);
|
||||
unsigned word_num
|
||||
= ((bit / (unsigned) HOST_BITS_PER_WIDE_INT) % BITMAP_ELEMENT_WORDS);
|
||||
unsigned bit_num = bit % (unsigned) HOST_BITS_PER_WIDE_INT;
|
||||
unsigned HOST_WIDE_INT bit_val = ((unsigned HOST_WIDE_INT) 1) << bit_num;
|
||||
unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
unsigned bit_num = bit % BITMAP_WORD_BITS;
|
||||
BITMAP_WORD bit_val = ((BITMAP_WORD) 1) << bit_num;
|
||||
|
||||
if (ptr == 0)
|
||||
{
|
||||
ptr = bitmap_element_allocate ();
|
||||
ptr = bitmap_element_allocate (head);
|
||||
ptr->indx = bit / BITMAP_ELEMENT_ALL_BITS;
|
||||
ptr->bits[word_num] = bit_val;
|
||||
bitmap_element_link (head, ptr);
|
||||
@ -387,9 +418,8 @@ bitmap_bit_p (head, bit)
|
||||
if (ptr == 0)
|
||||
return 0;
|
||||
|
||||
bit_num = bit % (unsigned) HOST_BITS_PER_WIDE_INT;
|
||||
word_num
|
||||
= ((bit / (unsigned) HOST_BITS_PER_WIDE_INT) % BITMAP_ELEMENT_WORDS);
|
||||
bit_num = bit % BITMAP_WORD_BITS;
|
||||
word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
|
||||
return (ptr->bits[word_num] >> bit_num) & 1;
|
||||
}
|
||||
@ -397,12 +427,12 @@ bitmap_bit_p (head, bit)
|
||||
/* Return the bit number of the first set bit in the bitmap, or -1
|
||||
if the bitmap is empty. */
|
||||
|
||||
int
|
||||
int
|
||||
bitmap_first_set_bit (a)
|
||||
bitmap a;
|
||||
{
|
||||
bitmap_element *ptr = a->first;
|
||||
unsigned HOST_WIDE_INT word;
|
||||
BITMAP_WORD word;
|
||||
unsigned word_num, bit_num;
|
||||
|
||||
if (ptr == NULL)
|
||||
@ -424,10 +454,10 @@ bitmap_first_set_bit (a)
|
||||
bit_num = 0;
|
||||
word = word & -word;
|
||||
|
||||
#if HOST_BITS_PER_WIDE_INT > 64
|
||||
#if nBITMAP_WORD_BITS > 64
|
||||
#error "Fill out the table."
|
||||
#endif
|
||||
#if HOST_BITS_PER_WIDE_INT > 32
|
||||
#if nBITMAP_WORD_BITS > 32
|
||||
if ((word & 0xffffffff) == 0)
|
||||
word >>= 32, bit_num += 32;
|
||||
#endif
|
||||
@ -443,19 +473,19 @@ bitmap_first_set_bit (a)
|
||||
bit_num += 1;
|
||||
|
||||
return (ptr->indx * BITMAP_ELEMENT_ALL_BITS
|
||||
+ word_num * HOST_BITS_PER_WIDE_INT
|
||||
+ word_num * BITMAP_WORD_BITS
|
||||
+ bit_num);
|
||||
}
|
||||
|
||||
/* Return the bit number of the last set bit in the bitmap, or -1
|
||||
if the bitmap is empty. */
|
||||
|
||||
int
|
||||
int
|
||||
bitmap_last_set_bit (a)
|
||||
bitmap a;
|
||||
{
|
||||
bitmap_element *ptr = a->first;
|
||||
unsigned HOST_WIDE_INT word;
|
||||
BITMAP_WORD word;
|
||||
unsigned word_num, bit_num;
|
||||
|
||||
if (ptr == NULL)
|
||||
@ -477,11 +507,11 @@ bitmap_last_set_bit (a)
|
||||
/* Binary search for the last set bit. */
|
||||
|
||||
bit_num = 0;
|
||||
#if HOST_BITS_PER_WIDE_INT > 64
|
||||
#if nBITMAP_WORD_BITS > 64
|
||||
#error "Fill out the table."
|
||||
#endif
|
||||
#if HOST_BITS_PER_WIDE_INT > 32
|
||||
if (word & ~ (unsigned HOST_WIDE_INT) 0xffffffff)
|
||||
#if nBITMAP_WORD_BITS > 32
|
||||
if (word & ~(BITMAP_WORD)0xffffffff)
|
||||
word >>= 32, bit_num += 32;
|
||||
#endif
|
||||
if (word & 0xffff0000)
|
||||
@ -496,7 +526,7 @@ bitmap_last_set_bit (a)
|
||||
bit_num += 1;
|
||||
|
||||
return (ptr->indx * BITMAP_ELEMENT_ALL_BITS
|
||||
+ word_num * HOST_BITS_PER_WIDE_INT
|
||||
+ word_num * BITMAP_WORD_BITS
|
||||
+ bit_num);
|
||||
}
|
||||
|
||||
@ -526,7 +556,7 @@ bitmap_operation (to, from1, from2, operation)
|
||||
#if BITMAP_ELEMENT_WORDS == 2
|
||||
#define DOIT(OP) \
|
||||
do { \
|
||||
unsigned HOST_WIDE_INT t0, t1, f10, f11, f20, f21; \
|
||||
BITMAP_WORD t0, t1, f10, f11, f20, f21; \
|
||||
f10 = from1_tmp->bits[0]; \
|
||||
f20 = from2_tmp->bits[0]; \
|
||||
t0 = f10 OP f20; \
|
||||
@ -541,7 +571,7 @@ bitmap_operation (to, from1, from2, operation)
|
||||
#else
|
||||
#define DOIT(OP) \
|
||||
do { \
|
||||
unsigned HOST_WIDE_INT t, f1, f2; \
|
||||
BITMAP_WORD t, f1, f2; \
|
||||
int i; \
|
||||
for (i = 0; i < BITMAP_ELEMENT_WORDS; ++i) \
|
||||
{ \
|
||||
@ -594,8 +624,7 @@ bitmap_operation (to, from1, from2, operation)
|
||||
changed = 1;
|
||||
to_tmp = to_ptr;
|
||||
to_ptr = to_ptr->next;
|
||||
to_tmp->next = bitmap_free;
|
||||
bitmap_free = to_tmp;
|
||||
bitmap_elem_to_freelist (to, to_tmp);
|
||||
}
|
||||
if (to_ptr && to_ptr->indx == indx)
|
||||
{
|
||||
@ -603,7 +632,7 @@ bitmap_operation (to, from1, from2, operation)
|
||||
to_ptr = to_ptr->next;
|
||||
}
|
||||
else
|
||||
to_tmp = bitmap_element_allocate ();
|
||||
to_tmp = bitmap_element_allocate (to);
|
||||
|
||||
/* Do the operation, and if any bits are set, link it into the
|
||||
linked list. */
|
||||
@ -638,8 +667,7 @@ bitmap_operation (to, from1, from2, operation)
|
||||
}
|
||||
else
|
||||
{
|
||||
to_tmp->next = bitmap_free;
|
||||
bitmap_free = to_tmp;
|
||||
bitmap_elem_to_freelist (to, to_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -649,8 +677,16 @@ bitmap_operation (to, from1, from2, operation)
|
||||
changed = 1;
|
||||
for (to_tmp = to_ptr; to_tmp->next ; to_tmp = to_tmp->next)
|
||||
continue;
|
||||
to_tmp->next = bitmap_free;
|
||||
bitmap_free = to_ptr;
|
||||
if (to->using_obstack)
|
||||
{
|
||||
to_tmp->next = bitmap_free;
|
||||
bitmap_free = to_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
to_tmp->next = bitmap_ggc_free;
|
||||
bitmap_ggc_free = to_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
#undef DOIT
|
||||
@ -668,7 +704,7 @@ bitmap_equal_p (a, b)
|
||||
bitmap_head c;
|
||||
int ret;
|
||||
|
||||
c.first = c.current = 0;
|
||||
memset (&c, 0, sizeof (c));
|
||||
ret = ! bitmap_operation (&c, a, b, BITMAP_XOR);
|
||||
bitmap_clear (&c);
|
||||
|
||||
@ -687,6 +723,7 @@ bitmap_ior_and_compl (to, from1, from2)
|
||||
bitmap_head tmp;
|
||||
|
||||
tmp.first = tmp.current = 0;
|
||||
tmp.using_obstack = 0;
|
||||
|
||||
bitmap_operation (&tmp, from1, from2, BITMAP_AND_COMPL);
|
||||
bitmap_operation (to, to, &tmp, BITMAP_IOR);
|
||||
@ -704,6 +741,7 @@ bitmap_union_of_diff (dst, a, b, c)
|
||||
int changed;
|
||||
|
||||
tmp.first = tmp.current = 0;
|
||||
tmp.using_obstack = 0;
|
||||
|
||||
bitmap_operation (&tmp, b, c, BITMAP_AND_COMPL);
|
||||
changed = bitmap_operation (dst, &tmp, a, BITMAP_IOR);
|
||||
@ -715,10 +753,15 @@ bitmap_union_of_diff (dst, a, b, c)
|
||||
/* Initialize a bitmap header. */
|
||||
|
||||
bitmap
|
||||
bitmap_initialize (head)
|
||||
bitmap_initialize (head, using_obstack)
|
||||
bitmap head;
|
||||
int using_obstack;
|
||||
{
|
||||
if (head == NULL && ! using_obstack)
|
||||
head = ggc_alloc (sizeof (*head));
|
||||
|
||||
head->first = head->current = 0;
|
||||
head->using_obstack = using_obstack;
|
||||
|
||||
return head;
|
||||
}
|
||||
@ -740,7 +783,7 @@ debug_bitmap_file (file, head)
|
||||
|
||||
for (ptr = head->first; ptr; ptr = ptr->next)
|
||||
{
|
||||
int i, j, col = 26;
|
||||
unsigned int i, j, col = 26;
|
||||
|
||||
fprintf (file, "\t");
|
||||
fprintf (file, HOST_PTR_PRINTF, (PTR) ptr);
|
||||
@ -751,7 +794,7 @@ debug_bitmap_file (file, head)
|
||||
fprintf (file, " indx = %u\n\t\tbits = {", ptr->indx);
|
||||
|
||||
for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
|
||||
for (j = 0; j < HOST_BITS_PER_WIDE_INT; j++)
|
||||
for (j = 0; j < BITMAP_WORD_BITS; j++)
|
||||
if ((ptr->bits[i] >> j) & 1)
|
||||
{
|
||||
if (col > 70)
|
||||
@ -761,7 +804,7 @@ debug_bitmap_file (file, head)
|
||||
}
|
||||
|
||||
fprintf (file, " %u", (ptr->indx * BITMAP_ELEMENT_ALL_BITS
|
||||
+ i * HOST_BITS_PER_WIDE_INT + j));
|
||||
+ i * BITMAP_WORD_BITS + j));
|
||||
col += 4;
|
||||
}
|
||||
|
||||
@ -800,3 +843,5 @@ bitmap_print (file, head, prefix, suffix)
|
||||
});
|
||||
fputs (suffix, file);
|
||||
}
|
||||
|
||||
#include "gt-bitmap.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Functions to support general ended bitmaps.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -20,12 +20,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#ifndef GCC_BITMAP_H
|
||||
#define GCC_BITMAP_H
|
||||
#define GCC_BITMAP_H
|
||||
|
||||
/* Fundamental storage type for bitmap. */
|
||||
|
||||
/* typedef unsigned HOST_WIDE_INT BITMAP_WORD; */
|
||||
/* #define nBITMAP_WORD_BITS HOST_BITS_PER_WIDE_INT */
|
||||
typedef unsigned long BITMAP_WORD;
|
||||
#define nBITMAP_WORD_BITS (CHAR_BIT * SIZEOF_LONG)
|
||||
#define BITMAP_WORD_BITS (unsigned) nBITMAP_WORD_BITS
|
||||
|
||||
/* Number of words to use for each element in the linked list. */
|
||||
|
||||
#ifndef BITMAP_ELEMENT_WORDS
|
||||
#define BITMAP_ELEMENT_WORDS 2
|
||||
#define BITMAP_ELEMENT_WORDS ((128 + nBITMAP_WORD_BITS - 1) / nBITMAP_WORD_BITS)
|
||||
#endif
|
||||
|
||||
/* Number of bits in each actual element of a bitmap. We get slightly better
|
||||
@ -33,28 +41,30 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
bits is unsigned, assuming it is a power of 2. */
|
||||
|
||||
#define BITMAP_ELEMENT_ALL_BITS \
|
||||
((unsigned) (BITMAP_ELEMENT_WORDS * HOST_BITS_PER_WIDE_INT))
|
||||
((unsigned) (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS))
|
||||
|
||||
/* Bitmap set element. We use a linked list to hold only the bits that
|
||||
are set. This allows for use to grow the bitset dynamically without
|
||||
having to realloc and copy a giant bit array. The `prev' field is
|
||||
undefined for an element on the free list. */
|
||||
|
||||
typedef struct bitmap_element_def
|
||||
typedef struct bitmap_element_def GTY(())
|
||||
{
|
||||
struct bitmap_element_def *next; /* Next element. */
|
||||
struct bitmap_element_def *prev; /* Previous element. */
|
||||
unsigned int indx; /* regno/BITMAP_ELEMENT_ALL_BITS. */
|
||||
unsigned HOST_WIDE_INT bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set. */
|
||||
BITMAP_WORD bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set. */
|
||||
} bitmap_element;
|
||||
|
||||
/* Head of bitmap linked list. */
|
||||
typedef struct bitmap_head_def {
|
||||
typedef struct bitmap_head_def GTY(()) {
|
||||
bitmap_element *first; /* First element in linked list. */
|
||||
bitmap_element *current; /* Last element looked at. */
|
||||
unsigned int indx; /* Index of last element looked at. */
|
||||
|
||||
} bitmap_head, *bitmap;
|
||||
int using_obstack; /* Are we using an obstack or ggc for
|
||||
allocation? */
|
||||
} bitmap_head;
|
||||
typedef struct bitmap_head_def *bitmap;
|
||||
|
||||
/* Enumeration giving the various operations we support. */
|
||||
enum bitmap_bits {
|
||||
@ -100,10 +110,12 @@ extern void debug_bitmap_file PARAMS ((FILE *, bitmap));
|
||||
/* Print a bitmap */
|
||||
extern void bitmap_print PARAMS ((FILE *, bitmap, const char *, const char *));
|
||||
|
||||
/* Initialize a bitmap header. */
|
||||
extern bitmap bitmap_initialize PARAMS ((bitmap));
|
||||
/* Initialize a bitmap header. If HEAD is NULL, a new header will be
|
||||
allocated. USING_OBSTACK indicates how elements should be allocated. */
|
||||
extern bitmap bitmap_initialize PARAMS ((bitmap head,
|
||||
int using_obstack));
|
||||
|
||||
/* Release all memory held by bitmaps. */
|
||||
/* Release all memory used by the bitmap obstack. */
|
||||
extern void bitmap_release_memory PARAMS ((void));
|
||||
|
||||
/* A few compatibility/functions macros for compatibility with sbitmaps */
|
||||
@ -117,22 +129,15 @@ extern int bitmap_last_set_bit PARAMS((bitmap));
|
||||
|
||||
/* Allocate a bitmap with oballoc. */
|
||||
#define BITMAP_OBSTACK_ALLOC(OBSTACK) \
|
||||
bitmap_initialize ((bitmap) obstack_alloc (OBSTACK, sizeof (bitmap_head)))
|
||||
bitmap_initialize ((bitmap) obstack_alloc (OBSTACK, sizeof (bitmap_head)), 1)
|
||||
|
||||
/* Allocate a bitmap with ggc_alloc. */
|
||||
#define BITMAP_GGC_ALLOC() \
|
||||
bitmap_initialize (NULL, 0)
|
||||
|
||||
/* Allocate a bitmap with alloca. Note alloca cannot be passed as an
|
||||
argument to a function, so we set a temporary variable to the value
|
||||
returned by alloca and pass that variable to bitmap_initialize().
|
||||
PTR is then set to the value returned from bitmap_initialize() to
|
||||
avoid having it appear more than once in case it has side effects. */
|
||||
#define BITMAP_ALLOCA(PTR) \
|
||||
do { \
|
||||
bitmap temp_bitmap_ = (bitmap) alloca (sizeof (bitmap_head)); \
|
||||
(PTR) = bitmap_initialize (temp_bitmap_); \
|
||||
} while (0)
|
||||
|
||||
/* Allocate a bitmap with xmalloc. */
|
||||
#define BITMAP_XMALLOC() \
|
||||
bitmap_initialize ((bitmap) xmalloc (sizeof (bitmap_head)))
|
||||
bitmap_initialize ((bitmap) xmalloc (sizeof (bitmap_head)), 1)
|
||||
|
||||
/* Do any cleanup needed on a bitmap when it is no longer used. */
|
||||
#define BITMAP_FREE(BITMAP) \
|
||||
@ -165,9 +170,8 @@ do { \
|
||||
do { \
|
||||
bitmap_element *ptr_ = (BITMAP)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % ((unsigned) HOST_BITS_PER_WIDE_INT); \
|
||||
unsigned word_num_ = (((MIN) / ((unsigned) HOST_BITS_PER_WIDE_INT)) \
|
||||
% BITMAP_ELEMENT_WORDS); \
|
||||
unsigned bit_num_ = (MIN) % BITMAP_WORD_BITS; \
|
||||
unsigned word_num_ = (MIN) / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; \
|
||||
\
|
||||
\
|
||||
/* Find the block the minimum bit is in. */ \
|
||||
@ -184,20 +188,19 @@ do { \
|
||||
{ \
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT word_ = ptr_->bits[word_num_]; \
|
||||
BITMAP_WORD word_ = ptr_->bits[word_num_]; \
|
||||
\
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < HOST_BITS_PER_WIDE_INT; bit_num_++) \
|
||||
for (; bit_num_ < BITMAP_WORD_BITS; bit_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT mask_ \
|
||||
= ((unsigned HOST_WIDE_INT) 1) << bit_num_; \
|
||||
BITMAP_WORD mask_ = ((BITMAP_WORD) 1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * HOST_BITS_PER_WIDE_INT \
|
||||
+ word_num_ * BITMAP_WORD_BITS \
|
||||
+ bit_num_); \
|
||||
CODE; \
|
||||
\
|
||||
@ -223,9 +226,8 @@ do { \
|
||||
bitmap_element *ptr1_ = (BITMAP1)->first; \
|
||||
bitmap_element *ptr2_ = (BITMAP2)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % ((unsigned) HOST_BITS_PER_WIDE_INT); \
|
||||
unsigned word_num_ = (((MIN) / ((unsigned) HOST_BITS_PER_WIDE_INT)) \
|
||||
% BITMAP_ELEMENT_WORDS); \
|
||||
unsigned bit_num_ = (MIN) % BITMAP_WORD_BITS; \
|
||||
unsigned word_num_ = (MIN) / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; \
|
||||
\
|
||||
/* Find the block the minimum bit is in in the first bitmap. */ \
|
||||
while (ptr1_ != 0 && ptr1_->indx < indx_) \
|
||||
@ -251,20 +253,19 @@ do { \
|
||||
\
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT word_ = (ptr1_->bits[word_num_] \
|
||||
& ~ tmp2_->bits[word_num_]); \
|
||||
BITMAP_WORD word_ = (ptr1_->bits[word_num_] \
|
||||
& ~ tmp2_->bits[word_num_]); \
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < HOST_BITS_PER_WIDE_INT; bit_num_++) \
|
||||
for (; bit_num_ < BITMAP_WORD_BITS; bit_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT mask_ \
|
||||
= ((unsigned HOST_WIDE_INT)1) << bit_num_; \
|
||||
BITMAP_WORD mask_ = ((BITMAP_WORD) 1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr1_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * HOST_BITS_PER_WIDE_INT \
|
||||
+ word_num_ * BITMAP_WORD_BITS \
|
||||
+ bit_num_); \
|
||||
\
|
||||
CODE; \
|
||||
@ -290,9 +291,8 @@ do { \
|
||||
bitmap_element *ptr1_ = (BITMAP1)->first; \
|
||||
bitmap_element *ptr2_ = (BITMAP2)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % ((unsigned) HOST_BITS_PER_WIDE_INT); \
|
||||
unsigned word_num_ = (((MIN) / ((unsigned) HOST_BITS_PER_WIDE_INT)) \
|
||||
% BITMAP_ELEMENT_WORDS); \
|
||||
unsigned bit_num_ = (MIN) % BITMAP_WORD_BITS; \
|
||||
unsigned word_num_ = (MIN) / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; \
|
||||
\
|
||||
/* Find the block the minimum bit is in in the first bitmap. */ \
|
||||
while (ptr1_ != 0 && ptr1_->indx < indx_) \
|
||||
@ -324,20 +324,19 @@ do { \
|
||||
\
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT word_ = (ptr1_->bits[word_num_] \
|
||||
& ptr2_->bits[word_num_]); \
|
||||
BITMAP_WORD word_ = (ptr1_->bits[word_num_] \
|
||||
& ptr2_->bits[word_num_]); \
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < HOST_BITS_PER_WIDE_INT; bit_num_++) \
|
||||
for (; bit_num_ < BITMAP_WORD_BITS; bit_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT mask_ \
|
||||
= ((unsigned HOST_WIDE_INT)1) << bit_num_; \
|
||||
BITMAP_WORD mask_ = ((BITMAP_WORD) 1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr1_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * HOST_BITS_PER_WIDE_INT \
|
||||
+ word_num_ * BITMAP_WORD_BITS \
|
||||
+ bit_num_); \
|
||||
\
|
||||
CODE; \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Joseph Myers <jsm28@cam.ac.uk>.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -77,36 +77,65 @@ DEF_LIST_INT_INT (3,0)
|
||||
DEF_LIST_INT_INT (3,4)
|
||||
#undef DEF_LIST_INT_INT
|
||||
|
||||
DEF_ATTR_IDENT (ATTR_PRINTF, "printf")
|
||||
DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
|
||||
DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime")
|
||||
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
|
||||
|
||||
/* Construct tress for identifiers. */
|
||||
DEF_ATTR_IDENT (ATTR_CONST, "const")
|
||||
DEF_ATTR_IDENT (ATTR_FORMAT, "format")
|
||||
DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg")
|
||||
DEF_ATTR_IDENT (ATTR_MALLOC, "malloc")
|
||||
DEF_ATTR_IDENT (ATTR_NONNULL, "nonnull")
|
||||
DEF_ATTR_IDENT (ATTR_NORETURN, "noreturn")
|
||||
DEF_ATTR_IDENT (ATTR_NOTHROW, "nothrow")
|
||||
DEF_ATTR_IDENT (ATTR_PRINTF, "printf")
|
||||
DEF_ATTR_IDENT (ATTR_PURE, "pure")
|
||||
DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
|
||||
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
|
||||
DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime")
|
||||
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_LIST, ATTR_NOTHROW, ATTR_NULL, ATTR_NULL)
|
||||
|
||||
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_LIST, ATTR_CONST, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LIST, ATTR_PURE, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_ATTR_TREE_LIST (ATTR_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
/* Construct a tree for a format attribute. */
|
||||
#define DEF_FORMAT_ATTRIBUTE(TYPE, VALUES) \
|
||||
#define DEF_FORMAT_ATTRIBUTE(TYPE, FA, VALUES) \
|
||||
DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_,TYPE,_,VALUES), ATTR_NULL, \
|
||||
CONCAT2 (ATTR_,TYPE), CONCAT2 (ATTR_LIST_,VALUES)) \
|
||||
DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_FORMAT_,TYPE,_,VALUES), ATTR_FORMAT, \
|
||||
CONCAT4 (ATTR_,TYPE,_,VALUES), ATTR_NULL)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,1_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,1_2)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,2_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,2_3)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,3_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,3_4)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,1_0)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,1_2)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,2_0)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,2_3)
|
||||
DEF_FORMAT_ATTRIBUTE(STRFTIME,3_0)
|
||||
DEF_FORMAT_ATTRIBUTE(STRFMON,3_4)
|
||||
CONCAT4 (ATTR_,TYPE,_,VALUES), CONCAT2 (ATTR_NONNULL_,FA))
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_2)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,2,2_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,2,2_3)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,3,3_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,3,3_4)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,1,1_0)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,1,1_2)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,2,2_0)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,2,2_3)
|
||||
DEF_FORMAT_ATTRIBUTE(STRFTIME,3,3_0)
|
||||
DEF_FORMAT_ATTRIBUTE(STRFMON,3,3_4)
|
||||
#undef DEF_FORMAT_ATTRIBUTE
|
||||
|
||||
DEF_ATTR_TREE_LIST (ATTR_FORMAT_ARG_1, ATTR_FORMAT_ARG, ATTR_LIST_1, ATTR_NULL)
|
||||
DEF_ATTR_TREE_LIST (ATTR_FORMAT_ARG_2, ATTR_FORMAT_ARG, ATTR_LIST_2, ATTR_NULL)
|
||||
/* Construct a tree for a format_arg attribute. */
|
||||
#define DEF_FORMAT_ARG_ATTRIBUTE(FA) \
|
||||
DEF_ATTR_TREE_LIST (CONCAT2 (ATTR_FORMAT_ARG_,FA), ATTR_FORMAT_ARG, \
|
||||
CONCAT2 (ATTR_LIST_,FA), CONCAT2 (ATTR_NONNULL_,FA))
|
||||
DEF_FORMAT_ARG_ATTRIBUTE(1)
|
||||
DEF_FORMAT_ARG_ATTRIBUTE(2)
|
||||
#undef DEF_FORMAT_ARG_ATTRIBUTE
|
||||
|
||||
/* Define an attribute for a function, along with the IDENTIFIER_NODE. */
|
||||
#define DEF_FN_ATTR_IDENT(NAME, ATTRS, PREDICATE) \
|
||||
@ -121,24 +150,10 @@ DEF_ATTR_TREE_LIST (ATTR_FORMAT_ARG_2, ATTR_FORMAT_ARG, ATTR_LIST_2, ATTR_NULL)
|
||||
-ffreestanding, these default attributes are disabled, and must be
|
||||
specified manually if desired. */
|
||||
|
||||
/* __builtin functions should be checked unconditionally, even with
|
||||
-ffreestanding. */
|
||||
DEF_FN_ATTR_IDENT (__builtin_printf, ATTR_FORMAT_PRINTF_1_2, true)
|
||||
DEF_FN_ATTR_IDENT (__builtin_fprintf, ATTR_FORMAT_PRINTF_2_3, true)
|
||||
DEF_FN_ATTR_IDENT (__builtin_printf_unlocked, ATTR_FORMAT_PRINTF_1_2, true)
|
||||
DEF_FN_ATTR_IDENT (__builtin_fprintf_unlocked, ATTR_FORMAT_PRINTF_2_3, true)
|
||||
|
||||
/* Functions from ISO/IEC 9899:1990. */
|
||||
#define DEF_C89_ATTR(NAME, ATTRS) DEF_FN_ATTR_IDENT (NAME, ATTRS, flag_hosted)
|
||||
DEF_C89_ATTR (printf, ATTR_FORMAT_PRINTF_1_2)
|
||||
DEF_C89_ATTR (fprintf, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_C89_ATTR (sprintf, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_C89_ATTR (scanf, ATTR_FORMAT_SCANF_1_2)
|
||||
DEF_C89_ATTR (fscanf, ATTR_FORMAT_SCANF_2_3)
|
||||
DEF_C89_ATTR (sscanf, ATTR_FORMAT_SCANF_2_3)
|
||||
DEF_C89_ATTR (vprintf, ATTR_FORMAT_PRINTF_1_0)
|
||||
DEF_C89_ATTR (vfprintf, ATTR_FORMAT_PRINTF_2_0)
|
||||
DEF_C89_ATTR (vsprintf, ATTR_FORMAT_PRINTF_2_0)
|
||||
DEF_C89_ATTR (strftime, ATTR_FORMAT_STRFTIME_3_0)
|
||||
#undef DEF_C89_ATTR
|
||||
|
||||
@ -147,11 +162,7 @@ DEF_C89_ATTR (strftime, ATTR_FORMAT_STRFTIME_3_0)
|
||||
DEF_FN_ATTR_IDENT (NAME, ATTRS, \
|
||||
(flag_hosted \
|
||||
&& (flag_isoc99 || flag_noniso_default_format_attributes)))
|
||||
DEF_C99_ATTR (snprintf, ATTR_FORMAT_PRINTF_3_4)
|
||||
DEF_C99_ATTR (vsnprintf, ATTR_FORMAT_PRINTF_3_0)
|
||||
DEF_C99_ATTR (vscanf, ATTR_FORMAT_SCANF_1_0)
|
||||
DEF_C99_ATTR (vfscanf, ATTR_FORMAT_SCANF_2_0)
|
||||
DEF_C99_ATTR (vsscanf, ATTR_FORMAT_SCANF_2_0)
|
||||
#undef DEF_C99_ATTR
|
||||
|
||||
/* Functions not in any version of ISO C. */
|
||||
@ -164,8 +175,5 @@ DEF_EXT_ATTR (dgettext, ATTR_FORMAT_ARG_2)
|
||||
DEF_EXT_ATTR (dcgettext, ATTR_FORMAT_ARG_2)
|
||||
/* X/Open strfmon function. */
|
||||
DEF_EXT_ATTR (strfmon, ATTR_FORMAT_STRFMON_3_4)
|
||||
/* Glibc thread-unsafe stdio functions. */
|
||||
DEF_EXT_ATTR (printf_unlocked, ATTR_FORMAT_PRINTF_1_2)
|
||||
DEF_EXT_ATTR (fprintf_unlocked, ATTR_FORMAT_PRINTF_2_3)
|
||||
#undef DEF_EXT_ATTR
|
||||
#undef DEF_FN_ATTR_IDENT
|
||||
|
@ -40,6 +40,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
DEF_FUNCTION_TYPE_VAR_0 (ENUM, RETURN)
|
||||
DEF_FUNCTION_TYPE_VAR_1 (ENUM, RETURN, ARG1)
|
||||
DEF_FUNCTION_TYPE_VAR_2 (ENUM, RETURN, ARG1, ARG2)
|
||||
DEF_FUNCTION_TYPE_VAR_3 (ENUM, RETURN, ARG1, ARG2, ARG3)
|
||||
|
||||
Similar, but for function types that take variable arguments.
|
||||
For example:
|
||||
@ -73,13 +74,10 @@ DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONG_DOUBLE, complex_long_double_type_node)
|
||||
|
||||
DEF_PRIMITIVE_TYPE (BT_PTR, ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_CONST_PTR, const_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_TRAD_PTR, traditional_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_TRAD_CONST_PTR, traditional_cptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_PTRMODE, type_for_mode (ptr_mode, 0))
|
||||
DEF_PRIMITIVE_TYPE (BT_PTRMODE, (*lang_hooks.types.type_for_mode)(ptr_mode, 0))
|
||||
DEF_PRIMITIVE_TYPE (BT_SIZE, size_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_STRING, string_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_CONST_STRING, const_string_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_LEN, traditional_len_type_node)
|
||||
|
||||
DEF_PRIMITIVE_TYPE (BT_VALIST_REF, va_list_ref_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node)
|
||||
@ -87,6 +85,9 @@ DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_VOID, BT_VOID)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_UNSIGNED, BT_UNSIGNED)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_LONG_DOUBLE, BT_LONG_DOUBLE)
|
||||
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONG, BT_LONG, BT_LONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGLONG, BT_LONGLONG, BT_LONGLONG)
|
||||
@ -112,11 +113,15 @@ DEF_FUNCTION_TYPE_1 (BT_FN_PTR_SIZE, BT_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_INT, BT_INT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_PTR, BT_INT, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTR, BT_VOID, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LEN_CONST_STRING, BT_LEN, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_SIZE_CONST_STRING, BT_SIZE, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_CONST_STRING, BT_INT, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_PTR, BT_PTR, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VALIST_REF, BT_VOID, BT_VALIST_REF)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_INT, BT_VOID, BT_INT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_STRING, BT_FLOAT, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE_CONST_STRING,
|
||||
BT_LONG_DOUBLE, BT_CONST_STRING)
|
||||
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_INT, BT_VOID, BT_PTR, BT_INT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_STRING_CONST_STRING,
|
||||
@ -141,25 +146,32 @@ DEF_FUNCTION_TYPE_2 (BT_FN_LONG_LONG_LONG,
|
||||
BT_LONG, BT_LONG, BT_LONG)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_PTR_CONST_STRING,
|
||||
BT_INT, BT_PTR, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_TRAD_PTR_LEN,
|
||||
BT_VOID, BT_TRAD_PTR, BT_LEN)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_SIZE,
|
||||
BT_VOID, BT_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_STRING_CONST_STRING_SIZE,
|
||||
BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_SIZE,
|
||||
BT_INT, BT_CONST_STRING, BT_CONST_STRING, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE,
|
||||
BT_TRAD_PTR, BT_PTR, BT_CONST_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_CONST_PTR_SIZE,
|
||||
BT_PTR, BT_PTR, BT_CONST_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
|
||||
BT_INT, BT_CONST_PTR, BT_CONST_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_TRAD_PTR_PTR_INT_SIZE,
|
||||
BT_TRAD_PTR, BT_PTR, BT_INT, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_TRAD_CONST_PTR_TRAD_CONST_PTR_LEN,
|
||||
BT_INT, BT_TRAD_CONST_PTR, BT_TRAD_CONST_PTR, BT_LEN)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_INT_INT, BT_VOID, BT_PTR, BT_INT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_INT_SIZE,
|
||||
BT_PTR, BT_PTR, BT_INT, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_INT_INT,
|
||||
BT_VOID, BT_PTR, BT_INT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_STRING, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_CONST_STRING, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
|
||||
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
|
||||
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
|
||||
@ -174,6 +186,13 @@ DEF_FUNCTION_TYPE_VAR_1 (BT_FN_INT_CONST_STRING_VAR,
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_PTR_CONST_STRING_VAR,
|
||||
BT_INT, BT_PTR, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_STRING_CONST_STRING_VAR,
|
||||
BT_INT, BT_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_CONST_STRING_CONST_STRING_VAR,
|
||||
BT_INT, BT_CONST_STRING, BT_CONST_STRING)
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_3 (BT_FN_INT_STRING_SIZE_CONST_STRING_VAR,
|
||||
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING)
|
||||
|
||||
DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
|
||||
|
@ -22,7 +22,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
/* Before including this file, you should define a macro:
|
||||
|
||||
DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
|
||||
FALLBACK_P, NONANSI_P)
|
||||
FALLBACK_P, NONANSI_P, ATTRS)
|
||||
|
||||
This macro will be called once for each builtin function. The
|
||||
ENUM will be of type `enum built_in_function', and will indicate
|
||||
@ -50,15 +50,18 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
If NONANSI_P is true, then the non-`__builtin_' variant is not an
|
||||
ANSI/ISO library function, and so we should pretend it does not
|
||||
exist when compiling in ANSI conformant mode. */
|
||||
exist when compiling in ANSI conformant mode.
|
||||
|
||||
ATTRs is an attribute list as defined in builtin-attrs.def that
|
||||
describes the attributes of this builtin function. */
|
||||
|
||||
/* A GCC builtin (like __builtin_saveregs) is provided by the
|
||||
compiler, but does not correspond to a function in the standard
|
||||
library. */
|
||||
#undef DEF_GCC_BUILTIN
|
||||
#define DEF_GCC_BUILTIN(ENUM, NAME, TYPE) \
|
||||
#define DEF_GCC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
||||
false, false, false)
|
||||
false, false, false, ATTRS)
|
||||
|
||||
|
||||
/* A fallback builtin is a builtin (like __builtin_puts) that falls
|
||||
@ -66,9 +69,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
for which we should not introduce the non-`__builtin' variant of
|
||||
the name. */
|
||||
#undef DEF_FALLBACK_BUILTIN
|
||||
#define DEF_FALLBACK_BUILTIN(ENUM, NAME, TYPE) \
|
||||
#define DEF_FALLBACK_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, false)
|
||||
false, true, false, ATTRS)
|
||||
|
||||
/* Like DEF_FALLBACK_BUILTIN, except that the function is not one that
|
||||
is specified by ANSI/ISO C. So, when we're being fully conformant
|
||||
@ -77,74 +80,76 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#undef DEF_EXT_FALLBACK_BUILTIN
|
||||
#define DEF_EXT_FALLBACK_BUILTIN(ENUM, NAME, TYPE) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, true)
|
||||
false, true, true, ATTR_NOTHROW_LIST)
|
||||
|
||||
/* A library builtin (like __builtin_strchr) is a builtin equivalent
|
||||
of an ANSI/ISO standard library function. In addition to the
|
||||
`__builtin' version, we will create an ordinary version (e.g,
|
||||
`strchr') as well. If we cannot compute the answer using the
|
||||
builtin function, we will fall back to the standard library
|
||||
version. */
|
||||
version. */
|
||||
#undef DEF_LIB_BUILTIN
|
||||
#define DEF_LIB_BUILTIN(ENUM, NAME, TYPE) \
|
||||
#define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, false)
|
||||
true, true, false, ATTRS)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that a call to the builtin should
|
||||
never fall back to the library version. */
|
||||
#undef DEF_LIB_ALWAYS_BUILTIN
|
||||
#define DEF_LIB_ALWAYS_BUILTIN(ENUM, NAME, TYPE) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, false, true)
|
||||
true, false, true, ATTR_CONST_NOTHROW_LIST)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is not one that is
|
||||
specified by ANSI/ISO C. So, when we're being fully conformant we
|
||||
ignore the version of these builtins that does not begin with
|
||||
__builtin. */
|
||||
#undef DEF_EXT_LIB_BUILTIN
|
||||
#define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE) \
|
||||
#define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, true)
|
||||
true, true, true, ATTRS)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||
the standard in C99 or above. */
|
||||
#undef DEF_C99_BUILTIN
|
||||
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE) \
|
||||
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, !flag_isoc99, true)
|
||||
true, true, !flag_isoc99, ATTRS)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is expanded in the
|
||||
front-end. */
|
||||
#undef DEF_FRONT_END_LIB_BUILTIN
|
||||
#define DEF_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE) \
|
||||
#define DEF_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE, \
|
||||
true, true, false)
|
||||
true, true, false, ATTRS)
|
||||
|
||||
/* Like DEF_FRONT_END_LIB_BUILTIN, except that the function is not one
|
||||
that is specified by ANSI/ISO C. So, when we're being fully
|
||||
conformant we ignore the version of these builtins that does not
|
||||
begin with __builtin. */
|
||||
#undef DEF_EXT_FRONT_END_LIB_BUILTIN
|
||||
#define DEF_EXT_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE) \
|
||||
#define DEF_EXT_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE, \
|
||||
true, true, true)
|
||||
true, true, true, ATTRS)
|
||||
|
||||
/* A built-in that is not currently used. */
|
||||
#undef DEF_UNUSED_BUILTIN
|
||||
#define DEF_UNUSED_BUILTIN(X) \
|
||||
DEF_BUILTIN (X, (const char *) NULL, NOT_BUILT_IN, BT_LAST, \
|
||||
BT_LAST, false, false, false)
|
||||
BT_LAST, false, false, false, ATTR_NOTHROW_LIST)
|
||||
|
||||
/* If SMALL_STACK is defined, then `alloca' is only defined in its
|
||||
`__builtin' form. */
|
||||
#if SMALL_STACK
|
||||
DEF_FALLBACK_BUILTIN(BUILT_IN_ALLOCA,
|
||||
"__builtin_alloca",
|
||||
BT_FN_PTR_SIZE)
|
||||
BT_FN_PTR_SIZE,
|
||||
ATTR_MALLOC_NOTHROW_LIST)
|
||||
#else
|
||||
DEF_EXT_LIB_BUILTIN(BUILT_IN_ALLOCA,
|
||||
"__builtin_alloca",
|
||||
BT_FN_PTR_SIZE)
|
||||
BT_FN_PTR_SIZE,
|
||||
ATTR_MALLOC_NOTHROW_LIST)
|
||||
#endif
|
||||
|
||||
DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_ABS,
|
||||
@ -166,37 +171,48 @@ DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_FABSL,
|
||||
|
||||
DEF_C99_BUILTIN(BUILT_IN_LLABS,
|
||||
"__builtin_llabs",
|
||||
BT_FN_LONGLONG_LONGLONG)
|
||||
BT_FN_LONGLONG_LONGLONG,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_IMAXABS,
|
||||
"__builtin_imaxabs",
|
||||
BT_FN_INTMAX_INTMAX)
|
||||
BT_FN_INTMAX_INTMAX,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CONJ,
|
||||
"__builtin_conj",
|
||||
BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE)
|
||||
BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CONJF,
|
||||
"__builtin_conjf",
|
||||
BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT)
|
||||
BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CONJL,
|
||||
"__builtin_conjl",
|
||||
BT_FN_COMPLEX_LONG_DOUBLE_COMPLEX_LONG_DOUBLE)
|
||||
BT_FN_COMPLEX_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CREAL,
|
||||
"__builtin_creal",
|
||||
BT_FN_DOUBLE_COMPLEX_DOUBLE)
|
||||
BT_FN_DOUBLE_COMPLEX_DOUBLE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CREALF,
|
||||
"__builtin_crealf",
|
||||
BT_FN_FLOAT_COMPLEX_FLOAT)
|
||||
BT_FN_FLOAT_COMPLEX_FLOAT,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CREALL,
|
||||
"__builtin_creall",
|
||||
BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE)
|
||||
BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CIMAG,
|
||||
"__builtin_cimag",
|
||||
BT_FN_DOUBLE_COMPLEX_DOUBLE)
|
||||
BT_FN_DOUBLE_COMPLEX_DOUBLE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CIMAGF,
|
||||
"__builtin_cimagf",
|
||||
BT_FN_FLOAT_COMPLEX_FLOAT)
|
||||
BT_FN_FLOAT_COMPLEX_FLOAT,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_CIMAGL,
|
||||
"__builtin_cimagl",
|
||||
BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE)
|
||||
BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_UNUSED_BUILTIN(BUILT_IN_DIV)
|
||||
DEF_UNUSED_BUILTIN(BUILT_IN_LDIV)
|
||||
@ -211,184 +227,383 @@ DEF_UNUSED_BUILTIN(BUILT_IN_FREM)
|
||||
DEF_BUILTIN (BUILT_IN_BZERO,
|
||||
"__builtin_bzero",
|
||||
BUILT_IN_NORMAL,
|
||||
BT_FN_VOID_TRAD_PTR_LEN,
|
||||
BT_FN_VOID_PTR_SIZE,
|
||||
BT_FN_VOID_VAR,
|
||||
true, true, true)
|
||||
true, true, true,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_BUILTIN (BUILT_IN_BCMP,
|
||||
"__builtin_bcmp",
|
||||
BUILT_IN_NORMAL,
|
||||
BT_FN_INT_TRAD_CONST_PTR_TRAD_CONST_PTR_LEN,
|
||||
BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
|
||||
BT_FN_INT_VAR,
|
||||
true, true, true)
|
||||
true, true, true,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
|
||||
DEF_EXT_LIB_BUILTIN(BUILT_IN_FFS,
|
||||
"__builtin_ffs",
|
||||
BT_FN_INT_INT)
|
||||
BT_FN_INT_INT,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN(BUILT_IN_INDEX,
|
||||
"__builtin_index",
|
||||
BT_FN_STRING_CONST_STRING_INT)
|
||||
BT_FN_STRING_CONST_STRING_INT,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN(BUILT_IN_RINDEX,
|
||||
"__builtin_rindex",
|
||||
BT_FN_STRING_CONST_STRING_INT)
|
||||
BT_FN_STRING_CONST_STRING_INT,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
|
||||
DEF_LIB_BUILTIN(BUILT_IN_MEMCPY,
|
||||
"__builtin_memcpy",
|
||||
BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE)
|
||||
BT_FN_PTR_PTR_CONST_PTR_SIZE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_MEMCMP,
|
||||
"__builtin_memcmp",
|
||||
BT_FN_INT_CONST_PTR_CONST_PTR_SIZE)
|
||||
BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_MEMSET,
|
||||
"__builtin_memset",
|
||||
BT_FN_TRAD_PTR_PTR_INT_SIZE)
|
||||
BT_FN_PTR_PTR_INT_SIZE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRCAT,
|
||||
"__builtin_strcat",
|
||||
BT_FN_STRING_STRING_CONST_STRING)
|
||||
BT_FN_STRING_STRING_CONST_STRING,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRNCAT,
|
||||
"__builtin_strncat",
|
||||
BT_FN_STRING_STRING_CONST_STRING_SIZE)
|
||||
BT_FN_STRING_STRING_CONST_STRING_SIZE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRCPY,
|
||||
"__builtin_strcpy",
|
||||
BT_FN_STRING_STRING_CONST_STRING)
|
||||
BT_FN_STRING_STRING_CONST_STRING,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRNCPY,
|
||||
"__builtin_strncpy",
|
||||
BT_FN_STRING_STRING_CONST_STRING_SIZE)
|
||||
BT_FN_STRING_STRING_CONST_STRING_SIZE,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRCMP,
|
||||
"__builtin_strcmp",
|
||||
BT_FN_INT_CONST_STRING_CONST_STRING)
|
||||
BT_FN_INT_CONST_STRING_CONST_STRING,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRNCMP,
|
||||
"__builtin_strncmp",
|
||||
BT_FN_INT_CONST_STRING_CONST_STRING_SIZE)
|
||||
BT_FN_INT_CONST_STRING_CONST_STRING_SIZE,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRLEN,
|
||||
"__builtin_strlen",
|
||||
BT_FN_LEN_CONST_STRING)
|
||||
BT_FN_SIZE_CONST_STRING,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRSTR,
|
||||
"__builtin_strstr",
|
||||
BT_FN_STRING_CONST_STRING_CONST_STRING)
|
||||
BT_FN_STRING_CONST_STRING_CONST_STRING,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRPBRK,
|
||||
"__builtin_strpbrk",
|
||||
BT_FN_STRING_CONST_STRING_CONST_STRING)
|
||||
BT_FN_STRING_CONST_STRING_CONST_STRING,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRSPN,
|
||||
"__builtin_strspn",
|
||||
BT_FN_SIZE_CONST_STRING_CONST_STRING)
|
||||
BT_FN_SIZE_CONST_STRING_CONST_STRING,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRCSPN,
|
||||
"__builtin_strcspn",
|
||||
BT_FN_SIZE_CONST_STRING_CONST_STRING)
|
||||
BT_FN_SIZE_CONST_STRING_CONST_STRING,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRCHR,
|
||||
"__builtin_strchr",
|
||||
BT_FN_STRING_CONST_STRING_INT)
|
||||
BT_FN_STRING_CONST_STRING_INT,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_STRRCHR,
|
||||
"__builtin_strrchr",
|
||||
BT_FN_STRING_CONST_STRING_INT)
|
||||
BT_FN_STRING_CONST_STRING_INT,
|
||||
ATTR_PURE_NOTHROW_LIST)
|
||||
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SQRT,
|
||||
"__builtin_sqrt",
|
||||
BT_FN_DOUBLE_DOUBLE)
|
||||
BT_FN_DOUBLE_DOUBLE,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SIN,
|
||||
"__builtin_sin",
|
||||
BT_FN_DOUBLE_DOUBLE)
|
||||
BT_FN_DOUBLE_DOUBLE,
|
||||
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_COS,
|
||||
"__builtin_cos",
|
||||
BT_FN_DOUBLE_DOUBLE)
|
||||
BT_FN_DOUBLE_DOUBLE,
|
||||
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_EXP,
|
||||
"__builtin_exp",
|
||||
BT_FN_DOUBLE_DOUBLE,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
DEF_LIB_BUILTIN(BUILT_IN_LOG,
|
||||
"__builtin_log",
|
||||
BT_FN_DOUBLE_DOUBLE,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SQRTF,
|
||||
"__builtin_sqrtf",
|
||||
BT_FN_FLOAT_FLOAT)
|
||||
BT_FN_FLOAT_FLOAT,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SINF,
|
||||
"__builtin_sinf",
|
||||
BT_FN_FLOAT_FLOAT)
|
||||
BT_FN_FLOAT_FLOAT,
|
||||
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_COSF,
|
||||
"__builtin_cosf",
|
||||
BT_FN_FLOAT_FLOAT)
|
||||
BT_FN_FLOAT_FLOAT,
|
||||
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_EXPF,
|
||||
"__builtin_expf",
|
||||
BT_FN_FLOAT_FLOAT,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
DEF_LIB_BUILTIN(BUILT_IN_LOGF,
|
||||
"__builtin_logf",
|
||||
BT_FN_FLOAT_FLOAT,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SQRTL,
|
||||
"__builtin_sqrtl",
|
||||
BT_FN_LONG_DOUBLE_LONG_DOUBLE)
|
||||
BT_FN_LONG_DOUBLE_LONG_DOUBLE,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SINL,
|
||||
"__builtin_sinl",
|
||||
BT_FN_LONG_DOUBLE_LONG_DOUBLE)
|
||||
BT_FN_LONG_DOUBLE_LONG_DOUBLE,
|
||||
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_COSL,
|
||||
"__builtin_cosl",
|
||||
BT_FN_LONG_DOUBLE_LONG_DOUBLE)
|
||||
BT_FN_LONG_DOUBLE_LONG_DOUBLE,
|
||||
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_EXPL,
|
||||
"__builtin_expl",
|
||||
BT_FN_LONG_DOUBLE_LONG_DOUBLE,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
DEF_LIB_BUILTIN(BUILT_IN_LOGL,
|
||||
"__builtin_logl",
|
||||
BT_FN_LONG_DOUBLE_LONG_DOUBLE,
|
||||
flag_errno_math ? ATTR_NOTHROW_LIST
|
||||
: (flag_unsafe_math_optimizations
|
||||
? ATTR_CONST_NOTHROW_LIST
|
||||
: ATTR_PURE_NOTHROW_LIST))
|
||||
|
||||
DEF_UNUSED_BUILTIN(BUILT_IN_GETEXP)
|
||||
DEF_UNUSED_BUILTIN(BUILT_IN_GETMAN)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_INF,
|
||||
"__builtin_inf",
|
||||
BT_FN_DOUBLE,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_INFF,
|
||||
"__builtin_inff",
|
||||
BT_FN_FLOAT,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_INFL,
|
||||
"__builtin_infl",
|
||||
BT_FN_LONG_DOUBLE,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
|
||||
DEF_GCC_BUILTIN(BUILT_IN_HUGE_VAL,
|
||||
"__builtin_huge_val",
|
||||
BT_FN_DOUBLE,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_HUGE_VALF,
|
||||
"__builtin_huge_valf",
|
||||
BT_FN_FLOAT,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_HUGE_VALL,
|
||||
"__builtin_huge_vall",
|
||||
BT_FN_LONG_DOUBLE,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
|
||||
DEF_LIB_BUILTIN(BUILT_IN_NAN,
|
||||
"__builtin_nan",
|
||||
BT_FN_DOUBLE_CONST_STRING,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_NANF,
|
||||
"__builtin_nanf",
|
||||
BT_FN_FLOAT_CONST_STRING,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_NANL,
|
||||
"__builtin_nanl",
|
||||
BT_FN_LONG_DOUBLE_CONST_STRING,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
|
||||
DEF_LIB_BUILTIN(BUILT_IN_NANS,
|
||||
"__builtin_nans",
|
||||
BT_FN_DOUBLE_CONST_STRING,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_NANSF,
|
||||
"__builtin_nansf",
|
||||
BT_FN_FLOAT_CONST_STRING,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_NANSL,
|
||||
"__builtin_nansl",
|
||||
BT_FN_LONG_DOUBLE_CONST_STRING,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
|
||||
DEF_GCC_BUILTIN(BUILT_IN_SAVEREGS,
|
||||
"__builtin_saveregs",
|
||||
BT_FN_PTR_VAR)
|
||||
BT_FN_PTR_VAR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_CLASSIFY_TYPE,
|
||||
"__builtin_classify_type",
|
||||
BT_FN_INT_VAR)
|
||||
BT_FN_INT_VAR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_NEXT_ARG,
|
||||
"__builtin_next_arg",
|
||||
BT_FN_PTR_VAR)
|
||||
BT_FN_PTR_VAR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_ARGS_INFO,
|
||||
"__builtin_args_info",
|
||||
BT_FN_INT_INT)
|
||||
BT_FN_INT_INT,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_CONSTANT_P,
|
||||
"__builtin_constant_p",
|
||||
BT_FN_INT_VAR)
|
||||
BT_FN_INT_VAR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_FRAME_ADDRESS,
|
||||
"__builtin_frame_address",
|
||||
BT_FN_PTR_UNSIGNED)
|
||||
BT_FN_PTR_UNSIGNED,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_RETURN_ADDRESS,
|
||||
"__builtin_return_address",
|
||||
BT_FN_PTR_UNSIGNED)
|
||||
BT_FN_PTR_UNSIGNED,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_AGGREGATE_INCOMING_ADDRESS,
|
||||
"__builtin_aggregate_incoming_address",
|
||||
BT_FN_PTR_VAR)
|
||||
BT_FN_PTR_VAR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_APPLY_ARGS,
|
||||
"__builtin_apply_args",
|
||||
BT_FN_PTR_VAR)
|
||||
BT_FN_PTR_VAR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_APPLY,
|
||||
"__builtin_apply",
|
||||
BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE)
|
||||
BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_RETURN,
|
||||
"__builtin_return",
|
||||
BT_FN_VOID_PTR)
|
||||
BT_FN_VOID_PTR,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_SETJMP,
|
||||
"__builtin_setjmp",
|
||||
BT_FN_INT_PTR)
|
||||
BT_FN_INT_PTR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_LONGJMP,
|
||||
"__builtin_longjmp",
|
||||
BT_FN_VOID_PTR_INT)
|
||||
BT_FN_VOID_PTR_INT,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_TRAP,
|
||||
"__builtin_trap",
|
||||
BT_FN_VOID)
|
||||
BT_FN_VOID,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_PREFETCH,
|
||||
"__builtin_prefetch",
|
||||
BT_FN_VOID_CONST_PTR_VAR)
|
||||
BT_FN_VOID_CONST_PTR_VAR,
|
||||
ATTR_NULL)
|
||||
|
||||
/* stdio.h builtins (without FILE *). */
|
||||
|
||||
/* Stdio builtins. */
|
||||
DEF_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR,
|
||||
"__builtin_putchar",
|
||||
BT_FN_INT_INT)
|
||||
DEF_FALLBACK_BUILTIN(BUILT_IN_PUTS,
|
||||
"__builtin_puts",
|
||||
BT_FN_INT_CONST_STRING)
|
||||
DEF_FRONT_END_LIB_BUILTIN(BUILT_IN_PRINTF,
|
||||
"__builtin_printf",
|
||||
BT_FN_INT_CONST_STRING_VAR)
|
||||
DEF_FALLBACK_BUILTIN(BUILT_IN_FPUTC,
|
||||
"__builtin_fputc",
|
||||
BT_FN_INT_INT_PTR)
|
||||
BT_FN_INT_CONST_STRING_VAR,
|
||||
ATTR_FORMAT_PRINTF_1_2)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_PUTCHAR,
|
||||
"__builtin_putchar",
|
||||
BT_FN_INT_INT,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_PUTS,
|
||||
"__builtin_puts",
|
||||
BT_FN_INT_CONST_STRING,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN(BUILT_IN_SNPRINTF,
|
||||
"__builtin_snprintf",
|
||||
BT_FN_INT_STRING_SIZE_CONST_STRING_VAR,
|
||||
ATTR_FORMAT_PRINTF_3_4)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SPRINTF,
|
||||
"__builtin_sprintf",
|
||||
BT_FN_INT_STRING_CONST_STRING_VAR,
|
||||
ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SCANF,
|
||||
"__builtin_scanf",
|
||||
BT_FN_INT_CONST_STRING_VAR,
|
||||
ATTR_FORMAT_SCANF_1_2)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_SSCANF,
|
||||
"__builtin_sscanf",
|
||||
BT_FN_INT_CONST_STRING_CONST_STRING_VAR,
|
||||
ATTR_FORMAT_SCANF_2_3)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_VPRINTF,
|
||||
"__builtin_vprintf",
|
||||
BT_FN_INT_CONST_STRING_VALIST_ARG,
|
||||
ATTR_FORMAT_PRINTF_1_0)
|
||||
DEF_C99_BUILTIN(BUILT_IN_VSCANF,
|
||||
"__builtin_vscanf",
|
||||
BT_FN_INT_CONST_STRING_VALIST_ARG,
|
||||
ATTR_FORMAT_SCANF_1_0)
|
||||
DEF_C99_BUILTIN(BUILT_IN_VSSCANF,
|
||||
"__builtin_vsscanf",
|
||||
BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
|
||||
ATTR_FORMAT_SCANF_2_0)
|
||||
DEF_C99_BUILTIN(BUILT_IN_VSNPRINTF,
|
||||
"__builtin_vsnprintf",
|
||||
BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
|
||||
ATTR_FORMAT_PRINTF_3_0)
|
||||
DEF_LIB_BUILTIN(BUILT_IN_VSPRINTF,
|
||||
"__builtin_vsprintf",
|
||||
BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
|
||||
ATTR_FORMAT_PRINTF_2_0)
|
||||
|
||||
|
||||
/* stdio.h builtins (with FILE *). */
|
||||
|
||||
/* Declare the __builtin_ style with arguments and the regular style
|
||||
without them. We rely on stdio.h to supply the arguments for the
|
||||
regular style declaration since we had to use void* instead of
|
||||
FILE* in the __builtin_ prototype supplied here. */
|
||||
|
||||
DEF_FALLBACK_BUILTIN(BUILT_IN_FPUTC,
|
||||
"__builtin_fputc",
|
||||
BT_FN_INT_INT_PTR,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_BUILTIN (BUILT_IN_FPUTS,
|
||||
"__builtin_fputs",
|
||||
BUILT_IN_NORMAL,
|
||||
BT_FN_INT_CONST_STRING_PTR,
|
||||
BT_FN_INT_VAR,
|
||||
true, true, false)
|
||||
true, true, false, ATTR_NOTHROW_LIST)
|
||||
DEF_FALLBACK_BUILTIN(BUILT_IN_FWRITE,
|
||||
"__builtin_fwrite",
|
||||
BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR)
|
||||
BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
|
||||
ATTR_NOTHROW_LIST)
|
||||
DEF_FRONT_END_LIB_BUILTIN(BUILT_IN_FPRINTF,
|
||||
"__builtin_fprintf",
|
||||
BT_FN_INT_PTR_CONST_STRING_VAR)
|
||||
BT_FN_INT_PTR_CONST_STRING_VAR,
|
||||
ATTR_FORMAT_PRINTF_2_3)
|
||||
|
||||
/* Stdio unlocked builtins. */
|
||||
/* stdio unlocked builtins (without FILE *). */
|
||||
|
||||
DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR_UNLOCKED,
|
||||
"__builtin_putchar_unlocked",
|
||||
@ -398,91 +613,152 @@ DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_PUTS_UNLOCKED,
|
||||
BT_FN_INT_CONST_STRING)
|
||||
DEF_EXT_FRONT_END_LIB_BUILTIN(BUILT_IN_PRINTF_UNLOCKED,
|
||||
"__builtin_printf_unlocked",
|
||||
BT_FN_INT_CONST_STRING_VAR)
|
||||
DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_FPUTC_UNLOCKED,
|
||||
"__builtin_fputc_unlocked",
|
||||
BT_FN_INT_INT_PTR)
|
||||
BT_FN_INT_CONST_STRING_VAR,
|
||||
ATTR_FORMAT_PRINTF_1_2)
|
||||
|
||||
/* stdio unlocked builtins (with FILE *). */
|
||||
|
||||
/* Declare the __builtin_ style with arguments and the regular style
|
||||
without them. We rely on stdio.h to supply the arguments for the
|
||||
regular style declaration since we had to use void* instead of
|
||||
FILE* in the __builtin_ prototype supplied here. */
|
||||
|
||||
DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_FPUTC_UNLOCKED,
|
||||
"__builtin_fputc_unlocked",
|
||||
BT_FN_INT_INT_PTR)
|
||||
DEF_BUILTIN (BUILT_IN_FPUTS_UNLOCKED,
|
||||
"__builtin_fputs_unlocked",
|
||||
BUILT_IN_NORMAL,
|
||||
BT_FN_INT_CONST_STRING_PTR,
|
||||
BT_FN_INT_VAR,
|
||||
true, true, true)
|
||||
true, true, true, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_FWRITE_UNLOCKED,
|
||||
"__builtin_fwrite_unlocked",
|
||||
BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR)
|
||||
DEF_EXT_FRONT_END_LIB_BUILTIN(BUILT_IN_FPRINTF_UNLOCKED,
|
||||
"__builtin_fprintf_unlocked",
|
||||
BT_FN_INT_PTR_CONST_STRING_VAR)
|
||||
BT_FN_INT_PTR_CONST_STRING_VAR,
|
||||
ATTR_FORMAT_PRINTF_2_3)
|
||||
|
||||
/* ISO C99 floating point unordered comparisons. */
|
||||
DEF_GCC_BUILTIN(BUILT_IN_ISGREATER,
|
||||
"__builtin_isgreater",
|
||||
BT_FN_INT_VAR)
|
||||
BT_FN_INT_VAR,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_ISGREATEREQUAL,
|
||||
"__builtin_isgreaterequal",
|
||||
BT_FN_INT_VAR)
|
||||
BT_FN_INT_VAR,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_ISLESS,
|
||||
"__builtin_isless",
|
||||
BT_FN_INT_VAR)
|
||||
BT_FN_INT_VAR,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_ISLESSEQUAL,
|
||||
"__builtin_islessequal",
|
||||
BT_FN_INT_VAR)
|
||||
BT_FN_INT_VAR,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_ISLESSGREATER,
|
||||
"__builtin_islessgreater",
|
||||
BT_FN_INT_VAR)
|
||||
BT_FN_INT_VAR,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_ISUNORDERED,
|
||||
"__builtin_isunordered",
|
||||
BT_FN_INT_VAR)
|
||||
BT_FN_INT_VAR,
|
||||
ATTR_CONST_NOTHROW_LIST)
|
||||
|
||||
/* Various hooks for the DWARF 2 __throw routine. */
|
||||
DEF_GCC_BUILTIN(BUILT_IN_UNWIND_INIT,
|
||||
"__builtin_unwind_init",
|
||||
BT_FN_VOID)
|
||||
BT_FN_VOID,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_DWARF_CFA,
|
||||
"__builtin_dwarf_cfa",
|
||||
BT_FN_PTR)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_DWARF_FP_REGNUM,
|
||||
"__builtin_dwarf_fp_regnum",
|
||||
BT_FN_UNSIGNED)
|
||||
BT_FN_PTR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_DWARF_SP_COLUMN,
|
||||
"__builtin_dwarf_sp_column",
|
||||
BT_FN_UNSIGNED,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_INIT_DWARF_REG_SIZES,
|
||||
"__builtin_init_dwarf_reg_size_table",
|
||||
BT_FN_VOID_PTR)
|
||||
BT_FN_VOID_PTR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_FROB_RETURN_ADDR,
|
||||
"__builtin_frob_return_addr",
|
||||
BT_FN_PTR_PTR)
|
||||
BT_FN_PTR_PTR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_EXTRACT_RETURN_ADDR,
|
||||
"__builtin_extract_return_addr",
|
||||
BT_FN_PTR_PTR)
|
||||
BT_FN_PTR_PTR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_EH_RETURN,
|
||||
"__builtin_eh_return",
|
||||
BT_FN_VOID_PTRMODE_PTR)
|
||||
BT_FN_VOID_PTRMODE_PTR,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_EH_RETURN_DATA_REGNO,
|
||||
"__builtin_eh_return_data_regno",
|
||||
BT_FN_INT_INT)
|
||||
BT_FN_INT_INT,
|
||||
ATTR_NULL)
|
||||
|
||||
DEF_GCC_BUILTIN(BUILT_IN_VARARGS_START,
|
||||
"__builtin_varargs_start",
|
||||
BT_FN_VOID_VALIST_REF)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_STDARG_START,
|
||||
/* Variable argument list (stdarg.h) support */
|
||||
DEF_GCC_BUILTIN(BUILT_IN_VA_START,
|
||||
"__builtin_va_start",
|
||||
BT_FN_VOID_VALIST_REF_VAR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_STDARG_START, /* backward compat */
|
||||
"__builtin_stdarg_start",
|
||||
BT_FN_VOID_VALIST_REF_VAR)
|
||||
BT_FN_VOID_VALIST_REF_VAR,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_VA_END,
|
||||
"__builtin_va_end",
|
||||
BT_FN_VOID_VALIST_REF)
|
||||
BT_FN_VOID_VALIST_REF,
|
||||
ATTR_NULL)
|
||||
DEF_GCC_BUILTIN(BUILT_IN_VA_COPY,
|
||||
"__builtin_va_copy",
|
||||
BT_FN_VOID_VALIST_REF_VALIST_ARG)
|
||||
BT_FN_VOID_VALIST_REF_VALIST_ARG,
|
||||
ATTR_NULL)
|
||||
|
||||
DEF_GCC_BUILTIN(BUILT_IN_EXPECT,
|
||||
"__builtin_expect",
|
||||
BT_FN_LONG_LONG_LONG)
|
||||
BT_FN_LONG_LONG_LONG,
|
||||
ATTR_NULL)
|
||||
|
||||
/* C++ extensions */
|
||||
DEF_UNUSED_BUILTIN(BUILT_IN_NEW)
|
||||
DEF_UNUSED_BUILTIN(BUILT_IN_VEC_NEW)
|
||||
DEF_UNUSED_BUILTIN(BUILT_IN_DELETE)
|
||||
DEF_UNUSED_BUILTIN(BUILT_IN_VEC_DELETE)
|
||||
|
||||
/* Declare abort, exit, _exit and _Exit */
|
||||
DEF_BUILTIN (BUILT_IN_ABORT,
|
||||
"__builtin_abort",
|
||||
NOT_BUILT_IN,
|
||||
BT_FN_VOID,
|
||||
BT_FN_VOID,
|
||||
1, 0, 0,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
|
||||
DEF_BUILTIN (BUILT_IN_EXIT,
|
||||
"__builtin_exit",
|
||||
NOT_BUILT_IN,
|
||||
BT_FN_VOID_INT,
|
||||
BT_FN_VOID_INT,
|
||||
1, 0, 0,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
|
||||
DEF_BUILTIN (BUILT_IN__EXIT,
|
||||
"__builtin__exit",
|
||||
NOT_BUILT_IN,
|
||||
BT_FN_VOID_INT,
|
||||
BT_FN_VOID_INT,
|
||||
1, 0, 1,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
|
||||
DEF_BUILTIN (BUILT_IN__EXIT2,
|
||||
"__builtin__Exit",
|
||||
NOT_BUILT_IN,
|
||||
BT_FN_VOID_INT,
|
||||
BT_FN_VOID_INT,
|
||||
1, 0, !flag_isoc99,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
|
||||
|
@ -188,7 +188,7 @@ gen_formal_list_for_type (fntype, style)
|
||||
/* For the generation of an ANSI prototype for a function definition, we have
|
||||
to look at the formal parameter list of the function's own "type" to
|
||||
determine if the function's formal parameter list should end with an
|
||||
ellipsis. Given a tree node, the following function will return non-zero
|
||||
ellipsis. Given a tree node, the following function will return nonzero
|
||||
if the "function type" parameter list should end with an ellipsis. */
|
||||
|
||||
static int
|
||||
@ -471,7 +471,7 @@ gen_type (ret_val, t, style)
|
||||
|
||||
The given entity may be either a variable or a function.
|
||||
|
||||
If the "is_func_definition" parameter is non-zero, assume that the thing
|
||||
If the "is_func_definition" parameter is nonzero, assume that the thing
|
||||
we are generating a declaration for is a FUNCTION_DECL node which is
|
||||
associated with a function definition. In this case, we can assume that
|
||||
an attached list of DECL nodes for function formal arguments is present. */
|
||||
|
@ -23,7 +23,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
/* Tree nodes relevant to both C and C++. These were originally in
|
||||
cp-tree.def in the cp subdir. */
|
||||
cp-tree.def in the cp subdir. */
|
||||
|
||||
/* A node to remember a source position. */
|
||||
DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
|
||||
@ -33,55 +33,55 @@ DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1)
|
||||
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)
|
||||
|
||||
/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to
|
||||
obtain the expression. */
|
||||
obtain the expression. */
|
||||
DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a brace-enclosed block. The operand is
|
||||
COMPOUND_BODY. */
|
||||
COMPOUND_BODY. */
|
||||
DEFTREECODE (COMPOUND_STMT, "compound_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a local declaration. The operand is
|
||||
DECL_STMT_DECL. */
|
||||
DECL_STMT_DECL. */
|
||||
DEFTREECODE (DECL_STMT, "decl_stmt", 'e', 1)
|
||||
|
||||
/* Represents an 'if' statement. The operands are IF_COND,
|
||||
THEN_CLAUSE, and ELSE_CLAUSE, respectively. */
|
||||
THEN_CLAUSE, and ELSE_CLAUSE, respectively. */
|
||||
DEFTREECODE (IF_STMT, "if_stmt", 'e', 3)
|
||||
|
||||
/* Used to represent a `for' statement. The operands are
|
||||
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
|
||||
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
|
||||
DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4)
|
||||
|
||||
/* Used to represent a 'while' statement. The operands are WHILE_COND
|
||||
and WHILE_BODY, respectively. */
|
||||
and WHILE_BODY, respectively. */
|
||||
DEFTREECODE (WHILE_STMT, "while_stmt", 'e', 2)
|
||||
|
||||
/* Used to represent a 'do' statement. The operands are DO_BODY and
|
||||
DO_COND, respectively. */
|
||||
DO_COND, respectively. */
|
||||
DEFTREECODE (DO_STMT, "do_stmt", 'e', 2)
|
||||
|
||||
/* Used to represent a 'return' statement. The operand is
|
||||
RETURN_EXPR. */
|
||||
RETURN_STMT_EXPR. */
|
||||
DEFTREECODE (RETURN_STMT, "return_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a 'break' statement. */
|
||||
/* Used to represent a 'break' statement. */
|
||||
DEFTREECODE (BREAK_STMT, "break_stmt", 'e', 0)
|
||||
|
||||
/* Used to represent a 'continue' statement. */
|
||||
/* Used to represent a 'continue' statement. */
|
||||
DEFTREECODE (CONTINUE_STMT, "continue_stmt", 'e', 0)
|
||||
|
||||
/* Used to represent a 'switch' statement. The operands are
|
||||
SWITCH_COND, SWITCH_BODY and SWITCH_TYPE, respectively. */
|
||||
SWITCH_COND, SWITCH_BODY and SWITCH_TYPE, respectively. */
|
||||
DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 3)
|
||||
|
||||
/* Used to represent a 'goto' statement. The operand is GOTO_DESTINATION. */
|
||||
/* Used to represent a 'goto' statement. The operand is GOTO_DESTINATION. */
|
||||
DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a 'label' statement. The operand is a LABEL_DECL
|
||||
and can be obtained through the macro LABEL_STMT_LABEL. */
|
||||
and can be obtained through the macro LABEL_STMT_LABEL. */
|
||||
DEFTREECODE (LABEL_STMT, "label_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent an inline assembly statement. */
|
||||
/* Used to represent an inline assembly statement. */
|
||||
DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
|
||||
|
||||
/* A SCOPE_STMT marks the beginning or end of a scope. If
|
||||
|
26
contrib/gcc/c-config-lang.in
Normal file
26
contrib/gcc/c-config-lang.in
Normal file
@ -0,0 +1,26 @@
|
||||
# Top level configure fragment for GNU C - C language.
|
||||
# Copyright (C) 1994, 1995, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
#This file is part of GCC.
|
||||
|
||||
#GCC is free software; you can redistribute it and/or modify
|
||||
#it under the terms of the GNU General Public License as published by
|
||||
#the Free Software Foundation; either version 2, or (at your option)
|
||||
#any later version.
|
||||
|
||||
#GCC is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
|
||||
#You should have received a copy of the GNU General Public License
|
||||
#along with GCC; see the file COPYING. If not, write to
|
||||
#the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
#Boston, MA 02111-1307, USA.
|
||||
|
||||
# This file c-config-lang.c is a special pseudo config-lang.in file
|
||||
# for the language C. It has limited use, specifically to record the
|
||||
# files used by C that have garbage collection GTY macros in them
|
||||
# which therefore need to be scanned by gengtype.c.
|
||||
|
||||
gtfiles="\$(srcdir)/c-lang.c \$(srcdir)/c-parse.in \$(srcdir)/c-tree.h \$(srcdir)/c-decl.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c \$(srcdir)/c-objc-common.c"
|
@ -1,5 +1,5 @@
|
||||
/* Language-level data type conversion for GNU C.
|
||||
Copyright (C) 1987, 1988, 1991, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987, 1988, 1991, 1998, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -29,6 +29,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "tree.h"
|
||||
#include "flags.h"
|
||||
#include "convert.h"
|
||||
#include "c-common.h"
|
||||
#include "toplev.h"
|
||||
|
||||
/* Change of width--truncation and extension of integers or reals--
|
||||
@ -42,7 +43,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
Here is a list of all the functions that assume that widening and
|
||||
narrowing is always done with a NOP_EXPR:
|
||||
In convert.c, convert_to_integer.
|
||||
In c-typeck.c, build_binary_op (boolean ops), and truthvalue_conversion.
|
||||
In c-typeck.c, build_binary_op (boolean ops), and
|
||||
c_common_truthvalue_conversion.
|
||||
In expr.c: expand_expr, for operands of a MULT_EXPR.
|
||||
In fold-const.c: fold.
|
||||
In tree.c: get_narrower and get_unwidened. */
|
||||
@ -90,9 +92,9 @@ convert (type, expr)
|
||||
return fold (convert_to_integer (type, e));
|
||||
if (code == BOOLEAN_TYPE)
|
||||
{
|
||||
tree t = truthvalue_conversion (expr);
|
||||
/* If truthvalue_conversion returns a NOP_EXPR, we must fold it here
|
||||
to avoid infinite recursion between fold () and convert (). */
|
||||
tree t = c_common_truthvalue_conversion (expr);
|
||||
/* If it returns a NOP_EXPR, we must fold it here to avoid
|
||||
infinite recursion between fold () and convert (). */
|
||||
if (TREE_CODE (t) == NOP_EXPR)
|
||||
return fold (build1 (NOP_EXPR, type, TREE_OPERAND (t, 0)));
|
||||
else
|
||||
|
196
contrib/gcc/c-dump.c
Normal file
196
contrib/gcc/c-dump.c
Normal file
@ -0,0 +1,196 @@
|
||||
/* Tree-dumping functionality for C-family languages.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Written by Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "tree.h"
|
||||
#include "c-tree.h"
|
||||
#include "tree-dump.h"
|
||||
|
||||
/* Dump information common to statements from STMT. */
|
||||
|
||||
void
|
||||
dump_stmt (di, t)
|
||||
dump_info_p di;
|
||||
tree t;
|
||||
{
|
||||
dump_int (di, "line", STMT_LINENO (t));
|
||||
}
|
||||
|
||||
/* Dump the next statement after STMT. */
|
||||
|
||||
void
|
||||
dump_next_stmt (di, t)
|
||||
dump_info_p di;
|
||||
tree t;
|
||||
{
|
||||
dump_child ("next", TREE_CHAIN (t));
|
||||
}
|
||||
|
||||
/* Dump any C-specific tree codes and attributes of common codes. */
|
||||
|
||||
int
|
||||
c_dump_tree (dump_info, t)
|
||||
void *dump_info;
|
||||
tree t;
|
||||
{
|
||||
enum tree_code code;
|
||||
dump_info_p di = (dump_info_p) dump_info;
|
||||
|
||||
/* Figure out what kind of node this is. */
|
||||
code = TREE_CODE (t);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case FIELD_DECL:
|
||||
if (DECL_C_BIT_FIELD (t))
|
||||
dump_string (di, "bitfield");
|
||||
break;
|
||||
|
||||
case ASM_STMT:
|
||||
dump_stmt (di, t);
|
||||
if (ASM_VOLATILE_P (t))
|
||||
dump_string (di, "volatile");
|
||||
dump_child ("strg", ASM_STRING (t));
|
||||
dump_child ("outs", ASM_OUTPUTS (t));
|
||||
dump_child ("ins", ASM_INPUTS (t));
|
||||
dump_child ("clbr", ASM_CLOBBERS (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case BREAK_STMT:
|
||||
case CONTINUE_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case CASE_LABEL:
|
||||
/* Note that a case label is not like other statements; there is
|
||||
no way to get the line-number of a case label. */
|
||||
dump_child ("low", CASE_LOW (t));
|
||||
dump_child ("high", CASE_HIGH (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case CLEANUP_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("decl", CLEANUP_DECL (t));
|
||||
dump_child ("expr", CLEANUP_EXPR (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case COMPOUND_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("body", COMPOUND_BODY (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case DECL_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("decl", DECL_STMT_DECL (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case DO_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("body", DO_BODY (t));
|
||||
dump_child ("cond", DO_COND (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case EXPR_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("expr", EXPR_STMT_EXPR (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case FOR_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("init", FOR_INIT_STMT (t));
|
||||
dump_child ("cond", FOR_COND (t));
|
||||
dump_child ("expr", FOR_EXPR (t));
|
||||
dump_child ("body", FOR_BODY (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case GOTO_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("dest", GOTO_DESTINATION (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case IF_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("cond", IF_COND (t));
|
||||
dump_child ("then", THEN_CLAUSE (t));
|
||||
dump_child ("else", ELSE_CLAUSE (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case LABEL_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("labl", LABEL_STMT_LABEL (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case RETURN_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("expr", RETURN_STMT_EXPR (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case SWITCH_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("cond", SWITCH_COND (t));
|
||||
dump_child ("body", SWITCH_BODY (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case WHILE_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("cond", WHILE_COND (t));
|
||||
dump_child ("body", WHILE_BODY (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case SCOPE_STMT:
|
||||
dump_stmt (di, t);
|
||||
if (SCOPE_BEGIN_P (t))
|
||||
dump_string (di, "begn");
|
||||
else
|
||||
dump_string (di, "end");
|
||||
if (SCOPE_NULLIFIED_P (t))
|
||||
dump_string (di, "null");
|
||||
if (!SCOPE_NO_CLEANUPS_P (t))
|
||||
dump_string (di, "clnp");
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case STMT_EXPR:
|
||||
dump_child ("stmt", STMT_EXPR_STMT (t));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -32,13 +32,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
void
|
||||
pedwarn_c99 VPARAMS ((const char *msgid, ...))
|
||||
{
|
||||
diagnostic_context dc;
|
||||
|
||||
diagnostic_info diagnostic;
|
||||
VA_OPEN (ap, msgid);
|
||||
VA_FIXEDARG (ap, const char *, msgid);
|
||||
|
||||
set_diagnostic_context (&dc, msgid, &ap, input_filename, lineno,
|
||||
!flag_isoc99 || !flag_pedantic_errors);
|
||||
report_diagnostic (&dc);
|
||||
diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
|
||||
flag_isoc99 ? pedantic_error_kind () : DK_WARNING);
|
||||
report_diagnostic (&diagnostic);
|
||||
VA_CLOSE (ap);
|
||||
}
|
||||
|
@ -24,10 +24,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "system.h"
|
||||
#include "tree.h"
|
||||
#include "c-tree.h"
|
||||
#include "c-common.h"
|
||||
#include "ggc.h"
|
||||
#include "langhooks.h"
|
||||
#include "langhooks-def.h"
|
||||
|
||||
static const char *c_init PARAMS ((const char *));
|
||||
static void c_init_options PARAMS ((void));
|
||||
|
||||
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
|
||||
@ -35,25 +36,51 @@ static void c_init_options PARAMS ((void));
|
||||
#undef LANG_HOOKS_NAME
|
||||
#define LANG_HOOKS_NAME "GNU C"
|
||||
#undef LANG_HOOKS_INIT
|
||||
#define LANG_HOOKS_INIT c_init
|
||||
#define LANG_HOOKS_INIT c_objc_common_init
|
||||
#undef LANG_HOOKS_FINISH
|
||||
#define LANG_HOOKS_FINISH c_common_finish
|
||||
#undef LANG_HOOKS_INIT_OPTIONS
|
||||
#define LANG_HOOKS_INIT_OPTIONS c_init_options
|
||||
#undef LANG_HOOKS_DECODE_OPTION
|
||||
#define LANG_HOOKS_DECODE_OPTION c_decode_option
|
||||
#define LANG_HOOKS_DECODE_OPTION c_common_decode_option
|
||||
#undef LANG_HOOKS_POST_OPTIONS
|
||||
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
|
||||
#undef LANG_HOOKS_GET_ALIAS_SET
|
||||
#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
|
||||
#undef LANG_HOOKS_SAFE_FROM_P
|
||||
#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
|
||||
#undef LANG_HOOKS_EXPAND_EXPR
|
||||
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
|
||||
#undef LANG_HOOKS_MARK_ADDRESSABLE
|
||||
#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
|
||||
#undef LANG_HOOKS_PARSE_FILE
|
||||
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
|
||||
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
|
||||
#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion
|
||||
#undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES
|
||||
#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES c_insert_default_attributes
|
||||
#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
|
||||
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
|
||||
#undef LANG_HOOKS_UNSAFE_FOR_REEVAL
|
||||
#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
|
||||
#undef LANG_HOOKS_STATICP
|
||||
#define LANG_HOOKS_STATICP c_staticp
|
||||
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
|
||||
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
|
||||
#undef LANG_HOOKS_PRINT_IDENTIFIER
|
||||
#define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier
|
||||
#undef LANG_HOOKS_SET_YYDEBUG
|
||||
#define LANG_HOOKS_SET_YYDEBUG c_set_yydebug
|
||||
#undef LANG_HOOKS_FUNCTION_ENTER_NESTED
|
||||
#define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
|
||||
#undef LANG_HOOKS_FUNCTION_LEAVE_NESTED
|
||||
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
|
||||
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
|
||||
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
|
||||
|
||||
/* Attribute hooks. */
|
||||
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table
|
||||
#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table
|
||||
|
||||
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
|
||||
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
|
||||
@ -67,25 +94,70 @@ static void c_init_options PARAMS ((void));
|
||||
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
|
||||
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
|
||||
c_convert_parm_for_inlining
|
||||
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
|
||||
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree
|
||||
|
||||
#undef LANG_HOOKS_TYPE_FOR_MODE
|
||||
#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
|
||||
#undef LANG_HOOKS_TYPE_FOR_SIZE
|
||||
#define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size
|
||||
#undef LANG_HOOKS_SIGNED_TYPE
|
||||
#define LANG_HOOKS_SIGNED_TYPE c_common_signed_type
|
||||
#undef LANG_HOOKS_UNSIGNED_TYPE
|
||||
#define LANG_HOOKS_UNSIGNED_TYPE c_common_unsigned_type
|
||||
#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
|
||||
#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE c_common_signed_or_unsigned_type
|
||||
#undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR
|
||||
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR c_incomplete_type_error
|
||||
#undef LANG_HOOKS_TYPE_PROMOTES_TO
|
||||
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
|
||||
|
||||
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
|
||||
|
||||
/* Each front end provides its own. */
|
||||
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
/* Tree code classes. */
|
||||
|
||||
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
|
||||
|
||||
const char tree_code_type[] = {
|
||||
#include "tree.def"
|
||||
'x',
|
||||
#include "c-common.def"
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
/* Table indexed by tree code giving number of expression
|
||||
operands beyond the fixed part of the node structure.
|
||||
Not used for types or decls. */
|
||||
|
||||
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
|
||||
|
||||
const unsigned char tree_code_length[] = {
|
||||
#include "tree.def"
|
||||
0,
|
||||
#include "c-common.def"
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
/* Names of tree components.
|
||||
Used for printing out the tree and error messages. */
|
||||
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
|
||||
|
||||
const char *const tree_code_name[] = {
|
||||
#include "tree.def"
|
||||
"@@dummy",
|
||||
#include "c-common.def"
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
static void
|
||||
c_init_options ()
|
||||
{
|
||||
c_common_init_options (clk_c);
|
||||
}
|
||||
|
||||
static const char *
|
||||
c_init (filename)
|
||||
const char *filename;
|
||||
{
|
||||
return c_objc_common_init (filename);
|
||||
}
|
||||
|
||||
/* Used by c-lex.c, but only for objc. */
|
||||
|
||||
tree
|
||||
@ -102,14 +174,21 @@ is_class_name (arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
tree
|
||||
objc_is_id (arg)
|
||||
tree arg ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
maybe_objc_check_decl (decl)
|
||||
objc_check_decl (decl)
|
||||
tree decl ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
maybe_objc_comptypes (lhs, rhs, reflexive)
|
||||
objc_comptypes (lhs, rhs, reflexive)
|
||||
tree lhs ATTRIBUTE_UNUSED;
|
||||
tree rhs ATTRIBUTE_UNUSED;
|
||||
int reflexive ATTRIBUTE_UNUSED;
|
||||
@ -118,13 +197,7 @@ maybe_objc_comptypes (lhs, rhs, reflexive)
|
||||
}
|
||||
|
||||
tree
|
||||
maybe_building_objc_message_expr ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
recognize_objc_keyword ()
|
||||
objc_message_selector ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -143,3 +216,5 @@ finish_file ()
|
||||
{
|
||||
c_objc_common_finish_file ();
|
||||
}
|
||||
|
||||
#include "gtype-c.h"
|
||||
|
@ -33,14 +33,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "tree-inline.h"
|
||||
#include "varray.h"
|
||||
#include "ggc.h"
|
||||
#include "langhooks.h"
|
||||
#include "target.h"
|
||||
|
||||
static int c_tree_printer PARAMS ((output_buffer *));
|
||||
static bool c_tree_printer PARAMS ((output_buffer *, text_info *));
|
||||
static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
|
||||
static void expand_deferred_fns PARAMS ((void));
|
||||
static tree start_cdtor PARAMS ((int));
|
||||
static void finish_cdtor PARAMS ((tree));
|
||||
|
||||
static varray_type deferred_fns;
|
||||
static GTY(()) varray_type deferred_fns;
|
||||
|
||||
int
|
||||
c_missing_noreturn_ok_p (decl)
|
||||
@ -90,7 +92,7 @@ inline_forbidden_p (nodep, walk_subtrees, fn)
|
||||
{
|
||||
/* We cannot inline functions that take a variable number of
|
||||
arguments. */
|
||||
case BUILT_IN_VARARGS_START:
|
||||
case BUILT_IN_VA_START:
|
||||
case BUILT_IN_STDARG_START:
|
||||
#if 0
|
||||
/* Functions that need information about the address of the
|
||||
@ -119,7 +121,7 @@ inline_forbidden_p (nodep, walk_subtrees, fn)
|
||||
/* We will not inline a function which uses computed goto. The
|
||||
addresses of its local labels, which may be tucked into
|
||||
global storage, are of course not constant across
|
||||
instantiations, which causes unexpected behaviour. */
|
||||
instantiations, which causes unexpected behavior. */
|
||||
if (TREE_CODE (t) != LABEL_DECL)
|
||||
return node;
|
||||
|
||||
@ -167,17 +169,11 @@ c_cannot_inline_tree_fn (fnp)
|
||||
|
||||
/* Don't auto-inline anything that might not be bound within
|
||||
this unit of translation. */
|
||||
if (!DECL_DECLARED_INLINE_P (fn) && flag_pic && TREE_PUBLIC (fn))
|
||||
{
|
||||
DECL_UNINLINABLE (fn) = 1;
|
||||
return 1;
|
||||
}
|
||||
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
|
||||
goto cannot_inline;
|
||||
|
||||
if (! function_attribute_inlinable_p (fn))
|
||||
{
|
||||
DECL_UNINLINABLE (fn) = 1;
|
||||
return 1;
|
||||
}
|
||||
goto cannot_inline;
|
||||
|
||||
/* If a function has pending sizes, we must not defer its
|
||||
compilation, and we can't inline it as a tree. */
|
||||
@ -187,10 +183,7 @@ c_cannot_inline_tree_fn (fnp)
|
||||
put_pending_sizes (t);
|
||||
|
||||
if (t)
|
||||
{
|
||||
DECL_UNINLINABLE (fn) = 1;
|
||||
return 1;
|
||||
}
|
||||
goto cannot_inline;
|
||||
}
|
||||
|
||||
if (DECL_CONTEXT (fn))
|
||||
@ -198,10 +191,7 @@ c_cannot_inline_tree_fn (fnp)
|
||||
/* If a nested function has pending sizes, we may have already
|
||||
saved them. */
|
||||
if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
|
||||
{
|
||||
DECL_UNINLINABLE (fn) = 1;
|
||||
return 1;
|
||||
}
|
||||
goto cannot_inline;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -223,13 +213,29 @@ c_cannot_inline_tree_fn (fnp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
|
||||
{
|
||||
DECL_UNINLINABLE (fn) = 1;
|
||||
return 1;
|
||||
}
|
||||
if (walk_tree_without_duplicates
|
||||
(&DECL_SAVED_TREE (fn), inline_forbidden_p, fn))
|
||||
goto cannot_inline;
|
||||
|
||||
return 0;
|
||||
|
||||
cannot_inline:
|
||||
DECL_UNINLINABLE (fn) = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Called from check_global_declarations. */
|
||||
|
||||
bool
|
||||
c_warn_unused_global_decl (decl)
|
||||
tree decl;
|
||||
{
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
|
||||
return false;
|
||||
if (DECL_IN_SYSTEM_HEADER (decl))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Initialization common to C and Objective-C front ends. */
|
||||
@ -240,13 +246,9 @@ c_objc_common_init (filename)
|
||||
c_init_decl_processing ();
|
||||
|
||||
filename = c_common_init (filename);
|
||||
if (filename == NULL)
|
||||
return NULL;
|
||||
|
||||
add_c_tree_codes ();
|
||||
|
||||
save_lang_status = &push_c_function_context;
|
||||
restore_lang_status = &pop_c_function_context;
|
||||
mark_lang_status = &mark_c_function_context;
|
||||
lang_expand_expr = c_expand_expr;
|
||||
lang_expand_decl_stmt = c_expand_decl_stmt;
|
||||
|
||||
/* These were not defined in the Objective-C front end, but I'm
|
||||
@ -266,7 +268,6 @@ c_objc_common_init (filename)
|
||||
}
|
||||
|
||||
VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
|
||||
ggc_add_tree_varray_root (&deferred_fns, 1);
|
||||
|
||||
return filename;
|
||||
}
|
||||
@ -304,7 +305,7 @@ expand_deferred_fns ()
|
||||
}
|
||||
}
|
||||
|
||||
VARRAY_FREE (deferred_fns);
|
||||
deferred_fns = 0;
|
||||
}
|
||||
|
||||
static tree
|
||||
@ -403,26 +404,29 @@ c_objc_common_finish_file ()
|
||||
by the C++ front-end.
|
||||
Please notice when called, the `%' part was already skipped by the
|
||||
diagnostic machinery. */
|
||||
static int
|
||||
c_tree_printer (buffer)
|
||||
static bool
|
||||
c_tree_printer (buffer, text)
|
||||
output_buffer *buffer;
|
||||
text_info *text;
|
||||
{
|
||||
tree t = va_arg (output_buffer_format_args (buffer), tree);
|
||||
tree t = va_arg (*text->args_ptr, tree);
|
||||
|
||||
switch (*output_buffer_text_cursor (buffer))
|
||||
switch (*text->format_spec)
|
||||
{
|
||||
case 'D':
|
||||
case 'F':
|
||||
case 'T':
|
||||
{
|
||||
const char *n = DECL_NAME (t)
|
||||
? (*decl_printable_name) (t, 2)
|
||||
? (*lang_hooks.decl_printable_name) (t, 2)
|
||||
: "({anonymous})";
|
||||
output_add_string (buffer, n);
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#include "gt-c-objc-common.h"
|
||||
|
1799
contrib/gcc/c-opts.c
Normal file
1799
contrib/gcc/c-opts.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "flags.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "c-lex.h"
|
||||
#include "c-common.h"
|
||||
#include "output.h"
|
||||
#include "tm_p.h"
|
||||
@ -37,11 +36,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#define GCC_BAD(msgid) do { warning (msgid); return; } while (0)
|
||||
#define GCC_BAD2(msgid, arg) do { warning (msgid, arg); return; } while (0)
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK
|
||||
static void handle_pragma_pack PARAMS ((cpp_reader *));
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
typedef struct align_stack
|
||||
typedef struct align_stack GTY(())
|
||||
{
|
||||
int alignment;
|
||||
unsigned int num_pushes;
|
||||
@ -49,8 +44,12 @@ typedef struct align_stack
|
||||
struct align_stack * prev;
|
||||
} align_stack;
|
||||
|
||||
static struct align_stack * alignment_stack = NULL;
|
||||
static GTY(()) struct align_stack * alignment_stack;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK
|
||||
static void handle_pragma_pack PARAMS ((cpp_reader *));
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
/* If we have a "global" #pragma pack(<n>) in effect when the first
|
||||
#pragma pack(push,<n>) is encountered, this stores the value of
|
||||
maximum_field_alignment in effect. When the final pop_alignment()
|
||||
@ -62,7 +61,6 @@ static int default_alignment;
|
||||
|
||||
static void push_alignment PARAMS ((int, tree));
|
||||
static void pop_alignment PARAMS ((tree));
|
||||
static void mark_align_stack PARAMS ((void *));
|
||||
|
||||
/* Push an alignment value onto the stack. */
|
||||
static void
|
||||
@ -76,7 +74,7 @@ push_alignment (alignment, id)
|
||||
{
|
||||
align_stack * entry;
|
||||
|
||||
entry = (align_stack *) xmalloc (sizeof (* entry));
|
||||
entry = (align_stack *) ggc_alloc (sizeof (* entry));
|
||||
|
||||
entry->alignment = alignment;
|
||||
entry->num_pushes = 1;
|
||||
@ -138,24 +136,9 @@ pop_alignment (id)
|
||||
else
|
||||
maximum_field_alignment = entry->alignment;
|
||||
|
||||
free (alignment_stack);
|
||||
|
||||
alignment_stack = entry;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mark_align_stack (p)
|
||||
void *p;
|
||||
{
|
||||
align_stack *a = *(align_stack **) p;
|
||||
|
||||
while (a)
|
||||
{
|
||||
ggc_mark_tree (a->id);
|
||||
a = a->prev;
|
||||
}
|
||||
}
|
||||
#else /* not HANDLE_PRAGMA_PACK_PUSH_POP */
|
||||
#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
|
||||
#define push_alignment(ID, N) \
|
||||
@ -273,12 +256,12 @@ handle_pragma_pack (dummy)
|
||||
}
|
||||
#endif /* HANDLE_PRAGMA_PACK */
|
||||
|
||||
static GTY(()) tree pending_weaks;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
static void apply_pragma_weak PARAMS ((tree, tree));
|
||||
static void handle_pragma_weak PARAMS ((cpp_reader *));
|
||||
|
||||
static tree pending_weaks;
|
||||
|
||||
static void
|
||||
apply_pragma_weak (decl, value)
|
||||
tree decl, value;
|
||||
@ -364,11 +347,11 @@ maybe_apply_pragma_weak (decl)
|
||||
}
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
|
||||
static GTY(()) tree pending_redefine_extname;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
|
||||
static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
|
||||
|
||||
static tree pending_redefine_extname;
|
||||
|
||||
/* #pragma redefined_extname oldname newname */
|
||||
static void
|
||||
handle_pragma_redefine_extname (dummy)
|
||||
@ -400,16 +383,23 @@ handle_pragma_redefine_extname (dummy)
|
||||
SET_DECL_ASSEMBLER_NAME (decl, newname);
|
||||
}
|
||||
else
|
||||
pending_redefine_extname
|
||||
= tree_cons (oldname, newname, pending_redefine_extname);
|
||||
add_to_renaming_pragma_list(oldname, newname);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
add_to_renaming_pragma_list (oldname, newname)
|
||||
tree oldname, newname;
|
||||
{
|
||||
pending_redefine_extname
|
||||
= tree_cons (oldname, newname, pending_redefine_extname);
|
||||
}
|
||||
|
||||
static GTY(()) tree pragma_extern_prefix;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
|
||||
|
||||
static tree pragma_extern_prefix;
|
||||
|
||||
/* #pragma extern_prefix "prefix" */
|
||||
static void
|
||||
handle_pragma_extern_prefix (dummy)
|
||||
@ -457,11 +447,10 @@ maybe_apply_renaming_pragma (decl, asmname)
|
||||
{
|
||||
const char *oldasmname = IDENTIFIER_POINTER (oldname) + 1;
|
||||
if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldasmname) != 0)
|
||||
warning ("asm declaration conficts with previous rename");
|
||||
warning ("asm declaration conflicts with previous rename");
|
||||
asmname = build_string (strlen (oldasmname), oldasmname);
|
||||
}
|
||||
|
||||
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
|
||||
{
|
||||
tree *p, t;
|
||||
|
||||
@ -477,7 +466,6 @@ maybe_apply_renaming_pragma (decl, asmname)
|
||||
return build_string (strlen (newname), newname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
if (pragma_extern_prefix && !asmname)
|
||||
@ -501,25 +489,19 @@ init_pragma ()
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
|
||||
ggc_add_tree_root (&pending_weaks, 1);
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
|
||||
cpp_register_pragma (parse_in, 0, "redefine_extname",
|
||||
handle_pragma_redefine_extname);
|
||||
ggc_add_tree_root (&pending_redefine_extname, 1);
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
cpp_register_pragma (parse_in, 0, "extern_prefix",
|
||||
handle_pragma_extern_prefix);
|
||||
ggc_add_tree_root (&pragma_extern_prefix, 1);
|
||||
#endif
|
||||
|
||||
#ifdef REGISTER_TARGET_PRAGMAS
|
||||
REGISTER_TARGET_PRAGMAS (parse_in);
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
ggc_add_root (&alignment_stack, 1, sizeof(alignment_stack),
|
||||
mark_align_stack);
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "gt-c-pragma.h"
|
||||
|
@ -22,6 +22,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#ifndef GCC_C_PRAGMA_H
|
||||
#define GCC_C_PRAGMA_H
|
||||
|
||||
/* Cause the `yydebug' variable to be defined. */
|
||||
#define YYDEBUG 1
|
||||
extern int yydebug;
|
||||
|
||||
struct cpp_reader;
|
||||
extern struct cpp_reader* parse_in;
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
#if ((defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)) \
|
||||
|| defined (ASM_WEAKEN_DECL))
|
||||
@ -55,5 +62,8 @@ extern void cpp_register_pragma PARAMS ((cpp_reader *,
|
||||
|
||||
extern void maybe_apply_pragma_weak PARAMS ((tree));
|
||||
extern tree maybe_apply_renaming_pragma PARAMS ((tree, tree));
|
||||
extern void add_to_renaming_pragma_list PARAMS ((tree, tree));
|
||||
|
||||
extern int c_lex PARAMS ((tree *));
|
||||
|
||||
#endif /* GCC_C_PRAGMA_H */
|
||||
|
1493
contrib/gcc/c-pretty-print.c
Normal file
1493
contrib/gcc/c-pretty-print.c
Normal file
File diff suppressed because it is too large
Load Diff
165
contrib/gcc/c-pretty-print.h
Normal file
165
contrib/gcc/c-pretty-print.h
Normal file
@ -0,0 +1,165 @@
|
||||
/* Various declarations for the C and C++ pretty-printers.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#ifndef GCC_C_PRETTY_PRINTER
|
||||
#define GCC_C_PRETTY_PRINTER
|
||||
|
||||
#include "tree.h"
|
||||
#include "c-common.h"
|
||||
#include "pretty-print.h"
|
||||
|
||||
|
||||
/* The data type used to bundle information necessary for pretty-printing
|
||||
a C or C++ entity. */
|
||||
typedef struct c_pretty_print_info *c_pretty_printer;
|
||||
|
||||
/* The type of a C pretty-printer 'member' function. */
|
||||
typedef void (*c_pretty_print_fn) PARAMS ((c_pretty_printer, tree));
|
||||
|
||||
struct c_pretty_print_info
|
||||
{
|
||||
struct pretty_print_info base;
|
||||
/* Points to the first element of an array of offset-list.
|
||||
Not used yet. */
|
||||
int *offset_list;
|
||||
|
||||
/* These must be overriden by each of the C and C++ front-end to
|
||||
reflect their understanding of syntatic productions when they differ. */
|
||||
c_pretty_print_fn declaration;
|
||||
c_pretty_print_fn declaration_specifiers;
|
||||
c_pretty_print_fn type_specifier;
|
||||
c_pretty_print_fn declarator;
|
||||
c_pretty_print_fn direct_declarator;
|
||||
c_pretty_print_fn parameter_declaration;
|
||||
c_pretty_print_fn type_id;
|
||||
|
||||
c_pretty_print_fn statement;
|
||||
|
||||
c_pretty_print_fn primary_expression;
|
||||
c_pretty_print_fn postfix_expression;
|
||||
c_pretty_print_fn unary_expression;
|
||||
c_pretty_print_fn initializer;
|
||||
c_pretty_print_fn multiplicative_expression;
|
||||
c_pretty_print_fn conditional_expression;
|
||||
c_pretty_print_fn assignment_expression;
|
||||
};
|
||||
|
||||
#define pp_c_left_paren(PPI) \
|
||||
do { \
|
||||
pp_left_paren (PPI); \
|
||||
pp_c_base (PPI)->base.padding = pp_none; \
|
||||
} while (0)
|
||||
#define pp_c_right_paren(PPI) \
|
||||
do { \
|
||||
pp_right_paren (PPI); \
|
||||
pp_c_base (PPI)->base.padding = pp_none; \
|
||||
} while (0)
|
||||
#define pp_c_left_bracket(PPI) \
|
||||
do { \
|
||||
pp_left_bracket (PPI); \
|
||||
pp_c_base (PPI)->base.padding = pp_none; \
|
||||
} while (0)
|
||||
#define pp_c_right_bracket(PPI) \
|
||||
do { \
|
||||
pp_right_bracket (PPI); \
|
||||
pp_c_base (PPI)->base.padding = pp_none; \
|
||||
} while (0)
|
||||
#define pp_c_whitespace(PPI) \
|
||||
do { \
|
||||
pp_whitespace (PPI); \
|
||||
pp_c_base (PPI)->base.padding = pp_none; \
|
||||
} while (0)
|
||||
#define pp_c_maybe_whitespace(PPI) \
|
||||
do { \
|
||||
if (pp_c_base (PPI)->base.padding != pp_none) \
|
||||
pp_c_whitespace (PPI); \
|
||||
} while (0)
|
||||
#define pp_c_identifier(PPI, ID) \
|
||||
do { \
|
||||
pp_c_maybe_whitespace (PPI); \
|
||||
pp_identifier (PPI, ID); \
|
||||
pp_c_base (PPI)->base.padding = pp_before; \
|
||||
} while (0)
|
||||
|
||||
#define pp_c_tree_identifier(PPI, ID) \
|
||||
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
|
||||
|
||||
/* Returns the 'output_buffer *' associated with a PRETTY-PRINTER, the latter
|
||||
being something digestible by pp_c_base. */
|
||||
#define pp_buffer(PPI) pp_c_base (PPI)->base.buffer
|
||||
|
||||
#define pp_declaration(PPI, T) \
|
||||
(*pp_c_base (PPI)->declaration) (pp_c_base (PPI), T)
|
||||
#define pp_declaration_specifiers(PPI, D) \
|
||||
(*pp_c_base (PPI)->declaration_specifiers) (pp_c_base (PPI), D)
|
||||
#define pp_type_specifier(PPI, D) \
|
||||
(*pp_c_base (PPI)->type_specifier) (pp_c_base (PPI), D)
|
||||
#define pp_declarator(PPI, D) \
|
||||
(*pp_c_base (PPI)->declarator) (pp_c_base (PPI), D)
|
||||
#define pp_direct_declarator(PPI, D) \
|
||||
(*pp_c_base (PPI)->direct_declarator) (pp_c_base (PPI), D)
|
||||
#define pp_parameter_declaration(PPI, T) \
|
||||
(*pp_c_base (PPI)->parameter_declaration) (pp_c_base (PPI), T)
|
||||
#define pp_type_id(PPI, D) \
|
||||
(*pp_c_base (PPI)->type_id) (pp_c_base (PPI), D)
|
||||
|
||||
#define pp_statement(PPI, S) \
|
||||
(*pp_c_base (PPI)->statement) (pp_c_base (PPI), S)
|
||||
|
||||
#define pp_primary_expression(PPI, E) \
|
||||
(*pp_c_base (PPI)->primary_expression) (pp_c_base (PPI), E)
|
||||
#define pp_postfix_expression(PPI, E) \
|
||||
(*pp_c_base (PPI)->postfix_expression) (pp_c_base (PPI), E)
|
||||
#define pp_unary_expression(PPI, E) \
|
||||
(*pp_c_base (PPI)->unary_expression) (pp_c_base (PPI), E)
|
||||
#define pp_initializer(PPI, E) \
|
||||
(*pp_c_base (PPI)->initializer) (pp_c_base (PPI), E)
|
||||
#define pp_multiplicative_expression(PPI, E) \
|
||||
(*pp_c_base (PPI)->multiplicative_expression) (pp_c_base (PPI), E)
|
||||
#define pp_conditional_expression(PPI, E) \
|
||||
(*pp_c_base (PPI)->conditional_expression) (pp_c_base (PPI), E)
|
||||
#define pp_assignment_expression(PPI, E) \
|
||||
(*pp_c_base (PPI)->assignment_expression) (pp_c_base (PPI), E)
|
||||
|
||||
|
||||
/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This
|
||||
macro must be overriden by any subclass of c_pretty_print_info. */
|
||||
#define pp_c_base(PP) (PP)
|
||||
|
||||
extern void pp_c_pretty_printer_init PARAMS ((c_pretty_printer));
|
||||
|
||||
/* Declarations. */
|
||||
void pp_c_attributes PARAMS ((c_pretty_printer, tree));
|
||||
void pp_c_cv_qualifier PARAMS ((c_pretty_printer, int));
|
||||
void pp_c_parameter_declaration_clause PARAMS ((c_pretty_printer, tree));
|
||||
void pp_c_declaration PARAMS ((c_pretty_printer, tree));
|
||||
/* Statements. */
|
||||
void pp_c_statement PARAMS ((c_pretty_printer, tree));
|
||||
/* Expressions. */
|
||||
void pp_c_expression PARAMS ((c_pretty_printer, tree));
|
||||
void pp_c_logical_or_expression PARAMS ((c_pretty_printer, tree));
|
||||
void pp_c_expression_list PARAMS ((c_pretty_printer, tree));
|
||||
void pp_c_cast_expression PARAMS ((c_pretty_printer, tree));
|
||||
void pp_c_postfix_expression PARAMS ((c_pretty_printer, tree));
|
||||
void pp_c_initializer PARAMS ((c_pretty_printer, tree));
|
||||
void pp_c_literal PARAMS ((c_pretty_printer, tree));
|
||||
|
||||
#endif /* GCC_C_PRETTY_PRINTER */
|
@ -36,6 +36,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "expr.h"
|
||||
#include "output.h"
|
||||
#include "timevar.h"
|
||||
#include "predict.h"
|
||||
|
||||
/* If non-NULL, the address of a language-specific function for
|
||||
expanding statements. */
|
||||
@ -334,7 +335,7 @@ genrtl_expr_stmt (expr)
|
||||
whether to (1) save the value of the expression, (0) discard it or
|
||||
(-1) use expr_stmts_for_value to tell. The use of -1 is
|
||||
deprecated, and retained only for backward compatibility.
|
||||
MAYBE_LAST is non-zero if this EXPR_STMT might be the last statement
|
||||
MAYBE_LAST is nonzero if this EXPR_STMT might be the last statement
|
||||
in expression statement. */
|
||||
|
||||
void
|
||||
@ -446,8 +447,9 @@ genrtl_do_stmt (t)
|
||||
/* Recognize the common special-case of do { ... } while (0) and do
|
||||
not emit the loop widgetry in this case. In particular this
|
||||
avoids cluttering the rtl with dummy loop notes, which can affect
|
||||
alignment of adjacent labels. */
|
||||
if (integer_zerop (cond))
|
||||
alignment of adjacent labels. COND can be NULL due to parse
|
||||
errors. */
|
||||
if (!cond || integer_zerop (cond))
|
||||
{
|
||||
expand_start_null_loop ();
|
||||
expand_stmt (DO_BODY (t));
|
||||
@ -486,7 +488,7 @@ genrtl_return_stmt (stmt)
|
||||
{
|
||||
tree expr;
|
||||
|
||||
expr = RETURN_EXPR (stmt);
|
||||
expr = RETURN_STMT_EXPR (stmt);
|
||||
|
||||
emit_line_note (input_filename, lineno);
|
||||
if (!expr)
|
||||
@ -673,8 +675,7 @@ genrtl_case_label (case_label)
|
||||
if (cleanup)
|
||||
{
|
||||
static int explained = 0;
|
||||
warning_with_decl (TREE_PURPOSE (cleanup),
|
||||
"destructor needed for `%#D'");
|
||||
warning ("destructor needed for `%#D'", (TREE_PURPOSE (cleanup)));
|
||||
warning ("where case label appears here");
|
||||
if (!explained)
|
||||
{
|
||||
@ -835,6 +836,15 @@ expand_stmt (t)
|
||||
break;
|
||||
|
||||
case GOTO_STMT:
|
||||
/* Emit information for branch prediction. */
|
||||
if (!GOTO_FAKE_P (t)
|
||||
&& TREE_CODE (GOTO_DESTINATION (t)) == LABEL_DECL
|
||||
&& flag_guess_branch_prob)
|
||||
{
|
||||
rtx note = emit_note (NULL, NOTE_INSN_PREDICTION);
|
||||
|
||||
NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_GOTO, NOT_TAKEN);
|
||||
}
|
||||
genrtl_goto_stmt (GOTO_DESTINATION (t));
|
||||
break;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -115,6 +115,9 @@ init_caller_save ()
|
||||
rtx address;
|
||||
int i, j;
|
||||
enum machine_mode mode;
|
||||
rtx savepat, restpat;
|
||||
rtx test_reg, test_mem;
|
||||
rtx saveinsn, restinsn;
|
||||
|
||||
/* First find all the registers that we need to deal with and all
|
||||
the modes that they can have. If we can't find a mode to use,
|
||||
@ -179,22 +182,35 @@ init_caller_save ()
|
||||
address = addr_reg;
|
||||
|
||||
/* Next we try to form an insn to save and restore the register. We
|
||||
see if such an insn is recognized and meets its constraints. */
|
||||
see if such an insn is recognized and meets its constraints.
|
||||
|
||||
start_sequence ();
|
||||
To avoid lots of unnecessary RTL allocation, we construct all the RTL
|
||||
once, then modify the memory and register operands in-place. */
|
||||
|
||||
test_reg = gen_rtx_REG (VOIDmode, 0);
|
||||
test_mem = gen_rtx_MEM (VOIDmode, address);
|
||||
savepat = gen_rtx_SET (VOIDmode, test_mem, test_reg);
|
||||
restpat = gen_rtx_SET (VOIDmode, test_reg, test_mem);
|
||||
|
||||
saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, savepat, -1, 0, 0);
|
||||
restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, restpat, -1, 0, 0);
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (mode = 0 ; mode < MAX_MACHINE_MODE; mode++)
|
||||
if (HARD_REGNO_MODE_OK (i, mode))
|
||||
{
|
||||
rtx mem = gen_rtx_MEM (mode, address);
|
||||
rtx reg = gen_rtx_REG (mode, i);
|
||||
rtx savepat = gen_rtx_SET (VOIDmode, mem, reg);
|
||||
rtx restpat = gen_rtx_SET (VOIDmode, reg, mem);
|
||||
rtx saveinsn = emit_insn (savepat);
|
||||
rtx restinsn = emit_insn (restpat);
|
||||
int ok;
|
||||
|
||||
/* Update the register number and modes of the register
|
||||
and memory operand. */
|
||||
REGNO (test_reg) = i;
|
||||
PUT_MODE (test_reg, mode);
|
||||
PUT_MODE (test_mem, mode);
|
||||
|
||||
/* Force re-recognition of the modified insns. */
|
||||
INSN_CODE (saveinsn) = -1;
|
||||
INSN_CODE (restinsn) = -1;
|
||||
|
||||
reg_save_code[i][mode] = recog_memoized (saveinsn);
|
||||
reg_restore_code[i][mode] = recog_memoized (restinsn);
|
||||
|
||||
@ -221,6 +237,7 @@ init_caller_save ()
|
||||
reg_save_code[i][mode] = -1;
|
||||
reg_restore_code[i][mode] = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (j = 1; j <= MOVE_MAX_WORDS; j++)
|
||||
if (reg_save_code [i][regno_save_mode[i][j]] == -1)
|
||||
@ -232,8 +249,6 @@ init_caller_save ()
|
||||
SET_HARD_REG_BIT (call_fixed_reg_set, i);
|
||||
}
|
||||
}
|
||||
|
||||
end_sequence ();
|
||||
}
|
||||
|
||||
/* Initialize save areas by showing that we haven't allocated any yet. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Convert function calls to rtl insns, for GNU C compiler.
|
||||
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -33,6 +33,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "tm_p.h"
|
||||
#include "timevar.h"
|
||||
#include "sbitmap.h"
|
||||
#include "langhooks.h"
|
||||
#include "target.h"
|
||||
#include "except.h"
|
||||
|
||||
#if !defined FUNCTION_OK_FOR_SIBCALL
|
||||
#define FUNCTION_OK_FOR_SIBCALL(DECL) 1
|
||||
@ -91,7 +94,7 @@ struct arg_data
|
||||
/* Number of registers to use. 0 means put the whole arg in registers.
|
||||
Also 0 if not passed in registers. */
|
||||
int partial;
|
||||
/* Non-zero if argument must be passed on stack.
|
||||
/* Nonzero if argument must be passed on stack.
|
||||
Note that some arguments may be passed on the stack
|
||||
even though pass_on_stack is zero, just because FUNCTION_ARG says so.
|
||||
pass_on_stack identifies arguments that *cannot* go in registers. */
|
||||
@ -126,7 +129,7 @@ struct arg_data
|
||||
struct args_size alignment_pad;
|
||||
};
|
||||
|
||||
/* A vector of one char per byte of stack space. A byte if non-zero if
|
||||
/* A vector of one char per byte of stack space. A byte if nonzero if
|
||||
the corresponding stack location has been used.
|
||||
This vector is used to prevent a function call within an argument from
|
||||
clobbering any stack already set up. */
|
||||
@ -225,6 +228,7 @@ static int check_sibcall_argument_overlap PARAMS ((rtx, struct arg_data *));
|
||||
|
||||
static int combine_pending_stack_adjustment_and_call
|
||||
PARAMS ((int, struct args_size *, int));
|
||||
static tree fix_unsafe_tree PARAMS ((tree));
|
||||
|
||||
#ifdef REG_PARM_STACK_SPACE
|
||||
static rtx save_fixed_argument_area PARAMS ((int, rtx, int *, int *));
|
||||
@ -614,6 +618,8 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
|
||||
if (ecf_flags & ECF_NOTHROW)
|
||||
REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, const0_rtx,
|
||||
REG_NOTES (call_insn));
|
||||
else
|
||||
note_eh_region_may_contain_throw ();
|
||||
|
||||
if (ecf_flags & ECF_NORETURN)
|
||||
REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_NORETURN, const0_rtx,
|
||||
@ -799,6 +805,21 @@ setjmp_call_p (fndecl)
|
||||
return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
|
||||
}
|
||||
|
||||
/* Return true when exp contains alloca call. */
|
||||
bool
|
||||
alloca_call_p (exp)
|
||||
tree exp;
|
||||
{
|
||||
if (TREE_CODE (exp) == CALL_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
|
||||
&& (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
|
||||
== FUNCTION_DECL)
|
||||
&& (special_function_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
|
||||
0) & ECF_MAY_BE_ALLOCA))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Detect flags (function attributes) from the function decl or type node. */
|
||||
|
||||
static int
|
||||
@ -876,6 +897,12 @@ precompute_register_parameters (num_actuals, args, reg_parm_seen)
|
||||
emit_queue ();
|
||||
}
|
||||
|
||||
/* If the value is a non-legitimate constant, force it into a
|
||||
pseudo now. TLS symbols sometimes need a call to resolve. */
|
||||
if (CONSTANT_P (args[i].value)
|
||||
&& !LEGITIMATE_CONSTANT_P (args[i].value))
|
||||
args[i].value = force_reg (args[i].mode, args[i].value);
|
||||
|
||||
/* If we are to promote the function arg to a wider mode,
|
||||
do it now. */
|
||||
|
||||
@ -967,11 +994,8 @@ save_fixed_argument_area (reg_parm_stack_space, argblock,
|
||||
if (save_mode == BLKmode)
|
||||
{
|
||||
save_area = assign_stack_temp (BLKmode, num_to_save, 0);
|
||||
/* Cannot use emit_block_move here because it can be done by a
|
||||
library call which in turn gets into this place again and deadly
|
||||
infinite recursion happens. */
|
||||
move_by_pieces (validize_mem (save_area), stack_area, num_to_save,
|
||||
PARM_BOUNDARY);
|
||||
emit_block_move (validize_mem (save_area), stack_area,
|
||||
GEN_INT (num_to_save), BLOCK_OP_CALL_PARM);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1008,11 +1032,9 @@ restore_fixed_argument_area (save_area, argblock, high_to_save, low_to_save)
|
||||
if (save_mode != BLKmode)
|
||||
emit_move_insn (stack_area, save_area);
|
||||
else
|
||||
/* Cannot use emit_block_move here because it can be done by a library
|
||||
call which in turn gets into this place again and deadly infinite
|
||||
recursion happens. */
|
||||
move_by_pieces (stack_area, validize_mem (save_area),
|
||||
high_to_save - low_to_save + 1, PARM_BOUNDARY);
|
||||
emit_block_move (stack_area, validize_mem (save_area),
|
||||
GEN_INT (high_to_save - low_to_save + 1),
|
||||
BLOCK_OP_CALL_PARM);
|
||||
}
|
||||
#endif /* REG_PARM_STACK_SPACE */
|
||||
|
||||
@ -1053,7 +1075,6 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
|
||||
this means we must skip the empty high order bytes when
|
||||
calculating the bit offset. */
|
||||
if (BYTES_BIG_ENDIAN
|
||||
&& !FUNCTION_ARG_REG_LITTLE_ENDIAN
|
||||
&& bytes < UNITS_PER_WORD)
|
||||
big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
|
||||
|
||||
@ -1539,8 +1560,8 @@ precompute_arguments (flags, num_actuals, args)
|
||||
args[i].initial_value
|
||||
= gen_lowpart_SUBREG (mode, args[i].value);
|
||||
SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
|
||||
SUBREG_PROMOTED_UNSIGNED_P (args[i].initial_value)
|
||||
= args[i].unsignedp;
|
||||
SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value,
|
||||
args[i].unsignedp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1645,6 +1666,7 @@ compute_argument_addresses (args, argblock, num_actuals)
|
||||
|
||||
addr = plus_constant (addr, arg_offset);
|
||||
args[i].stack = gen_rtx_MEM (args[i].mode, addr);
|
||||
set_mem_align (args[i].stack, PARM_BOUNDARY);
|
||||
set_mem_attributes (args[i].stack,
|
||||
TREE_TYPE (args[i].tree_value), 1);
|
||||
|
||||
@ -1655,6 +1677,7 @@ compute_argument_addresses (args, argblock, num_actuals)
|
||||
|
||||
addr = plus_constant (addr, arg_offset);
|
||||
args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
|
||||
set_mem_align (args[i].stack_slot, PARM_BOUNDARY);
|
||||
set_mem_attributes (args[i].stack_slot,
|
||||
TREE_TYPE (args[i].tree_value), 1);
|
||||
|
||||
@ -1674,12 +1697,12 @@ compute_argument_addresses (args, argblock, num_actuals)
|
||||
FNDECL is the tree node for the target function. For an indirect call
|
||||
FNDECL will be NULL_TREE.
|
||||
|
||||
EXP is the CALL_EXPR for this call. */
|
||||
ADDR is the operand 0 of CALL_EXPR for this call. */
|
||||
|
||||
static rtx
|
||||
rtx_for_function_call (fndecl, exp)
|
||||
rtx_for_function_call (fndecl, addr)
|
||||
tree fndecl;
|
||||
tree exp;
|
||||
tree addr;
|
||||
{
|
||||
rtx funexp;
|
||||
|
||||
@ -1703,7 +1726,7 @@ rtx_for_function_call (fndecl, exp)
|
||||
rtx funaddr;
|
||||
push_temp_slots ();
|
||||
funaddr = funexp
|
||||
= expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
|
||||
= expand_expr (addr, NULL_RTX, VOIDmode, 0);
|
||||
pop_temp_slots (); /* FUNEXP can't be BLKmode. */
|
||||
emit_queue ();
|
||||
}
|
||||
@ -1881,7 +1904,7 @@ try_to_integrate (fndecl, actparms, target, ignore, type, structure_value_addr)
|
||||
NULL_RTX, BITS_PER_UNIT);
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insns_before (seq, first_insn);
|
||||
emit_insn_before (seq, first_insn);
|
||||
emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
|
||||
}
|
||||
}
|
||||
@ -1904,7 +1927,7 @@ try_to_integrate (fndecl, actparms, target, ignore, type, structure_value_addr)
|
||||
warning_with_decl (fndecl, "inlining failed in call to `%s'");
|
||||
warning ("called from here");
|
||||
}
|
||||
mark_addressable (fndecl);
|
||||
(*lang_hooks.mark_addressable) (fndecl);
|
||||
return (rtx) (size_t) - 1;
|
||||
}
|
||||
|
||||
@ -1970,7 +1993,7 @@ combine_pending_stack_adjustment_and_call (unadjusted_args_size,
|
||||
/* Scan X expression if it does not dereference any argument slots
|
||||
we already clobbered by tail call arguments (as noted in stored_args_map
|
||||
bitmap).
|
||||
Return non-zero if X expression dereferences such argument slots,
|
||||
Return nonzero if X expression dereferences such argument slots,
|
||||
zero otherwise. */
|
||||
|
||||
static int
|
||||
@ -2033,7 +2056,7 @@ check_sibcall_argument_overlap_1 (x)
|
||||
/* Scan sequence after INSN if it does not dereference any argument slots
|
||||
we already clobbered by tail call arguments (as noted in stored_args_map
|
||||
bitmap). Add stack slots for ARG to stored_args_map bitmap afterwards.
|
||||
Return non-zero if sequence after INSN dereferences such argument slots,
|
||||
Return nonzero if sequence after INSN dereferences such argument slots,
|
||||
zero otherwise. */
|
||||
|
||||
static int
|
||||
@ -2204,6 +2227,7 @@ expand_call (exp, target, ignore)
|
||||
int old_stack_allocated;
|
||||
rtx call_fusage;
|
||||
tree p = TREE_OPERAND (exp, 0);
|
||||
tree addr = TREE_OPERAND (exp, 0);
|
||||
int i;
|
||||
/* The alignment of the stack, in bits. */
|
||||
HOST_WIDE_INT preferred_stack_boundary;
|
||||
@ -2239,7 +2263,7 @@ expand_call (exp, target, ignore)
|
||||
warning_with_decl (fndecl, "can't inline call to `%s'");
|
||||
warning ("called from here");
|
||||
}
|
||||
mark_addressable (fndecl);
|
||||
(*lang_hooks.mark_addressable) (fndecl);
|
||||
}
|
||||
|
||||
flags |= flags_from_decl_or_type (fndecl);
|
||||
@ -2285,7 +2309,7 @@ expand_call (exp, target, ignore)
|
||||
/* In case this is a static function, note that it has been
|
||||
used. */
|
||||
if (! TREE_ADDRESSABLE (fndecl))
|
||||
mark_addressable (fndecl);
|
||||
(*lang_hooks.mark_addressable) (fndecl);
|
||||
is_integrable = 0;
|
||||
}
|
||||
}
|
||||
@ -2325,7 +2349,7 @@ expand_call (exp, target, ignore)
|
||||
preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
|
||||
|
||||
/* Operand 0 is a pointer-to-function; get the type of the function. */
|
||||
funtype = TREE_TYPE (TREE_OPERAND (exp, 0));
|
||||
funtype = TREE_TYPE (addr);
|
||||
if (! POINTER_TYPE_P (funtype))
|
||||
abort ();
|
||||
funtype = TREE_TYPE (funtype);
|
||||
@ -2462,8 +2486,8 @@ expand_call (exp, target, ignore)
|
||||
|
||||
/* Tail recursion fails, when we are not dealing with recursive calls. */
|
||||
if (!try_tail_recursion
|
||||
|| TREE_CODE (TREE_OPERAND (exp, 0)) != ADDR_EXPR
|
||||
|| TREE_OPERAND (TREE_OPERAND (exp, 0), 0) != current_function_decl)
|
||||
|| TREE_CODE (addr) != ADDR_EXPR
|
||||
|| TREE_OPERAND (addr, 0) != current_function_decl)
|
||||
try_tail_recursion = 0;
|
||||
|
||||
/* Rest of purposes for tail call optimizations to fail. */
|
||||
@ -2487,19 +2511,19 @@ expand_call (exp, target, ignore)
|
||||
reload insns generated to fix things up would appear
|
||||
before the sibcall_epilogue. */
|
||||
|| fndecl == NULL_TREE
|
||||
|| (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP))
|
||||
|| TREE_THIS_VOLATILE (fndecl)
|
||||
|| (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN))
|
||||
|| !FUNCTION_OK_FOR_SIBCALL (fndecl)
|
||||
/* If this function requires more stack slots than the current
|
||||
function, we cannot change it into a sibling call. */
|
||||
|| args_size.constant > current_function_args_size
|
||||
/* If the callee pops its own arguments, then it must pop exactly
|
||||
the same number of arguments as the current function. */
|
||||
|| RETURN_POPS_ARGS (fndecl, funtype, args_size.constant)
|
||||
!= RETURN_POPS_ARGS (current_function_decl,
|
||||
TREE_TYPE (current_function_decl),
|
||||
current_function_args_size))
|
||||
try_tail_call = 0;
|
||||
|| (RETURN_POPS_ARGS (fndecl, funtype, args_size.constant)
|
||||
!= RETURN_POPS_ARGS (current_function_decl,
|
||||
TREE_TYPE (current_function_decl),
|
||||
current_function_args_size))
|
||||
|| !(*lang_hooks.decls.ok_for_sibcall) (fndecl))
|
||||
try_tail_call = 0;
|
||||
|
||||
if (try_tail_call || try_tail_recursion)
|
||||
{
|
||||
@ -2544,7 +2568,7 @@ expand_call (exp, target, ignore)
|
||||
}
|
||||
/* Do the same for the function address if it is an expression. */
|
||||
if (!fndecl)
|
||||
TREE_OPERAND (exp, 0) = fix_unsafe_tree (TREE_OPERAND (exp, 0));
|
||||
addr = fix_unsafe_tree (addr);
|
||||
/* Expanding one of those dangerous arguments could have added
|
||||
cleanups, but otherwise give it a whirl. */
|
||||
if (any_pending_cleanups (1))
|
||||
@ -2938,7 +2962,7 @@ expand_call (exp, target, ignore)
|
||||
be deferred during the evaluation of the arguments. */
|
||||
NO_DEFER_POP;
|
||||
|
||||
funexp = rtx_for_function_call (fndecl, exp);
|
||||
funexp = rtx_for_function_call (fndecl, addr);
|
||||
|
||||
/* Figure out the register where the value, if any, will come back. */
|
||||
valreg = 0;
|
||||
@ -3089,7 +3113,7 @@ expand_call (exp, target, ignore)
|
||||
{
|
||||
insns = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insns (insns);
|
||||
emit_insn (insns);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3143,7 +3167,7 @@ expand_call (exp, target, ignore)
|
||||
/* Write out the sequence. */
|
||||
insns = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insns (insns);
|
||||
emit_insn (insns);
|
||||
valreg = temp;
|
||||
}
|
||||
|
||||
@ -3288,7 +3312,7 @@ expand_call (exp, target, ignore)
|
||||
}
|
||||
target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
|
||||
SUBREG_PROMOTED_VAR_P (target) = 1;
|
||||
SUBREG_PROMOTED_UNSIGNED_P (target) = unsignedp;
|
||||
SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3327,9 +3351,9 @@ expand_call (exp, target, ignore)
|
||||
if (save_mode != BLKmode)
|
||||
emit_move_insn (stack_area, args[i].save_area);
|
||||
else
|
||||
emit_block_move (stack_area,
|
||||
validize_mem (args[i].save_area),
|
||||
GEN_INT (args[i].size.constant));
|
||||
emit_block_move (stack_area, args[i].save_area,
|
||||
GEN_INT (args[i].size.constant),
|
||||
BLOCK_OP_CALL_PARM);
|
||||
}
|
||||
|
||||
highest_outgoing_arg_in_use = initial_highest_arg_in_use;
|
||||
@ -3430,7 +3454,7 @@ expand_call (exp, target, ignore)
|
||||
tail_recursion_label));
|
||||
}
|
||||
else
|
||||
emit_insns (normal_call_insns);
|
||||
emit_insn (normal_call_insns);
|
||||
|
||||
currently_expanding_call--;
|
||||
|
||||
@ -3494,6 +3518,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
int reg_parm_stack_space = 0;
|
||||
int needed;
|
||||
rtx before_call;
|
||||
tree tfom; /* type_for_mode (outmode, 0) */
|
||||
|
||||
#ifdef REG_PARM_STACK_SPACE
|
||||
/* Define the boundary of the register parm stack space that needs to be
|
||||
@ -3555,27 +3580,31 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
|
||||
/* If this kind of value comes back in memory,
|
||||
decide where in memory it should come back. */
|
||||
if (outmode != VOIDmode && aggregate_value_p (type_for_mode (outmode, 0)))
|
||||
if (outmode != VOIDmode)
|
||||
{
|
||||
tfom = (*lang_hooks.types.type_for_mode) (outmode, 0);
|
||||
if (aggregate_value_p (tfom))
|
||||
{
|
||||
#ifdef PCC_STATIC_STRUCT_RETURN
|
||||
rtx pointer_reg
|
||||
= hard_function_value (build_pointer_type (type_for_mode (outmode, 0)),
|
||||
0, 0);
|
||||
mem_value = gen_rtx_MEM (outmode, pointer_reg);
|
||||
pcc_struct_value = 1;
|
||||
if (value == 0)
|
||||
value = gen_reg_rtx (outmode);
|
||||
rtx pointer_reg
|
||||
= hard_function_value (build_pointer_type (tfom), 0, 0);
|
||||
mem_value = gen_rtx_MEM (outmode, pointer_reg);
|
||||
pcc_struct_value = 1;
|
||||
if (value == 0)
|
||||
value = gen_reg_rtx (outmode);
|
||||
#else /* not PCC_STATIC_STRUCT_RETURN */
|
||||
struct_value_size = GET_MODE_SIZE (outmode);
|
||||
if (value != 0 && GET_CODE (value) == MEM)
|
||||
mem_value = value;
|
||||
else
|
||||
mem_value = assign_temp (type_for_mode (outmode, 0), 0, 1, 1);
|
||||
struct_value_size = GET_MODE_SIZE (outmode);
|
||||
if (value != 0 && GET_CODE (value) == MEM)
|
||||
mem_value = value;
|
||||
else
|
||||
mem_value = assign_temp (tfom, 0, 1, 1);
|
||||
#endif
|
||||
|
||||
/* This call returns a big structure. */
|
||||
flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
|
||||
/* This call returns a big structure. */
|
||||
flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
|
||||
}
|
||||
}
|
||||
else
|
||||
tfom = void_type_node;
|
||||
|
||||
/* ??? Unfinished: must pass the memory address as an argument. */
|
||||
|
||||
@ -3684,6 +3713,16 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
#endif
|
||||
;
|
||||
|
||||
/* loop.c won't look at CALL_INSN_FUNCTION_USAGE of const/pure
|
||||
functions, so we have to pretend this isn't such a function. */
|
||||
if (flags & ECF_LIBCALL_BLOCK)
|
||||
{
|
||||
rtx insns = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insn (insns);
|
||||
}
|
||||
flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
|
||||
|
||||
/* If this was a CONST function, it is now PURE since
|
||||
it now reads memory. */
|
||||
if (flags & ECF_CONST)
|
||||
@ -3696,12 +3735,13 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
slot = val;
|
||||
else if (must_copy)
|
||||
{
|
||||
slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1);
|
||||
slot = assign_temp ((*lang_hooks.types.type_for_mode) (mode, 0),
|
||||
0, 1, 1);
|
||||
emit_move_insn (slot, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree type = type_for_mode (mode, 0);
|
||||
tree type = (*lang_hooks.types.type_for_mode) (mode, 0);
|
||||
|
||||
slot = gen_rtx_MEM (mode,
|
||||
expand_expr (build1 (ADDR_EXPR,
|
||||
@ -3911,8 +3951,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
{
|
||||
save_area = assign_stack_temp (BLKmode, num_to_save, 0);
|
||||
set_mem_align (save_area, PARM_BOUNDARY);
|
||||
emit_block_move (validize_mem (save_area), stack_area,
|
||||
GEN_INT (num_to_save));
|
||||
emit_block_move (save_area, stack_area, GEN_INT (num_to_save),
|
||||
BLOCK_OP_CALL_PARM);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3980,8 +4020,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
}
|
||||
}
|
||||
|
||||
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
|
||||
argblock, GEN_INT (argvec[argnum].offset.constant),
|
||||
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY,
|
||||
partial, reg, 0, argblock,
|
||||
GEN_INT (argvec[argnum].offset.constant),
|
||||
reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
|
||||
|
||||
/* Now mark the segment we just used. */
|
||||
@ -4068,8 +4109,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
|
||||
emit_call_1 (fun,
|
||||
get_identifier (XSTR (orgfun, 0)),
|
||||
build_function_type (outmode == VOIDmode ? void_type_node
|
||||
: type_for_mode (outmode, 0), NULL_TREE),
|
||||
build_function_type (tfom, NULL_TREE),
|
||||
original_args_size.constant, args_size.constant,
|
||||
struct_value_size,
|
||||
FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
|
||||
@ -4109,18 +4149,27 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
{
|
||||
rtx insns;
|
||||
|
||||
if (valreg == 0 || GET_CODE (valreg) == PARALLEL)
|
||||
if (valreg == 0)
|
||||
{
|
||||
insns = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insns (insns);
|
||||
emit_insn (insns);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx note = 0;
|
||||
rtx temp = gen_reg_rtx (GET_MODE (valreg));
|
||||
rtx temp;
|
||||
int i;
|
||||
|
||||
if (GET_CODE (valreg) == PARALLEL)
|
||||
{
|
||||
temp = gen_reg_rtx (outmode);
|
||||
emit_group_store (temp, valreg, outmode);
|
||||
valreg = temp;
|
||||
}
|
||||
|
||||
temp = gen_reg_rtx (GET_MODE (valreg));
|
||||
|
||||
/* Construct an "equal form" for the value which mentions all the
|
||||
arguments in order as well as the function name. */
|
||||
for (i = 0; i < nargs; i++)
|
||||
@ -4154,10 +4203,16 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
if (value != mem_value)
|
||||
emit_move_insn (value, mem_value);
|
||||
}
|
||||
else if (GET_CODE (valreg) == PARALLEL)
|
||||
{
|
||||
if (value == 0)
|
||||
value = gen_reg_rtx (outmode);
|
||||
emit_group_store (value, valreg, outmode);
|
||||
}
|
||||
else if (value != 0)
|
||||
emit_move_insn (value, hard_libcall_value (outmode));
|
||||
emit_move_insn (value, valreg);
|
||||
else
|
||||
value = hard_libcall_value (outmode);
|
||||
value = valreg;
|
||||
}
|
||||
|
||||
if (ACCUMULATE_OUTGOING_ARGS)
|
||||
@ -4183,8 +4238,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|
||||
if (save_mode != BLKmode)
|
||||
emit_move_insn (stack_area, save_area);
|
||||
else
|
||||
emit_block_move (stack_area, validize_mem (save_area),
|
||||
GEN_INT (high_to_save - low_to_save + 1));
|
||||
emit_block_move (stack_area, save_area,
|
||||
GEN_INT (high_to_save - low_to_save + 1),
|
||||
BLOCK_OP_CALL_PARM);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4286,7 +4342,7 @@ emit_library_call_value VPARAMS((rtx orgfun, rtx value,
|
||||
|
||||
FNDECL is the declaration of the function we are calling.
|
||||
|
||||
Return non-zero if this arg should cause sibcall failure,
|
||||
Return nonzero if this arg should cause sibcall failure,
|
||||
zero otherwise. */
|
||||
|
||||
static int
|
||||
@ -4294,7 +4350,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
struct arg_data *arg;
|
||||
rtx argblock;
|
||||
int flags;
|
||||
int variable_size;
|
||||
int variable_size ATTRIBUTE_UNUSED;
|
||||
int reg_parm_stack_space;
|
||||
{
|
||||
tree pval = arg->tree_value;
|
||||
@ -4361,7 +4417,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
arg->save_area = assign_temp (nt, 0, 1, 1);
|
||||
preserve_temp_slots (arg->save_area);
|
||||
emit_block_move (validize_mem (arg->save_area), stack_area,
|
||||
expr_size (arg->tree_value));
|
||||
expr_size (arg->tree_value),
|
||||
BLOCK_OP_CALL_PARM);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4369,21 +4426,6 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
emit_move_insn (arg->save_area, stack_area);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that we have saved any slots that will be overwritten
|
||||
by this store, mark all slots this store will use. We
|
||||
must do this before we actually expand the argument since
|
||||
the expansion itself may trigger library calls which might
|
||||
need to use the same stack slot. We only do it if we can't
|
||||
pass all arguments to a library call in registers. */
|
||||
if (arg->partial)
|
||||
{
|
||||
for (i = lower_bound; i < upper_bound; i++)
|
||||
stack_usage_map[i] = 1;
|
||||
|
||||
/* Set it so that we don't do it again. */
|
||||
variable_size = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4437,7 +4479,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
(partial
|
||||
|| TYPE_MODE (TREE_TYPE (pval)) != arg->mode)
|
||||
? NULL_RTX : arg->stack,
|
||||
VOIDmode, 0);
|
||||
VOIDmode, EXPAND_STACK_PARM);
|
||||
|
||||
/* If we are promoting object (or for any other reason) the mode
|
||||
doesn't agree, convert the mode. */
|
||||
@ -4490,8 +4532,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
|
||||
/* This isn't already where we want it on the stack, so put it there.
|
||||
This can either be done with push or copy insns. */
|
||||
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 0,
|
||||
partial, reg, used - size, argblock,
|
||||
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX,
|
||||
PARM_BOUNDARY, partial, reg, used - size, argblock,
|
||||
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
|
||||
ARGS_SIZE_RTX (arg->alignment_pad));
|
||||
|
||||
@ -4504,6 +4546,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
{
|
||||
/* BLKmode, at least partly to be pushed. */
|
||||
|
||||
unsigned int parm_align;
|
||||
int excess;
|
||||
rtx size_rtx;
|
||||
|
||||
@ -4529,6 +4572,23 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
NULL_RTX, TYPE_MODE (sizetype), 0);
|
||||
}
|
||||
|
||||
/* Some types will require stricter alignment, which will be
|
||||
provided for elsewhere in argument layout. */
|
||||
parm_align = MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval)));
|
||||
|
||||
/* When an argument is padded down, the block is aligned to
|
||||
PARM_BOUNDARY, but the actual argument isn't. */
|
||||
if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
|
||||
{
|
||||
if (arg->size.var)
|
||||
parm_align = BITS_PER_UNIT;
|
||||
else if (excess)
|
||||
{
|
||||
unsigned int excess_align = (excess & -excess) * BITS_PER_UNIT;
|
||||
parm_align = MIN (parm_align, excess_align);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
|
||||
{
|
||||
/* emit_push_insn might not work properly if arg->value and
|
||||
@ -4562,42 +4622,9 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
}
|
||||
}
|
||||
|
||||
/* Special handling is required if part of the parameter lies in the
|
||||
register parameter area. The argument may be copied into the stack
|
||||
slot using memcpy(), but the original contents of the register
|
||||
parameter area will be restored after the memcpy() call.
|
||||
|
||||
To ensure that the part that lies in the register parameter area
|
||||
is copied correctly, we emit a separate push for that part. This
|
||||
push should be small enough to avoid a call to memcpy(). */
|
||||
#ifndef STACK_PARMS_IN_REG_PARM_AREA
|
||||
if (arg->reg && arg->pass_on_stack)
|
||||
#else
|
||||
if (1)
|
||||
#endif
|
||||
{
|
||||
if (arg->offset.constant < reg_parm_stack_space && arg->offset.var)
|
||||
error ("variable offset is passed partially in stack and in reg");
|
||||
else if (arg->offset.constant < reg_parm_stack_space && arg->size.var)
|
||||
error ("variable size is passed partially in stack and in reg");
|
||||
else if (arg->offset.constant < reg_parm_stack_space
|
||||
&& ((arg->offset.constant + arg->size.constant)
|
||||
> reg_parm_stack_space))
|
||||
{
|
||||
rtx size_rtx1 = GEN_INT (reg_parm_stack_space - arg->offset.constant);
|
||||
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx1,
|
||||
TYPE_ALIGN (TREE_TYPE (pval)), partial, reg,
|
||||
excess, argblock, ARGS_SIZE_RTX (arg->offset),
|
||||
reg_parm_stack_space,
|
||||
ARGS_SIZE_RTX (arg->alignment_pad));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
|
||||
TYPE_ALIGN (TREE_TYPE (pval)), partial, reg, excess,
|
||||
argblock, ARGS_SIZE_RTX (arg->offset),
|
||||
reg_parm_stack_space,
|
||||
parm_align, partial, reg, excess, argblock,
|
||||
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
|
||||
ARGS_SIZE_RTX (arg->alignment_pad));
|
||||
|
||||
/* Unless this is a partially-in-register argument, the argument is now
|
||||
@ -4612,6 +4639,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
|
||||
arg->value = arg->stack_slot;
|
||||
}
|
||||
|
||||
/* Mark all slots this store used. */
|
||||
if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL)
|
||||
&& argblock && ! variable_size && arg->stack)
|
||||
for (i = lower_bound; i < upper_bound; i++)
|
||||
|
@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
dump_flow_info, debug_flow_info, dump_edge_info
|
||||
- Allocation of AUX fields for basic blocks
|
||||
alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
|
||||
- clear_bb_flags
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -64,6 +65,10 @@ static char *flow_firstobj;
|
||||
|
||||
int n_basic_blocks;
|
||||
|
||||
/* First free basic block number. */
|
||||
|
||||
int last_basic_block;
|
||||
|
||||
/* Number of edges in the current function. */
|
||||
|
||||
int n_edges;
|
||||
@ -92,7 +97,10 @@ struct basic_block_def entry_exit_blocks[2]
|
||||
NULL, /* global_live_at_end */
|
||||
NULL, /* aux */
|
||||
ENTRY_BLOCK, /* index */
|
||||
NULL, /* prev_bb */
|
||||
EXIT_BLOCK_PTR, /* next_bb */
|
||||
0, /* loop_depth */
|
||||
NULL, /* loop_father */
|
||||
0, /* count */
|
||||
0, /* frequency */
|
||||
0 /* flags */
|
||||
@ -110,7 +118,10 @@ struct basic_block_def entry_exit_blocks[2]
|
||||
NULL, /* global_live_at_end */
|
||||
NULL, /* aux */
|
||||
EXIT_BLOCK, /* index */
|
||||
ENTRY_BLOCK_PTR, /* prev_bb */
|
||||
NULL, /* next_bb */
|
||||
0, /* loop_depth */
|
||||
NULL, /* loop_father */
|
||||
0, /* count */
|
||||
0, /* frequency */
|
||||
0 /* flags */
|
||||
@ -162,12 +173,11 @@ free_edge (e)
|
||||
void
|
||||
clear_edges ()
|
||||
{
|
||||
int i;
|
||||
basic_block bb;
|
||||
edge e;
|
||||
|
||||
for (i = 0; i < n_basic_blocks; ++i)
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
edge e = bb->succ;
|
||||
|
||||
while (e)
|
||||
@ -219,38 +229,99 @@ alloc_block ()
|
||||
return bb;
|
||||
}
|
||||
|
||||
/* Remove block B from the basic block array and compact behind it. */
|
||||
|
||||
/* Link block B to chain after AFTER. */
|
||||
void
|
||||
expunge_block_nocompact (b)
|
||||
link_block (b, after)
|
||||
basic_block b, after;
|
||||
{
|
||||
b->next_bb = after->next_bb;
|
||||
b->prev_bb = after;
|
||||
after->next_bb = b;
|
||||
b->next_bb->prev_bb = b;
|
||||
}
|
||||
|
||||
/* Unlink block B from chain. */
|
||||
void
|
||||
unlink_block (b)
|
||||
basic_block b;
|
||||
{
|
||||
b->next_bb->prev_bb = b->prev_bb;
|
||||
b->prev_bb->next_bb = b->next_bb;
|
||||
}
|
||||
|
||||
/* Sequentially order blocks and compact the arrays. */
|
||||
void
|
||||
compact_blocks ()
|
||||
{
|
||||
int i;
|
||||
basic_block bb;
|
||||
|
||||
i = 0;
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
BASIC_BLOCK (i) = bb;
|
||||
bb->index = i;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i != n_basic_blocks)
|
||||
abort ();
|
||||
|
||||
last_basic_block = n_basic_blocks;
|
||||
}
|
||||
|
||||
|
||||
/* Remove block B from the basic block array. */
|
||||
|
||||
void
|
||||
expunge_block (b)
|
||||
basic_block b;
|
||||
{
|
||||
unlink_block (b);
|
||||
BASIC_BLOCK (b->index) = NULL;
|
||||
n_basic_blocks--;
|
||||
|
||||
/* Invalidate data to make bughunting easier. */
|
||||
memset (b, 0, sizeof *b);
|
||||
b->index = -3;
|
||||
b->succ = (edge) first_deleted_block;
|
||||
first_deleted_block = (basic_block) b;
|
||||
}
|
||||
|
||||
void
|
||||
expunge_block (b)
|
||||
basic_block b;
|
||||
{
|
||||
int i, n = n_basic_blocks;
|
||||
|
||||
for (i = b->index; i + 1 < n; ++i)
|
||||
{
|
||||
basic_block x = BASIC_BLOCK (i + 1);
|
||||
BASIC_BLOCK (i) = x;
|
||||
x->index = i;
|
||||
}
|
||||
|
||||
n_basic_blocks--;
|
||||
basic_block_info->num_elements--;
|
||||
|
||||
expunge_block_nocompact (b);
|
||||
}
|
||||
|
||||
/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
|
||||
created edge. Use this only if you are sure that this edge can't
|
||||
possibly already exist. */
|
||||
|
||||
edge
|
||||
unchecked_make_edge (src, dst, flags)
|
||||
basic_block src, dst;
|
||||
int flags;
|
||||
{
|
||||
edge e;
|
||||
|
||||
if (first_deleted_edge)
|
||||
{
|
||||
e = first_deleted_edge;
|
||||
first_deleted_edge = e->succ_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = (edge) obstack_alloc (&flow_obstack, sizeof *e);
|
||||
memset (e, 0, sizeof *e);
|
||||
}
|
||||
n_edges++;
|
||||
|
||||
e->succ_next = src->succ;
|
||||
e->pred_next = dst->pred;
|
||||
e->src = src;
|
||||
e->dest = dst;
|
||||
e->flags = flags;
|
||||
|
||||
src->succ = e;
|
||||
dst->pred = e;
|
||||
|
||||
return e;
|
||||
}
|
||||
/* Create an edge connecting SRC and DST with FLAGS optionally using
|
||||
edge cache CACHE. Return the new edge, NULL if already exist. */
|
||||
|
||||
@ -291,26 +362,7 @@ cached_make_edge (edge_cache, src, dst, flags)
|
||||
break;
|
||||
}
|
||||
|
||||
if (first_deleted_edge)
|
||||
{
|
||||
e = first_deleted_edge;
|
||||
first_deleted_edge = e->succ_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = (edge) obstack_alloc (&flow_obstack, sizeof *e);
|
||||
memset (e, 0, sizeof *e);
|
||||
}
|
||||
n_edges++;
|
||||
|
||||
e->succ_next = src->succ;
|
||||
e->pred_next = dst->pred;
|
||||
e->src = src;
|
||||
e->dest = dst;
|
||||
e->flags = flags;
|
||||
|
||||
src->succ = e;
|
||||
dst->pred = e;
|
||||
e = unchecked_make_edge (src, dst, flags);
|
||||
|
||||
if (use_edge_cache)
|
||||
SET_BIT (edge_cache[src->index], dst->index);
|
||||
@ -418,6 +470,8 @@ redirect_edge_succ_nodup (e, new_succ)
|
||||
{
|
||||
s->flags |= e->flags;
|
||||
s->probability += e->probability;
|
||||
if (s->probability > REG_BR_PROB_BASE)
|
||||
s->probability = REG_BR_PROB_BASE;
|
||||
s->count += e->count;
|
||||
remove_edge (e);
|
||||
e = s;
|
||||
@ -448,12 +502,23 @@ redirect_edge_pred (e, new_pred)
|
||||
new_pred->succ = e;
|
||||
e->src = new_pred;
|
||||
}
|
||||
|
||||
void
|
||||
clear_bb_flags ()
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
|
||||
bb->flags = 0;
|
||||
}
|
||||
|
||||
void
|
||||
dump_flow_info (file)
|
||||
FILE *file;
|
||||
{
|
||||
int i;
|
||||
int max_regno = max_reg_num ();
|
||||
basic_block bb;
|
||||
static const char * const reg_class_names[] = REG_CLASS_NAMES;
|
||||
|
||||
fprintf (file, "%d registers.\n", max_regno);
|
||||
@ -469,7 +534,7 @@ dump_flow_info (file)
|
||||
if (REG_N_SETS (i))
|
||||
fprintf (file, "; set %d time%s", REG_N_SETS (i),
|
||||
(REG_N_SETS (i) == 1) ? "" : "s");
|
||||
if (REG_USERVAR_P (regno_reg_rtx[i]))
|
||||
if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
|
||||
fprintf (file, "; user var");
|
||||
if (REG_N_DEATHS (i) != 1)
|
||||
fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
|
||||
@ -477,7 +542,8 @@ dump_flow_info (file)
|
||||
fprintf (file, "; crosses 1 call");
|
||||
else if (REG_N_CALLS_CROSSED (i))
|
||||
fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
|
||||
if (PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
|
||||
if (regno_reg_rtx[i] != NULL
|
||||
&& PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
|
||||
fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
|
||||
|
||||
class = reg_preferred_class (i);
|
||||
@ -494,22 +560,30 @@ dump_flow_info (file)
|
||||
reg_class_names[(int) altclass]);
|
||||
}
|
||||
|
||||
if (REG_POINTER (regno_reg_rtx[i]))
|
||||
if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
|
||||
fprintf (file, "; pointer");
|
||||
fprintf (file, ".\n");
|
||||
}
|
||||
|
||||
fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
edge e;
|
||||
int sum;
|
||||
gcov_type lsum;
|
||||
|
||||
fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
|
||||
i, INSN_UID (bb->head), INSN_UID (bb->end));
|
||||
bb->index, INSN_UID (bb->head), INSN_UID (bb->end));
|
||||
fprintf (file, "prev %d, next %d, ",
|
||||
bb->prev_bb->index, bb->next_bb->index);
|
||||
fprintf (file, "loop_depth %d, count ", bb->loop_depth);
|
||||
fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
|
||||
fprintf (file, ", freq %i.\n", bb->frequency);
|
||||
fprintf (file, ", freq %i", bb->frequency);
|
||||
if (maybe_hot_bb_p (bb))
|
||||
fprintf (file, ", maybe hot");
|
||||
if (probably_never_executed_bb_p (bb))
|
||||
fprintf (file, ", probably never executed");
|
||||
fprintf (file, ".\n");
|
||||
|
||||
fprintf (file, "Predecessors: ");
|
||||
for (e = bb->pred; e; e = e->pred_next)
|
||||
@ -526,6 +600,37 @@ dump_flow_info (file)
|
||||
dump_regset (bb->global_live_at_end, file);
|
||||
|
||||
putc ('\n', file);
|
||||
|
||||
/* Check the consistency of profile information. We can't do that
|
||||
in verify_flow_info, as the counts may get invalid for incompletely
|
||||
solved graphs, later elliminating of conditionals or roundoff errors.
|
||||
It is still practical to have them reported for debugging of simple
|
||||
testcases. */
|
||||
sum = 0;
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
sum += e->probability;
|
||||
if (bb->succ && abs (sum - REG_BR_PROB_BASE) > 100)
|
||||
fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
|
||||
sum * 100.0 / REG_BR_PROB_BASE);
|
||||
sum = 0;
|
||||
for (e = bb->pred; e; e = e->pred_next)
|
||||
sum += EDGE_FREQUENCY (e);
|
||||
if (abs (sum - bb->frequency) > 100)
|
||||
fprintf (file,
|
||||
"Invalid sum of incomming frequencies %i, should be %i\n",
|
||||
sum, bb->frequency);
|
||||
lsum = 0;
|
||||
for (e = bb->pred; e; e = e->pred_next)
|
||||
lsum += e->count;
|
||||
if (lsum - bb->count > 100 || lsum - bb->count < -100)
|
||||
fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
|
||||
(int)lsum, (int)bb->count);
|
||||
lsum = 0;
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
lsum += e->count;
|
||||
if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
|
||||
fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
|
||||
(int)lsum, (int)bb->count);
|
||||
}
|
||||
|
||||
putc ('\n', file);
|
||||
@ -564,7 +669,7 @@ dump_edge_info (file, e, do_succ)
|
||||
if (e->flags)
|
||||
{
|
||||
static const char * const bitnames[]
|
||||
= {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back"};
|
||||
= {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
|
||||
int comma = 0;
|
||||
int i, flags = e->flags;
|
||||
|
||||
@ -594,7 +699,7 @@ static void *first_block_aux_obj = 0;
|
||||
static struct obstack edge_aux_obstack;
|
||||
static void *first_edge_aux_obj = 0;
|
||||
|
||||
/* Allocate an memory block of SIZE as BB->aux. The obstack must
|
||||
/* Allocate a memory block of SIZE as BB->aux. The obstack must
|
||||
be first initialized by alloc_aux_for_blocks. */
|
||||
|
||||
inline void
|
||||
@ -630,13 +735,10 @@ alloc_aux_for_blocks (size)
|
||||
first_block_aux_obj = (char *) obstack_alloc (&block_aux_obstack, 0);
|
||||
if (size)
|
||||
{
|
||||
int i;
|
||||
basic_block bb;
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
alloc_aux_for_block (BASIC_BLOCK (i), size);
|
||||
|
||||
alloc_aux_for_block (ENTRY_BLOCK_PTR, size);
|
||||
alloc_aux_for_block (EXIT_BLOCK_PTR, size);
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
|
||||
alloc_aux_for_block (bb, size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,13 +747,10 @@ alloc_aux_for_blocks (size)
|
||||
void
|
||||
clear_aux_for_blocks ()
|
||||
{
|
||||
int i;
|
||||
basic_block bb;
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
BASIC_BLOCK (i)->aux = NULL;
|
||||
|
||||
ENTRY_BLOCK_PTR->aux = NULL;
|
||||
EXIT_BLOCK_PTR->aux = NULL;
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
|
||||
bb->aux = NULL;
|
||||
}
|
||||
|
||||
/* Free data allocated in block_aux_obstack and clear AUX pointers
|
||||
@ -668,7 +767,7 @@ free_aux_for_blocks ()
|
||||
clear_aux_for_blocks ();
|
||||
}
|
||||
|
||||
/* Allocate an memory edge of SIZE as BB->aux. The obstack must
|
||||
/* Allocate a memory edge of SIZE as BB->aux. The obstack must
|
||||
be first initialized by alloc_aux_for_edges. */
|
||||
|
||||
inline void
|
||||
@ -705,16 +804,11 @@ alloc_aux_for_edges (size)
|
||||
first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0);
|
||||
if (size)
|
||||
{
|
||||
int i;
|
||||
for (i = -1; i < n_basic_blocks; i++)
|
||||
{
|
||||
basic_block bb;
|
||||
edge e;
|
||||
basic_block bb;
|
||||
|
||||
if (i >= 0)
|
||||
bb = BASIC_BLOCK (i);
|
||||
else
|
||||
bb = ENTRY_BLOCK_PTR;
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
|
||||
{
|
||||
edge e;
|
||||
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
alloc_aux_for_edge (e, size);
|
||||
@ -727,18 +821,11 @@ alloc_aux_for_edges (size)
|
||||
void
|
||||
clear_aux_for_edges ()
|
||||
{
|
||||
int i;
|
||||
basic_block bb;
|
||||
edge e;
|
||||
|
||||
for (i = -1; i < n_basic_blocks; i++)
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
|
||||
{
|
||||
basic_block bb;
|
||||
edge e;
|
||||
|
||||
if (i >= 0)
|
||||
bb = BASIC_BLOCK (i);
|
||||
else
|
||||
bb = ENTRY_BLOCK_PTR;
|
||||
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
e->aux = NULL;
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "insn-config.h"
|
||||
#include "recog.h"
|
||||
#include "toplev.h"
|
||||
#include "obstack.h"
|
||||
#include "tm_p.h"
|
||||
|
||||
/* Store the data structures necessary for depth-first search. */
|
||||
@ -55,7 +54,6 @@ static void flow_dfs_compute_reverse_finish
|
||||
PARAMS ((depth_first_search_ds));
|
||||
static void remove_fake_successors PARAMS ((basic_block));
|
||||
static bool need_fake_edge_p PARAMS ((rtx));
|
||||
static bool keep_with_call_p PARAMS ((rtx));
|
||||
static bool flow_active_insn_p PARAMS ((rtx));
|
||||
|
||||
/* Like active_insn_p, except keep the return value clobber around
|
||||
@ -69,7 +67,7 @@ flow_active_insn_p (insn)
|
||||
return true;
|
||||
|
||||
/* A clobber of the function return value exists for buggy
|
||||
programs that fail to return a value. It's effect is to
|
||||
programs that fail to return a value. Its effect is to
|
||||
keep the return value from being live across the entire
|
||||
function. If we allow it to be skipped, we introduce the
|
||||
possibility for register livetime aborts. */
|
||||
@ -112,7 +110,10 @@ can_fallthru (src, target)
|
||||
rtx insn = src->end;
|
||||
rtx insn2 = target->head;
|
||||
|
||||
if (src->index + 1 == target->index && !active_insn_p (insn2))
|
||||
if (src->next_bb != target)
|
||||
return 0;
|
||||
|
||||
if (!active_insn_p (insn2))
|
||||
insn2 = next_active_insn (insn2);
|
||||
|
||||
/* ??? Later we may add code to move jump tables offline. */
|
||||
@ -120,7 +121,7 @@ can_fallthru (src, target)
|
||||
}
|
||||
|
||||
/* Mark the back edges in DFS traversal.
|
||||
Return non-zero if a loop (natural or otherwise) is present.
|
||||
Return nonzero if a loop (natural or otherwise) is present.
|
||||
Inspired by Depth_First_Search_PP described in:
|
||||
|
||||
Advanced Compiler Design and Implementation
|
||||
@ -142,15 +143,15 @@ mark_dfs_back_edges ()
|
||||
bool found = false;
|
||||
|
||||
/* Allocate the preorder and postorder number arrays. */
|
||||
pre = (int *) xcalloc (n_basic_blocks, sizeof (int));
|
||||
post = (int *) xcalloc (n_basic_blocks, sizeof (int));
|
||||
pre = (int *) xcalloc (last_basic_block, sizeof (int));
|
||||
post = (int *) xcalloc (last_basic_block, sizeof (int));
|
||||
|
||||
/* Allocate stack for back-tracking up CFG. */
|
||||
stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
|
||||
sp = 0;
|
||||
|
||||
/* Allocate bitmap to track nodes that have been visited. */
|
||||
visited = sbitmap_alloc (n_basic_blocks);
|
||||
visited = sbitmap_alloc (last_basic_block);
|
||||
|
||||
/* None of the nodes in the CFG have been visited yet. */
|
||||
sbitmap_zero (visited);
|
||||
@ -211,6 +212,40 @@ mark_dfs_back_edges ()
|
||||
return found;
|
||||
}
|
||||
|
||||
/* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */
|
||||
|
||||
void
|
||||
set_edge_can_fallthru_flag ()
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
edge e;
|
||||
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
{
|
||||
e->flags &= ~EDGE_CAN_FALLTHRU;
|
||||
|
||||
/* The FALLTHRU edge is also CAN_FALLTHRU edge. */
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
e->flags |= EDGE_CAN_FALLTHRU;
|
||||
}
|
||||
|
||||
/* If the BB ends with an invertable condjump all (2) edges are
|
||||
CAN_FALLTHRU edges. */
|
||||
if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
|
||||
continue;
|
||||
if (!any_condjump_p (bb->end))
|
||||
continue;
|
||||
if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
|
||||
continue;
|
||||
invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
|
||||
bb->succ->flags |= EDGE_CAN_FALLTHRU;
|
||||
bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if we need to add fake edge to exit.
|
||||
Helper function for the flow_call_edges_add. */
|
||||
|
||||
@ -236,32 +271,6 @@ need_fake_edge_p (insn)
|
||||
|| GET_CODE (PATTERN (insn)) == ASM_INPUT);
|
||||
}
|
||||
|
||||
/* Return true if INSN should be kept in the same block as a preceding call.
|
||||
This is done for a single-set whose destination is a fixed register or
|
||||
whose source is the function return value. This is a helper function for
|
||||
flow_call_edges_add. */
|
||||
|
||||
static bool
|
||||
keep_with_call_p (insn)
|
||||
rtx insn;
|
||||
{
|
||||
rtx set;
|
||||
|
||||
if (INSN_P (insn) && (set = single_set (insn)) != NULL)
|
||||
{
|
||||
if (GET_CODE (SET_DEST (set)) == REG
|
||||
&& fixed_regs[REGNO (SET_DEST (set))]
|
||||
&& general_operand (SET_SRC (set), VOIDmode))
|
||||
return true;
|
||||
if (GET_CODE (SET_SRC (set)) == REG
|
||||
&& FUNCTION_VALUE_REGNO_P (REGNO (SET_SRC (set)))
|
||||
&& GET_CODE (SET_DEST (set)) == REG
|
||||
&& REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add fake edges to the function exit for any non constant and non noreturn
|
||||
calls, volatile inline assembly in the bitmap of blocks specified by
|
||||
BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
|
||||
@ -276,29 +285,16 @@ flow_call_edges_add (blocks)
|
||||
{
|
||||
int i;
|
||||
int blocks_split = 0;
|
||||
int bb_num = 0;
|
||||
basic_block *bbs;
|
||||
int last_bb = last_basic_block;
|
||||
bool check_last_block = false;
|
||||
|
||||
/* Map bb indices into basic block pointers since split_block
|
||||
will renumber the basic blocks. */
|
||||
|
||||
bbs = xmalloc (n_basic_blocks * sizeof (*bbs));
|
||||
if (n_basic_blocks == 0)
|
||||
return 0;
|
||||
|
||||
if (! blocks)
|
||||
{
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
bbs[bb_num++] = BASIC_BLOCK (i);
|
||||
|
||||
check_last_block = true;
|
||||
}
|
||||
check_last_block = true;
|
||||
else
|
||||
EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
|
||||
{
|
||||
bbs[bb_num++] = BASIC_BLOCK (i);
|
||||
if (i == n_basic_blocks - 1)
|
||||
check_last_block = true;
|
||||
});
|
||||
check_last_block = TEST_BIT (blocks, EXIT_BLOCK_PTR->prev_bb->index);
|
||||
|
||||
/* In the last basic block, before epilogue generation, there will be
|
||||
a fallthru edge to EXIT. Special care is required if the last insn
|
||||
@ -314,7 +310,7 @@ flow_call_edges_add (blocks)
|
||||
Handle this by adding a dummy instruction in a new last basic block. */
|
||||
if (check_last_block)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (n_basic_blocks - 1);
|
||||
basic_block bb = EXIT_BLOCK_PTR->prev_bb;
|
||||
rtx insn = bb->end;
|
||||
|
||||
/* Back up past insns that must be kept in the same block as a call. */
|
||||
@ -340,12 +336,18 @@ flow_call_edges_add (blocks)
|
||||
calls since there is no way that we can determine if they will
|
||||
return or not... */
|
||||
|
||||
for (i = 0; i < bb_num; i++)
|
||||
for (i = 0; i < last_bb; i++)
|
||||
{
|
||||
basic_block bb = bbs[i];
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
rtx insn;
|
||||
rtx prev_insn;
|
||||
|
||||
if (!bb)
|
||||
continue;
|
||||
|
||||
if (blocks && !TEST_BIT (blocks, i))
|
||||
continue;
|
||||
|
||||
for (insn = bb->end; ; insn = prev_insn)
|
||||
{
|
||||
prev_insn = PREV_INSN (insn);
|
||||
@ -375,9 +377,12 @@ flow_call_edges_add (blocks)
|
||||
|
||||
/* Note that the following may create a new basic block
|
||||
and renumber the existing basic blocks. */
|
||||
e = split_block (bb, split_at_insn);
|
||||
if (e)
|
||||
blocks_split++;
|
||||
if (split_at_insn != bb->end)
|
||||
{
|
||||
e = split_block (bb, split_at_insn);
|
||||
if (e)
|
||||
blocks_split++;
|
||||
}
|
||||
|
||||
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
|
||||
}
|
||||
@ -390,28 +395,26 @@ flow_call_edges_add (blocks)
|
||||
if (blocks_split)
|
||||
verify_flow_info ();
|
||||
|
||||
free (bbs);
|
||||
return blocks_split;
|
||||
}
|
||||
|
||||
/* Find unreachable blocks. An unreachable block will have 0 in
|
||||
the reachable bit in block->flags. A non-zero value indicates the
|
||||
the reachable bit in block->flags. A nonzero value indicates the
|
||||
block is reachable. */
|
||||
|
||||
void
|
||||
find_unreachable_blocks ()
|
||||
{
|
||||
edge e;
|
||||
int i, n;
|
||||
basic_block *tos, *worklist;
|
||||
basic_block *tos, *worklist, bb;
|
||||
|
||||
n = n_basic_blocks;
|
||||
tos = worklist = (basic_block *) xmalloc (sizeof (basic_block) * n);
|
||||
tos = worklist =
|
||||
(basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
|
||||
|
||||
/* Clear all the reachability flags. */
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
BASIC_BLOCK (i)->flags &= ~BB_REACHABLE;
|
||||
FOR_EACH_BB (bb)
|
||||
bb->flags &= ~BB_REACHABLE;
|
||||
|
||||
/* Add our starting points to the worklist. Almost always there will
|
||||
be only one. It isn't inconceivable that we might one day directly
|
||||
@ -461,8 +464,8 @@ create_edge_list ()
|
||||
struct edge_list *elist;
|
||||
edge e;
|
||||
int num_edges;
|
||||
int x;
|
||||
int block_count;
|
||||
basic_block bb;
|
||||
|
||||
block_count = n_basic_blocks + 2; /* Include the entry and exit blocks. */
|
||||
|
||||
@ -470,18 +473,12 @@ create_edge_list ()
|
||||
|
||||
/* Determine the number of edges in the flow graph by counting successor
|
||||
edges on each basic block. */
|
||||
for (x = 0; x < n_basic_blocks; x++)
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (x);
|
||||
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
num_edges++;
|
||||
}
|
||||
|
||||
/* Don't forget successors of the entry block. */
|
||||
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
|
||||
num_edges++;
|
||||
|
||||
elist = (struct edge_list *) xmalloc (sizeof (struct edge_list));
|
||||
elist->num_blocks = block_count;
|
||||
elist->num_edges = num_edges;
|
||||
@ -489,18 +486,10 @@ create_edge_list ()
|
||||
|
||||
num_edges = 0;
|
||||
|
||||
/* Follow successors of the entry block, and register these edges. */
|
||||
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
|
||||
elist->index_to_edge[num_edges++] = e;
|
||||
|
||||
for (x = 0; x < n_basic_blocks; x++)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (x);
|
||||
|
||||
/* Follow all successors of blocks, and register these edges. */
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
elist->index_to_edge[num_edges++] = e;
|
||||
}
|
||||
/* Follow successors of blocks, and register these edges. */
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
elist->index_to_edge[num_edges++] = e;
|
||||
|
||||
return elist;
|
||||
}
|
||||
@ -554,13 +543,12 @@ verify_edge_list (f, elist)
|
||||
FILE *f;
|
||||
struct edge_list *elist;
|
||||
{
|
||||
int x, pred, succ, index;
|
||||
int pred, succ, index;
|
||||
edge e;
|
||||
basic_block bb, p, s;
|
||||
|
||||
for (x = 0; x < n_basic_blocks; x++)
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (x);
|
||||
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
{
|
||||
pred = e->src->index;
|
||||
@ -581,33 +569,12 @@ verify_edge_list (f, elist)
|
||||
}
|
||||
}
|
||||
|
||||
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
|
||||
{
|
||||
pred = e->src->index;
|
||||
succ = e->dest->index;
|
||||
index = EDGE_INDEX (elist, e->src, e->dest);
|
||||
if (index == EDGE_INDEX_NO_EDGE)
|
||||
{
|
||||
fprintf (f, "*p* No index for edge from %d to %d\n", pred, succ);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (INDEX_EDGE_PRED_BB (elist, index)->index != pred)
|
||||
fprintf (f, "*p* Pred for index %d should be %d not %d\n",
|
||||
index, pred, INDEX_EDGE_PRED_BB (elist, index)->index);
|
||||
if (INDEX_EDGE_SUCC_BB (elist, index)->index != succ)
|
||||
fprintf (f, "*p* Succ for index %d should be %d not %d\n",
|
||||
index, succ, INDEX_EDGE_SUCC_BB (elist, index)->index);
|
||||
}
|
||||
|
||||
/* We've verified that all the edges are in the list, no lets make sure
|
||||
/* We've verified that all the edges are in the list, now lets make sure
|
||||
there are no spurious edges in the list. */
|
||||
|
||||
for (pred = 0; pred < n_basic_blocks; pred++)
|
||||
for (succ = 0; succ < n_basic_blocks; succ++)
|
||||
FOR_BB_BETWEEN (p, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
|
||||
FOR_BB_BETWEEN (s, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
|
||||
{
|
||||
basic_block p = BASIC_BLOCK (pred);
|
||||
basic_block s = BASIC_BLOCK (succ);
|
||||
int found_edge = 0;
|
||||
|
||||
for (e = p->succ; e; e = e->succ_next)
|
||||
@ -624,78 +591,15 @@ verify_edge_list (f, elist)
|
||||
break;
|
||||
}
|
||||
|
||||
if (EDGE_INDEX (elist, BASIC_BLOCK (pred), BASIC_BLOCK (succ))
|
||||
if (EDGE_INDEX (elist, p, s)
|
||||
== EDGE_INDEX_NO_EDGE && found_edge != 0)
|
||||
fprintf (f, "*** Edge (%d, %d) appears to not have an index\n",
|
||||
pred, succ);
|
||||
if (EDGE_INDEX (elist, BASIC_BLOCK (pred), BASIC_BLOCK (succ))
|
||||
p->index, s->index);
|
||||
if (EDGE_INDEX (elist, p, s)
|
||||
!= EDGE_INDEX_NO_EDGE && found_edge == 0)
|
||||
fprintf (f, "*** Edge (%d, %d) has index %d, but there is no edge\n",
|
||||
pred, succ, EDGE_INDEX (elist, BASIC_BLOCK (pred),
|
||||
BASIC_BLOCK (succ)));
|
||||
p->index, s->index, EDGE_INDEX (elist, p, s));
|
||||
}
|
||||
|
||||
for (succ = 0; succ < n_basic_blocks; succ++)
|
||||
{
|
||||
basic_block p = ENTRY_BLOCK_PTR;
|
||||
basic_block s = BASIC_BLOCK (succ);
|
||||
int found_edge = 0;
|
||||
|
||||
for (e = p->succ; e; e = e->succ_next)
|
||||
if (e->dest == s)
|
||||
{
|
||||
found_edge = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (e = s->pred; e; e = e->pred_next)
|
||||
if (e->src == p)
|
||||
{
|
||||
found_edge = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (EDGE_INDEX (elist, ENTRY_BLOCK_PTR, BASIC_BLOCK (succ))
|
||||
== EDGE_INDEX_NO_EDGE && found_edge != 0)
|
||||
fprintf (f, "*** Edge (entry, %d) appears to not have an index\n",
|
||||
succ);
|
||||
if (EDGE_INDEX (elist, ENTRY_BLOCK_PTR, BASIC_BLOCK (succ))
|
||||
!= EDGE_INDEX_NO_EDGE && found_edge == 0)
|
||||
fprintf (f, "*** Edge (entry, %d) has index %d, but no edge exists\n",
|
||||
succ, EDGE_INDEX (elist, ENTRY_BLOCK_PTR,
|
||||
BASIC_BLOCK (succ)));
|
||||
}
|
||||
|
||||
for (pred = 0; pred < n_basic_blocks; pred++)
|
||||
{
|
||||
basic_block p = BASIC_BLOCK (pred);
|
||||
basic_block s = EXIT_BLOCK_PTR;
|
||||
int found_edge = 0;
|
||||
|
||||
for (e = p->succ; e; e = e->succ_next)
|
||||
if (e->dest == s)
|
||||
{
|
||||
found_edge = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (e = s->pred; e; e = e->pred_next)
|
||||
if (e->src == p)
|
||||
{
|
||||
found_edge = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (EDGE_INDEX (elist, BASIC_BLOCK (pred), EXIT_BLOCK_PTR)
|
||||
== EDGE_INDEX_NO_EDGE && found_edge != 0)
|
||||
fprintf (f, "*** Edge (%d, exit) appears to not have an index\n",
|
||||
pred);
|
||||
if (EDGE_INDEX (elist, BASIC_BLOCK (pred), EXIT_BLOCK_PTR)
|
||||
!= EDGE_INDEX_NO_EDGE && found_edge == 0)
|
||||
fprintf (f, "*** Edge (%d, exit) has index %d, but no edge exists\n",
|
||||
pred, EDGE_INDEX (elist, BASIC_BLOCK (pred),
|
||||
EXIT_BLOCK_PTR));
|
||||
}
|
||||
}
|
||||
|
||||
/* This routine will determine what, if any, edge there is between
|
||||
@ -784,13 +688,10 @@ remove_fake_successors (bb)
|
||||
void
|
||||
remove_fake_edges ()
|
||||
{
|
||||
int x;
|
||||
basic_block bb;
|
||||
|
||||
for (x = 0; x < n_basic_blocks; x++)
|
||||
remove_fake_successors (BASIC_BLOCK (x));
|
||||
|
||||
/* We've handled all successors except the entry block's. */
|
||||
remove_fake_successors (ENTRY_BLOCK_PTR);
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
|
||||
remove_fake_successors (bb);
|
||||
}
|
||||
|
||||
/* This function will add a fake edge between any block which has no
|
||||
@ -800,11 +701,11 @@ remove_fake_edges ()
|
||||
void
|
||||
add_noreturn_fake_exit_edges ()
|
||||
{
|
||||
int x;
|
||||
basic_block bb;
|
||||
|
||||
for (x = 0; x < n_basic_blocks; x++)
|
||||
if (BASIC_BLOCK (x)->succ == NULL)
|
||||
make_single_succ_edge (BASIC_BLOCK (x), EXIT_BLOCK_PTR, EDGE_FAKE);
|
||||
FOR_EACH_BB (bb)
|
||||
if (bb->succ == NULL)
|
||||
make_single_succ_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
|
||||
}
|
||||
|
||||
/* This function adds a fake edge between any infinite loops to the
|
||||
@ -860,7 +761,7 @@ flow_reverse_top_sort_order_compute (rts_order)
|
||||
sp = 0;
|
||||
|
||||
/* Allocate bitmap to track nodes that have been visited. */
|
||||
visited = sbitmap_alloc (n_basic_blocks);
|
||||
visited = sbitmap_alloc (last_basic_block);
|
||||
|
||||
/* None of the nodes in the CFG have been visited yet. */
|
||||
sbitmap_zero (visited);
|
||||
@ -909,8 +810,8 @@ flow_reverse_top_sort_order_compute (rts_order)
|
||||
}
|
||||
|
||||
/* Compute the depth first search order and store in the array
|
||||
DFS_ORDER if non-zero, marking the nodes visited in VISITED. If
|
||||
RC_ORDER is non-zero, return the reverse completion number for each
|
||||
DFS_ORDER if nonzero, marking the nodes visited in VISITED. If
|
||||
RC_ORDER is nonzero, return the reverse completion number for each
|
||||
node. Returns the number of nodes visited. A depth first search
|
||||
tries to get as far away from the starting point as quickly as
|
||||
possible. */
|
||||
@ -931,7 +832,7 @@ flow_depth_first_order_compute (dfs_order, rc_order)
|
||||
sp = 0;
|
||||
|
||||
/* Allocate bitmap to track nodes that have been visited. */
|
||||
visited = sbitmap_alloc (n_basic_blocks);
|
||||
visited = sbitmap_alloc (last_basic_block);
|
||||
|
||||
/* None of the nodes in the CFG have been visited yet. */
|
||||
sbitmap_zero (visited);
|
||||
@ -1030,22 +931,23 @@ flow_preorder_transversal_compute (pot_order)
|
||||
sbitmap visited;
|
||||
struct dfst_node *node;
|
||||
struct dfst_node *dfst;
|
||||
basic_block bb;
|
||||
|
||||
/* Allocate stack for back-tracking up CFG. */
|
||||
stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
|
||||
sp = 0;
|
||||
|
||||
/* Allocate the tree. */
|
||||
dfst = (struct dfst_node *) xcalloc (n_basic_blocks,
|
||||
dfst = (struct dfst_node *) xcalloc (last_basic_block,
|
||||
sizeof (struct dfst_node));
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
max_successors = 0;
|
||||
for (e = BASIC_BLOCK (i)->succ; e; e = e->succ_next)
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
max_successors++;
|
||||
|
||||
dfst[i].node
|
||||
dfst[bb->index].node
|
||||
= (max_successors
|
||||
? (struct dfst_node **) xcalloc (max_successors,
|
||||
sizeof (struct dfst_node *))
|
||||
@ -1053,7 +955,7 @@ flow_preorder_transversal_compute (pot_order)
|
||||
}
|
||||
|
||||
/* Allocate bitmap to track nodes that have been visited. */
|
||||
visited = sbitmap_alloc (n_basic_blocks);
|
||||
visited = sbitmap_alloc (last_basic_block);
|
||||
|
||||
/* None of the nodes in the CFG have been visited yet. */
|
||||
sbitmap_zero (visited);
|
||||
@ -1104,7 +1006,7 @@ flow_preorder_transversal_compute (pot_order)
|
||||
walking the tree from right to left. */
|
||||
|
||||
i = 0;
|
||||
node = &dfst[0];
|
||||
node = &dfst[ENTRY_BLOCK_PTR->next_bb->index];
|
||||
pot_order[i++] = 0;
|
||||
|
||||
while (node)
|
||||
@ -1120,7 +1022,7 @@ flow_preorder_transversal_compute (pot_order)
|
||||
|
||||
/* Free the tree. */
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
for (i = 0; i < last_basic_block; i++)
|
||||
if (dfst[i].node)
|
||||
free (dfst[i].node);
|
||||
|
||||
@ -1154,7 +1056,7 @@ flow_preorder_transversal_compute (pot_order)
|
||||
/* Initialize the data structures used for depth-first search on the
|
||||
reverse graph. If INITIALIZE_STACK is nonzero, the exit block is
|
||||
added to the basic block stack. DATA is the current depth-first
|
||||
search context. If INITIALIZE_STACK is non-zero, there is an
|
||||
search context. If INITIALIZE_STACK is nonzero, there is an
|
||||
element on the stack. */
|
||||
|
||||
static void
|
||||
@ -1167,7 +1069,7 @@ flow_dfs_compute_reverse_init (data)
|
||||
data->sp = 0;
|
||||
|
||||
/* Allocate bitmap to track nodes that have been visited. */
|
||||
data->visited_blocks = sbitmap_alloc (n_basic_blocks - (INVALID_BLOCK + 1));
|
||||
data->visited_blocks = sbitmap_alloc (last_basic_block - (INVALID_BLOCK + 1));
|
||||
|
||||
/* None of the nodes in the CFG have been visited yet. */
|
||||
sbitmap_zero (data->visited_blocks);
|
||||
@ -1199,7 +1101,6 @@ flow_dfs_compute_reverse_execute (data)
|
||||
{
|
||||
basic_block bb;
|
||||
edge e;
|
||||
int i;
|
||||
|
||||
while (data->sp > 0)
|
||||
{
|
||||
@ -1213,9 +1114,9 @@ flow_dfs_compute_reverse_execute (data)
|
||||
}
|
||||
|
||||
/* Determine if there are unvisited basic blocks. */
|
||||
for (i = n_basic_blocks - (INVALID_BLOCK + 1); --i >= 0; )
|
||||
if (!TEST_BIT (data->visited_blocks, i))
|
||||
return BASIC_BLOCK (i + (INVALID_BLOCK + 1));
|
||||
FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
|
||||
if (!TEST_BIT (data->visited_blocks, bb->index - (INVALID_BLOCK + 1)))
|
||||
return bb;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -1230,3 +1131,54 @@ flow_dfs_compute_reverse_finish (data)
|
||||
free (data->stack);
|
||||
sbitmap_free (data->visited_blocks);
|
||||
}
|
||||
|
||||
/* Performs dfs search from BB over vertices satisfying PREDICATE;
|
||||
if REVERSE, go against direction of edges. Returns number of blocks
|
||||
found and their list in RSLT. RSLT can contain at most RSLT_MAX items. */
|
||||
int
|
||||
dfs_enumerate_from (bb, reverse, predicate, rslt, rslt_max, data)
|
||||
basic_block bb;
|
||||
int reverse;
|
||||
bool (*predicate) PARAMS ((basic_block, void *));
|
||||
basic_block *rslt;
|
||||
int rslt_max;
|
||||
void *data;
|
||||
{
|
||||
basic_block *st, lbb;
|
||||
int sp = 0, tv = 0;
|
||||
|
||||
st = xcalloc (rslt_max, sizeof (basic_block));
|
||||
rslt[tv++] = st[sp++] = bb;
|
||||
bb->flags |= BB_VISITED;
|
||||
while (sp)
|
||||
{
|
||||
edge e;
|
||||
lbb = st[--sp];
|
||||
if (reverse)
|
||||
{
|
||||
for (e = lbb->pred; e; e = e->pred_next)
|
||||
if (!(e->src->flags & BB_VISITED) && predicate (e->src, data))
|
||||
{
|
||||
if (tv == rslt_max)
|
||||
abort ();
|
||||
rslt[tv++] = st[sp++] = e->src;
|
||||
e->src->flags |= BB_VISITED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (e = lbb->succ; e; e = e->succ_next)
|
||||
if (!(e->dest->flags & BB_VISITED) && predicate (e->dest, data))
|
||||
{
|
||||
if (tv == rslt_max)
|
||||
abort ();
|
||||
rslt[tv++] = st[sp++] = e->dest;
|
||||
e->dest->flags |= BB_VISITED;
|
||||
}
|
||||
}
|
||||
}
|
||||
free (st);
|
||||
for (sp = 0; sp < tv; sp++)
|
||||
rslt[sp]->flags &= ~BB_VISITED;
|
||||
return tv;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Control flow graph building code for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -45,12 +45,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "except.h"
|
||||
#include "toplev.h"
|
||||
#include "timevar.h"
|
||||
#include "obstack.h"
|
||||
|
||||
static int count_basic_blocks PARAMS ((rtx));
|
||||
static void find_basic_blocks_1 PARAMS ((rtx));
|
||||
static rtx find_label_refs PARAMS ((rtx, rtx));
|
||||
static void make_edges PARAMS ((rtx, int, int, int));
|
||||
static void make_edges PARAMS ((rtx, basic_block,
|
||||
basic_block, int));
|
||||
static void make_label_edge PARAMS ((sbitmap *, basic_block,
|
||||
rtx, int));
|
||||
static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx));
|
||||
@ -102,35 +102,35 @@ control_flow_insn_p (insn)
|
||||
|
||||
switch (GET_CODE (insn))
|
||||
{
|
||||
case NOTE:
|
||||
case CODE_LABEL:
|
||||
return false;
|
||||
case NOTE:
|
||||
case CODE_LABEL:
|
||||
return false;
|
||||
|
||||
case JUMP_INSN:
|
||||
/* Jump insn always causes control transfer except for tablejumps. */
|
||||
return (GET_CODE (PATTERN (insn)) != ADDR_VEC
|
||||
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
|
||||
case JUMP_INSN:
|
||||
/* Jump insn always causes control transfer except for tablejumps. */
|
||||
return (GET_CODE (PATTERN (insn)) != ADDR_VEC
|
||||
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
|
||||
|
||||
case CALL_INSN:
|
||||
/* Call insn may return to the nonlocal goto handler. */
|
||||
return ((nonlocal_goto_handler_labels
|
||||
&& (0 == (note = find_reg_note (insn, REG_EH_REGION,
|
||||
NULL_RTX))
|
||||
|| INTVAL (XEXP (note, 0)) >= 0))
|
||||
/* Or may trap. */
|
||||
|| can_throw_internal (insn));
|
||||
case CALL_INSN:
|
||||
/* Call insn may return to the nonlocal goto handler. */
|
||||
return ((nonlocal_goto_handler_labels
|
||||
&& (0 == (note = find_reg_note (insn, REG_EH_REGION,
|
||||
NULL_RTX))
|
||||
|| INTVAL (XEXP (note, 0)) >= 0))
|
||||
/* Or may trap. */
|
||||
|| can_throw_internal (insn));
|
||||
|
||||
case INSN:
|
||||
return (flag_non_call_exceptions && can_throw_internal (insn));
|
||||
case INSN:
|
||||
return (flag_non_call_exceptions && can_throw_internal (insn));
|
||||
|
||||
case BARRIER:
|
||||
/* It is nonsence to reach barrier when looking for the
|
||||
end of basic block, but before dead code is eliminated
|
||||
this may happen. */
|
||||
return false;
|
||||
case BARRIER:
|
||||
/* It is nonsence to reach barrier when looking for the
|
||||
end of basic block, but before dead code is eliminated
|
||||
this may happen. */
|
||||
return false;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,9 +205,9 @@ find_label_refs (f, lvl)
|
||||
rtx lab = XEXP (note, 0), next;
|
||||
|
||||
if ((next = next_nonnote_insn (lab)) != NULL
|
||||
&& GET_CODE (next) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
|
||||
&& GET_CODE (next) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
|
||||
;
|
||||
else if (GET_CODE (lab) == NOTE)
|
||||
;
|
||||
@ -279,9 +279,10 @@ make_eh_edge (edge_cache, src, insn)
|
||||
static void
|
||||
make_edges (label_value_list, min, max, update_p)
|
||||
rtx label_value_list;
|
||||
int min, max, update_p;
|
||||
basic_block min, max;
|
||||
int update_p;
|
||||
{
|
||||
int i;
|
||||
basic_block bb;
|
||||
sbitmap *edge_cache = NULL;
|
||||
|
||||
/* Assume no computed jump; revise as we create edges. */
|
||||
@ -290,35 +291,35 @@ make_edges (label_value_list, min, max, update_p)
|
||||
/* Heavy use of computed goto in machine-generated code can lead to
|
||||
nearly fully-connected CFGs. In that case we spend a significant
|
||||
amount of time searching the edge lists for duplicates. */
|
||||
if (forced_labels || label_value_list)
|
||||
if (forced_labels || label_value_list || cfun->max_jumptable_ents > 100)
|
||||
{
|
||||
edge_cache = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
|
||||
sbitmap_vector_zero (edge_cache, n_basic_blocks);
|
||||
edge_cache = sbitmap_vector_alloc (last_basic_block, last_basic_block);
|
||||
sbitmap_vector_zero (edge_cache, last_basic_block);
|
||||
|
||||
if (update_p)
|
||||
for (i = min; i <= max; ++i)
|
||||
FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
|
||||
{
|
||||
edge e;
|
||||
|
||||
for (e = BASIC_BLOCK (i)->succ; e ; e = e->succ_next)
|
||||
for (e = bb->succ; e ; e = e->succ_next)
|
||||
if (e->dest != EXIT_BLOCK_PTR)
|
||||
SET_BIT (edge_cache[i], e->dest->index);
|
||||
SET_BIT (edge_cache[bb->index], e->dest->index);
|
||||
}
|
||||
}
|
||||
|
||||
/* By nature of the way these get numbered, block 0 is always the entry. */
|
||||
if (min == 0)
|
||||
cached_make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0),
|
||||
/* By nature of the way these get numbered, ENTRY_BLOCK_PTR->next_bb block
|
||||
is always the entry. */
|
||||
if (min == ENTRY_BLOCK_PTR->next_bb)
|
||||
cached_make_edge (edge_cache, ENTRY_BLOCK_PTR, min,
|
||||
EDGE_FALLTHRU);
|
||||
|
||||
for (i = min; i <= max; ++i)
|
||||
FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
rtx insn, x;
|
||||
enum rtx_code code;
|
||||
int force_fallthru = 0;
|
||||
|
||||
if (GET_CODE (bb->head) == CODE_LABEL && LABEL_ALTERNATE_NAME (bb->head))
|
||||
if (GET_CODE (bb->head) == CODE_LABEL && LABEL_ALT_ENTRY_P (bb->head))
|
||||
cached_make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
|
||||
|
||||
/* Examine the last instruction of the block, and discover the
|
||||
@ -442,16 +443,15 @@ make_edges (label_value_list, min, max, update_p)
|
||||
|
||||
/* Find out if we can drop through to the next block. */
|
||||
insn = next_nonnote_insn (insn);
|
||||
if (!insn || (i + 1 == n_basic_blocks && force_fallthru))
|
||||
if (!insn || (bb->next_bb == EXIT_BLOCK_PTR && force_fallthru))
|
||||
cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
|
||||
else if (i + 1 < n_basic_blocks)
|
||||
else if (bb->next_bb != EXIT_BLOCK_PTR)
|
||||
{
|
||||
rtx tmp = BLOCK_HEAD (i + 1);
|
||||
rtx tmp = bb->next_bb->head;
|
||||
if (GET_CODE (tmp) == NOTE)
|
||||
tmp = next_nonnote_insn (tmp);
|
||||
if (force_fallthru || insn == tmp)
|
||||
cached_make_edge (edge_cache, bb, BASIC_BLOCK (i + 1),
|
||||
EDGE_FALLTHRU);
|
||||
cached_make_edge (edge_cache, bb, bb->next_bb, EDGE_FALLTHRU);
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,12 +469,12 @@ find_basic_blocks_1 (f)
|
||||
rtx f;
|
||||
{
|
||||
rtx insn, next;
|
||||
int i = 0;
|
||||
rtx bb_note = NULL_RTX;
|
||||
rtx lvl = NULL_RTX;
|
||||
rtx trll = NULL_RTX;
|
||||
rtx head = NULL_RTX;
|
||||
rtx end = NULL_RTX;
|
||||
basic_block prev = ENTRY_BLOCK_PTR;
|
||||
|
||||
/* We process the instructions in a slightly different way than we did
|
||||
previously. This is so that we see a NOTE_BASIC_BLOCK after we have
|
||||
@ -491,7 +491,7 @@ find_basic_blocks_1 (f)
|
||||
if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER)
|
||||
&& head)
|
||||
{
|
||||
create_basic_block_structure (i++, head, end, bb_note);
|
||||
prev = create_basic_block_structure (head, end, bb_note, prev);
|
||||
head = end = NULL_RTX;
|
||||
bb_note = NULL_RTX;
|
||||
}
|
||||
@ -505,7 +505,7 @@ find_basic_blocks_1 (f)
|
||||
|
||||
if (head && control_flow_insn_p (insn))
|
||||
{
|
||||
create_basic_block_structure (i++, head, end, bb_note);
|
||||
prev = create_basic_block_structure (head, end, bb_note, prev);
|
||||
head = end = NULL_RTX;
|
||||
bb_note = NULL_RTX;
|
||||
}
|
||||
@ -587,15 +587,16 @@ find_basic_blocks_1 (f)
|
||||
}
|
||||
|
||||
if (head != NULL_RTX)
|
||||
create_basic_block_structure (i++, head, end, bb_note);
|
||||
create_basic_block_structure (head, end, bb_note, prev);
|
||||
else if (bb_note)
|
||||
delete_insn (bb_note);
|
||||
|
||||
if (i != n_basic_blocks)
|
||||
if (last_basic_block != n_basic_blocks)
|
||||
abort ();
|
||||
|
||||
label_value_list = lvl;
|
||||
tail_recursion_label_list = trll;
|
||||
clear_aux_for_blocks ();
|
||||
}
|
||||
|
||||
|
||||
@ -609,28 +610,28 @@ find_basic_blocks (f, nregs, file)
|
||||
int nregs ATTRIBUTE_UNUSED;
|
||||
FILE *file ATTRIBUTE_UNUSED;
|
||||
{
|
||||
int max_uid;
|
||||
timevar_push (TV_CFG);
|
||||
basic_block bb;
|
||||
|
||||
basic_block_for_insn = 0;
|
||||
timevar_push (TV_CFG);
|
||||
|
||||
/* Flush out existing data. */
|
||||
if (basic_block_info != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
clear_edges ();
|
||||
|
||||
/* Clear bb->aux on all extant basic blocks. We'll use this as a
|
||||
tag for reuse during create_basic_block, just in case some pass
|
||||
copies around basic block notes improperly. */
|
||||
for (i = 0; i < n_basic_blocks; ++i)
|
||||
BASIC_BLOCK (i)->aux = NULL;
|
||||
FOR_EACH_BB (bb)
|
||||
bb->aux = NULL;
|
||||
|
||||
VARRAY_FREE (basic_block_info);
|
||||
}
|
||||
|
||||
n_basic_blocks = count_basic_blocks (f);
|
||||
last_basic_block = 0;
|
||||
ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
|
||||
EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
|
||||
|
||||
/* Size the basic block table. The actual structures will be allocated
|
||||
by find_basic_blocks_1, since we want to keep the structure pointers
|
||||
@ -644,22 +645,8 @@ find_basic_blocks (f, nregs, file)
|
||||
|
||||
find_basic_blocks_1 (f);
|
||||
|
||||
/* Record the block to which an insn belongs. */
|
||||
/* ??? This should be done another way, by which (perhaps) a label is
|
||||
tagged directly with the basic block that it starts. It is used for
|
||||
more than that currently, but IMO that is the only valid use. */
|
||||
|
||||
max_uid = get_max_uid ();
|
||||
#ifdef AUTO_INC_DEC
|
||||
/* Leave space for insns life_analysis makes in some cases for auto-inc.
|
||||
These cases are rare, so we don't need too much space. */
|
||||
max_uid += max_uid / 10;
|
||||
#endif
|
||||
|
||||
compute_bb_for_insn (max_uid);
|
||||
|
||||
/* Discover the edges of our cfg. */
|
||||
make_edges (label_value_list, 0, n_basic_blocks - 1, 0);
|
||||
make_edges (label_value_list, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, 0);
|
||||
|
||||
/* Do very simple cleanup now, for the benefit of code that runs between
|
||||
here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns. */
|
||||
@ -710,7 +697,7 @@ find_bb_boundaries (bb)
|
||||
bb = fallthru->dest;
|
||||
remove_edge (fallthru);
|
||||
flow_transfer_insn = NULL_RTX;
|
||||
if (LABEL_ALTERNATE_NAME (insn))
|
||||
if (LABEL_ALT_ENTRY_P (insn))
|
||||
make_edge (ENTRY_BLOCK_PTR, bb, 0);
|
||||
}
|
||||
|
||||
@ -788,25 +775,24 @@ void
|
||||
find_many_sub_basic_blocks (blocks)
|
||||
sbitmap blocks;
|
||||
{
|
||||
int i;
|
||||
int min, max;
|
||||
basic_block bb, min, max;
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
SET_STATE (BASIC_BLOCK (i),
|
||||
TEST_BIT (blocks, i) ? BLOCK_TO_SPLIT : BLOCK_ORIGINAL);
|
||||
FOR_EACH_BB (bb)
|
||||
SET_STATE (bb,
|
||||
TEST_BIT (blocks, bb->index) ? BLOCK_TO_SPLIT : BLOCK_ORIGINAL);
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
if (STATE (BASIC_BLOCK (i)) == BLOCK_TO_SPLIT)
|
||||
find_bb_boundaries (BASIC_BLOCK (i));
|
||||
FOR_EACH_BB (bb)
|
||||
if (STATE (bb) == BLOCK_TO_SPLIT)
|
||||
find_bb_boundaries (bb);
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
if (STATE (BASIC_BLOCK (i)) != BLOCK_ORIGINAL)
|
||||
FOR_EACH_BB (bb)
|
||||
if (STATE (bb) != BLOCK_ORIGINAL)
|
||||
break;
|
||||
|
||||
min = max = i;
|
||||
for (; i < n_basic_blocks; i++)
|
||||
if (STATE (BASIC_BLOCK (i)) != BLOCK_ORIGINAL)
|
||||
max = i;
|
||||
min = max = bb;
|
||||
for (; bb != EXIT_BLOCK_PTR; bb = bb->next_bb)
|
||||
if (STATE (bb) != BLOCK_ORIGINAL)
|
||||
max = bb;
|
||||
|
||||
/* Now re-scan and wire in all edges. This expect simple (conditional)
|
||||
jumps at the end of each new basic blocks. */
|
||||
@ -814,45 +800,42 @@ find_many_sub_basic_blocks (blocks)
|
||||
|
||||
/* Update branch probabilities. Expect only (un)conditional jumps
|
||||
to be created with only the forward edges. */
|
||||
for (i = min; i <= max; i++)
|
||||
FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
|
||||
{
|
||||
edge e;
|
||||
basic_block b = BASIC_BLOCK (i);
|
||||
|
||||
if (STATE (b) == BLOCK_ORIGINAL)
|
||||
if (STATE (bb) == BLOCK_ORIGINAL)
|
||||
continue;
|
||||
if (STATE (b) == BLOCK_NEW)
|
||||
if (STATE (bb) == BLOCK_NEW)
|
||||
{
|
||||
b->count = 0;
|
||||
b->frequency = 0;
|
||||
for (e = b->pred; e; e=e->pred_next)
|
||||
bb->count = 0;
|
||||
bb->frequency = 0;
|
||||
for (e = bb->pred; e; e=e->pred_next)
|
||||
{
|
||||
b->count += e->count;
|
||||
b->frequency += EDGE_FREQUENCY (e);
|
||||
bb->count += e->count;
|
||||
bb->frequency += EDGE_FREQUENCY (e);
|
||||
}
|
||||
}
|
||||
|
||||
compute_outgoing_frequencies (b);
|
||||
compute_outgoing_frequencies (bb);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
SET_STATE (BASIC_BLOCK (i), 0);
|
||||
FOR_EACH_BB (bb)
|
||||
SET_STATE (bb, 0);
|
||||
}
|
||||
|
||||
/* Like above but for single basic block only. */
|
||||
|
||||
void
|
||||
find_sub_basic_blocks (bb)
|
||||
basic_block bb;
|
||||
basic_block bb;
|
||||
{
|
||||
int i;
|
||||
int min, max;
|
||||
basic_block next = (bb->index == n_basic_blocks - 1
|
||||
? NULL : BASIC_BLOCK (bb->index + 1));
|
||||
basic_block min, max, b;
|
||||
basic_block next = bb->next_bb;
|
||||
|
||||
min = bb->index;
|
||||
min = bb;
|
||||
find_bb_boundaries (bb);
|
||||
max = (next ? next->index : n_basic_blocks) - 1;
|
||||
max = next->prev_bb;
|
||||
|
||||
/* Now re-scan and wire in all edges. This expect simple (conditional)
|
||||
jumps at the end of each new basic blocks. */
|
||||
@ -860,12 +843,11 @@ find_sub_basic_blocks (bb)
|
||||
|
||||
/* Update branch probabilities. Expect only (un)conditional jumps
|
||||
to be created with only the forward edges. */
|
||||
for (i = min; i <= max; i++)
|
||||
FOR_BB_BETWEEN (b, min, max->next_bb, next_bb)
|
||||
{
|
||||
edge e;
|
||||
basic_block b = BASIC_BLOCK (i);
|
||||
|
||||
if (i != min)
|
||||
if (b != min)
|
||||
{
|
||||
b->count = 0;
|
||||
b->frequency = 0;
|
||||
|
@ -43,20 +43,18 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "recog.h"
|
||||
#include "toplev.h"
|
||||
#include "cselib.h"
|
||||
#include "params.h"
|
||||
#include "tm_p.h"
|
||||
#include "target.h"
|
||||
|
||||
#include "obstack.h"
|
||||
|
||||
/* cleanup_cfg maintains following flags for each basic block. */
|
||||
|
||||
enum bb_flags
|
||||
{
|
||||
/* Set if life info needs to be recomputed for given BB. */
|
||||
BB_UPDATE_LIFE = 1,
|
||||
/* Set if BB is the forwarder block to avoid too many
|
||||
forwarder_block_p calls. */
|
||||
BB_FORWARDER_BLOCK = 2
|
||||
BB_FORWARDER_BLOCK = 1,
|
||||
BB_NONTHREADABLE_BLOCK = 2
|
||||
};
|
||||
|
||||
#define BB_FLAGS(BB) (enum bb_flags) (BB)->aux
|
||||
@ -75,7 +73,6 @@ static int flow_find_cross_jump PARAMS ((int, basic_block, basic_block,
|
||||
rtx *, rtx *));
|
||||
static bool insns_match_p PARAMS ((int, rtx, rtx));
|
||||
|
||||
static bool delete_unreachable_blocks PARAMS ((void));
|
||||
static bool label_is_jump_target_p PARAMS ((rtx, rtx));
|
||||
static bool tail_recursion_label_p PARAMS ((rtx));
|
||||
static void merge_blocks_move_predecessor_nojumps PARAMS ((basic_block,
|
||||
@ -91,6 +88,7 @@ static edge thread_jump PARAMS ((int, edge, basic_block));
|
||||
static bool mark_effect PARAMS ((rtx, bitmap));
|
||||
static void notice_new_block PARAMS ((basic_block));
|
||||
static void update_forwarder_flag PARAMS ((basic_block));
|
||||
static int mentions_nonequal_regs PARAMS ((rtx *, void *));
|
||||
|
||||
/* Set flags for newly created block. */
|
||||
|
||||
@ -101,7 +99,6 @@ notice_new_block (bb)
|
||||
if (!bb)
|
||||
return;
|
||||
|
||||
BB_SET_FLAG (bb, BB_UPDATE_LIFE);
|
||||
if (forwarder_block_p (bb))
|
||||
BB_SET_FLAG (bb, BB_FORWARDER_BLOCK);
|
||||
}
|
||||
@ -149,7 +146,7 @@ try_simplify_condjump (cbranch_block)
|
||||
unconditional jump. */
|
||||
jump_block = cbranch_fallthru_edge->dest;
|
||||
if (jump_block->pred->pred_next
|
||||
|| jump_block->index == n_basic_blocks - 1
|
||||
|| jump_block->next_bb == EXIT_BLOCK_PTR
|
||||
|| !FORWARDER_BLOCK_P (jump_block))
|
||||
return false;
|
||||
jump_dest_block = jump_block->succ->dest;
|
||||
@ -192,8 +189,8 @@ try_simplify_condjump (cbranch_block)
|
||||
|
||||
static bool
|
||||
mark_effect (exp, nonequal)
|
||||
rtx exp;
|
||||
regset nonequal;
|
||||
rtx exp;
|
||||
regset nonequal;
|
||||
{
|
||||
int regno;
|
||||
rtx dest;
|
||||
@ -201,43 +198,69 @@ mark_effect (exp, nonequal)
|
||||
{
|
||||
/* In case we do clobber the register, mark it as equal, as we know the
|
||||
value is dead so it don't have to match. */
|
||||
case CLOBBER:
|
||||
if (REG_P (XEXP (exp, 0)))
|
||||
{
|
||||
dest = XEXP (exp, 0);
|
||||
regno = REGNO (dest);
|
||||
CLEAR_REGNO_REG_SET (nonequal, regno);
|
||||
if (regno < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
int n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
|
||||
while (--n > 0)
|
||||
CLEAR_REGNO_REG_SET (nonequal, regno + n);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case CLOBBER:
|
||||
if (REG_P (XEXP (exp, 0)))
|
||||
{
|
||||
dest = XEXP (exp, 0);
|
||||
regno = REGNO (dest);
|
||||
CLEAR_REGNO_REG_SET (nonequal, regno);
|
||||
if (regno < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
int n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
|
||||
while (--n > 0)
|
||||
CLEAR_REGNO_REG_SET (nonequal, regno + n);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
case SET:
|
||||
if (rtx_equal_for_cselib_p (SET_DEST (exp), SET_SRC (exp)))
|
||||
return false;
|
||||
dest = SET_DEST (exp);
|
||||
if (dest == pc_rtx)
|
||||
return false;
|
||||
if (!REG_P (dest))
|
||||
return true;
|
||||
regno = REGNO (dest);
|
||||
SET_REGNO_REG_SET (nonequal, regno);
|
||||
if (regno < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
int n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
|
||||
while (--n > 0)
|
||||
SET_REGNO_REG_SET (nonequal, regno + n);
|
||||
}
|
||||
case SET:
|
||||
if (rtx_equal_for_cselib_p (SET_DEST (exp), SET_SRC (exp)))
|
||||
return false;
|
||||
dest = SET_DEST (exp);
|
||||
if (dest == pc_rtx)
|
||||
return false;
|
||||
if (!REG_P (dest))
|
||||
return true;
|
||||
regno = REGNO (dest);
|
||||
SET_REGNO_REG_SET (nonequal, regno);
|
||||
if (regno < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
int n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
|
||||
while (--n > 0)
|
||||
SET_REGNO_REG_SET (nonequal, regno + n);
|
||||
}
|
||||
return false;
|
||||
|
||||
default:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return nonzero if X is an register set in regset DATA.
|
||||
Called via for_each_rtx. */
|
||||
static int
|
||||
mentions_nonequal_regs (x, data)
|
||||
rtx *x;
|
||||
void *data;
|
||||
{
|
||||
regset nonequal = (regset) data;
|
||||
if (REG_P (*x))
|
||||
{
|
||||
int regno;
|
||||
|
||||
regno = REGNO (*x);
|
||||
if (REGNO_REG_SET_P (nonequal, regno))
|
||||
return 1;
|
||||
if (regno < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
int n = HARD_REGNO_NREGS (regno, GET_MODE (*x));
|
||||
while (--n > 0)
|
||||
if (REGNO_REG_SET_P (nonequal, regno + n))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Attempt to prove that the basic block B will have no side effects and
|
||||
allways continues in the same edge if reached via E. Return the edge
|
||||
if exist, NULL otherwise. */
|
||||
@ -255,18 +278,29 @@ thread_jump (mode, e, b)
|
||||
regset nonequal;
|
||||
bool failed = false;
|
||||
|
||||
if (BB_FLAGS (b) & BB_NONTHREADABLE_BLOCK)
|
||||
return NULL;
|
||||
|
||||
/* At the moment, we do handle only conditional jumps, but later we may
|
||||
want to extend this code to tablejumps and others. */
|
||||
if (!e->src->succ->succ_next || e->src->succ->succ_next->succ_next)
|
||||
return NULL;
|
||||
if (!b->succ || !b->succ->succ_next || b->succ->succ_next->succ_next)
|
||||
return NULL;
|
||||
{
|
||||
BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Second branch must end with onlyjump, as we will eliminate the jump. */
|
||||
if (!any_condjump_p (e->src->end) || !any_condjump_p (b->end)
|
||||
|| !onlyjump_p (b->end))
|
||||
if (!any_condjump_p (e->src->end))
|
||||
return NULL;
|
||||
|
||||
if (!any_condjump_p (b->end) || !onlyjump_p (b->end))
|
||||
{
|
||||
BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
set1 = pc_set (e->src->end);
|
||||
set2 = pc_set (b->end);
|
||||
if (((e->flags & EDGE_FALLTHRU) != 0)
|
||||
@ -300,7 +334,10 @@ thread_jump (mode, e, b)
|
||||
for (insn = NEXT_INSN (b->head); insn != NEXT_INSN (b->end);
|
||||
insn = NEXT_INSN (insn))
|
||||
if (INSN_P (insn) && side_effects_p (PATTERN (insn)))
|
||||
return NULL;
|
||||
{
|
||||
BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cselib_init ();
|
||||
|
||||
@ -319,26 +356,34 @@ thread_jump (mode, e, b)
|
||||
|
||||
for (insn = NEXT_INSN (b->head); insn != NEXT_INSN (b->end) && !failed;
|
||||
insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (INSN_P (insn))
|
||||
{
|
||||
rtx pat = PATTERN (insn);
|
||||
{
|
||||
if (INSN_P (insn))
|
||||
{
|
||||
rtx pat = PATTERN (insn);
|
||||
|
||||
if (GET_CODE (pat) == PARALLEL)
|
||||
{
|
||||
for (i = 0; i < XVECLEN (pat, 0); i++)
|
||||
failed |= mark_effect (XVECEXP (pat, 0, i), nonequal);
|
||||
}
|
||||
else
|
||||
failed |= mark_effect (pat, nonequal);
|
||||
}
|
||||
if (GET_CODE (pat) == PARALLEL)
|
||||
{
|
||||
for (i = 0; i < XVECLEN (pat, 0); i++)
|
||||
failed |= mark_effect (XVECEXP (pat, 0, i), nonequal);
|
||||
}
|
||||
else
|
||||
failed |= mark_effect (pat, nonequal);
|
||||
}
|
||||
|
||||
cselib_process_insn (insn);
|
||||
}
|
||||
cselib_process_insn (insn);
|
||||
}
|
||||
|
||||
/* Later we should clear nonequal of dead registers. So far we don't
|
||||
have life information in cfg_cleanup. */
|
||||
if (failed)
|
||||
{
|
||||
BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
|
||||
goto failed_exit;
|
||||
}
|
||||
|
||||
/* cond2 must not mention any register that is not equal to the
|
||||
former block. */
|
||||
if (for_each_rtx (&cond2, mentions_nonequal_regs, nonequal))
|
||||
goto failed_exit;
|
||||
|
||||
/* In case liveness information is available, we need to prove equivalence
|
||||
@ -455,10 +500,10 @@ try_forward_edges (mode, b)
|
||||
For fallthru forwarders, the LOOP_BEG note must appear between
|
||||
the header of block and CODE_LABEL of the loop, for non forwarders
|
||||
it must appear before the JUMP_INSN. */
|
||||
if (mode & CLEANUP_PRE_LOOP)
|
||||
if ((mode & CLEANUP_PRE_LOOP) && optimize)
|
||||
{
|
||||
rtx insn = (target->succ->flags & EDGE_FALLTHRU
|
||||
? target->head : prev_nonnote_insn (target->end));
|
||||
? target->head : prev_nonnote_insn (target->end));
|
||||
|
||||
if (GET_CODE (insn) != NOTE)
|
||||
insn = NEXT_INSN (insn);
|
||||
@ -469,14 +514,23 @@ try_forward_edges (mode, b)
|
||||
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
|
||||
break;
|
||||
|
||||
if (insn && GET_CODE (insn) == NOTE)
|
||||
if (GET_CODE (insn) == NOTE)
|
||||
break;
|
||||
|
||||
/* Do not clean up branches to just past the end of a loop
|
||||
at this time; it can mess up the loop optimizer's
|
||||
recognition of some patterns. */
|
||||
|
||||
insn = PREV_INSN (target->head);
|
||||
if (insn && GET_CODE (insn) == NOTE
|
||||
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
|
||||
break;
|
||||
}
|
||||
|
||||
counter++;
|
||||
target = new_target;
|
||||
threaded |= new_target_threaded;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter >= n_basic_blocks)
|
||||
{
|
||||
@ -499,7 +553,7 @@ try_forward_edges (mode, b)
|
||||
{
|
||||
notice_new_block (redirect_edge_and_branch_force (e, target));
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Conditionals threaded.\n");
|
||||
fprintf (rtl_dump_file, "Conditionals threaded.\n");
|
||||
}
|
||||
else if (!redirect_edge_and_branch (e, target))
|
||||
{
|
||||
@ -519,7 +573,6 @@ try_forward_edges (mode, b)
|
||||
|
||||
if (!FORWARDER_BLOCK_P (b) && forwarder_block_p (b))
|
||||
BB_SET_FLAG (b, BB_FORWARDER_BLOCK);
|
||||
BB_SET_FLAG (b, BB_UPDATE_LIFE);
|
||||
|
||||
do
|
||||
{
|
||||
@ -569,7 +622,7 @@ try_forward_edges (mode, b)
|
||||
&& first == threaded_edges [n]->src)
|
||||
n++;
|
||||
t = first->succ;
|
||||
}
|
||||
}
|
||||
|
||||
t->count -= edge_count;
|
||||
if (t->count < 0)
|
||||
@ -643,7 +696,6 @@ merge_blocks_move_predecessor_nojumps (a, b)
|
||||
basic_block a, b;
|
||||
{
|
||||
rtx barrier;
|
||||
int index;
|
||||
|
||||
barrier = next_nonnote_insn (a->end);
|
||||
if (GET_CODE (barrier) != BARRIER)
|
||||
@ -663,20 +715,16 @@ merge_blocks_move_predecessor_nojumps (a, b)
|
||||
/* Scramble the insn chain. */
|
||||
if (a->end != PREV_INSN (b->head))
|
||||
reorder_insns_nobb (a->head, a->end, PREV_INSN (b->head));
|
||||
BB_SET_FLAG (a, BB_UPDATE_LIFE);
|
||||
a->flags |= BB_DIRTY;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Moved block %d before %d and merged.\n",
|
||||
a->index, b->index);
|
||||
|
||||
/* Swap the records for the two blocks around. Although we are deleting B,
|
||||
A is now where B was and we want to compact the BB array from where
|
||||
A used to be. */
|
||||
BASIC_BLOCK (a->index) = b;
|
||||
BASIC_BLOCK (b->index) = a;
|
||||
index = a->index;
|
||||
a->index = b->index;
|
||||
b->index = index;
|
||||
/* Swap the records for the two blocks around. */
|
||||
|
||||
unlink_block (a);
|
||||
link_block (a, b->prev_bb);
|
||||
|
||||
/* Now blocks A and B are contiguous. Merge them. */
|
||||
merge_blocks_nomove (a, b);
|
||||
@ -729,13 +777,12 @@ merge_blocks_move_successor_nojumps (a, b)
|
||||
/* Restore the real end of b. */
|
||||
b->end = real_b_end;
|
||||
|
||||
/* Now blocks A and B are contiguous. Merge them. */
|
||||
merge_blocks_nomove (a, b);
|
||||
BB_SET_FLAG (a, BB_UPDATE_LIFE);
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Moved block %d after %d and merged.\n",
|
||||
b->index, a->index);
|
||||
|
||||
/* Now blocks A and B are contiguous. Merge them. */
|
||||
merge_blocks_nomove (a, b);
|
||||
}
|
||||
|
||||
/* Attempt to merge basic blocks that are potentially non-adjacent.
|
||||
@ -760,18 +807,12 @@ merge_blocks (e, b, c, mode)
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
{
|
||||
int b_index = b->index, c_index = c->index;
|
||||
/* We need to update liveness in case C already has broken liveness
|
||||
or B ends by conditional jump to next instructions that will be
|
||||
removed. */
|
||||
if ((BB_FLAGS (c) & BB_UPDATE_LIFE)
|
||||
|| GET_CODE (b->end) == JUMP_INSN)
|
||||
BB_SET_FLAG (b, BB_UPDATE_LIFE);
|
||||
merge_blocks_nomove (b, c);
|
||||
update_forwarder_flag (b);
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Merged %d and %d without moving.\n",
|
||||
b_index, c_index);
|
||||
b_index, c_index);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -831,8 +872,6 @@ merge_blocks (e, b, c, mode)
|
||||
bb = force_nonfallthru (b_fallthru_edge);
|
||||
if (bb)
|
||||
notice_new_block (bb);
|
||||
else
|
||||
BB_SET_FLAG (b_fallthru_edge->src, BB_UPDATE_LIFE);
|
||||
}
|
||||
|
||||
merge_blocks_move_predecessor_nojumps (b, c);
|
||||
@ -847,8 +886,8 @@ merge_blocks (e, b, c, mode)
|
||||
|
||||
static bool
|
||||
insns_match_p (mode, i1, i2)
|
||||
int mode ATTRIBUTE_UNUSED;
|
||||
rtx i1, i2;
|
||||
int mode ATTRIBUTE_UNUSED;
|
||||
rtx i1, i2;
|
||||
{
|
||||
rtx p1, p2;
|
||||
|
||||
@ -873,8 +912,9 @@ insns_match_p (mode, i1, i2)
|
||||
equal, they were constructed identically. */
|
||||
|
||||
if (GET_CODE (i1) == CALL_INSN
|
||||
&& !rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
|
||||
CALL_INSN_FUNCTION_USAGE (i2)))
|
||||
&& (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
|
||||
CALL_INSN_FUNCTION_USAGE (i2))
|
||||
|| SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)))
|
||||
return false;
|
||||
|
||||
#ifdef STACK_REGS
|
||||
@ -988,10 +1028,10 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
|
||||
while (true)
|
||||
{
|
||||
/* Ignore notes. */
|
||||
while (!active_insn_p (i1) && i1 != bb1->head)
|
||||
while (!INSN_P (i1) && i1 != bb1->head)
|
||||
i1 = PREV_INSN (i1);
|
||||
|
||||
while (!active_insn_p (i2) && i2 != bb2->head)
|
||||
while (!INSN_P (i2) && i2 != bb2->head)
|
||||
i2 = PREV_INSN (i2);
|
||||
|
||||
if (i1 == bb1->head || i2 == bb2->head)
|
||||
@ -1000,8 +1040,8 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
|
||||
if (!insns_match_p (mode, i1, i2))
|
||||
break;
|
||||
|
||||
/* Don't begin a cross-jump with a USE or CLOBBER insn. */
|
||||
if (active_insn_p (i1))
|
||||
/* Don't begin a cross-jump with a NOTE insn. */
|
||||
if (INSN_P (i1))
|
||||
{
|
||||
/* If the merged insns have different REG_EQUAL notes, then
|
||||
remove them. */
|
||||
@ -1018,10 +1058,10 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
|
||||
remove_note (i1, equiv1);
|
||||
remove_note (i2, equiv2);
|
||||
}
|
||||
|
||||
|
||||
afterlast1 = last1, afterlast2 = last2;
|
||||
last1 = i1, last2 = i2;
|
||||
ninsns++;
|
||||
ninsns++;
|
||||
}
|
||||
|
||||
i1 = PREV_INSN (i1);
|
||||
@ -1040,13 +1080,13 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
|
||||
Two, it keeps line number notes as matched as may be. */
|
||||
if (ninsns)
|
||||
{
|
||||
while (last1 != bb1->head && !active_insn_p (PREV_INSN (last1)))
|
||||
while (last1 != bb1->head && !INSN_P (PREV_INSN (last1)))
|
||||
last1 = PREV_INSN (last1);
|
||||
|
||||
if (last1 != bb1->head && GET_CODE (PREV_INSN (last1)) == CODE_LABEL)
|
||||
last1 = PREV_INSN (last1);
|
||||
|
||||
while (last2 != bb2->head && !active_insn_p (PREV_INSN (last2)))
|
||||
while (last2 != bb2->head && !INSN_P (PREV_INSN (last2)))
|
||||
last2 = PREV_INSN (last2);
|
||||
|
||||
if (last2 != bb2->head && GET_CODE (PREV_INSN (last2)) == CODE_LABEL)
|
||||
@ -1078,9 +1118,11 @@ outgoing_edges_match (mode, bb1, bb2)
|
||||
/* If BB1 has only one successor, we may be looking at either an
|
||||
unconditional jump, or a fake edge to exit. */
|
||||
if (bb1->succ && !bb1->succ->succ_next
|
||||
&& !(bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)))
|
||||
&& (bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
|
||||
&& (GET_CODE (bb1->end) != JUMP_INSN || simplejump_p (bb1->end)))
|
||||
return (bb2->succ && !bb2->succ->succ_next
|
||||
&& (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0);
|
||||
&& (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
|
||||
&& (GET_CODE (bb2->end) != JUMP_INSN || simplejump_p (bb2->end)));
|
||||
|
||||
/* Match conditional jumps - this may get tricky when fallthru and branch
|
||||
edges are crossed. */
|
||||
@ -1096,7 +1138,7 @@ outgoing_edges_match (mode, bb1, bb2)
|
||||
enum rtx_code code1, code2;
|
||||
|
||||
if (!bb2->succ
|
||||
|| !bb2->succ->succ_next
|
||||
|| !bb2->succ->succ_next
|
||||
|| bb2->succ->succ_next->succ_next
|
||||
|| !any_condjump_p (bb2->end)
|
||||
|| !onlyjump_p (bb2->end))
|
||||
@ -1175,8 +1217,8 @@ outgoing_edges_match (mode, bb1, bb2)
|
||||
roughly similar. */
|
||||
if (match
|
||||
&& !optimize_size
|
||||
&& bb1->frequency > BB_FREQ_MAX / 1000
|
||||
&& bb2->frequency > BB_FREQ_MAX / 1000)
|
||||
&& maybe_hot_bb_p (bb1)
|
||||
&& maybe_hot_bb_p (bb2))
|
||||
{
|
||||
int prob2;
|
||||
|
||||
@ -1207,7 +1249,7 @@ outgoing_edges_match (mode, bb1, bb2)
|
||||
return match;
|
||||
}
|
||||
|
||||
/* Generic case - we are seeing an computed jump, table jump or trapping
|
||||
/* Generic case - we are seeing a computed jump, table jump or trapping
|
||||
instruction. */
|
||||
|
||||
/* First ensure that the instructions match. There may be many outgoing
|
||||
@ -1245,9 +1287,9 @@ outgoing_edges_match (mode, bb1, bb2)
|
||||
if (fallthru1)
|
||||
{
|
||||
basic_block d1 = (forwarder_block_p (fallthru1->dest)
|
||||
? fallthru1->dest->succ->dest: fallthru1->dest);
|
||||
? fallthru1->dest->succ->dest: fallthru1->dest);
|
||||
basic_block d2 = (forwarder_block_p (fallthru2->dest)
|
||||
? fallthru2->dest->succ->dest: fallthru2->dest);
|
||||
? fallthru2->dest->succ->dest: fallthru2->dest);
|
||||
|
||||
if (d1 != d2)
|
||||
return false;
|
||||
@ -1279,21 +1321,21 @@ try_crossjump_to_edge (mode, e1, e2)
|
||||
{
|
||||
int nmatch;
|
||||
basic_block src1 = e1->src, src2 = e2->src;
|
||||
basic_block redirect_to;
|
||||
basic_block redirect_to, redirect_from, to_remove;
|
||||
rtx newpos1, newpos2;
|
||||
edge s;
|
||||
rtx last;
|
||||
rtx label;
|
||||
|
||||
/* Search backward through forwarder blocks. We don't need to worry
|
||||
about multiple entry or chained forwarders, as they will be optimized
|
||||
away. We do this to look past the unconditional jump following a
|
||||
conditional jump that is required due to the current CFG shape. */
|
||||
if (src1->pred
|
||||
&& !src1->pred->pred_next
|
||||
&& FORWARDER_BLOCK_P (src1))
|
||||
e1 = src1->pred, src1 = e1->src;
|
||||
|
||||
if (src2->pred
|
||||
&& !src2->pred->pred_next
|
||||
&& FORWARDER_BLOCK_P (src2))
|
||||
e2 = src2->pred, src2 = e2->src;
|
||||
|
||||
@ -1344,6 +1386,8 @@ try_crossjump_to_edge (mode, e1, e2)
|
||||
|
||||
redirect_to->count += src1->count;
|
||||
redirect_to->frequency += src1->frequency;
|
||||
/* We may have some registers visible trought the block. */
|
||||
redirect_to->flags |= BB_DIRTY;
|
||||
|
||||
/* Recompute the frequencies and counts of outgoing edges. */
|
||||
for (s = redirect_to->succ; s; s = s->succ_next)
|
||||
@ -1407,29 +1451,14 @@ try_crossjump_to_edge (mode, e1, e2)
|
||||
|
||||
if (GET_CODE (newpos1) == NOTE)
|
||||
newpos1 = NEXT_INSN (newpos1);
|
||||
last = src1->end;
|
||||
|
||||
/* Emit the jump insn. */
|
||||
label = block_label (redirect_to);
|
||||
emit_jump_insn_after (gen_jump (label), src1->end);
|
||||
JUMP_LABEL (src1->end) = label;
|
||||
LABEL_NUSES (label)++;
|
||||
redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
|
||||
to_remove = redirect_from->succ->dest;
|
||||
|
||||
/* Delete the now unreachable instructions. */
|
||||
delete_insn_chain (newpos1, last);
|
||||
redirect_edge_and_branch_force (redirect_from->succ, redirect_to);
|
||||
flow_delete_block (to_remove);
|
||||
|
||||
/* Make sure there is a barrier after the new jump. */
|
||||
last = next_nonnote_insn (src1->end);
|
||||
if (!last || GET_CODE (last) != BARRIER)
|
||||
emit_barrier_after (src1->end);
|
||||
|
||||
/* Update CFG. */
|
||||
while (src1->succ)
|
||||
remove_edge (src1->succ);
|
||||
make_single_succ_edge (src1, redirect_to, 0);
|
||||
|
||||
BB_SET_FLAG (src1, BB_UPDATE_LIFE);
|
||||
update_forwarder_flag (src1);
|
||||
update_forwarder_flag (redirect_from);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1445,6 +1474,7 @@ try_crossjump_bb (mode, bb)
|
||||
{
|
||||
edge e, e2, nexte2, nexte, fallthru;
|
||||
bool changed;
|
||||
int n = 0, max;
|
||||
|
||||
/* Nothing to do if there is not at least two incoming edges. */
|
||||
if (!bb->pred || !bb->pred->pred_next)
|
||||
@ -1453,9 +1483,15 @@ try_crossjump_bb (mode, bb)
|
||||
/* It is always cheapest to redirect a block that ends in a branch to
|
||||
a block that falls through into BB, as that adds no branches to the
|
||||
program. We'll try that combination first. */
|
||||
for (fallthru = bb->pred; fallthru; fallthru = fallthru->pred_next)
|
||||
if (fallthru->flags & EDGE_FALLTHRU)
|
||||
break;
|
||||
fallthru = NULL;
|
||||
max = PARAM_VALUE (PARAM_MAX_CROSSJUMP_EDGES);
|
||||
for (e = bb->pred; e ; e = e->pred_next, n++)
|
||||
{
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
fallthru = e;
|
||||
if (n > max)
|
||||
return false;
|
||||
}
|
||||
|
||||
changed = false;
|
||||
for (e = bb->pred; e; e = nexte)
|
||||
@ -1530,17 +1566,19 @@ static bool
|
||||
try_optimize_cfg (mode)
|
||||
int mode;
|
||||
{
|
||||
int i;
|
||||
bool changed_overall = false;
|
||||
bool changed;
|
||||
int iterations = 0;
|
||||
sbitmap blocks;
|
||||
basic_block bb, b;
|
||||
|
||||
if (mode & CLEANUP_CROSSJUMP)
|
||||
add_noreturn_fake_exit_edges ();
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
update_forwarder_flag (BASIC_BLOCK (i));
|
||||
FOR_EACH_BB (bb)
|
||||
update_forwarder_flag (bb);
|
||||
|
||||
if (mode & CLEANUP_UPDATE_LIFE)
|
||||
clear_bb_flags ();
|
||||
|
||||
if (! (* targetm.cannot_modify_jumps_p) ())
|
||||
{
|
||||
@ -1557,16 +1595,16 @@ try_optimize_cfg (mode)
|
||||
"\n\ntry_optimize_cfg iteration %i\n\n",
|
||||
iterations);
|
||||
|
||||
for (i = 0; i < n_basic_blocks;)
|
||||
for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR;)
|
||||
{
|
||||
basic_block c, b = BASIC_BLOCK (i);
|
||||
basic_block c;
|
||||
edge s;
|
||||
bool changed_here = false;
|
||||
|
||||
/* Delete trivially dead basic blocks. */
|
||||
while (b->pred == NULL)
|
||||
{
|
||||
c = BASIC_BLOCK (b->index - 1);
|
||||
c = b->prev_bb;
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Deleting block %i.\n",
|
||||
b->index);
|
||||
@ -1620,7 +1658,7 @@ try_optimize_cfg (mode)
|
||||
"Deleting fallthru block %i.\n",
|
||||
b->index);
|
||||
|
||||
c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
|
||||
c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb;
|
||||
redirect_edge_succ_nodup (b->pred, b->succ->dest);
|
||||
flow_delete_block (b);
|
||||
changed = true;
|
||||
@ -1638,17 +1676,15 @@ try_optimize_cfg (mode)
|
||||
/* If the jump insn has side effects,
|
||||
we can't kill the edge. */
|
||||
&& (GET_CODE (b->end) != JUMP_INSN
|
||||
|| (onlyjump_p (b->end)
|
||||
&& !tablejump_p (b->end)))
|
||||
|| (flow2_completed
|
||||
? simplejump_p (b->end)
|
||||
: onlyjump_p (b->end)))
|
||||
&& merge_blocks (s, b, c, mode))
|
||||
changed_here = true;
|
||||
|
||||
/* Simplify branch over branch. */
|
||||
if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
|
||||
{
|
||||
BB_SET_FLAG (b, BB_UPDATE_LIFE);
|
||||
changed_here = true;
|
||||
}
|
||||
changed_here = true;
|
||||
|
||||
/* If B has a single outgoing edge, but uses a
|
||||
non-trivial jump instruction without side-effects, we
|
||||
@ -1661,7 +1697,6 @@ try_optimize_cfg (mode)
|
||||
&& onlyjump_p (b->end)
|
||||
&& redirect_edge_and_branch (b->succ, b->succ->dest))
|
||||
{
|
||||
BB_SET_FLAG (b, BB_UPDATE_LIFE);
|
||||
update_forwarder_flag (b);
|
||||
changed_here = true;
|
||||
}
|
||||
@ -1678,7 +1713,7 @@ try_optimize_cfg (mode)
|
||||
/* Don't get confused by the index shift caused by
|
||||
deleting blocks. */
|
||||
if (!changed_here)
|
||||
i = b->index + 1;
|
||||
b = b->next_bb;
|
||||
else
|
||||
changed = true;
|
||||
}
|
||||
@ -1700,64 +1735,33 @@ try_optimize_cfg (mode)
|
||||
if (mode & CLEANUP_CROSSJUMP)
|
||||
remove_fake_edges ();
|
||||
|
||||
if ((mode & CLEANUP_UPDATE_LIFE) && changed_overall)
|
||||
{
|
||||
bool found = 0;
|
||||
|
||||
blocks = sbitmap_alloc (n_basic_blocks);
|
||||
sbitmap_zero (blocks);
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
if (BB_FLAGS (BASIC_BLOCK (i)) & BB_UPDATE_LIFE)
|
||||
{
|
||||
found = 1;
|
||||
SET_BIT (blocks, i);
|
||||
}
|
||||
|
||||
if (found)
|
||||
update_life_info (blocks, UPDATE_LIFE_GLOBAL,
|
||||
PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
|
||||
| PROP_KILL_DEAD_CODE);
|
||||
sbitmap_free (blocks);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
BASIC_BLOCK (i)->aux = NULL;
|
||||
clear_aux_for_blocks ();
|
||||
|
||||
return changed_overall;
|
||||
}
|
||||
|
||||
/* Delete all unreachable basic blocks. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
delete_unreachable_blocks ()
|
||||
{
|
||||
int i, j;
|
||||
bool changed = false;
|
||||
basic_block b, next_bb;
|
||||
|
||||
find_unreachable_blocks ();
|
||||
|
||||
/* Delete all unreachable basic blocks. Do compaction concurrently,
|
||||
as otherwise we can wind up with O(N^2) behaviour here when we
|
||||
have oodles of dead code. */
|
||||
/* Delete all unreachable basic blocks. */
|
||||
|
||||
for (i = j = 0; i < n_basic_blocks; ++i)
|
||||
for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR; b = next_bb)
|
||||
{
|
||||
basic_block b = BASIC_BLOCK (i);
|
||||
next_bb = b->next_bb;
|
||||
|
||||
if (!(b->flags & BB_REACHABLE))
|
||||
{
|
||||
flow_delete_block_noexpunge (b);
|
||||
expunge_block_nocompact (b);
|
||||
flow_delete_block (b);
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BASIC_BLOCK (j) = b;
|
||||
b->index = j++;
|
||||
}
|
||||
}
|
||||
n_basic_blocks = j;
|
||||
basic_block_info->num_elements = j;
|
||||
|
||||
if (changed)
|
||||
tidy_fallthru_edges ();
|
||||
@ -1773,13 +1777,48 @@ cleanup_cfg (mode)
|
||||
bool changed = false;
|
||||
|
||||
timevar_push (TV_CLEANUP_CFG);
|
||||
changed = delete_unreachable_blocks ();
|
||||
if (try_optimize_cfg (mode))
|
||||
delete_unreachable_blocks (), changed = true;
|
||||
if (delete_unreachable_blocks ())
|
||||
{
|
||||
changed = true;
|
||||
/* We've possibly created trivially dead code. Cleanup it right
|
||||
now to introduce more oppurtunities for try_optimize_cfg. */
|
||||
if (!(mode & (CLEANUP_NO_INSN_DEL
|
||||
| CLEANUP_UPDATE_LIFE | CLEANUP_PRE_SIBCALL))
|
||||
&& !reload_completed)
|
||||
delete_trivially_dead_insns (get_insns(), max_reg_num ());
|
||||
}
|
||||
|
||||
compact_blocks ();
|
||||
|
||||
while (try_optimize_cfg (mode))
|
||||
{
|
||||
delete_unreachable_blocks (), changed = true;
|
||||
if (mode & CLEANUP_UPDATE_LIFE)
|
||||
{
|
||||
/* Cleaning up CFG introduces more oppurtunities for dead code
|
||||
removal that in turn may introduce more oppurtunities for
|
||||
cleaning up the CFG. */
|
||||
if (!update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
|
||||
PROP_DEATH_NOTES
|
||||
| PROP_SCAN_DEAD_CODE
|
||||
| PROP_KILL_DEAD_CODE
|
||||
| PROP_LOG_LINKS))
|
||||
break;
|
||||
}
|
||||
else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL))
|
||||
&& (mode & CLEANUP_EXPENSIVE)
|
||||
&& !reload_completed)
|
||||
{
|
||||
if (!delete_trivially_dead_insns (get_insns(), max_reg_num ()))
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
delete_dead_jumptables ();
|
||||
}
|
||||
|
||||
/* Kill the data we won't maintain. */
|
||||
free_EXPR_LIST_list (&label_value_list);
|
||||
free_EXPR_LIST_list (&tail_recursion_label_list);
|
||||
timevar_pop (TV_CLEANUP_CFG);
|
||||
|
||||
return changed;
|
||||
|
@ -35,7 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
extern struct obstack flow_obstack;
|
||||
|
||||
/* Holds the interesting trailing notes for the function. */
|
||||
static rtx function_tail_eff_head;
|
||||
static rtx function_footer;
|
||||
|
||||
static rtx skip_insns_after_block PARAMS ((basic_block));
|
||||
static void record_effective_endpoints PARAMS ((void));
|
||||
@ -46,10 +46,31 @@ static void set_block_levels PARAMS ((tree, int));
|
||||
static void change_scope PARAMS ((rtx, tree, tree));
|
||||
|
||||
void verify_insn_chain PARAMS ((void));
|
||||
static void cleanup_unconditional_jumps PARAMS ((void));
|
||||
static void fixup_fallthru_exit_predecessor PARAMS ((void));
|
||||
static rtx unlink_insn_chain PARAMS ((rtx, rtx));
|
||||
static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
|
||||
|
||||
static rtx
|
||||
unlink_insn_chain (first, last)
|
||||
rtx first;
|
||||
rtx last;
|
||||
{
|
||||
rtx prevfirst = PREV_INSN (first);
|
||||
rtx nextlast = NEXT_INSN (last);
|
||||
|
||||
/* Map insn uid to lexical block. */
|
||||
static varray_type insn_scopes;
|
||||
PREV_INSN (first) = NULL;
|
||||
NEXT_INSN (last) = NULL;
|
||||
if (prevfirst)
|
||||
NEXT_INSN (prevfirst) = nextlast;
|
||||
if (nextlast)
|
||||
PREV_INSN (nextlast) = prevfirst;
|
||||
else
|
||||
set_last_insn (prevfirst);
|
||||
if (!prevfirst)
|
||||
set_first_insn (nextlast);
|
||||
return first;
|
||||
}
|
||||
|
||||
/* Skip over inter-block insns occurring after BB which are typically
|
||||
associated with BB (e.g., barriers). If there are any such insns,
|
||||
@ -62,8 +83,8 @@ skip_insns_after_block (bb)
|
||||
rtx insn, last_insn, next_head, prev;
|
||||
|
||||
next_head = NULL_RTX;
|
||||
if (bb->index + 1 != n_basic_blocks)
|
||||
next_head = BASIC_BLOCK (bb->index + 1)->head;
|
||||
if (bb->next_bb != EXIT_BLOCK_PTR)
|
||||
next_head = bb->next_bb->head;
|
||||
|
||||
for (last_insn = insn = bb->end; (insn = NEXT_INSN (insn)) != 0; )
|
||||
{
|
||||
@ -103,7 +124,7 @@ skip_insns_after_block (bb)
|
||||
last_insn = insn;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -113,7 +134,7 @@ skip_insns_after_block (bb)
|
||||
}
|
||||
|
||||
/* It is possible to hit contradictory sequence. For instance:
|
||||
|
||||
|
||||
jump_insn
|
||||
NOTE_INSN_LOOP_BEG
|
||||
barrier
|
||||
@ -128,14 +149,14 @@ skip_insns_after_block (bb)
|
||||
if (GET_CODE (insn) == NOTE)
|
||||
switch (NOTE_LINE_NUMBER (insn))
|
||||
{
|
||||
case NOTE_INSN_LOOP_END:
|
||||
case NOTE_INSN_BLOCK_END:
|
||||
case NOTE_INSN_DELETED:
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
case NOTE_INSN_LOOP_END:
|
||||
case NOTE_INSN_BLOCK_END:
|
||||
case NOTE_INSN_DELETED:
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
continue;
|
||||
default:
|
||||
default:
|
||||
reorder_insns (insn, insn, last_insn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return last_insn;
|
||||
@ -155,8 +176,6 @@ label_for_bb (bb)
|
||||
fprintf (rtl_dump_file, "Emitting label for block %d\n", bb->index);
|
||||
|
||||
label = block_label (bb);
|
||||
if (bb->head == PREV_INSN (RBI (bb)->eff_head))
|
||||
RBI (bb)->eff_head = label;
|
||||
}
|
||||
|
||||
return label;
|
||||
@ -169,20 +188,24 @@ static void
|
||||
record_effective_endpoints ()
|
||||
{
|
||||
rtx next_insn = get_insns ();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
basic_block bb;
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
rtx end;
|
||||
|
||||
RBI (bb)->eff_head = next_insn;
|
||||
if (PREV_INSN (bb->head) && next_insn != bb->head)
|
||||
RBI (bb)->header = unlink_insn_chain (next_insn,
|
||||
PREV_INSN (bb->head));
|
||||
end = skip_insns_after_block (bb);
|
||||
RBI (bb)->eff_end = end;
|
||||
next_insn = NEXT_INSN (end);
|
||||
if (NEXT_INSN (bb->end) && bb->end != end)
|
||||
RBI (bb)->footer = unlink_insn_chain (NEXT_INSN (bb->end), end);
|
||||
next_insn = NEXT_INSN (bb->end);
|
||||
}
|
||||
|
||||
function_tail_eff_head = next_insn;
|
||||
function_footer = next_insn;
|
||||
if (function_footer)
|
||||
function_footer = unlink_insn_chain (function_footer, get_last_insn ());
|
||||
}
|
||||
|
||||
/* Build a varray mapping INSN_UID to lexical block. Return it. */
|
||||
@ -193,8 +216,6 @@ scope_to_insns_initialize ()
|
||||
tree block = NULL;
|
||||
rtx insn, next;
|
||||
|
||||
VARRAY_TREE_INIT (insn_scopes, get_max_uid (), "insn scopes");
|
||||
|
||||
for (insn = get_insns (); insn; insn = next)
|
||||
{
|
||||
next = NEXT_INSN (insn);
|
||||
@ -202,7 +223,7 @@ scope_to_insns_initialize ()
|
||||
if (active_insn_p (insn)
|
||||
&& GET_CODE (PATTERN (insn)) != ADDR_VEC
|
||||
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
|
||||
VARRAY_TREE (insn_scopes, INSN_UID (insn)) = block;
|
||||
INSN_SCOPE (insn) = block;
|
||||
else if (GET_CODE (insn) == NOTE)
|
||||
{
|
||||
switch (NOTE_LINE_NUMBER (insn))
|
||||
@ -220,6 +241,10 @@ scope_to_insns_initialize ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tag the blocks with a depth number so that change_scope can find
|
||||
the common parent easily. */
|
||||
set_block_levels (DECL_INITIAL (cfun->decl), 0);
|
||||
}
|
||||
|
||||
/* For each lexical block, set BLOCK_NUMBER to the depth at which it is
|
||||
@ -237,7 +262,21 @@ set_block_levels (block, level)
|
||||
block = BLOCK_CHAIN (block);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return sope resulting from combination of S1 and S2. */
|
||||
tree
|
||||
choose_inner_scope (s1, s2)
|
||||
tree s1, s2;
|
||||
{
|
||||
if (!s1)
|
||||
return s2;
|
||||
if (!s2)
|
||||
return s1;
|
||||
if (BLOCK_NUMBER (s1) > BLOCK_NUMBER (s2))
|
||||
return s1;
|
||||
return s2;
|
||||
}
|
||||
|
||||
/* Emit lexical block notes needed to change scope from S1 to S2. */
|
||||
|
||||
static void
|
||||
@ -294,17 +333,26 @@ scope_to_insns_finalize ()
|
||||
tree cur_block = DECL_INITIAL (cfun->decl);
|
||||
rtx insn, note;
|
||||
|
||||
/* Tag the blocks with a depth number so that change_scope can find
|
||||
the common parent easily. */
|
||||
set_block_levels (cur_block, 0);
|
||||
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||
insn = get_insns ();
|
||||
if (!active_insn_p (insn))
|
||||
insn = next_active_insn (insn);
|
||||
for (; insn; insn = next_active_insn (insn))
|
||||
{
|
||||
tree this_block;
|
||||
|
||||
if ((size_t) INSN_UID (insn) >= insn_scopes->num_elements)
|
||||
continue;
|
||||
this_block = VARRAY_TREE (insn_scopes, INSN_UID (insn));
|
||||
this_block = INSN_SCOPE (insn);
|
||||
/* For sequences compute scope resulting from merging all scopes
|
||||
of instructions nested inside. */
|
||||
if (GET_CODE (PATTERN (insn)) == SEQUENCE)
|
||||
{
|
||||
int i;
|
||||
rtx body = PATTERN (insn);
|
||||
|
||||
this_block = NULL;
|
||||
for (i = 0; i < XVECLEN (body, 0); i++)
|
||||
this_block = choose_inner_scope (this_block,
|
||||
INSN_SCOPE (XVECEXP (body, 0, i)));
|
||||
}
|
||||
if (! this_block)
|
||||
continue;
|
||||
|
||||
@ -315,8 +363,6 @@ scope_to_insns_finalize ()
|
||||
}
|
||||
}
|
||||
|
||||
VARRAY_FREE (insn_scopes);
|
||||
|
||||
/* change_scope emits before the insn, not after. */
|
||||
note = emit_note (NULL, NOTE_INSN_DELETED);
|
||||
change_scope (note, cur_block, DECL_INITIAL (cfun->decl));
|
||||
@ -330,32 +376,49 @@ scope_to_insns_finalize ()
|
||||
static void
|
||||
fixup_reorder_chain ()
|
||||
{
|
||||
basic_block bb, last_bb;
|
||||
basic_block bb, prev_bb;
|
||||
int index;
|
||||
rtx insn;
|
||||
int old_n_basic_blocks = n_basic_blocks;
|
||||
rtx insn = NULL;
|
||||
|
||||
/* First do the bulk reordering -- rechain the blocks without regard to
|
||||
the needed changes to jumps and labels. */
|
||||
|
||||
for (last_bb = BASIC_BLOCK (0), bb = RBI (last_bb)->next, index = 1;
|
||||
for (bb = ENTRY_BLOCK_PTR->next_bb, index = 0;
|
||||
bb != 0;
|
||||
last_bb = bb, bb = RBI (bb)->next, index++)
|
||||
bb = RBI (bb)->next, index++)
|
||||
{
|
||||
rtx last_e = RBI (last_bb)->eff_end;
|
||||
rtx curr_h = RBI (bb)->eff_head;
|
||||
|
||||
NEXT_INSN (last_e) = curr_h;
|
||||
PREV_INSN (curr_h) = last_e;
|
||||
if (RBI (bb)->header)
|
||||
{
|
||||
if (insn)
|
||||
NEXT_INSN (insn) = RBI (bb)->header;
|
||||
else
|
||||
set_first_insn (RBI (bb)->header);
|
||||
PREV_INSN (RBI (bb)->header) = insn;
|
||||
insn = RBI (bb)->header;
|
||||
while (NEXT_INSN (insn))
|
||||
insn = NEXT_INSN (insn);
|
||||
}
|
||||
if (insn)
|
||||
NEXT_INSN (insn) = bb->head;
|
||||
else
|
||||
set_first_insn (bb->head);
|
||||
PREV_INSN (bb->head) = insn;
|
||||
insn = bb->end;
|
||||
if (RBI (bb)->footer)
|
||||
{
|
||||
NEXT_INSN (insn) = RBI (bb)->footer;
|
||||
PREV_INSN (RBI (bb)->footer) = insn;
|
||||
while (NEXT_INSN (insn))
|
||||
insn = NEXT_INSN (insn);
|
||||
}
|
||||
}
|
||||
|
||||
if (index != n_basic_blocks)
|
||||
abort ();
|
||||
|
||||
insn = RBI (last_bb)->eff_end;
|
||||
NEXT_INSN (insn) = function_tail_eff_head;
|
||||
if (function_tail_eff_head)
|
||||
PREV_INSN (function_tail_eff_head) = insn;
|
||||
NEXT_INSN (insn) = function_footer;
|
||||
if (function_footer)
|
||||
PREV_INSN (function_footer) = insn;
|
||||
|
||||
while (NEXT_INSN (insn))
|
||||
insn = NEXT_INSN (insn);
|
||||
@ -368,7 +431,7 @@ fixup_reorder_chain ()
|
||||
/* Now add jumps and labels as needed to match the blocks new
|
||||
outgoing edges. */
|
||||
|
||||
for (bb = BASIC_BLOCK (0); bb ; bb = RBI (bb)->next)
|
||||
for (bb = ENTRY_BLOCK_PTR->next_bb; bb ; bb = RBI (bb)->next)
|
||||
{
|
||||
edge e_fall, e_taken, e;
|
||||
rtx bb_end_insn;
|
||||
@ -397,11 +460,44 @@ fixup_reorder_chain ()
|
||||
&& e_fall->dest == EXIT_BLOCK_PTR))
|
||||
continue;
|
||||
|
||||
if (!e_taken)
|
||||
e_taken = e_fall;
|
||||
|
||||
/* The degenerated case of conditional jump jumping to the next
|
||||
instruction can happen on target having jumps with side
|
||||
effects.
|
||||
|
||||
Create temporarily the duplicated edge representing branch.
|
||||
It will get unidentified by force_nonfallthru_and_redirect
|
||||
that would otherwise get confused by fallthru edge not pointing
|
||||
to the next basic block. */
|
||||
if (!e_taken)
|
||||
{
|
||||
rtx note;
|
||||
edge e_fake;
|
||||
|
||||
e_fake = unchecked_make_edge (bb, e_fall->dest, 0);
|
||||
|
||||
note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX);
|
||||
if (note)
|
||||
{
|
||||
int prob = INTVAL (XEXP (note, 0));
|
||||
|
||||
e_fake->probability = prob;
|
||||
e_fake->count = e_fall->count * prob / REG_BR_PROB_BASE;
|
||||
e_fall->probability -= e_fall->probability;
|
||||
e_fall->count -= e_fake->count;
|
||||
if (e_fall->probability < 0)
|
||||
e_fall->probability = 0;
|
||||
if (e_fall->count < 0)
|
||||
e_fall->count = 0;
|
||||
}
|
||||
}
|
||||
/* There is one special case: if *neither* block is next,
|
||||
such as happens at the very end of a function, then we'll
|
||||
need to add a new unconditional jump. Choose the taken
|
||||
edge based on known or assumed probability. */
|
||||
if (RBI (bb)->next != e_taken->dest)
|
||||
else if (RBI (bb)->next != e_taken->dest)
|
||||
{
|
||||
rtx note = find_reg_note (bb_end_insn, REG_BR_PROB, 0);
|
||||
|
||||
@ -417,7 +513,7 @@ fixup_reorder_chain ()
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise we can try to invert the jump. This will
|
||||
/* Otherwise we can try to invert the jump. This will
|
||||
basically never fail, however, keep up the pretense. */
|
||||
else if (invert_jump (bb_end_insn,
|
||||
label_for_bb (e_fall->dest), 0))
|
||||
@ -470,8 +566,6 @@ fixup_reorder_chain ()
|
||||
if (nb)
|
||||
{
|
||||
alloc_aux_for_block (nb, sizeof (struct reorder_block_def));
|
||||
RBI (nb)->eff_head = nb->head;
|
||||
RBI (nb)->eff_end = NEXT_INSN (nb->end);
|
||||
RBI (nb)->visited = 1;
|
||||
RBI (nb)->next = RBI (bb)->next;
|
||||
RBI (bb)->next = nb;
|
||||
@ -481,23 +575,38 @@ fixup_reorder_chain ()
|
||||
}
|
||||
|
||||
/* Put basic_block_info in the new order. */
|
||||
bb = BASIC_BLOCK (0);
|
||||
index = 0;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Reordered sequence:\n");
|
||||
|
||||
for (; bb; bb = RBI (bb)->next, index++)
|
||||
{
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, " %i %sbb %i freq %i\n", index,
|
||||
bb->index >= old_n_basic_blocks ? "compensation " : "",
|
||||
bb->index,
|
||||
bb->frequency);
|
||||
fprintf (rtl_dump_file, "Reordered sequence:\n");
|
||||
for (bb = ENTRY_BLOCK_PTR->next_bb, index = 0; bb; bb = RBI (bb)->next, index ++)
|
||||
{
|
||||
fprintf (rtl_dump_file, " %i ", index);
|
||||
if (RBI (bb)->original)
|
||||
fprintf (rtl_dump_file, "duplicate of %i ",
|
||||
RBI (bb)->original->index);
|
||||
else if (forwarder_block_p (bb) && GET_CODE (bb->head) != CODE_LABEL)
|
||||
fprintf (rtl_dump_file, "compensation ");
|
||||
else
|
||||
fprintf (rtl_dump_file, "bb %i ", bb->index);
|
||||
fprintf (rtl_dump_file, " [%i]\n", bb->frequency);
|
||||
}
|
||||
}
|
||||
|
||||
prev_bb = ENTRY_BLOCK_PTR;
|
||||
bb = ENTRY_BLOCK_PTR->next_bb;
|
||||
index = 0;
|
||||
|
||||
for (; bb; prev_bb = bb, bb = RBI (bb)->next, index ++)
|
||||
{
|
||||
bb->index = index;
|
||||
BASIC_BLOCK (index) = bb;
|
||||
|
||||
bb->prev_bb = prev_bb;
|
||||
prev_bb->next_bb = bb;
|
||||
}
|
||||
prev_bb->next_bb = EXIT_BLOCK_PTR;
|
||||
EXIT_BLOCK_PTR->prev_bb = prev_bb;
|
||||
}
|
||||
|
||||
/* Perform sanity checks on the insn chain.
|
||||
@ -530,10 +639,70 @@ verify_insn_chain ()
|
||||
if (insn_cnt1 != insn_cnt2)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Remove any unconditional jumps and forwarder block creating fallthru
|
||||
edges instead. During BB reordering, fallthru edges are not required
|
||||
to target next basic block in the linear CFG layout, so the unconditional
|
||||
jumps are not needed. */
|
||||
|
||||
/* The block falling through to exit must be the last one in the reordered
|
||||
chain. Ensure it is. */
|
||||
static void
|
||||
cleanup_unconditional_jumps ()
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
if (!bb->succ)
|
||||
continue;
|
||||
if (bb->succ->flags & EDGE_FALLTHRU)
|
||||
continue;
|
||||
if (!bb->succ->succ_next)
|
||||
{
|
||||
rtx insn;
|
||||
if (GET_CODE (bb->head) != CODE_LABEL && forwarder_block_p (bb)
|
||||
&& bb->prev_bb != ENTRY_BLOCK_PTR)
|
||||
{
|
||||
basic_block prev = bb->prev_bb;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Removing forwarder BB %i\n",
|
||||
bb->index);
|
||||
|
||||
redirect_edge_succ_nodup (bb->pred, bb->succ->dest);
|
||||
flow_delete_block (bb);
|
||||
bb = prev;
|
||||
}
|
||||
else if (simplejump_p (bb->end))
|
||||
{
|
||||
rtx jump = bb->end;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Removing jump %i in BB %i\n",
|
||||
INSN_UID (jump), bb->index);
|
||||
delete_insn (jump);
|
||||
bb->succ->flags |= EDGE_FALLTHRU;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
insn = NEXT_INSN (bb->end);
|
||||
while (insn
|
||||
&& (GET_CODE (insn) != NOTE
|
||||
|| NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK))
|
||||
{
|
||||
rtx next = NEXT_INSN (insn);
|
||||
|
||||
if (GET_CODE (insn) == BARRIER)
|
||||
delete_barrier (insn);
|
||||
|
||||
insn = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The block falling through to exit must be the last one in the
|
||||
reordered chain. Ensure that this condition is met. */
|
||||
static void
|
||||
fixup_fallthru_exit_predecessor ()
|
||||
{
|
||||
@ -546,7 +715,7 @@ fixup_fallthru_exit_predecessor ()
|
||||
|
||||
if (bb && RBI (bb)->next)
|
||||
{
|
||||
basic_block c = BASIC_BLOCK (0);
|
||||
basic_block c = ENTRY_BLOCK_PTR->next_bb;
|
||||
|
||||
while (RBI (c)->next != bb)
|
||||
c = RBI (c)->next;
|
||||
@ -560,15 +729,279 @@ fixup_fallthru_exit_predecessor ()
|
||||
}
|
||||
}
|
||||
|
||||
/* Main entry point to this module: initialize the datastructures for CFG
|
||||
layout changes. */
|
||||
/* Return true in case it is possible to duplicate the basic block BB. */
|
||||
|
||||
bool
|
||||
cfg_layout_can_duplicate_bb_p (bb)
|
||||
basic_block bb;
|
||||
{
|
||||
rtx next;
|
||||
edge s;
|
||||
|
||||
if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR)
|
||||
return false;
|
||||
|
||||
/* Duplicating fallthru block to exit would require adding a jump
|
||||
and splitting the real last BB. */
|
||||
for (s = bb->succ; s; s = s->succ_next)
|
||||
if (s->dest == EXIT_BLOCK_PTR && s->flags & EDGE_FALLTHRU)
|
||||
return false;
|
||||
|
||||
/* Do not attempt to duplicate tablejumps, as we need to unshare
|
||||
the dispatch table. This is dificult to do, as the instructions
|
||||
computing jump destination may be hoisted outside the basic block. */
|
||||
if (GET_CODE (bb->end) == JUMP_INSN && JUMP_LABEL (bb->end)
|
||||
&& (next = next_nonnote_insn (JUMP_LABEL (bb->end)))
|
||||
&& GET_CODE (next) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static rtx
|
||||
duplicate_insn_chain (from, to)
|
||||
rtx from, to;
|
||||
{
|
||||
rtx insn, last;
|
||||
|
||||
/* Avoid updating of boundaries of previous basic block. The
|
||||
note will get removed from insn stream in fixup. */
|
||||
last = emit_note (NULL, NOTE_INSN_DELETED);
|
||||
|
||||
/* Create copy at the end of INSN chain. The chain will
|
||||
be reordered later. */
|
||||
for (insn = from; insn != NEXT_INSN (to); insn = NEXT_INSN (insn))
|
||||
{
|
||||
rtx new;
|
||||
switch (GET_CODE (insn))
|
||||
{
|
||||
case INSN:
|
||||
case CALL_INSN:
|
||||
case JUMP_INSN:
|
||||
/* Avoid copying of dispatch tables. We never duplicate
|
||||
tablejumps, so this can hit only in case the table got
|
||||
moved far from original jump. */
|
||||
if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
|
||||
break;
|
||||
new = emit_copy_of_insn_after (insn, get_last_insn ());
|
||||
break;
|
||||
|
||||
case CODE_LABEL:
|
||||
break;
|
||||
|
||||
case BARRIER:
|
||||
emit_barrier ();
|
||||
break;
|
||||
|
||||
case NOTE:
|
||||
switch (NOTE_LINE_NUMBER (insn))
|
||||
{
|
||||
/* In case prologue is empty and function contain label
|
||||
in first BB, we may want to copy the block. */
|
||||
case NOTE_INSN_PROLOGUE_END:
|
||||
|
||||
case NOTE_INSN_LOOP_VTOP:
|
||||
case NOTE_INSN_LOOP_CONT:
|
||||
case NOTE_INSN_LOOP_BEG:
|
||||
case NOTE_INSN_LOOP_END:
|
||||
/* Strip down the loop notes - we don't really want to keep
|
||||
them consistent in loop copies. */
|
||||
case NOTE_INSN_DELETED:
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
/* No problem to strip these. */
|
||||
case NOTE_INSN_EPILOGUE_BEG:
|
||||
case NOTE_INSN_FUNCTION_END:
|
||||
/* Debug code expect these notes to exist just once.
|
||||
Keep them in the master copy.
|
||||
??? It probably makes more sense to duplicate them for each
|
||||
epilogue copy. */
|
||||
case NOTE_INSN_FUNCTION_BEG:
|
||||
/* There is always just single entry to function. */
|
||||
case NOTE_INSN_BASIC_BLOCK:
|
||||
break;
|
||||
|
||||
/* There is no purpose to duplicate prologue. */
|
||||
case NOTE_INSN_BLOCK_BEG:
|
||||
case NOTE_INSN_BLOCK_END:
|
||||
/* The BLOCK_BEG/BLOCK_END notes should be eliminated when BB
|
||||
reordering is in the progress. */
|
||||
case NOTE_INSN_EH_REGION_BEG:
|
||||
case NOTE_INSN_EH_REGION_END:
|
||||
/* Should never exist at BB duplication time. */
|
||||
abort ();
|
||||
break;
|
||||
case NOTE_INSN_REPEATED_LINE_NUMBER:
|
||||
emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (NOTE_LINE_NUMBER (insn) < 0)
|
||||
abort ();
|
||||
/* It is possible that no_line_number is set and the note
|
||||
won't be emitted. */
|
||||
emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
insn = NEXT_INSN (last);
|
||||
delete_insn (last);
|
||||
return insn;
|
||||
}
|
||||
|
||||
/* Redirect Edge to DEST. */
|
||||
void
|
||||
cfg_layout_redirect_edge (e, dest)
|
||||
edge e;
|
||||
basic_block dest;
|
||||
{
|
||||
basic_block src = e->src;
|
||||
basic_block old_next_bb = src->next_bb;
|
||||
|
||||
/* Redirect_edge_and_branch may decide to turn branch into fallthru edge
|
||||
in the case the basic block appears to be in sequence. Avoid this
|
||||
transformation. */
|
||||
|
||||
src->next_bb = NULL;
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
{
|
||||
/* Redirect any branch edges unified with the fallthru one. */
|
||||
if (GET_CODE (src->end) == JUMP_INSN
|
||||
&& JUMP_LABEL (src->end) == e->dest->head)
|
||||
{
|
||||
if (!redirect_jump (src->end, block_label (dest), 0))
|
||||
abort ();
|
||||
}
|
||||
/* In case we are redirecting fallthru edge to the branch edge
|
||||
of conditional jump, remove it. */
|
||||
if (src->succ->succ_next
|
||||
&& !src->succ->succ_next->succ_next)
|
||||
{
|
||||
edge s = e->succ_next ? e->succ_next : src->succ;
|
||||
if (s->dest == dest
|
||||
&& any_condjump_p (src->end)
|
||||
&& onlyjump_p (src->end))
|
||||
delete_insn (src->end);
|
||||
}
|
||||
redirect_edge_succ_nodup (e, dest);
|
||||
}
|
||||
else
|
||||
redirect_edge_and_branch (e, dest);
|
||||
|
||||
/* We don't want simplejumps in the insn stream during cfglayout. */
|
||||
if (simplejump_p (src->end))
|
||||
{
|
||||
delete_insn (src->end);
|
||||
delete_barrier (NEXT_INSN (src->end));
|
||||
src->succ->flags |= EDGE_FALLTHRU;
|
||||
}
|
||||
src->next_bb = old_next_bb;
|
||||
}
|
||||
|
||||
/* Create a duplicate of the basic block BB and redirect edge E into it. */
|
||||
|
||||
basic_block
|
||||
cfg_layout_duplicate_bb (bb, e)
|
||||
basic_block bb;
|
||||
edge e;
|
||||
{
|
||||
rtx insn;
|
||||
edge s, n;
|
||||
basic_block new_bb;
|
||||
gcov_type new_count = e ? e->count : 0;
|
||||
|
||||
if (bb->count < new_count)
|
||||
new_count = bb->count;
|
||||
if (!bb->pred)
|
||||
abort ();
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (!cfg_layout_can_duplicate_bb_p (bb))
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
insn = duplicate_insn_chain (bb->head, bb->end);
|
||||
new_bb = create_basic_block (insn,
|
||||
insn ? get_last_insn () : NULL,
|
||||
EXIT_BLOCK_PTR->prev_bb);
|
||||
alloc_aux_for_block (new_bb, sizeof (struct reorder_block_def));
|
||||
|
||||
if (RBI (bb)->header)
|
||||
{
|
||||
insn = RBI (bb)->header;
|
||||
while (NEXT_INSN (insn))
|
||||
insn = NEXT_INSN (insn);
|
||||
insn = duplicate_insn_chain (RBI (bb)->header, insn);
|
||||
if (insn)
|
||||
RBI (new_bb)->header = unlink_insn_chain (insn, get_last_insn ());
|
||||
}
|
||||
|
||||
if (RBI (bb)->footer)
|
||||
{
|
||||
insn = RBI (bb)->footer;
|
||||
while (NEXT_INSN (insn))
|
||||
insn = NEXT_INSN (insn);
|
||||
insn = duplicate_insn_chain (RBI (bb)->footer, insn);
|
||||
if (insn)
|
||||
RBI (new_bb)->footer = unlink_insn_chain (insn, get_last_insn ());
|
||||
}
|
||||
|
||||
if (bb->global_live_at_start)
|
||||
{
|
||||
new_bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
|
||||
new_bb->global_live_at_end = OBSTACK_ALLOC_REG_SET (&flow_obstack);
|
||||
COPY_REG_SET (new_bb->global_live_at_start, bb->global_live_at_start);
|
||||
COPY_REG_SET (new_bb->global_live_at_end, bb->global_live_at_end);
|
||||
}
|
||||
|
||||
new_bb->loop_depth = bb->loop_depth;
|
||||
new_bb->flags = bb->flags;
|
||||
for (s = bb->succ; s; s = s->succ_next)
|
||||
{
|
||||
n = make_edge (new_bb, s->dest, s->flags);
|
||||
n->probability = s->probability;
|
||||
if (new_count)
|
||||
/* Take care for overflows! */
|
||||
n->count = s->count * (new_count * 10000 / bb->count) / 10000;
|
||||
else
|
||||
n->count = 0;
|
||||
s->count -= n->count;
|
||||
}
|
||||
|
||||
new_bb->count = new_count;
|
||||
bb->count -= new_count;
|
||||
|
||||
if (e)
|
||||
{
|
||||
new_bb->frequency = EDGE_FREQUENCY (e);
|
||||
bb->frequency -= EDGE_FREQUENCY (e);
|
||||
|
||||
cfg_layout_redirect_edge (e, new_bb);
|
||||
}
|
||||
|
||||
if (bb->count < 0)
|
||||
bb->count = 0;
|
||||
if (bb->frequency < 0)
|
||||
bb->frequency = 0;
|
||||
|
||||
RBI (new_bb)->original = bb;
|
||||
return new_bb;
|
||||
}
|
||||
|
||||
/* Main entry point to this module - initialize the datastructures for
|
||||
CFG layout changes. It keeps LOOPS up-to-date if not null. */
|
||||
|
||||
void
|
||||
cfg_layout_initialize ()
|
||||
{
|
||||
/* Our algorithm depends on fact that there are now dead jumptables
|
||||
around the code. */
|
||||
alloc_aux_for_blocks (sizeof (struct reorder_block_def));
|
||||
|
||||
scope_to_insns_initialize ();
|
||||
cleanup_unconditional_jumps ();
|
||||
|
||||
record_effective_endpoints ();
|
||||
}
|
||||
@ -586,8 +1019,6 @@ cfg_layout_finalize ()
|
||||
verify_insn_chain ();
|
||||
#endif
|
||||
|
||||
scope_to_insns_finalize ();
|
||||
|
||||
free_aux_for_blocks ();
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
|
@ -21,9 +21,12 @@
|
||||
/* Structure to hold information about the blocks during reordering. */
|
||||
typedef struct reorder_block_def
|
||||
{
|
||||
rtx eff_head;
|
||||
rtx eff_end;
|
||||
rtx header;
|
||||
rtx footer;
|
||||
basic_block next;
|
||||
basic_block original;
|
||||
|
||||
/* These fields are used by bb-reorder pass. */
|
||||
int visited;
|
||||
} *reorder_block_def;
|
||||
|
||||
@ -31,6 +34,8 @@ typedef struct reorder_block_def
|
||||
|
||||
extern void cfg_layout_initialize PARAMS ((void));
|
||||
extern void cfg_layout_finalize PARAMS ((void));
|
||||
|
||||
extern bool cfg_layout_can_duplicate_bb_p PARAMS ((basic_block));
|
||||
extern basic_block cfg_layout_duplicate_bb PARAMS ((basic_block, edge));
|
||||
extern void scope_to_insns_initialize PARAMS ((void));
|
||||
extern void scope_to_insns_finalize PARAMS ((void));
|
||||
extern void cfg_layout_redirect_edge PARAMS ((edge, basic_block));
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -57,10 +57,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "obstack.h"
|
||||
#include "intl.h"
|
||||
#include "version.h"
|
||||
|
||||
/* Obstack allocation and deallocation routines. */
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
|
||||
/* On certain systems, we have code that works by scanning the object file
|
||||
directly. But this code uses system-specific header files and library
|
||||
@ -144,11 +140,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
/* Some systems use __main in a way incompatible with its use in gcc, in these
|
||||
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
|
||||
give the same symbol without quotes for an alternative entry point. You
|
||||
must define both, or neither. */
|
||||
give the same symbol without quotes for an alternative entry point. */
|
||||
#ifndef NAME__MAIN
|
||||
#define NAME__MAIN "__main"
|
||||
#define SYMBOL__MAIN __main
|
||||
#endif
|
||||
|
||||
/* This must match tree.h. */
|
||||
@ -237,19 +231,11 @@ static struct head exports; /* list of exported symbols */
|
||||
static struct head frame_tables; /* list of frame unwind info tables */
|
||||
|
||||
struct obstack temporary_obstack;
|
||||
struct obstack permanent_obstack;
|
||||
char * temporary_firstobj;
|
||||
|
||||
/* Holds the return value of pexecute. */
|
||||
int pexecute_pid;
|
||||
|
||||
/* Defined in the automatically-generated underscore.c. */
|
||||
extern int prepends_underscore;
|
||||
|
||||
#ifndef GET_ENV_PATH_LIST
|
||||
#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
|
||||
#endif
|
||||
|
||||
/* Structure to hold all the directories in which to search for files to
|
||||
execute. */
|
||||
|
||||
@ -526,8 +512,8 @@ dump_file (name)
|
||||
if (*word == '.')
|
||||
++word, putc ('.', stderr);
|
||||
p = word;
|
||||
if (*p == '_' && prepends_underscore)
|
||||
++p;
|
||||
if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
|
||||
p += strlen (USER_LABEL_PREFIX);
|
||||
|
||||
if (no_demangle)
|
||||
result = 0;
|
||||
@ -762,7 +748,7 @@ prefix_from_env (env, pprefix)
|
||||
struct path_prefix *pprefix;
|
||||
{
|
||||
const char *p;
|
||||
GET_ENV_PATH_LIST (p, env);
|
||||
GET_ENVIRONMENT (p, env);
|
||||
|
||||
if (p)
|
||||
prefix_from_string (p, pprefix);
|
||||
@ -926,7 +912,6 @@ main (argc, argv)
|
||||
#endif
|
||||
|
||||
obstack_begin (&temporary_obstack, 0);
|
||||
obstack_begin (&permanent_obstack, 0);
|
||||
temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
|
||||
|
||||
current_demangling_style = auto_demangling;
|
||||
@ -1086,18 +1071,18 @@ main (argc, argv)
|
||||
{
|
||||
const char *q = extract_string (&p);
|
||||
if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
|
||||
*c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
|
||||
*c_ptr++ = xstrdup (q);
|
||||
if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
|
||||
*c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
|
||||
*c_ptr++ = xstrdup (q);
|
||||
if (strcmp (q, "-shared") == 0)
|
||||
shared_obj = 1;
|
||||
if (*q == '-' && q[1] == 'B')
|
||||
{
|
||||
*c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
|
||||
*c_ptr++ = xstrdup (q);
|
||||
if (q[2] == 0)
|
||||
{
|
||||
q = extract_string (&p);
|
||||
*c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
|
||||
*c_ptr++ = xstrdup (q);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1506,7 +1491,7 @@ main (argc, argv)
|
||||
}
|
||||
|
||||
|
||||
/* Wait for a process to finish, and exit if a non-zero status is found. */
|
||||
/* Wait for a process to finish, and exit if a nonzero status is found. */
|
||||
|
||||
int
|
||||
collect_wait (prog)
|
||||
@ -1522,7 +1507,7 @@ collect_wait (prog)
|
||||
int sig = WTERMSIG (status);
|
||||
error ("%s terminated with signal %d [%s]%s",
|
||||
prog, sig, strsignal(sig),
|
||||
status & 0200 ? "" : ", core dumped");
|
||||
WCOREDUMP(status) ? ", core dumped" : "");
|
||||
collect_exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
@ -2144,7 +2129,7 @@ scan_prog_file (prog_name, which_pass)
|
||||
fatal_perror ("close %d", pipe_fd[1]);
|
||||
|
||||
execv (nm_file_name, real_nm_argv);
|
||||
fatal_perror ("execvp %s", nm_file_name);
|
||||
fatal_perror ("execv %s", nm_file_name);
|
||||
}
|
||||
|
||||
/* Parent context from here on. */
|
||||
@ -2870,7 +2855,7 @@ scan_prog_file (prog_name, which_pass)
|
||||
(void) ldclose(ldptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* OBJECT_FORMAT_COFF */
|
||||
|
||||
#ifdef COLLECT_EXPORT_LIST
|
||||
/* Given a library name without "lib" prefix, this function
|
||||
@ -2950,9 +2935,7 @@ ignore_library (name)
|
||||
if (! strcmp (name, *p)) return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OBJECT_FORMAT_COFF */
|
||||
#endif /* COLLECT_EXPORT_LIST */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -36,7 +36,6 @@ extern int file_exists PARAMS ((const char *));
|
||||
extern const char *ldout;
|
||||
extern const char *c_file_name;
|
||||
extern struct obstack temporary_obstack;
|
||||
extern struct obstack permanent_obstack;
|
||||
extern char *temporary_firstobj;
|
||||
extern int vflag, debug;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* config.in. Generated automatically from configure.in by autoheader. */
|
||||
/* config.in. Generated automatically from configure.in by autoheader 2.13. */
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
@ -93,6 +93,9 @@
|
||||
/* Define if you have the __argz_stringify function. */
|
||||
#undef HAVE___ARGZ_STRINGIFY
|
||||
|
||||
/* Define if you have the alphasort function. */
|
||||
#undef HAVE_ALPHASORT
|
||||
|
||||
/* Define if you have the atoll function. */
|
||||
#undef HAVE_ATOLL
|
||||
|
||||
@ -138,15 +141,15 @@
|
||||
/* Define if you have the getgid function. */
|
||||
#undef HAVE_GETGID
|
||||
|
||||
/* Define if you have the getpagesize function. */
|
||||
#undef HAVE_GETPAGESIZE
|
||||
|
||||
/* Define if you have the getrlimit function. */
|
||||
#undef HAVE_GETRLIMIT
|
||||
|
||||
/* Define if you have the getrusage function. */
|
||||
#undef HAVE_GETRUSAGE
|
||||
|
||||
/* Define if you have the gettimeofday function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define if you have the getuid function. */
|
||||
#undef HAVE_GETUID
|
||||
|
||||
@ -159,6 +162,9 @@
|
||||
/* Define if you have the mempcpy function. */
|
||||
#undef HAVE_MEMPCPY
|
||||
|
||||
/* Define if you have the mmap function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if you have the munmap function. */
|
||||
#undef HAVE_MUNMAP
|
||||
|
||||
@ -171,6 +177,9 @@
|
||||
/* Define if you have the putenv function. */
|
||||
#undef HAVE_PUTENV
|
||||
|
||||
/* Define if you have the scandir function. */
|
||||
#undef HAVE_SCANDIR
|
||||
|
||||
/* Define if you have the setenv function. */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
@ -246,6 +255,9 @@
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
@ -273,39 +285,6 @@
|
||||
/* Define to enable the use of a default assembler. */
|
||||
#undef DEFAULT_ASSEMBLER
|
||||
|
||||
/* Define if you want more run-time sanity checks. This one gets a grab
|
||||
bag of miscellaneous but relatively cheap checks. */
|
||||
#undef ENABLE_CHECKING
|
||||
|
||||
/* Define if you want all operations on trees (the basic data
|
||||
structure of the front ends) to be checked for dynamic type safety
|
||||
at runtime. This is moderately expensive. */
|
||||
#undef ENABLE_TREE_CHECKING
|
||||
|
||||
/* Define if you want all operations on RTL (the basic data structure
|
||||
of the optimizer and back end) to be checked for dynamic type safety
|
||||
at runtime. This is quite expensive. */
|
||||
#undef ENABLE_RTL_CHECKING
|
||||
|
||||
/* Define if you want the garbage collector to do object poisoning and
|
||||
other memory allocation checks. This is quite expensive. */
|
||||
#undef ENABLE_GC_CHECKING
|
||||
|
||||
/* Define if you want the garbage collector to operate in maximally
|
||||
paranoid mode, validating the entire heap and collecting garbage at
|
||||
every opportunity. This is extremely expensive. */
|
||||
#undef ENABLE_GC_ALWAYS_COLLECT
|
||||
|
||||
/* Define if you want to use __cxa_atexit, rather than atexit, to
|
||||
register C++ destructors for local statics and global objects.
|
||||
This is essential for fully standards-compliant handling of
|
||||
destructors, but requires __cxa_atexit in libc. */
|
||||
#undef DEFAULT_USE_CXA_ATEXIT
|
||||
|
||||
/* Define if you want the C and C++ compilers to support multibyte
|
||||
character sets for source code. */
|
||||
#undef MULTIBYTE_CHARS
|
||||
|
||||
/* Define if your compiler understands volatile. */
|
||||
#undef HAVE_VOLATILE
|
||||
|
||||
@ -339,6 +318,48 @@
|
||||
/* Define if the host execution character set is EBCDIC. */
|
||||
#undef HOST_EBCDIC
|
||||
|
||||
/* Define if you want more run-time sanity checks. This one gets a grab
|
||||
bag of miscellaneous but relatively cheap checks. */
|
||||
#undef ENABLE_CHECKING
|
||||
|
||||
/* Define if you want all operations on trees (the basic data
|
||||
structure of the front ends) to be checked for dynamic type safety
|
||||
at runtime. This is moderately expensive. */
|
||||
#undef ENABLE_TREE_CHECKING
|
||||
|
||||
/* Define if you want all operations on RTL (the basic data structure
|
||||
of the optimizer and back end) to be checked for dynamic type safety
|
||||
at runtime. This is quite expensive. */
|
||||
#undef ENABLE_RTL_CHECKING
|
||||
|
||||
/* Define if you want RTL flag accesses to be checked against the RTL
|
||||
codes that are supported for each access macro. This is relatively
|
||||
cheap. */
|
||||
#undef ENABLE_RTL_FLAG_CHECKING
|
||||
|
||||
/* Define if you want the garbage collector to do object poisoning and
|
||||
other memory allocation checks. This is quite expensive. */
|
||||
#undef ENABLE_GC_CHECKING
|
||||
|
||||
/* Define if you want the garbage collector to operate in maximally
|
||||
paranoid mode, validating the entire heap and collecting garbage at
|
||||
every opportunity. This is extremely expensive. */
|
||||
#undef ENABLE_GC_ALWAYS_COLLECT
|
||||
|
||||
/* Define if you want to run subprograms and generated programs
|
||||
through valgrind (a memory checker). This is extremely expensive. */
|
||||
#undef ENABLE_VALGRIND_CHECKING
|
||||
|
||||
/* Define if you want to use __cxa_atexit, rather than atexit, to
|
||||
register C++ destructors for local statics and global objects.
|
||||
This is essential for fully standards-compliant handling of
|
||||
destructors, but requires __cxa_atexit in libc. */
|
||||
#undef DEFAULT_USE_CXA_ATEXIT
|
||||
|
||||
/* Define if you want the C and C++ compilers to support multibyte
|
||||
character sets for source code. */
|
||||
#undef MULTIBYTE_CHARS
|
||||
|
||||
/* Always define this when using the GNU C Library */
|
||||
#undef _GNU_SOURCE
|
||||
|
||||
@ -372,15 +393,15 @@
|
||||
/* Define if printf supports %p. */
|
||||
#undef HAVE_PRINTF_PTR
|
||||
|
||||
/* Define if mmap can get us zeroed pages from /dev/zero. */
|
||||
#undef HAVE_MMAP_DEV_ZERO
|
||||
|
||||
/* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */
|
||||
#undef HAVE_MMAP_ANON
|
||||
|
||||
/* Define if read-only mmap of a plain file works. */
|
||||
#undef HAVE_MMAP_FILE
|
||||
|
||||
/* Define if mmap of /dev/zero works. */
|
||||
#undef HAVE_MMAP_DEV_ZERO
|
||||
|
||||
/* Define if mmap with MAP_ANON(YMOUS) works. */
|
||||
#undef HAVE_MMAP_ANON
|
||||
|
||||
/* Define if you have the iconv() function. */
|
||||
#undef HAVE_ICONV
|
||||
|
||||
@ -429,6 +450,9 @@
|
||||
/* Define to 1 if we found this declaration otherwise define to 0. */
|
||||
#undef HAVE_DECL_ERRNO
|
||||
|
||||
/* Define to 1 if we found this declaration otherwise define to 0. */
|
||||
#undef HAVE_DECL_VASPRINTF
|
||||
|
||||
/* Define to 1 if we found this declaration otherwise define to 0. */
|
||||
#undef HAVE_DECL_MALLOC
|
||||
|
||||
@ -459,6 +483,9 @@
|
||||
/* Define to 1 if we found this declaration otherwise define to 0. */
|
||||
#undef HAVE_DECL_GETRUSAGE
|
||||
|
||||
/* Define to `long' if <sys/resource.h> doesn't define. */
|
||||
#undef rlim_t
|
||||
|
||||
/* Define to 1 if we found this declaration otherwise define to 0. */
|
||||
#undef HAVE_DECL_TIMES
|
||||
|
||||
@ -468,9 +495,20 @@
|
||||
/* Define if <time.h> defines clock_t. */
|
||||
#undef HAVE_CLOCK_T
|
||||
|
||||
/* Define .init_array/.fini_array sections are available and working. */
|
||||
#undef HAVE_INITFINI_ARRAY
|
||||
|
||||
/* Define if host mkdir takes a single argument. */
|
||||
#undef MKDIR_TAKES_ONE_ARG
|
||||
|
||||
/* Define to the name of a file containing a list of extra machine modes
|
||||
for this architecture. */
|
||||
#undef EXTRA_MODES_FILE
|
||||
|
||||
/* Define if the target architecture needs extra machine modes to represent
|
||||
the results of comparisons. */
|
||||
#undef EXTRA_CC_MODES
|
||||
|
||||
/* Define if you have the iconv() function. */
|
||||
#undef HAVE_ICONV
|
||||
|
||||
@ -523,6 +561,9 @@
|
||||
/* Define if your assembler supports marking sections with SHF_MERGE flag. */
|
||||
#undef HAVE_GAS_SHF_MERGE
|
||||
|
||||
/* Define if your assembler supports thread-local storage. */
|
||||
#undef HAVE_AS_TLS
|
||||
|
||||
/* Define if your assembler supports explicit relocations. */
|
||||
#undef HAVE_AS_EXPLICIT_RELOCS
|
||||
|
||||
@ -544,6 +585,9 @@
|
||||
/* Define true if the assembler supports '.long foo@GOTOFF'. */
|
||||
#undef HAVE_AS_GOTOFF_IN_DATA
|
||||
|
||||
/* Define if your assembler supports ltoffx and ldxmov relocations. */
|
||||
#undef HAVE_AS_LTOFFX_LDXMOV_RELOCS
|
||||
|
||||
/* Define if your assembler supports dwarf2 .file/.loc directives,
|
||||
and preserves file table indices exactly as given. */
|
||||
#undef HAVE_AS_DWARF2_DEBUG_LINE
|
||||
@ -554,12 +598,22 @@
|
||||
/* Define if your assembler supports the --gstabs option. */
|
||||
#undef HAVE_AS_GSTABS_DEBUG_FLAG
|
||||
|
||||
/* Define if your linker links a mix of read-only
|
||||
and read-write sections into a read-write section. */
|
||||
#undef HAVE_LD_RO_RW_SECTION_MIXING
|
||||
|
||||
/* Define if your linker supports --eh-frame-hdr option. */
|
||||
#undef HAVE_LD_EH_FRAME_HDR
|
||||
|
||||
/* Define if your MIPS libgloss linker scripts consistently include STARTUP directives. */
|
||||
#undef HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES
|
||||
|
||||
/* Define 0/1 to force the choice for exception handling model. */
|
||||
#undef CONFIG_SJLJ_EXCEPTIONS
|
||||
|
||||
/* Define if gcc should use -lunwind. */
|
||||
#undef USE_LIBUNWIND_EXCEPTIONS
|
||||
|
||||
|
||||
/* Bison unconditionally undefines `const' if neither `__STDC__' nor
|
||||
__cplusplus are defined. That's a problem since we use `const' in
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler, for DEC Alpha
|
||||
running Windows/NT.
|
||||
Copyright (C) 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
|
||||
Donn Terry, Softway Systems, Inc.
|
||||
From code
|
||||
@ -25,15 +25,18 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* cpp handles __STDC__ */
|
||||
/* The three "Alpha" defines on the first such line are from the CLAXP spec */
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES " \
|
||||
-D__INTERIX \
|
||||
-D__OPENNT \
|
||||
-D__Alpha_AXP -D_M_ALPHA -D_ALPHA_ \
|
||||
-D__alpha -D__alpha__\
|
||||
-D__stdcall= \
|
||||
-D__cdecl= \
|
||||
-Asystem=unix -Asystem=interix -Acpu=alpha -Amachine=alpha"
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define ("__INTERIX"); \
|
||||
builtin_define ("__OPENNT"); \
|
||||
builtin_define ("__Alpha_AXP"); \
|
||||
builtin_define ("_M_ALPHA"); \
|
||||
builtin_define ("_ALPHA_"); \
|
||||
builtin_define ("__stdcall="); \
|
||||
builtin_define ("__cdecl="); \
|
||||
builtin_assert ("system=unix"); \
|
||||
builtin_assert ("system=interix"); \
|
||||
} while (0)
|
||||
|
||||
#undef CPP_SUBTARGET_SPEC
|
||||
#define CPP_SUBTARGET_SPEC "\
|
||||
@ -64,17 +67,9 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* The following are needed for C++, but also needed for profiling */
|
||||
|
||||
/* Support const sections and the ctors and dtors sections for g++.
|
||||
Note that there appears to be two different ways to support const
|
||||
sections at the moment. You can either #define the symbol
|
||||
READONLY_DATA_SECTION (giving it some code which switches to the
|
||||
readonly data section) or else you can #define the symbols
|
||||
EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and
|
||||
SELECT_RTX_SECTION. We do both here just to be on the safe side. */
|
||||
/* Support const sections and the ctors and dtors sections for g++. */
|
||||
|
||||
#define USE_CONST_SECTION 1
|
||||
|
||||
#define CONST_SECTION_ASM_OP "\t.rdata"
|
||||
#define READONLY_DATA_SECTION_ASM_OP "\t.rdata"
|
||||
|
||||
/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
|
||||
|
||||
@ -94,38 +89,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#define CTORS_SECTION_ASM_OP "\t.ctors"
|
||||
#define DTORS_SECTION_ASM_OP "\t.dtors"
|
||||
|
||||
/* A default list of other sections which we might be "in" at any given
|
||||
time. For targets that use additional sections (e.g. .tdesc) you
|
||||
should override this definition in the target-specific file which
|
||||
includes this file. */
|
||||
|
||||
#undef EXTRA_SECTIONS
|
||||
#define EXTRA_SECTIONS in_const
|
||||
|
||||
/* A default list of extra section function definitions. For targets
|
||||
that use additional sections (e.g. .tdesc) you should override this
|
||||
definition in the target-specific file which includes this file. */
|
||||
|
||||
#undef EXTRA_SECTION_FUNCTIONS
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
CONST_SECTION_FUNCTION
|
||||
|
||||
#undef READONLY_DATA_SECTION
|
||||
#define READONLY_DATA_SECTION() const_section ()
|
||||
|
||||
#define CONST_SECTION_FUNCTION \
|
||||
void \
|
||||
const_section () \
|
||||
{ \
|
||||
if (!USE_CONST_SECTION) \
|
||||
text_section(); \
|
||||
else if (in_section != in_const) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \
|
||||
in_section = in_const; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* The linker will take care of this, and having them causes problems with
|
||||
ld -r (specifically -rU). */
|
||||
#define CTOR_LISTS_DEFINED_EXTERNALLY 1
|
||||
@ -185,15 +148,3 @@ while (0)
|
||||
fprintf (FILE, "\t.globl\t__fltused\n"); \
|
||||
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
|
||||
}
|
||||
|
||||
/* The current Interix assembler (consistent with the DEC documentation)
|
||||
uses a=b NOT .set a,b; .set is for assembler options. */
|
||||
#undef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL
|
||||
#define ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL(FILE, SY, HI, LO) \
|
||||
do { \
|
||||
assemble_name (FILE, SY); \
|
||||
fputc ('=', FILE); \
|
||||
assemble_name (FILE, HI); \
|
||||
fputc ('-', FILE); \
|
||||
assemble_name (FILE, LO); \
|
||||
} while (0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Prototypes for alpha.c functions used in the md file & elsewhere.
|
||||
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -34,10 +34,10 @@ extern void alpha_expand_epilogue PARAMS ((void));
|
||||
extern void alpha_output_filename PARAMS ((FILE *, const char *));
|
||||
extern void alpha_output_lineno PARAMS ((FILE *, int));
|
||||
|
||||
#ifdef RTX_CODE
|
||||
extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_6bit_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_8bit_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_const_int_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int cint8_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int add_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int sext_add_operand PARAMS ((rtx, enum machine_mode));
|
||||
@ -47,8 +47,7 @@ extern int or_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int mode_width_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int mode_mask_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int mul8_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int fp0_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_fp0_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int const0_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int hard_fp_register_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int hard_int_register_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
|
||||
@ -61,6 +60,12 @@ extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int some_small_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int dtp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int dtp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int gotdtp_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int tp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int tp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int gottp_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int call_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode));
|
||||
@ -108,13 +113,7 @@ extern rtx alpha_emit_set_long_const PARAMS ((rtx, HOST_WIDE_INT,
|
||||
extern bool alpha_expand_mov PARAMS ((enum machine_mode, rtx *));
|
||||
extern bool alpha_expand_mov_nobwx PARAMS ((enum machine_mode, rtx *));
|
||||
extern void alpha_emit_floatuns PARAMS ((rtx[]));
|
||||
extern rtx alpha_emit_conditional_branch PARAMS ((enum rtx_code));
|
||||
extern rtx alpha_emit_setcc PARAMS ((enum rtx_code));
|
||||
extern rtx alpha_emit_conditional_move PARAMS ((rtx, enum machine_mode));
|
||||
extern int alpha_split_conditional_move PARAMS ((enum rtx_code, rtx, rtx,
|
||||
rtx, rtx));
|
||||
extern void alpha_emit_xfloating_arith PARAMS ((enum rtx_code, rtx[]));
|
||||
extern void alpha_emit_xfloating_cvt PARAMS ((enum rtx_code, rtx[]));
|
||||
extern void alpha_split_tfmode_pair PARAMS ((rtx[]));
|
||||
extern void alpha_split_tfmode_frobsign PARAMS ((rtx[],
|
||||
rtx (*)(rtx, rtx, rtx)));
|
||||
@ -124,61 +123,55 @@ extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT,
|
||||
HOST_WIDE_INT));
|
||||
extern int alpha_expand_block_move PARAMS ((rtx []));
|
||||
extern int alpha_expand_block_clear PARAMS ((rtx []));
|
||||
extern rtx alpha_expand_zap_mask PARAMS ((HOST_WIDE_INT));
|
||||
extern void alpha_expand_builtin_vector_binop PARAMS ((rtx (*)(rtx, rtx, rtx),
|
||||
enum machine_mode,
|
||||
rtx, rtx, rtx));
|
||||
extern rtx alpha_return_addr PARAMS ((int, rtx));
|
||||
extern rtx alpha_gp_save_rtx PARAMS ((void));
|
||||
extern void print_operand PARAMS ((FILE *, rtx, int));
|
||||
extern void print_operand_address PARAMS ((FILE *, rtx));
|
||||
extern void alpha_initialize_trampoline PARAMS ((rtx, rtx, rtx, int, int, int));
|
||||
extern void alpha_reorg PARAMS ((rtx));
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
extern tree alpha_build_va_list PARAMS ((void));
|
||||
extern void alpha_va_start PARAMS ((tree, rtx));
|
||||
extern rtx alpha_va_arg PARAMS ((tree, tree));
|
||||
extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
|
||||
tree, int));
|
||||
extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
|
||||
extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
|
||||
|
||||
extern int alpha_find_lo_sum_using_gp PARAMS ((rtx));
|
||||
|
||||
#ifdef REAL_VALUE_TYPE
|
||||
extern int check_float_value PARAMS ((enum machine_mode,
|
||||
REAL_VALUE_TYPE *, int));
|
||||
REAL_VALUE_TYPE *, int));
|
||||
#endif
|
||||
|
||||
#ifdef RTX_CODE
|
||||
extern rtx alpha_emit_conditional_branch PARAMS ((enum rtx_code));
|
||||
extern rtx alpha_emit_setcc PARAMS ((enum rtx_code));
|
||||
extern int alpha_split_conditional_move PARAMS ((enum rtx_code, rtx, rtx,
|
||||
rtx, rtx));
|
||||
extern void alpha_emit_xfloating_arith PARAMS ((enum rtx_code, rtx[]));
|
||||
extern void alpha_emit_xfloating_cvt PARAMS ((enum rtx_code, rtx[]));
|
||||
#endif
|
||||
|
||||
extern rtx alpha_need_linkage PARAMS ((const char *, int));
|
||||
extern rtx alpha_use_linkage PARAMS ((rtx, tree, int, int));
|
||||
|
||||
#if TARGET_ABI_OPEN_VMS
|
||||
#ifdef HAVE_MACHINE_MODES
|
||||
extern enum avms_arg_type alpha_arg_type PARAMS ((enum machine_mode));
|
||||
#endif
|
||||
#ifdef RTX_CODE
|
||||
extern rtx alpha_arg_info_reg_val PARAMS ((CUMULATIVE_ARGS));
|
||||
#endif
|
||||
#ifdef BUFSIZ
|
||||
extern void alpha_write_linkage PARAMS ((FILE *));
|
||||
#endif
|
||||
#endif /* TARGET_ABI_OPEN_VMS */
|
||||
|
||||
#ifdef RTX_CODE
|
||||
extern rtx alpha_need_linkage PARAMS ((const char *, int));
|
||||
#endif
|
||||
|
||||
#ifdef TREE_CODE
|
||||
extern tree alpha_build_va_list PARAMS ((void));
|
||||
#ifdef RTX_CODE
|
||||
extern void alpha_va_start PARAMS ((int, tree, rtx));
|
||||
extern rtx alpha_va_arg PARAMS ((tree, tree));
|
||||
extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
|
||||
tree, int));
|
||||
#endif
|
||||
extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
|
||||
extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
|
||||
extern void alpha_output_mi_thunk_osf PARAMS ((FILE *, tree,
|
||||
HOST_WIDE_INT, tree));
|
||||
extern void alpha_encode_section_info PARAMS ((tree));
|
||||
#endif /* TREE CODE */
|
||||
|
||||
#ifdef RTX_CODE
|
||||
extern rtx unicosmk_add_call_info_word PARAMS ((rtx));
|
||||
#endif
|
||||
|
||||
#if TARGET_ABI_UNICOSMK
|
||||
#ifdef RTX_CODE
|
||||
extern void unicosmk_defer_case_vector PARAMS ((rtx, rtx));
|
||||
#endif
|
||||
#ifdef TREE_CODE
|
||||
extern void unicosmk_unique_section PARAMS ((tree, int));
|
||||
#endif
|
||||
extern void unicosmk_add_extern PARAMS ((const char *));
|
||||
extern void unicosmk_output_align PARAMS ((FILE *, int));
|
||||
extern char * unicosmk_text_section PARAMS ((void));
|
||||
|
@ -20,24 +20,81 @@ along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Target CPU builtins. */
|
||||
#define TARGET_CPU_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
builtin_define ("__alpha"); \
|
||||
builtin_define ("__alpha__"); \
|
||||
builtin_assert ("cpu=alpha"); \
|
||||
builtin_assert ("machine=alpha"); \
|
||||
if (TARGET_CIX) \
|
||||
{ \
|
||||
builtin_define ("__alpha_cix__"); \
|
||||
builtin_assert ("cpu=cix"); \
|
||||
} \
|
||||
if (TARGET_FIX) \
|
||||
{ \
|
||||
builtin_define ("__alpha_fix__"); \
|
||||
builtin_assert ("cpu=fix"); \
|
||||
} \
|
||||
if (TARGET_BWX) \
|
||||
{ \
|
||||
builtin_define ("__alpha_bwx__"); \
|
||||
builtin_assert ("cpu=bwx"); \
|
||||
} \
|
||||
if (TARGET_MAX) \
|
||||
{ \
|
||||
builtin_define ("__alpha_max__"); \
|
||||
builtin_assert ("cpu=max"); \
|
||||
} \
|
||||
if (TARGET_CPU_EV6) \
|
||||
{ \
|
||||
builtin_define ("__alpha_ev6__"); \
|
||||
builtin_assert ("cpu=ev6"); \
|
||||
} \
|
||||
else if (TARGET_CPU_EV5) \
|
||||
{ \
|
||||
builtin_define ("__alpha_ev5__"); \
|
||||
builtin_assert ("cpu=ev5"); \
|
||||
} \
|
||||
else /* Presumably ev4. */ \
|
||||
{ \
|
||||
builtin_define ("__alpha_ev4__"); \
|
||||
builtin_assert ("cpu=ev4"); \
|
||||
} \
|
||||
if (TARGET_IEEE || TARGET_IEEE_WITH_INEXACT) \
|
||||
builtin_define ("_IEEE_FP"); \
|
||||
if (TARGET_IEEE_WITH_INEXACT) \
|
||||
builtin_define ("_IEEE_FP_INEXACT"); \
|
||||
\
|
||||
/* Macros dependent on the C dialect. */ \
|
||||
SUBTARGET_LANGUAGE_CPP_BUILTINS(); \
|
||||
} while (0)
|
||||
|
||||
/* For C++ we need to ensure that __LANGUAGE_C_PLUS_PLUS is defined independent
|
||||
of the source file extension. */
|
||||
#define CPLUSPLUS_CPP_SPEC "\
|
||||
-D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus \
|
||||
%(cpp) \
|
||||
"
|
||||
#ifndef SUBTARGET_LANGUAGE_CPP_BUILTINS
|
||||
#define SUBTARGET_LANGUAGE_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
if (preprocessing_asm_p ()) \
|
||||
builtin_define_std ("LANGUAGE_ASSEMBLY"); \
|
||||
else if (c_language == clk_c) \
|
||||
builtin_define_std ("LANGUAGE_C"); \
|
||||
else if (c_language == clk_cplusplus) \
|
||||
{ \
|
||||
builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \
|
||||
builtin_define ("__LANGUAGE_C_PLUS_PLUS__"); \
|
||||
} \
|
||||
if (flag_objc) \
|
||||
{ \
|
||||
builtin_define ("__LANGUAGE_OBJECTIVE_C"); \
|
||||
builtin_define ("__LANGUAGE_OBJECTIVE_C__"); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Write out the correct language type definition for the header files.
|
||||
Unless we have assembler language, write out the symbols for C. */
|
||||
#define CPP_SPEC "\
|
||||
%{!undef:\
|
||||
%{.S:-D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY }}\
|
||||
%{.m:-D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C }\
|
||||
%{!.S:%{!.cc:%{!.cxx:%{!.cpp:%{!.cp:%{!.c++:%{!.C:%{!.m:-D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C }}}}}}}}}\
|
||||
%{mieee:-D_IEEE_FP }\
|
||||
%{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT }}\
|
||||
%(cpp_cpu) %(cpp_subtarget)"
|
||||
#define CPP_SPEC "%(cpp_subtarget)"
|
||||
|
||||
#ifndef CPP_SUBTARGET_SPEC
|
||||
#define CPP_SUBTARGET_SPEC ""
|
||||
@ -89,6 +146,7 @@ extern int target_flags;
|
||||
extern enum alpha_trap_precision alpha_tp;
|
||||
extern enum alpha_fp_rounding_mode alpha_fprm;
|
||||
extern enum alpha_fp_trap_mode alpha_fptm;
|
||||
extern int alpha_tls_size;
|
||||
|
||||
/* This means that floating-point support exists in the target implementation
|
||||
of the Alpha architecture. This is usually the default. */
|
||||
@ -160,6 +218,10 @@ extern enum alpha_fp_trap_mode alpha_fptm;
|
||||
#define MASK_SMALL_DATA (1 << 13)
|
||||
#define TARGET_SMALL_DATA (target_flags & MASK_SMALL_DATA)
|
||||
|
||||
/* This means emit thread pointer loads for kernel not user. */
|
||||
#define MASK_TLS_KERNEL (1 << 14)
|
||||
#define TARGET_TLS_KERNEL (target_flags & MASK_TLS_KERNEL)
|
||||
|
||||
/* This means that the processor is an EV5, EV56, or PCA56.
|
||||
Unlike alpha_cpu this is not affected by -mtune= setting. */
|
||||
#define MASK_CPU_EV5 (1 << 28)
|
||||
@ -203,6 +265,9 @@ extern enum alpha_fp_trap_mode alpha_fptm;
|
||||
#ifndef TARGET_FIXUP_EV5_PREFETCH
|
||||
#define TARGET_FIXUP_EV5_PREFETCH 0
|
||||
#endif
|
||||
#ifndef HAVE_AS_TLS
|
||||
#define HAVE_AS_TLS 0
|
||||
#endif
|
||||
|
||||
/* Macro to define tables used to set the flags.
|
||||
This is a list in braces of pairs in braces,
|
||||
@ -245,6 +310,8 @@ extern enum alpha_fp_trap_mode alpha_fptm;
|
||||
N_("Emit 16-bit relocations to the small data areas")}, \
|
||||
{"large-data", -MASK_SMALL_DATA, \
|
||||
N_("Emit 32-bit relocations to the small data areas")}, \
|
||||
{"tls-kernel", MASK_TLS_KERNEL, \
|
||||
N_("Emit rdval instead of rduniq for thread pointer")}, \
|
||||
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT \
|
||||
| TARGET_DEFAULT_EXPLICIT_RELOCS, ""} }
|
||||
|
||||
@ -268,6 +335,7 @@ extern const char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */
|
||||
extern const char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */
|
||||
extern const char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */
|
||||
extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
extern const char *alpha_tls_size_string; /* For -mtls-size= */
|
||||
|
||||
#define TARGET_OPTIONS \
|
||||
{ \
|
||||
@ -283,67 +351,10 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
N_("Control the precision given to fp exceptions")}, \
|
||||
{"memory-latency=", &alpha_mlat_string, \
|
||||
N_("Tune expected memory latency")}, \
|
||||
{"tls-size=", &alpha_tls_size_string, \
|
||||
N_("Specify bit size of immediate TLS offsets")}, \
|
||||
}
|
||||
|
||||
/* Attempt to describe CPU characteristics to the preprocessor. */
|
||||
|
||||
/* Corresponding to amask... */
|
||||
#define CPP_AM_BWX_SPEC "-D__alpha_bwx__ -Acpu=bwx"
|
||||
#define CPP_AM_MAX_SPEC "-D__alpha_max__ -Acpu=max"
|
||||
#define CPP_AM_FIX_SPEC "-D__alpha_fix__ -Acpu=fix"
|
||||
#define CPP_AM_CIX_SPEC "-D__alpha_cix__ -Acpu=cix"
|
||||
|
||||
/* Corresponding to implver... */
|
||||
#define CPP_IM_EV4_SPEC "-D__alpha_ev4__ -Acpu=ev4"
|
||||
#define CPP_IM_EV5_SPEC "-D__alpha_ev5__ -Acpu=ev5"
|
||||
#define CPP_IM_EV6_SPEC "-D__alpha_ev6__ -Acpu=ev6"
|
||||
|
||||
/* Common combinations. */
|
||||
#define CPP_CPU_EV4_SPEC "%(cpp_im_ev4)"
|
||||
#define CPP_CPU_EV5_SPEC "%(cpp_im_ev5)"
|
||||
#define CPP_CPU_EV56_SPEC "%(cpp_im_ev5) %(cpp_am_bwx)"
|
||||
#define CPP_CPU_PCA56_SPEC "%(cpp_im_ev5) %(cpp_am_bwx) %(cpp_am_max)"
|
||||
#define CPP_CPU_EV6_SPEC \
|
||||
"%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_fix)"
|
||||
#define CPP_CPU_EV67_SPEC \
|
||||
"%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_fix) %(cpp_am_cix)"
|
||||
|
||||
#ifndef CPP_CPU_DEFAULT_SPEC
|
||||
# if TARGET_CPU_DEFAULT & MASK_CPU_EV6
|
||||
# if TARGET_CPU_DEFAULT & MASK_CIX
|
||||
# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV67_SPEC
|
||||
# else
|
||||
# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV6_SPEC
|
||||
# endif
|
||||
# else
|
||||
# if TARGET_CPU_DEFAULT & MASK_CPU_EV5
|
||||
# if TARGET_CPU_DEFAULT & MASK_MAX
|
||||
# define CPP_CPU_DEFAULT_SPEC CPP_CPU_PCA56_SPEC
|
||||
# else
|
||||
# if TARGET_CPU_DEFAULT & MASK_BWX
|
||||
# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV56_SPEC
|
||||
# else
|
||||
# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV5_SPEC
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
# define CPP_CPU_DEFAULT_SPEC CPP_CPU_EV4_SPEC
|
||||
# endif
|
||||
# endif
|
||||
#endif /* CPP_CPU_DEFAULT_SPEC */
|
||||
|
||||
#ifndef CPP_CPU_SPEC
|
||||
#define CPP_CPU_SPEC "\
|
||||
%{!undef:-Acpu=alpha -Amachine=alpha -D__alpha -D__alpha__ \
|
||||
%{mcpu=ev4|mcpu=21064:%(cpp_cpu_ev4) }\
|
||||
%{mcpu=ev5|mcpu=21164:%(cpp_cpu_ev5) }\
|
||||
%{mcpu=ev56|mcpu=21164a:%(cpp_cpu_ev56) }\
|
||||
%{mcpu=pca56|mcpu=21164pc|mcpu=21164PC:%(cpp_cpu_pca56) }\
|
||||
%{mcpu=ev6|mcpu=21264:%(cpp_cpu_ev6) }\
|
||||
%{mcpu=ev67|mcpu=21264a:%(cpp_cpu_ev67) }\
|
||||
%{!mcpu*:%(cpp_cpu_default) }}"
|
||||
#endif
|
||||
|
||||
/* This macro defines names of additional specifications to put in the
|
||||
specs that can be used in various specifications like CC1_SPEC. Its
|
||||
definition is an initializer with a subgrouping for each command option.
|
||||
@ -359,21 +370,6 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
#endif
|
||||
|
||||
#define EXTRA_SPECS \
|
||||
{ "cpp_am_bwx", CPP_AM_BWX_SPEC }, \
|
||||
{ "cpp_am_max", CPP_AM_MAX_SPEC }, \
|
||||
{ "cpp_am_fix", CPP_AM_FIX_SPEC }, \
|
||||
{ "cpp_am_cix", CPP_AM_CIX_SPEC }, \
|
||||
{ "cpp_im_ev4", CPP_IM_EV4_SPEC }, \
|
||||
{ "cpp_im_ev5", CPP_IM_EV5_SPEC }, \
|
||||
{ "cpp_im_ev6", CPP_IM_EV6_SPEC }, \
|
||||
{ "cpp_cpu_ev4", CPP_CPU_EV4_SPEC }, \
|
||||
{ "cpp_cpu_ev5", CPP_CPU_EV5_SPEC }, \
|
||||
{ "cpp_cpu_ev56", CPP_CPU_EV56_SPEC }, \
|
||||
{ "cpp_cpu_pca56", CPP_CPU_PCA56_SPEC }, \
|
||||
{ "cpp_cpu_ev6", CPP_CPU_EV6_SPEC }, \
|
||||
{ "cpp_cpu_ev67", CPP_CPU_EV67_SPEC }, \
|
||||
{ "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \
|
||||
{ "cpp_cpu", CPP_CPU_SPEC }, \
|
||||
{ "cpp_subtarget", CPP_SUBTARGET_SPEC }, \
|
||||
SUBTARGET_EXTRA_SPECS
|
||||
|
||||
@ -409,15 +405,16 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
|
||||
/* target machine storage layout */
|
||||
|
||||
/* Define to enable software floating point emulation. */
|
||||
#define REAL_ARITHMETIC
|
||||
|
||||
/* Define the size of `int'. The default is the same as the word size. */
|
||||
#define INT_TYPE_SIZE 32
|
||||
|
||||
/* Define the size of `long long'. The default is the twice the word size. */
|
||||
#define LONG_LONG_TYPE_SIZE 64
|
||||
|
||||
/* We're IEEE unless someone says to use VAX. */
|
||||
#define TARGET_FLOAT_FORMAT \
|
||||
(TARGET_FLOAT_VAX ? VAX_FLOAT_FORMAT : IEEE_FLOAT_FORMAT)
|
||||
|
||||
/* The two floating-point formats we support are S-floating, which is
|
||||
4 bytes, and T-floating, which is 8 bytes. `float' is S and `double'
|
||||
and `long double' are T. */
|
||||
@ -474,15 +471,6 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
for them. Might as well be consistent with bytes. */
|
||||
#define WORDS_BIG_ENDIAN 0
|
||||
|
||||
/* number of bits in an addressable storage unit */
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
/* Width in bits of a "word", which is the contents of a machine register.
|
||||
Note that this is not necessarily the width of data type `int';
|
||||
if using 16-bit ints on a 68000, this would still be 32.
|
||||
But on a machine with 16-bit registers, this would be 16. */
|
||||
#define BITS_PER_WORD 64
|
||||
|
||||
/* Width of a word, in units (bytes). */
|
||||
#define UNITS_PER_WORD 8
|
||||
|
||||
@ -505,7 +493,7 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
/* Every structure's size must be a multiple of this. */
|
||||
#define STRUCTURE_SIZE_BOUNDARY 8
|
||||
|
||||
/* A bitfield declared as `int' forces `int' alignment for the struct. */
|
||||
/* A bit-field declared as `int' forces `int' alignment for the struct. */
|
||||
#define PCC_BITFIELD_TYPE_MATTERS 1
|
||||
|
||||
/* No data type wants to be aligned rounder than this. */
|
||||
@ -524,14 +512,14 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
#define DATA_ALIGNMENT(EXP, ALIGN) MAX ((ALIGN), BITS_PER_WORD)
|
||||
#endif
|
||||
|
||||
/* Set this non-zero if move instructions will actually fail to work
|
||||
/* Set this nonzero if move instructions will actually fail to work
|
||||
when given unaligned data.
|
||||
|
||||
Since we get an error message when we do one, call them invalid. */
|
||||
|
||||
#define STRICT_ALIGNMENT 1
|
||||
|
||||
/* Set this non-zero if unaligned move instructions are extremely slow.
|
||||
/* Set this nonzero if unaligned move instructions are extremely slow.
|
||||
|
||||
On the Alpha, they trap. */
|
||||
|
||||
@ -640,6 +628,12 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \
|
||||
: 1)
|
||||
|
||||
/* Value is 1 if MODE is a supported vector mode. */
|
||||
|
||||
#define VECTOR_MODE_SUPPORTED_P(MODE) \
|
||||
(TARGET_MAX \
|
||||
&& ((MODE) == V8QImode || (MODE) == V4HImode || (MODE) == V2SImode))
|
||||
|
||||
/* A C expression that is nonzero if a value of mode
|
||||
MODE1 is accessible in mode MODE2 without copying.
|
||||
|
||||
@ -719,7 +713,7 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
|
||||
class that represents their union. */
|
||||
|
||||
enum reg_class {
|
||||
NO_REGS, R24_REG, R25_REG, R27_REG,
|
||||
NO_REGS, R0_REG, R24_REG, R25_REG, R27_REG,
|
||||
GENERAL_REGS, FLOAT_REGS, ALL_REGS,
|
||||
LIM_REG_CLASSES
|
||||
};
|
||||
@ -728,8 +722,8 @@ enum reg_class {
|
||||
|
||||
/* Give names of register classes as strings for dump file. */
|
||||
|
||||
#define REG_CLASS_NAMES \
|
||||
{"NO_REGS", "R24_REG", "R25_REG", "R27_REG", \
|
||||
#define REG_CLASS_NAMES \
|
||||
{"NO_REGS", "R0_REG", "R24_REG", "R25_REG", "R27_REG", \
|
||||
"GENERAL_REGS", "FLOAT_REGS", "ALL_REGS" }
|
||||
|
||||
/* Define which registers fit in which classes.
|
||||
@ -738,6 +732,7 @@ enum reg_class {
|
||||
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ {0x00000000, 0x00000000}, /* NO_REGS */ \
|
||||
{0x00000001, 0x00000000}, /* R0_REG */ \
|
||||
{0x01000000, 0x00000000}, /* R24_REG */ \
|
||||
{0x02000000, 0x00000000}, /* R25_REG */ \
|
||||
{0x08000000, 0x00000000}, /* R27_REG */ \
|
||||
@ -751,7 +746,8 @@ enum reg_class {
|
||||
or could index an array. */
|
||||
|
||||
#define REGNO_REG_CLASS(REGNO) \
|
||||
((REGNO) == 24 ? R24_REG \
|
||||
((REGNO) == 0 ? R0_REG \
|
||||
: (REGNO) == 24 ? R24_REG \
|
||||
: (REGNO) == 25 ? R25_REG \
|
||||
: (REGNO) == 27 ? R27_REG \
|
||||
: (REGNO) >= 32 && (REGNO) <= 62 ? FLOAT_REGS \
|
||||
@ -768,6 +764,7 @@ enum reg_class {
|
||||
: (C) == 'b' ? R25_REG \
|
||||
: (C) == 'c' ? R27_REG \
|
||||
: (C) == 'f' ? FLOAT_REGS \
|
||||
: (C) == 'v' ? R0_REG \
|
||||
: NO_REGS)
|
||||
|
||||
/* Define this macro to change register usage conditional on target flags. */
|
||||
@ -811,7 +808,9 @@ enum reg_class {
|
||||
|
||||
'T' is a HIGH.
|
||||
|
||||
'U' is a symbolic operand. */
|
||||
'U' is a symbolic operand.
|
||||
|
||||
'W' is a vector zero. */
|
||||
|
||||
#define EXTRA_CONSTRAINT alpha_extra_constraint
|
||||
|
||||
@ -858,15 +857,11 @@ enum reg_class {
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* If defined, gives a class of registers that cannot be used as the
|
||||
operand of a SUBREG that changes the mode of the object illegally. */
|
||||
/* Return the class of registers that cannot change mode from FROM to TO. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
|
||||
|
||||
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
|
||||
? reg_classes_intersect_p (FLOAT_REGS, CLASS) : 0)
|
||||
|
||||
/* Define the cost of moving between registers of various classes. Moving
|
||||
between FLOAT_REGS and anything else except float regs is expensive.
|
||||
@ -1172,12 +1167,11 @@ extern int alpha_memory_latency;
|
||||
|
||||
/* We do not allow indirect calls to be optimized into sibling calls, nor
|
||||
can we allow a call to a function in a different compilation unit to
|
||||
be optimized into a sibcall. Except if the function is known not to
|
||||
return, in which case our caller doesn't care what the gp is. */
|
||||
be optimized into a sibcall. */
|
||||
#define FUNCTION_OK_FOR_SIBCALL(DECL) \
|
||||
(DECL \
|
||||
&& ((TREE_ASM_WRITTEN (DECL) && !flag_pic) \
|
||||
|| ! TREE_PUBLIC (DECL)))
|
||||
&& (! TREE_PUBLIC (DECL) \
|
||||
|| (TREE_ASM_WRITTEN (DECL) && (*targetm.binds_local_p) (DECL))))
|
||||
|
||||
/* Try to output insns to set TARGET equal to the constant C if it can be
|
||||
done in less than N insns. Do all computations in MODE. Returns the place
|
||||
@ -1474,7 +1468,7 @@ do { \
|
||||
#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TImode)
|
||||
|
||||
/* Nonzero if access to memory by bytes is no faster than for words.
|
||||
Also non-zero if doing byte operations (specifically shifts) in registers
|
||||
Also nonzero if doing byte operations (specifically shifts) in registers
|
||||
is undesirable.
|
||||
|
||||
On the Alpha, we want to not use the byte operation and instead use
|
||||
@ -1730,60 +1724,6 @@ do { \
|
||||
|
||||
#define DATA_SECTION_ASM_OP "\t.data"
|
||||
|
||||
/* Define an extra section for read-only data, a routine to enter it, and
|
||||
indicate that it is for read-only data.
|
||||
|
||||
The first time we enter the readonly data section for a file, we write
|
||||
eight bytes of zero. This works around a bug in DEC's assembler in
|
||||
some versions of OSF/1 V3.x. */
|
||||
|
||||
#define EXTRA_SECTIONS readonly_data
|
||||
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
void \
|
||||
literal_section () \
|
||||
{ \
|
||||
if (in_section != readonly_data) \
|
||||
{ \
|
||||
static int firsttime = 1; \
|
||||
\
|
||||
fprintf (asm_out_file, "%s\n", READONLY_DATA_SECTION_ASM_OP); \
|
||||
if (firsttime) \
|
||||
{ \
|
||||
firsttime = 0; \
|
||||
assemble_aligned_integer (8, const0_rtx); \
|
||||
} \
|
||||
\
|
||||
in_section = readonly_data; \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define READONLY_DATA_SECTION literal_section
|
||||
|
||||
/* Define this macro if references to a symbol must be treated differently
|
||||
depending on something about the variable or function named by the symbol
|
||||
(such as what section it is in). */
|
||||
|
||||
#define ENCODE_SECTION_INFO(DECL) alpha_encode_section_info (DECL)
|
||||
|
||||
/* If a variable is weakened, made one only or moved into a different
|
||||
section, it may be necessary to redo the section info to move the
|
||||
variable out of sdata. */
|
||||
|
||||
#define REDO_SECTION_INFO_P(DECL) \
|
||||
((TREE_CODE (DECL) == VAR_DECL) \
|
||||
&& (DECL_ONE_ONLY (DECL) || DECL_WEAK (DECL) || DECL_COMMON (DECL) \
|
||||
|| DECL_SECTION_NAME (DECL) != 0))
|
||||
|
||||
#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
|
||||
do { \
|
||||
(VAR) = (SYMBOL_NAME); \
|
||||
if ((VAR)[0] == '@') \
|
||||
(VAR) += 2; \
|
||||
if ((VAR)[0] == '*') \
|
||||
(VAR)++; \
|
||||
} while (0)
|
||||
|
||||
/* How to refer to registers in assembler output.
|
||||
This sequence is indexed by compiler's hard-register-number (see above). */
|
||||
|
||||
@ -1802,7 +1742,7 @@ do { \
|
||||
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
|
||||
do { \
|
||||
const char *name_ = NAME; \
|
||||
if (*name_ == '@') \
|
||||
if (*name_ == '@' || *name_ == '%') \
|
||||
name_ += 2; \
|
||||
if (*name_ == '*') \
|
||||
name_++; \
|
||||
@ -1811,17 +1751,8 @@ do { \
|
||||
fputs (name_, STREAM); \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output the definition of a user-level label named NAME,
|
||||
such as the label on a static function or variable NAME. */
|
||||
|
||||
#define ASM_OUTPUT_LABEL(FILE,NAME) \
|
||||
do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
|
||||
|
||||
/* This is how to output a command to make the user-level label named NAME
|
||||
defined for reference from other files. */
|
||||
|
||||
#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
|
||||
do { fputs ("\t.globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
|
||||
/* Globalizing directive for a label. */
|
||||
#define GLOBAL_ASM_OP "\t.globl "
|
||||
|
||||
/* The prefix to add to user-visible assembler symbols. */
|
||||
|
||||
@ -1848,11 +1779,6 @@ do { \
|
||||
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
|
||||
sprintf ((LABEL), "*$%s%ld", (PREFIX), (long)(NUM))
|
||||
|
||||
/* Check a floating-point value for validity for a particular machine mode. */
|
||||
|
||||
#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
|
||||
((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW))
|
||||
|
||||
/* We use the default ASCII-output routine, except that we don't write more
|
||||
than 50 characters since the assembler doesn't support very long lines. */
|
||||
|
||||
@ -1985,7 +1911,7 @@ do { \
|
||||
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
|
||||
((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \
|
||||
|| (CODE) == '#' || (CODE) == '*')
|
||||
|| (CODE) == '#' || (CODE) == '*' || (CODE) == '&')
|
||||
|
||||
/* Print a memory address as an operand to reference that memory location. */
|
||||
|
||||
@ -1995,9 +1921,11 @@ do { \
|
||||
/* Define the codes that are matched by predicates in alpha.c. */
|
||||
|
||||
#define PREDICATE_CODES \
|
||||
{"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, \
|
||||
CONST_VECTOR}}, \
|
||||
{"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_const_int_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"cint8_operand", {CONST_INT}}, \
|
||||
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"add_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
@ -2008,24 +1936,29 @@ do { \
|
||||
{"mode_mask_operand", {CONST_INT}}, \
|
||||
{"mul8_operand", {CONST_INT}}, \
|
||||
{"mode_width_operand", {CONST_INT}}, \
|
||||
{"reg_or_fp0_operand", {SUBREG, REG, CONST_DOUBLE}}, \
|
||||
{"alpha_comparison_operator", {EQ, LE, LT, LEU, LTU}}, \
|
||||
{"alpha_zero_comparison_operator", {EQ, NE, LE, LT, LEU, LTU}}, \
|
||||
{"alpha_swapped_comparison_operator", {EQ, GE, GT, GEU, GTU}}, \
|
||||
{"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \
|
||||
{"alpha_fp_comparison_operator", {EQ, LE, LT, UNORDERED}}, \
|
||||
{"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \
|
||||
{"fp0_operand", {CONST_DOUBLE}}, \
|
||||
{"const0_operand", {CONST_INT, CONST_DOUBLE, CONST_VECTOR}}, \
|
||||
{"current_file_function_operand", {SYMBOL_REF}}, \
|
||||
{"direct_call_operand", {SYMBOL_REF}}, \
|
||||
{"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
|
||||
{"small_symbolic_operand", {SYMBOL_REF, CONST}}, \
|
||||
{"global_symbolic_operand", {SYMBOL_REF, CONST}}, \
|
||||
{"dtp16_symbolic_operand", {CONST}}, \
|
||||
{"dtp32_symbolic_operand", {CONST}}, \
|
||||
{"gotdtp_symbolic_operand", {CONST}}, \
|
||||
{"tp16_symbolic_operand", {CONST}}, \
|
||||
{"tp32_symbolic_operand", {CONST}}, \
|
||||
{"gottp_symbolic_operand", {CONST}}, \
|
||||
{"call_operand", {REG, SYMBOL_REF}}, \
|
||||
{"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
|
||||
SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \
|
||||
CONST_VECTOR, SYMBOL_REF, CONST, LABEL_REF, HIGH}},\
|
||||
{"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
|
||||
SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \
|
||||
CONST_VECTOR, SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \
|
||||
{"some_ni_operand", {SUBREG, REG, MEM}}, \
|
||||
{"aligned_memory_operand", {MEM}}, \
|
||||
{"unaligned_memory_operand", {MEM}}, \
|
||||
@ -2045,8 +1978,8 @@ do { \
|
||||
(VALIST) = alpha_build_va_list ()
|
||||
|
||||
/* Implement `va_start' for varargs and stdarg. */
|
||||
#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
|
||||
alpha_va_start (stdarg, valist, nextarg)
|
||||
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
|
||||
alpha_va_start (valist, nextarg)
|
||||
|
||||
/* Implement `va_arg'. */
|
||||
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
|
||||
@ -2061,9 +1994,9 @@ do { \
|
||||
|
||||
/* Definitions for debugging. */
|
||||
|
||||
#define SDB_DEBUGGING_INFO /* generate info for mips-tfile */
|
||||
#define DBX_DEBUGGING_INFO /* generate embedded stabs */
|
||||
#define MIPS_DEBUGGING_INFO /* MIPS specific debugging info */
|
||||
#define SDB_DEBUGGING_INFO 1 /* generate info for mips-tfile */
|
||||
#define DBX_DEBUGGING_INFO 1 /* generate embedded stabs */
|
||||
#define MIPS_DEBUGGING_INFO 1 /* MIPS specific debugging info */
|
||||
|
||||
#ifndef PREFERRED_DEBUGGING_TYPE /* assume SDB_DEBUGGING_INFO */
|
||||
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
|
||||
@ -2201,8 +2134,3 @@ do { \
|
||||
|
||||
/* Generate calls to memcpy, etc., not bcopy, etc. */
|
||||
#define TARGET_MEM_FUNCTIONS 1
|
||||
|
||||
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
|
||||
Used for C++ multiple inheritance. */
|
||||
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
|
||||
alpha_output_mi_thunk_osf (FILE, THUNK_FNDECL, DELTA, FUNCTION)
|
||||
|
File diff suppressed because it is too large
Load Diff
147
contrib/gcc/config/alpha/ev4.md
Normal file
147
contrib/gcc/config/alpha/ev4.md
Normal file
@ -0,0 +1,147 @@
|
||||
;; Scheduling description for Alpha EV4.
|
||||
;; Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; This file is part of GNU CC.
|
||||
;;
|
||||
;; GNU CC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 2, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; GNU CC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU CC; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
;; Boston, MA 02111-1307, USA.
|
||||
|
||||
; On EV4 there are two classes of resources to consider: resources needed
|
||||
; to issue, and resources needed to execute. IBUS[01] are in the first
|
||||
; category. ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second.
|
||||
; (There are a few other register-like resources, but ...)
|
||||
|
||||
(define_automaton "ev4_0,ev4_1,ev4_2")
|
||||
(define_cpu_unit "ev4_ib0,ev4_ib1,ev4_abox,ev4_bbox" "ev4_0")
|
||||
(define_cpu_unit "ev4_ebox,ev4_imul" "ev4_1")
|
||||
(define_cpu_unit "ev4_fbox,ev4_fdiv" "ev4_2")
|
||||
(define_reservation "ev4_ib01" "ev4_ib0|ev4_ib1")
|
||||
|
||||
; Assume type "multi" single issues.
|
||||
(define_insn_reservation "ev4_multi" 1
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "multi"))
|
||||
"ev4_ib0+ev4_ib1")
|
||||
|
||||
; Loads from L0 completes in three cycles. adjust_cost still factors
|
||||
; in user-specified memory latency, so return 1 here.
|
||||
(define_insn_reservation "ev4_ld" 1
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "ild,fld,ldsym"))
|
||||
"ev4_ib01+ev4_abox")
|
||||
|
||||
; Stores can issue before the data (but not address) is ready.
|
||||
(define_insn_reservation "ev4_ist" 1
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "ist"))
|
||||
"ev4_ib1+ev4_abox")
|
||||
|
||||
(define_insn_reservation "ev4_fst" 1
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "fst"))
|
||||
"ev4_ib0+ev4_abox")
|
||||
|
||||
; Branches have no delay cost, but do tie up the unit for two cycles.
|
||||
(define_insn_reservation "ev4_ibr" 2
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "ibr,jsr"))
|
||||
"ev4_ib1+ev4_bbox,ev4_bbox")
|
||||
|
||||
(define_insn_reservation "ev4_callpal" 2
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "callpal"))
|
||||
"ev4_ib1+ev4_bbox,ev4_bbox")
|
||||
|
||||
(define_insn_reservation "ev4_fbr" 2
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "fbr"))
|
||||
"ev4_ib0+ev4_bbox,ev4_bbox")
|
||||
|
||||
; Arithmetic insns are normally have their results available after
|
||||
; two cycles. There are a number of exceptions.
|
||||
|
||||
(define_insn_reservation "ev4_iaddlog" 2
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "iadd,ilog"))
|
||||
"ev4_ib0+ev4_ebox")
|
||||
|
||||
(define_bypass 1
|
||||
"ev4_iaddlog"
|
||||
"ev4_ibr,ev4_iaddlog,ev4_shiftcm,ev4_icmp,ev4_imulsi,ev4_imuldi")
|
||||
|
||||
(define_insn_reservation "ev4_shiftcm" 2
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "shift,icmov"))
|
||||
"ev4_ib0+ev4_ebox")
|
||||
|
||||
(define_insn_reservation "ev4_icmp" 2
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "icmp"))
|
||||
"ev4_ib0+ev4_ebox")
|
||||
|
||||
(define_bypass 1 "ev4_icmp" "ev4_ibr")
|
||||
|
||||
(define_bypass 0
|
||||
"ev4_iaddlog,ev4_shiftcm,ev4_icmp"
|
||||
"ev4_ist"
|
||||
"store_data_bypass_p")
|
||||
|
||||
; Multiplies use a non-piplined imul unit. Also, "no [ebox] insn can
|
||||
; be issued exactly three cycles before an integer multiply completes".
|
||||
|
||||
(define_insn_reservation "ev4_imulsi" 21
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(and (eq_attr "type" "imul")
|
||||
(eq_attr "opsize" "si")))
|
||||
"ev4_ib0+ev4_imul,ev4_imul*18,ev4_ebox")
|
||||
|
||||
(define_bypass 20 "ev4_imulsi" "ev4_ist" "store_data_bypass_p")
|
||||
|
||||
(define_insn_reservation "ev4_imuldi" 23
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(and (eq_attr "type" "imul")
|
||||
(eq_attr "opsize" "!si")))
|
||||
"ev4_ib0+ev4_imul,ev4_imul*20,ev4_ebox")
|
||||
|
||||
(define_bypass 22 "ev4_imuldi" "ev4_ist" "store_data_bypass_p")
|
||||
|
||||
; Most FP insns have a 6 cycle latency, but with a 4 cycle bypass back in.
|
||||
(define_insn_reservation "ev4_fpop" 6
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "fadd,fmul,fcpys,fcmov"))
|
||||
"ev4_ib1+ev4_fbox")
|
||||
|
||||
(define_bypass 4 "ev4_fpop" "ev4_fpop")
|
||||
|
||||
; The floating point divider is not pipelined. Also, "no FPOP insn can be
|
||||
; issued exactly five or exactly six cycles before an fdiv insn completes".
|
||||
|
||||
(define_insn_reservation "ev4_fdivsf" 34
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(and (eq_attr "type" "fdiv")
|
||||
(eq_attr "opsize" "si")))
|
||||
"ev4_ib1+ev4_fdiv,ev4_fdiv*28,ev4_fdiv+ev4_fbox,ev4_fbox")
|
||||
|
||||
(define_insn_reservation "ev4_fdivdf" 63
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(and (eq_attr "type" "fdiv")
|
||||
(eq_attr "opsize" "di")))
|
||||
"ev4_ib1+ev4_fdiv,ev4_fdiv*57,ev4_fdiv+ev4_fbox,ev4_fbox")
|
||||
|
||||
; Traps don't consume or produce data.
|
||||
(define_insn_reservation "ev4_misc" 1
|
||||
(and (eq_attr "cpu" "ev4")
|
||||
(eq_attr "type" "misc"))
|
||||
"ev4_ib1")
|
190
contrib/gcc/config/alpha/ev5.md
Normal file
190
contrib/gcc/config/alpha/ev5.md
Normal file
@ -0,0 +1,190 @@
|
||||
;; Scheduling description for Alpha EV5.
|
||||
;; Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; This file is part of GNU CC.
|
||||
;;
|
||||
;; GNU CC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 2, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; GNU CC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU CC; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
;; Boston, MA 02111-1307, USA.
|
||||
|
||||
;; EV5 has two asymetric integer units, E0 and E1, plus separate
|
||||
;; FP add and multiply units.
|
||||
|
||||
(define_automaton "ev5_0,ev5_1")
|
||||
(define_cpu_unit "ev5_e0,ev5_e1,ev5_fa,ev5_fm" "ev5_0")
|
||||
(define_reservation "ev5_e01" "ev5_e0|ev5_e1")
|
||||
(define_reservation "ev5_fam" "ev5_fa|ev5_fm")
|
||||
(define_cpu_unit "ev5_imul" "ev5_0")
|
||||
(define_cpu_unit "ev5_fdiv" "ev5_1")
|
||||
|
||||
; Assume type "multi" single issues.
|
||||
(define_insn_reservation "ev5_multi" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "multi"))
|
||||
"ev5_e0+ev5_e1+ev5_fa+ev5_fm")
|
||||
|
||||
; Stores can only issue to E0, and may not issue with loads.
|
||||
; Model this with some fake units.
|
||||
|
||||
(define_cpu_unit "ev5_l0,ev5_l1,ev5_st" "ev5_0")
|
||||
(define_reservation "ev5_ld" "ev5_l0|ev5_l1")
|
||||
(exclusion_set "ev5_l0,ev5_l1" "ev5_st")
|
||||
|
||||
(define_insn_reservation "ev5_st" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "ist,fst"))
|
||||
"ev5_e0+ev5_st")
|
||||
|
||||
; Loads from L0 complete in two cycles. adjust_cost still factors
|
||||
; in user-specified memory latency, so return 1 here.
|
||||
(define_insn_reservation "ev5_ld" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "ild,fld,ldsym"))
|
||||
"ev5_e01+ev5_ld")
|
||||
|
||||
; Integer branches slot only to E1.
|
||||
(define_insn_reservation "ev5_ibr" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "ibr"))
|
||||
"ev5_e1")
|
||||
|
||||
(define_insn_reservation "ev5_callpal" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "callpal"))
|
||||
"ev5_e1")
|
||||
|
||||
(define_insn_reservation "ev5_jsr" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "jsr"))
|
||||
"ev5_e1")
|
||||
|
||||
(define_insn_reservation "ev5_shift" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "shift"))
|
||||
"ev5_e0")
|
||||
|
||||
(define_insn_reservation "ev5_mvi" 2
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "mvi"))
|
||||
"ev5_e0")
|
||||
|
||||
(define_insn_reservation "ev5_cmov" 2
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "icmov"))
|
||||
"ev5_e01")
|
||||
|
||||
(define_insn_reservation "ev5_iadd" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "iadd"))
|
||||
"ev5_e01")
|
||||
|
||||
(define_insn_reservation "ev5_ilogcmp" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "ilog,icmp"))
|
||||
"ev5_e01")
|
||||
|
||||
; Conditional move and branch can issue the same cycle as the test.
|
||||
(define_bypass 0 "ev5_ilogcmp" "ev5_ibr,ev5_cmov" "if_test_bypass_p")
|
||||
|
||||
; Multiplies use a non-piplined imul unit. Also, "no insn can be issued
|
||||
; to E0 exactly two cycles before an integer multiply completes".
|
||||
|
||||
(define_insn_reservation "ev5_imull" 8
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(and (eq_attr "type" "imul")
|
||||
(eq_attr "opsize" "si")))
|
||||
"ev5_e0+ev5_imul,ev5_imul*3,nothing,ev5_e0")
|
||||
|
||||
(define_insn_reservation "ev5_imulq" 12
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(and (eq_attr "type" "imul")
|
||||
(eq_attr "opsize" "di")))
|
||||
"ev5_e0+ev5_imul,ev5_imul*7,nothing,ev5_e0")
|
||||
|
||||
(define_insn_reservation "ev5_imulh" 14
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(and (eq_attr "type" "imul")
|
||||
(eq_attr "opsize" "udi")))
|
||||
"ev5_e0+ev5_imul,ev5_imul*7,nothing*3,ev5_e0")
|
||||
|
||||
; The multiplier is unable to receive data from Ebox bypass paths. The
|
||||
; instruction issues at the expected time, but its latency is increased
|
||||
; by the time it takes for the input data to become available to the
|
||||
; multiplier. For example, an IMULL instruction issued one cycle later
|
||||
; than an ADDL instruction, which produced one of its operands, has a
|
||||
; latency of 10 (8 + 2). If the IMULL instruction is issued two cycles
|
||||
; later than the ADDL instruction, the latency is 9 (8 + 1).
|
||||
;
|
||||
; Model this instead with increased latency on the input instruction.
|
||||
|
||||
(define_bypass 3
|
||||
"ev5_ld,ev5_shift,ev5_mvi,ev5_cmov,ev5_iadd,ev5_ilogcmp"
|
||||
"ev5_imull,ev5_imulq,ev5_imulh")
|
||||
|
||||
(define_bypass 9 "ev5_imull" "ev5_imull,ev5_imulq,ev5_imulh")
|
||||
(define_bypass 13 "ev5_imulq" "ev5_imull,ev5_imulq,ev5_imulh")
|
||||
(define_bypass 15 "ev5_imulh" "ev5_imull,ev5_imulq,ev5_imulh")
|
||||
|
||||
; Similarly for the FPU we have two asymetric units.
|
||||
|
||||
(define_insn_reservation "ev5_fadd" 4
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "fadd,fcmov"))
|
||||
"ev5_fa")
|
||||
|
||||
(define_insn_reservation "ev5_fbr" 1
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "fbr"))
|
||||
"ev5_fa")
|
||||
|
||||
(define_insn_reservation "ev5_fcpys" 4
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "fcpys"))
|
||||
"ev5_fam")
|
||||
|
||||
(define_insn_reservation "ev5_fmul" 4
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "fmul"))
|
||||
"ev5_fm")
|
||||
|
||||
; The floating point divider is not pipelined. Also, "no insn can be issued
|
||||
; to FA exactly five before an fdiv insn completes".
|
||||
;
|
||||
; ??? Do not model this late reservation due to the enormously increased
|
||||
; size of the resulting DFA.
|
||||
;
|
||||
; ??? Putting ev5_fa and ev5_fdiv alone into the same automata produces
|
||||
; a DFA of acceptable size, but putting ev5_fm and ev5_fa into separate
|
||||
; automata produces incorrect results for insns that can choose one or
|
||||
; the other, i.e. ev5_fcpys.
|
||||
|
||||
(define_insn_reservation "ev5_fdivsf" 15
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(and (eq_attr "type" "fdiv")
|
||||
(eq_attr "opsize" "si")))
|
||||
; "ev5_fa+ev5_fdiv,ev5_fdiv*9,ev5_fa+ev5_fdiv,ev5_fdiv*4"
|
||||
"ev5_fa+ev5_fdiv,ev5_fdiv*14")
|
||||
|
||||
(define_insn_reservation "ev5_fdivdf" 22
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(and (eq_attr "type" "fdiv")
|
||||
(eq_attr "opsize" "di")))
|
||||
; "ev5_fa+ev5_fdiv,ev5_fdiv*17,ev5_fa+ev5_fdiv,ev5_fdiv*4"
|
||||
"ev5_fa+ev5_fdiv,ev5_fdiv*21")
|
||||
|
||||
; Traps don't consume or produce data; rpcc is latency 2 if we ever add it.
|
||||
(define_insn_reservation "ev5_misc" 2
|
||||
(and (eq_attr "cpu" "ev5")
|
||||
(eq_attr "type" "misc"))
|
||||
"ev5_e0")
|
173
contrib/gcc/config/alpha/ev6.md
Normal file
173
contrib/gcc/config/alpha/ev6.md
Normal file
@ -0,0 +1,173 @@
|
||||
;; Scheduling description for Alpha EV6.
|
||||
;; Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; This file is part of GNU CC.
|
||||
;;
|
||||
;; GNU CC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 2, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; GNU CC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU CC; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
;; Boston, MA 02111-1307, USA.
|
||||
|
||||
; EV6 can issue 4 insns per clock. It's out-of-order, so this isn't
|
||||
; expected to help over-much, but a precise description can be important
|
||||
; for software pipelining.
|
||||
;
|
||||
; EV6 has two symmetric pairs ("clusters") of two asymetric integer
|
||||
; units ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
|
||||
;
|
||||
; ??? The clusters have independent register files that are re-synced
|
||||
; every cycle. Thus there is one additional cycle of latency between
|
||||
; insns issued on different clusters. Possibly model that by duplicating
|
||||
; all EBOX insn_reservations that can issue to either cluster, increasing
|
||||
; all latencies by one, and adding bypasses within the cluster.
|
||||
;
|
||||
; ??? In addition, instruction order affects cluster issue.
|
||||
|
||||
(define_automaton "ev6_0,ev6_1")
|
||||
(define_cpu_unit "ev6_u0,ev6_u1,ev6_l0,ev6_l1" "ev6_0")
|
||||
(define_reservation "ev6_u" "ev6_u0|ev6_u1")
|
||||
(define_reservation "ev6_l" "ev6_l0|ev6_l1")
|
||||
(define_reservation "ev6_ebox" "ev6_u|ev6_l")
|
||||
|
||||
(define_cpu_unit "ev6_fa" "ev6_1")
|
||||
(define_cpu_unit "ev6_fm,ev6_fst0,ev6_fst1" "ev6_0")
|
||||
(define_reservation "ev6_fst" "ev6_fst0|ev6_fst1")
|
||||
|
||||
; Assume type "multi" single issues.
|
||||
(define_insn_reservation "ev6_multi" 1
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "multi"))
|
||||
"ev6_u0+ev6_u1+ev6_l0+ev6_l1+ev6_fa+ev6_fm+ev6_fst0+ev6_fst1")
|
||||
|
||||
; Integer loads take at least 3 clocks, and only issue to lower units.
|
||||
; adjust_cost still factors in user-specified memory latency, so return 1 here.
|
||||
(define_insn_reservation "ev6_ild" 1
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "ild,ldsym"))
|
||||
"ev6_l")
|
||||
|
||||
(define_insn_reservation "ev6_ist" 1
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "ist"))
|
||||
"ev6_l")
|
||||
|
||||
; FP loads take at least 4 clocks. adjust_cost still factors
|
||||
; in user-specified memory latency, so return 2 here.
|
||||
(define_insn_reservation "ev6_fld" 2
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "fld"))
|
||||
"ev6_l")
|
||||
|
||||
; The FPU communicates with memory and the integer register file
|
||||
; via two fp store units. We need a slot in the fst immediately, and
|
||||
; a slot in LOW after the operand data is ready. At which point the
|
||||
; data may be moved either to the store queue or the integer register
|
||||
; file and the insn retired.
|
||||
|
||||
(define_insn_reservation "ev6_fst" 3
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "fst"))
|
||||
"ev6_fst,nothing,ev6_l")
|
||||
|
||||
; Arithmetic goes anywhere.
|
||||
(define_insn_reservation "ev6_arith" 1
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "iadd,ilog,icmp"))
|
||||
"ev6_ebox")
|
||||
|
||||
; Motion video insns also issue only to U0, and take three ticks.
|
||||
(define_insn_reservation "ev6_mvi" 3
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "mvi"))
|
||||
"ev6_u0")
|
||||
|
||||
; Shifts issue to upper units.
|
||||
(define_insn_reservation "ev6_shift" 1
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "shift"))
|
||||
"ev6_u")
|
||||
|
||||
; Multiplies issue only to U1, and all take 7 ticks.
|
||||
(define_insn_reservation "ev6_imul" 7
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "imul"))
|
||||
"ev6_u1")
|
||||
|
||||
; Conditional moves decompose into two independent primitives, each taking
|
||||
; one cycle. Since ev6 is out-of-order, we can't see anything but two cycles.
|
||||
(define_insn_reservation "ev6_icmov" 2
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "icmov"))
|
||||
"ev6_ebox,ev6_ebox")
|
||||
|
||||
; Integer branches issue to upper units
|
||||
(define_insn_reservation "ev6_ibr" 1
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "ibr,callpal"))
|
||||
"ev6_u")
|
||||
|
||||
; Calls only issue to L0.
|
||||
(define_insn_reservation "ev6_jsr" 1
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "jsr"))
|
||||
"ev6_l0")
|
||||
|
||||
; Ftoi/itof only issue to lower pipes.
|
||||
(define_insn_reservation "ev6_itof" 3
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "itof"))
|
||||
"ev6_l")
|
||||
|
||||
(define_insn_reservation "ev6_ftoi" 3
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "ftoi"))
|
||||
"ev6_fst,nothing,ev6_l")
|
||||
|
||||
(define_insn_reservation "ev6_fmul" 4
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "fmul"))
|
||||
"ev6_fm")
|
||||
|
||||
(define_insn_reservation "ev6_fadd" 4
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "fadd,fcpys,fbr"))
|
||||
"ev6_fa")
|
||||
|
||||
(define_insn_reservation "ev6_fcmov" 8
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(eq_attr "type" "fcmov"))
|
||||
"ev6_fa,nothing*3,ev6_fa")
|
||||
|
||||
(define_insn_reservation "ev6_fdivsf" 12
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(and (eq_attr "type" "fdiv")
|
||||
(eq_attr "opsize" "si")))
|
||||
"ev6_fa*9")
|
||||
|
||||
(define_insn_reservation "ev6_fdivdf" 15
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(and (eq_attr "type" "fdiv")
|
||||
(eq_attr "opsize" "di")))
|
||||
"ev6_fa*12")
|
||||
|
||||
(define_insn_reservation "ev6_sqrtsf" 18
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(and (eq_attr "type" "fsqrt")
|
||||
(eq_attr "opsize" "si")))
|
||||
"ev6_fa*15")
|
||||
|
||||
(define_insn_reservation "ev6_sqrtdf" 33
|
||||
(and (eq_attr "cpu" "ev6")
|
||||
(and (eq_attr "type" "fsqrt")
|
||||
(eq_attr "opsize" "di")))
|
||||
"ev6_fa*30")
|
30
contrib/gcc/config/alpha/gnu.h
Normal file
30
contrib/gcc/config/alpha/gnu.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* Configuration for an Alpha running GNU with ELF as the target machine. */
|
||||
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (Alpha GNU)");
|
||||
|
||||
#undef TARGET_OS_CPP_BUILTINS /* config.gcc includes alpha/linux.h. */
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define ("__GNU__"); \
|
||||
builtin_define ("__ELF__"); \
|
||||
builtin_define ("__gnu_hurd__"); \
|
||||
builtin_define ("_LONGLONG"); \
|
||||
builtin_define_std ("unix"); \
|
||||
builtin_assert ("system=gnu"); \
|
||||
} while (0)
|
||||
|
||||
#undef ELF_DYNAMIC_LINKER
|
||||
#define ELF_DYNAMIC_LINKER "/lib/ld.so"
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!shared: \
|
||||
%{!static: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
|
||||
%{static:crt0.o%s}} \
|
||||
crti.o%s \
|
||||
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
|
||||
|
||||
/* FIXME: Is a Hurd-specific fallback mechanism necessary? */
|
||||
#undef MD_FALLBACK_FRAME_STATE_FOR
|
@ -27,17 +27,23 @@ Boston, MA 02111-1307, USA. */
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "elf_dynamic_linker", ELF_DYNAMIC_LINKER },
|
||||
|
||||
#undef SUB_CPP_PREDEFINES
|
||||
#define SUB_CPP_PREDEFINES "-D__ELF__"
|
||||
|
||||
#ifdef USE_GNULIBC_1
|
||||
#define ELF_DYNAMIC_LINKER "/lib/ld.so.1"
|
||||
#else
|
||||
#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2"
|
||||
#endif
|
||||
|
||||
#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \
|
||||
%{O*:-O3} %{!O*:-O1} \
|
||||
%{shared:-shared} \
|
||||
%{!shared: \
|
||||
%{!static: \
|
||||
%{rdynamic:-export-dynamic} \
|
||||
%{!dynamic-linker:-dynamic-linker %(elf_dynamic_linker)}} \
|
||||
%{static:-static}}"
|
||||
|
||||
#ifndef USE_GNULIBC_1
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC \
|
||||
"%{shared:-lc}%{!shared:%{pthread:-lpthread }%{profile:-lc_p}%{!profile:-lc}} "
|
||||
"%{pthread:-lpthread }%{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} "
|
||||
#endif
|
||||
|
@ -23,20 +23,23 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-D__gnu_linux__ -Dlinux -Dunix -Asystem=linux -D_LONGLONG -D__alpha__ " \
|
||||
SUB_CPP_PREDEFINES
|
||||
|
||||
/* The GNU C++ standard library requires that these macros be defined. */
|
||||
#undef CPLUSPLUS_CPP_SPEC
|
||||
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define ("__gnu_linux__"); \
|
||||
builtin_define ("_LONGLONG"); \
|
||||
builtin_define_std ("linux"); \
|
||||
builtin_define_std ("unix"); \
|
||||
builtin_assert ("system=linux"); \
|
||||
/* The GNU C++ standard library requires this. */ \
|
||||
if (c_language == clk_cplusplus) \
|
||||
builtin_define ("_GNU_SOURCE"); \
|
||||
} while (0)
|
||||
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC \
|
||||
"%{shared: -lc} \
|
||||
%{!shared: %{pthread:-lpthread} \
|
||||
%{profile:-lc_p} %{!profile: -lc}}"
|
||||
"%{pthread:-lpthread} \
|
||||
%{shared:-lc} \
|
||||
%{!shared: %{profile:-lc_p}%{!profile:-lc}}"
|
||||
|
||||
/* Show that we need a GP when profiling. */
|
||||
#undef TARGET_PROFILING_NEEDS_GP
|
||||
@ -56,6 +59,8 @@ SUB_CPP_PREDEFINES
|
||||
/* Define this so that all GNU/Linux targets handle the same pragmas. */
|
||||
#define HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
|
||||
#define TARGET_HAS_F_SETLKW
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
|
||||
|
@ -22,9 +22,16 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-D__NetBSD__ -D__ELF__ -D_LP64 -Asystem=unix -Asystem=NetBSD"
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
NETBSD_OS_CPP_BUILTINS_ELF(); \
|
||||
NETBSD_OS_CPP_BUILTINS_LP64(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* NetBSD doesn't use the LANGUAGE* built-ins. */
|
||||
#undef SUBTARGET_LANGUAGE_CPP_BUILTINS
|
||||
#define SUBTARGET_LANGUAGE_CPP_BUILTINS() /* nothing */
|
||||
|
||||
|
||||
/* Show that we need a GP when profiling. */
|
||||
@ -32,39 +39,28 @@ Boston, MA 02111-1307, USA. */
|
||||
#define TARGET_PROFILING_NEEDS_GP 1
|
||||
|
||||
|
||||
/* Provide a CPP_SPEC appropriate for NetBSD/alpha. In addition to
|
||||
the standard NetBSD specs, we also handle Alpha FP mode indications. */
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC \
|
||||
"%{mieee:-D_IEEE_FP} \
|
||||
%{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT} \
|
||||
%(cpp_cpu) %(cpp_subtarget)"
|
||||
/* Provide a CPP_SUBTARGET_SPEC appropriate for NetBSD/alpha. We use
|
||||
this to pull in CPP specs that all NetBSD configurations need. */
|
||||
|
||||
#undef CPP_SUBTARGET_SPEC
|
||||
#define CPP_SUBTARGET_SPEC \
|
||||
"%{posix:-D_POSIX_SOURCE}"
|
||||
#define CPP_SUBTARGET_SPEC NETBSD_CPP_SPEC
|
||||
|
||||
#undef SUBTARGET_EXTRA_SPECS
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
|
||||
{ "netbsd_entry_point", NETBSD_ENTRY_POINT }, \
|
||||
{ "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC },
|
||||
|
||||
|
||||
/* Provide a LINK_SPEC appropriate for a NetBSD/alpha ELF target.
|
||||
This is a copy of LINK_SPEC from <netbsd-elf.h> tweaked for
|
||||
the alpha target. */
|
||||
/* Provide a LINK_SPEC appropriate for a NetBSD/alpha ELF target. */
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC \
|
||||
"%{G*} %{relax:-relax} \
|
||||
%{O*:-O3} %{!O*:-O1} \
|
||||
%{assert*} %{R*} \
|
||||
%{shared:-shared} \
|
||||
%{!shared: \
|
||||
-dc -dp \
|
||||
%{!nostdlib: \
|
||||
%{!r*: \
|
||||
%{!e*:-e __start}}} \
|
||||
%{!static: \
|
||||
%{rdynamic:-export-dynamic} \
|
||||
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld.elf_so}} \
|
||||
%{static:-static}}"
|
||||
#define LINK_SPEC \
|
||||
"%{G*} %{relax:-relax} \
|
||||
%{O*:-O3} %{!O*:-O1} \
|
||||
%(netbsd_link_spec)"
|
||||
|
||||
#define NETBSD_ENTRY_POINT "__start"
|
||||
|
||||
|
||||
/* Provide an ENDFILE_SPEC appropriate for NetBSD/alpha ELF. Here we
|
||||
@ -76,7 +72,12 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC \
|
||||
"%{ffast-math|funsafe-math-optimizations:crtfm%O%s} \
|
||||
%{!shared:crtend%O%s} %{shared:crtendS%O%s}"
|
||||
%(netbsd_endfile_spec)"
|
||||
|
||||
|
||||
/* Attempt to enable execute permissions on the stack. */
|
||||
|
||||
#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
|
||||
|
||||
|
||||
#undef TARGET_VERSION
|
||||
|
@ -21,8 +21,6 @@ Boston, MA 02111-1307, USA. */
|
||||
/* We settle for little endian for now. */
|
||||
#define TARGET_ENDIAN_DEFAULT 0
|
||||
|
||||
#include <alpha/alpha.h>
|
||||
|
||||
#define OBSD_NO_DYNAMIC_LIBRARIES
|
||||
#define OBSD_HAS_DECLARE_FUNCTION_NAME
|
||||
#define OBSD_HAS_DECLARE_FUNCTION_SIZE
|
||||
@ -41,8 +39,13 @@ Boston, MA 02111-1307, USA. */
|
||||
"%{!nostdlib:%{!r*:%{!e*:-e __start}}} -dc -dp %{assert*}"
|
||||
|
||||
/* run-time target specifications */
|
||||
#define CPP_PREDEFINES "-D__unix__ -D__ANSI_COMPAT -Asystem=unix \
|
||||
-D__OpenBSD__ -D__alpha__ -D__alpha"
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define ("__OpenBSD__"); \
|
||||
builtin_define ("__ANSI_COMPAT"); \
|
||||
builtin_define ("__unix__"); \
|
||||
builtin_assert ("system=unix"); \
|
||||
} while (0)
|
||||
|
||||
/* Layout of source language data types. */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Definitions of target machine for GNU compiler, for DEC Alpha on OSF/1.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
||||
|
||||
@ -32,14 +32,24 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Names to predefine in the preprocessor for this target machine. */
|
||||
|
||||
#define CPP_PREDEFINES "\
|
||||
-Dunix -D__osf__ -D_LONGLONG -DSYSTYPE_BSD \
|
||||
-D_SYSTYPE_BSD -Asystem=unix -Asystem=xpg4"
|
||||
|
||||
/* Tru64 UNIX V5 requires additional definitions for 16 byte long double
|
||||
support. Empty by default. */
|
||||
|
||||
#define CPP_XFLOAT_SPEC ""
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define_std ("unix"); \
|
||||
builtin_define_std ("SYSTYPE_BSD"); \
|
||||
builtin_define ("_SYSTYPE_BSD"); \
|
||||
builtin_define ("__osf__"); \
|
||||
builtin_define ("__digital__"); \
|
||||
builtin_define ("__arch64__"); \
|
||||
builtin_define ("_LONGLONG"); \
|
||||
builtin_define ("__PRAGMA_EXTERN_PREFIX"); \
|
||||
builtin_assert ("system=unix"); \
|
||||
builtin_assert ("system=xpg4"); \
|
||||
/* Tru64 UNIX V5 has a 16 byte long \
|
||||
double type and requires __X_FLOAT \
|
||||
to be defined for <math.h>. */ \
|
||||
if (LONG_DOUBLE_TYPE_SIZE == 128) \
|
||||
builtin_define ("__X_FLOAT"); \
|
||||
} while (0)
|
||||
|
||||
/* Accept DEC C flags for multithreaded programs. We use _PTHREAD_USE_D4
|
||||
instead of PTHREAD_USE_D4 since both have the same effect and the former
|
||||
@ -47,8 +57,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef CPP_SUBTARGET_SPEC
|
||||
#define CPP_SUBTARGET_SPEC \
|
||||
"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat) \
|
||||
-D__EXTERN_PREFIX"
|
||||
"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4}"
|
||||
|
||||
/* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */
|
||||
|
||||
@ -136,9 +145,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#endif
|
||||
|
||||
#undef SUBTARGET_EXTRA_SPECS
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "cpp_xfloat", CPP_XFLOAT_SPEC }, \
|
||||
{ "asm_oldas", ASM_OLDAS_SPEC }
|
||||
#define SUBTARGET_EXTRA_SPECS { "asm_oldas", ASM_OLDAS_SPEC }
|
||||
|
||||
/* Indicate that we have a stamp.h to use. */
|
||||
#ifndef CROSS_COMPILE
|
||||
@ -193,7 +200,7 @@ __enable_execute_stack (addr) \
|
||||
#define ASM_OUTPUT_WEAK_ALIAS(FILE, NAME, VALUE) \
|
||||
do \
|
||||
{ \
|
||||
ASM_GLOBALIZE_LABEL (FILE, NAME); \
|
||||
(*targetm.asm_out.globalize_label) (FILE, NAME); \
|
||||
fputs ("\t.weakext\t", FILE); \
|
||||
assemble_name (FILE, NAME); \
|
||||
if (VALUE) \
|
||||
@ -208,7 +215,6 @@ __enable_execute_stack (addr) \
|
||||
#define ASM_WEAKEN_LABEL(FILE, NAME) ASM_OUTPUT_WEAK_ALIAS(FILE, NAME, 0)
|
||||
|
||||
/* Handle #pragma weak and #pragma pack. */
|
||||
#undef HANDLE_SYSV_PRAGMA
|
||||
#define HANDLE_SYSV_PRAGMA 1
|
||||
|
||||
/* Handle #pragma extern_prefix. Technically only needed for Tru64 5.x,
|
||||
|
@ -18,15 +18,12 @@
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Tru64 5.1 uses IEEE QUAD format. */
|
||||
/* ??? However, since there is no support for VAX H_floating, we must
|
||||
drop back to a 64-bit long double to avoid a crash looking for the
|
||||
format associated with TFmode. */
|
||||
#undef LONG_DOUBLE_TYPE_SIZE
|
||||
#define LONG_DOUBLE_TYPE_SIZE 128
|
||||
|
||||
/* Tru64 UNIX V5 has a 16 byte long double type and requires __X_FLOAT to be
|
||||
defined to get the appropriate prototypes for the long double functions
|
||||
in <math.h>. */
|
||||
|
||||
#undef CPP_XFLOAT_SPEC
|
||||
#define CPP_XFLOAT_SPEC "-D__X_FLOAT"
|
||||
#define LONG_DOUBLE_TYPE_SIZE (TARGET_FLOAT_VAX ? 64 : 128)
|
||||
|
||||
/* In Tru64 UNIX V5.1, Compaq introduced a new assembler
|
||||
(/usr/lib/cmplrs/cc/adu) which currently (versions between 3.04.29 and
|
||||
|
@ -1,4 +1,5 @@
|
||||
EXTRA_PARTS += crtfastmath.o
|
||||
|
||||
crtfastmath.o: $(srcdir)/config/alpha/crtfastmath.c $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtfastmath.o $(srcdir)/config/alpha/crtfastmath.c
|
||||
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -frandom-seed=gcc-crtfastmath -c \
|
||||
-o crtfastmath.o $(srcdir)/config/alpha/crtfastmath.c
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler, for DEC Alpha on Cray
|
||||
T3E running Unicos/Mk.
|
||||
Copyright (C) 2001
|
||||
Copyright (C) 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
|
||||
|
||||
@ -32,15 +32,18 @@ Boston, MA 02111-1307, USA. */
|
||||
/* The following defines are necessary for the standard headers to work
|
||||
correctly. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-D__unix=1 -D_UNICOS=205 -D_CRAY=1 -D_CRAYT3E=1 -D_CRAYMPP=1 -D_CRAYIEEE=1 -D_ADDR64=1 -D_LD64=1 -D__UNICOSMK__ -D__INT_MAX__=9223372036854775807 -D__SHRT_MAX__=2147483647"
|
||||
|
||||
/* Disable software floating point emulation because it requires a 16-bit
|
||||
type which we do not have. */
|
||||
|
||||
#ifndef __GNUC__
|
||||
#undef REAL_ARITHMETIC
|
||||
#endif
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define ("__unix"); \
|
||||
builtin_define ("_UNICOS=205"); \
|
||||
builtin_define ("_CRAY"); \
|
||||
builtin_define ("_CRAYT3E"); \
|
||||
builtin_define ("_CRAYMPP"); \
|
||||
builtin_define ("_CRAYIEEE"); \
|
||||
builtin_define ("_ADDR64"); \
|
||||
builtin_define ("_LD64"); \
|
||||
builtin_define ("__UNICOSMK__"); \
|
||||
} while (0)
|
||||
|
||||
#define SHORT_TYPE_SIZE 32
|
||||
|
||||
@ -234,10 +237,7 @@ do { \
|
||||
On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
|
||||
arguments on the stack. Unfortunately, it doesn't always store the first
|
||||
one (i.e. the one that arrives in $16 or $f16). This is not a problem
|
||||
with stdargs as we always have at least one named argument there. This is
|
||||
not always the case when varargs.h is used, however. In such cases, we
|
||||
have to store the first argument ourselves. We use the information from
|
||||
the CIW to determine whether the first argument arrives in $16 or $f16. */
|
||||
with stdargs as we always have at least one named argument there. */
|
||||
|
||||
#undef SETUP_INCOMING_VARARGS
|
||||
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
|
||||
@ -245,36 +245,9 @@ do { \
|
||||
{ \
|
||||
if (! (NO_RTL)) \
|
||||
{ \
|
||||
int start; \
|
||||
\
|
||||
start = (CUM).num_reg_words; \
|
||||
if (!current_function_varargs || start == 0) \
|
||||
++start; \
|
||||
int start = (CUM).num_reg_words + 1; \
|
||||
\
|
||||
emit_insn (gen_umk_mismatch_args (GEN_INT (start))); \
|
||||
if (current_function_varargs && (CUM).num_reg_words == 0) \
|
||||
{ \
|
||||
rtx tmp; \
|
||||
rtx int_label, end_label; \
|
||||
\
|
||||
tmp = gen_reg_rtx (DImode); \
|
||||
emit_move_insn (tmp, \
|
||||
gen_rtx_ZERO_EXTRACT (DImode, \
|
||||
gen_rtx_REG (DImode, 2),\
|
||||
(GEN_INT (1)), \
|
||||
(GEN_INT (7)))); \
|
||||
int_label = gen_label_rtx (); \
|
||||
end_label = gen_label_rtx (); \
|
||||
emit_insn (gen_cmpdi (tmp, GEN_INT (0))); \
|
||||
emit_jump_insn (gen_beq (int_label)); \
|
||||
emit_move_insn (gen_rtx_MEM (DFmode, virtual_incoming_args_rtx),\
|
||||
gen_rtx_REG (DFmode, 48)); \
|
||||
emit_jump (end_label); \
|
||||
emit_label (int_label); \
|
||||
emit_move_insn (gen_rtx_MEM (DImode, virtual_incoming_args_rtx),\
|
||||
gen_rtx_REG (DImode, 16)); \
|
||||
emit_label (end_label); \
|
||||
} \
|
||||
emit_insn (gen_arg_home_umk ()); \
|
||||
} \
|
||||
\
|
||||
@ -288,19 +261,6 @@ do { \
|
||||
#undef EPILOGUE_USES
|
||||
#define EPILOGUE_USES(REGNO) ((REGNO) == 26 || (REGNO) == 15)
|
||||
|
||||
/* Machine-specific function data. */
|
||||
|
||||
struct machine_function
|
||||
{
|
||||
/* List of call information words for calls from this function. */
|
||||
struct rtx_def *first_ciw;
|
||||
struct rtx_def *last_ciw;
|
||||
int ciw_count;
|
||||
|
||||
/* List of deferred case vectors. */
|
||||
struct rtx_def *addr_list;
|
||||
};
|
||||
|
||||
/* Would have worked, only the stack doesn't seem to be executable
|
||||
#undef TRAMPOLINE_TEMPLATE
|
||||
#define TRAMPOLINE_TEMPLATE(FILE) \
|
||||
@ -342,9 +302,9 @@ do { fprintf (FILE, "\tbr $1,0\n"); \
|
||||
#undef DATA_SECTION_ASM_OP
|
||||
#define DATA_SECTION_ASM_OP unicosmk_data_section ()
|
||||
|
||||
/* There are ni read-only sections on Unicos/Mk. */
|
||||
/* There are no read-only sections on Unicos/Mk. */
|
||||
|
||||
#undef READONLY_DATA_SECTION
|
||||
#undef READONLY_DATA_SECTION_ASM_OP
|
||||
#define READONLY_DATA_SECTION data_section
|
||||
|
||||
/* Define extra sections for common data and SSIBs (static subroutine
|
||||
@ -375,16 +335,6 @@ ssib_section () \
|
||||
in_section = in_ssib; \
|
||||
}
|
||||
|
||||
/* A C expression which evaluates to true if declshould be placed into a
|
||||
unique section for some target-specific reason. On Unicos/Mk, functions
|
||||
and public variables are always placed in unique sections. */
|
||||
|
||||
/*
|
||||
#define UNIQUE_SECTION_P(DECL) (TREE_PUBLIC (DECL) \
|
||||
|| TREE_CODE (DECL) == FUNCTION_DECL)
|
||||
*/
|
||||
#define UNIQUE_SECTION(DECL, RELOC) unicosmk_unique_section (DECL, RELOC)
|
||||
|
||||
/* This outputs text to go at the start of an assembler file. */
|
||||
|
||||
#undef ASM_FILE_START
|
||||
@ -399,12 +349,6 @@ ssib_section () \
|
||||
|
||||
#undef ASM_OUTPUT_SOURCE_FILENAME
|
||||
|
||||
/* There is no directive for declaring a label as global. Instead, an
|
||||
additional colon must be appended when the label is defined. */
|
||||
|
||||
#undef ASM_GLOBALIZE_LABEL
|
||||
#define ASM_GLOBALIZE_LABEL(FILE,NAME)
|
||||
|
||||
/* This is how to output a label for a jump table. Arguments are the same as
|
||||
for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
|
||||
passed. */
|
||||
@ -568,38 +512,6 @@ ssib_section () \
|
||||
#undef ASM_OUTPUT_MAX_SKIP_ALIGN
|
||||
#define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM,POWER,MAXSKIP)
|
||||
|
||||
/* We have to define these because we do not use the floating-point
|
||||
emulation. Unfortunately, atof does not accept hex literals. */
|
||||
|
||||
#ifndef REAL_ARITHMETIC
|
||||
#define REAL_VALUE_ATOF(x,s) atof(x)
|
||||
#define REAL_VALUE_HTOF(x,s) atof(x)
|
||||
|
||||
#define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) \
|
||||
do { \
|
||||
union { \
|
||||
float f; \
|
||||
HOST_WIDE_INT l; \
|
||||
} u; \
|
||||
\
|
||||
u.f = (IN); \
|
||||
(OUT) = (u.l >> 32) & 0xFFFFFFFF; \
|
||||
} while (0)
|
||||
|
||||
#define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \
|
||||
do { \
|
||||
union { \
|
||||
REAL_VALUE_TYPE f; \
|
||||
HOST_WIDE_INT l; \
|
||||
} u; \
|
||||
\
|
||||
u.f = (IN); \
|
||||
(OUT)[0] = (u.l >> 32) & 0xFFFFFFFF; \
|
||||
(OUT)[1] = (u.l & 0xFFFFFFFF); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#undef NM_FLAGS
|
||||
|
||||
#undef OBJECT_FORMAT_COFF
|
||||
|
@ -109,16 +109,11 @@ preprocess_args (p_argc, argv)
|
||||
if (strcmp (argv[i], "-o") == 0)
|
||||
{
|
||||
char *buff, *ptr;
|
||||
int out_len;
|
||||
|
||||
i++;
|
||||
ptr = to_host_file_spec (argv[i]);
|
||||
objfilename = xstrdup (ptr);
|
||||
out_len = strlen (ptr);
|
||||
buff = xmalloc (out_len + 6);
|
||||
|
||||
strcpy (buff, "/obj=");
|
||||
strcat (buff, ptr);
|
||||
buff = concat ("/obj=", ptr, NULL);
|
||||
addarg (buff);
|
||||
}
|
||||
}
|
||||
@ -202,11 +197,8 @@ main (argc, argv)
|
||||
strncpy (cwdev, cwd, devlen);
|
||||
cwdev [devlen] = '\0';
|
||||
|
||||
search_dirs = xmalloc (strlen (system_search_dirs) + 1);
|
||||
strcpy (search_dirs, system_search_dirs);
|
||||
|
||||
defines = xmalloc (strlen (default_defines) + 1);
|
||||
strcpy (defines, default_defines);
|
||||
search_dirs = xstrdup (system_search_dirs);
|
||||
defines = xstrdup (default_defines);
|
||||
|
||||
addarg ("cc");
|
||||
preprocess_args (&argc , argv);
|
||||
@ -251,7 +243,6 @@ main (argc, argv)
|
||||
{
|
||||
/* Assume filename arg */
|
||||
char buff [256], *ptr;
|
||||
int buff_len;
|
||||
|
||||
ptr = to_host_file_spec (argv[i]);
|
||||
arg_len = strlen (ptr);
|
||||
@ -263,10 +254,7 @@ main (argc, argv)
|
||||
else
|
||||
sprintf (buff, "%s%s", cwd, ptr);
|
||||
|
||||
buff_len = strlen (buff);
|
||||
ptr = xmalloc (buff_len + 1);
|
||||
|
||||
strcpy (ptr, buff);
|
||||
ptr = xstrdup (buff);
|
||||
addarg (ptr);
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
You Lose! This file can only be compiled with DEC C.
|
||||
#else
|
||||
|
||||
/* This file can only be compiled with DEC C, due the the call to
|
||||
/* This file can only be compiled with DEC C, due to the call to
|
||||
lib$establish and the pragmas pointer_size. */
|
||||
|
||||
#pragma __pointer_size short
|
||||
|
@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
You Lose! This file can only be compiled with DEC C.
|
||||
#else
|
||||
|
||||
/* This file can only be compiled with DEC C, due the the call to
|
||||
/* This file can only be compiled with DEC C, due to the call to
|
||||
lib$establish. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -396,8 +396,7 @@ main (argc, argv)
|
||||
strncpy (cwdev, cwd, devlen);
|
||||
cwdev [devlen] = '\0';
|
||||
|
||||
search_dirs = xmalloc (strlen (system_search_dirs) + 1);
|
||||
strcpy (search_dirs, system_search_dirs);
|
||||
search_dirs = xstrdup (system_search_dirs);
|
||||
|
||||
addarg ("link");
|
||||
|
||||
|
@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
You Lose! This file can only be compiled with DEC C.
|
||||
#else
|
||||
|
||||
/* This file can only be compiled with DEC C, due the the call to
|
||||
/* This file can only be compiled with DEC C, due to the call to
|
||||
lib$establish and the pragmas pointer_size. */
|
||||
|
||||
#pragma __pointer_size short
|
||||
|
@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
You Lose! This file can only be compiled with DEC C.
|
||||
#else
|
||||
|
||||
/* This file can only be compiled with DEC C, due the the call to
|
||||
/* This file can only be compiled with DEC C, due to the call to
|
||||
lib$establish. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -29,17 +29,17 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define NO_EXTERNAL_INDIRECT_ADDRESS
|
||||
|
||||
#include "alpha/alpha.h"
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-D__ALPHA -Dvms -DVMS -D__vms__ -D__VMS__ -Asystem=vms"
|
||||
|
||||
#undef CPP_SUBTARGET_SPEC
|
||||
#define CPP_SUBTARGET_SPEC "\
|
||||
%{mfloat-ieee:-D__IEEE_FLOAT} \
|
||||
%{mfloat-vax:-D__G_FLOAT} \
|
||||
%{!mfloat-vax:-D__IEEE_FLOAT}"
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define_std ("vms"); \
|
||||
builtin_define_std ("VMS"); \
|
||||
builtin_define ("__ALPHA"); \
|
||||
builtin_assert ("system=vms"); \
|
||||
if (TARGET_FLOAT_VAX) \
|
||||
builtin_define ("__G_FLOAT"); \
|
||||
else \
|
||||
builtin_define ("__IEEE_FLOAT"); \
|
||||
} while (0)
|
||||
|
||||
/* By default, allow $ to be part of an identifier. */
|
||||
#define DOLLARS_IN_IDENTIFIERS 2
|
||||
@ -261,26 +261,17 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
|
||||
}
|
||||
|
||||
#define LINK_SECTION_ASM_OP "\t.link"
|
||||
#define READONLY_SECTION_ASM_OP "\t.rdata"
|
||||
#define READONLY_DATA_SECTION_ASM_OP "\t.rdata"
|
||||
#define LITERALS_SECTION_ASM_OP "\t.literals"
|
||||
#define CTORS_SECTION_ASM_OP "\t.ctors"
|
||||
#define DTORS_SECTION_ASM_OP "\t.dtors"
|
||||
|
||||
#undef EXTRA_SECTIONS
|
||||
#define EXTRA_SECTIONS in_link, in_rdata, in_literals
|
||||
#define EXTRA_SECTIONS in_link, in_literals
|
||||
|
||||
#undef EXTRA_SECTION_FUNCTIONS
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
void \
|
||||
readonly_section () \
|
||||
{ \
|
||||
if (in_section != in_rdata) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", READONLY_SECTION_ASM_OP); \
|
||||
in_section = in_rdata; \
|
||||
} \
|
||||
} \
|
||||
void \
|
||||
link_section () \
|
||||
{ \
|
||||
if (in_section != in_link) \
|
||||
@ -299,7 +290,6 @@ literals_section () \
|
||||
} \
|
||||
}
|
||||
|
||||
extern void readonly_section PARAMS ((void));
|
||||
extern void link_section PARAMS ((void));
|
||||
extern void literals_section PARAMS ((void));
|
||||
|
||||
@ -310,11 +300,6 @@ extern void literals_section PARAMS ((void));
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
|
||||
fprintf (FILE, "\t.quad $L%d\n", (VALUE))
|
||||
|
||||
#undef READONLY_DATA_SECTION
|
||||
#define READONLY_DATA_SECTION readonly_section
|
||||
|
||||
#define ASM_FILE_END(FILE) alpha_write_linkage (FILE);
|
||||
|
||||
#undef CASE_VECTOR_MODE
|
||||
#define CASE_VECTOR_MODE DImode
|
||||
#undef CASE_VECTOR_PC_RELATIVE
|
||||
@ -379,8 +364,8 @@ do { \
|
||||
#undef MIPS_DEBUGGING_INFO
|
||||
#undef DBX_DEBUGGING_INFO
|
||||
|
||||
#define DWARF2_DEBUGGING_INFO
|
||||
#define VMS_DEBUGGING_INFO
|
||||
#define DWARF2_DEBUGGING_INFO 1
|
||||
#define VMS_DEBUGGING_INFO 1
|
||||
|
||||
#define DWARF2_UNWIND_INFO 1
|
||||
|
||||
@ -469,7 +454,7 @@ do { \
|
||||
sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
|
||||
|
||||
/* ??? VMS uses different linkage. */
|
||||
#undef ASM_OUTPUT_MI_THUNK
|
||||
#undef TARGET_ASM_OUTPUT_MI_THUNK
|
||||
|
||||
#undef ASM_SPEC
|
||||
#undef ASM_FINAL_SPEC
|
||||
|
@ -26,10 +26,14 @@ Boston, MA 02111-1307, USA. */
|
||||
%{!mvxsim: %{!mcpu*|mcpu=21064:-DCPU=21064} %{mcpu=21164:-DCPU=21164}} \
|
||||
%{posix: -D_POSIX_SOURCE}"
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "\
|
||||
-D__vxworks -D__alpha_vxworks -Asystem=vxworks \
|
||||
-Asystem=embedded -D_LONGLONG"
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define ("__vxworks"); \
|
||||
builtin_define ("__alpha_vxworks"); \
|
||||
builtin_define ("_LONGLONG"); \
|
||||
builtin_assert ("system=vxworks"); \
|
||||
builtin_assert ("system=embedded"); \
|
||||
} while (0)
|
||||
|
||||
/* VxWorks does all the library stuff itself. */
|
||||
|
||||
|
@ -235,7 +235,7 @@ processing is enabled.
|
||||
When the -mthumb-interwork command line switch is specified, gcc
|
||||
arranges for all functions to return to their caller by using the BX
|
||||
instruction. Thus provided that the return address has the bottom bit
|
||||
correctly initialised to indicate the instruction set of the caller,
|
||||
correctly initialized to indicate the instruction set of the caller,
|
||||
correct operation will ensue.
|
||||
|
||||
When a function is called explicitly (rather than via a function
|
||||
|
@ -54,8 +54,6 @@ Boston, MA 02111-1307, USA. */
|
||||
addressing across such boundaries. */
|
||||
#define TEXT_SECTION_ASM_OP aof_text_section ()
|
||||
|
||||
#define SELECT_RTX_SECTION(MODE,RTX,ALIGN) text_section ();
|
||||
|
||||
#define DATA_SECTION_ASM_OP aof_data_section ()
|
||||
|
||||
#define EXTRA_SECTIONS in_zero_init, in_common
|
||||
@ -222,14 +220,8 @@ do \
|
||||
|
||||
extern int arm_main_function;
|
||||
|
||||
#define ASM_GLOBALIZE_LABEL(STREAM,NAME) \
|
||||
do { \
|
||||
fprintf ((STREAM), "\tEXPORT\t"); \
|
||||
assemble_name ((STREAM), (NAME)); \
|
||||
fputc ('\n', (STREAM)); \
|
||||
if ((NAME)[0] == 'm' && ! strcmp ((NAME), "main")) \
|
||||
arm_main_function = 1; \
|
||||
} while (0)
|
||||
/* Globalizing directive for a label. */
|
||||
#define GLOBAL_ASM_OP "\tEXPORT\t"
|
||||
|
||||
#define ASM_OUTPUT_LABEL(STREAM,NAME) \
|
||||
do { \
|
||||
|
@ -111,9 +111,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Generate DBX debugging information. riscix.h will undefine this because
|
||||
the native assembler does not support stabs. */
|
||||
#ifndef DBX_DEBUGGING_INFO
|
||||
#define DBX_DEBUGGING_INFO 1
|
||||
#endif
|
||||
#define DBX_DEBUGGING_INFO 1
|
||||
|
||||
/* Acorn dbx moans about continuation chars, so don't use any. */
|
||||
#ifndef DBX_CONTIN_LENGTH
|
||||
@ -144,27 +142,8 @@ Boston, MA 02111-1307, USA. */
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
#ifndef ASM_OUTPUT_LABEL
|
||||
#define ASM_OUTPUT_LABEL(STREAM, NAME) \
|
||||
do \
|
||||
{ \
|
||||
assemble_name (STREAM,NAME); \
|
||||
fputs (":\n", STREAM); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Output a globalising directive for a label. */
|
||||
#ifndef ASM_GLOBALIZE_LABEL
|
||||
#define ASM_GLOBALIZE_LABEL(STREAM, NAME) \
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, "\t.global\t"); \
|
||||
assemble_name (STREAM, NAME); \
|
||||
fputc ('\n',STREAM); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
/* Globalizing directive for a label. */
|
||||
#define GLOBAL_ASM_OP "\t.global\t"
|
||||
|
||||
/* Make an internal label into a string. */
|
||||
#ifndef ASM_GENERATE_INTERNAL_LABEL
|
||||
|
46
contrib/gcc/config/arm/arm-modes.def
Normal file
46
contrib/gcc/config/arm/arm-modes.def
Normal file
@ -0,0 +1,46 @@
|
||||
/* Definitions of target machine for GNU compiler, for ARM.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
|
||||
and Martin Simmons (@harleqn.co.uk).
|
||||
More major hacks by Richard Earnshaw (rearnsha@arm.com)
|
||||
Minor hacks by Nick Clifton (nickc@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* CCFPEmode should be used with floating inequalities,
|
||||
CCFPmode should be used with floating equalities.
|
||||
CC_NOOVmode should be used with SImode integer equalities.
|
||||
CC_Zmode should be used if only the Z flag is set correctly
|
||||
CCmode should be used otherwise. */
|
||||
|
||||
CC (CC_NOOV)
|
||||
CC (CC_Z)
|
||||
CC (CC_SWP)
|
||||
CC (CCFP)
|
||||
CC (CCFPE)
|
||||
CC (CC_DNE)
|
||||
CC (CC_DEQ)
|
||||
CC (CC_DLE)
|
||||
CC (CC_DLT)
|
||||
CC (CC_DGE)
|
||||
CC (CC_DGT)
|
||||
CC (CC_DLEU)
|
||||
CC (CC_DLTU)
|
||||
CC (CC_DGEU)
|
||||
CC (CC_DGTU)
|
||||
CC (CC_C)
|
@ -1,5 +1,5 @@
|
||||
/* Prototypes for exported functions defined in arm.c and pe.c
|
||||
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Richard Earnshaw (rearnsha@arm.com)
|
||||
Minor hacks by Nick Clifton (nickc@cygnus.com)
|
||||
|
||||
@ -31,9 +31,11 @@ extern void arm_finalize_pic PARAMS ((int));
|
||||
extern int arm_volatile_func PARAMS ((void));
|
||||
extern const char * arm_output_epilogue PARAMS ((int));
|
||||
extern void arm_expand_prologue PARAMS ((void));
|
||||
extern HOST_WIDE_INT arm_get_frame_size PARAMS ((void));
|
||||
/* Used in arm.md, but defined in output.c. */
|
||||
extern void assemble_align PARAMS ((int));
|
||||
extern const char * arm_strip_name_encoding PARAMS ((const char *));
|
||||
extern void arm_asm_output_labelref PARAMS ((FILE *, const char *));
|
||||
extern unsigned long arm_current_func_type PARAMS ((void));
|
||||
extern unsigned int arm_compute_initial_elimination_offset PARAMS ((unsigned int, unsigned int));
|
||||
|
||||
@ -43,7 +45,8 @@ extern void arm_encode_call_attribute PARAMS ((tree, int));
|
||||
extern int arm_function_ok_for_sibcall PARAMS ((tree));
|
||||
#endif
|
||||
#ifdef RTX_CODE
|
||||
extern int arm_hard_regno_mode_ok PARAMS ((unsigned int, enum machine_mode));
|
||||
extern int arm_hard_regno_mode_ok PARAMS ((unsigned int,
|
||||
enum machine_mode));
|
||||
extern int const_ok_for_arm PARAMS ((HOST_WIDE_INT));
|
||||
extern int arm_split_constant PARAMS ((RTX_CODE, enum machine_mode,
|
||||
HOST_WIDE_INT, rtx, rtx, int));
|
||||
@ -106,6 +109,7 @@ extern int arm_gen_movstrqi PARAMS ((rtx *));
|
||||
extern rtx arm_gen_rotated_half_load PARAMS ((rtx));
|
||||
extern enum machine_mode arm_select_cc_mode PARAMS ((RTX_CODE, rtx, rtx));
|
||||
extern rtx arm_gen_compare_reg PARAMS ((RTX_CODE, rtx, rtx));
|
||||
extern rtx arm_gen_return_addr_mask PARAMS ((void));
|
||||
extern void arm_reload_in_hi PARAMS ((rtx *));
|
||||
extern void arm_reload_out_hi PARAMS ((rtx *));
|
||||
extern void arm_reorg PARAMS ((rtx));
|
||||
@ -121,7 +125,8 @@ extern const char * output_move_double PARAMS ((rtx *));
|
||||
extern const char * output_mov_immediate PARAMS ((rtx *));
|
||||
extern const char * output_add_immediate PARAMS ((rtx *));
|
||||
extern const char * arithmetic_instr PARAMS ((rtx, int));
|
||||
extern void output_ascii_pseudo_op PARAMS ((FILE *, const unsigned char *, int));
|
||||
extern void output_ascii_pseudo_op PARAMS ((FILE *, const unsigned char *,
|
||||
int));
|
||||
extern const char * output_return_instruction PARAMS ((rtx, int, int));
|
||||
extern void arm_poke_function_name PARAMS ((FILE *, const char *));
|
||||
extern void arm_print_operand PARAMS ((FILE *, rtx, int));
|
||||
@ -136,6 +141,11 @@ extern rtx arm_function_arg PARAMS ((CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int));
|
||||
extern void arm_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx,
|
||||
int));
|
||||
extern rtx arm_va_arg PARAMS ((tree, tree));
|
||||
extern int arm_function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
|
||||
enum machine_mode,
|
||||
tree, int));
|
||||
|
||||
#endif
|
||||
|
||||
#if defined AOF_ASSEMBLER
|
||||
@ -152,10 +162,13 @@ extern void common_section PARAMS ((void));
|
||||
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
extern int arm_float_words_big_endian PARAMS ((void));
|
||||
|
||||
/* Thumb functions. */
|
||||
extern void arm_init_expanders PARAMS ((void));
|
||||
extern int thumb_far_jump_used_p PARAMS ((int));
|
||||
extern const char * thumb_unexpanded_epilogue PARAMS ((void));
|
||||
extern HOST_WIDE_INT thumb_get_frame_size PARAMS ((void));
|
||||
extern void thumb_expand_prologue PARAMS ((void));
|
||||
extern void thumb_expand_epilogue PARAMS ((void));
|
||||
#ifdef TREE_CODE
|
||||
@ -185,7 +198,7 @@ extern int arm_dllimport_name_p PARAMS ((const char *));
|
||||
|
||||
#ifdef TREE_CODE
|
||||
extern void arm_pe_unique_section PARAMS ((tree, int));
|
||||
extern void arm_pe_encode_section_info PARAMS ((tree));
|
||||
extern void arm_pe_encode_section_info PARAMS ((tree, int));
|
||||
extern int arm_dllexport_p PARAMS ((tree));
|
||||
extern int arm_dllimport_p PARAMS ((tree));
|
||||
extern void arm_mark_dllexport PARAMS ((tree));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,52 @@ Boston, MA 02111-1307, USA. */
|
||||
#ifndef GCC_ARM_H
|
||||
#define GCC_ARM_H
|
||||
|
||||
/* Target CPU builtins. */
|
||||
#define TARGET_CPU_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
if (TARGET_ARM) \
|
||||
builtin_define ("__arm__"); \
|
||||
else \
|
||||
builtin_define ("__thumb__"); \
|
||||
\
|
||||
if (TARGET_BIG_END) \
|
||||
{ \
|
||||
builtin_define ("__ARMEB__"); \
|
||||
if (TARGET_THUMB) \
|
||||
builtin_define ("__THUMBEB__"); \
|
||||
if (TARGET_LITTLE_WORDS) \
|
||||
builtin_define ("__ARMWEL__"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
builtin_define ("__ARMEL__"); \
|
||||
if (TARGET_THUMB) \
|
||||
builtin_define ("__THUMBEL__"); \
|
||||
} \
|
||||
\
|
||||
if (TARGET_APCS_32) \
|
||||
builtin_define ("__APCS_32__"); \
|
||||
else \
|
||||
builtin_define ("__APCS_26__"); \
|
||||
\
|
||||
if (TARGET_SOFT_FLOAT) \
|
||||
builtin_define ("__SOFTFP__"); \
|
||||
\
|
||||
/* FIXME: TARGET_HARD_FLOAT currently implies \
|
||||
FPA. */ \
|
||||
if (TARGET_VFP && !TARGET_HARD_FLOAT) \
|
||||
builtin_define ("__VFP_FP__"); \
|
||||
\
|
||||
/* Add a define for interworking. \
|
||||
Needed when building libgcc.a. */ \
|
||||
if (TARGET_INTERWORK) \
|
||||
builtin_define ("__THUMB_INTERWORK__"); \
|
||||
\
|
||||
builtin_assert ("cpu=arm"); \
|
||||
builtin_assert ("machine=arm"); \
|
||||
} while (0)
|
||||
|
||||
#define TARGET_CPU_arm2 0x0000
|
||||
#define TARGET_CPU_arm250 0x0000
|
||||
#define TARGET_CPU_arm3 0x0000
|
||||
@ -66,21 +112,22 @@ extern arm_cc arm_current_cc;
|
||||
|
||||
extern int arm_target_label;
|
||||
extern int arm_ccfsm_state;
|
||||
extern struct rtx_def * arm_target_insn;
|
||||
extern GTY(()) rtx arm_target_insn;
|
||||
/* Run-time compilation parameters selecting different hardware subsets. */
|
||||
extern int target_flags;
|
||||
/* The floating point instruction architecture, can be 2 or 3 */
|
||||
extern const char * target_fp_name;
|
||||
/* Define the information needed to generate branch insns. This is
|
||||
stored from the compare operation. Note that we can't use "rtx" here
|
||||
since it hasn't been defined! */
|
||||
extern struct rtx_def * arm_compare_op0;
|
||||
extern struct rtx_def * arm_compare_op1;
|
||||
stored from the compare operation. */
|
||||
extern GTY(()) rtx arm_compare_op0;
|
||||
extern GTY(()) rtx arm_compare_op1;
|
||||
/* The label of the current constant pool. */
|
||||
extern struct rtx_def * pool_vector_label;
|
||||
extern rtx pool_vector_label;
|
||||
/* Set to 1 when a return insn is output, this means that the epilogue
|
||||
is not needed. */
|
||||
extern int return_used_this_function;
|
||||
/* Used to produce AOF syntax assembler. */
|
||||
extern GTY(()) rtx aof_pic_label;
|
||||
|
||||
/* Just in case configure has failed to define anything. */
|
||||
#ifndef TARGET_CPU_DEFAULT
|
||||
@ -126,16 +173,17 @@ Unrecognized value in TARGET_CPU_DEFAULT.
|
||||
#endif
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "\
|
||||
%(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) \
|
||||
%(cpp_endian) %(subtarget_cpp_spec) %(cpp_isa) %(cpp_interwork)"
|
||||
|
||||
#define CPP_ISA_SPEC "%{mthumb:-D__thumb__} %{!mthumb:-D__arm__}"
|
||||
#define CPP_SPEC "%(cpp_cpu_arch) %(subtarget_cpp_spec) \
|
||||
%{mapcs-32:%{mapcs-26: \
|
||||
%e-mapcs-26 and -mapcs-32 may not be used together}} \
|
||||
%{msoft-float:%{mhard-float: \
|
||||
%e-msoft-float and -mhard_float may not be used together}} \
|
||||
%{mbig-endian:%{mlittle-endian: \
|
||||
%e-mbig-endian and -mlittle-endian may not be used together}}"
|
||||
|
||||
/* Set the architecture define -- if -march= is set, then it overrides
|
||||
the -mcpu= setting. */
|
||||
#define CPP_CPU_ARCH_SPEC "\
|
||||
-Acpu=arm -Amachine=arm \
|
||||
%{march=arm2:-D__ARM_ARCH_2__} \
|
||||
%{march=arm250:-D__ARM_ARCH_2__} \
|
||||
%{march=arm3:-D__ARM_ARCH_2__} \
|
||||
@ -206,58 +254,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
|
||||
%{!mcpu*:%(cpp_cpu_arch_default)}} \
|
||||
"
|
||||
|
||||
/* Define __APCS_26__ if the PC also contains the PSR */
|
||||
#define CPP_APCS_PC_SPEC "\
|
||||
%{mapcs-32:%{mapcs-26:%e-mapcs-26 and -mapcs-32 may not be used together} \
|
||||
-D__APCS_32__} \
|
||||
%{mapcs-26:-D__APCS_26__} \
|
||||
%{!mapcs-32: %{!mapcs-26:%(cpp_apcs_pc_default)}} \
|
||||
"
|
||||
|
||||
#ifndef CPP_APCS_PC_DEFAULT_SPEC
|
||||
#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_26__"
|
||||
#endif
|
||||
|
||||
#define CPP_FLOAT_SPEC "\
|
||||
%{msoft-float:\
|
||||
%{mhard-float:%e-msoft-float and -mhard_float may not be used together} \
|
||||
-D__SOFTFP__} \
|
||||
%{!mhard-float:%{!msoft-float:%(cpp_float_default)}} \
|
||||
"
|
||||
|
||||
/* Default is hard float, which doesn't define anything */
|
||||
#define CPP_FLOAT_DEFAULT_SPEC ""
|
||||
|
||||
#define CPP_ENDIAN_SPEC "\
|
||||
%{mbig-endian: \
|
||||
%{mlittle-endian: \
|
||||
%e-mbig-endian and -mlittle-endian may not be used together} \
|
||||
-D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__} %{mthumb:-D__THUMBEB__}}\
|
||||
%{mlittle-endian:-D__ARMEL__ %{mthumb:-D__THUMBEL__}} \
|
||||
%{!mlittle-endian:%{!mbig-endian:%(cpp_endian_default)}} \
|
||||
"
|
||||
|
||||
/* Default is little endian. */
|
||||
#define CPP_ENDIAN_DEFAULT_SPEC "-D__ARMEL__ %{mthumb:-D__THUMBEL__}"
|
||||
|
||||
/* Add a define for interworking. Needed when building libgcc.a.
|
||||
This must define __THUMB_INTERWORK__ to the pre-processor if
|
||||
interworking is enabled by default. */
|
||||
#ifndef CPP_INTERWORK_DEFAULT_SPEC
|
||||
#define CPP_INTERWORK_DEFAULT_SPEC ""
|
||||
#endif
|
||||
|
||||
#define CPP_INTERWORK_SPEC " \
|
||||
%{mthumb-interwork: \
|
||||
%{mno-thumb-interwork: %eincompatible interworking options} \
|
||||
-D__THUMB_INTERWORK__} \
|
||||
%{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}} \
|
||||
"
|
||||
|
||||
#ifndef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES ""
|
||||
#endif
|
||||
|
||||
#ifndef CC1_SPEC
|
||||
#define CC1_SPEC ""
|
||||
#endif
|
||||
@ -274,15 +270,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
|
||||
#define EXTRA_SPECS \
|
||||
{ "cpp_cpu_arch", CPP_CPU_ARCH_SPEC }, \
|
||||
{ "cpp_cpu_arch_default", CPP_ARCH_DEFAULT_SPEC }, \
|
||||
{ "cpp_apcs_pc", CPP_APCS_PC_SPEC }, \
|
||||
{ "cpp_apcs_pc_default", CPP_APCS_PC_DEFAULT_SPEC }, \
|
||||
{ "cpp_float", CPP_FLOAT_SPEC }, \
|
||||
{ "cpp_float_default", CPP_FLOAT_DEFAULT_SPEC }, \
|
||||
{ "cpp_endian", CPP_ENDIAN_SPEC }, \
|
||||
{ "cpp_endian_default", CPP_ENDIAN_DEFAULT_SPEC }, \
|
||||
{ "cpp_isa", CPP_ISA_SPEC }, \
|
||||
{ "cpp_interwork", CPP_INTERWORK_SPEC }, \
|
||||
{ "cpp_interwork_default", CPP_INTERWORK_DEFAULT_SPEC }, \
|
||||
{ "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \
|
||||
SUBTARGET_EXTRA_SPECS
|
||||
|
||||
@ -383,6 +370,12 @@ Unrecognized value in TARGET_CPU_DEFAULT.
|
||||
destination is non-Thumb aware. */
|
||||
#define THUMB_FLAG_CALLER_SUPER_INTERWORKING (1 << 20)
|
||||
|
||||
/* Nonzero means target uses VFP FP. */
|
||||
#define ARM_FLAG_VFP (1 << 21)
|
||||
|
||||
/* Nonzero means to use ARM/Thumb Procedure Call Standard conventions. */
|
||||
#define ARM_FLAG_ATPCS (1 << 22)
|
||||
|
||||
#define TARGET_APCS_FRAME (target_flags & ARM_FLAG_APCS_FRAME)
|
||||
#define TARGET_POKE_FUNCTION_NAME (target_flags & ARM_FLAG_POKE)
|
||||
#define TARGET_FPE (target_flags & ARM_FLAG_FPE)
|
||||
@ -390,9 +383,11 @@ Unrecognized value in TARGET_CPU_DEFAULT.
|
||||
#define TARGET_APCS_STACK (target_flags & ARM_FLAG_APCS_STACK)
|
||||
#define TARGET_APCS_FLOAT (target_flags & ARM_FLAG_APCS_FLOAT)
|
||||
#define TARGET_APCS_REENT (target_flags & ARM_FLAG_APCS_REENT)
|
||||
#define TARGET_ATPCS (target_flags & ARM_FLAG_ATPCS)
|
||||
#define TARGET_MMU_TRAPS (target_flags & ARM_FLAG_MMU_TRAPS)
|
||||
#define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT)
|
||||
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
|
||||
#define TARGET_VFP (target_flags & ARM_FLAG_VFP)
|
||||
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
|
||||
#define TARGET_INTERWORK (target_flags & ARM_FLAG_INTERWORK)
|
||||
#define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS)
|
||||
@ -409,8 +404,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
|
||||
? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \
|
||||
: (target_flags & THUMB_FLAG_BACKTRACE))
|
||||
|
||||
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
|
||||
Bit 31 is reserved. See riscix.h. */
|
||||
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis. */
|
||||
#ifndef SUBTARGET_SWITCHES
|
||||
#define SUBTARGET_SWITCHES
|
||||
#endif
|
||||
@ -647,8 +641,6 @@ extern int arm_is_6_or_7;
|
||||
/* This is required to ensure that push insns always push a word. */
|
||||
#define PROMOTE_FUNCTION_ARGS
|
||||
|
||||
/* Define for XFmode extended real floating point support.
|
||||
This will automatically cause REAL_ARITHMETIC to be defined. */
|
||||
/* For the ARM:
|
||||
I think I have added all the code to make this work. Unfortunately,
|
||||
early releases of the floating point emulation code on RISCiX used a
|
||||
@ -663,12 +655,6 @@ extern int arm_is_6_or_7;
|
||||
/* Disable XFmode patterns in md file */
|
||||
#define ENABLE_XF_PATTERNS 0
|
||||
|
||||
/* Define if you don't want extended real, but do want to use the
|
||||
software floating point emulator for REAL_ARITHMETIC and
|
||||
decimal <-> binary conversion. */
|
||||
/* See comment above */
|
||||
#define REAL_ARITHMETIC
|
||||
|
||||
/* Define this if most significant bit is lowest numbered
|
||||
in instructions that operate on numbered bit-fields. */
|
||||
#define BITS_BIG_ENDIAN 0
|
||||
@ -693,22 +679,18 @@ extern int arm_is_6_or_7;
|
||||
#endif
|
||||
|
||||
/* Define this if most significant word of doubles is the lowest numbered.
|
||||
This is always true, even when in little-endian mode. */
|
||||
#define FLOAT_WORDS_BIG_ENDIAN 1
|
||||
|
||||
/* Number of bits in an addressable storage unit */
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
#define BITS_PER_WORD 32
|
||||
The rules are different based on whether or not we use FPA-format or
|
||||
VFP-format doubles. */
|
||||
#define FLOAT_WORDS_BIG_ENDIAN (arm_float_words_big_endian ())
|
||||
|
||||
#define UNITS_PER_WORD 4
|
||||
|
||||
#define POINTER_SIZE 32
|
||||
|
||||
#define PARM_BOUNDARY 32
|
||||
|
||||
#define STACK_BOUNDARY 32
|
||||
|
||||
#define PREFERRED_STACK_BOUNDARY (TARGET_ATPCS ? 64 : 32)
|
||||
|
||||
#define FUNCTION_BOUNDARY 32
|
||||
|
||||
/* The lowest bit is used to indicate Thumb-mode functions, so the
|
||||
@ -737,7 +719,7 @@ extern int arm_is_6_or_7;
|
||||
#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
|
||||
extern int arm_structure_size_boundary;
|
||||
|
||||
/* This is the value used to initialise arm_structure_size_boundary. If a
|
||||
/* This is the value used to initialize arm_structure_size_boundary. If a
|
||||
particular arm target wants to change the default value it should change
|
||||
the definition of this macro, not STRUCTRUE_SIZE_BOUNDARY. See netbsd.h
|
||||
for an example of this. */
|
||||
@ -748,12 +730,9 @@ extern int arm_structure_size_boundary;
|
||||
/* Used when parsing command line option -mstructure_size_boundary. */
|
||||
extern const char * structure_size_string;
|
||||
|
||||
/* Non-zero if move instructions will actually fail to work
|
||||
/* Nonzero if move instructions will actually fail to work
|
||||
when given unaligned data. */
|
||||
#define STRICT_ALIGNMENT 1
|
||||
|
||||
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
|
||||
|
||||
|
||||
/* Standard register usage. */
|
||||
|
||||
@ -889,15 +868,15 @@ extern const char * structure_size_string;
|
||||
#define ROUND_UP(X) (((X) + 3) & ~3)
|
||||
|
||||
/* Convert fron bytes to ints. */
|
||||
#define NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
#define ARM_NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* The number of (integer) registers required to hold a quantity of type MODE. */
|
||||
#define NUM_REGS(MODE) \
|
||||
NUM_INTS (GET_MODE_SIZE (MODE))
|
||||
#define ARM_NUM_REGS(MODE) \
|
||||
ARM_NUM_INTS (GET_MODE_SIZE (MODE))
|
||||
|
||||
/* The number of (integer) registers required to hold a quantity of TYPE MODE. */
|
||||
#define NUM_REGS2(MODE, TYPE) \
|
||||
NUM_INTS ((MODE) == BLKmode ? \
|
||||
#define ARM_NUM_REGS2(MODE, TYPE) \
|
||||
ARM_NUM_INTS ((MODE) == BLKmode ? \
|
||||
int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))
|
||||
|
||||
/* The number of (integer) argument register available. */
|
||||
@ -1001,7 +980,7 @@ extern const char * structure_size_string;
|
||||
&& REGNO >= FIRST_ARM_FP_REGNUM \
|
||||
&& REGNO != FRAME_POINTER_REGNUM \
|
||||
&& REGNO != ARG_POINTER_REGNUM) \
|
||||
? 1 : NUM_REGS (MODE))
|
||||
? 1 : ARM_NUM_REGS (MODE))
|
||||
|
||||
/* Return true if REGNO is suitable for holding a quantity of type MODE. */
|
||||
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
|
||||
@ -1324,7 +1303,7 @@ enum reg_class
|
||||
needed to represent mode MODE in a register of class CLASS.
|
||||
ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
((CLASS) == FPU_REGS ? 1 : NUM_REGS (MODE))
|
||||
((CLASS) == FPU_REGS ? 1 : ARM_NUM_REGS (MODE))
|
||||
|
||||
/* Moves between FPU_REGS and GENERAL_REGS are two memory insns. */
|
||||
#define REGISTER_MOVE_COST(MODE, FROM, TO) \
|
||||
@ -1420,7 +1399,7 @@ enum reg_class
|
||||
Note value 7 is currently unassigned. Also note that the interrupt
|
||||
function types all have bit 2 set, so that they can be tested for easily.
|
||||
Note that 0 is deliberately chosen for ARM_FT_UNKNOWN so that when the
|
||||
machine_function structure is initialised (to zero) func_type will
|
||||
machine_function structure is initialized (to zero) func_type will
|
||||
default to unknown. This will force the first use of arm_current_func_type
|
||||
to call arm_compute_func_type. */
|
||||
#define ARM_FT_UNKNOWN 0 /* Type has not yet been determined. */
|
||||
@ -1449,16 +1428,18 @@ enum reg_class
|
||||
|
||||
/* A C structure for machine-specific, per-function data.
|
||||
This is added to the cfun structure. */
|
||||
typedef struct machine_function
|
||||
typedef struct machine_function GTY(())
|
||||
{
|
||||
/* Additionsl stack adjustment in __builtin_eh_throw. */
|
||||
struct rtx_def *eh_epilogue_sp_ofs;
|
||||
rtx eh_epilogue_sp_ofs;
|
||||
/* Records if LR has to be saved for far jumps. */
|
||||
int far_jump_used;
|
||||
/* Records if ARG_POINTER was ever live. */
|
||||
int arg_pointer_live;
|
||||
/* Records if the save of LR has been eliminated. */
|
||||
int lr_save_eliminated;
|
||||
/* The size of the stack frame. Only valid after reload. */
|
||||
int frame_size;
|
||||
/* Records the type of the current function. */
|
||||
unsigned long func_type;
|
||||
/* Record if the function has a variable argument list. */
|
||||
@ -1503,9 +1484,17 @@ typedef struct
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
( NUM_ARG_REGS > (CUM).nregs \
|
||||
&& (NUM_ARG_REGS < ((CUM).nregs + NUM_REGS2 (MODE, TYPE))) \
|
||||
&& (NUM_ARG_REGS < ((CUM).nregs + ARM_NUM_REGS2 (MODE, TYPE))) \
|
||||
? NUM_ARG_REGS - (CUM).nregs : 0)
|
||||
|
||||
/* A C expression that indicates when an argument must be passed by
|
||||
reference. If nonzero for an argument, a copy of that argument is
|
||||
made in memory and a pointer to the argument is passed instead of
|
||||
the argument itself. The pointer is passed in whatever way is
|
||||
appropriate for passing a pointer to that type. */
|
||||
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
|
||||
arm_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||
for a call to a function whose data type is FNTYPE.
|
||||
For a library call, FNTYPE is 0.
|
||||
@ -1517,12 +1506,16 @@ typedef struct
|
||||
of mode MODE and data type TYPE.
|
||||
(TYPE is null for libcalls where that information may not be available.) */
|
||||
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
|
||||
(CUM).nregs += NUM_REGS2 (MODE, TYPE)
|
||||
(CUM).nregs += ARM_NUM_REGS2 (MODE, TYPE)
|
||||
|
||||
/* 1 if N is a possible register number for function argument passing.
|
||||
On the ARM, r0-r3 are used to pass args. */
|
||||
#define FUNCTION_ARG_REGNO_P(REGNO) (IN_RANGE ((REGNO), 0, 3))
|
||||
|
||||
/* Implement `va_arg'. */
|
||||
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
|
||||
arm_va_arg (valist, type)
|
||||
|
||||
|
||||
/* Tail calling. */
|
||||
|
||||
@ -1572,7 +1565,10 @@ typedef struct
|
||||
will output the .text section.
|
||||
|
||||
The ``mov ip,lr'' seems like a good idea to stick with cc convention.
|
||||
``prof'' doesn't seem to mind about this! */
|
||||
``prof'' doesn't seem to mind about this!
|
||||
|
||||
Note - this version of the code is designed to work in both ARM and
|
||||
Thumb modes. */
|
||||
#ifndef ARM_FUNCTION_PROFILER
|
||||
#define ARM_FUNCTION_PROFILER(STREAM, LABELNO) \
|
||||
{ \
|
||||
@ -1589,20 +1585,16 @@ typedef struct
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef THUMB_FUNCTION_PROFILER
|
||||
#define THUMB_FUNCTION_PROFILER(STREAM, LABELNO) \
|
||||
{ \
|
||||
fprintf (STREAM, "\tmov\tip, lr\n"); \
|
||||
fprintf (STREAM, "\tbl\tmcount\n"); \
|
||||
fprintf (STREAM, "\t.word\tLP%d\n", LABELNO); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef THUMB_FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(STREAM, LABELNO) \
|
||||
if (TARGET_ARM) \
|
||||
ARM_FUNCTION_PROFILER (STREAM, LABELNO) \
|
||||
else \
|
||||
THUMB_FUNCTION_PROFILER (STREAM, LABELNO)
|
||||
#else
|
||||
#define FUNCTION_PROFILER(STREAM, LABELNO) \
|
||||
ARM_FUNCTION_PROFILER (STREAM, LABELNO)
|
||||
#endif
|
||||
|
||||
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
|
||||
the stack pointer does not matter. The value is tested only in
|
||||
@ -1657,7 +1649,13 @@ typedef struct
|
||||
((TO) == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? 0 : \
|
||||
((TO) == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? 0 : \
|
||||
1)
|
||||
|
||||
|
||||
#define THUMB_REG_PUSHED_P(reg) \
|
||||
(regs_ever_live [reg] \
|
||||
&& (! call_used_regs [reg] \
|
||||
|| (flag_pic && (reg) == PIC_OFFSET_TABLE_REGNUM)) \
|
||||
&& !(TARGET_SINGLE_PIC_BASE && ((reg) == arm_pic_register)))
|
||||
|
||||
/* Define the offset between two registers, one to be eliminated, and the
|
||||
other its replacement, at the start of a routine. */
|
||||
#define ARM_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||
@ -1676,13 +1674,13 @@ typedef struct
|
||||
int count_regs = 0; \
|
||||
int regno; \
|
||||
for (regno = 8; regno < 13; regno ++) \
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno]) \
|
||||
count_regs ++; \
|
||||
if (THUMB_REG_PUSHED_P (regno)) \
|
||||
count_regs ++; \
|
||||
if (count_regs) \
|
||||
(OFFSET) += 4 * count_regs; \
|
||||
count_regs = 0; \
|
||||
for (regno = 0; regno <= LAST_LO_REGNUM; regno ++) \
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno]) \
|
||||
if (THUMB_REG_PUSHED_P (regno)) \
|
||||
count_regs ++; \
|
||||
if (count_regs || ! leaf_function_p () || thumb_far_jump_used_p (0))\
|
||||
(OFFSET) += 4 * (count_regs + 1); \
|
||||
@ -1697,7 +1695,7 @@ typedef struct
|
||||
if ((TO) == STACK_POINTER_REGNUM) \
|
||||
{ \
|
||||
(OFFSET) += current_function_outgoing_args_size; \
|
||||
(OFFSET) += ROUND_UP (get_frame_size ()); \
|
||||
(OFFSET) += thumb_get_frame_size (); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -1884,56 +1882,11 @@ typedef struct
|
||||
case '*': return 1; \
|
||||
SUBTARGET_NAME_ENCODING_LENGTHS
|
||||
|
||||
/* This has to be handled by a function because more than part of the
|
||||
ARM backend uses function name prefixes to encode attributes. */
|
||||
#undef STRIP_NAME_ENCODING
|
||||
#define STRIP_NAME_ENCODING(VAR, SYMBOL_NAME) \
|
||||
(VAR) = arm_strip_name_encoding (SYMBOL_NAME)
|
||||
|
||||
/* This is how to output a reference to a user-level label named NAME.
|
||||
`assemble_name' uses this. */
|
||||
#undef ASM_OUTPUT_LABELREF
|
||||
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
|
||||
asm_fprintf (FILE, "%U%s", arm_strip_name_encoding (NAME))
|
||||
|
||||
/* If we are referencing a function that is weak then encode a long call
|
||||
flag in the function name, otherwise if the function is static or
|
||||
or known to be defined in this file then encode a short call flag.
|
||||
This macro is used inside the ENCODE_SECTION macro. */
|
||||
#define ARM_ENCODE_CALL_TYPE(decl) \
|
||||
if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd') \
|
||||
{ \
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl)) \
|
||||
arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR); \
|
||||
else if (! TREE_PUBLIC (decl)) \
|
||||
arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR); \
|
||||
}
|
||||
|
||||
/* Symbols in the text segment can be accessed without indirecting via the
|
||||
constant pool; it may take an extra binary operation, but this is still
|
||||
faster than indirecting via memory. Don't do this when not optimizing,
|
||||
since we won't be calculating al of the offsets necessary to do this
|
||||
simplification. */
|
||||
/* This doesn't work with AOF syntax, since the string table may be in
|
||||
a different AREA. */
|
||||
#ifndef AOF_ASSEMBLER
|
||||
#define ENCODE_SECTION_INFO(decl) \
|
||||
{ \
|
||||
if (optimize > 0 && TREE_CONSTANT (decl) \
|
||||
&& (!flag_writable_strings || TREE_CODE (decl) != STRING_CST)) \
|
||||
{ \
|
||||
rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd' \
|
||||
? TREE_CST_RTL (decl) : DECL_RTL (decl)); \
|
||||
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; \
|
||||
} \
|
||||
ARM_ENCODE_CALL_TYPE (decl) \
|
||||
}
|
||||
#else
|
||||
#define ENCODE_SECTION_INFO(decl) \
|
||||
{ \
|
||||
ARM_ENCODE_CALL_TYPE (decl) \
|
||||
}
|
||||
#endif
|
||||
arm_asm_output_labelref (FILE, NAME)
|
||||
|
||||
#define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \
|
||||
arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
|
||||
@ -2168,7 +2121,8 @@ typedef struct
|
||||
goto WIN; \
|
||||
/* This is PC relative data before MACHINE_DEPENDENT_REORG runs. */ \
|
||||
else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \
|
||||
&& CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic) \
|
||||
&& GET_CODE (X) == SYMBOL_REF \
|
||||
&& CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic) \
|
||||
goto WIN; \
|
||||
/* This is PC relative data after MACHINE_DEPENDENT_REORG runs. */ \
|
||||
else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
|
||||
@ -2477,12 +2431,13 @@ extern const char * arm_pic_register_string;
|
||||
/* We can't directly access anything that contains a symbol,
|
||||
nor can we indirect via the constant pool. */
|
||||
#define LEGITIMATE_PIC_OPERAND_P(X) \
|
||||
( ! symbol_mentioned_p (X) \
|
||||
&& ! label_mentioned_p (X) \
|
||||
&& (! CONSTANT_POOL_ADDRESS_P (X) \
|
||||
|| ( ! symbol_mentioned_p (get_pool_constant (X)) \
|
||||
&& ! label_mentioned_p (get_pool_constant (X)))))
|
||||
|
||||
(!(symbol_mentioned_p (X) \
|
||||
|| label_mentioned_p (X) \
|
||||
|| (GET_CODE (X) == SYMBOL_REF \
|
||||
&& CONSTANT_POOL_ADDRESS_P (X) \
|
||||
&& (symbol_mentioned_p (get_pool_constant (X)) \
|
||||
|| label_mentioned_p (get_pool_constant (X))))))
|
||||
|
||||
/* We need to know when we are making a constant pool; this determines
|
||||
whether data needs to be in the GOT or can be referenced via a GOT
|
||||
offset. */
|
||||
@ -2497,30 +2452,7 @@ extern int making_const_table;
|
||||
|
||||
/* Condition code information. */
|
||||
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
|
||||
return the mode to be used for the comparison.
|
||||
CCFPEmode should be used with floating inequalities,
|
||||
CCFPmode should be used with floating equalities.
|
||||
CC_NOOVmode should be used with SImode integer equalities.
|
||||
CC_Zmode should be used if only the Z flag is set correctly
|
||||
CCmode should be used otherwise. */
|
||||
|
||||
#define EXTRA_CC_MODES \
|
||||
CC(CC_NOOVmode, "CC_NOOV") \
|
||||
CC(CC_Zmode, "CC_Z") \
|
||||
CC(CC_SWPmode, "CC_SWP") \
|
||||
CC(CCFPmode, "CCFP") \
|
||||
CC(CCFPEmode, "CCFPE") \
|
||||
CC(CC_DNEmode, "CC_DNE") \
|
||||
CC(CC_DEQmode, "CC_DEQ") \
|
||||
CC(CC_DLEmode, "CC_DLE") \
|
||||
CC(CC_DLTmode, "CC_DLT") \
|
||||
CC(CC_DGEmode, "CC_DGE") \
|
||||
CC(CC_DGTmode, "CC_DGT") \
|
||||
CC(CC_DLEUmode, "CC_DLEU") \
|
||||
CC(CC_DLTUmode, "CC_DLTU") \
|
||||
CC(CC_DGEUmode, "CC_DGEU") \
|
||||
CC(CC_DGTUmode, "CC_DGTU") \
|
||||
CC(CC_Cmode, "CC_C")
|
||||
return the mode to be used for the comparison. */
|
||||
|
||||
#define SELECT_CC_MODE(OP, X, Y) arm_select_cc_mode (OP, X, Y)
|
||||
|
||||
@ -2779,39 +2711,6 @@ extern int making_const_table;
|
||||
else \
|
||||
THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
|
||||
|
||||
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
|
||||
Used for C++ multiple inheritance. */
|
||||
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
|
||||
do \
|
||||
{ \
|
||||
int mi_delta = (DELTA); \
|
||||
const char *const mi_op = mi_delta < 0 ? "sub" : "add"; \
|
||||
int shift = 0; \
|
||||
int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) \
|
||||
? 1 : 0); \
|
||||
if (mi_delta < 0) \
|
||||
mi_delta = - mi_delta; \
|
||||
while (mi_delta != 0) \
|
||||
{ \
|
||||
if ((mi_delta & (3 << shift)) == 0) \
|
||||
shift += 2; \
|
||||
else \
|
||||
{ \
|
||||
asm_fprintf (FILE, "\t%s\t%r, %r, #%d\n", \
|
||||
mi_op, this_regno, this_regno, \
|
||||
mi_delta & (0xff << shift)); \
|
||||
mi_delta &= ~(0xff << shift); \
|
||||
shift += 8; \
|
||||
} \
|
||||
} \
|
||||
fputs ("\tb\t", FILE); \
|
||||
assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
|
||||
if (NEED_PLT_RELOC) \
|
||||
fputs ("(PLT)", FILE); \
|
||||
fputc ('\n', FILE); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* A C expression whose value is RTL representing the value of the return
|
||||
address for the frame COUNT steps up from the current frame. */
|
||||
|
||||
@ -2835,8 +2734,10 @@ extern int making_const_table;
|
||||
in 26 bit mode, the condition codes must be masked out of the \
|
||||
return address. This does not apply to ARM6 and later processors \
|
||||
when running in 32 bit mode. */ \
|
||||
((!TARGET_APCS_32) ? (GEN_INT (RETURN_ADDR_MASK26)) \
|
||||
: (GEN_INT ((unsigned long)0xffffffff)))
|
||||
((!TARGET_APCS_32) ? (gen_int_mode (RETURN_ADDR_MASK26, Pmode)) \
|
||||
: (arm_arch4 || TARGET_THUMB) ? \
|
||||
(gen_int_mode ((unsigned long)0xffffffff, Pmode)) \
|
||||
: arm_gen_return_addr_mask ())
|
||||
|
||||
|
||||
/* Define the codes that are matched by predicates in arm.c */
|
||||
|
@ -59,7 +59,11 @@
|
||||
(UNSPEC_PIC_SYM 3) ; A symbol that has been treated properly for pic
|
||||
; usage, that is, we will add the pic_register
|
||||
; value to it before trying to dereference it.
|
||||
(UNSPEC_PRLG_STK 4) ; A special barrier that prevents frame accesses
|
||||
(UNSPEC_PIC_BASE 4) ; Adding the PC value to the offset to the
|
||||
; GLOBAL_OFFSET_TABLE. The operation is fully
|
||||
; described by the RTL but must be wrapped to
|
||||
; prevent combine from trying to rip it apart.
|
||||
(UNSPEC_PRLG_STK 5) ; A special barrier that prevents frame accesses
|
||||
; being scheduled before the stack adjustment insn.
|
||||
(UNSPEC_CLZ 5) ; `clz' instruction, count leading zeros (SImode):
|
||||
; operand 0 is the result,
|
||||
@ -69,6 +73,7 @@
|
||||
; instructions setting registers for EH handling
|
||||
; and stack frame generation. Operand 0 is the
|
||||
; register to "use".
|
||||
(UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
|
||||
]
|
||||
)
|
||||
|
||||
@ -179,7 +184,7 @@
|
||||
(const_string "normal"))
|
||||
|
||||
; Load scheduling, set from the arm_ld_sched variable
|
||||
; initialised by arm_override_options()
|
||||
; initialized by arm_override_options()
|
||||
(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
|
||||
|
||||
; condition codes: this one is used by final_prescan_insn to speed up
|
||||
@ -600,10 +605,10 @@
|
||||
;; Reloading and elimination of the frame pointer can
|
||||
;; sometimes cause this optimization to be missed.
|
||||
(define_peephole2
|
||||
[(set (match_operand:SI 0 "register_operand" "=l")
|
||||
(match_operand:SI 1 "const_int_operand" "M"))
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(match_operand:SI 1 "const_int_operand" ""))
|
||||
(set (match_dup 0)
|
||||
(plus:SI (match_dup 0) (match_operand:SI 2 "register_operand" "k")))]
|
||||
(plus:SI (match_dup 0) (match_operand:SI 2 "register_operand" "")))]
|
||||
"TARGET_THUMB
|
||||
&& REGNO (operands[2]) == STACK_POINTER_REGNUM
|
||||
&& (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
|
||||
@ -1857,9 +1862,9 @@
|
||||
;;; ??? This pattern is bogus. If operand3 has bits outside the range
|
||||
;;; represented by the bitfield, then this will produce incorrect results.
|
||||
;;; Somewhere, the value needs to be truncated. On targets like the m68k,
|
||||
;;; which have a real bitfield insert instruction, the truncation happens
|
||||
;;; in the bitfield insert instruction itself. Since arm does not have a
|
||||
;;; bitfield insert instruction, we would have to emit code here to truncate
|
||||
;;; which have a real bit-field insert instruction, the truncation happens
|
||||
;;; in the bit-field insert instruction itself. Since arm does not have a
|
||||
;;; bit-field insert instruction, we would have to emit code here to truncate
|
||||
;;; the value before we insert. This loses some of the advantage of having
|
||||
;;; this insv pattern, so this pattern needs to be reevalutated.
|
||||
|
||||
@ -1867,7 +1872,7 @@
|
||||
[(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
|
||||
(match_operand:SI 1 "general_operand" "")
|
||||
(match_operand:SI 2 "general_operand" ""))
|
||||
(match_operand:SI 3 "nonmemory_operand" ""))]
|
||||
(match_operand:SI 3 "reg_or_int_operand" ""))]
|
||||
"TARGET_ARM"
|
||||
"
|
||||
{
|
||||
@ -2035,7 +2040,7 @@
|
||||
"TARGET_ARM
|
||||
&& reload_completed
|
||||
&& operands[0] != operands[1]"
|
||||
[(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
|
||||
[(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
|
||||
(set (match_dup 3) (match_dup 4))]
|
||||
"
|
||||
{
|
||||
@ -2052,11 +2057,11 @@
|
||||
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
|
||||
(and:DI (not:DI (sign_extend:DI
|
||||
(match_operand:SI 2 "s_register_operand" "r,r")))
|
||||
(match_operand:DI 1 "s_register_operand" "?r,0")))]
|
||||
(match_operand:DI 1 "s_register_operand" "0,r")))]
|
||||
"TARGET_ARM"
|
||||
"#"
|
||||
"TARGET_ARM && reload_completed"
|
||||
[(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
|
||||
[(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
|
||||
(set (match_dup 3) (and:SI (not:SI
|
||||
(ashiftrt:SI (match_dup 2) (const_int 31)))
|
||||
(match_dup 4)))]
|
||||
@ -2339,11 +2344,11 @@
|
||||
; insns.
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=r")
|
||||
(ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
|
||||
(not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
|
||||
(match_operand:SI 3 "arm_rhs_operand" "rI")))
|
||||
(clobber (match_operand:SI 4 "s_register_operand" "=r"))]
|
||||
[(set (match_operand:SI 0 "s_register_operand" "")
|
||||
(ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
|
||||
(not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
|
||||
(match_operand:SI 3 "arm_rhs_operand" "")))
|
||||
(clobber (match_operand:SI 4 "s_register_operand" ""))]
|
||||
"TARGET_ARM"
|
||||
[(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
|
||||
(not:SI (match_dup 3))))
|
||||
@ -3913,7 +3918,7 @@
|
||||
;; DONE;
|
||||
;;}")
|
||||
|
||||
;; Recognise garbage generated above.
|
||||
;; Recognize garbage generated above.
|
||||
|
||||
;;(define_insn ""
|
||||
;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
|
||||
@ -4129,6 +4134,7 @@
|
||||
if ((val & (mask << i)) == val)
|
||||
break;
|
||||
|
||||
/* Shouldn't happen, but we don't want to split if the shift is zero. */
|
||||
if (i == 0)
|
||||
FAIL;
|
||||
|
||||
@ -4200,7 +4206,9 @@
|
||||
|
||||
(define_insn "pic_add_dot_plus_four"
|
||||
[(set (match_operand:SI 0 "register_operand" "+r")
|
||||
(plus:SI (match_dup 0) (const (plus:SI (pc) (const_int 4)))))
|
||||
(unspec:SI [(plus:SI (match_dup 0)
|
||||
(const (plus:SI (pc) (const_int 4))))]
|
||||
UNSPEC_PIC_BASE))
|
||||
(use (label_ref (match_operand 1 "" "")))]
|
||||
"TARGET_THUMB && flag_pic"
|
||||
"*
|
||||
@ -4213,7 +4221,9 @@
|
||||
|
||||
(define_insn "pic_add_dot_plus_eight"
|
||||
[(set (match_operand:SI 0 "register_operand" "+r")
|
||||
(plus:SI (match_dup 0) (const (plus:SI (pc) (const_int 8)))))
|
||||
(unspec:SI [(plus:SI (match_dup 0)
|
||||
(const (plus:SI (pc) (const_int 8))))]
|
||||
UNSPEC_PIC_BASE))
|
||||
(use (label_ref (match_operand 1 "" "")))]
|
||||
"TARGET_ARM && flag_pic"
|
||||
"*
|
||||
@ -4417,6 +4427,14 @@
|
||||
emit_insn (gen_movsi (reg, GEN_INT (val)));
|
||||
operands[1] = gen_lowpart (HImode, reg);
|
||||
}
|
||||
else if (arm_arch4 && !no_new_pseudos && optimize > 0
|
||||
&& GET_CODE (operands[1]) == MEM)
|
||||
{
|
||||
rtx reg = gen_reg_rtx (SImode);
|
||||
|
||||
emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
|
||||
operands[1] = gen_lowpart (HImode, reg);
|
||||
}
|
||||
else if (!arm_arch4)
|
||||
{
|
||||
/* Note: We do not have to worry about TARGET_MMU_TRAPS
|
||||
@ -4673,7 +4691,7 @@
|
||||
"
|
||||
)
|
||||
|
||||
;; Pattern to recognise insn generated default case above
|
||||
;; Pattern to recognize insn generated default case above
|
||||
(define_insn "*movhi_insn_arch4"
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
|
||||
(match_operand:HI 1 "general_operand" "rI,K,r,m"))]
|
||||
@ -4814,9 +4832,16 @@
|
||||
emit_insn (gen_movsi (reg, operands[1]));
|
||||
operands[1] = gen_lowpart (QImode, reg);
|
||||
}
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
operands[1] = force_reg (QImode, operands[1]);
|
||||
}
|
||||
if (GET_CODE (operands[1]) == MEM && optimize > 0)
|
||||
{
|
||||
rtx reg = gen_reg_rtx (SImode);
|
||||
|
||||
emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
|
||||
operands[1] = gen_lowpart (QImode, reg);
|
||||
}
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
operands[1] = force_reg (QImode, operands[1]);
|
||||
}
|
||||
}
|
||||
else /* TARGET_THUMB */
|
||||
{
|
||||
@ -6014,7 +6039,7 @@
|
||||
if (arm_ccfsm_state != 0)
|
||||
abort ();
|
||||
|
||||
return \"bvs\\t%l0;beq\\t%l0\";
|
||||
return \"bvs\\t%l0\;beq\\t%l0\";
|
||||
"
|
||||
[(set_attr "conds" "jump_clob")
|
||||
(set_attr "length" "8")]
|
||||
@ -6031,7 +6056,7 @@
|
||||
if (arm_ccfsm_state != 0)
|
||||
abort ();
|
||||
|
||||
return \"bmi\\t%l0;bgt\\t%l0\";
|
||||
return \"bmi\\t%l0\;bgt\\t%l0\";
|
||||
"
|
||||
[(set_attr "conds" "jump_clob")
|
||||
(set_attr "length" "8")]
|
||||
@ -6066,7 +6091,7 @@
|
||||
if (arm_ccfsm_state != 0)
|
||||
abort ();
|
||||
|
||||
return \"bmi\\t%l0;bgt\\t%l0\";
|
||||
return \"bmi\\t%l0\;bgt\\t%l0\";
|
||||
"
|
||||
[(set_attr "conds" "jump_clob")
|
||||
(set_attr "length" "8")]
|
||||
@ -6083,7 +6108,7 @@
|
||||
if (arm_ccfsm_state != 0)
|
||||
abort ();
|
||||
|
||||
return \"bvs\\t%l0;beq\\t%l0\";
|
||||
return \"bvs\\t%l0\;beq\\t%l0\";
|
||||
"
|
||||
[(set_attr "conds" "jump_clob")
|
||||
(set_attr "length" "8")]
|
||||
@ -6288,8 +6313,12 @@
|
||||
"
|
||||
{
|
||||
enum rtx_code code = GET_CODE (operands[1]);
|
||||
rtx ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
|
||||
rtx ccreg;
|
||||
|
||||
if (code == UNEQ || code == LTGT)
|
||||
FAIL;
|
||||
|
||||
ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
|
||||
operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
|
||||
}"
|
||||
)
|
||||
@ -6305,6 +6334,9 @@
|
||||
enum rtx_code code = GET_CODE (operands[1]);
|
||||
rtx ccreg;
|
||||
|
||||
if (code == UNEQ || code == LTGT)
|
||||
FAIL;
|
||||
|
||||
/* When compiling for SOFT_FLOAT, ensure both arms are in registers.
|
||||
Otherwise, ensure it is a valid FP add operand */
|
||||
if ((!TARGET_HARD_FLOAT)
|
||||
@ -6325,8 +6357,12 @@
|
||||
"
|
||||
{
|
||||
enum rtx_code code = GET_CODE (operands[1]);
|
||||
rtx ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
|
||||
rtx ccreg;
|
||||
|
||||
if (code == UNEQ || code == LTGT)
|
||||
FAIL;
|
||||
|
||||
ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
|
||||
operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
|
||||
}"
|
||||
)
|
||||
@ -6665,8 +6701,8 @@
|
||||
(define_expand "sibcall"
|
||||
[(parallel [(call (match_operand 0 "memory_operand" "")
|
||||
(match_operand 1 "general_operand" ""))
|
||||
(use (match_operand 2 "" ""))
|
||||
(use (reg:SI LR_REGNUM))])]
|
||||
(return)
|
||||
(use (match_operand 2 "" ""))])]
|
||||
"TARGET_ARM"
|
||||
"
|
||||
{
|
||||
@ -6679,8 +6715,8 @@
|
||||
[(parallel [(set (match_operand 0 "register_operand" "")
|
||||
(call (match_operand 1 "memory_operand" "")
|
||||
(match_operand 2 "general_operand" "")))
|
||||
(use (match_operand 3 "" ""))
|
||||
(use (reg:SI LR_REGNUM))])]
|
||||
(return)
|
||||
(use (match_operand 3 "" ""))])]
|
||||
"TARGET_ARM"
|
||||
"
|
||||
{
|
||||
@ -6692,8 +6728,8 @@
|
||||
(define_insn "*sibcall_insn"
|
||||
[(call (mem:SI (match_operand:SI 0 "" "X"))
|
||||
(match_operand 1 "" ""))
|
||||
(use (match_operand 2 "" ""))
|
||||
(use (reg:SI LR_REGNUM))]
|
||||
(return)
|
||||
(use (match_operand 2 "" ""))]
|
||||
"TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
|
||||
"*
|
||||
return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
|
||||
@ -6705,8 +6741,8 @@
|
||||
[(set (match_operand 0 "s_register_operand" "=r,f")
|
||||
(call (mem:SI (match_operand:SI 1 "" "X,X"))
|
||||
(match_operand 2 "" "")))
|
||||
(use (match_operand 3 "" ""))
|
||||
(use (reg:SI LR_REGNUM))]
|
||||
(return)
|
||||
(use (match_operand 3 "" ""))]
|
||||
"TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
|
||||
"*
|
||||
return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
|
||||
@ -6725,7 +6761,7 @@
|
||||
arm_ccfsm_state += 2;
|
||||
return \"\";
|
||||
}
|
||||
return output_return_instruction (NULL, TRUE, FALSE);
|
||||
return output_return_instruction (const_true_rtx, TRUE, FALSE);
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "predicable" "yes")]
|
||||
@ -6771,6 +6807,33 @@
|
||||
(set_attr "type" "load")]
|
||||
)
|
||||
|
||||
;; Generate a sequence of instructions to determine if the processor is
|
||||
;; in 26-bit or 32-bit mode, and return the appropriate return address
|
||||
;; mask.
|
||||
|
||||
(define_expand "return_addr_mask"
|
||||
[(set (match_dup 1)
|
||||
(compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
|
||||
(const_int 0)))
|
||||
(set (match_operand:SI 0 "s_register_operand" "")
|
||||
(if_then_else:SI (eq (match_dup 1) (const_int 0))
|
||||
(const_int -1)
|
||||
(const_int 67108860)))] ; 0x03fffffc
|
||||
"TARGET_ARM"
|
||||
"
|
||||
operands[1] = gen_rtx_REG (CC_NOOVmode, 24);
|
||||
")
|
||||
|
||||
(define_insn "*check_arch2"
|
||||
[(set (match_operand:CC_NOOV 0 "cc_register" "")
|
||||
(compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
|
||||
(const_int 0)))]
|
||||
"TARGET_ARM"
|
||||
"teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "conds" "set")]
|
||||
)
|
||||
|
||||
;; Call subroutine returning any type.
|
||||
|
||||
(define_expand "untyped_call"
|
||||
@ -7015,139 +7078,6 @@
|
||||
]
|
||||
)
|
||||
|
||||
;; These variants of the above insns can occur if the first operand is the
|
||||
;; frame pointer and we eliminate that. This is a kludge, but there doesn't
|
||||
;; seem to be a way around it. Most of the predicates have to be null
|
||||
;; because the format can be generated part way through reload, so
|
||||
;; if we don't match it as soon as it becomes available, reload doesn't know
|
||||
;; how to reload pseudos that haven't got hard registers; the constraints will
|
||||
;; sort everything out.
|
||||
|
||||
(define_insn "*reload_mulsi3"
|
||||
[(set (match_operand:SI 0 "" "=&r")
|
||||
(plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
|
||||
[(match_operand:SI 3 "" "r")
|
||||
(match_operand:SI 4 "" "rM")])
|
||||
(match_operand:SI 2 "" "r"))
|
||||
(match_operand:SI 1 "const_int_operand" "n")))]
|
||||
"TARGET_ARM && reload_in_progress"
|
||||
"*
|
||||
output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
|
||||
operands[2] = operands[1];
|
||||
operands[1] = operands[0];
|
||||
return output_add_immediate (operands);
|
||||
"
|
||||
[
|
||||
; we have no idea how long the add_immediate is, it could be up to 4.
|
||||
(set_attr "length" "20")]
|
||||
)
|
||||
|
||||
(define_insn "*reload_mulsi_compare0"
|
||||
[(set (reg:CC_NOOV CC_REGNUM)
|
||||
(compare:CC_NOOV (plus:SI
|
||||
(plus:SI
|
||||
(match_operator:SI 5 "shift_operator"
|
||||
[(match_operand:SI 3 "" "r")
|
||||
(match_operand:SI 4 "" "rM")])
|
||||
(match_operand:SI 1 "" "r"))
|
||||
(match_operand:SI 2 "const_int_operand" "n"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:SI 0 "" "=&r")
|
||||
(plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
|
||||
(match_dup 1))
|
||||
(match_dup 2)))]
|
||||
"TARGET_ARM && reload_in_progress && !arm_is_xscale"
|
||||
"*
|
||||
output_add_immediate (operands);
|
||||
return \"add%?s\\t%0, %0, %3%S5\";
|
||||
"
|
||||
[(set_attr "conds" "set")
|
||||
(set_attr "shift" "3")
|
||||
(set_attr "length" "20")]
|
||||
)
|
||||
|
||||
(define_insn "*reload_mulsi_compare0_scratch"
|
||||
[(set (reg:CC_NOOV CC_REGNUM)
|
||||
(compare:CC_NOOV (plus:SI
|
||||
(plus:SI
|
||||
(match_operator:SI 5 "shift_operator"
|
||||
[(match_operand:SI 3 "" "r")
|
||||
(match_operand:SI 4 "" "rM")])
|
||||
(match_operand:SI 1 "" "r"))
|
||||
(match_operand:SI 2 "const_int_operand" "n"))
|
||||
(const_int 0)))
|
||||
(clobber (match_scratch:SI 0 "=&r"))]
|
||||
"TARGET_ARM && reload_in_progress && !arm_is_xscale"
|
||||
"*
|
||||
output_add_immediate (operands);
|
||||
return \"add%?s\\t%0, %0, %3%S5\";
|
||||
"
|
||||
[(set_attr "conds" "set")
|
||||
(set_attr "shift" "3")
|
||||
(set_attr "length" "20")]
|
||||
)
|
||||
|
||||
;; These are similar, but are needed when the mla pattern contains the
|
||||
;; eliminated register as operand 3.
|
||||
|
||||
(define_insn "*reload_muladdsi"
|
||||
[(set (match_operand:SI 0 "" "=&r,&r")
|
||||
(plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
|
||||
(match_operand:SI 2 "" "r,r"))
|
||||
(match_operand:SI 3 "" "r,r"))
|
||||
(match_operand:SI 4 "const_int_operand" "n,n")))]
|
||||
"TARGET_ARM && reload_in_progress"
|
||||
"*
|
||||
output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
|
||||
operands[2] = operands[4];
|
||||
operands[1] = operands[0];
|
||||
return output_add_immediate (operands);
|
||||
"
|
||||
[(set_attr "length" "20")
|
||||
(set_attr "type" "mult")]
|
||||
)
|
||||
|
||||
(define_insn "*reload_muladdsi_compare0"
|
||||
[(set (reg:CC_NOOV CC_REGNUM)
|
||||
(compare:CC_NOOV (plus:SI (plus:SI (mult:SI
|
||||
(match_operand:SI 3 "" "r")
|
||||
(match_operand:SI 4 "" "r"))
|
||||
(match_operand:SI 1 "" "r"))
|
||||
(match_operand:SI 2 "const_int_operand" "n"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:SI 0 "" "=&r")
|
||||
(plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
|
||||
(match_dup 2)))]
|
||||
"TARGET_ARM && reload_in_progress && !arm_is_xscale"
|
||||
"*
|
||||
output_add_immediate (operands);
|
||||
output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
|
||||
return \"\";
|
||||
"
|
||||
[(set_attr "length" "20")
|
||||
(set_attr "conds" "set")
|
||||
(set_attr "type" "mult")]
|
||||
)
|
||||
|
||||
(define_insn "*reload_muladdsi_compare0_scratch"
|
||||
[(set (reg:CC_NOOV CC_REGNUM)
|
||||
(compare:CC_NOOV (plus:SI (plus:SI (mult:SI
|
||||
(match_operand:SI 3 "" "r")
|
||||
(match_operand:SI 4 "" "r"))
|
||||
(match_operand:SI 1 "" "r"))
|
||||
(match_operand:SI 2 "const_int_operand" "n"))
|
||||
(const_int 0)))
|
||||
(clobber (match_scratch:SI 0 "=&r"))]
|
||||
"TARGET_ARM && reload_in_progress"
|
||||
"*
|
||||
output_add_immediate (operands);
|
||||
return \"mla%?s\\t%0, %3, %4, %0\";
|
||||
"
|
||||
[(set_attr "length" "20")
|
||||
(set_attr "conds" "set")
|
||||
(set_attr "type" "mult")]
|
||||
)
|
||||
|
||||
|
||||
|
||||
(define_insn "*and_scc"
|
||||
@ -8506,7 +8436,7 @@
|
||||
; We must watch to see that the source/destination register isn't also the
|
||||
; same as the base address register, and that if the index is a register,
|
||||
; that it is not the same as the base address register. In such cases the
|
||||
; instruction that we would generate would have UNPREDICTABLE behaviour so
|
||||
; instruction that we would generate would have UNPREDICTABLE behavior so
|
||||
; we cannot use it.
|
||||
|
||||
(define_peephole
|
||||
@ -8759,18 +8689,27 @@
|
||||
"
|
||||
)
|
||||
|
||||
;; Note - although unspec_volatile's USE all hard registers,
|
||||
;; USEs are ignored after relaod has completed. Thus we need
|
||||
;; to add an unspec of the link register to ensure that flow
|
||||
;; does not think that it is unused by the sibcall branch that
|
||||
;; will replace the standard function epilogue.
|
||||
(define_insn "sibcall_epilogue"
|
||||
[(unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)]
|
||||
[(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
|
||||
(unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
|
||||
"TARGET_ARM"
|
||||
"*
|
||||
output_asm_insn (\"%@ Sibcall epilogue\", operands);
|
||||
if (USE_RETURN_INSN (FALSE))
|
||||
return output_return_instruction (NULL, FALSE, FALSE);
|
||||
return output_return_instruction (const_true_rtx, FALSE, FALSE);
|
||||
return arm_output_epilogue (FALSE);
|
||||
"
|
||||
;; Length is absolute worst case
|
||||
[(set_attr "length" "44")
|
||||
(set_attr "type" "block")]
|
||||
(set_attr "type" "block")
|
||||
;; We don't clobber the conditions, but the potential length of this
|
||||
;; operation is sufficient to make conditionalizing the sequence
|
||||
;; unlikely to be profitable.
|
||||
(set_attr "conds" "clob")]
|
||||
)
|
||||
|
||||
(define_insn "*epilogue_insns"
|
||||
@ -8784,7 +8723,11 @@
|
||||
"
|
||||
; Length is absolute worst case
|
||||
[(set_attr "length" "44")
|
||||
(set_attr "type" "block")]
|
||||
(set_attr "type" "block")
|
||||
;; We don't clobber the conditions, but the potential length of this
|
||||
;; operation is sufficient to make conditionalizing the sequence
|
||||
;; unlikely to be profitable.
|
||||
(set_attr "conds" "clob")]
|
||||
)
|
||||
|
||||
(define_expand "eh_epilogue"
|
||||
@ -9018,6 +8961,16 @@
|
||||
[(set_attr "type" "store4")]
|
||||
)
|
||||
|
||||
(define_insn "stack_tie"
|
||||
[(set (mem:BLK (scratch))
|
||||
(unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
|
||||
(match_operand:SI 1 "s_register_operand" "r")]
|
||||
UNSPEC_PRLG_STK))]
|
||||
""
|
||||
""
|
||||
[(set_attr "length" "0")]
|
||||
)
|
||||
|
||||
;; Similarly for the floating point registers
|
||||
(define_insn "*push_fp_multi"
|
||||
[(match_parallel 2 "multi_register_push"
|
||||
@ -9090,9 +9043,9 @@
|
||||
{
|
||||
case MODE_FLOAT:
|
||||
{
|
||||
union real_extract u;
|
||||
memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
|
||||
assemble_real (u.d, GET_MODE (operands[0]), BITS_PER_WORD);
|
||||
REAL_VALUE_TYPE r;
|
||||
REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
|
||||
assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -9114,9 +9067,9 @@
|
||||
{
|
||||
case MODE_FLOAT:
|
||||
{
|
||||
union real_extract u;
|
||||
memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
|
||||
assemble_real (u.d, GET_MODE (operands[0]), BITS_PER_WORD);
|
||||
REAL_VALUE_TYPE r;
|
||||
REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
|
||||
assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler.
|
||||
For ARM with COFF object format.
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Doug Evans (devans@cygnus.com).
|
||||
|
||||
@ -40,7 +40,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#endif
|
||||
|
||||
/* This is COFF, but prefer stabs. */
|
||||
#define SDB_DEBUGGING_INFO
|
||||
#define SDB_DEBUGGING_INFO 1
|
||||
|
||||
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
|
||||
|
||||
@ -76,42 +76,12 @@ Boston, MA 02111-1307, USA. */
|
||||
more efficient, but for Thumb it's better to put them out of band. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION (TARGET_ARM)
|
||||
|
||||
#undef READONLY_DATA_SECTION
|
||||
#define READONLY_DATA_SECTION rdata_section
|
||||
#undef RDATA_SECTION_ASM_OP
|
||||
#define RDATA_SECTION_ASM_OP "\t.section .rdata"
|
||||
#undef READONLY_DATA_SECTION_ASM_OP
|
||||
#define READONLY_DATA_SECTION_ASM_OP "\t.section .rdata"
|
||||
#undef CTORS_SECTION_ASM_OP
|
||||
#define CTORS_SECTION_ASM_OP "\t.section .ctors,\"x\""
|
||||
#undef DTORS_SECTION_ASM_OP
|
||||
#define DTORS_SECTION_ASM_OP "\t.section .dtors,\"x\""
|
||||
|
||||
/* A list of other sections which the compiler might be "in" at any
|
||||
given time. */
|
||||
|
||||
#undef EXTRA_SECTIONS
|
||||
#define EXTRA_SECTIONS SUBTARGET_EXTRA_SECTIONS in_rdata
|
||||
|
||||
#define SUBTARGET_EXTRA_SECTIONS
|
||||
|
||||
/* A list of extra section function definitions. */
|
||||
|
||||
#undef EXTRA_SECTION_FUNCTIONS
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
RDATA_SECTION_FUNCTION \
|
||||
SUBTARGET_EXTRA_SECTION_FUNCTIONS
|
||||
|
||||
#define SUBTARGET_EXTRA_SECTION_FUNCTIONS
|
||||
|
||||
#define RDATA_SECTION_FUNCTION \
|
||||
void \
|
||||
rdata_section () \
|
||||
{ \
|
||||
if (in_section != in_rdata) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", RDATA_SECTION_ASM_OP); \
|
||||
in_section = in_rdata; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Support the ctors/dtors sections for g++. */
|
||||
|
||||
|
@ -39,6 +39,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm7tdmi
|
||||
#endif
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-D__arm__ -D__CONIX__ -D__ELF__"
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define ("__CONIX__"); \
|
||||
builtin_define ("__ELF__"); \
|
||||
} while (0)
|
||||
|
@ -35,7 +35,7 @@
|
||||
# .init sections. Users may put any desired instructions in those
|
||||
# sections.
|
||||
|
||||
# Note - this macro is complimented by the FUNC_END macro
|
||||
# Note - this macro is complemented by the FUNC_END macro
|
||||
# in crtn.asm. If you change this macro you must also change
|
||||
# that macro match.
|
||||
.macro FUNC_START
|
||||
|
@ -35,7 +35,7 @@
|
||||
# fact return. Users may put any desired instructions in those sections.
|
||||
# This file is the last thing linked into any executable.
|
||||
|
||||
# Note - this macro is complimented by the FUNC_START macro
|
||||
# Note - this macro is complemented by the FUNC_START macro
|
||||
# in crti.asm. If you change this macro you must also change
|
||||
# that macro match.
|
||||
#
|
||||
|
@ -36,21 +36,27 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef SUBTARGET_EXTRA_SPECS
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC },
|
||||
{ "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC }, \
|
||||
{ "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC },
|
||||
#endif
|
||||
|
||||
#ifndef SUBTARGET_EXTRA_ASM_SPEC
|
||||
#define SUBTARGET_EXTRA_ASM_SPEC ""
|
||||
#endif
|
||||
|
||||
#ifndef SUBTARGET_ASM_FLOAT_SPEC
|
||||
#define SUBTARGET_ASM_FLOAT_SPEC "\
|
||||
%{mapcs-float:-mfloat} %{msoft-float:-mno-fpu}"
|
||||
#endif
|
||||
|
||||
#ifndef ASM_SPEC
|
||||
#define ASM_SPEC "\
|
||||
%{mbig-endian:-EB} \
|
||||
%{mcpu=*:-m%*} \
|
||||
%{march=*:-m%*} \
|
||||
%{mlittle-endian:-EL} \
|
||||
%{mcpu=*:-mcpu=%*} \
|
||||
%{march=*:-march=%*} \
|
||||
%{mapcs-*:-mapcs-%*} \
|
||||
%{mapcs-float:-mfloat} \
|
||||
%{msoft-float:-mno-fpu} \
|
||||
%(subtarget_asm_float_spec) \
|
||||
%{mthumb-interwork:-mthumb-interwork} \
|
||||
%(subtarget_extra_asm_spec)"
|
||||
#endif
|
||||
@ -58,22 +64,18 @@ Boston, MA 02111-1307, USA. */
|
||||
/* The ARM uses @ are a comment character so we need to redefine
|
||||
TYPE_OPERAND_FMT. */
|
||||
#undef TYPE_OPERAND_FMT
|
||||
#define TYPE_OPERAND_FMT "%s"
|
||||
#define TYPE_OPERAND_FMT "%%%s"
|
||||
|
||||
/* We might need a ARM specific header to function declarations. */
|
||||
#undef ASM_DECLARE_FUNCTION_NAME
|
||||
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
ARM_DECLARE_FUNCTION_NAME (FILE, NAME, DECL); \
|
||||
fprintf (FILE, "%s", TYPE_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
putc (',', FILE); \
|
||||
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
|
||||
putc ('\n', FILE); \
|
||||
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
|
||||
ASM_OUTPUT_LABEL(FILE, NAME); \
|
||||
} \
|
||||
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
ARM_DECLARE_FUNCTION_NAME (FILE, NAME, DECL); \
|
||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
|
||||
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
|
||||
ASM_OUTPUT_LABEL(FILE, NAME); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* We might need an ARM specific trailer for function declarations. */
|
||||
@ -83,20 +85,7 @@ Boston, MA 02111-1307, USA. */
|
||||
{ \
|
||||
ARM_DECLARE_FUNCTION_SIZE (FILE, FNAME, DECL); \
|
||||
if (!flag_inhibit_size_directive) \
|
||||
{ \
|
||||
char label[256]; \
|
||||
static int labelno; \
|
||||
labelno ++; \
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
|
||||
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
|
||||
fprintf (FILE, "%s", SIZE_ASM_OP); \
|
||||
assemble_name (FILE, (FNAME)); \
|
||||
fprintf (FILE, ","); \
|
||||
assemble_name (FILE, label); \
|
||||
fprintf (FILE, "-"); \
|
||||
assemble_name (FILE, (FNAME)); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -108,7 +97,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION (TARGET_ARM)
|
||||
|
||||
#ifndef LINK_SPEC
|
||||
#define LINK_SPEC "%{mbig-endian:-EB} -X"
|
||||
#define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
|
||||
#endif
|
||||
|
||||
/* Run-time Target Specification. */
|
||||
|
@ -41,9 +41,6 @@ Boston, MA 02111-1307, USA. */
|
||||
/* We use the GCC defaults here. */
|
||||
#undef WCHAR_TYPE
|
||||
|
||||
#undef WCHAR_UNSIGNED
|
||||
#define WCHAR_UNSIGNED 0
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
|
@ -48,9 +48,9 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Now we define the strings used to build the spec file. */
|
||||
#define LIB_SPEC \
|
||||
"%{shared: -lc} \
|
||||
%{!shared: %{pthread:-lpthread} \
|
||||
%{profile:-lc_p} %{!profile: -lc}}"
|
||||
"%{pthread:-lpthread} \
|
||||
%{shared:-lc} \
|
||||
%{!shared:%{profile:-lc_p}%{!profile:-lc}}"
|
||||
|
||||
#define LIBGCC_SPEC "%{msoft-float:-lfloat} -lgcc"
|
||||
|
||||
@ -89,13 +89,15 @@ Boston, MA 02111-1307, USA. */
|
||||
%{mbig-endian:-EB}" \
|
||||
SUBTARGET_EXTRA_LINK_SPEC
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-Dunix -D__gnu_linux__ -Dlinux -D__ELF__ \
|
||||
-Asystem=unix -Asystem=posix"
|
||||
|
||||
/* Allow #sccs in preprocessor. */
|
||||
#define SCCS_DIRECTIVE
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define_std ("unix"); \
|
||||
builtin_define_std ("linux"); \
|
||||
builtin_define ("__gnu_linux__"); \
|
||||
builtin_define ("__ELF__"); \
|
||||
builtin_assert ("system=unix"); \
|
||||
builtin_assert ("system=posix"); \
|
||||
} while (0)
|
||||
|
||||
/* This is how we tell the assembler that two symbols have the same value. */
|
||||
#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
|
||||
|
@ -45,7 +45,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE BITS_PER_WORD
|
||||
|
||||
/* Emit code to set up a trampoline and synchronise the caches. */
|
||||
/* Emit code to set up a trampoline and synchronize the caches. */
|
||||
#undef INITIALIZE_TRAMPOLINE
|
||||
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
|
||||
{ \
|
||||
|
177
contrib/gcc/config/arm/netbsd-elf.h
Normal file
177
contrib/gcc/config/arm/netbsd-elf.h
Normal file
@ -0,0 +1,177 @@
|
||||
/* Definitions of target machine for GNU compiler, NetBSD/arm ELF version.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Contributed by Wasabi Systems, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Run-time Target Specification. */
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fputs (" (NetBSD/arm ELF)", stderr);
|
||||
|
||||
/* This is used in ASM_FILE_START. */
|
||||
#undef ARM_OS_NAME
|
||||
#define ARM_OS_NAME "NetBSD"
|
||||
|
||||
/* arm.h defaults to ARM6 CPU. */
|
||||
|
||||
/* This defaults us to little-endian. */
|
||||
#ifndef TARGET_ENDIAN_DEFAULT
|
||||
#define TARGET_ENDIAN_DEFAULT 0
|
||||
#endif
|
||||
|
||||
#undef MULTILIB_DEFAULTS
|
||||
|
||||
/* Default it to use ATPCS with soft-VFP. */
|
||||
#undef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT \
|
||||
(ARM_FLAG_APCS_32 \
|
||||
| ARM_FLAG_SOFT_FLOAT \
|
||||
| ARM_FLAG_APCS_FRAME \
|
||||
| ARM_FLAG_ATPCS \
|
||||
| ARM_FLAG_VFP \
|
||||
| ARM_FLAG_MMU_TRAPS \
|
||||
| TARGET_ENDIAN_DEFAULT)
|
||||
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
NETBSD_OS_CPP_BUILTINS_ELF(); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#undef SUBTARGET_CPP_SPEC
|
||||
#define SUBTARGET_CPP_SPEC NETBSD_CPP_SPEC
|
||||
|
||||
#undef SUBTARGET_EXTRA_ASM_SPEC
|
||||
#define SUBTARGET_EXTRA_ASM_SPEC \
|
||||
"-matpcs %{fpic:-k} %{fPIC:-k}"
|
||||
|
||||
/* Default floating point model is soft-VFP.
|
||||
FIXME: -mhard-float currently implies FPA. */
|
||||
#undef SUBTARGET_ASM_FLOAT_SPEC
|
||||
#define SUBTARGET_ASM_FLOAT_SPEC \
|
||||
"%{mhard-float:-mfpu=fpa} \
|
||||
%{msoft-float:-mfpu=softvfp} \
|
||||
%{!mhard-float: \
|
||||
%{!msoft-float:-mfpu=softvfp}}"
|
||||
|
||||
#undef SUBTARGET_EXTRA_SPECS
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC }, \
|
||||
{ "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC }, \
|
||||
{ "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
|
||||
{ "netbsd_entry_point", NETBSD_ENTRY_POINT },
|
||||
|
||||
#define NETBSD_ENTRY_POINT "__start"
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC \
|
||||
"-X %{mbig-endian:-EB} %{mlittle-endian:-EL} \
|
||||
%(netbsd_link_spec)"
|
||||
|
||||
/* Make GCC agree with <machine/ansi.h>. */
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "long unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "long int"
|
||||
|
||||
/* We don't have any limit on the length as out debugger is GDB. */
|
||||
#undef DBX_CONTIN_LENGTH
|
||||
|
||||
/* NetBSD does its profiling differently to the Acorn compiler. We
|
||||
don't need a word following the mcount call; and to skip it
|
||||
requires either an assembly stub or use of fomit-frame-pointer when
|
||||
compiling the profiling functions. Since we break Acorn CC
|
||||
compatibility below a little more won't hurt. */
|
||||
|
||||
#undef ARM_FUNCTION_PROFILER
|
||||
#define ARM_FUNCTION_PROFILER(STREAM,LABELNO) \
|
||||
{ \
|
||||
asm_fprintf (STREAM, "\tmov\t%Rip, %Rlr\n"); \
|
||||
asm_fprintf (STREAM, "\tbl\t__mcount%s\n", \
|
||||
NEED_PLT_RELOC ? "(PLT)" : ""); \
|
||||
}
|
||||
|
||||
/* VERY BIG NOTE: Change of structure alignment for NetBSD/arm.
|
||||
There are consequences you should be aware of...
|
||||
|
||||
Normally GCC/arm uses a structure alignment of 32 for compatibility
|
||||
with armcc. This means that structures are padded to a word
|
||||
boundary. However this causes problems with bugged NetBSD kernel
|
||||
code (possibly userland code as well - I have not checked every
|
||||
binary). The nature of this bugged code is to rely on sizeof()
|
||||
returning the correct size of various structures rounded to the
|
||||
nearest byte (SCSI and ether code are two examples, the vm system
|
||||
is another). This code breaks when the structure alignment is 32
|
||||
as sizeof() will report a word=rounded size. By changing the
|
||||
structure alignment to 8. GCC will conform to what is expected by
|
||||
NetBSD.
|
||||
|
||||
This has several side effects that should be considered.
|
||||
1. Structures will only be aligned to the size of the largest member.
|
||||
i.e. structures containing only bytes will be byte aligned.
|
||||
structures containing shorts will be half word alinged.
|
||||
structures containing ints will be word aligned.
|
||||
|
||||
This means structures should be padded to a word boundary if
|
||||
alignment of 32 is required for byte structures etc.
|
||||
|
||||
2. A potential performance penalty may exist if strings are no longer
|
||||
word aligned. GCC will not be able to use word load/stores to copy
|
||||
short strings.
|
||||
|
||||
This modification is not encouraged but with the present state of the
|
||||
NetBSD source tree it is currently the only solution that meets the
|
||||
requirements. */
|
||||
|
||||
#undef DEFAULT_STRUCTURE_SIZE_BOUNDARY
|
||||
#define DEFAULT_STRUCTURE_SIZE_BOUNDARY 8
|
||||
|
||||
/* Emit code to set up a trampoline and synchronize the caches. */
|
||||
#undef INITIALIZE_TRAMPOLINE
|
||||
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
|
||||
do \
|
||||
{ \
|
||||
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 8)), \
|
||||
(CXT)); \
|
||||
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 12)), \
|
||||
(FNADDR)); \
|
||||
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"), \
|
||||
0, VOIDmode, 2, TRAMP, Pmode, \
|
||||
plus_constant (TRAMP, TRAMPOLINE_SIZE), Pmode); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Clear the instruction cache from `BEG' to `END'. This makes a
|
||||
call to the ARM_SYNC_ICACHE architecture specific syscall. */
|
||||
#define CLEAR_INSN_CACHE(BEG, END) \
|
||||
do \
|
||||
{ \
|
||||
extern int sysarch(int number, void *args); \
|
||||
struct \
|
||||
{ \
|
||||
unsigned int addr; \
|
||||
int len; \
|
||||
} s; \
|
||||
s.addr = (unsigned int)(BEG); \
|
||||
s.len = (END) - (BEG); \
|
||||
(void) sysarch (0, &s); \
|
||||
} \
|
||||
while (0)
|
@ -44,16 +44,22 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Some defines for CPP.
|
||||
arm32 is the NetBSD port name, so we always define arm32 and __arm32__. */
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "\
|
||||
-Dunix -Driscbsd -Darm32 -D__arm32__ -D__arm__ -D__NetBSD__ \
|
||||
-Asystem=unix -Asystem=NetBSD"
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
NETBSD_OS_CPP_BUILTINS_AOUT(); \
|
||||
builtin_define_std ("arm32"); \
|
||||
builtin_define_std ("unix"); \
|
||||
builtin_define_std ("riscbsd"); \
|
||||
} while (0)
|
||||
|
||||
#undef SUBTARGET_EXTRA_SPECS
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "netbsd_cpp_spec", NETBSD_CPP_SPEC }, \
|
||||
{ "netbsd_link_spec", NETBSD_LINK_SPEC_AOUT },
|
||||
|
||||
/* Define _POSIX_SOURCE if necessary. */
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "\
|
||||
%(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) %(cpp_endian) \
|
||||
%{posix:-D_POSIX_SOURCE} \
|
||||
%(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) %(cpp_endian) %(netbsd_cpp_spec) \
|
||||
"
|
||||
|
||||
/* Because TARGET_DEFAULT sets ARM_FLAG_APCS_32 */
|
||||
@ -66,10 +72,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Pass -X to the linker so that it will strip symbols starting with 'L' */
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC "\
|
||||
-X %{!shared:%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{R*} \
|
||||
%{static:-Bstatic}} %{shared} %{assert*} \
|
||||
"
|
||||
#define LINK_SPEC "-X %(netbsd_link_spec)"
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
@ -77,7 +80,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#define HANDLE_SYSV_PRAGMA
|
||||
#define HANDLE_SYSV_PRAGMA 1
|
||||
|
||||
/* We don't have any limit on the length as out debugger is GDB. */
|
||||
#undef DBX_CONTIN_LENGTH
|
||||
@ -142,3 +145,30 @@ Boston, MA 02111-1307, USA. */
|
||||
requirements. */
|
||||
#undef DEFAULT_STRUCTURE_SIZE_BOUNDARY
|
||||
#define DEFAULT_STRUCTURE_SIZE_BOUNDARY 8
|
||||
|
||||
/* Emit code to set up a trampoline and synchronize the caches. */
|
||||
#undef INITIALIZE_TRAMPOLINE
|
||||
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
|
||||
{ \
|
||||
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 8)), \
|
||||
(CXT)); \
|
||||
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 12)), \
|
||||
(FNADDR)); \
|
||||
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"), \
|
||||
0, VOIDmode, 2, TRAMP, Pmode, \
|
||||
plus_constant (TRAMP, TRAMPOLINE_SIZE), Pmode); \
|
||||
}
|
||||
|
||||
/* Clear the instruction cache from `BEG' to `END'. This makes a
|
||||
call to the ARM32_SYNC_ICACHE architecture specific syscall. */
|
||||
#define CLEAR_INSN_CACHE(BEG, END) \
|
||||
{ \
|
||||
extern int sysarch(int number, void *args); \
|
||||
struct { \
|
||||
unsigned int addr; \
|
||||
int len; \
|
||||
} s; \
|
||||
s.addr = (unsigned int)(BEG); \
|
||||
s.len = (END) - (BEG); \
|
||||
(void)sysarch(0, &s); \
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Routines for GCC for ARM/pe.
|
||||
Copyright (C) 1995, 1996, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Doug Evans (dje@cygnus.com).
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
extern int current_function_anonymous_args;
|
||||
|
||||
|
||||
/* Return non-zero if DECL is a dllexport'd object. */
|
||||
/* Return nonzero if DECL is a dllexport'd object. */
|
||||
|
||||
tree current_class_type; /* FIXME */
|
||||
|
||||
@ -52,7 +52,7 @@ arm_dllexport_p (decl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return non-zero if DECL is a dllimport'd object. */
|
||||
/* Return nonzero if DECL is a dllimport'd object. */
|
||||
|
||||
int
|
||||
arm_dllimport_p (decl)
|
||||
@ -74,7 +74,7 @@ arm_dllimport_p (decl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return non-zero if SYMBOL is marked as being dllexport'd. */
|
||||
/* Return nonzero if SYMBOL is marked as being dllexport'd. */
|
||||
|
||||
int
|
||||
arm_dllexport_name_p (symbol)
|
||||
@ -83,7 +83,7 @@ arm_dllexport_name_p (symbol)
|
||||
return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'e' && symbol[2] == '.';
|
||||
}
|
||||
|
||||
/* Return non-zero if SYMBOL is marked as being dllimport'd. */
|
||||
/* Return nonzero if SYMBOL is marked as being dllimport'd. */
|
||||
|
||||
int
|
||||
arm_dllimport_name_p (symbol)
|
||||
@ -204,13 +204,12 @@ arm_mark_dllimport (decl)
|
||||
XEXP (DECL_RTL (decl), 0) = newrtl;
|
||||
}
|
||||
|
||||
/* Cover function to implement ENCODE_SECTION_INFO. */
|
||||
|
||||
void
|
||||
arm_pe_encode_section_info (decl)
|
||||
arm_pe_encode_section_info (decl, first)
|
||||
tree decl;
|
||||
int first ATTRIBUTE_UNUSED;
|
||||
{
|
||||
/* This bit is copied from arm.h. */
|
||||
/* This bit is copied from arm_encode_section_info. */
|
||||
if (optimize > 0 && TREE_CONSTANT (decl)
|
||||
&& (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
|
||||
{
|
||||
@ -247,8 +246,6 @@ arm_pe_encode_section_info (decl)
|
||||
}
|
||||
}
|
||||
|
||||
/* Cover function for UNIQUE_SECTION. */
|
||||
|
||||
void
|
||||
arm_pe_unique_section (decl, reloc)
|
||||
tree decl;
|
||||
@ -260,15 +257,14 @@ arm_pe_unique_section (decl, reloc)
|
||||
const char * prefix;
|
||||
|
||||
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
/* Strip off any encoding in fnname. */
|
||||
STRIP_NAME_ENCODING (name, name);
|
||||
name = arm_strip_name_encoding (name);
|
||||
|
||||
/* The object is put in, for example, section .text$foo.
|
||||
The linker will then ultimately place them in .text
|
||||
(everything from the $ on is stripped). */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
prefix = ".text$";
|
||||
else if (DECL_READONLY_SECTION (decl, reloc))
|
||||
else if (decl_readonly_section (decl, reloc))
|
||||
prefix = ".rdata$";
|
||||
else
|
||||
prefix = ".data$";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Definitions of target machine for GNU compiler, for ARM with PE obj format.
|
||||
Copyright (C) 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Doug Evans (dje@cygnus.com).
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -94,30 +94,13 @@ Boston, MA 02111-1307, USA. */
|
||||
1,1,1 \
|
||||
}
|
||||
|
||||
/* In addition to the stuff done in arm.h, we must mark dll symbols specially.
|
||||
Definitions of dllexport'd objects install some info in the .drectve
|
||||
section. References to dllimport'd objects are fetched indirectly via
|
||||
__imp_. If both are declared, dllexport overrides.
|
||||
This is also needed to implement one-only vtables: they go into their own
|
||||
section and we need to set DECL_SECTION_NAME so we do that here.
|
||||
Note that we can be called twice on the same decl. */
|
||||
#undef ENCODE_SECTION_INFO
|
||||
#define ENCODE_SECTION_INFO(DECL) \
|
||||
arm_pe_encode_section_info (DECL)
|
||||
|
||||
/* Used to implement dllexport overriding dllimport semantics. It's also used
|
||||
to handle vtables - the first pass won't do anything because
|
||||
DECL_CONTEXT (DECL) will be 0 so arm_dll{ex,im}port_p will return 0.
|
||||
It's also used to handle dllimport override semantics. */
|
||||
#define REDO_SECTION_INFO_P(DECL) 1
|
||||
|
||||
/* Define this macro if in some cases global symbols from one translation
|
||||
unit may not be bound to undefined symbols in another translation unit
|
||||
without user intervention. For instance, under Microsoft Windows
|
||||
symbols must be explicitly imported from shared libraries (DLLs). */
|
||||
#define MULTIPLE_SYMBOL_SPACES
|
||||
|
||||
#define UNIQUE_SECTION(DECL, RELOC) arm_pe_unique_section (DECL, RELOC)
|
||||
#define TARGET_ASM_UNIQUE_SECTION arm_pe_unique_section
|
||||
|
||||
#define SUPPORTS_ONE_ONLY 1
|
||||
|
||||
@ -206,13 +189,13 @@ Boston, MA 02111-1307, USA. */
|
||||
/* A list of other sections which the compiler might be "in" at any
|
||||
given time. */
|
||||
|
||||
#undef SUBTARGET_EXTRA_SECTIONS
|
||||
#define SUBTARGET_EXTRA_SECTIONS in_drectve,
|
||||
#undef EXTRA_SECTIONS
|
||||
#define EXTRA_SECTIONS in_drectve
|
||||
|
||||
/* A list of extra section function definitions. */
|
||||
|
||||
#undef SUBTARGET_EXTRA_SECTION_FUNCTIONS
|
||||
#define SUBTARGET_EXTRA_SECTION_FUNCTIONS \
|
||||
#undef EXTRA_SECTION_FUNCTIONS
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
DRECTVE_SECTION_FUNCTION \
|
||||
SWITCH_TO_SECTION_FUNCTION
|
||||
|
||||
@ -245,7 +228,7 @@ switch_to_section (section, decl) \
|
||||
case in_text: text_section (); break; \
|
||||
case in_data: data_section (); break; \
|
||||
case in_named: named_section (decl, NULL, 0); break; \
|
||||
case in_rdata: rdata_section (); break; \
|
||||
case in_readonly_data: readonly_data_section (); break; \
|
||||
case in_ctors: ctors_section (); break; \
|
||||
case in_dtors: dtors_section (); break; \
|
||||
case in_drectve: drectve_section (); break; \
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user