Gcc 3.3.1-pre as of 2003-07-11.

This commit is contained in:
Alexander Kabaev 2003-07-11 03:40:53 +00:00
parent fabd8bcd49
commit bd0df3aa27
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/gcc/dist/; revision=117395
726 changed files with 205777 additions and 89857 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -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>

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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
---------------------------------------

View File

@ -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
View File

@ -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])

View File

@ -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"

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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"

View File

@ -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; \

View File

@ -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

View File

@ -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,

File diff suppressed because it is too large Load Diff

View File

@ -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)

View File

@ -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. */

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -43,7 +43,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
*/
/* Reserved identifiers. This is the union of all the keywords for C,
C++, and Objective C. All the type modifiers have to be in one
C++, and Objective-C. All the type modifiers have to be in one
block at the beginning, because they are used as mask bits. There
are 27 type modifiers; if we add many more we will have to redesign
the mask mechanism. */
@ -58,7 +58,7 @@ enum rid
RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT,
/* C extensions */
RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX,
RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX, RID_THREAD,
/* C++ */
RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
@ -93,12 +93,7 @@ enum rid
/* casts */
RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST,
/* alternate spellings */
RID_AND, RID_AND_EQ, RID_NOT, RID_NOT_EQ,
RID_OR, RID_OR_EQ, RID_XOR, RID_XOR_EQ,
RID_BITAND, RID_BITOR, RID_COMPL,
/* Objective C */
/* Objective-C */
RID_ID, RID_AT_ENCODE, RID_AT_END,
RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS,
RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC,
@ -179,10 +174,10 @@ enum c_tree_index
/* Identifier part common to the C front ends. Inherits from
tree_identifier, despite appearances. */
struct c_common_identifier
struct c_common_identifier GTY(())
{
struct tree_common common;
struct cpp_hashnode node;
struct cpp_hashnode GTY ((skip (""))) node;
};
#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE]
@ -226,7 +221,7 @@ struct c_common_identifier
/* A node for `((void) 0)'. */
#define void_zero_node c_global_trees[CTI_VOID_ZERO]
extern tree c_global_trees[CTI_MAX];
extern GTY(()) tree c_global_trees[CTI_MAX];
/* Mark which labels are explicitly declared.
These may be shadowed, and may be referenced from nested functions. */
@ -238,16 +233,14 @@ extern tree c_global_trees[CTI_MAX];
typedef enum c_language_kind
{
clk_c, /* A dialect of C: K&R C, ANSI/ISO C89, C2000,
etc. */
clk_cplusplus, /* ANSI/ISO C++ */
clk_objective_c /* Objective C */
clk_c = 0, /* A dialect of C: K&R C, ANSI/ISO C89, C2000, etc. */
clk_cplusplus /* ANSI/ISO C++ */
}
c_language_kind;
/* Information about a statement tree. */
struct stmt_tree_s {
struct stmt_tree_s GTY(()) {
/* The last statement added to the tree. */
tree x_last_stmt;
/* The type of the last expression statement. (This information is
@ -255,12 +248,12 @@ struct stmt_tree_s {
tree x_last_expr_type;
/* The last filename we recorded. */
const char *x_last_expr_filename;
/* In C++, Non-zero if we should treat statements as full
/* In C++, Nonzero if we should treat statements as full
expressions. In particular, this variable is no-zero if at the
end of a statement we should destroy any temporaries created
during that statement. Similarly, if, at the end of a block, we
should destroy any local variables in this block. Normally, this
variable is non-zero, since those are the normal semantics of
variable is nonzero, since those are the normal semantics of
C++.
However, in order to represent aggregate initialization code as
@ -277,7 +270,7 @@ typedef struct stmt_tree_s *stmt_tree;
/* Global state pertinent to the current function. Some C dialects
extend this structure with additional fields. */
struct language_function {
struct c_language_function GTY(()) {
/* While we are parsing the function, this contains information
about the statement-tree that we are building. */
struct stmt_tree_s x_stmt_tree;
@ -316,11 +309,14 @@ extern int (*lang_statement_code_p) PARAMS ((enum tree_code));
extern void (*lang_expand_stmt) PARAMS ((tree));
extern void (*lang_expand_decl_stmt) PARAMS ((tree));
extern void (*lang_expand_function_end) PARAMS ((void));
extern tree gettags PARAMS ((void));
/* Callback that determines if it's ok for a function to have no
noreturn attribute. */
extern int (*lang_missing_noreturn_ok_p) PARAMS ((tree));
extern int yyparse PARAMS ((void));
extern void free_parser_stacks PARAMS ((void));
extern stmt_tree current_stmt_tree PARAMS ((void));
extern tree *current_scope_stmt_stack PARAMS ((void));
@ -336,7 +332,6 @@ extern tree walk_stmt_tree PARAMS ((tree *,
void *));
extern void prep_stmt PARAMS ((tree));
extern void expand_stmt PARAMS ((tree));
extern void mark_stmt_tree PARAMS ((void *));
extern void shadow_warning PARAMS ((const char *,
tree, tree));
extern tree c_begin_if_stmt PARAMS ((void));
@ -349,7 +344,7 @@ extern void c_finish_while_stmt_cond PARAMS ((tree, tree));
structure for FUNCTION_DECLs; all other DECLs have a NULL
DECL_LANG_SPECIFIC field. */
struct c_lang_decl {
struct c_lang_decl GTY(()) {
unsigned declared_inline : 1;
};
@ -360,17 +355,35 @@ struct c_lang_decl {
#define DECL_NUM_STMTS(NODE) \
(FUNCTION_DECL_CHECK (NODE)->decl.u1.i)
extern void c_mark_lang_decl PARAMS ((struct c_lang_decl *));
/* The variant of the C language being processed. Each C language
front-end defines this variable. */
extern c_language_kind c_language;
/* Nonzero means give string constants the type `const char *', rather
than `char *'. */
/* Switches common to the C front ends. */
extern int flag_const_strings;
/* Nonzero if prepreprocessing only. */
extern int flag_preprocess_only;
/* Nonzero if an ISO standard was selected. It rejects macros in the
user's namespace. */
extern int flag_iso;
/* Nonzero whenever Objective-C functionality is being used. */
extern int flag_objc;
/* Nonzero if -undef was given. It suppresses target built-in macros
and assertions. */
extern int flag_undef;
/* Nonzero means don't recognize the non-ANSI builtin functions. */
extern int flag_no_builtin;
/* Nonzero means don't recognize the non-ANSI builtin functions.
-ansi sets this. */
extern int flag_no_nonansi_builtin;
/* Nonzero means give `double' the same size as `float'. */
@ -380,7 +393,91 @@ extern int flag_short_double;
extern int flag_short_wchar;
/* Warn about *printf or *scanf format/argument anomalies. */
/* Nonzero means allow Microsoft extensions without warnings or errors. */
extern int flag_ms_extensions;
/* Nonzero means don't recognize the keyword `asm'. */
extern int flag_no_asm;
/* Nonzero means give string constants the type `const char *', as mandated
by the standard. */
extern int flag_const_strings;
/* Nonzero means `$' can be in an identifier. */
extern int dollars_in_ident;
/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
extern int flag_signed_bitfields;
extern int explicit_flag_signed_bitfields;
/* Nonzero means warn about pointer casts that can drop a type qualifier
from the pointer target type. */
extern int warn_cast_qual;
/* Warn about functions which might be candidates for format attributes. */
extern int warn_missing_format_attribute;
/* Nonzero means warn about sizeof(function) or addition/subtraction
of function pointers. */
extern int warn_pointer_arith;
/* Nonzero means warn for any global function def
without separate previous prototype decl. */
extern int warn_missing_prototypes;
/* Warn if adding () is suggested. */
extern int warn_parentheses;
/* Warn if initializer is not completely bracketed. */
extern int warn_missing_braces;
/* Warn about comparison of signed and unsigned values.
If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified. */
extern int warn_sign_compare;
/* Nonzero means warn about usage of long long when `-pedantic'. */
extern int warn_long_long;
/* Nonzero means warn about deprecated conversion from string constant to
`char *'. */
extern int warn_write_strings;
/* Nonzero means warn about multiple (redundant) decls for the same single
variable or function. */
extern int warn_redundant_decls;
/* Warn about testing equality of floating point numbers. */
extern int warn_float_equal;
/* Warn about a subscript that has type char. */
extern int warn_char_subscripts;
/* Warn if a type conversion is done that might have confusing results. */
extern int warn_conversion;
/* Warn about #pragma directives that are not recognized. */
extern int warn_unknown_pragmas; /* Tri state variable. */
/* Warn about format/argument anomalies in calls to formatted I/O functions
(*printf, *scanf, strftime, strfmon, etc.). */
extern int warn_format;
@ -392,6 +489,10 @@ extern int warn_format_y2k;
extern int warn_format_extra_args;
/* Warn about zero-length formats. */
extern int warn_format_zero_length;
/* Warn about non-literal format arguments. */
extern int warn_format_nonliteral;
@ -400,25 +501,19 @@ extern int warn_format_nonliteral;
extern int warn_format_security;
/* Warn about possible violations of sequence point rules. */
extern int warn_sequence_point;
/* C/ObjC language option variables. */
/* Warn about functions which might be candidates for format attributes. */
extern int warn_missing_format_attribute;
/* Nonzero means message about use of implicit function declarations;
1 means warning; 2 means error. */
/* Nonzero means warn about sizeof (function) or addition/subtraction
of function pointers. */
extern int mesg_implicit_function_declaration;
extern int warn_pointer_arith;
/* Nonzero means allow type mismatches in conditional expressions;
just make their values `void'. */
/* Nonzero means to warn about compile-time division by zero. */
extern int warn_div_by_zero;
/* Nonzero means do some things the same way PCC does. */
extern int flag_traditional;
extern int flag_cond_mismatch;
/* Nonzero means enable C89 Amendment 1 features. */
@ -428,7 +523,7 @@ extern int flag_isoc94;
extern int flag_isoc99;
/* Nonzero means environment is hosted (i.e., not freestanding) */
/* Nonzero means that we have builtin functions, and main is an int */
extern int flag_hosted;
@ -437,27 +532,286 @@ extern int flag_hosted;
extern int flag_noniso_default_format_attributes;
/* Nonzero means don't recognize any builtin functions. */
/* Nonzero means warn when casting a function call to a type that does
not match the return type (e.g. (float)sqrt() or (anything*)malloc()
when there is no previous declaration of sqrt or malloc. */
extern int flag_no_builtin;
extern int warn_bad_function_cast;
/* Nonzero means don't recognize the non-ANSI builtin functions.
-ansi sets this. */
/* Warn about traditional constructs whose meanings changed in ANSI C. */
extern int flag_no_nonansi_builtin;
extern int warn_traditional;
/* Nonzero means warn about suggesting putting in ()'s. */
/* Nonzero means warn for non-prototype function decls
or non-prototyped defs without previous prototype. */
extern int warn_parentheses;
extern int warn_strict_prototypes;
/* Warn if a type conversion is done that might have confusing results. */
/* Nonzero means warn for any global function def
without separate previous decl. */
extern int warn_conversion;
extern int warn_missing_declarations;
/* Nonzero means warn about usage of long long,
when `-pedantic' and not C99. */
/* Nonzero means warn about extern declarations of objects not at
file-scope level and about *all* declarations of functions (whether
extern or static) not at file-scope level. Note that we exclude
implicit function declarations. To get warnings about those, use
-Wimplicit. */
extern int warn_long_long;
extern int warn_nested_externs;
/* Warn if main is suspicious. */
extern int warn_main;
/* Nonzero means warn about possible violations of sequence point rules. */
extern int warn_sequence_point;
/* Nonzero means to warn about compile-time division by zero. */
extern int warn_div_by_zero;
/* Nonzero means warn about use of implicit int. */
extern int warn_implicit_int;
/* Warn about NULL being passed to argument slots marked as requiring
non-NULL. */
extern int warn_nonnull;
/* ObjC language option variables. */
/* Open and close the file for outputting class declarations, if
requested (ObjC). */
extern int flag_gen_declaration;
/* Generate code for GNU or NeXT runtime environment. */
extern int flag_next_runtime;
/* Tells the compiler that this is a special run. Do not perform any
compiling, instead we are to test some platform dependent features
and output a C header file with appropriate definitions. */
extern int print_struct_values;
/* ???. Undocumented. */
extern const char *constant_string_class_name;
/* Warn if multiple methods are seen for the same selector, but with
different argument types. Performs the check on the whole selector
table at the end of compilation. */
extern int warn_selector;
/* Warn if a @selector() is found, and no method with that selector
has been previously declared. The check is done on each
@selector() as soon as it is found - so it warns about forward
declarations. */
extern int warn_undeclared_selector;
/* Warn if methods required by a protocol are not implemented in the
class adopting it. When turned off, methods inherited to that
class are also considered implemented. */
extern int warn_protocol;
/* C++ language option variables. */
/* Nonzero means don't recognize any extension keywords. */
extern int flag_no_gnu_keywords;
/* Nonzero means do emit exported implementations of functions even if
they can be inlined. */
extern int flag_implement_inlines;
/* Nonzero means do emit exported implementations of templates, instead of
multiple static copies in each file that needs a definition. */
extern int flag_external_templates;
/* Nonzero means that the decision to emit or not emit the implementation of a
template depends on where the template is instantiated, rather than where
it is defined. */
extern int flag_alt_external_templates;
/* Nonzero means that implicit instantiations will be emitted if needed. */
extern int flag_implicit_templates;
/* Nonzero means that implicit instantiations of inline templates will be
emitted if needed, even if instantiations of non-inline templates
aren't. */
extern int flag_implicit_inline_templates;
/* Nonzero means generate separate instantiation control files and
juggle them at link time. */
extern int flag_use_repository;
/* Nonzero if we want to issue diagnostics that the standard says are not
required. */
extern int flag_optional_diags;
/* Nonzero means we should attempt to elide constructors when possible. */
extern int flag_elide_constructors;
/* Nonzero means that member functions defined in class scope are
inline by default. */
extern int flag_default_inline;
/* Controls whether compiler generates 'type descriptor' that give
run-time type information. */
extern int flag_rtti;
/* Nonzero if we want to conserve space in the .o files. We do this
by putting uninitialized data and runtime initialized data into
.common instead of .data at the expense of not flagging multiple
definitions. */
extern int flag_conserve_space;
/* Nonzero if we want to obey access control semantics. */
extern int flag_access_control;
/* Nonzero if we want to check the return value of new and avoid calling
constructors if it is a null pointer. */
extern int flag_check_new;
/* Nonzero if we want the new ISO rules for pushing a new scope for `for'
initialization variables.
0: Old rules, set by -fno-for-scope.
2: New ISO rules, set by -ffor-scope.
1: Try to implement new ISO rules, but with backup compatibility
(and warnings). This is the default, for now. */
extern int flag_new_for_scope;
/* Nonzero if we want to emit defined symbols with common-like linkage as
weak symbols where possible, in order to conform to C++ semantics.
Otherwise, emit them as local symbols. */
extern int flag_weak;
/* Nonzero to use __cxa_atexit, rather than atexit, to register
destructors for local statics and global objects. */
extern int flag_use_cxa_atexit;
/* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */
extern int flag_vtable_gc;
/* Nonzero means make the default pedwarns warnings instead of errors.
The value of this flag is ignored if -pedantic is specified. */
extern int flag_permissive;
/* Nonzero means to implement standard semantics for exception
specifications, calling unexpected if an exception is thrown that
doesn't match the specification. Zero means to treat them as
assertions and optimize accordingly, but not check them. */
extern int flag_enforce_eh_specs;
/* The version of the C++ ABI in use. The following values are
allowed:
0: The version of the ABI believed most conformant with the
C++ ABI specification. This ABI may change as bugs are
discovered and fixed. Therefore, 0 will not necessarily
indicate the same ABI in different versions of G++.
1: The version of the ABI first used in G++ 3.2.
Additional positive integers will be assigned as new versions of
the ABI become the default version of the ABI. */
extern int flag_abi_version;
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
extern int warn_abi;
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
/* Nonzero means warn when all ctors or dtors are private, and the class
has no friends. */
extern int warn_ctor_dtor_privacy;
/* Nonzero means warn in function declared in derived class has the
same name as a virtual in the base class, but fails to match the
type signature of any virtual function in the base class. */
extern int warn_overloaded_virtual;
/* Nonzero means warn when declaring a class that has a non virtual
destructor, when it really ought to have a virtual one. */
extern int warn_nonvdtor;
/* Nonzero means warn when the compiler will reorder code. */
extern int warn_reorder;
/* Nonzero means warn when synthesis behavior differs from Cfront's. */
extern int warn_synth;
/* Nonzero means warn when we convert a pointer to member function
into a pointer to (void or function). */
extern int warn_pmf2ptr;
/* Nonzero means warn about violation of some Effective C++ style rules. */
extern int warn_ecpp;
/* Nonzero means warn where overload resolution chooses a promotion from
unsigned to signed over a conversion to an unsigned of the same size. */
extern int warn_sign_promo;
/* Nonzero means warn when an old-style cast is used. */
extern int warn_old_style_cast;
/* Nonzero means warn when non-templatized friend functions are
declared within a template */
extern int warn_nontemplate_friend;
/* Nonzero means complain about deprecated features. */
extern int warn_deprecated;
/* Maximum template instantiation depth. This limit is rather
arbitrary, but it exists to limit the time it takes to notice
infinite template instantiations. */
extern int max_tinst_depth;
/* Nonzero means the expression being parsed will never be evaluated.
This is a count, since unevaluated expressions can nest. */
@ -484,6 +838,10 @@ extern int skip_evaluation;
what operator was specified for it. */
#define C_EXP_ORIGINAL_CODE(exp) ((enum tree_code) TREE_COMPLEXITY (exp))
/* Attribute table common to the C front ends. */
extern const struct attribute_spec c_common_attribute_table[];
extern const struct attribute_spec c_common_format_attribute_table[];
/* Pointer to function to lazily generate the VAR_DECL for __FUNCTION__ etc.
ID is the identifier to use, NAME is the string.
TYPE_DEP indicates whether it depends on type of the function or not
@ -501,6 +859,12 @@ extern const char *fname_as_string PARAMS ((int));
extern tree fname_decl PARAMS ((unsigned, tree));
extern const char *fname_string PARAMS ((unsigned));
extern void check_function_arguments PARAMS ((tree, tree));
extern void check_function_arguments_recurse PARAMS ((void (*) (void *,
tree,
unsigned HOST_WIDE_INT),
void *, tree,
unsigned HOST_WIDE_INT));
extern void check_function_format PARAMS ((int *, tree, tree));
extern void set_Wformat PARAMS ((int));
extern tree handle_format_attribute PARAMS ((tree *, tree, tree,
@ -508,23 +872,34 @@ extern tree handle_format_attribute PARAMS ((tree *, tree, tree,
extern tree handle_format_arg_attribute PARAMS ((tree *, tree, tree,
int, bool *));
extern void c_common_insert_default_attributes PARAMS ((tree));
extern int c_common_decode_option PARAMS ((int, char **));
extern tree c_common_type_for_mode PARAMS ((enum machine_mode,
int));
extern tree c_common_type_for_size PARAMS ((unsigned int, int));
extern tree c_common_unsigned_type PARAMS ((tree));
extern tree c_common_signed_type PARAMS ((tree));
extern tree c_common_signed_or_unsigned_type PARAMS ((int, tree));
extern tree c_common_truthvalue_conversion PARAMS ((tree));
extern void c_apply_type_quals_to_decl PARAMS ((int, tree));
extern tree c_sizeof PARAMS ((tree));
extern tree c_alignof PARAMS ((tree));
extern tree c_sizeof_or_alignof_type PARAMS ((tree, enum tree_code, int));
extern tree c_alignof_expr PARAMS ((tree));
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PARAMS ((enum tree_code));
#define my_friendly_assert(EXP, N) (void) \
(((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
extern tree c_expand_expr_stmt PARAMS ((tree));
extern void c_expand_start_cond PARAMS ((tree, int, tree));
extern void c_finish_then PARAMS ((void));
extern void c_expand_start_else PARAMS ((void));
extern void c_finish_else PARAMS ((void));
extern void c_finish_else PARAMS ((void));
extern void c_expand_end_cond PARAMS ((void));
/* Validate the expression after `case' and apply default promotions. */
extern tree check_case_value PARAMS ((tree));
/* Concatenate a list of STRING_CST nodes into one STRING_CST. */
extern tree combine_strings PARAMS ((tree));
extern tree fix_string_type PARAMS ((tree));
struct varray_head_tag;
extern tree combine_strings PARAMS ((struct varray_head_tag *));
extern void constant_expression_warning PARAMS ((tree));
extern tree convert_and_check PARAMS ((tree, tree));
extern void overflow_warning PARAMS ((tree));
@ -533,6 +908,8 @@ extern void unsigned_conversion_warning PARAMS ((tree, tree));
/* Read the rest of the current #-directive line. */
extern char *get_directive_line PARAMS ((void));
#define GET_DIRECTIVE_LINE() get_directive_line ()
#define c_sizeof(T) c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 1)
#define c_alignof(T) c_sizeof_or_alignof_type (T, ALIGNOF_EXPR, 1)
/* Subroutine of build_binary_op, used for comparison operations.
See if the operands have both been converted from subword integer types
@ -554,13 +931,13 @@ extern void disable_builtin_function PARAMS ((const char *));
extern tree build_va_arg PARAMS ((tree, tree));
extern void c_common_init_options PARAMS ((enum c_language_kind));
extern void c_common_post_options PARAMS ((void));
extern bool c_common_post_options PARAMS ((void));
extern const char *c_common_init PARAMS ((const char *));
extern void c_common_finish PARAMS ((void));
extern void c_common_parse_file PARAMS ((int));
extern HOST_WIDE_INT c_common_get_alias_set PARAMS ((tree));
extern bool c_promoting_integer_type_p PARAMS ((tree));
extern int self_promoting_args_p PARAMS ((tree));
extern tree simple_type_promotes_to PARAMS ((tree));
extern tree strip_array_types PARAMS ((tree));
/* These macros provide convenient access to the various _STMT nodes. */
@ -591,7 +968,7 @@ extern tree strip_array_types PARAMS ((tree));
/* RETURN_STMT accessors. These give the expression associated with a
return statement, and whether it should be ignored when expanding
(as opposed to inlining). */
#define RETURN_EXPR(NODE) TREE_OPERAND (RETURN_STMT_CHECK (NODE), 0)
#define RETURN_STMT_EXPR(NODE) TREE_OPERAND (RETURN_STMT_CHECK (NODE), 0)
/* EXPR_STMT accessor. This gives the expression associated with an
expression statement. */
@ -721,7 +1098,7 @@ extern tree strip_array_types PARAMS ((tree));
#define STMT_LINENO(NODE) \
(TREE_COMPLEXITY ((NODE)))
/* If non-zero, the STMT_LINENO for NODE is the line at which the
/* If nonzero, the STMT_LINENO for NODE is the line at which the
function ended. */
#define STMT_LINENO_FOR_FN_P(NODE) \
(TREE_LANG_FLAG_2 ((NODE)))
@ -744,7 +1121,6 @@ enum c_tree_code {
#undef DEFTREECODE
extern void add_c_tree_codes PARAMS ((void));
extern void genrtl_do_pushlevel PARAMS ((void));
extern void genrtl_goto_stmt PARAMS ((tree));
extern void genrtl_expr_stmt PARAMS ((tree));
@ -830,8 +1206,6 @@ extern tree boolean_increment PARAMS ((enum tree_code,
after entering or leaving a header file. */
extern void extract_interface_info PARAMS ((void));
extern void mark_c_language_function PARAMS ((struct language_function *));
extern int case_compare PARAMS ((splay_tree_key,
splay_tree_key));
@ -847,18 +1221,19 @@ extern tree finish_label_address_expr PARAMS ((tree));
different implementations. Used in c-common.c. */
extern tree lookup_label PARAMS ((tree));
/* enum expand_modified is in expr.h, as is the macro below. */
#ifdef QUEUED_VAR
extern rtx c_expand_expr PARAMS ((tree, rtx, enum machine_mode,
enum expand_modifier));
#endif
extern rtx c_expand_expr PARAMS ((tree, rtx,
enum machine_mode,
int));
extern int c_safe_from_p PARAMS ((rtx, tree));
extern int c_staticp PARAMS ((tree));
extern int c_unsafe_for_reeval PARAMS ((tree));
extern int c_common_unsafe_for_reeval PARAMS ((tree));
extern const char *init_c_lex PARAMS ((const char *));
extern void cb_register_builtins PARAMS ((cpp_reader *));
/* Information recorded about each file examined during compilation. */
@ -872,4 +1247,6 @@ struct c_fileinfo
struct c_fileinfo *get_fileinfo PARAMS ((const char *));
extern void dump_time_statistics PARAMS ((void));
extern int c_dump_tree PARAMS ((void *, tree));
#endif /* ! GCC_C_COMMON_H */

View 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"

View File

@ -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

File diff suppressed because it is too large Load Diff

196
contrib/gcc/c-dump.c Normal file
View 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;
}

View File

@ -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);
}

View File

@ -27,31 +27,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "c-common.h"
#include "intl.h"
#include "diagnostic.h"
#include "langhooks.h"
/* Command line options and their associated flags. */
/* Warn about format/argument anomalies in calls to formatted I/O functions
(*printf, *scanf, strftime, strfmon, etc.). */
int warn_format;
/* Warn about Y2K problems with strftime formats. */
int warn_format_y2k;
/* Warn about excess arguments to formats. */
int warn_format_extra_args;
/* Warn about non-literal format arguments. */
int warn_format_nonliteral;
/* Warn about possible security problems with calls to format functions. */
int warn_format_security;
/* Set format warning options according to a -Wformat=n option. */
void
@ -61,11 +38,15 @@ set_Wformat (setting)
warn_format = setting;
warn_format_y2k = setting;
warn_format_extra_args = setting;
warn_format_zero_length = setting;
if (setting != 1)
{
warn_format_nonliteral = setting;
warn_format_security = setting;
}
/* Make sure not to disable -Wnonnull if -Wformat=0 is specified. */
if (setting)
warn_nonnull = setting;
}
@ -305,7 +286,7 @@ decode_format_attr (args, info, validated_p)
/* Check a call to a format function against a parameter list. */
/* The meaningfully distinct length modifiers for format checking recognised
/* The meaningfully distinct length modifiers for format checking recognized
by GCC. */
enum format_lengths
{
@ -348,7 +329,7 @@ enum format_std_version
? "ISO C++" \
: ((FEATURE_VER) == STD_EXT \
? "ISO C" \
: "ISO C89"))
: "ISO C90"))
/* Adjust a C standard version, which may be STD_C9L, to account for
-Wno-long-long. Returns other standard versions unchanged. */
#define ADJ_STD(VER) ((int)((VER) == STD_C9L \
@ -458,7 +439,7 @@ typedef struct
/* The flag character in question (0 for end of array). */
const int flag_char;
/* Zero if this entry describes the flag character in general, or a
non-zero character that may be found in flags2 if it describes the
nonzero character that may be found in flags2 if it describes the
flag when used with certain formats only. If the latter, only
the first such entry found that applies to the current conversion
specifier is used; the values of `name' and `long_name' it supplies
@ -488,11 +469,11 @@ typedef struct
const int flag_char1;
/* The second flag character. */
const int flag_char2;
/* Non-zero if the message should say that the first flag is ignored with
/* Nonzero if the message should say that the first flag is ignored with
the second, zero if the combination should simply be objected to. */
const int ignored;
/* Zero if this entry applies whenever this flag combination occurs,
a non-zero character from flags2 if it only applies in some
a nonzero character from flags2 if it only applies in some
circumstances (e.g. 'i' for printf formats ignoring 0 with precision). */
const int predicate;
} format_flag_pair;
@ -709,7 +690,6 @@ static const format_flag_pair strfmon_flag_pairs[] =
#define T_I &integer_type_node
#define T89_I { STD_C89, NULL, T_I }
#define T99_I { STD_C99, NULL, T_I }
#define T_L &long_integer_type_node
#define T89_L { STD_C89, NULL, T_L }
#define T_LL &long_long_integer_type_node
@ -719,7 +699,6 @@ static const format_flag_pair strfmon_flag_pairs[] =
#define T89_S { STD_C89, NULL, T_S }
#define T_UI &unsigned_type_node
#define T89_UI { STD_C89, NULL, T_UI }
#define T99_UI { STD_C99, NULL, T_UI }
#define T_UL &long_unsigned_type_node
#define T89_UL { STD_C89, NULL, T_UL }
#define T_ULL &long_long_unsigned_type_node
@ -895,10 +874,16 @@ typedef struct
int number_other;
} format_check_results;
typedef struct
{
format_check_results *res;
function_format_info *info;
tree params;
int *status;
} format_check_context;
static void check_format_info PARAMS ((int *, function_format_info *, tree));
static void check_format_info_recurse PARAMS ((int *, format_check_results *,
function_format_info *, tree,
tree, unsigned HOST_WIDE_INT));
static void check_format_arg PARAMS ((void *, tree, unsigned HOST_WIDE_INT));
static void check_format_info_main PARAMS ((int *, format_check_results *,
function_format_info *,
const char *, int, tree,
@ -1011,7 +996,7 @@ check_function_format (status, attrs, params)
static void
status_warning VPARAMS ((int *status, const char *msgid, ...))
{
diagnostic_context dc;
diagnostic_info diagnostic ;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, int *, status);
@ -1022,9 +1007,9 @@ status_warning VPARAMS ((int *status, const char *msgid, ...))
else
{
/* This duplicates the warning function behavior. */
set_diagnostic_context
(&dc, msgid, &ap, input_filename, lineno, /* warn = */ 1);
report_diagnostic (&dc);
diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, lineno,
DK_WARNING);
report_diagnostic (&diagnostic);
}
VA_CLOSE (ap);
@ -1289,6 +1274,7 @@ check_format_info (status, info, params)
function_format_info *info;
tree params;
{
format_check_context format_ctx;
unsigned HOST_WIDE_INT arg_num;
tree format_tree;
format_check_results res;
@ -1315,7 +1301,13 @@ check_format_info (status, info, params)
res.number_unterminated = 0;
res.number_other = 0;
check_format_info_recurse (status, &res, info, format_tree, params, arg_num);
format_ctx.res = &res;
format_ctx.info = info;
format_ctx.params = params;
format_ctx.status = status;
check_function_arguments_recurse (check_format_arg, &format_ctx,
format_tree, arg_num);
if (res.number_non_literal > 0)
{
@ -1361,8 +1353,9 @@ check_format_info (status, info, params)
&& res.number_other == 0 && warn_format_extra_args)
status_warning (status, "unused arguments in $-style format");
if (res.number_empty > 0 && res.number_non_literal == 0
&& res.number_other == 0)
status_warning (status, "zero-length format string");
&& res.number_other == 0 && warn_format_zero_length)
status_warning (status, "zero-length %s format string",
format_types[info->format_type].name);
if (res.number_wide > 0)
status_warning (status, "format is a wide character string");
@ -1371,112 +1364,31 @@ check_format_info (status, info, params)
status_warning (status, "unterminated format string");
}
/* Recursively check a call to a format function. FORMAT_TREE is the
format parameter, which may be a conditional expression in which
both halves should be checked. ARG_NUM is the number of the
format argument; PARAMS points just after it in the argument list. */
/* Callback from check_function_arguments_recurse to check a
format string. FORMAT_TREE is the format parameter. ARG_NUM
is the number of the format argument. CTX points to a
format_check_context. */
static void
check_format_info_recurse (status, res, info, format_tree, params, arg_num)
int *status;
format_check_results *res;
function_format_info *info;
check_format_arg (ctx, format_tree, arg_num)
void *ctx;
tree format_tree;
tree params;
unsigned HOST_WIDE_INT arg_num;
{
format_check_context *format_ctx = ctx;
format_check_results *res = format_ctx->res;
function_format_info *info = format_ctx->info;
tree params = format_ctx->params;
int *status = format_ctx->status;
int format_length;
HOST_WIDE_INT offset;
const char *format_chars;
tree array_size = 0;
tree array_init;
if (TREE_CODE (format_tree) == NOP_EXPR)
{
/* Strip coercion. */
check_format_info_recurse (status, res, info,
TREE_OPERAND (format_tree, 0), params,
arg_num);
return;
}
if (TREE_CODE (format_tree) == CALL_EXPR)
{
tree type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (format_tree, 0)));
tree attrs;
bool found_format_arg = false;
/* See if this is a call to a known internationalization function
that modifies the format arg. Such a function may have multiple
format_arg attributes (for example, ngettext). */
for (attrs = TYPE_ATTRIBUTES (type);
attrs;
attrs = TREE_CHAIN (attrs))
if (is_attribute_p ("format_arg", TREE_PURPOSE (attrs)))
{
tree inner_args;
tree format_num_expr;
int format_num;
int i;
/* Extract the argument number, which was previously checked
to be valid. */
format_num_expr = TREE_VALUE (TREE_VALUE (attrs));
while (TREE_CODE (format_num_expr) == NOP_EXPR
|| TREE_CODE (format_num_expr) == CONVERT_EXPR
|| TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
format_num_expr = TREE_OPERAND (format_num_expr, 0);
if (TREE_CODE (format_num_expr) != INTEGER_CST
|| TREE_INT_CST_HIGH (format_num_expr) != 0)
abort ();
format_num = TREE_INT_CST_LOW (format_num_expr);
for (inner_args = TREE_OPERAND (format_tree, 1), i = 1;
inner_args != 0;
inner_args = TREE_CHAIN (inner_args), i++)
if (i == format_num)
{
check_format_info_recurse (status, res, info,
TREE_VALUE (inner_args), params,
arg_num);
found_format_arg = true;
break;
}
}
/* If we found a format_arg attribute and did a recursive check,
we are done with checking this format string. Otherwise, we
continue and this will count as a non-literal format string. */
if (found_format_arg)
return;
}
if (TREE_CODE (format_tree) == COND_EXPR)
{
/* Check both halves of the conditional expression. */
check_format_info_recurse (status, res, info,
TREE_OPERAND (format_tree, 1), params,
arg_num);
check_format_info_recurse (status, res, info,
TREE_OPERAND (format_tree, 2), params,
arg_num);
return;
}
if (integer_zerop (format_tree))
{
/* FIXME: this warning should go away once Marc Espie's
__attribute__((nonnull)) patch is in. Instead, checking for
nonnull attributes should probably change this function to act
specially if info == NULL and add a res->number_null entry for
that case, or maybe add a function pointer to be called at
the end instead of hardcoding check_format_info_main. */
status_warning (status, "null format string");
/* Skip to first argument to check, so we can see if this format
has any arguments (it shouldn't). */
while (arg_num + 1 < info->first_arg_num)
@ -1751,11 +1663,6 @@ check_format_info_main (status, res, info, format_chars, format_length,
/* "...a field width...may be indicated by an asterisk.
In this case, an int argument supplies the field width..." */
++format_chars;
if (params == 0)
{
status_warning (status, "too few arguments for format");
return;
}
if (has_operand_number != 0)
{
int opnum;
@ -1775,6 +1682,11 @@ check_format_info_main (status, res, info, format_chars, format_length,
}
if (info->first_arg_num != 0)
{
if (params == 0)
{
status_warning (status, "too few arguments for format");
return;
}
cur_param = TREE_VALUE (params);
if (has_operand_number <= 0)
{
@ -2258,7 +2170,6 @@ check_format_types (status, types)
tree cur_type;
tree orig_cur_type;
tree wanted_type;
tree promoted_type;
int arg_num;
int i;
int char_type_flag;
@ -2277,11 +2188,7 @@ check_format_types (status, types)
abort ();
if (types->pointer_count == 0)
{
promoted_type = simple_type_promotes_to (wanted_type);
if (promoted_type != NULL_TREE)
wanted_type = promoted_type;
}
wanted_type = (*lang_hooks.types.type_promotes_to) (wanted_type);
STRIP_NOPS (cur_param);
@ -2386,8 +2293,8 @@ check_format_types (status, types)
&& TREE_CODE (cur_type) == INTEGER_TYPE
&& (! pedantic || i == 0 || (i == 1 && char_type_flag))
&& (TREE_UNSIGNED (wanted_type)
? wanted_type == unsigned_type (cur_type)
: wanted_type == signed_type (cur_type)))
? wanted_type == c_common_unsigned_type (cur_type)
: wanted_type == c_common_signed_type (cur_type)))
continue;
/* Likewise, "signed char", "unsigned char" and "char" are
equivalent but the above test won't consider them equivalent. */

View File

@ -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"

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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

File diff suppressed because it is too large Load Diff

View 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 */

View File

@ -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;

View File

@ -34,16 +34,32 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
lang_identifier nodes, because some keywords are only special in a
particular context. */
struct lang_identifier
struct lang_identifier GTY(())
{
struct c_common_identifier ignore;
tree global_value, local_value, label_value, implicit_decl;
tree error_locus, limbo_value;
struct c_common_identifier common_id;
tree global_value;
tree local_value;
tree label_value;
tree implicit_decl;
tree error_locus;
tree limbo_value;
};
/* The resulting tree type. */
union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
union tree_node GTY ((tag ("0"),
desc ("tree_node_structure (&%h)")))
generic;
struct lang_identifier GTY ((tag ("1"))) identifier;
};
/* Language-specific declaration information. */
struct lang_decl
struct lang_decl GTY(())
{
struct c_lang_decl base;
/* The return types and parameter types may have variable size.
@ -107,10 +123,10 @@ struct lang_decl
(DECL_LANG_SPECIFIC (NODE)->base.declared_inline)
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
struct lang_type
struct lang_type GTY(())
{
int len;
tree elts[1];
tree GTY((length ("%h.len"))) elts[1];
};
/* Record whether a type or decl was written with nonconstant size.
@ -150,29 +166,36 @@ struct lang_type
/* in c-lang.c and objc-act.c */
extern tree lookup_interface PARAMS ((tree));
extern tree is_class_name PARAMS ((tree));
extern void maybe_objc_check_decl PARAMS ((tree));
extern tree objc_is_id PARAMS ((tree));
extern void objc_check_decl PARAMS ((tree));
extern void finish_file PARAMS ((void));
extern int maybe_objc_comptypes PARAMS ((tree, tree, int));
extern tree maybe_building_objc_message_expr PARAMS ((void));
extern int recognize_objc_keyword PARAMS ((void));
extern int objc_comptypes PARAMS ((tree, tree, int));
extern tree objc_message_selector PARAMS ((void));
extern tree lookup_objc_ivar PARAMS ((tree));
/* in c-parse.in */
extern void c_parse_init PARAMS ((void));
extern void c_set_yydebug PARAMS ((int));
extern int yyparse_1 PARAMS ((void));
/* in c-aux-info.c */
extern void gen_aux_info_record PARAMS ((tree, int, int, int));
/* in c-decl.c */
extern int global_bindings_p PARAMS ((void));
extern int kept_level_p PARAMS ((void));
extern tree getdecls PARAMS ((void));
extern void pushlevel PARAMS ((int));
extern tree poplevel PARAMS ((int,int, int));
extern void insert_block PARAMS ((tree));
extern void set_block PARAMS ((tree));
extern tree pushdecl PARAMS ((tree));
extern void c_insert_default_attributes PARAMS ((tree));
extern void c_init_decl_processing PARAMS ((void));
extern void c_dup_lang_specific_decl PARAMS ((tree));
extern void c_print_identifier PARAMS ((FILE *, tree, int));
extern tree build_array_declarator PARAMS ((tree, tree, int, int));
extern tree build_enumerator PARAMS ((tree, tree));
extern int c_decode_option PARAMS ((int, char **));
extern void c_mark_varargs PARAMS ((void));
extern void check_for_loop_decls PARAMS ((void));
extern void clear_parm_order PARAMS ((void));
extern int complete_array_type PARAMS ((tree, tree, int));
@ -191,14 +214,12 @@ extern tree implicitly_declare PARAMS ((tree));
extern void implicit_decl_warning PARAMS ((tree));
extern int in_parm_level_p PARAMS ((void));
extern void keep_next_level PARAMS ((void));
extern int kept_level_p PARAMS ((void));
extern tree lookup_name PARAMS ((tree));
extern tree lookup_name_current_level PARAMS ((tree));
extern void parmlist_tags_warning PARAMS ((void));
extern void pending_xref_error PARAMS ((void));
extern void mark_c_function_context PARAMS ((struct function *));
extern void push_c_function_context PARAMS ((struct function *));
extern void pop_c_function_context PARAMS ((struct function *));
extern void c_push_function_context PARAMS ((struct function *));
extern void c_pop_function_context PARAMS ((struct function *));
extern void pop_label_level PARAMS ((void));
extern void push_label_level PARAMS ((void));
extern void push_parm_decl PARAMS ((tree));
@ -218,7 +239,7 @@ extern tree xref_tag PARAMS ((enum tree_code, tree));
extern tree c_begin_compound_stmt PARAMS ((void));
extern void c_expand_deferred_function PARAMS ((tree));
extern void c_expand_decl_stmt PARAMS ((tree));
extern tree make_pointer_declarator PARAMS ((tree, tree));
/* in c-objc-common.c */
extern int c_disregard_inline_limits PARAMS ((tree));
@ -227,23 +248,28 @@ extern const char *c_objc_common_init PARAMS ((const char *));
extern int c_missing_noreturn_ok_p PARAMS ((tree));
extern void c_objc_common_finish_file PARAMS ((void));
extern int defer_fn PARAMS ((tree));
extern bool c_warn_unused_global_decl PARAMS ((tree));
#define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \
c_build_qualified_type ((TYPE), \
((CONST_P) ? TYPE_QUAL_CONST : 0) | \
((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
#define c_sizeof_nowarn(T) c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 0)
/* in c-typeck.c */
extern tree require_complete_type PARAMS ((tree));
extern int comptypes PARAMS ((tree, tree));
extern tree c_sizeof_nowarn PARAMS ((tree));
extern tree c_size_in_bytes PARAMS ((tree));
extern bool c_mark_addressable PARAMS ((tree));
extern void c_incomplete_type_error PARAMS ((tree, tree));
extern tree c_type_promotes_to PARAMS ((tree));
extern tree build_component_ref PARAMS ((tree, tree));
extern tree build_indirect_ref PARAMS ((tree, const char *));
extern tree build_array_ref PARAMS ((tree, tree));
extern tree build_external_ref PARAMS ((tree, int));
extern tree parser_build_binary_op PARAMS ((enum tree_code,
tree, tree));
extern int c_tree_expr_nonnegative_p PARAMS ((tree));
extern void readonly_warning PARAMS ((tree, const char *));
extern tree build_conditional_expr PARAMS ((tree, tree, tree));
extern tree build_compound_expr PARAMS ((tree));
@ -287,94 +313,14 @@ extern int current_function_returns_null;
extern int current_function_returns_abnormally;
/* Nonzero means `$' can be in an identifier. */
extern int dollars_in_ident;
/* Nonzero means allow type mismatches in conditional expressions;
just make their values `void'. */
extern int flag_cond_mismatch;
/* Nonzero means don't recognize the keyword `asm'. */
extern int flag_no_asm;
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
/* Nonzero means warn for all old-style non-prototype function decls. */
extern int warn_strict_prototypes;
/* Nonzero means warn about multiple (redundant) decls for the same single
variable or function. */
extern int warn_redundant_decls;
/* Nonzero means warn about extern declarations of objects not at
file-scope level and about *all* declarations of functions (whether
extern or static) not at file-scope level. Note that we exclude
implicit function declarations. To get warnings about those, use
-Wimplicit. */
extern int warn_nested_externs;
/* Nonzero means warn about pointer casts that can drop a type qualifier
from the pointer target type. */
extern int warn_cast_qual;
/* Nonzero means warn when casting a function call to a type that does
not match the return type (e.g. (float)sqrt() or (anything*)malloc()
when there is no previous declaration of sqrt or malloc. */
extern int warn_bad_function_cast;
/* Warn about traditional constructs whose meanings changed in ANSI C. */
extern int warn_traditional;
/* Warn about a subscript that has type char. */
extern int warn_char_subscripts;
/* Warn if main is suspicious. */
extern int warn_main;
/* Nonzero means to allow single precision math even if we're generally
being traditional. */
extern int flag_allow_single_precision;
/* Warn if initializer is not completely bracketed. */
extern int warn_missing_braces;
/* Warn about comparison of signed and unsigned values. */
extern int warn_sign_compare;
/* Warn about testing equality of floating point numbers. */
extern int warn_float_equal;
/* Warn about multicharacter constants. */
extern int warn_multichar;
/* Nonzero means we are reading code that came from a system header file. */
extern int system_header_p;
/* Warn about implicit declarations. 1 = warning, 2 = error. */
extern int mesg_implicit_function_declaration;
/* In c-decl.c */
extern void finish_incomplete_decl PARAMS ((tree));
extern void c_finish_incomplete_decl PARAMS ((tree));
extern tree static_ctors;
extern tree static_dtors;
extern GTY(()) tree static_ctors;
extern GTY(()) tree static_dtors;
#endif /* ! GCC_C_TREE_H */

File diff suppressed because it is too large Load Diff

View File

@ -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. */

View File

@ -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++)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 */
/*

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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));

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -27,30 +27,23 @@ Boston, MA 02111-1307, USA. */
/* ??? Move all SDB stuff from alpha.h to osf.h. */
#undef SDB_DEBUGGING_INFO
#define DBX_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO
#define DBX_DEBUGGING_INFO 1
#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
#undef ASM_FINAL_SPEC
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "-D__ELF__"
#undef CC1_SPEC
#define CC1_SPEC "%{G*}"
#undef ASM_SPEC
#define ASM_SPEC "%{G*} %{relax:-relax} %{!gstabs*:-no-mdebug}%{gstabs*:-mdebug}"
#undef LINK_SPEC
#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}}"
/* Output at beginning of assembler file. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
@ -75,9 +68,6 @@ do { \
#undef IDENT_ASM_OP
#define IDENT_ASM_OP "\t.ident\t"
/* Allow #sccs in preprocessor. */
#define SCCS_DIRECTIVE
/* Output #ident as a .ident. */
#undef ASM_OUTPUT_IDENT
#define ASM_OUTPUT_IDENT(FILE, NAME) \
@ -122,7 +112,7 @@ do { \
#undef ASM_OUTPUT_EXTERNAL_LIBCALL
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0))
(*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0))
/* This says how to output assembler code to declare an
uninitialized external linkage data object. Under SVR4,
@ -152,17 +142,9 @@ do { \
sbss_section(); \
else \
bss_section(); \
fprintf (FILE, "%s", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "object"); \
putc ('\n', FILE); \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
if (!flag_inhibit_size_directive) \
{ \
fprintf (FILE, "%s", SIZE_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, ",%d\n", (SIZE)); \
} \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
@ -174,7 +156,7 @@ do { \
#undef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
ASM_GLOBALIZE_LABEL (FILE, NAME); \
(*targetm.asm_out.globalize_label) (FILE, NAME); \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
@ -198,20 +180,8 @@ do { \
#undef ASCII_DATA_ASM_OP
#define ASCII_DATA_ASM_OP "\t.ascii\t"
/* 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. */
#undef USE_CONST_SECTION
#define USE_CONST_SECTION 1
#undef CONST_SECTION_ASM_OP
#define CONST_SECTION_ASM_OP "\t.section\t.rodata"
#undef READONLY_DATA_SECTION_ASM_OP
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata"
#undef BSS_SECTION_ASM_OP
#define BSS_SECTION_ASM_OP "\t.section\t.bss"
#undef SBSS_SECTION_ASM_OP
@ -246,7 +216,7 @@ do { \
includes this file. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_const, in_sbss, in_sdata
#define EXTRA_SECTIONS in_sbss, in_sdata
/* A default list of extra section function definitions. For targets
that use additional sections (e.g. .tdesc) you should override this
@ -254,30 +224,12 @@ do { \
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CONST_SECTION_FUNCTION \
SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP) \
SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP)
extern void sbss_section PARAMS ((void));
extern void sdata_section PARAMS ((void));
#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION() const_section ()
#undef CONST_SECTION_FUNCTION
#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; \
} \
}
#undef SECTION_FUNCTION_TEMPLATE
#define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \
void FN () \
@ -291,177 +243,10 @@ void FN () \
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
/* A C statement or statements to switch to the appropriate
section for output of DECL. DECL is either a `VAR_DECL' node
or a constant of some sort. RELOC indicates whether forming
the initial value of DECL requires link-time relocations.
Set SECNUM to:
0 .text
1 .rodata
2 .data
3 .sdata
4 .bss
5 .sbss
*/
#define DO_SELECT_SECTION(SECNUM, DECL, RELOC) \
do \
{ \
HOST_WIDE_INT size; \
SECNUM = 1; \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
{ \
SECNUM = 0; \
break; \
} \
else if (TREE_CODE (DECL) == STRING_CST) \
{ \
if (flag_writable_strings) \
SECNUM = 2; \
else \
SECNUM = 0x101; \
break; \
} \
else if (TREE_CODE (DECL) == VAR_DECL) \
{ \
if (DECL_INITIAL (DECL) == NULL \
|| DECL_INITIAL (DECL) == error_mark_node) \
SECNUM = 4; \
else if ((flag_pic && RELOC) \
|| ! TREE_READONLY (DECL) \
|| TREE_SIDE_EFFECTS (DECL) \
|| ! TREE_CONSTANT (DECL_INITIAL (DECL))) \
SECNUM = 2; \
else if (flag_merge_constants >= 2) \
{ \
/* C and C++ don't allow different variables to \
share the same location. -fmerge-all-constants\
allows even that (at the expense of not \
conforming). */ \
if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST)\
SECNUM = 0x201; \
else \
SECNUM = 0x301; \
} \
} \
else if (TREE_CODE (DECL) == CONSTRUCTOR) \
{ \
if ((flag_pic && RELOC) \
|| TREE_SIDE_EFFECTS (DECL) \
|| ! TREE_CONSTANT (DECL)) \
SECNUM = 2; \
} \
\
/* Select small data sections based on size. */ \
size = int_size_in_bytes (TREE_TYPE (DECL)); \
if (size >= 0 && size <= g_switch_value) \
{ \
if ((SECNUM & 0xff) >= 2) \
SECNUM += 1; \
/* Move readonly data to .sdata only if -msmall-data. */ \
/* ??? Consider .sdata.{lit4,lit8} as \
SHF_MERGE|SHF_ALPHA_GPREL. */ \
else if (TARGET_SMALL_DATA) \
SECNUM = 3; \
} \
} \
while (0)
#undef SELECT_SECTION
#define SELECT_SECTION(DECL, RELOC, ALIGN) \
do \
{ \
typedef void (*sec_fn) PARAMS ((void)); \
static sec_fn const sec_functions[6] = \
{ \
text_section, \
const_section, \
data_section, \
sdata_section, \
bss_section, \
sbss_section \
}; \
\
int sec; \
\
DO_SELECT_SECTION (sec, DECL, RELOC); \
\
switch (sec) \
{ \
case 0x101: \
mergeable_string_section (DECL, ALIGN, 0); \
break; \
case 0x201: \
mergeable_string_section (DECL_INITIAL (DECL),\
ALIGN, 0); \
break; \
case 0x301: \
mergeable_constant_section (DECL_MODE (DECL), \
ALIGN, 0); \
break; \
default: \
(*sec_functions[sec]) (); \
break; \
} \
} \
while (0)
#define TARGET_ASM_SELECT_SECTION default_elf_select_section
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
#undef UNIQUE_SECTION
#define UNIQUE_SECTION(DECL, RELOC) \
do \
{ \
static const char * const prefixes[6][2] = \
{ \
{ ".text.", ".gnu.linkonce.t." }, \
{ ".rodata.", ".gnu.linkonce.r." }, \
{ ".data.", ".gnu.linkonce.d." }, \
{ ".sdata.", ".gnu.linkonce.s." }, \
{ ".bss.", ".gnu.linkonce.b." }, \
{ ".sbss.", ".gnu.linkonce.sb." } \
}; \
\
int nlen, plen, sec; \
const char *name, *prefix; \
char *string; \
\
DO_SELECT_SECTION (sec, DECL, RELOC); \
\
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
STRIP_NAME_ENCODING (name, name); \
nlen = strlen (name); \
\
prefix = prefixes[sec & 0xff][DECL_ONE_ONLY(DECL)]; \
plen = strlen (prefix); \
\
string = alloca (nlen + plen + 1); \
\
memcpy (string, prefix, plen); \
memcpy (string + plen, name, nlen + 1); \
\
DECL_SECTION_NAME (DECL) = build_string (nlen + plen, string); \
} \
while (0)
/* A C statement or statements to switch to the appropriate
section for output of RTX in mode MODE. RTX is some kind
of constant in RTL. The argument MODE is redundant except
in the case of a `const_int' rtx. Currently, these always
go into the const section. */
#undef SELECT_RTX_SECTION
#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) \
do { \
if (TARGET_SMALL_DATA && GET_MODE_SIZE (MODE) <= g_switch_value) \
/* ??? Consider .sdata.{lit4,lit8} as SHF_MERGE|SHF_ALPHA_GPREL. */ \
sdata_section (); \
else \
mergeable_constant_section((MODE), (ALIGN), 0); \
} while (0)
/* Define the strings used for the special svr4 .type and .size directives.
These strings generally do not vary from one system running svr4 to
another, but if a given system (e.g. m88k running svr) needs to use
@ -538,22 +323,14 @@ do { \
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
do { \
HOST_WIDE_INT size; \
fprintf (FILE, "%s", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "object"); \
putc ('\n', FILE); \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
size_directive_output = 0; \
if (!flag_inhibit_size_directive \
&& DECL_SIZE (DECL) \
&& (size = int_size_in_bytes (TREE_TYPE (DECL))) > 0) \
{ \
size_directive_output = 1; \
fprintf (FILE, "%s", SIZE_ASM_OP); \
assemble_name (FILE, NAME); \
fputc (',', FILE); \
fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, size); \
fputc ('\n', FILE); \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \
} \
ASM_OUTPUT_LABEL(FILE, NAME); \
} while (0)
@ -577,11 +354,7 @@ do { \
&& (size = int_size_in_bytes (TREE_TYPE (DECL))) > 0) \
{ \
size_directive_output = 1; \
fprintf (FILE, "%s", SIZE_ASM_OP); \
assemble_name (FILE, name); \
fputc (',', FILE); \
fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, size); \
fputc ('\n', FILE); \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, name, size); \
} \
} while (0)
@ -653,7 +426,7 @@ do { \
%{shared:crtendS.o%s}%{!shared:crtend.o%s} crtn.o%s"
/* We support #pragma. */
#define HANDLE_SYSV_PRAGMA
#define HANDLE_SYSV_PRAGMA 1
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is

View 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")

View 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")

View 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")

View File

@ -20,18 +20,26 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Provide a CPP_SPEC appropriate for FreeBSD/alpha. Besides the dealing with
/* Provide a FBSD_TARGET_CPU_CPP_BUILTINS and CPP_SPEC appropriate for
FreeBSD/alpha. Besides the dealing with
the GCC option `-posix', and PIC issues as on all FreeBSD platforms, we must
deal with the Alpha's FP issues. */
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %(cpp_subtarget) -D__ELF__ \
%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} \
%{posix:-D_POSIX_SOURCE} \
%{mieee:-D_IEEE_FP} \
%{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT}"
#undef FBSD_TARGET_CPU_CPP_BUILTINS
#define FBSD_TARGET_CPU_CPP_BUILTINS() \
do \
{ \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
builtin_define ("__pic__"); \
} \
} \
while (0)
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_subtarget) %{posix:-D_POSIX_SOURCE}"
#undef LINK_SPEC
#define LINK_SPEC "%{G*} %{relax:-relax} \
%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
%{Wl,*:%*} \
@ -54,9 +62,6 @@ Boston, MA 02111-1307, USA. */
/* alpha.h gets this wrong for FreeBSD. We use the GCC defaults instead. */
#undef WCHAR_TYPE
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32

View 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

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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. */

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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>

View File

@ -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");

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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 { \

View File

@ -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

View 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)

View File

@ -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

View File

@ -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 */

View File

@ -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:

View File

@ -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++. */

Some files were not shown because too many files have changed in this diff Show More